Commit 2d2f05ce authored by Andy Simmonett's avatar Andy Simmonett
Browse files

Merge branch 'master' of github.com:pandegroup/openmm into genpt

parents 94823d84 4d32047c
......@@ -53,11 +53,11 @@ real4 computeCross(real4 vec1, real4 vec2) {
/**
* Compute forces on donors.
*/
__kernel void computeDonorForces(__global real4* restrict forceBuffers, __global real* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict exclusions,
__kernel void computeDonorForces(__global real4* restrict forceBuffers, __global mixed* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict exclusions,
__global const int4* restrict donorAtoms, __global const int4* restrict acceptorAtoms, __global const int4* restrict donorBufferIndices, __local real4* posBuffer, real4 periodicBoxSize, real4 invPeriodicBoxSize,
real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ
PARAMETER_ARGUMENTS) {
real energy = 0;
mixed energy = 0;
real4 f1 = (real4) 0;
real4 f2 = (real4) 0;
real4 f3 = (real4) 0;
......@@ -142,7 +142,7 @@ __kernel void computeDonorForces(__global real4* restrict forceBuffers, __global
/**
* Compute forces on acceptors.
*/
__kernel void computeAcceptorForces(__global real4* restrict forceBuffers, __global real* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict exclusions,
__kernel void computeAcceptorForces(__global real4* restrict forceBuffers, __global mixed* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict exclusions,
__global const int4* restrict donorAtoms, __global const int4* restrict acceptorAtoms, __global const int4* restrict acceptorBufferIndices, __local real4* restrict posBuffer, real4 periodicBoxSize, real4 invPeriodicBoxSize,
real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ
PARAMETER_ARGUMENTS) {
......
......@@ -72,7 +72,7 @@ inline bool isInteractionExcluded(int atom1, int atom2, __global int* restrict e
* Compute the interaction.
*/
__kernel void computeInteraction(
__global long* restrict forceBuffers, __global real* restrict energyBuffer, __global const real4* restrict posq,
__global long* restrict forceBuffers, __global mixed* restrict energyBuffer, __global const real4* restrict posq,
real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ
#ifdef USE_CUTOFF
, __global const int* restrict neighbors, __global const int* restrict neighborStartIndex
......@@ -84,7 +84,7 @@ __kernel void computeInteraction(
, __global int* restrict exclusions, __global int* restrict exclusionStartIndex
#endif
PARAMETER_ARGUMENTS) {
real energy = 0.0f;
mixed energy = 0;
// Loop over particles to be the first one in the set.
......
......@@ -42,14 +42,14 @@ __kernel void computeInteractionGroups(
#else
__global real4* restrict forceBuffers,
#endif
__global real* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict groupData,
__global mixed* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict groupData,
real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ
PARAMETER_ARGUMENTS) {
const unsigned int totalWarps = get_global_size(0)/TILE_SIZE;
const unsigned int warp = get_global_id(0)/TILE_SIZE; // global warpIndex
const unsigned int tgx = get_local_id(0) & (TILE_SIZE-1); // index within the warp
const unsigned int tbx = get_local_id(0) - tgx; // block warpIndex
real energy = 0.0f;
mixed energy = 0;
__local AtomData localData[LOCAL_MEMORY_SIZE];
const unsigned int startTile = FIRST_TILE+warp*(LAST_TILE-FIRST_TILE)/totalWarps;
......
......@@ -6,13 +6,13 @@ real2 multofReal2(real2 a, real2 b) {
* Precompute the cosine and sine sums which appear in each force term.
*/
__kernel void calculateEwaldCosSinSums(__global real* restrict energyBuffer, __global const real4* restrict posq, __global real2* restrict cosSinSum, real4 reciprocalPeriodicBoxSize, real reciprocalCoefficient) {
__kernel void calculateEwaldCosSinSums(__global mixed* restrict energyBuffer, __global const real4* restrict posq, __global real2* restrict cosSinSum, real4 reciprocalPeriodicBoxSize, real reciprocalCoefficient) {
const unsigned int ksizex = 2*KMAX_X-1;
const unsigned int ksizey = 2*KMAX_Y-1;
const unsigned int ksizez = 2*KMAX_Z-1;
const unsigned int totalK = ksizex*ksizey*ksizez;
unsigned int index = get_global_id(0);
real energy = 0.0f;
mixed energy = 0;
while (index < (KMAX_Y-1)*ksizez+KMAX_Z)
index += get_global_size(0);
while (index < totalK) {
......
......@@ -387,7 +387,7 @@ __kernel void computeGBSAForce1(
#else
__global real4* restrict forceBuffers, __global real* restrict global_bornForce,
#endif
__global real* restrict energyBuffer, __global const real4* restrict posq, __global const real* restrict global_bornRadii,
__global mixed* restrict energyBuffer, __global const real4* restrict posq, __global const real* restrict global_bornRadii,
#ifdef USE_CUTOFF
__global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize,
real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter,
......@@ -400,7 +400,7 @@ __kernel void computeGBSAForce1(
const unsigned int warp = get_global_id(0)/TILE_SIZE;
const unsigned int tgx = get_local_id(0) & (TILE_SIZE-1);
const unsigned int tbx = get_local_id(0) - tgx;
real energy = 0.0f;
mixed energy = 0;
__local AtomData2 localData[FORCE_WORK_GROUP_SIZE];
// First loop: process tiles that contain exclusions.
......
......@@ -50,8 +50,8 @@ __kernel void reduceBornForce(int bufferSize, int numBuffers, __global real* bor
#ifdef SUPPORTS_64_BIT_ATOMICS
__global const long* restrict bornForceIn,
#endif
__global real* restrict energyBuffer, __global const float2* restrict params, __global const real* restrict bornRadii, __global const real* restrict obcChain) {
real energy = 0.0f;
__global mixed* restrict energyBuffer, __global const float2* restrict params, __global const real* restrict bornRadii, __global const real* restrict obcChain) {
mixed energy = 0;
unsigned int index = get_global_id(0);
while (index < NUM_ATOMS) {
// Sum the Born force
......
......@@ -409,7 +409,7 @@ __kernel void computeGBSAForce1(
#else
__global real4* restrict forceBuffers, __global real* restrict global_bornForce,
#endif
__global real* restrict energyBuffer, __global const real4* restrict posq, __global const real* restrict global_bornRadii,
__global mixed* restrict energyBuffer, __global const real4* restrict posq, __global const real* restrict global_bornRadii,
#ifdef USE_CUTOFF
__global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize,
real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter,
......@@ -418,7 +418,7 @@ __kernel void computeGBSAForce1(
unsigned int numTiles,
#endif
__global const ushort2* exclusionTiles) {
real energy = 0.0f;
mixed energy = 0;
__local AtomData2 localData[TILE_SIZE];
// First loop: process tiles that contain exclusions.
......
......@@ -22,7 +22,7 @@ __kernel void computeNonbonded(
#else
__global real4* restrict forceBuffers,
#endif
__global real* restrict energyBuffer, __global const real4* restrict posq, __global const unsigned int* restrict exclusions,
__global mixed* restrict energyBuffer, __global const real4* restrict posq, __global const unsigned int* restrict exclusions,
__global const ushort2* restrict exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices
#ifdef USE_CUTOFF
, __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize,
......@@ -429,6 +429,6 @@ __kernel void computeNonbonded(
pos++;
}
#ifdef INCLUDE_ENERGY
energyBuffer[get_global_id(0)] += (real) energy;
energyBuffer[get_global_id(0)] += energy;
#endif
}
......@@ -19,7 +19,7 @@ __kernel void computeNonbonded(
#else
__global real4* restrict forceBuffers,
#endif
__global real* restrict energyBuffer, __global const real4* restrict posq, __global const unsigned int* restrict exclusions,
__global mixed* restrict energyBuffer, __global const real4* restrict posq, __global const unsigned int* restrict exclusions,
__global const ushort2* restrict exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices
#ifdef USE_CUTOFF
, __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize,
......@@ -27,7 +27,7 @@ __kernel void computeNonbonded(
__global const real4* restrict blockSize, __global const int* restrict interactingAtoms
#endif
PARAMETER_ARGUMENTS) {
real energy = 0;
mixed energy = 0;
__local AtomData localData[TILE_SIZE];
// First loop: process tiles that contain exclusions.
......
......@@ -325,14 +325,14 @@ __kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global c
}
}
__kernel void gridEvaluateEnergy(__global real2* restrict pmeGrid, __global real* restrict energyBuffer,
__kernel void gridEvaluateEnergy(__global real2* restrict pmeGrid, __global mixed* restrict energyBuffer,
__global const real* restrict pmeBsplineModuliX, __global const real* restrict pmeBsplineModuliY, __global const real* restrict pmeBsplineModuliZ,
real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) {
// R2C stores into a half complex matrix where the last dimension is cut by half
const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z;
const real recipScaleFactor = (1.0f/M_PI)*recipBoxVecX.x*recipBoxVecY.y*recipBoxVecZ.z;
real energy = 0;
mixed energy = 0;
for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) {
// real indices
int kx = index/(GRID_SIZE_Y*(GRID_SIZE_Z));
......@@ -362,7 +362,7 @@ __kernel void gridEvaluateEnergy(__global real2* restrict pmeGrid, __global real
energy += eterm*(grid.x*grid.x + grid.y*grid.y);
}
}
energyBuffer[get_global_id(0)] += 0.5f*energy;
energyBuffer[get_global_id(0)] = 0.5f*energy;
}
__kernel void gridInterpolateForce(__global const real4* restrict posq, __global real4* restrict forceBuffers, __global const real* restrict pmeGrid,
......@@ -445,3 +445,8 @@ __kernel void addForces(__global const real4* restrict forces, __global real4* r
for (int atom = get_global_id(0); atom < NUM_ATOMS; atom += get_global_size(0))
forceBuffers[atom] += forces[atom];
}
__kernel void addEnergy(__global const mixed* restrict pmeEnergyBuffer, __global mixed* restrict energyBuffer, int bufferSize) {
for (int i = get_global_id(0); i < bufferSize; i += get_global_size(0))
energyBuffer[i] += pmeEnergyBuffer[i];
}
......@@ -8,6 +8,11 @@ ENABLE_TESTING()
INCLUDE_DIRECTORIES(${OPENCL_INCLUDE_DIR})
SET(OPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS TRUE CACHE BOOL "Whether to build double precision versions of OpenCL test cases")
set(OPENCL_TEST_PLATFORM_INDEX -1 CACHE STRING "OpenCL platform index used for running OpenCL test cases. The default, -1, selects the fastest platform")
set(OPENCL_TEST_DEVICE_INDEX -1 CACHE STRING "OpenCL device index used for running OpenCL test cases. The default, -1, selects the fastest device")
MARK_AS_ADVANCED(OPENCL_TEST_PLATFORM_INDEX)
MARK_AS_ADVANCED(OPENCL_TEST_DEVICE_INDEX)
SET( INCLUDE_SERIALIZATION FALSE )
#SET( INCLUDE_SERIALIZATION TRUE )
......@@ -27,10 +32,10 @@ FOREACH(TEST_PROG ${TEST_PROGS})
TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_TARGET})
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}")
ADD_TEST(${TEST_ROOT}Single ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} single)
ADD_TEST(${TEST_ROOT}Single ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} single ${OPENCL_TEST_PLATFORM_INDEX} ${OPENCL_TEST_DEVICE_INDEX})
IF (OPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS)
ADD_TEST(${TEST_ROOT}Mixed ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} mixed)
ADD_TEST(${TEST_ROOT}Double ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} double)
ADD_TEST(${TEST_ROOT}Mixed ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} mixed ${OPENCL_TEST_PLATFORM_INDEX} ${OPENCL_TEST_DEVICE_INDEX})
ADD_TEST(${TEST_ROOT}Double ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} double ${OPENCL_TEST_PLATFORM_INDEX} ${OPENCL_TEST_DEVICE_INDEX})
ENDIF(OPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS)
# Link with static library
......
......@@ -40,4 +40,8 @@ OpenMM::OpenCLPlatform platform;
void initializeTests(int argc, char* argv[]) {
if (argc > 1)
platform.setPropertyDefaultValue("OpenCLPrecision", std::string(argv[1]));
if (argc > 2)
platform.setPropertyDefaultValue("OpenCLPlatformIndex", std::string(argv[2]));
if (argc > 3)
platform.setPropertyDefaultValue("OpenCLDeviceIndex", std::string(argv[3]));
}
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2015 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* 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, CONTRIBUTORS 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 "OpenCLTests.h"
#include "TestCompoundIntegrator.h"
void runPlatformTests() {
}
/**
* This file is adapted from vexcl's (https://github.com/ddemidov/vexcl)
* example "devlist.cpp", which is
*
* Copyright (c) 2012-2014 Denis Demidov <dennis.demidov@gmail.com>
*
* 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 <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#include <set>
#include <algorithm>
#include <vector>
#include "OpenCLContext.h"
using namespace std;
#define SHOW_DEVPROP(name) \
cout << " " << left << setw(32) << #name << " = " \
<< d.getInfo< name >() << endl
int main() {
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
cout << "OpenCL devices:" << endl << endl;
for (int j = 0; j < platforms.size(); j++) {
vector<cl::Device> devices;
platforms[j].getDevices(CL_DEVICE_TYPE_ALL, &devices);
for (int i = 0; i < devices.size(); i++) {
cl::Device d = devices[i];
cout << "OpenCLPlatformIndex " << j << ", OpenCLDeviceIndex " << i << ": \"" << d.getInfo<CL_DEVICE_NAME>()
<< "\"" << endl << " " << left << setw(32) << "CL_PLATFORM_NAME" << " = "
<< cl::Platform(d.getInfo<CL_DEVICE_PLATFORM>()).getInfo<CL_PLATFORM_NAME>()
<< endl
<< " " << left << setw(32) << "CL_PLATFORM_VENDOR" << " = "
<< platforms[j].getInfo<CL_PLATFORM_VENDOR>()
<< endl;
SHOW_DEVPROP(CL_DEVICE_VENDOR);
SHOW_DEVPROP(CL_DEVICE_VERSION);
cout << " " << left << setw(32) << "CL_DEVICE_TYPE" << " = ";
if (d.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_CPU) {
cout << "CL_DEVICE_TYPE_CPU" << endl;
} else if (d.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_GPU) {
cout << "CL_DEVICE_TYPE_GPU" << endl;
} else if (d.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_ACCELERATOR) {
cout << "CL_DEVICE_TYPE_ACCELERATOR" << endl;
} else {
cout << "Unknown" << endl;
}
SHOW_DEVPROP(CL_DEVICE_MAX_COMPUTE_UNITS);
cout << " " << left << setw(32) << "CL_DEVICE_MAX_WORK_ITEM_SIZES" << " = [";
for (int k = 0; k < d.getInfo<CL_DEVICE_MAX_WORK_ITEM_SIZES>().size(); k++) {
cout << d.getInfo<CL_DEVICE_MAX_WORK_ITEM_SIZES>()[k];
if (k < d.getInfo<CL_DEVICE_MAX_WORK_ITEM_SIZES>().size() - 1)
cout << ", ";
}
cout << "]" << endl;
SHOW_DEVPROP(CL_DEVICE_HOST_UNIFIED_MEMORY);
SHOW_DEVPROP(CL_DEVICE_GLOBAL_MEM_SIZE);
SHOW_DEVPROP(CL_DEVICE_LOCAL_MEM_SIZE);
SHOW_DEVPROP(CL_DEVICE_MAX_MEM_ALLOC_SIZE);
SHOW_DEVPROP(CL_DEVICE_ADDRESS_BITS);
SHOW_DEVPROP(CL_DEVICE_MAX_CLOCK_FREQUENCY);
int processingElementsPerComputeUnit;
if (d.getInfo<CL_DEVICE_TYPE>() != CL_DEVICE_TYPE_GPU) {
processingElementsPerComputeUnit = 1;
} else if (d.getInfo<CL_DEVICE_EXTENSIONS>().find("cl_nv_device_attribute_query") != string::npos) {
cl_uint computeCapabilityMajor;
#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
clGetDeviceInfo(d(), CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, sizeof(cl_uint), &computeCapabilityMajor, NULL);
processingElementsPerComputeUnit = (computeCapabilityMajor < 2 ? 8 : 32);
#endif
} else if (d.getInfo<CL_DEVICE_EXTENSIONS>().find("cl_amd_device_attribute_query") != string::npos) {
#ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
try {
processingElementsPerComputeUnit = d.getInfo<CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD>() *
d.getInfo<CL_DEVICE_SIMD_WIDTH_AMD>() *
d.getInfo<CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD>();
} catch (cl::Error err) {}
#endif
}
cout << " processingElementsPerComputeUnit" << " = " << processingElementsPerComputeUnit << endl;
int speed = devices[i].getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>()*processingElementsPerComputeUnit*d.getInfo<CL_DEVICE_MAX_CLOCK_FREQUENCY>();
cout << " estimatedSpeed = " << speed << endl;
cout << " " << left << setw(32) << "CL_DEVICE_EXTENSIONS" << " = ";
istringstream iss(d.getInfo<CL_DEVICE_EXTENSIONS>());
set<string> extensions;
extensions.insert(istream_iterator<string>(iss), istream_iterator<string>());
size_t w = 40;
for (set<string>::iterator s = extensions.begin(); s != extensions.end(); ++s) {
w += s->length() + 1;
if (w > 80) {
cout << endl << setw(w = 8) << "";
w += s->length() + 1;
}
cout << *s << " ";
}
cout << endl << endl;
}
}
}
/* Portions copyright (c) 2006-2009 Stanford University and Simbios.
* Contributors: Pande Group
*
* 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, CONTRIBUTORS 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.
*/
#ifndef __GBVIParameters_H__
#define __GBVIParameters_H__
#include "RealVec.h"
#include <vector>
namespace OpenMM {
class GBVIParameters {
public:
/**
* This is an enumeration of the different methods that may be used for scaling of the Born radii.
*/
enum BornRadiusScalingMethod {
/**
* No scaling method is applied.
*/
NoScaling = 0,
/**
* Use quintic spline scaling function
*/
QuinticSpline = 1
};
private:
int _numberOfAtoms;
RealOpenMM _solventDielectric;
RealOpenMM _soluteDielectric;
RealOpenMM _electricConstant;
// parameter vectors
std::vector<RealOpenMM> _atomicRadii;
std::vector<RealOpenMM> _scaledRadii;
std::vector<RealOpenMM> _gammaParameters;
// cutoff and periodic boundary conditions
bool _cutoff;
bool _periodic;
OpenMM::RealVec _periodicBoxVectors[3];
RealOpenMM _cutoffDistance;
int _bornRadiusScalingMethod;
RealOpenMM _quinticLowerLimitFactor;
RealOpenMM _quinticUpperBornRadiusLimit;
public:
/**---------------------------------------------------------------------------------------
GBVIParameters constructor (Simbios)
@param numberOfAtoms number of atoms
--------------------------------------------------------------------------------------- */
GBVIParameters(int numberOfAtoms);
/**---------------------------------------------------------------------------------------
GBVIParameters destructor (Simbios)
--------------------------------------------------------------------------------------- */
~GBVIParameters();
/**---------------------------------------------------------------------------------------
Get number of atoms
@return number of atoms
--------------------------------------------------------------------------------------- */
int getNumberOfAtoms() const;
/**---------------------------------------------------------------------------------------
Get electric constant
@return electric constant
--------------------------------------------------------------------------------------- */
RealOpenMM getElectricConstant() const;
/**---------------------------------------------------------------------------------------
Get solvent dielectric
@return solvent dielectric
--------------------------------------------------------------------------------------- */
RealOpenMM getSolventDielectric() const;
/**---------------------------------------------------------------------------------------
Set solvent dielectric
@param solventDielectric solvent dielectric
--------------------------------------------------------------------------------------- */
void setSolventDielectric(RealOpenMM solventDielectric);
/**---------------------------------------------------------------------------------------
Get solute dielectric
@return soluteDielectric
--------------------------------------------------------------------------------------- */
RealOpenMM getSoluteDielectric() const;
/**---------------------------------------------------------------------------------------
Set solute dielectric
@param soluteDielectric solute dielectric
--------------------------------------------------------------------------------------- */
void setSoluteDielectric(RealOpenMM soluteDielectric);
/**---------------------------------------------------------------------------------------
Return scaled radii
@return array
--------------------------------------------------------------------------------------- */
const std::vector<RealOpenMM>& getScaledRadii() const;
/**---------------------------------------------------------------------------------------
Return scaled radii
@return array
--------------------------------------------------------------------------------------- */
void setScaledRadii(const std::vector<RealOpenMM>& scaledRadii);
/**---------------------------------------------------------------------------------------
Get AtomicRadii array w/ dielectric offset applied
@return array of atom volumes
--------------------------------------------------------------------------------------- */
const std::vector<RealOpenMM>& getAtomicRadii() const;
/**---------------------------------------------------------------------------------------
Set AtomicRadii array
@param atomicRadii vector of atomic radii
--------------------------------------------------------------------------------------- */
void setAtomicRadii(const std::vector<RealOpenMM>& atomicRadii);
/**---------------------------------------------------------------------------------------
Get GammaParameters array
@return array of gamma values
--------------------------------------------------------------------------------------- */
const std::vector<RealOpenMM>& getGammaParameters() const;
/**---------------------------------------------------------------------------------------
Set GammaParameters array
@param gammaParameters array of gamma parameters
--------------------------------------------------------------------------------------- */
void setGammaParameters(const std::vector<RealOpenMM>& gammaParameters);
/**---------------------------------------------------------------------------------------
Set the force to use a cutoff.
@param distance the cutoff distance
--------------------------------------------------------------------------------------- */
void setUseCutoff(RealOpenMM distance);
/**---------------------------------------------------------------------------------------
Get whether to use a cutoff.
--------------------------------------------------------------------------------------- */
bool getUseCutoff();
/**---------------------------------------------------------------------------------------
Get the cutoff distance.
--------------------------------------------------------------------------------------- */
RealOpenMM getCutoffDistance();
/**---------------------------------------------------------------------------------------
Set the force to use periodic boundary conditions. This requires that a cutoff has
already been set, and the smallest side of the periodic box is at least twice the cutoff
distance.
@param vectors the vectors defining the periodic box
--------------------------------------------------------------------------------------- */
void setPeriodic(OpenMM::RealVec* vectors);
/**---------------------------------------------------------------------------------------
Get whether to use periodic boundary conditions.
--------------------------------------------------------------------------------------- */
bool getPeriodic();
/**---------------------------------------------------------------------------------------
Get the periodic box dimension
--------------------------------------------------------------------------------------- */
const OpenMM::RealVec* getPeriodicBox();
/**---------------------------------------------------------------------------------------
Get tau prefactor
@return (1/e1 - 1/e0), where e1 = solute dielectric, e0 = solvent dielectric
--------------------------------------------------------------------------------------- */
RealOpenMM getTau() const;
/**---------------------------------------------------------------------------------------
Get bornRadiusScalingMethod
@return bornRadiusScalingMethod
--------------------------------------------------------------------------------------- */
int getBornRadiusScalingMethod() const;
/**---------------------------------------------------------------------------------------
Set bornRadiusScalingMethod
@param bornRadiusScalingMethod bornRadiusScalingMethod
--------------------------------------------------------------------------------------- */
void setBornRadiusScalingMethod(int bornRadiusScalingMethod);
/**---------------------------------------------------------------------------------------
Get quinticLowerLimitFactor
@return quinticLowerLimitFactor
--------------------------------------------------------------------------------------- */
RealOpenMM getQuinticLowerLimitFactor() const;
/**---------------------------------------------------------------------------------------
Set quinticLowerLimitFactor
@param quinticLowerLimitFactor quinticLowerLimitFactor
--------------------------------------------------------------------------------------- */
void setQuinticLowerLimitFactor(RealOpenMM quinticLowerLimitFactor);
/**---------------------------------------------------------------------------------------
Get quinticUpperBornRadiusLimit
@return quinticUpperBornRadiusLimit
--------------------------------------------------------------------------------------- */
RealOpenMM getQuinticUpperBornRadiusLimit() const;
/**---------------------------------------------------------------------------------------
Set quinticUpperBornRadiusLimit
@param quinticUpperBornRadiusLimit quinticUpperBornRadiusLimit
--------------------------------------------------------------------------------------- */
void setQuinticUpperBornRadiusLimit(RealOpenMM quinticUpperSplineLimit);
};
} // namespace OpenMM
#endif // __GBVIParameters_H__
/* Portions copyright (c) 2006 Stanford University and Simbios.
* Contributors: Pande Group
*
* 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, CONTRIBUTORS 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.
*/
#ifndef __ReferenceGBVI_H__
#define __ReferenceGBVI_H__
#include <vector>
#include "RealVec.h"
#include "GBVIParameters.h"
namespace OpenMM {
class ReferenceGBVI {
private:
// GB/VI parameters
GBVIParameters* _gbviParameters;
std::vector<RealOpenMM> _switchDeriviative;
public:
/**---------------------------------------------------------------------------------------
Constructor
@param implicitSolventParameters ImplicitSolventParameters reference
@return CpuImplicitSolvent object
--------------------------------------------------------------------------------------- */
ReferenceGBVI(GBVIParameters* gbviParameters);
/**---------------------------------------------------------------------------------------
Destructor
--------------------------------------------------------------------------------------- */
~ReferenceGBVI();
/**---------------------------------------------------------------------------------------
Return GBVIParameters
@return GBVIParameters
--------------------------------------------------------------------------------------- */
GBVIParameters* getGBVIParameters() const;
/**---------------------------------------------------------------------------------------
Set ImplicitSolventParameters
@param ImplicitSolventParameters
--------------------------------------------------------------------------------------- */
void setGBVIParameters(GBVIParameters* gbviParameters);
/**---------------------------------------------------------------------------------------
Get Born radii based on Eq. 3 of Labute paper [JCC 29 p. 1693-1698 2008])
@param atomCoordinates atomic coordinates
@param bornRadii output array of Born radii
@param gbviChain not used
--------------------------------------------------------------------------------------- */
void computeBornRadii(const std::vector<OpenMM::RealVec>& atomCoordinates, std::vector<RealOpenMM>& bornRadii);
/**---------------------------------------------------------------------------------------
Get volume Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return volume
--------------------------------------------------------------------------------------- */
static RealOpenMM getVolume(RealOpenMM r, RealOpenMM R, RealOpenMM S);
/**---------------------------------------------------------------------------------------
Get L (analytical solution for volume integrals)
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return L value (Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
--------------------------------------------------------------------------------------- */
static RealOpenMM getL(RealOpenMM r, RealOpenMM x, RealOpenMM S);
/**---------------------------------------------------------------------------------------
Get partial derivative of L wrt r
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return partial derivative based on Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
--------------------------------------------------------------------------------------- */
static RealOpenMM dL_dr(RealOpenMM r, RealOpenMM x, RealOpenMM S);
/**---------------------------------------------------------------------------------------
Get partial derivative of L wrt x
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return partial derivative based on Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
--------------------------------------------------------------------------------------- */
static RealOpenMM dL_dx(RealOpenMM r, RealOpenMM x, RealOpenMM S);
/**---------------------------------------------------------------------------------------
Sgb function
@param t r*r*G_i*G_j
@return Sgb (p. 1694 of Labute paper [JCC 29 p. 1693-1698 2008])
--------------------------------------------------------------------------------------- */
static RealOpenMM Sgb(RealOpenMM t);
/**---------------------------------------------------------------------------------------
Get GB/VI energy
@param atomCoordinates atomic coordinates
@param partialCharges partial charges
@return energy
--------------------------------------------------------------------------------------- */
RealOpenMM computeBornEnergy(const std::vector<OpenMM::RealVec>& atomCoordinates, const std::vector<RealOpenMM>& partialCharges);
/**---------------------------------------------------------------------------------------
Get GB/VI forces
@param atomCoordinates atomic coordinates
@param partialCharges partial charges
@param forces output forces
--------------------------------------------------------------------------------------- */
void computeBornForces(std::vector<OpenMM::RealVec>& atomCoordinates,
const std::vector<RealOpenMM>& partialCharges, std::vector<OpenMM::RealVec>& inputForces);
/**---------------------------------------------------------------------------------------
Get volume Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return volume
--------------------------------------------------------------------------------------- */
static double getVolumeD(double r, double R, double S);
/**---------------------------------------------------------------------------------------
Get L (analytical solution for volume integrals)
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return L value (Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
--------------------------------------------------------------------------------------- */
static double getLD(double r, double x, double S);
/**---------------------------------------------------------------------------------------
Get partial derivative of L wrt r
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return partial derivative based on Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
--------------------------------------------------------------------------------------- */
static double dL_drD(double r, double x, double S);
/**---------------------------------------------------------------------------------------
Get partial derivative of L wrt x
@param r distance between atoms i & j
@param R atomic radius
@param S scaled atomic radius
@return partial derivative based on Eq. 4 of Labute paper [JCC 29 p. 1693-1698 2008])
--------------------------------------------------------------------------------------- */
static double dL_dxD(double r, double x, double S);
/**---------------------------------------------------------------------------------------
Return OBC chain derivative: size = _obcParameters->getNumberOfAtoms()
On first call, memory for array is allocated if not set
@return array
--------------------------------------------------------------------------------------- */
std::vector<RealOpenMM>& getSwitchDeriviative();
/**---------------------------------------------------------------------------------------
Compute quintic spline value and associated derviative
@param x value to compute spline at
@param rl lower cutoff value
@param ru upper cutoff value
@param outValue value of spline at x
@param outDerivative value of derivative of spline at x
--------------------------------------------------------------------------------------- */
void quinticSpline(RealOpenMM x, RealOpenMM rl, RealOpenMM ru,
RealOpenMM* outValue, RealOpenMM* outDerivative);
/**---------------------------------------------------------------------------------------
Compute Born radii based on Eq. 3 of Labute paper [JCC 29 p. 1693-1698 2008])
and quintic splice switching function
@param atomicRadius3 atomic radius cubed
@param bornSum Born sum (volume integral)
@param gbviParameters Gbvi parameters (parameters used in spline
QuinticLowerLimitFactor & QuinticUpperBornRadiusLimit)
@param bornRadius output Born radius
@param switchDeriviative output switching function deriviative
--------------------------------------------------------------------------------------- */
void computeBornRadiiUsingQuinticSpline(RealOpenMM atomicRadius3, RealOpenMM bornSum,
GBVIParameters* gbviParameters,
RealOpenMM* bornRadius, RealOpenMM* switchDeriviative);
};
} // namespace OpenMM
#endif // __ReferenceGBVI_H__
......@@ -43,7 +43,6 @@
namespace OpenMM {
class ReferenceObc;
class ReferenceGBVI;
class ReferenceAndersenThermostat;
class ReferenceCustomCentroidBondIxn;
class ReferenceCustomCompoundBondIxn;
......@@ -683,37 +682,6 @@ private:
bool isPeriodic;
};
/**
* This kernel is invoked by GBVIForce to calculate the forces acting on the system.
*/
class ReferenceCalcGBVIForceKernel : public CalcGBVIForceKernel {
public:
ReferenceCalcGBVIForceKernel(std::string name, const Platform& platform) : CalcGBVIForceKernel(name, platform) {
}
~ReferenceCalcGBVIForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the GBVIForce this kernel will be used for
* @param scaled radii the scaled radii (Eq. 5 of Labute paper)
*/
void initialize(const System& system, const GBVIForce& force, const std::vector<double> & scaledRadii);
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @param includeForces true if forces should be calculated
* @param includeEnergy true if the energy should be calculated
* @return the potential energy due to the force
*/
double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
private:
ReferenceGBVI * gbvi;
std::vector<RealOpenMM> charges;
bool isPeriodic;
};
/**
* This kernel is invoked by CustomGBForce to calculate the forces acting on the system.
*/
......
......@@ -70,8 +70,6 @@ KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Pla
return new ReferenceCalcCustomTorsionForceKernel(name, platform);
if (name == CalcGBSAOBCForceKernel::Name())
return new ReferenceCalcGBSAOBCForceKernel(name, platform);
if (name == CalcGBVIForceKernel::Name())
return new ReferenceCalcGBVIForceKernel(name, platform);
if (name == CalcCustomGBForceKernel::Name())
return new ReferenceCalcCustomGBForceKernel(name, platform);
if (name == CalcCustomExternalForceKernel::Name())
......
......@@ -31,7 +31,6 @@
#include "ReferenceKernels.h"
#include "ReferenceObc.h"
#include "ReferenceGBVI.h"
#include "ReferenceAndersenThermostat.h"
#include "ReferenceAngleBondIxn.h"
#include "ReferenceBondForce.h"
......@@ -1224,69 +1223,6 @@ void ReferenceCalcGBSAOBCForceKernel::copyParametersToContext(ContextImpl& conte
obcParameters->setScaledRadiusFactors(scaleFactors);
}
ReferenceCalcGBVIForceKernel::~ReferenceCalcGBVIForceKernel() {
if (gbvi) {
GBVIParameters * gBVIParameters = gbvi->getGBVIParameters();
delete gBVIParameters;
delete gbvi;
}
}
void ReferenceCalcGBVIForceKernel::initialize(const System& system, const GBVIForce& force, const std::vector<double> & inputScaledRadii) {
int numParticles = system.getNumParticles();
charges.resize(numParticles);
vector<RealOpenMM> atomicRadii(numParticles);
vector<RealOpenMM> scaledRadii(numParticles);
vector<RealOpenMM> gammas(numParticles);
for (int i = 0; i < numParticles; ++i) {
double charge, radius, gamma;
force.getParticleParameters(i, charge, radius, gamma);
charges[i] = static_cast<RealOpenMM>(charge);
atomicRadii[i] = static_cast<RealOpenMM>(radius);
gammas[i] = static_cast<RealOpenMM>(gamma);
scaledRadii[i] = static_cast<RealOpenMM>(inputScaledRadii[i]);
}
GBVIParameters * gBVIParameters = new GBVIParameters(numParticles);
gBVIParameters->setAtomicRadii(atomicRadii);
gBVIParameters->setGammaParameters(gammas);
gBVIParameters->setScaledRadii(scaledRadii);
gBVIParameters->setSolventDielectric(static_cast<RealOpenMM>(force.getSolventDielectric()));
gBVIParameters->setSoluteDielectric(static_cast<RealOpenMM>(force.getSoluteDielectric()));
gBVIParameters->setBornRadiusScalingMethod(force.getBornRadiusScalingMethod());
gBVIParameters->setQuinticUpperBornRadiusLimit(static_cast<RealOpenMM>(force.getQuinticUpperBornRadiusLimit()));
gBVIParameters->setQuinticLowerLimitFactor(static_cast<RealOpenMM>(force.getQuinticLowerLimitFactor()));
if (force.getNonbondedMethod() != GBVIForce::NoCutoff)
gBVIParameters->setUseCutoff(static_cast<RealOpenMM>(force.getCutoffDistance()));
isPeriodic = (force.getNonbondedMethod() == GBVIForce::CutoffPeriodic);
gbvi = new ReferenceGBVI(gBVIParameters);
}
double ReferenceCalcGBVIForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& posData = extractPositions(context);
if (isPeriodic)
gbvi->getGBVIParameters()->setPeriodic(extractBoxVectors(context));
RealOpenMM energy;
if (includeForces) {
vector<RealVec>& forceData = extractForces(context);
gbvi->computeBornForces(posData, charges, forceData);
energy = 0.0;
}
if (includeEnergy) {
energy = gbvi->computeBornEnergy(posData, charges);
}
return static_cast<double>(energy);
}
ReferenceCalcCustomGBForceKernel::~ReferenceCalcCustomGBForceKernel() {
disposeRealArray(particleParamArray, numParticles);
if (neighborList != NULL)
......@@ -1488,6 +1424,8 @@ double ReferenceCalcCustomExternalForceKernel::PeriodicDistanceFunction::evaluat
delta -= boxVectors[1]*floor(delta[1]/boxVectors[1][1]+0.5);
delta -= boxVectors[0]*floor(delta[0]/boxVectors[0][0]+0.5);
double r = sqrt(delta.dot(delta));
if (r == 0)
return 0.0;
if (argIndex < 3)
return delta[argIndex]/r;
return -delta[argIndex-3]/r;
......
......@@ -58,7 +58,6 @@ ReferencePlatform::ReferencePlatform() {
registerKernelFactory(CalcNonbondedForceKernel::Name(), factory);
registerKernelFactory(CalcCustomNonbondedForceKernel::Name(), factory);
registerKernelFactory(CalcGBSAOBCForceKernel::Name(), factory);
registerKernelFactory(CalcGBVIForceKernel::Name(), factory);
registerKernelFactory(CalcCustomGBForceKernel::Name(), factory);
registerKernelFactory(CalcCustomExternalForceKernel::Name(), factory);
registerKernelFactory(CalcCustomHbondForceKernel::Name(), factory);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment