From 2953548885486834d6ec233211cab95c3f1a297c Mon Sep 17 00:00:00 2001 From: Chris Maffeo <cmaffeo2@illinois.edu> Date: Thu, 4 Feb 2021 15:56:27 -0600 Subject: [PATCH] Revert "Merge branch 'feat/bondangle' into release" This reverts commit c6c19c644b139776d3bb351457e1d0d85c4cd3a5, reversing changes made to c195bf0980e9f797f33906e7068af1b4a1df8d0f. --- src/Angle.cu | 12 -- src/Angle.h | 52 ------ src/ComputeForce.cu | 143 +-------------- src/ComputeForce.cuh | 88 ---------- src/ComputeForce.h | 60 +------ src/Configuration.cpp | 233 +----------------------- src/Configuration.h | 19 -- src/GrandBrownTown.cu | 41 +---- src/GrandBrownTown.h | 4 - src/Makefile | 4 - src/ProductPotential.h | 30 ---- src/TabulatedMethods.cuh | 110 ------------ src/TabulatedPotential.cu | 138 ++++++++------- src/TabulatedPotential.h | 360 +------------------------------------- 14 files changed, 96 insertions(+), 1198 deletions(-) delete mode 100644 src/ProductPotential.h diff --git a/src/Angle.cu b/src/Angle.cu index 2201187..acc2a09 100644 --- a/src/Angle.cu +++ b/src/Angle.cu @@ -15,15 +15,3 @@ String Angle::toString() return String("ANGLE ") + ind1 + " " + ind2 + " " + ind3 + " " + fileName; } -// void BondAngle::print() -// { -// // printf("about to print fileName %p\n", fileName.val()); -// // fileName.print(); -// printf("BONDANGLE (%d %d %d) %s; %s; %s\n", ind1, ind2, ind3, angleFileName.val(), bondFileName1.val(), bondFileName2.val()); -// } - -// String BondAngle::toString() -// { -// return String("BONDANGLE ") + ind1 + " " + ind2 + " " + ind3 + " " + angleFileName + " " + bondFileName1 + " " + bondFileName2; -// } - diff --git a/src/Angle.h b/src/Angle.h index e03a779..a4e9542 100644 --- a/src/Angle.h +++ b/src/Angle.h @@ -59,56 +59,4 @@ public: String toString(); void print(); }; - -// TODO consolidate with Angle using inheritence -class BondAngle -{ -public: - BondAngle() {} - BondAngle(int ind1, int ind2, int ind3, int ind4, String angleFileName1, String bondFileName, String angleFileName2) : - ind1(ind1), ind2(ind2), ind3(ind3), ind4(ind4), angleFileName1(angleFileName1), bondFileName(bondFileName), angleFileName2(angleFileName2), tabFileIndex1(-1), tabFileIndex2(-1), tabFileIndex3(-1) { } - - int ind1, ind2, ind3, ind4; - - String angleFileName1; - String bondFileName; - String angleFileName2; - // tabFileIndex will be assigned after ComputeForce loads the - // TabulatedAnglePotentials. The tabefileIndex is used by ComputeForce to - // discern which TabulatedAnglePotential this Angle uses. - int tabFileIndex1; - int tabFileIndex2; - int tabFileIndex3; - - inline BondAngle(const BondAngle& a) : ind1(a.ind1), ind2(a.ind2), ind3(a.ind3), ind4(a.ind4), - angleFileName1(a.angleFileName1), bondFileName(a.bondFileName), angleFileName2(a.angleFileName2), - tabFileIndex1(a.tabFileIndex1), tabFileIndex2(a.tabFileIndex2), tabFileIndex3(a.tabFileIndex3) { } - - // HOST DEVICE inline float calcAngle(Vector3* pos, BaseGrid* sys) { - // const Vector3& posa = pos[ind1]; - // const Vector3& posb = pos[ind2]; - // const Vector3& posc = pos[ind3]; - // const float distab = sys->wrapDiff(posa - posb).length(); - // const float distbc = sys->wrapDiff(posb - posc).length(); - // const float distac = sys->wrapDiff(posc - posa).length(); - // float cos = (distbc * distbc + distab * distab - distac * distac) - // / (2.0f * distbc * distab); - // if (cos < -1.0f) cos = -1.0f; - // else if (cos > 1.0f) cos = 1.0f; - // float angle = acos(cos); - // return angle; - // } - - // HOST DEVICE inline int getIndex(int index) { - // if (index == ind1) return 1; - // if (index == ind2) return 2; - // if (index == ind3) return 3; - // if (index == ind4) return 4; - // return -1; - // } - - // String toString(); - // void print(); -}; - #endif diff --git a/src/ComputeForce.cu b/src/ComputeForce.cu index ce8b6ed..5144a55 100644 --- a/src/ComputeForce.cu +++ b/src/ComputeForce.cu @@ -47,9 +47,7 @@ ComputeForce::ComputeForce(const Configuration& c, const int numReplicas = 1) : numBonds(c.numBonds), numTabBondFiles(c.numTabBondFiles), numExcludes(c.numExcludes), numAngles(c.numAngles), numTabAngleFiles(c.numTabAngleFiles), numDihedrals(c.numDihedrals), - numTabDihedralFiles(c.numTabDihedralFiles), numRestraints(c.numRestraints), - numBondAngles(c.numBondAngles), numProductPotentials(c.numProductPotentials), - numReplicas(numReplicas) { + numTabDihedralFiles(c.numTabDihedralFiles), numRestraints(c.numRestraints), numReplicas(numReplicas) { // Grow vectors for per-gpu device pointers for (int i = 0; i < gpuman.gpus.size(); ++i) { @@ -232,8 +230,6 @@ ComputeForce::ComputeForce(const Configuration& c, const int numReplicas = 1) : } restraintIds_d = NULL; - bondAngleList_d = NULL; - product_potential_list_d = NULL; //Calculate the number of blocks the grid should contain gridSize = num / NUM_THREADS + 1; @@ -401,7 +397,7 @@ bool ComputeForce::addTabulatedPotential(String fileName, int type0, int type1) return true; } -bool ComputeForce::addBondPotential(String fileName, int ind, Bond bonds[], BondAngle bondAngles[]) +bool ComputeForce::addBondPotential(String fileName, int ind, Bond bonds[]) { // TODO: see if tableBond_addr can be removed if (tableBond[ind] != NULL) { @@ -415,12 +411,6 @@ bool ComputeForce::addBondPotential(String fileName, int ind, Bond bonds[], Bond if (bonds[i].fileName == fileName) bonds[i].tabFileIndex = ind; - for (int i = 0; i < numBondAngles; i++) - { - if (bondAngles[i].bondFileName == fileName) - bondAngles[i].tabFileIndex2 = ind; - } - gpuErrchk(cudaMemcpyAsync(bonds_d, bonds, sizeof(Bond) * numBonds, cudaMemcpyHostToDevice)); tableBond_addr[ind] = tableBond[ind]->copy_to_cuda(); @@ -429,7 +419,7 @@ bool ComputeForce::addBondPotential(String fileName, int ind, Bond bonds[], Bond return true; } -bool ComputeForce::addAnglePotential(String fileName, int ind, Angle* angles, BondAngle* bondAngles) { +bool ComputeForce::addAnglePotential(String fileName, int ind, Angle* angles) { if (tableAngle[ind] != NULL) { delete tableAngle[ind]; gpuErrchk(cudaFree(tableAngle_addr[ind])); @@ -458,12 +448,6 @@ bool ComputeForce::addAnglePotential(String fileName, int ind, Angle* angles, Bo if (angles[i].fileName == fileName) angles[i].tabFileIndex = ind; - for (int i = 0; i < numBondAngles; i++) { - if (bondAngles[i].angleFileName1 == fileName) - bondAngles[i].tabFileIndex1 = ind; - if (bondAngles[i].angleFileName2 == fileName) - bondAngles[i].tabFileIndex3 = ind; - } gpuErrchk(cudaMemcpy(angles_d, angles, sizeof(Angle) * numAngles, cudaMemcpyHostToDevice)); return true; @@ -824,17 +808,6 @@ float ComputeForce::computeTabulated(bool get_energy) { //Mlog: the commented function doesn't use bondList, uncomment for testing. //if(bondMap_d != NULL && tableBond_d != NULL) - - if(product_potential_list_d != NULL && product_potentials_d != NULL) - { - computeProductPotentials <<<nb, numThreads, 0, gpuman.get_next_stream()>>> ( forceInternal_d[0], pos_d[0], sys_d[0], numReplicas*numProductPotentials, product_potential_particles_d, product_potentials_d, product_potential_list_d, productCount_d, energies_d, get_energy); - } - - if(bondAngleList_d != NULL && tableBond_d != NULL && tableAngle_d != NULL) - { - computeTabulatedBondAngles <<<nb, numThreads, 0, gpuman.get_next_stream()>>> ( forceInternal_d[0], pos_d[0], sys_d[0], numReplicas*numBondAngles, bondAngleList_d, tableAngle_d, tableBond_d, energies_d, get_energy); - } - if(bondList_d != NULL && tableBond_d != NULL) { @@ -985,7 +958,7 @@ void ComputeForce::setForceInternalOnDevice(Vector3* f) { } -void ComputeForce::copyToCUDA(int simNum, int *type, Bond* bonds, int2* bondMap, Exclude* excludes, int2* excludeMap, Angle* angles, Dihedral* dihedrals, const Restraint* const restraints, const BondAngle* const bondAngles, const XpotMap simple_potential_map, const std::vector<SimplePotential> simple_potentials, const ProductPotentialConf* const product_potential_confs) +void ComputeForce::copyToCUDA(int simNum, int *type, Bond* bonds, int2* bondMap, Exclude* excludes, int2* excludeMap, Angle* angles, Dihedral* dihedrals, const Restraint* const restraints) { // type_d gpuErrchk(cudaMalloc(&type_d, sizeof(int) * num * simNum)); @@ -1053,105 +1026,6 @@ void ComputeForce::copyToCUDA(int simNum, int *type, Bond* bonds, int2* bondMap, sizeof(float) * numRestraints, cudaMemcpyHostToDevice)); } - if (numBondAngles > 0) { - gpuErrchk(cudaMalloc(&bondAngles_d, sizeof(BondAngle) * numBondAngles)); - gpuErrchk(cudaMemcpyAsync(bondAngles_d, bondAngles, sizeof(BondAngle) * numBondAngles, - cudaMemcpyHostToDevice)); - } - - if (simple_potentials.size() > 0) { - float **val = simple_potential_pots_d = new float*[simple_potentials.size()]; - // float **tmp = new float*[simple_potentials.size()]; - for (int i=0; i < simple_potentials.size(); ++i) { - const SimplePotential sp = simple_potentials[i]; - gpuErrchk(cudaMalloc(&val[i], sizeof(float)*sp.size)); - gpuErrchk(cudaMemcpyAsync(val[i], sp.pot, sizeof(float)*sp.size, cudaMemcpyHostToDevice)); - // tmp[i] = sp.pot; - // // sp.pot = val[i]; - } - - // size_t sz = sizeof(SimplePotential) * simple_potentials.size(); - // gpuErrchk(cudaMalloc(&simple_potentials_d, sz)); - // gpuErrchk(cudaMemcpyAsync(simple_potentials_d, &simple_potentials[0], sz, - // cudaMemcpyHostToDevice)); - - // for (int i=0; i < simple_potentials.size(); ++i) { // Restore host pointers on host object - // SimplePotential &sp = simple_potentials[i]; - // sp.pot = tmp[i]; - // } - // // delete[] val; - // delete[] tmp; - - } - - if (numProductPotentials > 0) { - // Count particles - int n_pots = 0; - int n_particles = 0; - for (int i=0; i < numProductPotentials; ++i) { - const ProductPotentialConf& c = product_potential_confs[i]; - n_pots += c.indices.size(); - for (int j=0; j < c.indices.size(); ++j) { - n_particles += c.indices[j].size(); - } - } - // printf("DEBUG: Found %d particles participating in %d potentials forming %d productPotentials\n", - // n_particles, n_pots, numProductPotentials); - - // Build productPotentialLists on host - int *particle_list = new int[n_particles*numReplicas]; - SimplePotential *product_potentials = new SimplePotential[n_pots]; - uint2 *product_potential_list = new uint2[numProductPotentials*numReplicas]; - unsigned short *productCount = new unsigned short[numProductPotentials*numReplicas]; - - n_particles = 0; - - for (unsigned int r=0; r < numReplicas; ++r) { - n_pots = 0; - for (int i=0; i < numProductPotentials; ++i) { - const ProductPotentialConf& c = product_potential_confs[i]; - product_potential_list[i+r*numProductPotentials] = make_uint2( n_pots, n_particles ); - - for (int j=0; j < c.indices.size(); ++j) { - if (r == 0) { - unsigned int sp_i = simple_potential_map.at(c.potential_names[j]); - product_potentials[n_pots] = simple_potentials[sp_i]; - product_potentials[n_pots].pot = simple_potential_pots_d[sp_i]; - } - ++n_pots; - for (int k=0; k < c.indices[j].size(); ++k) { - particle_list[n_particles++] = c.indices[j][k]+r*num; - } - } - productCount[i+r*numProductPotentials] = c.indices.size(); - } - } - - // Copy to device - size_t sz = n_particles*numReplicas * sizeof(int); - gpuErrchk(cudaMalloc(&product_potential_particles_d, sz)); - gpuErrchk(cudaMemcpyAsync(product_potential_particles_d, particle_list, sz, - cudaMemcpyHostToDevice)); - sz = n_pots * sizeof(SimplePotential); - gpuErrchk(cudaMalloc(&product_potentials_d, sz)); - gpuErrchk(cudaMemcpyAsync(product_potentials_d, product_potentials, sz, - cudaMemcpyHostToDevice)); - sz = numProductPotentials*numReplicas * sizeof(uint2); - gpuErrchk(cudaMalloc(&product_potential_list_d, sz)); - gpuErrchk(cudaMemcpyAsync(product_potential_list_d, product_potential_list, sz, - cudaMemcpyHostToDevice)); - sz = numProductPotentials*numReplicas * sizeof(unsigned short); - gpuErrchk(cudaMalloc(&productCount_d, sz)); - gpuErrchk(cudaMemcpyAsync(productCount_d, productCount, sz, - cudaMemcpyHostToDevice)); - - // Clean up - delete[] particle_list; - delete[] product_potentials; - delete[] product_potential_list; - delete[] productCount; - } - gpuErrchk(cudaDeviceSynchronize()); } @@ -1170,7 +1044,7 @@ void ComputeForce::copyToCUDA(int simNum, int *type, Bond* bonds, int2* bondMap, // } // } -void ComputeForce::copyBondedListsToGPU(int3 *bondList, int4 *angleList, int4 *dihedralList, int *dihedralPotList, int4* bondAngleList) { +void ComputeForce::copyBondedListsToGPU(int3 *bondList, int4 *angleList, int4 *dihedralList, int *dihedralPotList) { size_t size; @@ -1196,11 +1070,4 @@ void ComputeForce::copyBondedListsToGPU(int3 *bondList, int4 *angleList, int4 *d gpuErrchk( cudaMalloc( &dihedralPotList_d, size ) ); gpuErrchk( cudaMemcpyAsync( dihedralPotList_d, dihedralPotList, size, cudaMemcpyHostToDevice) ); } - - if (numBondAngles > 0) { - size = 2*numBondAngles * numReplicas * sizeof(int4); - gpuErrchk( cudaMalloc( &bondAngleList_d, size ) ); - gpuErrchk( cudaMemcpyAsync( bondAngleList_d, bondAngleList, size, cudaMemcpyHostToDevice) ); - } - } diff --git a/src/ComputeForce.cuh b/src/ComputeForce.cuh index 62d2b1c..9109ab4 100644 --- a/src/ComputeForce.cuh +++ b/src/ComputeForce.cuh @@ -4,9 +4,7 @@ #define NEW #pragma once #include <cassert> - #include "CudaUtil.cuh" - #include "TabulatedMethods.cuh" #define BD_PI 3.1415927f @@ -1096,92 +1094,6 @@ void computeTabulatedAngles(Vector3* force, } } -__global__ -void computeTabulatedBondAngles(Vector3* force, - Vector3* __restrict__ pos, - BaseGrid* __restrict__ sys, - int numBondAngles, int4* __restrict__ bondAngleList_d, TabulatedAnglePotential** tableAngle, - TabulatedPotential** tableBond, - float* energy, bool get_energy) { - // Loop over ALL angles in ALL replicas - for (int i = threadIdx.x+blockIdx.x*blockDim.x; i<numBondAngles; i+=blockDim.x*gridDim.x) { - int atom1 = bondAngleList_d[2*i].x; - int atom2 = bondAngleList_d[2*i].y; - int atom3 = bondAngleList_d[2*i].z; - int atom4 = bondAngleList_d[2*i].w; - - int angleInd1 = bondAngleList_d[2*i+1].x; - int bondInd = bondAngleList_d[2*i+1].y; - int angleInd2 = bondAngleList_d[2*i+1].z; - - computeBondAngle(tableAngle[ angleInd1 ], tableBond[ bondInd ], tableAngle[ angleInd2 ], sys, force, pos, atom1, atom2, atom3, atom4, energy, get_energy); - } -} - -__global__ -void computeProductPotentials(Vector3* force, - Vector3* __restrict__ pos, - BaseGrid* __restrict__ sys, - int numProductPotentials, - int* __restrict__ productPotentialParticles, - SimplePotential* __restrict__ potentialList, - uint2* __restrict__ productPotential_list, - unsigned short* __restrict__ productCount, - float* energy, bool get_energy) { - /* - productPotential_list[i].x : index of first potential in potentialList for i_th productPotential - productPotential_list[i].y : index of first atom in productPotentialParticles for i_th productPotential - - for three potentials, angle, bond, angle, we would have the following atomic indices in productPotentialParticles: - pot1 : productPotential_list[i].y, productPotential_list[i].y + 1 , productPotential_list[i].y + 2 - pot2 : productPotential_list[i].y + 3, productPotential_list[i].y + 4 - and - pot3 : productPotential_list[i].y + 5, productPotential_list[i].y + 6, productPotential_list[i].y + 7 - - productCount[i] : number of potentials in the i_th productPotential - */ - - // CRAPPY NAIVE IMPLEMENTATION -#define MAX_XPOTS 4 - float2 energy_and_deriv[MAX_XPOTS]; - float tmp_force; - - for (int i = threadIdx.x+blockIdx.x*blockDim.x; i<numProductPotentials; i+=blockDim.x*gridDim.x) { - unsigned short num_pots = productCount[i]; - - unsigned int part_idx = productPotential_list[i].y; -#pragma unroll - for (unsigned short int j = 0; j < MAX_XPOTS; ++j) { - if (j == num_pots) break; - SimplePotential& p = potentialList[ productPotential_list[i].x + j ]; - - // Hidden branch divergence in compute_value => sort potentials by type before running kernel - float tmp = p.compute_value(pos,sys, &productPotentialParticles[part_idx]); - energy_and_deriv[j] = p.compute_energy_and_deriv(tmp); - part_idx += p.type==BOND? 2: p.type==ANGLE? 3: 4; - } - - part_idx = productPotential_list[i].y; -#pragma unroll - for (unsigned short int j = 0; j < MAX_XPOTS; ++j) { - if (j == num_pots) break; - tmp_force = energy_and_deriv[j].y; -#pragma unroll - for (unsigned short int k = 0; k < MAX_XPOTS; ++k) { - if (k == num_pots) break; - if (j == k) continue; - tmp_force *= energy_and_deriv[k].x; - } - SimplePotential& p = potentialList[ productPotential_list[i].x + j ]; - if (tmp_force != 0) { - // TODO add energy - p.apply_force(pos,sys, force, &productPotentialParticles[part_idx], tmp_force); - } - part_idx += p.type==BOND? 2: p.type==ANGLE? 3: 4; - } - } -} - __global__ void computeDihedrals(Vector3 force[], Vector3 pos[], diff --git a/src/ComputeForce.h b/src/ComputeForce.h index 04ccb8d..fc11106 100644 --- a/src/ComputeForce.h +++ b/src/ComputeForce.h @@ -1,7 +1,8 @@ /////////////////////////////////////////////////////////////////////// // Brownian dynamics base class // Author: Jeff Comer <jcomer2@illinois.edu> -#pragma once +#ifndef COMPUTEFORCE_H +#define COMPUTEFORCE_H #ifdef __CUDACC__ #define HOST __host__ @@ -24,44 +25,13 @@ #include "TabulatedPotential.h" #include "TabulatedAngle.h" #include "TabulatedDihedral.h" -#include "ProductPotential.h" #include "GPUManager.h" -// #include <map> - #include <cstdio> // #include <cuda_runtime.h> #include <thrust/transform_reduce.h> // thrust::reduce #include <thrust/functional.h> // thrust::plus -#ifndef gpuErrchk -#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } -inline void gpuAssert(cudaError_t code, const char* file, int line, bool abort=true) { - if (code != cudaSuccess) { - fprintf(stderr,"CUDA Error: %s %s:%d\n", cudaGetErrorString(code), __FILE__, line); - if (abort) exit(code); - } -} -#endif - -#ifdef USE_BOOST -#include <boost/unordered_map.hpp> -typedef boost::unordered_map<String,unsigned int> XpotMap; -inline std::size_t hash_value(String const& s) { - if (s.length() == 0) return 0; - return boost::hash_range(s.val(), s.val()+s.length()); -} -#else -#include <map> -typedef std::map<String,unsigned int> XpotMap; -inline std::size_t hash_value(String const& s) { - if (s.length() == 0) return 0; - return hash_value(s.val()); -} -#endif - - - const unsigned int NUM_THREADS = 256; // Configuration @@ -76,8 +46,8 @@ public: void makeTables(const BrownianParticleType* part); bool addTabulatedPotential(String fileName, int type0, int type1); - bool addBondPotential(String fileName, int ind, Bond* bonds, BondAngle* bondAngles); - bool addAnglePotential(String fileName, int ind, Angle* angles, BondAngle* bondAngles); + bool addBondPotential(String fileName, int ind, Bond* bonds); + bool addAnglePotential(String fileName, int ind, Angle* angles); bool addDihedralPotential(String fileName, int ind, Dihedral* dihedrals); void decompose(); @@ -105,15 +75,12 @@ public: //MLog: new copy function to allocate memory required by ComputeForce class. void copyToCUDA(Vector3* forceInternal, Vector3* pos); - void copyToCUDA(int simNum, int *type, Bond* bonds, int2* bondMap, Exclude* excludes, int2* excludeMap, Angle* angles, Dihedral* dihedrals, const Restraint* const restraints, const BondAngle* const bondAngles, - const XpotMap simple_potential_map, - const std::vector<SimplePotential> simple_potentials, - const ProductPotentialConf* const product_potential_confs); + void copyToCUDA(int simNum, int *type, Bond* bonds, int2* bondMap, Exclude* excludes, int2* excludeMap, Angle* angles, Dihedral* dihedrals, const Restraint* const restraints); void copyToCUDA(Vector3* forceInternal, Vector3* pos, Vector3* mom); void copyToCUDA(Vector3* forceInternal, Vector3* pos, Vector3* mom, float* random); // void createBondList(int3 *bondList); - void copyBondedListsToGPU(int3 *bondList, int4 *angleList, int4 *dihedralList, int *dihedralPotList, int4 *bondAngleList); + void copyBondedListsToGPU(int3 *bondList, int4 *angleList, int4 *dihedralList, int *dihedralPotList); //MLog: because of the move of a lot of private variables, some functions get starved necessary memory access to these variables, below is a list of functions that return the specified private variable. std::vector<Vector3*> getPos_d() @@ -214,7 +181,6 @@ private: int numTabAngleFiles; int numDihedrals; int numTabDihedralFiles; - float *tableEps, *tableRad6, *tableAlpha; TabulatedPotential **tablePot; // 100% on Host TabulatedPotential **tableBond; @@ -277,18 +243,6 @@ private: Angle* angles_d; Dihedral* dihedrals_d; - int numBondAngles; - BondAngle* bondAngles_d; - int4* bondAngleList_d; - - int numProductPotentials; - float** simple_potential_pots_d; - SimplePotential* simple_potentials_d; - int* product_potential_particles_d; - SimplePotential* product_potentials_d; - uint2* product_potential_list_d; - unsigned short* productCount_d; - int3* bondList_d; int4* angleList_d; int4* dihedralList_d; @@ -300,3 +254,5 @@ private: float* restraintSprings_d; }; + +#endif diff --git a/src/Configuration.cpp b/src/Configuration.cpp index e18fc06..66c4206 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -2,7 +2,6 @@ #include "Angle.h" #include "Dihedral.h" #include "Restraint.h" -#include "ProductPotential.h" #include <cmath> #include <cassert> #include <stdlib.h> /* srand, rand */ @@ -231,9 +230,6 @@ Configuration::Configuration(const char* config_file, int simNum, bool debug) : if (readAnglesFromFile) readAngles(); if (readDihedralsFromFile) readDihedrals(); if (readRestraintsFromFile) readRestraints(); - if (readBondAnglesFromFile) readBondAngles(); - if (readProductPotentialsFromFile) readProductPotentials(); - if (temperatureGridFile.length() != 0) { printf("\nFound temperature grid file: %s\n", temperatureGridFile.val()); @@ -567,8 +563,6 @@ Configuration::~Configuration() { if (excludeMap != NULL) delete[] excludeMap; if (angles != NULL) delete[] angles; if (dihedrals != NULL) delete[] dihedrals; - if (bondAngles != NULL) delete[] bondAngles; - if (productPotentials != NULL) delete[] productPotentials; delete[] numPartsOfType; @@ -789,14 +783,6 @@ void Configuration::setDefaults() { dihedrals = NULL; numTabDihedralFiles = 0; - readBondAnglesFromFile = false; - numBondAngles = 0; - bondAngles = NULL; - - readProductPotentialsFromFile = false; - numProductPotentials = 0; - productPotentials = NULL; - readRestraintsFromFile = false; numRestraints = 0; restraints = NULL; @@ -1037,20 +1023,6 @@ int Configuration::readParameters(const char * config_file) { angleFile = value; readAnglesFromFile = true; } - } else if (param == String("inputBondAngles")) { - if (readBondAnglesFromFile) { - printf("WARNING: More than one angle file specified. Ignoring new angle file.\n"); - } else { - bondAngleFile = value; - readBondAnglesFromFile = true; - } - } else if (param == String("inputProductPotentials")) { - if (readBondAnglesFromFile) { - printf("WARNING: More than one product potential file specified. Ignoring new file.\n"); - } else { - productPotentialFile = value; - readProductPotentialsFromFile = true; - } } else if (param == String("tabulatedAngleFile")) { if (numTabAngleFiles >= atfcap) { String* temp = angleTableFile; @@ -1446,7 +1418,7 @@ void Configuration::readBonds() { String s(line); int numTokens = s.tokenCount(); - + // Break the line down into pieces (tokens) so we can process them individually String* tokenList = new String[numTokens]; s.tokenize(tokenList); @@ -1763,178 +1735,6 @@ void Configuration::readDihedrals() { // dihedrals[i].print(); } -void Configuration::readBondAngles() { - FILE* inp = fopen(bondAngleFile.val(), "r"); - char line[256]; - int capacity = 256; - numBondAngles = 0; - bondAngles = new BondAngle[capacity]; - - // If the angle file cannot be found, exit the program - if (inp == NULL) { - printf("WARNING: Could not open `%s'.\n", bondAngleFile.val()); - printf("This simulation will not use angles.\n"); - return; - } - - while(fgets(line, 256, inp)) { - if (line[0] == '#') continue; - String s(line); - int numTokens = s.tokenCount(); - String* tokenList = new String[numTokens]; - s.tokenize(tokenList); - - // Legitimate BONDANGLE inputs have 7 tokens - // BONDANGLE | INDEX1 | INDEX2 | INDEX3 | ANGLE_FILENAME | BOND_FILENAME1 | BOND_FILENAME2 - // Any angle input line without exactly 5 tokens should be discarded - if (numTokens != 8) { - printf("WARNING: Invalid bond_angle input line: %s\n", line); - continue; - } - - // Discard any empty line - if (tokenList == NULL) - continue; - - int ind1 = atoi(tokenList[1].val()); - int ind2 = atoi(tokenList[2].val()); - int ind3 = atoi(tokenList[3].val()); - int ind4 = atoi(tokenList[4].val()); - String file_name1 = tokenList[5]; - String file_name2 = tokenList[6]; - String file_name3 = tokenList[7]; - //printf("file_name %s\n", file_name.val()); - if (ind1 >= num or ind2 >= num or ind3 >= num or ind4 >= num) - continue; - - if (numBondAngles >= capacity) { - BondAngle* temp = bondAngles; - capacity *= 2; - bondAngles = new BondAngle[capacity]; - for (int i = 0; i < numBondAngles; i++) - bondAngles[i] = temp[i]; - delete[] temp; - } - - BondAngle a(ind1, ind2, ind3, ind4, file_name1, file_name2, file_name3); - bondAngles[numBondAngles++] = a; - delete[] tokenList; - } - std::sort(bondAngles, bondAngles + numBondAngles, compare()); - - // for(int i = 0; i < numAngles; i++) - // angles[i].print(); -} - -void Configuration::readProductPotentials() { - FILE* inp = fopen(productPotentialFile.val(), "r"); - char line[256]; - int capacity = 256; - numProductPotentials = 0; - productPotentials = new ProductPotentialConf[capacity]; - - // If the angle file cannot be found, exit the program - if (inp == NULL) { - printf("WARNING: Could not open `%s'.\n", productPotentialFile.val()); - printf("This simulation will not use product potentials.\n"); - return; - } - printf("DEBUG: READING PRODUCT POTENTAL FILE\n"); - std::vector<std::vector<int>> indices; - std::vector<int> tmp; - std::vector<String> pot_names; - - while(fgets(line, 256, inp)) { - if (line[0] == '#') continue; - String s(line); - int numTokens = s.tokenCount(); - String* tokenList = new String[numTokens]; - s.tokenize(tokenList); - - indices.clear(); - tmp.clear(); - pot_names.clear(); - - printf("\rDEBUG: reading line %d",numProductPotentials+1); - - // Legitimate ProductPotential inputs have at least 7 tokens - // BONDANGLE | INDEX1 | INDEX2 | INDEX3 | [TYPE1] | POT_FILENAME1 | INDEX4 | INDEX5 | [TYPE2] POT_FILENAME2 ... - if (numTokens < 7) { - printf("WARNING: Invalid product potential input line (too few tokens %d): %s\n", numTokens, line); - continue; - } - - // Discard any empty line - if (tokenList == NULL) - continue; - - SimplePotentialType type = BOND; // initialize to suppress warning - bool type_specified = false; - for (int i = 1; i < numTokens; ++i) { - char *end; - // printf("DEBUG: Working on token %d '%s'\n", i, tokenList[i].val()); - - // Try to convert token to integer - int index = (int) strtol(tokenList[i].val(), &end, 10); - if (tokenList[i].val() == end || *end != '\0' || errno == ERANGE) { - // Failed to convert token to integer; therefore it must be a potential name or type - - // Try to match a type - String n = tokenList[i]; - n.lower(); - if (n == "bond") { type = DIHEDRAL; type_specified = true; } - else if (n == "angle") { type = DIHEDRAL; type_specified = true; } - else if (n == "dihedral") { type = DIHEDRAL; type_specified = true; } - else if (n == "vecangle") { type = VECANGLE; type_specified = true; } - else { // Not a type, therefore a path to a potential - n = tokenList[i]; - indices.push_back(tmp); - pot_names.push_back( n ); - // TODO: Key should be tuple of (type,n) - if ( simple_potential_ids.find(n) == simple_potential_ids.end() ) { - // Could not find fileName in dictionary, so read and add it - unsigned int s = tmp.size(); - if (s < 2 || s > 4) { - printf("WARNING: Invalid product potential input line (indices of potential %d == %d): %s\n", i, s, line); - continue; - } - simple_potential_ids[n] = simple_potentials.size(); - if (not type_specified) type = s==2? BOND: s==3? ANGLE: DIHEDRAL; - simple_potentials.push_back( SimplePotential(n.val(), type) ); - } - tmp.clear(); - type_specified = false; - - } - } else { - if (index >= num) { - continue; - } - tmp.push_back(index); - } - } - - if (numProductPotentials >= capacity) { - ProductPotentialConf* temp = productPotentials; - capacity *= 2; - productPotentials = new ProductPotentialConf[capacity]; - for (int i = 0; i < numProductPotentials; i++) - productPotentials[i] = temp[i]; - delete[] temp; - } - - ProductPotentialConf a(indices, pot_names); - productPotentials[numProductPotentials++] = a; - delete[] tokenList; - } - printf("\nDEBUG: Sorting\n"); - std::sort(productPotentials, productPotentials + numProductPotentials, compare()); - - // for(int i = 0; i < numAngles; i++) - // angles[i].print(); -} - - void Configuration::readRestraints() { FILE* inp = fopen(restraintFile.val(), "r"); char line[256]; @@ -2534,34 +2334,3 @@ bool Configuration::compare::operator()(const Dihedral& lhs, const Dihedral& rhs return lhs.ind3 < rhs.ind3; return lhs.ind4 < rhs.ind4; } - -bool Configuration::compare::operator()(const BondAngle& lhs, const BondAngle& rhs) { - int diff = lhs.ind1 - rhs.ind1; - if (diff != 0) - return lhs.ind1 < rhs.ind1; - diff = lhs.ind2 - rhs.ind2; - if (diff != 0) - return lhs.ind2 < rhs.ind2; - diff = lhs.ind3 - rhs.ind3; - if (diff != 0) - return lhs.ind3 < rhs.ind3; - return lhs.ind4 < rhs.ind4; -} - -bool Configuration::compare::operator()(const ProductPotentialConf& lhs, const ProductPotentialConf& rhs) { - int diff = rhs.indices.size() - lhs.indices.size(); - if (diff != 0) return diff > 0; - - for (unsigned int i = 0; i < lhs.indices.size(); ++i) { - diff = rhs.indices[i].size() - lhs.indices[i].size(); - if (diff != 0) return diff > 0; - } - - for (unsigned int i = 0; i < lhs.indices.size(); ++i) { - for (unsigned int j = 0; j < lhs.indices[i].size(); ++j) { - diff = rhs.indices[i][j] - lhs.indices[i][j]; - if (diff != 0) return diff > 0; - } - } - return true; -} diff --git a/src/Configuration.h b/src/Configuration.h index 85ae13f..0895235 100644 --- a/src/Configuration.h +++ b/src/Configuration.h @@ -24,7 +24,6 @@ #include "TrajectoryWriter.h" #include "TabulatedPotential.h" #include "TabulatedAngle.h" -#include "ProductPotential.h" #include "GPUManager.h" #include "RigidBodyType.h" #include "RigidBody.h" @@ -48,8 +47,6 @@ class Configuration { bool operator()(const Exclude& lhs, const Exclude& rhs); bool operator()(const Angle& lhs, const Angle& rhs); bool operator()(const Dihedral& lhs, const Dihedral& rhs); - bool operator()(const BondAngle& lhs, const BondAngle& rhs); - bool operator()(const ProductPotentialConf& lhs, const ProductPotentialConf& rhs); }; void setDefaults(); @@ -65,15 +62,12 @@ class Configuration { void buildExcludeMap(); void readDihedrals(); void readRestraints(); - void readBondAngles(); bool readTableFile(const String& value, int currTab); bool readBondFile(const String& value, int currBond); bool readAngleFile(const String& value, int currAngle); bool readDihedralFile(const String& value, int currDihedral); - bool readBondAngleFile(const String& value, const String& bondfile1, const String& bondfile2, int currBondAngle); - // Given the numbers of each particle, populate the type list. void populate(); @@ -193,7 +187,6 @@ public: int numExcludes; int numAngles; int numDihedrals; - int numBondAngles; int numRestraints; int* numPartsOfType; String partFile; @@ -202,13 +195,11 @@ public: String angleFile; String dihedralFile; String restraintFile; - String bondAngleFile; bool readPartsFromFile; bool readBondsFromFile; bool readExcludesFromFile; bool readAnglesFromFile; bool readDihedralsFromFile; - bool readBondAnglesFromFile; bool readRestraintsFromFile; //String* partGridFile; String **partGridFile; @@ -242,18 +233,8 @@ public: String* dihedralTableFile; int numTabDihedralFiles; - BondAngle* bondAngles; - Restraint* restraints; - void readProductPotentials(); - String productPotentialFile; - int numProductPotentials; - bool readProductPotentialsFromFile; - ProductPotentialConf* productPotentials; - XpotMap simple_potential_ids; - std::vector<SimplePotential> simple_potentials; - //Han-Yi Chou String ParticleDynamicType; String RigidBodyDynamicType; diff --git a/src/GrandBrownTown.cu b/src/GrandBrownTown.cu index 5b87c3a..5966843 100644 --- a/src/GrandBrownTown.cu +++ b/src/GrandBrownTown.cu @@ -199,8 +199,6 @@ GrandBrownTown::GrandBrownTown(const Configuration& c, const char* outArg, partTableIndex0 = c.partTableIndex0; partTableIndex1 = c.partTableIndex1; - numBondAngles = c.numBondAngles; - numTabBondFiles = c.numTabBondFiles; bondMap = c.bondMap; // TODO: bondList = c.bondList; @@ -217,8 +215,6 @@ GrandBrownTown::GrandBrownTown(const Configuration& c, const char* outArg, dihedrals = c.dihedrals; numTabDihedralFiles = c.numTabDihedralFiles; - bondAngles = c.bondAngles; - // Device parameters //type_d = c.type_d; part_d = c.part_d; @@ -255,9 +251,9 @@ GrandBrownTown::GrandBrownTown(const Configuration& c, const char* outArg, // fullLongRange, numBonds, numTabBondFiles, numExcludes, numAngles, numTabAngleFiles, // numDihedrals, numTabDihedralFiles, c.pairlistDistance, numReplicas); internal = new ComputeForce(c, numReplicas); - + //MLog: I did the other halve of the copyToCUDA function from the Configuration class here, keep an eye on any mistakes that may occur due to the location. - internal -> copyToCUDA(c.simNum, c.type, c.bonds, c.bondMap, c.excludes, c.excludeMap, c.angles, c.dihedrals, c.restraints, c.bondAngles, c.simple_potential_ids, c.simple_potentials, c.productPotentials ); + internal -> copyToCUDA(c.simNum, c.type, c.bonds, c.bondMap, c.excludes, c.excludeMap, c.angles, c.dihedrals, c.restraints); // TODO: check for duplicate potentials if (c.tabulatedPotential) { @@ -281,11 +277,11 @@ GrandBrownTown::GrandBrownTown(const Configuration& c, const char* outArg, if (bondTableFile[p].length() > 0) { //MLog: make sure to add to all GPUs // printf("...loading %s\n",bondTableFile[p].val()); - internal->addBondPotential(bondTableFile[p].val(), p, bonds, bondAngles); + internal->addBondPotential(bondTableFile[p].val(), p, bonds); // printf("%s\n",bondTableFile[p].val()); } else { printf("...skipping %s (\n",bondTableFile[p].val()); - internal->addBondPotential(bondTableFile[p].val(), p, bonds, bondAngles); + internal->addBondPotential(bondTableFile[p].val(), p, bonds); } } @@ -296,7 +292,7 @@ GrandBrownTown::GrandBrownTown(const Configuration& c, const char* outArg, if (angleTableFile[p].length() > 0) { //MLog: make sure to do this for every GPU - internal->addAnglePotential(angleTableFile[p].val(), p, angles, bondAngles); + internal->addAnglePotential(angleTableFile[p].val(), p, angles); } } @@ -361,32 +357,7 @@ GrandBrownTown::GrandBrownTown(const Configuration& c, const char* outArg, } } } - - if (numBondAngles > 0) { - bondAngleList = new int4[ (numBondAngles*2) * numReplicas ]; - for(int k = 0 ; k < numReplicas; k++) { - for(int i = 0; i < numBondAngles; ++i) { - if (bondAngles[i].tabFileIndex1 == -1) { - fprintf(stderr,"Error: bondanglefile '%s' was not read with tabulatedAngleFile command.\n", bondAngles[i].angleFileName1.val()); - exit(1); - } - if (bondAngles[i].tabFileIndex2 == -1) { - fprintf(stderr,"Error: bondanglefile1 '%s' was not read with tabulatedBondFile command.\n", bondAngles[i].bondFileName.val()); - exit(1); - } - if (bondAngles[i].tabFileIndex3 == -1) { - fprintf(stderr,"Error: bondanglefile2 '%s' was not read with tabulatedBondFile command.\n", bondAngles[i].angleFileName2.val()); - exit(1); - } - int idx = i+k*numBondAngles; - bondAngleList[idx*2] = make_int4( bondAngles[i].ind1+k*num, bondAngles[i].ind2+k*num, - bondAngles[i].ind3+k*num, bondAngles[i].ind4+k*num ); - bondAngleList[idx*2+1] = make_int4( bondAngles[i].tabFileIndex1, bondAngles[i].tabFileIndex2, bondAngles[i].tabFileIndex3, -1 ); - } - } - } - - internal->copyBondedListsToGPU(bondList,angleList,dihedralList,dihedralPotList,bondAngleList); + internal->copyBondedListsToGPU(bondList,angleList,dihedralList,dihedralPotList); forceInternal = new Vector3[num * numReplicas]; if (fullLongRange != 0) diff --git a/src/GrandBrownTown.h b/src/GrandBrownTown.h index 8a50140..bb63a5c 100644 --- a/src/GrandBrownTown.h +++ b/src/GrandBrownTown.h @@ -267,10 +267,6 @@ private: int4 *dihedralList; int *dihedralPotList; - int numBondAngles; - BondAngle* bondAngles; - int4 *bondAngleList; - //Han-Yi Chou String particle_dynamic; String rigidbody_dynamic; diff --git a/src/Makefile b/src/Makefile index 8d4b024..b0356b8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -82,10 +82,6 @@ ifdef NCCL_PATH LD_FLAGS += -L$(NCCL_PATH)/lib -lnccl -Wl,-rpath,$(NCCL_PATH)/lib endif -ifdef USE_BOOST - CC_FLAGS += -DUSE_BOOST -endif - ### Sources CC_SRC := $(wildcard *.cpp) CC_SRC := $(filter-out arbd.cpp, $(CC_SRC)) diff --git a/src/ProductPotential.h b/src/ProductPotential.h deleted file mode 100644 index ff918e6..0000000 --- a/src/ProductPotential.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#ifdef __CUDACC__ - #define HOST __host__ - #define DEVICE __device__ -#else - #define HOST - #define DEVICE -#endif - -#include "useful.h" -#include <cuda.h> - - -class ProductPotentialConf { -public: - ProductPotentialConf() {} - ProductPotentialConf( std::vector< std::vector<int> > indices, std::vector<String> potential_names ) : - indices(indices), potential_names(potential_names) { } - - std::vector< std::vector<int> > indices; /* indices of particles */ - std::vector<String> potential_names; - - inline ProductPotentialConf(const ProductPotentialConf& a) : indices(a.indices), potential_names(a.potential_names) { } - - - /* String toString(); */ - /* void print(); */ -}; - diff --git a/src/TabulatedMethods.cuh b/src/TabulatedMethods.cuh index deee3f0..6f530f2 100644 --- a/src/TabulatedMethods.cuh +++ b/src/TabulatedMethods.cuh @@ -2,14 +2,6 @@ #define BD_PI 3.1415927f -struct AngleForce { - __host__ __device__ - AngleForce(Vector3 f1, Vector3 f3, float e) : f1(f1), f3(f3), e(e) { } - Vector3 f1; - Vector3 f3; - float e; -}; - __device__ inline void computeAngle(const TabulatedAnglePotential* __restrict__ a, const BaseGrid* __restrict__ sys, Vector3* force, const Vector3* __restrict__ pos, const int& i, const int& j, const int& k, float* energy, bool get_energy) { @@ -85,108 +77,6 @@ __device__ inline void computeAngle(const TabulatedAnglePotential* __restrict__ atomicAdd( &force[k], force3 ); } -__device__ inline AngleForce calcAngle(const TabulatedAnglePotential* __restrict__ a, const Vector3 ab, const Vector3 bc, const Vector3 ac) { - // // The vectors between each pair of particles - // const Vector3 ab = sys->wrapDiff(posa - posb); - // const Vector3 bc = sys->wrapDiff(posb - posc); - // const Vector3 ac = sys->wrapDiff(posc - posa); - - // Find the distance between each pair of particles - float distab = ab.length2(); - float distbc = bc.length2(); - const float distac2 = ac.length2(); - - // Find the cosine of the angle we want - <ABC - float cos = (distab + distbc - distac2); - - distab = 1.0f/sqrt(distab); //TODO: test other functiosn - distbc = 1.0f/sqrt(distbc); - cos *= 0.5f * distbc * distab; - - // If the cosine is illegitimate, set it to 1 or -1 so that acos won't fail - if (cos < -1.0f) cos = -1.0f; - if (cos > 1.0f) cos = 1.0f; - - // Find the sine while we're at it. - - // Now we can use the cosine to find the actual angle (in radians) - float angle = acos(cos); - - // transform angle to units of tabulated array index - angle *= a->angle_step_inv; - - // tableAngle[0] stores the potential at angle_step - // tableAngle[1] stores the potential at angle_step * 2, etc. - // 'home' is the index after which 'convertedAngle' would appear if it were stored in the table - int home = int(floorf(angle)); - home = (home >= a->size) ? (a->size)-1 : home; - //assert(home >= 0); - //assert(home+1 < a->size); - - // // Make angle the distance from [0,1) from the first index in the potential array index - // angle -= home; - - // Linearly interpolate the potential - float U0 = a->pot[home]; - float dUdx = (a->pot[(((home+1)==(a->size)) ? (a->size)-1 : home+1)] - U0) * a->angle_step_inv; - float e = ((dUdx * (angle-home)) + U0); - - float sin = sqrtf(1.0f - cos*cos); - dUdx /= abs(sin) > 1e-3 ? sin : 1e-3; // avoid singularity - - // Calculate the forces - Vector3 force1 = -(dUdx*distab) * (ab * (cos*distab) + bc * distbc); // force on particle 1 - Vector3 force3 = (dUdx*distbc) * (bc * (cos*distbc) + ab * distab); // force on particle 3 - - return AngleForce(force1,force3,e); -} - -__device__ inline void computeBondAngle(const TabulatedAnglePotential* __restrict__ a1, - const TabulatedPotential* __restrict__ b, const TabulatedAnglePotential* __restrict__ a2, - const BaseGrid* __restrict__ sys, Vector3* force, const Vector3* __restrict__ pos, - const int& i, const int& j, const int& k, const int& l, float* energy, bool get_energy) { - - // Particle's type and position - Vector3 posa = pos[i]; - Vector3 posb = pos[j]; - Vector3 posc = pos[k]; - Vector3 posd = pos[l]; - - // The vectors between each pair of particles - const Vector3 ab = sys->wrapDiff(posb - posa); - const Vector3 bc = sys->wrapDiff(posc - posb); - const Vector3 ca = sys->wrapDiff(posc - posa); - AngleForce fe_a1 = calcAngle(a1, -ab,-bc,ca); - - float distbc = bc.length2(); - EnergyForce fe_b = b->compute(bc,distbc); - - const Vector3 cd = sys->wrapDiff(posd - posc); - const Vector3 db = sys->wrapDiff(posd - posb); - AngleForce fe_a2 = calcAngle(a2, -bc,-cd,db); - - if(get_energy) - { - float e = fe_a1.e * fe_b.e * fe_a2.e * 0.25f; - atomicAdd( &energy[i], e); - atomicAdd( &energy[j], e); - atomicAdd( &energy[k], e); - atomicAdd( &energy[l], e); - } - atomicAdd( &force[i], fe_a1.f1 * fe_b.e * fe_a2.e ); - atomicAdd( &force[j], - -(fe_a1.f1 + fe_a1.f3) * fe_b.e * fe_a2.e - + fe_b.f * fe_a1.e * fe_a2.e - + fe_a2.f1 * fe_b.e * fe_a1.e - ); - atomicAdd( &force[k], - fe_a1.f3 * fe_b.e * fe_a2.e - - fe_b.f * fe_a1.e * fe_a2.e - - (fe_a2.f1 + fe_a2.f3) * fe_b.e * fe_a1.e - ); - atomicAdd( &force[l], fe_a2.f3 * fe_b.e * fe_a1.e ); -} - __device__ inline void computeDihedral(const TabulatedDihedralPotential* __restrict__ d, const BaseGrid* __restrict__ sys, Vector3* forces, const Vector3* __restrict__ pos, diff --git a/src/TabulatedPotential.cu b/src/TabulatedPotential.cu index 8e48bc9..08bef40 100644 --- a/src/TabulatedPotential.cu +++ b/src/TabulatedPotential.cu @@ -181,71 +181,79 @@ int FullTabulatedPotential::countValueLines(const char* fileName) { return count; } -int countValueLines(const char* fileName) { - FILE* inp = fopen(fileName, "r"); - if (inp == NULL) { - printf("SimplePotential::countValueLines Could not open file '%s'\n", fileName); - exit(-1); - } - char line[256]; - int count = 0; - - while (fgets(line, 256, inp) != NULL) { - // Ignore comments. - int len = strlen(line); - if (line[0] == '#') continue; - if (len < 2) continue; - count++; - } - fclose(inp); - return count; -} - -SimplePotential::SimplePotential(const char* filename, SimplePotentialType type) : type(type) { - FILE* inp = fopen(filename, "r"); - if (inp == NULL) { - printf("SimplePotential::SimplePotential Could not open file '%s'\n", filename); - exit(-1); - } - - char line[256]; - - size = (unsigned int) countValueLines(filename); - float* r = new float[size]; - pot = new float[size]; - - int count = 0; - while (fgets(line, 256, inp) != NULL) { - // Ignore comments. - int len = strlen(line); - if (line[0] == '#') continue; - if (len < 2) continue; - - String s(line); - int numTokens = s.tokenCount(); - if (numTokens != 2) { - printf("SimplePotential::SimplePotential Invalid tabulated potential file line: %s\n", line); - exit(-1); - } - - String* tokenList = new String[numTokens]; - s.tokenize(tokenList); - if (tokenList == NULL) { - printf("SimplePotential::SimplePotential Invalid tabulated potential file line: %s\n", line); - exit(-1); - } - r[count] = (float) strtod(tokenList[0], NULL); - pot[count] = (float) strtod(tokenList[1], NULL); - count++; - - delete[] tokenList; - } - fclose(inp); +void TabulatedPotential::truncate(float cutoff) { + int home = int(floor((cutoff - r0)/dr)); + if (home > n) return; - if (type == BOND) { - step_inv = (size-1.0f) / (r[size-1]-r[0]); - } else { - step_inv = 57.29578f * (size-1.0f) / (r[size-1]-r[0]); + float v = v0[home]; + for (int i = home; i < n; i++) v0[i] = v; + interpolate(); +} + +bool TabulatedPotential::truncate(float switchDist, float cutoff, float value) { + int indOff = int(floor((cutoff - r0)/dr)); + int indSwitch = int(floor((switchDist - r0)/dr)); + + if (indSwitch > n) return false; + + // Set everything after the cutoff to "value". + for (int i = indOff; i < n; i++) v0[i] = value; + + // Apply a linear switch. + float v = v0[indSwitch]; + float m = (value - v)/(indOff - indSwitch); + for (int i = indSwitch; i < indOff; i++) v0[i] = m*(i - indSwitch) + v; + + interpolate(); + return true; +} + +Vector3 TabulatedPotential::computeForce(Vector3 r) { + float d = r.length(); + Vector3 rUnit = -r/d; + int home = int(floor((d - r0)/dr)); + + if (home < 0) return Vector3(0.0f); + if (home >= n) return Vector3(0.0f); + + float homeR = home*dr + r0; + float w = (d - homeR)/dr; + + // Interpolate. + Vector3 force = -(3.0f*v3[home]*w*w + 2.0f*v2[home]*w + v1[home])*rUnit/dr; + return force; +} + +void TabulatedPotential::init(const float* dist, const float* pot, int n0) { + n = abs(n0); + dr = dist[1]-dist[0]; + r0 = dist[0]; + r1 = r0 + n*dr; + + v0 = new float[n]; + for (int i = 0; i < n; i++) v0[i] = pot[i]; +} + +void TabulatedPotential::interpolate() { + v1 = new float[n]; + v2 = new float[n]; + v3 = new float[n]; + + for (int i = 0; i < n; i++) { + int i0 = i - 1; + int i1 = i; + int i2 = i + 1; + int i3 = i + 2; + + if (i0 < 0) i0 = 0; + if (i2 >= n) i2 = n-1; + if (i3 >= n) i3 = n-1; + + v3[i] = 0.5f*(-v0[i0] + 3.0f*v0[i1] - 3.0f*v0[i2] + v0[i3]); + v2[i] = 0.5f*(2.0f*v0[i0] - 5.0f*v0[i1] + 4.0f*v0[i2] - v0[i3]); + v1[i] = 0.5f*(-v0[i0] + v0[i2]); } - delete[] r; + e0 = v3[n-1] + v2[n-1] + v1[n-1] + v0[n-1]; } + +>>>>>>> parent of 7b4247c... Merge branch 'feat/bondangle' into release diff --git a/src/TabulatedPotential.h b/src/TabulatedPotential.h index 4a0f0fc..c0b0a70 100644 --- a/src/TabulatedPotential.h +++ b/src/TabulatedPotential.h @@ -7,27 +7,13 @@ #define HOST __host__ #define DEVICE __device__ #else - #define HOST - #define DEVICE + #define HOST + #define DEVICE #endif #include "useful.h" -#include "BaseGrid.h" - -#ifdef __CUDA_ARCH__ -#include "CudaUtil.cuh" -#endif - #include <cuda.h> -#define BD_PI 3.1415927f - -#ifndef gpuErrchk -#define delgpuErrchk -#define gpuErrchk(code) { if ((code) != cudaSuccess) { \ - fprintf(stderr,"CUDA Error: %s %s %d\n", cudaGetErrorString(code), __FILE__, __LINE__); \ - }} -#endif class EnergyForce { public: @@ -161,7 +147,7 @@ public: Vector3 force = (du*drInv/d)*r; return EnergyForce(energy,force); } - HOST DEVICE inline Vector3 computef(const Vector3 r, float d) const { + HOST DEVICE inline Vector3 computef(Vector3 r, float d) { d = sqrt(d); // float d = r.length(); // RBTODO: precompute so that initial blocks are zero; reduce computation here @@ -185,344 +171,4 @@ private: float drInv; //TODO replace with drInv float r0; }; - -/* // New unified/simplified classes for working with potentials */ -/* <template int num_indices, int max_integer> */ -/* class BitMaskInts { */ -/* BitMaskInts(); */ - -/* private: */ -/* static_assert( ceil(log2(max_integer)) <= CHAR_BIT ); */ - -/* char data[ ceil(num_indices * ceil(log2(max_integer)) / CHAR_BIT) ]; */ - -/* HOST DEVICE inline unsigned short int get_int(i) const { */ -/* unsigned int first_bit = i * ceil(log2(max_integer)); */ -/* unsigned int last_bit = (i+1) * ceil(log2(max_integer))-1; */ -/* char c0 = data[floor(first_bit/CHAR_BIT)]; */ -/* char c1 = data[floor(last_bit/CHAR_BIT)]; */ - -/* unsigned short int ret = c0 << (first_bit % CHAR_BIT) /\* shift left *\/ */ -/* }; */ - -/* } */ - - -enum SimplePotentialType { UNSET, BOND, ANGLE, DIHEDRAL, VECANGLE }; -// enum PotentialTypeAtoms { bond=2, angle=3, dihedral=4 }; - - -class SimplePotential { -public: - SimplePotential() { } - SimplePotential(const char* filename, SimplePotentialType type); - SimplePotential(float* pot, float step_inv, unsigned int size, SimplePotentialType type) : - pot(pot), step_inv(step_inv), size(size), type(type) { } - - - float* pot; // actual potential values - float step_inv; // angular increments of potential file - unsigned int size; // number of data points in the file - - SimplePotentialType type; - - /* float start = 0; */ - /* bool is_periodic = false; */ - - /* HOST void copy_to_device(SimplePotential* device_addr_p, unsigned int offset=0) { */ - /* /\* Assumes device_addr_p is already allocated, allocates space for pot *\/ */ - /* float* val, tmp; */ - /* gpuErrchk(cudaMalloc(&val, sizeof(float)*size)); // TODO equivalent cudaFree */ - /* gpuErrchk(cudaMemcpyAsync(val, pot, sizeof(float)*size, cudaMemcpyHostToDevice)); */ - /* tmp = pot; */ - /* pot = val; */ - /* gpuErrchk(cudaMemcpyAsync(device_addr_p+offset, this, sizeof(SimplePotential), cudaMemcpyHostToDevice)); */ - /* pot = tmp; */ - /* // return val; */ - /* } */ - - HOST DEVICE inline float compute_value(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - const int* __restrict__ particles) const { - float val; - if (type == BOND) - val = compute_bond(pos, sys, particles[0], particles[1]); - else if (type == ANGLE) - val = compute_angle(pos, sys, particles[0], particles[1], particles[2]); - else if (type == DIHEDRAL) - val = compute_dihedral(pos, sys, particles[0], particles[1], particles[2], particles[3]); - else if (type == VECANGLE) - val = compute_vecangle(pos, sys, particles[0], particles[1], particles[2], particles[3]); - return val; - } - - HOST DEVICE inline float2 compute_energy_and_deriv(float value) { - float2 ret; - if (type == DIHEDRAL) { - ret = linearly_interpolate<true>(value, -BD_PI); - } else { - ret = linearly_interpolate<false>(value); - } - return ret; - } - - HOST DEVICE inline float compute_bond(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - int i, int j) const { - return sys->wrapDiff( pos[j] - pos[i] ).length(); - } - - HOST DEVICE inline float compute_angle(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - int i, int j, int k) const { - const Vector3 ab = sys->wrapDiff(pos[j] - pos[i]); - const Vector3 bc = sys->wrapDiff(pos[k] - pos[j]); - const Vector3 ac = sys->wrapDiff(pos[k] - pos[i]); - return compute_angle( ab.length2(), bc.length2(), ac.length2() ); - } - - HOST DEVICE inline float compute_vecangle(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - int i, int j, int k, int l) const { - const Vector3 ab = sys->wrapDiff(pos[j] - pos[i]); - const Vector3 bc = sys->wrapDiff(pos[l] - pos[k]); - const Vector3 ac = bc+ab; - return compute_angle( ab.length2(), bc.length2(), ac.length2() ); - } - - HOST DEVICE inline float compute_angle(float distab2, float distbc2, float distac2) const { - // Find the cosine of the angle we want - <ABC - float cos = (distab2 + distbc2 - distac2); - - distab2 = 1.0f/sqrt(distab2); //TODO: test other functions - distbc2 = 1.0f/sqrt(distbc2); - cos *= 0.5f * distbc2 * distab2; - - // If the cosine is illegitimate, set it to 1 or -1 so that acos won't fail - if (cos < -1.0f) cos = -1.0f; - if (cos > 1.0f) cos = 1.0f; - - return acos(cos); - } - - HOST DEVICE inline float compute_dihedral(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - int i, int j, int k, int l) const { - const Vector3 ab = -sys->wrapDiff(pos[j] - pos[i]); - const Vector3 bc = -sys->wrapDiff(pos[k] - pos[j]); - const Vector3 cd = -sys->wrapDiff(pos[l] - pos[k]); - - const Vector3 crossABC = ab.cross(bc); - const Vector3 crossBCD = bc.cross(cd); - const Vector3 crossX = bc.cross(crossABC); - - const float cos_phi = crossABC.dot(crossBCD) / (crossABC.length() * crossBCD.length()); - const float sin_phi = crossX.dot(crossBCD) / (crossX.length() * crossBCD.length()); - - return -atan2(sin_phi,cos_phi); - } - - template <bool is_periodic> - HOST DEVICE inline float2 linearly_interpolate(float x, float start=0.0f) const { - float w = (x - start) * step_inv; - int signed_home = int( floorf(w) ); - w = w - signed_home; - // if (home < 0) return EnergyForce(v0[0], Vector3(0.0f)); - if (signed_home < 0) { - if (is_periodic) signed_home += size; - else return make_float2(pot[0],0.0f); - } - unsigned int home = signed_home; - if (home >= size) { - if (is_periodic) home -= size; - else return make_float2(pot[size-1],0.0f); - } - - float u0 = pot[home]; - float du = ((unsigned int) home+1) < size ? pot[home+1]-u0 : is_periodic ? pot[0]-u0 : 0; - - return make_float2(du*w+u0, du*step_inv); - } - - DEVICE inline void apply_force(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - Vector3* __restrict__ forces, - int* particles, float energy_deriv) const { - if (type == BOND) - apply_bond_force(pos, sys, forces, particles[0], particles[1], energy_deriv); - else if (type == ANGLE) - apply_angle_force(pos, sys, forces, particles[0], particles[1], - particles[2], energy_deriv); - else if (type == DIHEDRAL) - apply_dihedral_force(pos, sys, forces, particles[0], particles[1], - particles[2], particles[3], energy_deriv); - else if (type == VECANGLE) - apply_vecangle_force(pos, sys, forces, particles[0], particles[1], - particles[2], particles[3], energy_deriv); - } - - __device__ inline void apply_bond_force(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - Vector3* __restrict__ force, - int i, int j, float energy_deriv) const { -#ifdef __CUDA_ARCH__ - Vector3 f = sys->wrapDiff( pos[j] - pos[i] ); - f = f * energy_deriv / f.length(); - atomicAdd(&force[i], f); - atomicAdd(&force[j], -f); -#endif - } - - struct TwoVector3 { - Vector3 v1; - Vector3 v2; - }; - - DEVICE inline TwoVector3 get_angle_force(const Vector3& ab, - const Vector3& bc, - float energy_deriv) const { - // Find the distance between each pair of particles - float distab = ab.length2(); - float distbc = bc.length2(); - const float distac2 = (ab+bc).length2(); - - // Find the cosine of the angle we want - <ABC - float cos = (distab + distbc - distac2); - - distab = 1.0f/sqrt(distab); //TODO: test other functions - distbc = 1.0f/sqrt(distbc); - cos *= 0.5f * distbc * distab; - - // If the cosine is illegitimate, set it to 1 or -1 so that acos won't fail - if (cos < -1.0f) cos = -1.0f; - if (cos > 1.0f) cos = 1.0f; - - float sin = sqrtf(1.0f - cos*cos); - energy_deriv /= abs(sin) > 1e-3 ? sin : 1e-3; // avoid singularity - if (abs(sin) < 1e-3) { - printf("BAD ANGLE: sin, cos, energy_deriv, distab, distbc, distac2: (%f %f %f %f %f)\n", - sin,cos,energy_deriv,distab,distbc); } - - // Calculate the forces - TwoVector3 force; - force.v1 = (energy_deriv*distab) * (ab * (cos*distab) + bc * distbc); // force on 1st particle - force.v2 = -(energy_deriv*distbc) * (bc * (cos*distbc) + ab * distab); // force on last particle - return force; - } - - // DEVICE inline TwoVector3 get_angle_force(const Vector3& ab, - // const Vector3& bc, - // float energy_deriv) const { - // // Find the distance between each pair of particles - // float distab = ab.length2(); - // float distbc = bc.length2(); - - // float pre = distab*distbc - pow(ab.dot(bc),2); - // // if (pre < 1e-6) { - // // pre = 1e-3; - // // printf("BAD ANGLE: pre, energy_deriv, distab, distbc, ab.dot(bc): (%f %f %f %f %f)\n", - // // pre,energy_deriv,distab,distbc,ab.dot(bc)); - // // } else pre = sqrt(pre); - // // if (distab == distbc) { - // // printf("GOOD ANGLE: pre, energy_deriv, distab, distbc, ab.dot(bc): (%f %f %f %f %f)\n", - // // pre,energy_deriv,distab,distbc,ab.dot(bc)); - // // } - - // pre = pre > 1e-6 ? sqrt(pre) : 1e-3; - // energy_deriv /= pre; - - // TwoVector3 force; - // //force.v1 = energy_deriv * Vector3::element_mult( 1-Vector3::element_mult(ab,ab)/distab, bc); - // //force.v2 = energy_deriv * Vector3::element_mult( 1-Vector3::element_mult(bc,bc)/distbc, ab); - - // Vector3 abbc = Vector3::element_mult(-ab,bc); - // force.v1 = -energy_deriv * (bc-Vector3::element_mult(abbc, -ab/distab)); - // force.v2 = -energy_deriv * (-ab-Vector3::element_mult(abbc, bc/distbc)); - // return force; - // } - - DEVICE inline void apply_angle_force(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - Vector3* __restrict__ force, - int i, int j, int k, float energy_deriv) const { - -#ifdef __CUDA_ARCH__ - const Vector3 ab = sys->wrapDiff(pos[j] - pos[i]); - const Vector3 bc = sys->wrapDiff(pos[k] - pos[j]); - // const Vector3 ac = sys->wrapDiff(pos[k] - pos[i]); - - TwoVector3 f = get_angle_force(ab,bc, energy_deriv); - - atomicAdd( &force[i], f.v1 ); - atomicAdd( &force[j], -(f.v1 + f.v2) ); - atomicAdd( &force[k], f.v2 ); -#endif - } - - DEVICE inline void apply_dihedral_force(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - Vector3* __restrict__ force, - int i, int j, int k, int l, float energy_deriv) const { -#ifdef __CUDA_ARCH__ - const Vector3 ab = -sys->wrapDiff(pos[j] - pos[i]); - const Vector3 bc = -sys->wrapDiff(pos[k] - pos[j]); - const Vector3 cd = -sys->wrapDiff(pos[l] - pos[k]); - - const Vector3 crossABC = ab.cross(bc); - const Vector3 crossBCD = bc.cross(cd); - const Vector3 crossX = bc.cross(crossABC); - - const float cos_phi = crossABC.dot(crossBCD) / (crossABC.length() * crossBCD.length()); - const float sin_phi = crossX.dot(crossBCD) / (crossX.length() * crossBCD.length()); - - // return -atan2(sin_phi,cos_phi); - Vector3 f1, f2, f3; // forces - float distbc = bc.length(); - - f1 = -distbc * crossABC.rLength2() * crossABC; - f3 = -distbc * crossBCD.rLength2() * crossBCD; - f2 = -(ab.dot(bc) * bc.rLength2()) * f1 - (bc.dot(cd) * bc.rLength2()) * f3; - - // energy_deriv = (ab.length2()*bc.length2()*crossABC.rLength2() > 100.0f || bc.length2()*cd.length2()*crossBCD.rLength2() > 100.0f) ? 0.0f : energy_deriv; - /* if ( energy_deriv > 1000.0f ) */ - /* energy_deriv = 1000.0f; */ - /* if ( energy_deriv < -1000.0f ) */ - /* energy_deriv = -1000.0f; */ - - f1 *= energy_deriv; - f2 *= energy_deriv; - f3 *= energy_deriv; - - atomicAdd( &force[i], f1 ); - atomicAdd( &force[j], f2-f1 ); - atomicAdd( &force[k], f3-f2 ); - atomicAdd( &force[l], -f3 ); -#endif - } - DEVICE inline void apply_vecangle_force(const Vector3* __restrict__ pos, - const BaseGrid* __restrict__ sys, - Vector3* __restrict__ force, - int i, int j, int k, int l, float energy_deriv) const { - -#ifdef __CUDA_ARCH__ - - const Vector3 ab = -sys->wrapDiff(pos[j] - pos[i]); - const Vector3 bc = -sys->wrapDiff(pos[k] - pos[j]); - // const Vector3 ac = sys->wrapDiff(pos[k] - pos[i]); - - TwoVector3 f = get_angle_force(ab,bc, energy_deriv); - - atomicAdd( &force[i], f.v1 ); - atomicAdd( &force[j], -f.v1 ); - atomicAdd( &force[k], -f.v2 ); - atomicAdd( &force[l], f.v2 ); -#endif - } - -}; - -#ifndef delgpuErrchk -#undef delgpuErrchk -#undef gpuErrchk -#endif #endif -- GitLab