"platforms/cuda-old/src/kernels/kCalculateCDLJForces.h" did not exist on "630bdd40e9c65fb22e471712fd378f98473c3456"
Commit 19d2885a authored by Lee-Ping's avatar Lee-Ping
Browse files

Merge github.com:SimTk/openmm

parents 99ef4344 57a6768e
......@@ -32,8 +32,8 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/serialization/internal/windowsExportDrudeSerialization.h"
#include "openmm/serialization/SerializationProxy.h"
#include "openmm/internal/windowsExportDrude.h"
namespace OpenMM {
......@@ -41,7 +41,7 @@ namespace OpenMM {
* This is a proxy for serializing DrudeLangevinIntegrator objects.
*/
class OPENMM_EXPORT_DRUDE_SERIALIZATION DrudeLangevinIntegratorProxy : public SerializationProxy {
class OPENMM_EXPORT_DRUDE DrudeLangevinIntegratorProxy : public SerializationProxy {
public:
DrudeLangevinIntegratorProxy();
void serialize(const void* object, SerializationNode& node) const;
......
#ifndef OPENMM_WINDOWSEXPORTDRUDESERIALIZATION_H_
#define OPENMM_WINDOWSEXPORTDRUDESERIALIZATION_H_
/*
* Shared libraries are messy in Visual Studio. We have to distinguish three
* cases:
* (1) this header is being used to build the OpenMM shared library
* (dllexport)
* (2) this header is being used by a *client* of the OpenMM shared
* library (dllimport)
* (3) we are building the OpenMM static library, or the client is
* being compiled with the expectation of linking with the
* OpenMM static library (nothing special needed)
* In the CMake script for building this library, we define one of the symbols
* OPENMM_DRUDE_SERIALIZATION_BUILDING_{SHARED|STATIC}_LIBRARY
* Client code normally has no special symbol defined, in which case we'll
* assume it wants to use the shared library. However, if the client defines
* the symbol OPENMM_USE_STATIC_LIBRARIES we'll suppress the dllimport so
* that the client code can be linked with static libraries. Note that
* the client symbol is not library dependent, while the library symbols
* affect only the OpenMM library, meaning that other libraries can
* be clients of this one. However, we are assuming all-static or all-shared.
*/
#ifdef _MSC_VER
// We don't want to hear about how sprintf is "unsafe".
#pragma warning(disable:4996)
// Keep MS VC++ quiet about lack of dll export of private members.
#pragma warning(disable:4251)
#if defined(OPENMM_DRUDE_SERIALIZATION_BUILDING_SHARED_LIBRARY)
#define OPENMM_EXPORT_DRUDE_SERIALIZATION __declspec(dllexport)
#elif defined(OPENMM_DRUDE_SERIALIZATION_BUILDING_STATIC_LIBRARY) || defined(OPENMM_DRUDE_SERIALIZATION_USE_STATIC_LIBRARIES)
#define OPENMM_EXPORT_DRUDE_SERIALIZATION
#else
#define OPENMM_EXPORT_DRUDE_SERIALIZATION __declspec(dllimport) // i.e., a client of a shared library
#endif
#else
#define OPENMM_EXPORT_DRUDE_SERIALIZATION // Linux, Mac
#endif
#endif // OPENMM_WINDOWSEXPORTDRUDESERIALIZATION_H_
......@@ -47,11 +47,10 @@
#include "openmm/serialization/DrudeForceProxy.h"
#include "openmm/serialization/DrudeLangevinIntegratorProxy.h"
#include "openmm/serialization/internal/windowsExportDrudeSerialization.h"
#if defined(WIN32)
#include <windows.h>
extern "C" OPENMM_EXPORT_DRUDE_SERIALIZATION void registerDrudeSerializationProxies();
extern "C" OPENMM_EXPORT_DRUDE void registerDrudeSerializationProxies();
BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
registerDrudeSerializationProxies();
......@@ -63,7 +62,7 @@
using namespace OpenMM;
extern "C" OPENMM_EXPORT_DRUDE_SERIALIZATION void registerDrudeSerializationProxies() {
extern "C" OPENMM_EXPORT_DRUDE void registerDrudeSerializationProxies() {
SerializationProxy::registerProxy(typeid(DrudeForce), new DrudeForceProxy());
SerializationProxy::registerProxy(typeid(DrudeLangevinIntegrator), new DrudeLangevinIntegratorProxy());
}
......@@ -11,7 +11,8 @@ FOREACH(TEST_PROG ${TEST_PROGS})
# All tests use shared libraries
ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG})
TARGET_LINK_LIBRARIES(${TEST_ROOT} ${OPENMM_SERIALIZATION_LIBRARY_NAME} ${OPENMM_DRUDE_SERIALIZATION_LIBRARY_NAME} ${OPENMM_DRUDE_LIBRARY_NAME})
TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_DRUDE_TARGET})
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}")
ADD_TEST(${TEST_ROOT} ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT})
ENDFOREACH(TEST_PROG ${TEST_PROGS})
......@@ -22,7 +22,7 @@ SET(CREATE_SERIALIZABLE_OPENMM_RPMD FALSE )
# The source is organized into subdirectories, but we handle them all from
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
SET(OPENMM_RPMD_PLUGIN_SOURCE_SUBDIRS . openmmapi platforms/reference)
SET(OPENMM_RPMD_PLUGIN_SOURCE_SUBDIRS . openmmapi)
SET(OPENMM_RPMD_LIBRARY_NAME OpenMMRPMD)
SET(SHARED_RPMD_TARGET ${OPENMM_RPMD_LIBRARY_NAME})
......@@ -80,46 +80,18 @@ FOREACH(subdir ${OPENMM_RPMD_PLUGIN_SOURCE_SUBDIRS})
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include)
ENDFOREACH(subdir)
INCLUDE_DIRECTORIES(BEFORE ${OPENMM_DIR}/platforms/reference/src)
INCLUDE_DIRECTORIES(BEFORE ${OPENMM_DIR}/platforms/reference/src/SimTKReference)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/platforms/reference/src)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/platforms/reference/src/SimTKReference)
# ----------------------------------------------------------------------------
# If API_RPMD wrappers are being generated, and add them to the build.
#IF(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS)
# ADD_SUBDIRECTORY(wrappers)
# SET(SOURCE_RPMD_FILES ${SOURCE_RPMD_FILES} wrappers/RPMDOpenMMCWrapper.cpp wrappers/RPMDOpenMMFortranWrapper.cpp)
# SET_SOURCE_FILES_PROPERTIES(wrappers/RPMDOpenMMCWrapper.cpp wrappers/RPMDOpenMMFortranWrapper.cpp PROPERTIES GENERATED TRUE)
#ENDIF(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src)
ADD_LIBRARY(${SHARED_RPMD_TARGET} SHARED ${SOURCE_RPMD_FILES} ${SOURCE_RPMD_INCLUDE_FILES} ${API_RPMD_ABS_INCLUDE_FILES})
SET_TARGET_PROPERTIES(${SHARED_RPMD_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_RPMD_BUILDING_SHARED_LIBRARY -DLEPTON_BUILDING_SHARED_LIBRARY")
#IF( CREATE_SERIALIZABLE_OPENMM_RPMD )
# ADD_LIBRARY(${SHARED_RPMD_SERIALIZABLE_TARGET} SHARED ${SOURCE_RPMD_FILES} ${SOURCE_RPMD_INCLUDE_FILES} ${API_RPMD_ABS_INCLUDE_FILES})
# SET_TARGET_PROPERTIES(${SHARED_RPMD_SERIALIZABLE_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_RPMD_BUILDING_SHARED_LIBRARY -DLEPTON_BUILDING_SHARED_LIBRARY -DOPENMM_SERIALIZE")
# INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/../../serialization/include)
#ENDIF( CREATE_SERIALIZABLE_OPENMM_RPMD )
SET_TARGET_PROPERTIES(${SHARED_RPMD_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_RPMD_BUILDING_SHARED_LIBRARY -DLEPTON_BUILDING_SHARED_LIBRARY")
IF(OPENMM_BUILD_STATIC_LIB)
ADD_LIBRARY(${STATIC_RPMD_TARGET} STATIC ${SOURCE_RPMD_FILES} ${SOURCE_RPMD_INCLUDE_FILES} ${API_RPMD_ABS_INCLUDE_FILES})
SET_TARGET_PROPERTIES(${STATIC_RPMD_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_USE_STATIC_LIBRARIES -DOPENMM_BUILDING_STATIC_LIBRARY -DLEPTON_USE_STATIC_LIBRARIES -DLEPTON_BUILDING_STATIC_LIBRARY")
SET_TARGET_PROPERTIES(${STATIC_RPMD_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_USE_STATIC_LIBRARIES -DOPENMM_BUILDING_STATIC_LIBRARY -DLEPTON_USE_STATIC_LIBRARIES -DLEPTON_BUILDING_STATIC_LIBRARY")
ENDIF(OPENMM_BUILD_STATIC_LIB)
#IF(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS)
# ADD_DEPENDENCIES(${SHARED_RPMD_TARGET} RPMDApiWrappers)
# IF( CREATE_SERIALIZABLE_OPENMM_RPMD )
# ADD_DEPENDENCIES(${SHARED_RPMD_SERIALIZABLE_TARGET} RPMDApiWrappers)
# ENDIF( CREATE_SERIALIZABLE_OPENMM_RPMD )
# IF(OPENMM_BUILD_STATIC_LIB)
# ADD_DEPENDENCIES(${STATIC_RPMD_TARGET} RPMDApiWrappers)
# ENDIF(OPENMM_BUILD_STATIC_LIB)
#ENDIF(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS)
# ----------------------------------------------------------------------------
# On Linux need to link to libdl
......@@ -148,18 +120,9 @@ IF(OPENMM_BUILD_STATIC_LIB)
TARGET_LINK_LIBRARIES( ${STATIC_RPMD_TARGET} ${STATIC_TARGET} )
ENDIF(OPENMM_BUILD_STATIC_LIB)
ADD_SUBDIRECTORY(platforms/reference/tests)
# Which hardware platforms to build
#SET(OPENMM_BUILD_RPMD_PATH)
#SET(OPENMM_BUILD_RPMD_CUDA_PATH)
#IF(OPENMM_BUILD_RPMD_CUDA_LIB)
# ADD_SUBDIRECTORY(platforms/cuda)
# SET(OPENMM_BUILD_RPMD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/platforms/cuda)
# SET(OPENMM_BUILD_RPMD_CUDA_PATH ${CMAKE_CURRENT_SOURCE_DIR}/platforms/cuda)
# SET(OPENMM_RPMD_CUDA_SOURCE_SUBDIRS . openmmapi olla platforms/cuda)
#ENDIF(OPENMM_BUILD_RPMD_CUDA_LIB)
ADD_SUBDIRECTORY(platforms/reference)
IF(OPENCL_FOUND)
SET(OPENMM_BUILD_RPMD_OPENCL_LIB ON CACHE BOOL "Build RPMD implementation for OpenCL")
......@@ -208,7 +171,3 @@ ENDIF (EXECUTABLE_OUTPUT_PATH)
#IF (OPENMM_BUILD_SERIALIZATION_SUPPORT)
# ADD_SUBDIRECTORY(serialization)
#ENDIF (OPENMM_BUILD_SERIALIZATION_SUPPORT)
#INCLUDE(ApiDoxygen.cmake)
#ADD_SUBDIRECTORY(tests)
......@@ -12,10 +12,6 @@
# libOpenMMRPMDCUDA[_d].so
#----------------------------------------------------
IF (APPLE)
SET (CMAKE_OSX_DEPLOYMENT_TARGET "10.6")
ENDIF (APPLE)
# The source is organized into subdirectories, but we handle them all from
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
SET(OPENMM_SOURCE_SUBDIRS .)
......@@ -31,9 +27,9 @@ SET(SHARED_TARGET ${OPENMMRPMDCUDA_LIBRARY_NAME})
# Ensure that debug libraries have "_d" appended to their names.
# CMake gets this right on Windows automatically with this definition.
IF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
IF (MSVC)
SET(CMAKE_DEBUG_POSTFIX "_d" CACHE INTERNAL "" FORCE)
ENDIF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
ENDIF (MSVC)
# But on Unix or Cygwin we have to add the suffix manually
IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
......@@ -113,7 +109,12 @@ ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${CUDA_LIBRARIES} ${PTHREADS_LIB})
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}CUDA_d optimized ${OPENMM_LIBRARY_NAME}CUDA)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_RPMD_TARGET} optimized ${SHARED_RPMD_TARGET})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_BUILDING_SHARED_LIBRARY")
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY")
IF (APPLE)
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS} -F/Library/Frameworks -framework CUDA")
ELSE (APPLE)
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}")
ENDIF (APPLE)
INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins)
# Ensure that links to the main CUDA library will be resolved.
......
......@@ -252,7 +252,18 @@ void CudaIntegrateRPMDStepKernel::computeForces(ContextImpl& context) {
&cu.getPosq().getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i};
cu.executeKernel(copyToContextKernel, copyToContextArgs, cu.getNumAtoms());
context.computeVirtualSites();
Vec3 initialBox[3];
context.getPeriodicBoxVectors(initialBox[0], initialBox[1], initialBox[2]);
context.updateContextState();
Vec3 finalBox[3];
context.getPeriodicBoxVectors(finalBox[0], finalBox[1], finalBox[2]);
if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) {
// A barostat was applied during updateContextState(). Adjust the particle positions in all the
// other copies to match this one.
void* args[] = {&positions->getDevicePointer(), &cu.getPosq().getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i};
cu.executeKernel(translateKernel, args, cu.getNumAtoms());
}
context.calcForcesAndEnergy(true, false, groupsNotContracted);
void* copyFromContextArgs[] = {&cu.getForce().getDevicePointer(), &forces->getDevicePointer(), &cu.getVelm().getDevicePointer(),
&velocities->getDevicePointer(), &cu.getPosq().getDevicePointer(), &positions->getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i};
......
......@@ -217,7 +217,7 @@ extern "C" __global__ void copyDataFromContext(long long* srcForce, long long* d
}
/**
* Update atom positions so all copies are offset by the same number of periodic box widths.
* Atom positions in one copy have been modified. Apply the same offsets to all the other copies.
*/
extern "C" __global__ void applyCellTranslations(mixed4* posq, real4* movedPos, int* order, int movedCopy) {
for (int particle = blockIdx.x*blockDim.x+threadIdx.x; particle < NUM_ATOMS; particle += blockDim.x*gridDim.x) {
......
......@@ -14,6 +14,11 @@ FOREACH(TEST_PROG ${TEST_PROGS})
# Link with shared library
ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG})
TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_RPMD_TARGET} ${SHARED_TARGET})
IF (APPLE)
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS} -F/Library/Frameworks -framework CUDA" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}")
ELSE (APPLE)
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}")
ENDIF (APPLE)
ADD_TEST(${TEST_ROOT}Single ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} single)
IF (OPENMM_BUILD_CUDA_DOUBLE_PRECISION_TESTS)
ADD_TEST(${TEST_ROOT}Mixed ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} mixed)
......
......@@ -38,6 +38,7 @@
#include "openmm/Context.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/MonteCarloBarostat.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
......@@ -496,6 +497,80 @@ void testWithoutThermostat() {
}
}
void testWithBarostat() {
const int gridSize = 3;
const int numMolecules = gridSize*gridSize*gridSize;
const int numParticles = numMolecules*2;
const int numCopies = 10;
const double spacing = 2.0;
const double cutoff = 3.0;
const double boxSize = spacing*(gridSize+1);
const double temperature = 300.0;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
HarmonicBondForce* bonds = new HarmonicBondForce();
system.addForce(bonds);
NonbondedForce* nonbonded = new NonbondedForce();
nonbonded->setCutoffDistance(cutoff);
nonbonded->setNonbondedMethod(NonbondedForce::PME);
nonbonded->setForceGroup(1);
nonbonded->setReciprocalSpaceForceGroup(2);
system.addForce(nonbonded);
system.addForce(new MonteCarloBarostat(0.5, temperature));
// Create a cloud of molecules.
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
vector<Vec3> positions(numParticles);
for (int i = 0; i < numMolecules; i++) {
system.addParticle(1.0);
system.addParticle(1.0);
nonbonded->addParticle(-0.2, 0.2, 0.2);
nonbonded->addParticle(0.2, 0.2, 0.2);
nonbonded->addException(2*i, 2*i+1, 0, 1, 0);
bonds->addBond(2*i, 2*i+1, 1.0, 10000.0);
}
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001);
Platform& platform = Platform::getPlatformByName("CUDA");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
for (int k = 0; k < gridSize; k++) {
Vec3 pos = Vec3(spacing*(i+0.02*genrand_real2(sfmt)), spacing*(j+0.02*genrand_real2(sfmt)), spacing*(k+0.02*genrand_real2(sfmt)));
int index = k+gridSize*(j+gridSize*i);
positions[2*index] = pos;
positions[2*index+1] = Vec3(pos[0]+1.0, pos[1], pos[2]);
}
integ.setPositions(copy, positions);
}
// Check the temperature.
const int numSteps = 500;
integ.step(100);
vector<double> ke(numCopies, 0.0);
for (int i = 0; i < numSteps; i++) {
integ.step(1);
vector<State> state(numCopies);
for (int j = 0; j < numCopies; j++)
state[j] = integ.getState(j, State::Velocities, true);
for (int j = 0; j < numParticles; j++) {
for (int k = 0; k < numCopies; k++) {
Vec3 v = state[k].getVelocities()[j];
ke[k] += 0.5*system.getParticleMass(j)*v.dot(v);
}
}
}
double meanKE = 0.0;
for (int i = 0; i < numCopies; i++)
meanKE += ke[i];
meanKE /= numSteps*numCopies;
double expectedKE = 0.5*numCopies*numParticles*3*BOLTZ*temperature;
ASSERT_USUALLY_EQUAL_TOL(expectedKE, meanKE, 1e-2);
}
int main(int argc, char* argv[]) {
try {
registerRPMDCudaKernelFactories();
......@@ -507,6 +582,7 @@ int main(int argc, char* argv[]) {
testVirtualSites();
testContractions();
testWithoutThermostat();
testWithBarostat();
}
catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
......
......@@ -12,10 +12,6 @@
# libOpenMMRPMDOpenCL[_d].so
#----------------------------------------------------
IF (APPLE)
SET (CMAKE_OSX_DEPLOYMENT_TARGET "10.6")
ENDIF (APPLE)
# The source is organized into subdirectories, but we handle them all from
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
SET(OPENMM_SOURCE_SUBDIRS .)
......@@ -31,9 +27,9 @@ SET(SHARED_TARGET ${OPENMMRPMDOPENCL_LIBRARY_NAME})
# Ensure that debug libraries have "_d" appended to their names.
# CMake gets this right on Windows automatically with this definition.
IF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
IF (MSVC)
SET(CMAKE_DEBUG_POSTFIX "_d" CACHE INTERNAL "" FORCE)
ENDIF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
ENDIF (MSVC)
# But on Unix or Cygwin we have to add the suffix manually
IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
......@@ -112,7 +108,7 @@ ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB} ${OPENCL_LIBRARIES} ${PTHREADS_LIB})
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}OpenCL_d optimized ${OPENMM_LIBRARY_NAME}OpenCL)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_RPMD_TARGET} optimized ${SHARED_RPMD_TARGET})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-msse2 -DOPENMM_BUILDING_SHARED_LIBRARY")
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY")
INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins)
# Ensure that links to the main OpenCL library will be resolved.
......
......@@ -268,7 +268,18 @@ void OpenCLIntegrateRPMDStepKernel::computeForces(ContextImpl& context) {
copyToContextKernel.setArg<cl_int>(5, i);
cl.executeKernel(copyToContextKernel, cl.getNumAtoms());
context.computeVirtualSites();
Vec3 initialBox[3];
context.getPeriodicBoxVectors(initialBox[0], initialBox[1], initialBox[2]);
context.updateContextState();
Vec3 finalBox[3];
context.getPeriodicBoxVectors(finalBox[0], finalBox[1], finalBox[2]);
if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) {
// A barostat was applied during updateContextState(). Adjust the particle positions in all the
// other copies to match this one.
translateKernel.setArg<cl_int>(3, i);
cl.executeKernel(translateKernel, cl.getNumAtoms());
}
context.calcForcesAndEnergy(true, false, groupsNotContracted);
copyFromContextKernel.setArg<cl_int>(7, i);
cl.executeKernel(copyFromContextKernel, cl.getNumAtoms());
......
......@@ -204,7 +204,7 @@ __kernel void copyDataFromContext(__global real4* srcForce, __global real4* dstF
}
/**
* Update atom positions so all copies are offset by the same number of periodic box widths.
* Atom positions in one copy have been modified. Apply the same offsets to all the other copies.
*/
__kernel void applyCellTranslations(__global mixed4* posq, __global real4* movedPos, __global int* order, int movedCopy) {
for (int particle = get_global_id(0); particle < NUM_ATOMS; particle += get_global_size(0)) {
......
......@@ -14,6 +14,7 @@ FOREACH(TEST_PROG ${TEST_PROGS})
# Link with shared library
ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG})
TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_RPMD_TARGET} ${SHARED_TARGET})
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}")
ADD_TEST(${TEST_ROOT}Single ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} single)
IF (OPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS)
ADD_TEST(${TEST_ROOT}Mixed ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} mixed)
......
......@@ -38,6 +38,7 @@
#include "openmm/Context.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/MonteCarloBarostat.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
......@@ -497,6 +498,80 @@ void testWithoutThermostat() {
}
}
void testWithBarostat() {
const int gridSize = 3;
const int numMolecules = gridSize*gridSize*gridSize;
const int numParticles = numMolecules*2;
const int numCopies = 10;
const double spacing = 2.0;
const double cutoff = 3.0;
const double boxSize = spacing*(gridSize+1);
const double temperature = 300.0;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
HarmonicBondForce* bonds = new HarmonicBondForce();
system.addForce(bonds);
NonbondedForce* nonbonded = new NonbondedForce();
nonbonded->setCutoffDistance(cutoff);
nonbonded->setNonbondedMethod(NonbondedForce::PME);
nonbonded->setForceGroup(1);
nonbonded->setReciprocalSpaceForceGroup(2);
system.addForce(nonbonded);
system.addForce(new MonteCarloBarostat(0.5, temperature));
// Create a cloud of molecules.
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
vector<Vec3> positions(numParticles);
for (int i = 0; i < numMolecules; i++) {
system.addParticle(1.0);
system.addParticle(1.0);
nonbonded->addParticle(-0.2, 0.2, 0.2);
nonbonded->addParticle(0.2, 0.2, 0.2);
nonbonded->addException(2*i, 2*i+1, 0, 1, 0);
bonds->addBond(2*i, 2*i+1, 1.0, 10000.0);
}
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001);
Platform& platform = Platform::getPlatformByName("OpenCL");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
for (int k = 0; k < gridSize; k++) {
Vec3 pos = Vec3(spacing*(i+0.02*genrand_real2(sfmt)), spacing*(j+0.02*genrand_real2(sfmt)), spacing*(k+0.02*genrand_real2(sfmt)));
int index = k+gridSize*(j+gridSize*i);
positions[2*index] = pos;
positions[2*index+1] = Vec3(pos[0]+1.0, pos[1], pos[2]);
}
integ.setPositions(copy, positions);
}
// Check the temperature.
const int numSteps = 500;
integ.step(100);
vector<double> ke(numCopies, 0.0);
for (int i = 0; i < numSteps; i++) {
integ.step(1);
vector<State> state(numCopies);
for (int j = 0; j < numCopies; j++)
state[j] = integ.getState(j, State::Velocities, true);
for (int j = 0; j < numParticles; j++) {
for (int k = 0; k < numCopies; k++) {
Vec3 v = state[k].getVelocities()[j];
ke[k] += 0.5*system.getParticleMass(j)*v.dot(v);
}
}
}
double meanKE = 0.0;
for (int i = 0; i < numCopies; i++)
meanKE += ke[i];
meanKE /= numSteps*numCopies;
double expectedKE = 0.5*numCopies*numParticles*3*BOLTZ*temperature;
ASSERT_USUALLY_EQUAL_TOL(expectedKE, meanKE, 1e-2);
}
int main(int argc, char* argv[]) {
try {
registerRPMDOpenCLKernelFactories();
......@@ -508,6 +583,7 @@ int main(int argc, char* argv[]) {
testVirtualSites();
testContractions();
testWithoutThermostat();
testWithBarostat();
}
catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
......
#---------------------------------------------------
# OpenMMAmoeba Serialization Library
# OpenMM Reference RPMD Integrator
#
# Creates OpenMMAmoeba serializatin library, base name=OpenMMAmoebaSerialization.
# Creates OpenMM library, base name=OpenMMRPMDReference.
# Default libraries are shared & optimized. Variants
# are created for static (_static) and debug (_d).
# are created for debug (_d).
#
# Windows:
# OpenMMAmoebaSerialization[_d].dll
# OpenMMAmoebaSerialization[_d].lib
# OpenMMRPMDReference[_d].dll
# OpenMMRPMDReference[_d].lib
# Unix:
# libOpenMMAmoebaSerialization[_d].so
# libOpenMMRPMDReference[_d].so
#----------------------------------------------------
# The source is organized into subdirectories, but we handle them all from
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
SET(OPENMM_SOURCE_SUBDIRS . ../../../serialization)
SET(OPENMM_AMOEBA_SOURCE_SUBDIRS . )
SET(OPENMM_SOURCE_SUBDIRS .)
# Collect up information about the version of the OpenMM library we're building
# and make it available to the code so it can be built into the binaries.
SET(OPENMM_AMOEBA_LIBRARY_NAME OpenMMAmoeba)
SET(OPENMM_SERIALIZATION_LIBRARY_NAME OpenMMSerialization)
SET(OPENMM_AMOEBA_SERIALIZATION_LIBRARY_NAME OpenMMAmoebaSerialization)
SET(OPENMMRPMDREFERENCE_LIBRARY_NAME OpenMMRPMDReference)
SET(SHARED_TARGET ${OPENMMRPMDREFERENCE_LIBRARY_NAME})
# Ensure that debug libraries have "_d" appended to their names.
# CMake gets this right on Windows automatically with this definition.
IF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
IF (MSVC)
SET(CMAKE_DEBUG_POSTFIX "_d" CACHE INTERNAL "" FORCE)
ENDIF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
ENDIF (MSVC)
# But on Unix or Cygwin we have to add the suffix manually
IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
SET(OPENMM_AMOEBA_LIBRARY_NAME ${OPENMM_AMOEBA_LIBRARY_NAME}_d)
SET(OPENMM_SERIALIZATION_LIBRARY_NAME ${OPENMM_SERIALIZATION_LIBRARY_NAME}_d)
SET(OPENMM_AMOEBA_SERIALIZATION_LIBRARY_NAME ${OPENMM_AMOEBA_SERIALIZATION_LIBRARY_NAME}_d)
SET(SHARED_TARGET ${SHARED_TARGET}_d)
ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
# These are all the places to search for header files which are
# to be part of the API.
SET(API_INCLUDE_DIRS) # start empty
......@@ -66,22 +66,32 @@ ENDFOREACH(dir)
SET(SOURCE_FILES) # empty
SET(SOURCE_INCLUDE_FILES)
FOREACH(subdir ${OPENMM_AMOEBA_SOURCE_SUBDIRS})
FILE(GLOB_RECURSE src_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.c)
FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.h ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.hpp)
FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS})
FILE(GLOB_RECURSE src_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.c)
FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.h)
SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) #append
SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files})
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/../../../serialization/${subdir}/include)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include)
ENDFOREACH(subdir)
#Message( "API_REL_INCLUDE_FILES=${API_REL_INCLUDE_FILES}\n" )
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src )
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/reference/include)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/reference/src)
# Create the library
ADD_LIBRARY(${OPENMM_AMOEBA_SERIALIZATION_LIBRARY_NAME} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES})
TARGET_LINK_LIBRARIES(${OPENMM_AMOEBA_SERIALIZATION_LIBRARY_NAME} ${OPENMM_AMOEBA_LIBRARY_NAME} ${OPENMM_SERIALIZATION_LIBRARY_NAME} ${SHARED_TARGET})
SET_TARGET_PROPERTIES(${OPENMM_AMOEBA_SERIALIZATION_LIBRARY_NAME} PROPERTIES COMPILE_FLAGS "-DOPENMM_AMOEBA_SERIALIZATION_BUILDING_SHARED_LIBRARY -DTIXML_USE_STL -DIEEE_8087")
INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${OPENMM_AMOEBA_SERIALIZATION_LIBRARY_NAME})
ADD_SUBDIRECTORY(tests)
INCLUDE_DIRECTORIES(${REFERENCE_INCLUDE_DIR})
ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES})
IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
SET(MAIN_OPENMM_LIB ${OPENMM_LIBRARY_NAME}_d)
ELSE (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
SET(MAIN_OPENMM_LIB ${OPENMM_LIBRARY_NAME})
ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MAIN_OPENMM_LIB})
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_RPMD_TARGET} optimized ${SHARED_RPMD_TARGET})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY")
INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins)
SUBDIRS (tests)
......@@ -32,22 +32,21 @@
using namespace OpenMM;
#if defined(WIN32)
#include <windows.h>
extern "C" void initRpmdReferenceKernels();
BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
initRpmdReferenceKernels();
return TRUE;
extern "C" OPENMM_EXPORT void registerPlatforms() {
}
extern "C" OPENMM_EXPORT void registerKernelFactories() {
for (int i = 0; i < Platform::getNumPlatforms(); i++) {
Platform& platform = Platform::getPlatform(i);
if (dynamic_cast<ReferencePlatform*>(&platform) != NULL) {
ReferenceRpmdKernelFactory* factory = new ReferenceRpmdKernelFactory();
platform.registerKernelFactory(IntegrateRPMDStepKernel::Name(), factory);
}
}
#else
extern "C" void __attribute__((constructor)) initRpmdReferenceKernels();
#endif
}
extern "C" void initRpmdReferenceKernels() {
Platform& platform = Platform::getPlatformByName("Reference");
ReferenceRpmdKernelFactory* factory = new ReferenceRpmdKernelFactory();
platform.registerKernelFactory(IntegrateRPMDStepKernel::Name(), factory);
extern "C" OPENMM_EXPORT void registerRpmdReferenceKernelFactories() {
registerKernelFactories();
}
KernelImpl* ReferenceRpmdKernelFactory::createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const {
......
......@@ -275,7 +275,22 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const
pos = positions[i];
vel = velocities[i];
context.computeVirtualSites();
Vec3 initialBox[3];
context.getPeriodicBoxVectors(initialBox[0], initialBox[1], initialBox[2]);
context.updateContextState();
Vec3 finalBox[3];
context.getPeriodicBoxVectors(finalBox[0], finalBox[1], finalBox[2]);
if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) {
// A barostat was applied during updateContextState(). Adjust the particle positions in all the
// other copies to match this one.
for (int j = 0; j < numParticles; j++) {
Vec3 delta = pos[j]-positions[i][j];
for (int k = 0; k < totalCopies; k++)
if (k != i)
positions[k][j] += delta;
}
}
positions[i] = pos;
velocities[i] = vel;
context.calcForcesAndEnergy(true, false, groupsNotContracted);
......
......@@ -2,11 +2,9 @@
# Testing
#
ENABLE_TESTING()
#INCLUDE_DIRECTORIES(${CUDA_INCLUDE})
INCLUDE_DIRECTORIES(${OPENMM_DIR}/platforms/reference/include)
INCLUDE_DIRECTORIES(${OPENMM_DIR}/openmmapi/include/openmm)
INCLUDE_DIRECTORIES(${OPENMM_DIR}/platforms/reference/src)
#INCLUDE_DIRECTORIES(${OPENMM_DIR}/platforms/reference/src/kernels)
SET(SHARED_OPENMM_RPMD_TARGET OpenMMRPMD)
......@@ -26,5 +24,6 @@ FOREACH(TEST_PROG ${TEST_PROGS})
ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG})
TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_TARGET} ${SHARED_OPENMM_TARGET} ${SHARED_OPENMM_RPMD_TARGET})
SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}")
ADD_TEST(${TEST_ROOT} ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT})
ENDFOREACH(TEST_PROG ${TEST_PROGS})
......@@ -37,6 +37,7 @@
#include "openmm/CMMotionRemover.h"
#include "openmm/Context.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/MonteCarloBarostat.h"
#include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
......@@ -50,6 +51,8 @@
using namespace OpenMM;
using namespace std;
extern "C" OPENMM_EXPORT void registerRpmdReferenceKernelFactories();
void testFreeParticles() {
const int numParticles = 100;
const int numCopies = 30;
......@@ -378,13 +381,89 @@ void testWithoutThermostat() {
}
}
void testWithBarostat() {
const int gridSize = 3;
const int numMolecules = gridSize*gridSize*gridSize;
const int numParticles = numMolecules*2;
const int numCopies = 5;
const double spacing = 2.0;
const double cutoff = 3.0;
const double boxSize = spacing*(gridSize+1);
const double temperature = 300.0;
System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
HarmonicBondForce* bonds = new HarmonicBondForce();
system.addForce(bonds);
NonbondedForce* nonbonded = new NonbondedForce();
nonbonded->setCutoffDistance(cutoff);
nonbonded->setNonbondedMethod(NonbondedForce::PME);
nonbonded->setForceGroup(1);
nonbonded->setReciprocalSpaceForceGroup(2);
system.addForce(nonbonded);
system.addForce(new MonteCarloBarostat(0.5, temperature));
// Create a cloud of molecules.
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
vector<Vec3> positions(numParticles);
for (int i = 0; i < numMolecules; i++) {
system.addParticle(1.0);
system.addParticle(1.0);
nonbonded->addParticle(-0.2, 0.2, 0.2);
nonbonded->addParticle(0.2, 0.2, 0.2);
nonbonded->addException(2*i, 2*i+1, 0, 1, 0);
bonds->addBond(2*i, 2*i+1, 1.0, 10000.0);
}
RPMDIntegrator integ(numCopies, temperature, 50.0, 0.001);
Platform& platform = Platform::getPlatformByName("Reference");
Context context(system, integ, platform);
for (int copy = 0; copy < numCopies; copy++) {
for (int i = 0; i < gridSize; i++)
for (int j = 0; j < gridSize; j++)
for (int k = 0; k < gridSize; k++) {
Vec3 pos = Vec3(spacing*(i+0.02*genrand_real2(sfmt)), spacing*(j+0.02*genrand_real2(sfmt)), spacing*(k+0.02*genrand_real2(sfmt)));
int index = k+gridSize*(j+gridSize*i);
positions[2*index] = pos;
positions[2*index+1] = Vec3(pos[0]+1.0, pos[1], pos[2]);
}
integ.setPositions(copy, positions);
}
// Check the temperature.
const int numSteps = 500;
integ.step(100);
vector<double> ke(numCopies, 0.0);
for (int i = 0; i < numSteps; i++) {
integ.step(1);
vector<State> state(numCopies);
for (int j = 0; j < numCopies; j++)
state[j] = integ.getState(j, State::Velocities, true);
for (int j = 0; j < numParticles; j++) {
for (int k = 0; k < numCopies; k++) {
Vec3 v = state[k].getVelocities()[j];
ke[k] += 0.5*system.getParticleMass(j)*v.dot(v);
}
}
}
double meanKE = 0.0;
for (int i = 0; i < numCopies; i++)
meanKE += ke[i];
meanKE /= numSteps*numCopies;
double expectedKE = 0.5*numCopies*numParticles*3*BOLTZ*temperature;
ASSERT_USUALLY_EQUAL_TOL(expectedKE, meanKE, 1e-2);
}
int main() {
try {
registerRpmdReferenceKernelFactories();
testFreeParticles();
testCMMotionRemoval();
testVirtualSites();
testContractions();
testWithoutThermostat();
testWithBarostat();
}
catch(const std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
......
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