<commit_before>/*******************************************************************************
GPU OPTIMIZED MONTE CARLO (GOMC) 2.40
Copyright (C) 2018  GOMC Group
A copy of the GNU General Public License can be found in the COPYRIGHT.txt
along with this program, also can be found at <http://www.gnu.org/licenses/>.
********************************************************************************/
#include "Simulation.h"
#include "GOMC_Config.h"    //For version number
#if GOMC_LIB_MPI
#include <mpi.h>
#include "ParallelTemperingPreprocessor.h"
#endif
#ifdef GOMC_CUDA
#include "cuda.h"
#include <cuda_runtime_api.h>
#endif
#include <iostream>
#include <ctime>

//find and include appropriate files for getHostname
#ifdef _WIN32
#include <Winsock2.h>
#define HOSTNAME
#elif defined(__linux__) || defined(__apple__) || defined(__FreeBSD__)
#include <unistd.h>
#include <sys/sysinfo.h>
#include <sys/utsname.h>
#define HOSTNAME
#endif

namespace
{
std::ostream& PrintTime(std::ostream& stream);
std::ostream& PrintHostname(std::ostream& stream);
std::ostream& PrintVersion(std::ostream& stream);
void PrintSimulationHeader();
void PrintSimulationFooter();
void PrintDebugMode();
bool CheckAndPrintEnsemble();
uint ReadNum(char *argv);
}

void PrintHardwareInfo();
#ifdef GOMC_CUDA
void PrintGPUHardwareInfo();
#endif

int main(int argc, char *argv[])
{
#if GOMC_LIB_MPI
  string inputFileStringMPI;
  fstream inputFileReaderMPI;
  MultiSim * multisim;
  int worldSize;
  int worldRank;
  ParallelTemperingPreprocessor pt;

  //std::streambuf * savedCOUT;
  //CHECK IF ARGS/FILE PROVIDED IN CMD LINE
  if (argc < 2) {
    std::cout << "Error: Input parameter file (*.dat or *.conf) not specified on command line!\n";
    exit(EXIT_FAILURE);
  } else {
    if(argc == 2) {
      //FIRST PARAMETER WILL BE FILE NAME
      inputFileStringMPI = argv[1];
    } else {
      //SECOND PARAMETER WILL BE FILE NAME
      inputFileStringMPI = argv[2];

      if(argv[1][0] == '+' && argv[1][1] == 'p') {
      // placeholder
      } else {
        std::cout << "Error: Undefined command to set number of threads!\n";
        std::cout << "Use +p# command to set number of threads.\n";
        exit(EXIT_FAILURE);
      }
    }

    //OPEN FILE
    inputFileReaderMPI.open(inputFileStringMPI.c_str(), ios::in | ios::out);

    //CHECK IF FILE IS OPENED...IF NOT OPENED EXCEPTION REASON FIRED
    if (!inputFileReaderMPI.is_open()) {
      std::cout << "Error: Cannot open/find " << inputFileStringMPI <<
                " in the directory provided!\n";
      exit(EXIT_FAILURE);
    }

    //CLOSE FILE TO NOW PASS TO SIMULATION
    inputFileReaderMPI.close();

    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    // Get the number of processes
    MPI_Comm_size(MPI_COMM_WORLD, &worldSize);

    // Get the rank of the process
    MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);

    std::string pathToReplicaDirectory;
    if(pt.checkIfParallelTempering(inputFileStringMPI)){
      pt.checkIfValid(inputFileStringMPI);
      if(worldSize > pt.getNumberOfReplicas(inputFileStringMPI)){
        std::cout << "You may not request more processes (" << worldSize
          << ") than there are replicas(" << pt.getNumberOfReplicas(inputFileStringMPI) << ")! Exiting!\n";
      } else {
        #if ENSEMBLE == GCMC
        pathToReplicaDirectory = pt.setupReplicaDirectoriesAndRedirectSTDOUTToFile  ( pt.getMultiSimFolderName(inputFileStringMPI).c_str(),
                                                                                pt.getTemperature(inputFileStringMPI.c_str(), worldRank).c_str(),
                                                                                pt.getChemicalPotential(inputFileStringMPI.c_str(), worldRank).c_str()
                                                                                );
        #else
        pathToReplicaDirectory = pt.setupReplicaDirectoriesAndRedirectSTDOUTToFile  ( pt.getMultiSimFolderName(inputFileStringMPI).c_str(),
                                                                                pt.getTemperature(inputFileStringMPI.c_str(), worldRank).c_str()
                                                                                );
        #endif
        multisim = new MultiSim(worldSize, worldRank, pathToReplicaDirectory);
      }
    }
  }
#endif
#ifndef NDEBUG
  PrintDebugMode();
#endif
  PrintSimulationHeader();
  PrintHardwareInfo();
#ifdef GOMC_CUDA
  PrintGPUHardwareInfo();
#endif
  //Only run if valid ensemble was detected.
  if (CheckAndPrintEnsemble()) {
    //FOLLOWING LINES ADDED TO OBTAIN INPUT PARAMETER FILE
    string inputFileString;
    fstream inputFileReader;
    uint numThreads;

    //CHECK IF ARGS/FILE PROVIDED IN CMD LINE
    if (argc < 2) {
      std::cout << "Error: Input parameter file (*.dat or *.conf) not specified on command line!\n";
      exit(EXIT_FAILURE);
    } else {
      if(argc == 2) {
        //FIRST PARAMETER WILL BE FILE NAME
        inputFileString = argv[1];
        numThreads = 1;
      } else {
        //SECOND PARAMETER WILL BE FILE NAME
        inputFileString = argv[2];

        if(argv[1][0] == '+' && argv[1][1] == 'p') {
          numThreads = ReadNum(argv[1]);
        } else {
          std::cout << "Error: Undefined command to set number of threads!\n";
          std::cout << "Use +p# command to set number of threads.\n";
          exit(EXIT_FAILURE);
        }

      }
    }

    //SET NUMBER OF THREADS
#ifdef _OPENMP
    omp_set_num_threads(numThreads);
    printf("%-40s %-d \n", "Info: Number of threads", numThreads);
#else
    printf("%-40s %-d \n", "Info: Number of threads", 1);
#endif

    //OPEN FILE
    inputFileReader.open(inputFileString.c_str(), ios::in | ios::out);

    //CHECK IF FILE IS OPENED...IF NOT OPENED EXCEPTION REASON FIRED
    if (!inputFileReader.is_open()) {
      std::cout << "Error: Cannot open/find " << inputFileString <<
                " in the directory provided!\n";
      exit(EXIT_FAILURE);
    }

    //CLOSE FILE TO NOW PASS TO SIMULATION
    inputFileReader.close();

    //ONCE FILE FOUND PASS STRING TO SIMULATION CLASS TO READ AND
    //HANDLE PDB|PSF FILE
#if GOMC_LIB_MPI
    if(worldSize <= pt.getNumberOfReplicas(inputFileStringMPI)){
      Simulation sim(inputFileString.c_str(), multisim);
      sim.RunSimulation();
      PrintSimulationFooter();
    }
#else
    Simulation sim(inputFileString.c_str());
    sim.RunSimulation();
    PrintSimulationFooter();
    delete multisim;
#endif
  }
  #if GOMC_LIB_MPI
    MPI_Finalize();
    //std::cout.rdbuf(savedCOUT); //reset to standard output again
  #endif
  return 0;
}

namespace
{

void PrintSimulationHeader()
{
  std::cout << PrintVersion << '\n'
            << "Info: Start Time: " << PrintTime
#ifdef HOSTNAME
            << "Info: Host Name: " << PrintHostname
#endif
            << "\n";
}

bool CheckAndPrintEnsemble()
{
  bool healthy = true;
  std::cout << "Info: GOMC COMPILED TO RUN ";
#if ENSEMBLE == NVT
  std::cout << "CANONICAL (NVT)";
#elif ENSEMBLE == GEMC
  std::cout << "GIBBS";
#elif ENSEMBLE == GCMC
  std::cout << "GRAND CANONICAL";
#elif ENSEMBLE == NPT
  std::cout << "ISOBARIC-ISOTHERMAL";
#else
  std::cerr << "CRITICAL ERROR! Preprocessor value ENSEMBLE is "
            << "invalid or undefined." << std::endl
            << "Code will exit.";
  healthy = false;
#endif
  std::cout << " ENSEMBLE." << std::endl;
  return healthy;
}

void PrintDebugMode()
{
  std::cout << "################################################################################\n";
  std::cout << "########################## RUNNING GOMC IN DEBUG MODE ##########################\n";
  std::cout << "################################################################################\n";
}

void PrintSimulationFooter()
{
  std::cout << PrintVersion << '\n'
            << "Info: Completed at: " << PrintTime
            << "Info: On hostname: " << PrintHostname
            << '\n';
}

std::ostream& PrintVersion(std::ostream& stream)
{
  stream << "Info: GOMC Version " << GOMC_VERSION_MAJOR
         << '.' << GOMC_VERSION_MINOR;
  return stream;
}

std::ostream& PrintTime(std::ostream& stream)
{
  time_t timer;
  time(&timer);
  stream << asctime(localtime(&timer));
  return stream;
}

std::ostream& PrintHostname(std::ostream& stream)
{
#ifdef HOSTNAME
#ifdef _WIN32
  //setup WINSOCK
  WSADATA wsaData;
  WSAStartup(MAKEWORD(2, 0), &wsaData);
#endif

  const int maxNameLength = 80;
  char hostname[maxNameLength];
  gethostname(hostname, maxNameLength);
  //gethostname does not guarantee null termination
  hostname[maxNameLength - 1] = '\0';
  stream << hostname;

#ifdef _WIN32
  //teardown WINSOCK
  WSACleanup();
#endif
#else
  stream << "Info: Hostname Unavailable";
#endif
  return stream;
}

uint ReadNum(char *argv)
{
  uint thread = 0;

  for(uint i = 2; argv[i] != 0; i++) {
    thread = thread * 10 + (argv[i] - '0');
  }

  return thread;
}
}

void PrintHardwareInfo()
{
#ifdef __linux__
  struct sysinfo mem;
  const double megabyte = 1024 * 1024;
  struct utsname name;
  uname(&name);
  printf("CPU information:\n");
  std::cout << std::setprecision(1) << std::fixed;
  std::cout << "Info: Total number of CPUs: " << get_nprocs() << std::endl;
  std::cout << "Info: Total number of CPUs available: " << sysconf(_SC_NPROCESSORS_ONLN) << std::endl;
  std::cout << "Info: Model name:" << std::flush;
  if(system("awk -F: '/model name/ {print $2;exit}' /proc/cpuinfo") == -1)
    std::cout << "Error: Couldn't retrieve CPU information" << std::endl;
  std::cout << "Info: System name: " << name.sysname << std::endl;
  std::cout << "Info: Release: " << name.release << std::endl;
  std::cout << "Info: Version: " << name.version << std::endl;
  std::cout << "Info: Kernel Architecture: " << name.machine << std::endl;
  if(sysinfo(&mem) == 0) {
    std::cout << "Info: Total Ram: " << mem.totalram / megabyte << "MB" << std::endl;
    std::cout << "Info: Used Ram: " << mem.totalram / megabyte - mem.freeram / megabyte << "MB" << std::endl;
  }
  std::cout << "Info: Working in the current directory: " << get_current_dir_name();
  std::cout << std::endl;
#endif
}

#ifdef GOMC_CUDA
void PrintGPUHardwareInfo()
{
  int nDevices;
  int fast = 0;
  int fastIndex = 0;

  cudaGetDeviceCount(&nDevices);

  if(nDevices == 0) {
    printf("There are no available device(s) that support CUDA\n");
    exit(EXIT_FAILURE);
  }

  if(nDevices <= 4) {
    printf("GPU information:\n");
    for (int i = 0; i < nDevices; i++) {
      cudaDeviceProp prop;
      cudaGetDeviceProperties(&prop, i);
      printf("Info: Device Number: %d\n", i);
      printf("Info: Device name: %s\n", prop.name);
      printf("Info: Memory Clock Rate (KHz): %d\n", prop.memoryClockRate);
      printf("Info: Memory Bus Width (bits): %d\n", prop.memoryBusWidth);
      printf("Info: Peak Memory Bandwidth (GB/s): %f\n",
             2.0 * prop.memoryClockRate * (prop.memoryBusWidth / 8) / 1.0e6);
      if( prop.memoryClockRate > fast) {
        fast =  prop.memoryClockRate;
        fastIndex = i;
      }
    }
  }
  cudaSetDevice(fastIndex);
  printf("Info: Using Device Number: %d\n", fastIndex);
}
#endif
<commit_msg>Delete multisim only if created in MPI macro<commit_after>/*******************************************************************************
GPU OPTIMIZED MONTE CARLO (GOMC) 2.40
Copyright (C) 2018  GOMC Group
A copy of the GNU General Public License can be found in the COPYRIGHT.txt
along with this program, also can be found at <http://www.gnu.org/licenses/>.
********************************************************************************/
#include "Simulation.h"
#include "GOMC_Config.h"    //For version number
#if GOMC_LIB_MPI
#include <mpi.h>
#include "ParallelTemperingPreprocessor.h"
#endif
#ifdef GOMC_CUDA
#include "cuda.h"
#include <cuda_runtime_api.h>
#endif
#include <iostream>
#include <ctime>

//find and include appropriate files for getHostname
#ifdef _WIN32
#include <Winsock2.h>
#define HOSTNAME
#elif defined(__linux__) || defined(__apple__) || defined(__FreeBSD__)
#include <unistd.h>
#include <sys/sysinfo.h>
#include <sys/utsname.h>
#define HOSTNAME
#endif

namespace
{
std::ostream& PrintTime(std::ostream& stream);
std::ostream& PrintHostname(std::ostream& stream);
std::ostream& PrintVersion(std::ostream& stream);
void PrintSimulationHeader();
void PrintSimulationFooter();
void PrintDebugMode();
bool CheckAndPrintEnsemble();
uint ReadNum(char *argv);
}

void PrintHardwareInfo();
#ifdef GOMC_CUDA
void PrintGPUHardwareInfo();
#endif

int main(int argc, char *argv[])
{
#if GOMC_LIB_MPI
  string inputFileStringMPI;
  fstream inputFileReaderMPI;
  MultiSim * multisim;
  int worldSize;
  int worldRank;
  ParallelTemperingPreprocessor pt;

  //std::streambuf * savedCOUT;
  //CHECK IF ARGS/FILE PROVIDED IN CMD LINE
  if (argc < 2) {
    std::cout << "Error: Input parameter file (*.dat or *.conf) not specified on command line!\n";
    exit(EXIT_FAILURE);
  } else {
    if(argc == 2) {
      //FIRST PARAMETER WILL BE FILE NAME
      inputFileStringMPI = argv[1];
    } else {
      //SECOND PARAMETER WILL BE FILE NAME
      inputFileStringMPI = argv[2];

      if(argv[1][0] == '+' && argv[1][1] == 'p') {
      // placeholder
      } else {
        std::cout << "Error: Undefined command to set number of threads!\n";
        std::cout << "Use +p# command to set number of threads.\n";
        exit(EXIT_FAILURE);
      }
    }

    //OPEN FILE
    inputFileReaderMPI.open(inputFileStringMPI.c_str(), ios::in | ios::out);

    //CHECK IF FILE IS OPENED...IF NOT OPENED EXCEPTION REASON FIRED
    if (!inputFileReaderMPI.is_open()) {
      std::cout << "Error: Cannot open/find " << inputFileStringMPI <<
                " in the directory provided!\n";
      exit(EXIT_FAILURE);
    }

    //CLOSE FILE TO NOW PASS TO SIMULATION
    inputFileReaderMPI.close();

    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    // Get the number of processes
    MPI_Comm_size(MPI_COMM_WORLD, &worldSize);

    // Get the rank of the process
    MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);

    std::string pathToReplicaDirectory;
    if(pt.checkIfParallelTempering(inputFileStringMPI)){
      pt.checkIfValid(inputFileStringMPI);
      if(worldSize > pt.getNumberOfReplicas(inputFileStringMPI)){
        std::cout << "You may not request more processes (" << worldSize
          << ") than there are replicas(" << pt.getNumberOfReplicas(inputFileStringMPI) << ")! Exiting!\n";
      } else {
        #if ENSEMBLE == GCMC
        pathToReplicaDirectory = pt.setupReplicaDirectoriesAndRedirectSTDOUTToFile  ( pt.getMultiSimFolderName(inputFileStringMPI).c_str(),
                                                                                pt.getTemperature(inputFileStringMPI.c_str(), worldRank).c_str(),
                                                                                pt.getChemicalPotential(inputFileStringMPI.c_str(), worldRank).c_str()
                                                                                );
        #else
        pathToReplicaDirectory = pt.setupReplicaDirectoriesAndRedirectSTDOUTToFile  ( pt.getMultiSimFolderName(inputFileStringMPI).c_str(),
                                                                                pt.getTemperature(inputFileStringMPI.c_str(), worldRank).c_str()
                                                                                );
        #endif
        multisim = new MultiSim(worldSize, worldRank, pathToReplicaDirectory);
      }
    }
  }
#endif
#ifndef NDEBUG
  PrintDebugMode();
#endif
  PrintSimulationHeader();
  PrintHardwareInfo();
#ifdef GOMC_CUDA
  PrintGPUHardwareInfo();
#endif
  //Only run if valid ensemble was detected.
  if (CheckAndPrintEnsemble()) {
    //FOLLOWING LINES ADDED TO OBTAIN INPUT PARAMETER FILE
    string inputFileString;
    fstream inputFileReader;
    uint numThreads;

    //CHECK IF ARGS/FILE PROVIDED IN CMD LINE
    if (argc < 2) {
      std::cout << "Error: Input parameter file (*.dat or *.conf) not specified on command line!\n";
      exit(EXIT_FAILURE);
    } else {
      if(argc == 2) {
        //FIRST PARAMETER WILL BE FILE NAME
        inputFileString = argv[1];
        numThreads = 1;
      } else {
        //SECOND PARAMETER WILL BE FILE NAME
        inputFileString = argv[2];

        if(argv[1][0] == '+' && argv[1][1] == 'p') {
          numThreads = ReadNum(argv[1]);
        } else {
          std::cout << "Error: Undefined command to set number of threads!\n";
          std::cout << "Use +p# command to set number of threads.\n";
          exit(EXIT_FAILURE);
        }

      }
    }

    //SET NUMBER OF THREADS
#ifdef _OPENMP
    omp_set_num_threads(numThreads);
    printf("%-40s %-d \n", "Info: Number of threads", numThreads);
#else
    printf("%-40s %-d \n", "Info: Number of threads", 1);
#endif

    //OPEN FILE
    inputFileReader.open(inputFileString.c_str(), ios::in | ios::out);

    //CHECK IF FILE IS OPENED...IF NOT OPENED EXCEPTION REASON FIRED
    if (!inputFileReader.is_open()) {
      std::cout << "Error: Cannot open/find " << inputFileString <<
                " in the directory provided!\n";
      exit(EXIT_FAILURE);
    }

    //CLOSE FILE TO NOW PASS TO SIMULATION
    inputFileReader.close();

    //ONCE FILE FOUND PASS STRING TO SIMULATION CLASS TO READ AND
    //HANDLE PDB|PSF FILE
#if GOMC_LIB_MPI
    if(worldSize <= pt.getNumberOfReplicas(inputFileStringMPI)){
      Simulation sim(inputFileString.c_str(), multisim);
      sim.RunSimulation();
      PrintSimulationFooter();
      delete multisim;
    }
#else
    Simulation sim(inputFileString.c_str());
    sim.RunSimulation();
    PrintSimulationFooter();
#endif
  }
  #if GOMC_LIB_MPI
    MPI_Finalize();
    //std::cout.rdbuf(savedCOUT); //reset to standard output again
  #endif
  return 0;
}

namespace
{

void PrintSimulationHeader()
{
  std::cout << PrintVersion << '\n'
            << "Info: Start Time: " << PrintTime
#ifdef HOSTNAME
            << "Info: Host Name: " << PrintHostname
#endif
            << "\n";
}

bool CheckAndPrintEnsemble()
{
  bool healthy = true;
  std::cout << "Info: GOMC COMPILED TO RUN ";
#if ENSEMBLE == NVT
  std::cout << "CANONICAL (NVT)";
#elif ENSEMBLE == GEMC
  std::cout << "GIBBS";
#elif ENSEMBLE == GCMC
  std::cout << "GRAND CANONICAL";
#elif ENSEMBLE == NPT
  std::cout << "ISOBARIC-ISOTHERMAL";
#else
  std::cerr << "CRITICAL ERROR! Preprocessor value ENSEMBLE is "
            << "invalid or undefined." << std::endl
            << "Code will exit.";
  healthy = false;
#endif
  std::cout << " ENSEMBLE." << std::endl;
  return healthy;
}

void PrintDebugMode()
{
  std::cout << "################################################################################\n";
  std::cout << "########################## RUNNING GOMC IN DEBUG MODE ##########################\n";
  std::cout << "################################################################################\n";
}

void PrintSimulationFooter()
{
  std::cout << PrintVersion << '\n'
            << "Info: Completed at: " << PrintTime
            << "Info: On hostname: " << PrintHostname
            << '\n';
}

std::ostream& PrintVersion(std::ostream& stream)
{
  stream << "Info: GOMC Version " << GOMC_VERSION_MAJOR
         << '.' << GOMC_VERSION_MINOR;
  return stream;
}

std::ostream& PrintTime(std::ostream& stream)
{
  time_t timer;
  time(&timer);
  stream << asctime(localtime(&timer));
  return stream;
}

std::ostream& PrintHostname(std::ostream& stream)
{
#ifdef HOSTNAME
#ifdef _WIN32
  //setup WINSOCK
  WSADATA wsaData;
  WSAStartup(MAKEWORD(2, 0), &wsaData);
#endif

  const int maxNameLength = 80;
  char hostname[maxNameLength];
  gethostname(hostname, maxNameLength);
  //gethostname does not guarantee null termination
  hostname[maxNameLength - 1] = '\0';
  stream << hostname;

#ifdef _WIN32
  //teardown WINSOCK
  WSACleanup();
#endif
#else
  stream << "Info: Hostname Unavailable";
#endif
  return stream;
}

uint ReadNum(char *argv)
{
  uint thread = 0;

  for(uint i = 2; argv[i] != 0; i++) {
    thread = thread * 10 + (argv[i] - '0');
  }

  return thread;
}
}

void PrintHardwareInfo()
{
#ifdef __linux__
  struct sysinfo mem;
  const double megabyte = 1024 * 1024;
  struct utsname name;
  uname(&name);
  printf("CPU information:\n");
  std::cout << std::setprecision(1) << std::fixed;
  std::cout << "Info: Total number of CPUs: " << get_nprocs() << std::endl;
  std::cout << "Info: Total number of CPUs available: " << sysconf(_SC_NPROCESSORS_ONLN) << std::endl;
  std::cout << "Info: Model name:" << std::flush;
  if(system("awk -F: '/model name/ {print $2;exit}' /proc/cpuinfo") == -1)
    std::cout << "Error: Couldn't retrieve CPU information" << std::endl;
  std::cout << "Info: System name: " << name.sysname << std::endl;
  std::cout << "Info: Release: " << name.release << std::endl;
  std::cout << "Info: Version: " << name.version << std::endl;
  std::cout << "Info: Kernel Architecture: " << name.machine << std::endl;
  if(sysinfo(&mem) == 0) {
    std::cout << "Info: Total Ram: " << mem.totalram / megabyte << "MB" << std::endl;
    std::cout << "Info: Used Ram: " << mem.totalram / megabyte - mem.freeram / megabyte << "MB" << std::endl;
  }
  std::cout << "Info: Working in the current directory: " << get_current_dir_name();
  std::cout << std::endl;
#endif
}

#ifdef GOMC_CUDA
void PrintGPUHardwareInfo()
{
  int nDevices;
  int fast = 0;
  int fastIndex = 0;

  cudaGetDeviceCount(&nDevices);

  if(nDevices == 0) {
    printf("There are no available device(s) that support CUDA\n");
    exit(EXIT_FAILURE);
  }

  if(nDevices <= 4) {
    printf("GPU information:\n");
    for (int i = 0; i < nDevices; i++) {
      cudaDeviceProp prop;
      cudaGetDeviceProperties(&prop, i);
      printf("Info: Device Number: %d\n", i);
      printf("Info: Device name: %s\n", prop.name);
      printf("Info: Memory Clock Rate (KHz): %d\n", prop.memoryClockRate);
      printf("Info: Memory Bus Width (bits): %d\n", prop.memoryBusWidth);
      printf("Info: Peak Memory Bandwidth (GB/s): %f\n",
             2.0 * prop.memoryClockRate * (prop.memoryBusWidth / 8) / 1.0e6);
      if( prop.memoryClockRate > fast) {
        fast =  prop.memoryClockRate;
        fastIndex = i;
      }
    }
  }
  cudaSetDevice(fastIndex);
  printf("Info: Using Device Number: %d\n", fastIndex);
}
#endif
<|endoftext|>


<commit_before>#include "MemoryManager.h"
#include "LuaManager.h"
#include "MongoManager.h"
#include "CliArgs.h"
#include <iostream> //getline
//#include <conio.h> //_kbhit

#define LUA_DB_VERSION "0.1.0.0"

int run(int argc, char* argv[]) {
	CliArgs args;
	CliArgs::parse(argc, argv, &args);
	const String uri = MongoManager::getUri(args.host, args.port);

	args.database = "test";

	printf("LuaDB shell version: %s\n", LUA_DB_VERSION);
	if (args.database.size()) {
		printf("Connecting to : %s/%s\n", uri.c_str(), args.database.c_str());
	}
	else {
		printf("Connecting to : %s\n", uri.c_str());
	}

	LuaManager *pLua = LuaManager::getInstance();

	bson_t reply;
	if (!pLua->getMongo()->connect(uri, &reply)) {
		printf("Error: couldn't connect to server, connection attempt failed\n");
		return -1;
	}

	bson_iter_t it;
	if (bson_iter_init_find(&it, &reply, "version")) {
		printf("MongoDB server version: %s\n", bson_iter_utf8(&it, nullptr));
	}
	bson_destroy(&reply);

	if (args.database.size()) {
		pLua->useDatabase(args.database);
	}

//	pLua->loadFile("../test/test_bsonTypes.lua");
//	pLua->loadFile("../test/test_crud.lua");
	//pLua->loadFile("../test/performance.lua");

	if (args.files.size()) {
		for (int i = 0; i < args.files.size(); ++i) {
			printf("\nLoading file: %s\n\n", args.files[i].c_str());
			pLua->loadFile(args.files[i]);
		}
		if (args.shell) {
			printf("\n");
		}
		pLua->setIsRunning(args.shell);
	}

	if (pLua->isRunning()) {
		printf("Type \"help()\" for help\n");
		while (pLua->isRunning()) {
			printf("> ");
			String commandStr;
			String inputStr;
			if (std::getline(std::cin, inputStr)) {
				commandStr += inputStr;
//				while (_kbhit()) {
//					printf("... ");
//					std::getline(std::cin, inputStr);
//					commandStr += inputStr + "\n";
//				}
			}
			if (!commandStr.empty()) {
				pLua->loadString(commandStr.c_str());
			}
		}
	}

	return 0;
}

int main(int argc, char* argv[]) {
	run(argc, argv);
	LuaManager::destroyInstance();
	#ifdef DEBUG_MEMORY
		if (MemoryManager::getInstance()->hasLeak()) {
			printf("\n");
			MemoryManager::getInstance()->displayInfo();
			getchar();
			return 1;
		}
	#endif
	return 0;
}<commit_msg>Disable print buf so that lua script doest block print to terminal<commit_after>#include "MemoryManager.h"
#include "LuaManager.h"
#include "MongoManager.h"
#include "CliArgs.h"
#include <iostream> //getline
//#include <conio.h> //_kbhit

#define LUA_DB_VERSION "0.1.0.0"

int run(int argc, char* argv[]) {
    CliArgs args;
    CliArgs::parse(argc, argv, &args);
    const String uri = MongoManager::getUri(args.host, args.port);

    args.database = "test";

    printf("LuaDB shell version: %s\n", LUA_DB_VERSION);
    if (args.database.size()) {
        printf("Connecting to : %s/%s\n", uri.c_str(), args.database.c_str());
    }
    else {
        printf("Connecting to : %s\n", uri.c_str());
    }

    LuaManager* pLua = LuaManager::getInstance();

    bson_t reply;
    if (!pLua->getMongo()->connect(uri, &reply)) {
        printf("Error: couldn't connect to server, connection attempt failed\n");
        return -1;
    }

    bson_iter_t it;
    if (bson_iter_init_find(&it, &reply, "version")) {
        printf("MongoDB server version: %s\n", bson_iter_utf8(&it, nullptr));
    }
    bson_destroy(&reply);

    if (args.database.size()) {
        pLua->useDatabase(args.database);
    }

    //	pLua->loadFile("../test/test_bsonTypes.lua");
    //	pLua->loadFile("../test/test_crud.lua");
        //pLua->loadFile("../test/performance.lua");

    //    fflush(stdout);

    if (args.files.size()) {

 /*       printf("111111");
        fflush(stdout);*/

        for (int i = 0; i < args.files.size(); ++i) {
            printf("\nLoading file: %s\n\n", args.files[i].c_str());
            pLua->loadFile(args.files[i]);
        }

     /*   printf("222222");
        fflush(stdout);*/

        if (args.shell) {
            printf("\n");
            //fflush(stdout);
        }
        pLua->setIsRunning(args.shell);
    }

    if (pLua->isRunning()) {
        printf("Type \"help()\" for help\n");
        while (pLua->isRunning()) {
            printf("> ");
            String commandStr;
            String inputStr;
            if (std::getline(std::cin, inputStr)) {
                commandStr += inputStr;
                //				while (_kbhit()) {
                //					printf("... ");
                //					std::getline(std::cin, inputStr);
                //					commandStr += inputStr + "\n";
                //				}
            }
            if (!commandStr.empty()) {
                pLua->loadString(commandStr.c_str());
            }
        }
    }

    return 0;
}

int main(int argc, char* argv[]) {
    //Disable print buffer
    setvbuf(stdout, NULL, _IONBF, BUFSIZ);

    run(argc, argv);
    LuaManager::destroyInstance();
#ifdef DEBUG_MEMORY
    if (MemoryManager::getInstance()->hasLeak()) {
        printf("\n");
        MemoryManager::getInstance()->displayInfo();
        getchar();
        return 1;
    }
#endif
    //getchar();
    return 0;
}<|endoftext|>


<commit_before>#pragma once

#include <El.hpp>

#include <array>
#include <memory>
#include <iostream>

struct Mesh
{
  std::array<El::BigFloat, 5> x, f;
  std::unique_ptr<Mesh> lower, upper;

  Mesh(const El::BigFloat &x_0, const El::BigFloat &x_3,
       const El::BigFloat &x_5, const El::BigFloat &f_0,
       const El::BigFloat &f_3, const El::BigFloat &f_5,
       const std::function<El::BigFloat(const El::BigFloat &x)> &fn,
       const El::BigFloat &epsilon,
       const El::BigFloat &block_epsilon);

  Mesh(const El::BigFloat &x_0, const El::BigFloat &x_5,
       const std::function<El::BigFloat(const El::BigFloat &x)> &fn,
       const El::BigFloat &epsilon,
       const El::BigFloat &block_epsilon)
      : Mesh(x_0, (x_0 + x_5) / 2, x_5, fn(x_0), fn((x_0 + x_5) / 2), fn(x_5),
             fn, epsilon, block_epsilon)
  {}
};

std::ostream & operator<<(std::ostream &os, const Mesh &mesh);
<commit_msg>Fix confusing names<commit_after>#pragma once

#include <El.hpp>

#include <array>
#include <memory>
#include <iostream>

struct Mesh
{
  std::array<El::BigFloat, 5> x, f;
  std::unique_ptr<Mesh> lower, upper;

  Mesh(const El::BigFloat &x_0, const El::BigFloat &x_2,
       const El::BigFloat &x_4, const El::BigFloat &f_0,
       const El::BigFloat &f_2, const El::BigFloat &f_4,
       const std::function<El::BigFloat(const El::BigFloat &x)> &fn,
       const El::BigFloat &epsilon,
       const El::BigFloat &block_epsilon);

  Mesh(const El::BigFloat &x_0, const El::BigFloat &x_4,
       const std::function<El::BigFloat(const El::BigFloat &x)> &fn,
       const El::BigFloat &epsilon,
       const El::BigFloat &block_epsilon)
      : Mesh(x_0, (x_0 + x_4) / 2, x_4, fn(x_0), fn((x_0 + x_4) / 2), fn(x_4),
             fn, epsilon, block_epsilon)
  {}
};

std::ostream & operator<<(std::ostream &os, const Mesh &mesh);
<|endoftext|>


<commit_before>//
// Copyright 2016 Giovanni Mels
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef N3_MODEL_HH
#define N3_MODEL_HH

#include <cstddef>
#include <string>
#include <ostream>
#include <vector>

#include <utility> // std::move

#include <iostream>

namespace turtle {

	class URIResource;
	class BlankNode;
	class RDFList;
	class Literal;
	class BooleanLiteral;
	class IntegerLiteral;
	class DoubleLiteral;
	class DecimalLiteral;
	class StringLiteral;

	template<typename T>
	struct Cloneable {
		Cloneable() = default;
		Cloneable(const Cloneable &c) = default;
		Cloneable(Cloneable &&c) = default;
		Cloneable &operator=(const Cloneable &c) = default;
		Cloneable &operator=(Cloneable &&c) = default;
		virtual T *clone() const = 0;
		virtual ~Cloneable() = default;
	};

	struct N3NodeVisitor {
		virtual void visit(const URIResource &resource) = 0;
		virtual void visit(const BlankNode &blankNode) = 0;
		virtual void visit(const Literal &literal) = 0;
		virtual void visit(const RDFList &list) = 0;
		virtual void visit(const BooleanLiteral &literal) = 0;
		virtual void visit(const IntegerLiteral &literal) = 0;
		virtual void visit(const DoubleLiteral &literal) = 0;
		virtual void visit(const DecimalLiteral &literal) = 0;
		virtual void visit(const StringLiteral &literal) = 0;
		virtual ~N3NodeVisitor() {}
	};

	struct N3Node : public Cloneable<N3Node> {
		/*N3Node() = default;
		N3Node(const N3Node &c) = default;
		N3Node(N3Node &&c) = default;
		N3Node &operator=(const N3Node &c) = default;
		N3Node &operator=(N3Node &&c) = default;*/
		virtual std::ostream &print(std::ostream &out) const = 0;
		virtual void visit(N3NodeVisitor &visitor) const = 0;
		//virtual ~N3Node() = default;
	};

	std::ostream &operator<<(std::ostream &out, const N3Node &n);

	struct Resource : public N3Node {

		virtual Resource *clone() const = 0;

	};

	class URIResource : public Resource {
		std::string m_uri;
	public:
		explicit URIResource(const std::string &uri) : Resource(), m_uri(uri) {}
		explicit URIResource(std::string &&uri)      : Resource(), m_uri(std::move(uri)) {}

		const std::string &uri() const { return m_uri; }

		std::ostream &print(std::ostream &out) const
		{
			out << '<' << m_uri << '>';

			return out;
		}

		URIResource *clone() const
		{
			return new URIResource(m_uri);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}

	};

	class BlankNode : public Resource {
		std::string m_id;
	public:
		explicit BlankNode(const std::string &id) : Resource(), m_id(id) {}
		explicit BlankNode(std::string &&id)      : Resource(), m_id(std::move(id)) {}

		const std::string &id() const { return m_id; }

		std::ostream &print(std::ostream &out) const
		{
			out << "_:b" << m_id;

			return out;
		}

		BlankNode *clone() const
		{
			return new BlankNode(m_id);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class RDFList : public Resource {
		std::vector<N3Node *> m_elements;

		typedef std::vector<N3Node *>::iterator iterator;
		typedef std::vector<N3Node *>::const_iterator const_iterator;

	public:
		RDFList() : m_elements() {}

		RDFList(const RDFList &list) : RDFList()
		{
			m_elements.reserve(list.m_elements.size());
			for (N3Node *n : list.m_elements) {
				m_elements.push_back(n->clone());
			}
		}

		RDFList(RDFList &&list) : RDFList()
		{
			std::swap(list.m_elements, m_elements);
		}

		RDFList& operator=(RDFList list)
		{
			std::swap(list.m_elements, m_elements);

			return *this;
		}

		RDFList& operator=(RDFList &&list) // TODO correct?
		{
			std::swap(list.m_elements, m_elements);

			return *this;
		}

		~RDFList()
		{
			for (N3Node *n : m_elements)
				delete n;
		}

		void add(N3Node *element)
		{
			m_elements.push_back(element);
		}

		N3Node *&operator[](std::size_t index)
		{
			return m_elements[index];
		}

		N3Node * const &operator[](std::size_t index) const
		{
			return m_elements[index];
		}

		std::size_t size() const
		{
			return m_elements.size();
		}

		iterator begin()
		{
			return m_elements.begin();
		}

		iterator end()
		{
			return m_elements.end();
		}

		const_iterator begin() const
		{
			return m_elements.begin();
		}

		const_iterator end() const
		{
			return m_elements.end();
		}

		bool empty() const
		{
			return m_elements.empty();
		}

		std::ostream &print(std::ostream &out) const
		{
			out << '(';

			for (N3Node *n : m_elements)
				out << ' ' << *n;

			out << ')';

			return out;
		}

		RDFList *clone() const
		{
			return new RDFList(*this);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}

	};

	class Literal : public N3Node {
	protected:
		std::string m_lexical;
		const std::string *m_datatype;

		Literal(const std::string &lexical, const std::string *datatype) : N3Node(), m_lexical(lexical), m_datatype(datatype) {}
		Literal(std::string &&lexical, const std::string *datatype)      : N3Node(), m_lexical(std::move(lexical)), m_datatype(datatype) {}

	public:

		const std::string &lexical() const { return m_lexical; }

		const std::string &datatype() const { return *m_datatype; }

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}

	};

	class BooleanLiteral : public Literal {
	public:
		explicit BooleanLiteral(const std::string &value) : Literal(value, &TYPE) {}

		static const std::string TYPE;

		static const BooleanLiteral VALUE_TRUE;
		static const BooleanLiteral VALUE_FALSE;
		static const BooleanLiteral VALUE_1;
		static const BooleanLiteral VALUE_0;

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		bool value() const { return m_lexical == VALUE_TRUE.m_lexical || m_lexical == "1"; }

		BooleanLiteral *clone() const
		{
			return new BooleanLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class IntegerLiteral : public Literal {
	public:
		static const std::string TYPE;

		explicit IntegerLiteral(const std::string &value) : Literal(value, &TYPE) {}

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		IntegerLiteral *clone() const
		{
			return new IntegerLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class DoubleLiteral : public Literal {
	public:
		static const std::string TYPE;

		explicit DoubleLiteral(const std::string &value) : Literal(value, &TYPE) {}

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		DoubleLiteral *clone() const
		{
			return new DoubleLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class DecimalLiteral : public Literal {
	public:
		static const std::string TYPE;

		explicit DecimalLiteral(const std::string &value) : Literal(value, &TYPE) {}

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		DecimalLiteral *clone() const
		{
			return new DecimalLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class StringLiteral : public Literal {

		std::string m_language;
	public:
		static const std::string TYPE;

		explicit StringLiteral(const std::string &value, const std::string &language = std::string()) : Literal(value, &TYPE), m_language(language) {}
		explicit StringLiteral(std::string &&value, std::string &&language = std::string()) : Literal(std::move(value), &TYPE), m_language(std::move(language)) {}

		const std::string &language() const { return m_language; }

		std::ostream &print(std::ostream &out) const
		{
			out << '"' << lexical() << '"';

			if (!language().empty())
				out << '@' << language();

			return out;
		}

		StringLiteral *clone() const
		{
			return new StringLiteral(m_lexical, m_language);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class OtherLiteral : public Literal { /* keeps a copy of the type uri */

		std::string m_datatype_copy;

	public:

		explicit OtherLiteral(const std::string &value, const std::string &datatype) : Literal(value, nullptr), m_datatype_copy(datatype)
		{
			m_datatype = &m_datatype_copy;
		}

		explicit OtherLiteral(std::string &&value, std::string &&datatype) : Literal(std::move(value), nullptr), m_datatype_copy(std::move(datatype))
		{
			m_datatype = &m_datatype_copy;
		}

		OtherLiteral(const OtherLiteral &other) : Literal(other.m_lexical, nullptr), m_datatype_copy(other.m_datatype_copy)
		{
			m_datatype = &m_datatype_copy;
		}

		OtherLiteral(OtherLiteral &&other) : Literal(other.m_lexical, nullptr), m_datatype_copy(other.m_datatype_copy)
		{
			m_datatype = &m_datatype_copy;
		}

		OtherLiteral& operator=(OtherLiteral other)
		{
			std::swap(m_lexical, other.m_lexical);
			std::swap(m_datatype, other.m_datatype);

			m_datatype = &m_datatype_copy;

			return *this;
		}

		OtherLiteral& operator=(OtherLiteral &&other)
		{
			std::swap(m_lexical, other.m_lexical);
			std::swap(m_datatype, other.m_datatype);

			m_datatype = &m_datatype_copy;

			return *this;
		}

		std::ostream &print(std::ostream &out) const
		{
			out << '"' << lexical() << '"' << '@' << '<' << datatype() << '>';

			return out;
		}

		OtherLiteral *clone() const
		{
			return new OtherLiteral(m_lexical, m_datatype_copy);
		}
	};

	struct RDF {
		static const std::string NS;

		static const URIResource type;
		static const URIResource first;
		static const URIResource rest;
		static const URIResource nil;
	};

	struct XSD {
		static const std::string NS;
	};

}

#endif /* N3_MODEL_HH */
<commit_msg>Removed unused include.<commit_after>//
// Copyright 2016 Giovanni Mels
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef N3_MODEL_HH
#define N3_MODEL_HH

#include <cstddef>
#include <string>
#include <ostream>
#include <vector>
#include <utility>

namespace turtle {

	class URIResource;
	class BlankNode;
	class RDFList;
	class Literal;
	class BooleanLiteral;
	class IntegerLiteral;
	class DoubleLiteral;
	class DecimalLiteral;
	class StringLiteral;

	template<typename T>
	struct Cloneable {
		Cloneable() = default;
		Cloneable(const Cloneable &c) = default;
		Cloneable(Cloneable &&c) = default;
		Cloneable &operator=(const Cloneable &c) = default;
		Cloneable &operator=(Cloneable &&c) = default;
		virtual T *clone() const = 0;
		virtual ~Cloneable() = default;
	};

	struct N3NodeVisitor {
		virtual void visit(const URIResource &resource) = 0;
		virtual void visit(const BlankNode &blankNode) = 0;
		virtual void visit(const Literal &literal) = 0;
		virtual void visit(const RDFList &list) = 0;
		virtual void visit(const BooleanLiteral &literal) = 0;
		virtual void visit(const IntegerLiteral &literal) = 0;
		virtual void visit(const DoubleLiteral &literal) = 0;
		virtual void visit(const DecimalLiteral &literal) = 0;
		virtual void visit(const StringLiteral &literal) = 0;
		virtual ~N3NodeVisitor() {}
	};

	struct N3Node : public Cloneable<N3Node> {
		/*N3Node() = default;
		N3Node(const N3Node &c) = default;
		N3Node(N3Node &&c) = default;
		N3Node &operator=(const N3Node &c) = default;
		N3Node &operator=(N3Node &&c) = default;*/
		virtual std::ostream &print(std::ostream &out) const = 0;
		virtual void visit(N3NodeVisitor &visitor) const = 0;
		//virtual ~N3Node() = default;
	};

	std::ostream &operator<<(std::ostream &out, const N3Node &n);

	struct Resource : public N3Node {

		virtual Resource *clone() const = 0;

	};

	class URIResource : public Resource {
		std::string m_uri;
	public:
		explicit URIResource(const std::string &uri) : Resource(), m_uri(uri) {}
		explicit URIResource(std::string &&uri)      : Resource(), m_uri(std::move(uri)) {}

		const std::string &uri() const { return m_uri; }

		std::ostream &print(std::ostream &out) const
		{
			out << '<' << m_uri << '>';

			return out;
		}

		URIResource *clone() const
		{
			return new URIResource(m_uri);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}

	};

	class BlankNode : public Resource {
		std::string m_id;
	public:
		explicit BlankNode(const std::string &id) : Resource(), m_id(id) {}
		explicit BlankNode(std::string &&id)      : Resource(), m_id(std::move(id)) {}

		const std::string &id() const { return m_id; }

		std::ostream &print(std::ostream &out) const
		{
			out << "_:b" << m_id;

			return out;
		}

		BlankNode *clone() const
		{
			return new BlankNode(m_id);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class RDFList : public Resource {
		std::vector<N3Node *> m_elements;

		typedef std::vector<N3Node *>::iterator iterator;
		typedef std::vector<N3Node *>::const_iterator const_iterator;

	public:
		RDFList() : m_elements() {}

		RDFList(const RDFList &list) : RDFList()
		{
			m_elements.reserve(list.m_elements.size());
			for (N3Node *n : list.m_elements) {
				m_elements.push_back(n->clone());
			}
		}

		RDFList(RDFList &&list) : RDFList()
		{
			std::swap(list.m_elements, m_elements);
		}

		RDFList& operator=(RDFList list)
		{
			std::swap(list.m_elements, m_elements);

			return *this;
		}

		RDFList& operator=(RDFList &&list) // TODO correct?
		{
			std::swap(list.m_elements, m_elements);

			return *this;
		}

		~RDFList()
		{
			for (N3Node *n : m_elements)
				delete n;
		}

		void add(N3Node *element)
		{
			m_elements.push_back(element);
		}

		N3Node *&operator[](std::size_t index)
		{
			return m_elements[index];
		}

		N3Node * const &operator[](std::size_t index) const
		{
			return m_elements[index];
		}

		std::size_t size() const
		{
			return m_elements.size();
		}

		iterator begin()
		{
			return m_elements.begin();
		}

		iterator end()
		{
			return m_elements.end();
		}

		const_iterator begin() const
		{
			return m_elements.begin();
		}

		const_iterator end() const
		{
			return m_elements.end();
		}

		bool empty() const
		{
			return m_elements.empty();
		}

		std::ostream &print(std::ostream &out) const
		{
			out << '(';

			for (N3Node *n : m_elements)
				out << ' ' << *n;

			out << ')';

			return out;
		}

		RDFList *clone() const
		{
			return new RDFList(*this);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}

	};

	class Literal : public N3Node {
	protected:
		std::string m_lexical;
		const std::string *m_datatype;

		Literal(const std::string &lexical, const std::string *datatype) : N3Node(), m_lexical(lexical), m_datatype(datatype) {}
		Literal(std::string &&lexical, const std::string *datatype)      : N3Node(), m_lexical(std::move(lexical)), m_datatype(datatype) {}

	public:

		const std::string &lexical() const { return m_lexical; }

		const std::string &datatype() const { return *m_datatype; }

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}

	};

	class BooleanLiteral : public Literal {
	public:
		explicit BooleanLiteral(const std::string &value) : Literal(value, &TYPE) {}

		static const std::string TYPE;

		static const BooleanLiteral VALUE_TRUE;
		static const BooleanLiteral VALUE_FALSE;
		static const BooleanLiteral VALUE_1;
		static const BooleanLiteral VALUE_0;

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		bool value() const { return m_lexical == VALUE_TRUE.m_lexical || m_lexical == "1"; }

		BooleanLiteral *clone() const
		{
			return new BooleanLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class IntegerLiteral : public Literal {
	public:
		static const std::string TYPE;

		explicit IntegerLiteral(const std::string &value) : Literal(value, &TYPE) {}

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		IntegerLiteral *clone() const
		{
			return new IntegerLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class DoubleLiteral : public Literal {
	public:
		static const std::string TYPE;

		explicit DoubleLiteral(const std::string &value) : Literal(value, &TYPE) {}

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		DoubleLiteral *clone() const
		{
			return new DoubleLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class DecimalLiteral : public Literal {
	public:
		static const std::string TYPE;

		explicit DecimalLiteral(const std::string &value) : Literal(value, &TYPE) {}

		std::ostream &print(std::ostream &out) const
		{
			out << lexical();

			return out;
		}

		DecimalLiteral *clone() const
		{
			return new DecimalLiteral(m_lexical);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class StringLiteral : public Literal {

		std::string m_language;
	public:
		static const std::string TYPE;

		explicit StringLiteral(const std::string &value, const std::string &language = std::string()) : Literal(value, &TYPE), m_language(language) {}
		explicit StringLiteral(std::string &&value, std::string &&language = std::string()) : Literal(std::move(value), &TYPE), m_language(std::move(language)) {}

		const std::string &language() const { return m_language; }

		std::ostream &print(std::ostream &out) const
		{
			out << '"' << lexical() << '"';

			if (!language().empty())
				out << '@' << language();

			return out;
		}

		StringLiteral *clone() const
		{
			return new StringLiteral(m_lexical, m_language);
		}

		void visit(N3NodeVisitor &visitor) const
		{
			visitor.visit(*this);
		}
	};

	class OtherLiteral : public Literal { /* keeps a copy of the type uri */

		std::string m_datatype_copy;

	public:

		explicit OtherLiteral(const std::string &value, const std::string &datatype) : Literal(value, nullptr), m_datatype_copy(datatype)
		{
			m_datatype = &m_datatype_copy;
		}

		explicit OtherLiteral(std::string &&value, std::string &&datatype) : Literal(std::move(value), nullptr), m_datatype_copy(std::move(datatype))
		{
			m_datatype = &m_datatype_copy;
		}

		OtherLiteral(const OtherLiteral &other) : Literal(other.m_lexical, nullptr), m_datatype_copy(other.m_datatype_copy)
		{
			m_datatype = &m_datatype_copy;
		}

		OtherLiteral(OtherLiteral &&other) : Literal(other.m_lexical, nullptr), m_datatype_copy(other.m_datatype_copy)
		{
			m_datatype = &m_datatype_copy;
		}

		OtherLiteral& operator=(OtherLiteral other)
		{
			std::swap(m_lexical, other.m_lexical);
			std::swap(m_datatype, other.m_datatype);

			m_datatype = &m_datatype_copy;

			return *this;
		}

		OtherLiteral& operator=(OtherLiteral &&other)
		{
			std::swap(m_lexical, other.m_lexical);
			std::swap(m_datatype, other.m_datatype);

			m_datatype = &m_datatype_copy;

			return *this;
		}

		std::ostream &print(std::ostream &out) const
		{
			out << '"' << lexical() << '"' << '@' << '<' << datatype() << '>';

			return out;
		}

		OtherLiteral *clone() const
		{
			return new OtherLiteral(m_lexical, m_datatype_copy);
		}
	};

	struct RDF {
		static const std::string NS;

		static const URIResource type;
		static const URIResource first;
		static const URIResource rest;
		static const URIResource nil;
	};

	struct XSD {
		static const std::string NS;
	};

}

#endif /* N3_MODEL_HH */
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include <algorithm>
#include <cassert>

#include "IECore/ContrastSmoothSkinningWeightsOp.h"

#include "IECore/CompoundObject.h"
#include "IECore/CompoundParameter.h"
#include "IECore/CompressSmoothSkinningDataOp.h"
#include "IECore/DecompressSmoothSkinningDataOp.h"
#include "IECore/Interpolator.h"
#include "IECore/NormalizeSmoothSkinningWeightsOp.h"
#include "IECore/SmoothSkinningData.h"
#include "IECore/SimpleTypedData.h"
#include "IECore/TypedObjectParameter.h"
#include "IECore/Math.h"

using namespace IECore;

IE_CORE_DEFINERUNTIMETYPED( ContrastSmoothSkinningWeightsOp );

ContrastSmoothSkinningWeightsOp::ContrastSmoothSkinningWeightsOp()
	: ModifyOp(
		"The ContrastSmoothSkinningWeightsOp contrasts the weights of SmoothSkinningData by applying a custom step function on the weights. This op does not normalize the weights.",
		new SmoothSkinningDataParameter( "result", "The result", new SmoothSkinningData ),
		new SmoothSkinningDataParameter( "input", "The SmoothSkinningData to modify", new SmoothSkinningData )
	)
{
	m_meshParameter = new MeshPrimitiveParameter(
		"mesh",
		"The mesh primitive corresponding to the input SmoothSkinningData",
		new MeshPrimitive
	);

	m_vertexIdsParameter = new FrameListParameter(
		"vertexIndices",
		"The indices of the vertices to smooth. All vertices will be smoothed if this parameter is empty",
		""
	);

	m_contrastRatioParameter = new FloatParameter(
		"contrastRatio",
		"Controls the level of contrast. Interpolates between linear function and smooth step function.",
		1,
		0.0,
		1.0
	);

	m_contrastCenterParameter = new FloatParameter(
		"contrastCenter",
		"Sets the middle value for the contrast. Weights lower than that will tend zero and the higher ones will tend to one.",
		0.5,
		1e-3,
		1.0 - 1e-3
	);

	m_iterationsParameter = new IntParameter(
		"iterations",
		"The number of iterations to perform the contrast operation.",
		3,
		1
	);

	m_useLocksParameter = new BoolParameter(
		"applyLocks",
		"Whether or not influenceLocks should be applied",
		true
	);

	m_influenceLocksParameter = new BoolVectorParameter(
		"influenceLocks",
		"A per-influence list of lock values",
		new BoolVectorData
	);

	parameters()->addParameter( m_meshParameter );
	parameters()->addParameter( m_vertexIdsParameter );
	parameters()->addParameter( m_contrastRatioParameter );
	parameters()->addParameter( m_contrastCenterParameter );
	parameters()->addParameter( m_iterationsParameter );
	parameters()->addParameter( m_useLocksParameter );
	parameters()->addParameter( m_influenceLocksParameter );
}

ContrastSmoothSkinningWeightsOp::~ContrastSmoothSkinningWeightsOp()
{
}

// Custom smoothstep class. Defines the neutral center point, interpolates it with the linear function and applies multiple iterations.
class ContrastSmoothSkinningWeightsOp::ContrastSmoothStep
{
	public:

		ContrastSmoothStep( int iterations, float ratio, float center ) :
								m_iterations(iterations), m_ratio(ratio), m_center(center)
		{
			m_firstHalfScale = 0.5 / m_center;
			m_secondHalfScale = 0.5 / (1.0 - m_center);
			m_norm = 0.5*m_firstHalfScale+0.5*m_secondHalfScale;
		}

		float operator()( float value )
		{
			float result = value;
			for ( int i = 0; i < m_iterations; i++ )
			{
				if ( result >= m_center )
				{
					result = ((smoothstep(0.0,1.0,(result-m_center)*m_secondHalfScale+0.5) - 0.5) * m_firstHalfScale + m_secondHalfScale*0.5) / m_norm;
				}
				else
				{
					result = (smoothstep(0.0,1.0,(result-m_center)*m_firstHalfScale+0.5) * m_secondHalfScale) / m_norm;
				}
				result = m_ratio*result + (1-m_ratio)*value;
			}
			return result;
		}

	private :

		int m_iterations;
		float m_ratio;
		float m_center;
		float m_firstHalfScale;
		float m_secondHalfScale;
		float m_norm;
};

void ContrastSmoothSkinningWeightsOp::modify( Object * object, const CompoundObject * operands )
{
	SmoothSkinningData *skinningData = static_cast<SmoothSkinningData *>( object );
	assert( skinningData );

	// \todo: remove decompression/compression.
	// decompress
	DecompressSmoothSkinningDataOp decompressionOp;
	decompressionOp.inputParameter()->setValidatedValue( skinningData );
	decompressionOp.copyParameter()->setTypedValue( false );
	decompressionOp.operate();

	const std::vector<int> &pointIndexOffsets = skinningData->pointIndexOffsets()->readable();
	const std::vector<int> &pointInfluenceCounts = skinningData->pointInfluenceCounts()->readable();
	const std::vector<int> &pointInfluenceIndices = skinningData->pointInfluenceIndices()->readable();
	int numSsdVerts = pointIndexOffsets.size();

	std::vector<float> &pointInfluenceWeights = skinningData->pointInfluenceWeights()->writable();

	const MeshPrimitive *mesh = runTimeCast<const MeshPrimitive>( m_meshParameter->getValidatedValue() );
	if ( !mesh )
	{
		throw IECore::Exception( "ContrastSmoothSkinningWeightsOp: The given mesh is not valid" );
	}
	int numMeshVerts = mesh->variableSize( PrimitiveVariable::Vertex );

	// make sure the mesh matches the skinning data
	if ( numMeshVerts != numSsdVerts )
	{
		throw IECore::Exception( "ContrastSmoothSkinningWeightsOp: The input SmoothSkinningData and mesh have a different number of vertices" );
	}

	bool useLocks = m_useLocksParameter->getTypedValue();
	std::vector<bool> &locks = m_influenceLocksParameter->getTypedValue();

	// make sure there is one lock per influence
	if ( useLocks && ( locks.size() != skinningData->influenceNames()->readable().size() ) )
	{
		throw IECore::Exception( "ContrastSmoothSkinningWeightsOp: There must be exactly one lock per influence" );
	}

	if ( !useLocks )
	{
		locks.clear();
		locks.resize( skinningData->influenceNames()->readable().size(), false );
	}

	std::vector<int64_t> vertexIds;
	m_vertexIdsParameter->getFrameListValue()->asList( vertexIds );

	// make sure all vertex ids are valid
	for ( unsigned i=0; i < vertexIds.size(); i++ )
	{
		if ( vertexIds[i] > numSsdVerts )
		{
			throw IECore::Exception( ( boost::format( "ContrastSmoothSkinningWeightsOp: VertexId \"%d\" is outside the range of the SmoothSkinningData and mesh" ) % vertexIds[i] ).str() );
		}
	}

	float contrastRatio = m_contrastRatioParameter->getNumericValue();
	float contrastCenter = m_contrastCenterParameter->getNumericValue();
	int numIterations = m_iterationsParameter->getNumericValue();

	ContrastSmoothStep contrastFunction( numIterations, contrastRatio, contrastCenter );

	// an empty vertexId list means we operate over all vertices
	if ( vertexIds.size() == 0 )
	{
		for ( unsigned int i=0; i < pointInfluenceWeights.size(); i++ )
		{
			unsigned int current = i;
			if ( !locks[ pointInfluenceIndices[current] ] )
			{
				pointInfluenceWeights[current] = contrastFunction( pointInfluenceWeights[ current ] );
			}
		}
	}
	else
	{
		// apply contrast with the per-influence locks
		for ( unsigned i=0; i < vertexIds.size(); i++ )
		{
			int currentVertId = vertexIds[i];
			for ( int j=0; j < pointInfluenceCounts[currentVertId]; j++ )
			{
				int current = pointIndexOffsets[currentVertId] + j;
				if ( !locks[ pointInfluenceIndices[current] ] )
				{
					pointInfluenceWeights[current] = contrastFunction( pointInfluenceWeights[ current ] );
				}
			}
		}
	}

	// re-compress
	CompressSmoothSkinningDataOp compressionOp;
	compressionOp.inputParameter()->setValidatedValue( skinningData );
	compressionOp.copyParameter()->setTypedValue( false );
	compressionOp.operate();
}
<commit_msg>Fixing contrast computation when iterations > 1.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include <algorithm>
#include <cassert>

#include "IECore/ContrastSmoothSkinningWeightsOp.h"

#include "IECore/CompoundObject.h"
#include "IECore/CompoundParameter.h"
#include "IECore/CompressSmoothSkinningDataOp.h"
#include "IECore/DecompressSmoothSkinningDataOp.h"
#include "IECore/Interpolator.h"
#include "IECore/NormalizeSmoothSkinningWeightsOp.h"
#include "IECore/SmoothSkinningData.h"
#include "IECore/SimpleTypedData.h"
#include "IECore/TypedObjectParameter.h"
#include "IECore/Math.h"

using namespace IECore;

IE_CORE_DEFINERUNTIMETYPED( ContrastSmoothSkinningWeightsOp );

ContrastSmoothSkinningWeightsOp::ContrastSmoothSkinningWeightsOp()
	: ModifyOp(
		"The ContrastSmoothSkinningWeightsOp contrasts the weights of SmoothSkinningData by applying a custom step function on the weights. This op does not normalize the weights.",
		new SmoothSkinningDataParameter( "result", "The result", new SmoothSkinningData ),
		new SmoothSkinningDataParameter( "input", "The SmoothSkinningData to modify", new SmoothSkinningData )
	)
{
	m_meshParameter = new MeshPrimitiveParameter(
		"mesh",
		"The mesh primitive corresponding to the input SmoothSkinningData",
		new MeshPrimitive
	);

	m_vertexIdsParameter = new FrameListParameter(
		"vertexIndices",
		"The indices of the vertices to smooth. All vertices will be smoothed if this parameter is empty",
		""
	);

	m_contrastRatioParameter = new FloatParameter(
		"contrastRatio",
		"Controls the level of contrast. Interpolates between linear function and smooth step function.",
		1,
		0.0,
		1.0
	);

	m_contrastCenterParameter = new FloatParameter(
		"contrastCenter",
		"Sets the middle value for the contrast. Weights lower than that will tend zero and the higher ones will tend to one.",
		0.5,
		1e-3,
		1.0 - 1e-3
	);

	m_iterationsParameter = new IntParameter(
		"iterations",
		"The number of iterations to perform the contrast operation.",
		3,
		1
	);

	m_useLocksParameter = new BoolParameter(
		"applyLocks",
		"Whether or not influenceLocks should be applied",
		true
	);

	m_influenceLocksParameter = new BoolVectorParameter(
		"influenceLocks",
		"A per-influence list of lock values",
		new BoolVectorData
	);

	parameters()->addParameter( m_meshParameter );
	parameters()->addParameter( m_vertexIdsParameter );
	parameters()->addParameter( m_contrastRatioParameter );
	parameters()->addParameter( m_contrastCenterParameter );
	parameters()->addParameter( m_iterationsParameter );
	parameters()->addParameter( m_useLocksParameter );
	parameters()->addParameter( m_influenceLocksParameter );
}

ContrastSmoothSkinningWeightsOp::~ContrastSmoothSkinningWeightsOp()
{
}

// Custom smoothstep class. Defines the neutral center point, interpolates it with the linear function and applies multiple iterations.
class ContrastSmoothSkinningWeightsOp::ContrastSmoothStep
{
	public:

		ContrastSmoothStep( int iterations, float ratio, float center ) :
								m_iterations(iterations), m_ratio(ratio), m_center(center)
		{
			m_firstHalfScale = 0.5 / m_center;
			m_secondHalfScale = 0.5 / (1.0 - m_center);
			m_norm = 0.5*m_firstHalfScale+0.5*m_secondHalfScale;
		}

		float operator()( float value )
		{
			for ( int i = 0; i < m_iterations; i++ )
			{
				float result;
				if ( value >= m_center )
				{
					result = ((smoothstep(0.0,1.0,(value-m_center)*m_secondHalfScale+0.5) - 0.5) * m_firstHalfScale + m_secondHalfScale*0.5) / m_norm;
				}
				else
				{
					result = (smoothstep(0.0,1.0,(value-m_center)*m_firstHalfScale+0.5) * m_secondHalfScale) / m_norm;
				}
				value = m_ratio*result + (1-m_ratio)*value;
			}
			return value;
		}

	private :

		int m_iterations;
		float m_ratio;
		float m_center;
		float m_firstHalfScale;
		float m_secondHalfScale;
		float m_norm;
};

void ContrastSmoothSkinningWeightsOp::modify( Object * object, const CompoundObject * operands )
{
	SmoothSkinningData *skinningData = static_cast<SmoothSkinningData *>( object );
	assert( skinningData );

	// \todo: remove decompression/compression.
	// decompress
	DecompressSmoothSkinningDataOp decompressionOp;
	decompressionOp.inputParameter()->setValidatedValue( skinningData );
	decompressionOp.copyParameter()->setTypedValue( false );
	decompressionOp.operate();

	const std::vector<int> &pointIndexOffsets = skinningData->pointIndexOffsets()->readable();
	const std::vector<int> &pointInfluenceCounts = skinningData->pointInfluenceCounts()->readable();
	const std::vector<int> &pointInfluenceIndices = skinningData->pointInfluenceIndices()->readable();
	int numSsdVerts = pointIndexOffsets.size();

	std::vector<float> &pointInfluenceWeights = skinningData->pointInfluenceWeights()->writable();

	const MeshPrimitive *mesh = runTimeCast<const MeshPrimitive>( m_meshParameter->getValidatedValue() );
	if ( !mesh )
	{
		throw IECore::Exception( "ContrastSmoothSkinningWeightsOp: The given mesh is not valid" );
	}
	int numMeshVerts = mesh->variableSize( PrimitiveVariable::Vertex );

	// make sure the mesh matches the skinning data
	if ( numMeshVerts != numSsdVerts )
	{
		throw IECore::Exception( "ContrastSmoothSkinningWeightsOp: The input SmoothSkinningData and mesh have a different number of vertices" );
	}

	bool useLocks = m_useLocksParameter->getTypedValue();
	std::vector<bool> &locks = m_influenceLocksParameter->getTypedValue();

	// make sure there is one lock per influence
	if ( useLocks && ( locks.size() != skinningData->influenceNames()->readable().size() ) )
	{
		throw IECore::Exception( "ContrastSmoothSkinningWeightsOp: There must be exactly one lock per influence" );
	}

	if ( !useLocks )
	{
		locks.clear();
		locks.resize( skinningData->influenceNames()->readable().size(), false );
	}

	std::vector<int64_t> vertexIds;
	m_vertexIdsParameter->getFrameListValue()->asList( vertexIds );

	// make sure all vertex ids are valid
	for ( unsigned i=0; i < vertexIds.size(); i++ )
	{
		if ( vertexIds[i] > numSsdVerts )
		{
			throw IECore::Exception( ( boost::format( "ContrastSmoothSkinningWeightsOp: VertexId \"%d\" is outside the range of the SmoothSkinningData and mesh" ) % vertexIds[i] ).str() );
		}
	}

	float contrastRatio = m_contrastRatioParameter->getNumericValue();
	float contrastCenter = m_contrastCenterParameter->getNumericValue();
	int numIterations = m_iterationsParameter->getNumericValue();

	ContrastSmoothStep contrastFunction( numIterations, contrastRatio, contrastCenter );

	// an empty vertexId list means we operate over all vertices
	if ( vertexIds.size() == 0 )
	{
		for ( unsigned int i=0; i < pointInfluenceWeights.size(); i++ )
		{
			unsigned int current = i;
			if ( !locks[ pointInfluenceIndices[current] ] )
			{
				pointInfluenceWeights[current] = contrastFunction( pointInfluenceWeights[ current ] );
			}
		}
	}
	else
	{
		// apply contrast with the per-influence locks
		for ( unsigned i=0; i < vertexIds.size(); i++ )
		{
			int currentVertId = vertexIds[i];
			for ( int j=0; j < pointInfluenceCounts[currentVertId]; j++ )
			{
				int current = pointIndexOffsets[currentVertId] + j;
				if ( !locks[ pointInfluenceIndices[current] ] )
				{
					pointInfluenceWeights[current] = contrastFunction( pointInfluenceWeights[ current ] );
				}
			}
		}
	}

	// re-compress
	CompressSmoothSkinningDataOp compressionOp;
	compressionOp.inputParameter()->setValidatedValue( skinningData );
	compressionOp.copyParameter()->setTypedValue( false );
	compressionOp.operate();
}
<|endoftext|>


<commit_before>#include	"FTGlyphContainer.h"
#include	"FTGlyph.h"
#include	"FTFace.h"
#ifdef FTGL_DEBUG
	#include "mmgr.h"
#endif

FTGlyphContainer::FTGlyphContainer( FTFace* f, unsigned int g, bool p)
:	preCache( p),
	numGlyphs( g),
	face( f),
	err( 0)
{
	glyphs.reserve( g);

	for( unsigned int i = 0; i < g; ++i)
	{
		glyphs.push_back( NULL);
	}
}

FTGlyphContainer::~FTGlyphContainer()
{
	vector<FTGlyph*>::iterator iter;
	for( iter = glyphs.begin(); iter != glyphs.end(); ++iter)
	{
		if( *iter)
		{
			delete *iter;
		}
	}

	glyphs.clear();
}

bool FTGlyphContainer::Add( FTGlyph* tempGlyph, unsigned int g)
{
	glyphs[g] = tempGlyph;
	return true;
}

FTGlyph* FTGlyphContainer::Glyph( unsigned int c) const
{
	unsigned int g = face->CharIndex( c);
	return glyphs[g];
}

FTBBox FTGlyphContainer::BBox( unsigned int index)
{
	unsigned int left = face->CharIndex( index);

	return glyphs[left]->BBox();
}

float FTGlyphContainer::Advance( unsigned int index, unsigned int next)
{
	unsigned int left = face->CharIndex( index);
	unsigned int right = face->CharIndex( next);

	float width = face->KernAdvance( left, right).x;
	width += glyphs[left]->Advance();

	return width;
}

FT_Vector& FTGlyphContainer::render( unsigned int index, unsigned int next, FT_Vector pen)
{
	kernAdvance.x = 0; kernAdvance.y = 0;

	unsigned int left = face->CharIndex( index);
	unsigned int right = face->CharIndex( next);

	kernAdvance = face->KernAdvance( left, right);

	if( !face->Error())
	{
		advance = glyphs[left]->Render( pen);
	}

	kernAdvance.x = advance + kernAdvance.x;
//	kernAdvance.y = advance.y + kernAdvance.y;
	return kernAdvance;
}
<commit_msg>More const stuff
Replaced the for loop with a resize to fill the vector with null<commit_after>#include	"FTGlyphContainer.h"
#include	"FTGlyph.h"
#include	"FTFace.h"
#ifdef FTGL_DEBUG
	#include "mmgr.h"
#endif

FTGlyphContainer::FTGlyphContainer( FTFace* f, unsigned int g, bool p)
:	preCache( p),
	numGlyphs( g),
	face( f),
	err( 0)
{
	// Fill the glyphlist with null glyphs
	glyphs.resize( g, NULL);
}

FTGlyphContainer::~FTGlyphContainer()
{
	vector<FTGlyph*>::iterator iter;
	for( iter = glyphs.begin(); iter != glyphs.end(); ++iter)
	{
		if( *iter)
		{
			delete *iter;
		}
	}

	glyphs.clear();
}

bool FTGlyphContainer::Add( FTGlyph* tempGlyph, unsigned int g)
{
	glyphs[g] = tempGlyph;
	return true;
}

FTGlyph* FTGlyphContainer::Glyph( const unsigned int c) const
{
	return glyphs[face->CharIndex( c)];
}

FTBBox FTGlyphContainer::BBox( const unsigned int index) const
{
	return glyphs[face->CharIndex( index)]->BBox();
}

float FTGlyphContainer::Advance( unsigned int index, unsigned int next)
{
	unsigned int left = face->CharIndex( index);
	unsigned int right = face->CharIndex( next);

	float width = face->KernAdvance( left, right).x;
	width += glyphs[left]->Advance();

	return width;
}

FT_Vector& FTGlyphContainer::render( unsigned int index, unsigned int next, FT_Vector pen)
{
	kernAdvance.x = 0; kernAdvance.y = 0;

	unsigned int left = face->CharIndex( index);
	unsigned int right = face->CharIndex( next);

	kernAdvance = face->KernAdvance( left, right);

	if( !face->Error())
	{
		advance = glyphs[left]->Render( pen);
	}

	kernAdvance.x = advance + kernAdvance.x;
//	kernAdvance.y = advance.y + kernAdvance.y;
	return kernAdvance;
}
<|endoftext|>


<commit_before>/*
 * FTGL - OpenGL font library
 *
 * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
 * Copyright (c) 2008 Sam Hocevar <sam@hocevar.net>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "config.h"

#include "FTGL/ftgl.h"

#include "FTGlyphContainer.h"
#include "FTFace.h"
#include "FTCharmap.h"

FTGlyphContainer::FTGlyphContainer(FTFace* f)
:   face(f),
    err(0)
{
    glyphs.push_back(NULL);
    charMap = new FTCharmap(face);
}

FTGlyphContainer::~FTGlyphContainer()
{
    GlyphVector::iterator it;
    for(it = glyphs.begin(); it != glyphs.end(); ++it)
    {
        delete *it;
    }

    glyphs.clear();
    delete charMap;
}

bool FTGlyphContainer::CharMap(FT_Encoding encoding)
{
    bool result = charMap->CharMap(encoding);
    err = charMap->Error();
    return result;
}

unsigned int FTGlyphContainer::FontIndex(const unsigned int charCode) const
{
    return charMap->FontIndex(charCode);
}

void FTGlyphContainer::Add(FTGlyph* tempGlyph, const unsigned int charCode)
{
    charMap->InsertIndex(charCode, glyphs.size());
    glyphs.push_back(tempGlyph);
}

const FTGlyph* const FTGlyphContainer::Glyph(const unsigned int charCode) const
{
    unsigned int index = charMap->GlyphListIndex(charCode);
    if (index > glyphs.size()) {
      return NULL;
    }
    return glyphs[index];
}

FTBBox FTGlyphContainer::BBox(const unsigned int charCode) const
{
    return Glyph(charCode)->BBox();
}

float FTGlyphContainer::Advance(const unsigned int charCode,
                                const unsigned int nextCharCode)
{
    unsigned int left = charMap->FontIndex(charCode);
    unsigned int right = charMap->FontIndex(nextCharCode);
    const FTGlyph *glyph = Glyph(charCode);
    if (!glyph) {
      return 0.0f;
    }

    return face->KernAdvance(left, right).Xf() + glyph->Advance();
}

FTPoint FTGlyphContainer::Render(const unsigned int charCode,
                                 const unsigned int nextCharCode,
                                 FTPoint penPosition, int renderMode)
{
    unsigned int left = charMap->FontIndex(charCode);
    unsigned int right = charMap->FontIndex(nextCharCode);

    FTPoint kernAdvance = face->KernAdvance(left, right);

    if(!face->Error())
    {
        unsigned int index = charMap->GlyphListIndex(charCode);
        if (index <= glyphs.size()) {
            kernAdvance += glyphs[index]->Render(penPosition, renderMode);
        }
    }

    return kernAdvance;
}

<commit_msg>Fix improper bound checks in FTGlyphContainer.<commit_after>/*
 * FTGL - OpenGL font library
 *
 * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
 * Copyright (c) 2008 Sam Hocevar <sam@hocevar.net>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "config.h"

#include "FTGL/ftgl.h"

#include "FTGlyphContainer.h"
#include "FTFace.h"
#include "FTCharmap.h"

FTGlyphContainer::FTGlyphContainer(FTFace* f)
:   face(f),
    err(0)
{
    glyphs.push_back(NULL);
    charMap = new FTCharmap(face);
}

FTGlyphContainer::~FTGlyphContainer()
{
    GlyphVector::iterator it;
    for(it = glyphs.begin(); it != glyphs.end(); ++it)
    {
        delete *it;
    }

    glyphs.clear();
    delete charMap;
}

bool FTGlyphContainer::CharMap(FT_Encoding encoding)
{
    bool result = charMap->CharMap(encoding);
    err = charMap->Error();
    return result;
}

unsigned int FTGlyphContainer::FontIndex(const unsigned int charCode) const
{
    return charMap->FontIndex(charCode);
}

void FTGlyphContainer::Add(FTGlyph* tempGlyph, const unsigned int charCode)
{
    charMap->InsertIndex(charCode, glyphs.size());
    glyphs.push_back(tempGlyph);
}

const FTGlyph* const FTGlyphContainer::Glyph(const unsigned int charCode) const
{
    unsigned int index = charMap->GlyphListIndex(charCode);

    return (index < glyphs.size()) ? glyphs[index] : NULL;
}

FTBBox FTGlyphContainer::BBox(const unsigned int charCode) const
{
    return Glyph(charCode)->BBox();
}

float FTGlyphContainer::Advance(const unsigned int charCode,
                                const unsigned int nextCharCode)
{
    unsigned int left = charMap->FontIndex(charCode);
    unsigned int right = charMap->FontIndex(nextCharCode);
    const FTGlyph *glyph = Glyph(charCode);

    if (!glyph)
      return 0.0f;

    return face->KernAdvance(left, right).Xf() + glyph->Advance();
}

FTPoint FTGlyphContainer::Render(const unsigned int charCode,
                                 const unsigned int nextCharCode,
                                 FTPoint penPosition, int renderMode)
{
    unsigned int left = charMap->FontIndex(charCode);
    unsigned int right = charMap->FontIndex(nextCharCode);

    FTPoint kernAdvance = face->KernAdvance(left, right);

    if(!face->Error())
    {
        unsigned int index = charMap->GlyphListIndex(charCode);
        if (index < glyphs.size())
            kernAdvance += glyphs[index]->Render(penPosition, renderMode);
    }

    return kernAdvance;
}

<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/ChannelOp.h"
#include "IECore/TypeTraits.h"
#include "IECore/DespatchTypedData.h"
#include "IECore/CompoundParameter.h"

#include "boost/format.hpp"

using namespace IECore;
using namespace std;
using namespace boost;

ChannelOp::ChannelOp( const std::string &name, const std::string &description )
	:	ImagePrimitiveOp( name, description )
{

	StringVectorDataPtr defaultChannels = new StringVectorData;
	defaultChannels->writable().push_back( "R" );
	defaultChannels->writable().push_back( "G" );
	defaultChannels->writable().push_back( "B" );

	m_channelNamesParameter = new StringVectorParameter(
		"channels",
		"The names of the channels to modify.",
		defaultChannels
	);

	parameters()->addParameter( m_channelNamesParameter );
}

ChannelOp::~ChannelOp()
{
}

StringVectorParameterPtr ChannelOp::channelNamesParameter()
{
	return m_channelNamesParameter;
}

ConstStringVectorParameterPtr ChannelOp::channelNamesParameter() const
{
	return m_channelNamesParameter;
}

void ChannelOp::modifyTypedPrimitive( ImagePrimitivePtr image, ConstCompoundObjectPtr operands )
{
	if( image->getDataWindow().isEmpty() )
	{
		return;
	}

	ChannelVector channels;

	/// \todo Just use ImagePrimitive::channelValid. We don't want to do that right now
	/// as it imposes loose restrictions on the channel datatype - in the future it should perhaps
	/// impose the restrictions we have here (float, int or half vector data).
	size_t numPixels = image->variableSize( PrimitiveVariable::Vertex );
	const vector<string> channelNames = channelNamesParameter()->getTypedValue();
	for( unsigned i=0; i<channelNames.size(); i++ )
	{
		PrimitiveVariableMap::iterator it = image->variables.find( channelNames[i] );
		if( it==image->variables.end() )
		{
			throw Exception( str( format( "Channel \"%s\" does not exist." ) % channelNames[i] ) );
		}

		if( it->second.interpolation!=PrimitiveVariable::Vertex &&
			it->second.interpolation!=PrimitiveVariable::Varying &&
			it->second.interpolation!=PrimitiveVariable::FaceVarying )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has inappropriate interpolation." ) % channelNames[i] ) );
		}

		if( !it->second.data )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has no data." ) % channelNames[i] ) );
		}

		if( !it->second.data->isInstanceOf( FloatVectorData::staticTypeId() ) &&
			!it->second.data->isInstanceOf( HalfVectorData::staticTypeId() ) &&
			!it->second.data->isInstanceOf( IntVectorData::staticTypeId() ) )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has inappropriate type." ) % channelNames[i] ) );
		}

		size_t size = despatchTypedData<TypedDataSize>( it->second.data );
		if( size!=numPixels )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has wrong size (%d but should be %d)." ) % channelNames[i] % size % numPixels ) );
		}

		channels.push_back( it->second.data );
	}

	modifyChannels( image->getDisplayWindow(), image->getDataWindow(), channels );
	assert( image->arePrimitiveVariablesValid() );
}
<commit_msg>Removed assert<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/ChannelOp.h"
#include "IECore/TypeTraits.h"
#include "IECore/DespatchTypedData.h"
#include "IECore/CompoundParameter.h"

#include "boost/format.hpp"

using namespace IECore;
using namespace std;
using namespace boost;

ChannelOp::ChannelOp( const std::string &name, const std::string &description )
	:	ImagePrimitiveOp( name, description )
{

	StringVectorDataPtr defaultChannels = new StringVectorData;
	defaultChannels->writable().push_back( "R" );
	defaultChannels->writable().push_back( "G" );
	defaultChannels->writable().push_back( "B" );

	m_channelNamesParameter = new StringVectorParameter(
		"channels",
		"The names of the channels to modify.",
		defaultChannels
	);

	parameters()->addParameter( m_channelNamesParameter );
}

ChannelOp::~ChannelOp()
{
}

StringVectorParameterPtr ChannelOp::channelNamesParameter()
{
	return m_channelNamesParameter;
}

ConstStringVectorParameterPtr ChannelOp::channelNamesParameter() const
{
	return m_channelNamesParameter;
}

void ChannelOp::modifyTypedPrimitive( ImagePrimitivePtr image, ConstCompoundObjectPtr operands )
{
	if( image->getDataWindow().isEmpty() )
	{
		return;
	}

	ChannelVector channels;

	/// \todo Just use ImagePrimitive::channelValid. We don't want to do that right now
	/// as it imposes loose restrictions on the channel datatype - in the future it should perhaps
	/// impose the restrictions we have here (float, int or half vector data).
	size_t numPixels = image->variableSize( PrimitiveVariable::Vertex );
	const vector<string> channelNames = channelNamesParameter()->getTypedValue();
	for( unsigned i=0; i<channelNames.size(); i++ )
	{
		PrimitiveVariableMap::iterator it = image->variables.find( channelNames[i] );
		if( it==image->variables.end() )
		{
			throw Exception( str( format( "Channel \"%s\" does not exist." ) % channelNames[i] ) );
		}

		if( it->second.interpolation!=PrimitiveVariable::Vertex &&
			it->second.interpolation!=PrimitiveVariable::Varying &&
			it->second.interpolation!=PrimitiveVariable::FaceVarying )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has inappropriate interpolation." ) % channelNames[i] ) );
		}

		if( !it->second.data )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has no data." ) % channelNames[i] ) );
		}

		if( !it->second.data->isInstanceOf( FloatVectorData::staticTypeId() ) &&
			!it->second.data->isInstanceOf( HalfVectorData::staticTypeId() ) &&
			!it->second.data->isInstanceOf( IntVectorData::staticTypeId() ) )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has inappropriate type." ) % channelNames[i] ) );
		}

		size_t size = despatchTypedData<TypedDataSize>( it->second.data );
		if( size!=numPixels )
		{
			throw Exception( str( format( "Primitive variable \"%s\" has wrong size (%d but should be %d)." ) % channelNames[i] % size % numPixels ) );
		}

		channels.push_back( it->second.data );
	}

	modifyChannels( image->getDisplayWindow(), image->getDataWindow(), channels );
}
<|endoftext|>