#ifndef OPENMM_OPENCLCONTEXT_H_ #define OPENMM_OPENCLCONTEXT_H_ /* -------------------------------------------------------------------------- * * 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) 2009 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published * * by the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see . * * -------------------------------------------------------------------------- */ #define __CL_ENABLE_EXCEPTIONS #include namespace OpenMM { template class OpenCLArray; class OpenCLForceInfo; class System; /** * We can't use predefined vector types like cl_float4, since different OpenCL implementations currently define * them in incompatible ways. Hopefully that will be fixed in the future. In the mean time, we define our own * types to represent them on the host. */ typedef struct { cl_float x, y; } mm_float2; typedef struct { cl_float x, y, z, w; } mm_float4; typedef struct { cl_float s0, s1, s2, s3, s4, s5, s6, s7; } mm_float8; typedef struct { cl_int x, y; } mm_int2; typedef struct { cl_int x, y, z, w; } mm_int4; typedef struct { cl_int s0, s1, s2, s3, s4, s5, s6, s7; } mm_int8; /** * This class contains the information associated with a Context by the OpenCL Platform. */ class OpenCLContext { public: static const int ThreadBlockSize = 64; static const int TileSize = 32; OpenCLContext(int numParticles, int deviceIndex); ~OpenCLContext(); /** * This is called to initialize internal data structures after all Forces in the system * have been initialized. */ void initialize(const System& system); /** * Add an OpenCLForce to this context. */ void addForce(OpenCLForceInfo* force); /** * Get the cl::Context associated with this object. */ cl::Context& getContext() { return context; } /** * Get the cl::CommandQueue associated with this object. */ cl::CommandQueue& getQueue() { return queue; } /** * Get the array which contains the position and charge of each atom. */ OpenCLArray& getPosq() { return *posq; } /** * Get the array which contains the velocity and massof each atom. */ OpenCLArray& getVelm() { return *velm; } /** * Get the array which contains the force on each atom. */ OpenCLArray& getForce() { return *force; } /** * Get the array which contains the buffers in which forces are computed. */ OpenCLArray& getForceBuffers() { return *forceBuffers; } /** * Get the array which contains the buffer in which energy is computed. */ OpenCLArray& getEnergyBuffer() { return *energyBuffer; } /** * Get the array which contains the index of each atom. */ OpenCLArray& getAtomIndex() { return *atomIndex; } /** * Load OpenCL source code from a file in the kernels directory. */ std::string loadSourceFromFile(const std::string& filename) const; /** * Create an OpenCL Program from source code. */ cl::Program createProgram(const std::string source); /** * Execute a kernel. * * @param kernel the kernel to execute * @param workUnits the maximum number of work units that should be used */ void executeKernel(cl::Kernel& kernel, int workUnits); /** * Set all elements of an array to 0. */ void clearBuffer(OpenCLArray& array); /** * Set all elements of an array to 0. */ void clearBuffer(OpenCLArray& array); /** * Given a collection of buffers packed into an array, sum them and store * the sum in the first buffer. * * @param array the array containing the buffers to reduce * @param numBuffers the number of buffers packed into the array */ void reduceBuffer(OpenCLArray& array, int numBuffers); /** * Get the number of atoms. */ int getNumAtoms() const { return numAtoms; } /** * Get the number of atoms, rounded up to a multiple of TileSize. This is the actual size of * most arrays with one element per atom. */ int getPaddedNumAtoms() const { return paddedNumAtoms; } /** * Get the number of blocks of TileSize atoms. */ int getNumAtomBlocks() const { return numAtomBlocks; } /** * Get the standard number of thread blocks to use when executing kernels. */ int getNumThreadBlocks() const { return numThreadBlocks; } /** * Get the total number of tiles used for nonbonded computation. */ int getNumTiles() const { return numTiles; } /** * Get the number of force buffers. */ int getNumForceBuffers() const { return numForceBuffers; } private: int numAtoms; int paddedNumAtoms; int numAtomBlocks; int numTiles; int numThreadBlocks; int numForceBuffers; cl::Context context; cl::Device device; cl::CommandQueue queue; cl::Program utilities; cl::Kernel clearBufferKernel; cl::Kernel reduceFloat4Kernel; std::vector forces; OpenCLArray* posq; OpenCLArray* velm; OpenCLArray* force; OpenCLArray* forceBuffers; OpenCLArray* energyBuffer; OpenCLArray* atomIndex; }; } // namespace OpenMM #endif /*OPENMM_OPENCLCONTEXT_H_*/