Commit 017e60c5 authored by Peter Eastman's avatar Peter Eastman
Browse files

Disabled compiler optimizations for integrator kernels, since they caused excessive error on Fermi

parent 7d4b549d
......@@ -86,7 +86,8 @@ OpenCLContext::OpenCLContext(int numParticles, int deviceIndex) : time(0.0), ste
this->deviceIndex = deviceIndex;
if (device.getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>() < minThreadBlockSize)
throw OpenMMException("The specified OpenCL device is not compatible with OpenMM");
compilationOptions = "-cl-fast-relaxed-math -DWORK_GROUP_SIZE="+OpenCLExpressionUtilities::intToString(ThreadBlockSize);
compilationOptions = "-DWORK_GROUP_SIZE="+OpenCLExpressionUtilities::intToString(ThreadBlockSize);
defaultOptimizationOptions = "-cl-fast-relaxed-math";
string vendor = device.getInfo<CL_DEVICE_VENDOR>();
if (vendor.size() >= 6 && vendor.substr(0, 6) == "NVIDIA") {
compilationOptions += " -DWARPS_ARE_ATOMIC";
......@@ -243,18 +244,24 @@ string OpenCLContext::replaceStrings(const string& input, const std::map<std::st
return result;
}
cl::Program OpenCLContext::createProgram(const string source) {
return createProgram(source, map<string, string>());
cl::Program OpenCLContext::createProgram(const string source, const char* optimizationFlags) {
return createProgram(source, map<string, string>(), optimizationFlags);
}
cl::Program OpenCLContext::createProgram(const string source, const map<string, string>& defines) {
cl::Program OpenCLContext::createProgram(const string source, const map<string, string>& defines, const char* optimizationFlags) {
cl::Program::Sources sources(1, make_pair(source.c_str(), source.size()));
cl::Program program(context, sources);
string options = compilationOptions;
stringstream options;
options << compilationOptions;
if (optimizationFlags == NULL)
options << " " << defaultOptimizationOptions;
else
options << " " << optimizationFlags;
for (map<string, string>::const_iterator iter = defines.begin(); iter != defines.end(); ++iter)
options += " -D"+iter->first+"="+iter->second;
options << " -D" << iter->first << "=" << iter->second;
try {
program.build(vector<cl::Device>(1, device), options.c_str());
std::cout << options.str()<< std::endl;
program.build(vector<cl::Device>(1, device), options.str().c_str());
} catch (cl::Error err) {
throw OpenMMException("Error compiling kernel: "+program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device));
}
......
......@@ -230,14 +230,21 @@ public:
std::string replaceStrings(const std::string& input, const std::map<std::string, std::string>& replacements) const;
/**
* Create an OpenCL Program from source code.
*
* @param source the source code of the program
* @param optimizationFlags the optimization flags to pass to the OpenCL compiler. If this is
* omitted, a default set of options will be used
*/
cl::Program createProgram(const std::string source);
cl::Program createProgram(const std::string source, const char* optimizationFlags = NULL);
/**
* Create an OpenCL Program from source code.
*
* @param defines a set of preprocessor definitions (name, value) to define when compiling the program
* @param source the source code of the program
* @param defines a set of preprocessor definitions (name, value) to define when compiling the program
* @param optimizationFlags the optimization flags to pass to the OpenCL compiler. If this is
* omitted, a default set of options will be used
*/
cl::Program createProgram(const std::string source, const std::map<std::string, std::string>& defines);
cl::Program createProgram(const std::string source, const std::map<std::string, std::string>& defines, const char* optimizationFlags = NULL);
/**
* Execute a kernel.
*
......@@ -406,7 +413,7 @@ private:
int simdWidth;
mm_float4 periodicBoxSize;
mm_float4 invPeriodicBoxSize;
std::string compilationOptions;
std::string compilationOptions, defaultOptimizationOptions;
cl::Context context;
cl::Device device;
cl::CommandQueue queue;
......
......@@ -3236,7 +3236,7 @@ OpenCLIntegrateVerletStepKernel::~OpenCLIntegrateVerletStepKernel() {
void OpenCLIntegrateVerletStepKernel::initialize(const System& system, const VerletIntegrator& integrator) {
cl.initialize(system);
cl::Program program = cl.createProgram(OpenCLKernelSources::verlet);
cl::Program program = cl.createProgram(OpenCLKernelSources::verlet, "");
kernel1 = cl::Kernel(program, "integrateVerletPart1");
kernel2 = cl::Kernel(program, "integrateVerletPart2");
prevStepSize = -1.0;
......@@ -3296,7 +3296,7 @@ void OpenCLIntegrateLangevinStepKernel::initialize(const System& system, const L
map<string, string> defines;
defines["NUM_ATOMS"] = intToString(cl.getNumAtoms());
defines["PADDED_NUM_ATOMS"] = intToString(cl.getPaddedNumAtoms());
cl::Program program = cl.createProgram(OpenCLKernelSources::langevin, defines);
cl::Program program = cl.createProgram(OpenCLKernelSources::langevin, defines, "");
kernel1 = cl::Kernel(program, "integrateLangevinPart1");
kernel2 = cl::Kernel(program, "integrateLangevinPart2");
params = new OpenCLArray<cl_float>(cl, 3, "langevinParams");
......@@ -3369,7 +3369,7 @@ void OpenCLIntegrateBrownianStepKernel::initialize(const System& system, const B
cl.getIntegrationUtilities().initRandomNumberGenerator(integrator.getRandomNumberSeed());
map<string, string> defines;
defines["NUM_ATOMS"] = intToString(cl.getNumAtoms());
cl::Program program = cl.createProgram(OpenCLKernelSources::brownian, defines);
cl::Program program = cl.createProgram(OpenCLKernelSources::brownian, defines, "");
kernel1 = cl::Kernel(program, "integrateBrownianPart1");
kernel2 = cl::Kernel(program, "integrateBrownianPart2");
prevStepSize = -1.0;
......@@ -3425,7 +3425,7 @@ OpenCLIntegrateVariableVerletStepKernel::~OpenCLIntegrateVariableVerletStepKerne
void OpenCLIntegrateVariableVerletStepKernel::initialize(const System& system, const VariableVerletIntegrator& integrator) {
cl.initialize(system);
cl::Program program = cl.createProgram(OpenCLKernelSources::verlet);
cl::Program program = cl.createProgram(OpenCLKernelSources::verlet, "");
kernel1 = cl::Kernel(program, "integrateVerletPart1");
kernel2 = cl::Kernel(program, "integrateVerletPart2");
selectSizeKernel = cl::Kernel(program, "selectVerletStepSize");
......@@ -3496,7 +3496,7 @@ void OpenCLIntegrateVariableLangevinStepKernel::initialize(const System& system,
map<string, string> defines;
defines["NUM_ATOMS"] = intToString(cl.getNumAtoms());
defines["PADDED_NUM_ATOMS"] = intToString(cl.getPaddedNumAtoms());
cl::Program program = cl.createProgram(OpenCLKernelSources::langevin, defines);
cl::Program program = cl.createProgram(OpenCLKernelSources::langevin, defines, "");
kernel1 = cl::Kernel(program, "integrateLangevinPart1");
kernel2 = cl::Kernel(program, "integrateLangevinPart2");
selectSizeKernel = cl::Kernel(program, "selectLangevinStepSize");
......
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