Platform.h 12.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#ifndef OPENMM_PLATFORM_H_
#define OPENMM_PLATFORM_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.               *
 *                                                                            *
12
 * Portions copyright (c) 2008-2016 Stanford University and the Authors.      *
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 * 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 <map>
36
#include <string>
37
#include <vector>
38
#include "openmm/internal/windowsExport.h"
39
40
41

namespace OpenMM {

42
43
class Context;
class ContextImpl;
44
45
46
47
class Kernel;
class KernelFactory;

/**
48
49
50
 * A Platform defines an implementation of all the kernels needed to perform some calculation.
 * More precisely, a Platform object acts as a registry for a set of KernelFactory
 * objects which together implement the kernels.  The Platform class, in turn, provides a
51
 * static registry of all available Platform objects.
Robert McGibbon's avatar
Robert McGibbon committed
52
 *
53
 * To get a Platform object, call
Robert McGibbon's avatar
Robert McGibbon committed
54
 *
55
 * <pre>
peastman's avatar
peastman committed
56
 * Platform& platform = Platform::findPlatform(kernelNames);
57
 * </pre>
Robert McGibbon's avatar
Robert McGibbon committed
58
 *
59
60
 * passing in the names of all kernels that will be required for the calculation you plan to perform.  It
 * will return the fastest available Platform which provides implementations of all the specified kernels.
61
 * You can then call createKernel() to construct particular kernels as needed.
62
63
 */

64
class OPENMM_EXPORT Platform {
65
public:
66
    virtual ~Platform();
67
68
69
    /**
     * Get the name of this platform.  This should be a unique identifier which can be used to recognized it.
     */
70
    virtual const std::string& getName() const = 0;
71
72
73
74
75
76
77
78
79
    /**
     * Get an estimate of how fast this Platform class is.  This need not be precise.  It only is expected to
     * return an order or magnitude estimate of the relative performance of different Platform classes.  An
     * unoptimized reference implementation should return 1.0, and all other Platforms should return a larger
     * value that is an estimate of how many times faster they are than the reference implementation.
     */
    virtual double getSpeed() const = 0;
    /**
     * Get whether this Platform supports double precision arithmetic.  If this returns false, the platform
80
     * is permitted to represent double precision values internally as single precision.
peastman's avatar
peastman committed
81
82
83
     *
     * @deprecated This method is not well defined, and is too simplistic to describe the actual behavior of
     * some Platforms, such as ones that offer multiple precision modes.  It will be removed in a future release.
84
85
     */
    virtual bool supportsDoublePrecision() const = 0;
86
87
88
    /**
     * Get the names of all Platform-specific properties this Platform supports.
     */
Peter Eastman's avatar
Peter Eastman committed
89
    const std::vector<std::string>& getPropertyNames() const;
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
    /**
     * Get the value of a Platform-specific property for a Context.
     *
     * @param context     the Context for which to get the property
     * @param property    the name of the property to get
     * @return the value of the property
     */
    virtual const std::string& getPropertyValue(const Context& context, const std::string& property) const;
    /**
     * Set the value of a Platform-specific property for a Context.
     *
     * @param context     the Context for which to set the property
     * @param property    the name of the property to set
     * @param value       the value to set for the property
     */
    virtual void setPropertyValue(Context& context, const std::string& property, const std::string& value) const;
    /**
     * Get the default value of a Platform-specific property.  This is the value that will be used for
     * newly created Contexts.
     *
     * @param property    the name of the property to get
     * @return the default value of the property
     */
    const std::string& getPropertyDefaultValue(const std::string& property) const;
    /**
     * Set the default value of a Platform-specific property.  This is the value that will be used for
     * newly created Contexts.
     *
     * @param property    the name of the property to set
     * @param value       the value to set for the property
     */
    void setPropertyDefaultValue(const std::string& property, const std::string& value);
122
    /**
123
     * This is called whenever a new Context is created.  It gives the Platform a chance to initialize
124
     * the context and store platform-specific data in it.
125
126
127
     *
     * @param context    the newly created context
     * @param properties a set of values for platform-specific properties.  Keys are the property names.
128
     */
129
    virtual void contextCreated(ContextImpl& context, const std::map<std::string, std::string>& properties) const;
130
131
132
133
134
135
136
137
    /**
     * This is called whenever a new Context is created using ContextImpl::createLinkedContext().  It gives the
     * Platform a chance to initialize the context and store platform-specific data in it.
     *
     * @param context          the newly created context
     * @param originalContext  the original context it is linked to
     */
    virtual void linkedContextCreated(ContextImpl& context, ContextImpl& originalContext) const;
138
    /**
139
     * This is called whenever a Context is deleted.  It gives the Platform a chance to clean up
140
141
     * any platform-specific data that was stored in it.
     */
142
    virtual void contextDestroyed(ContextImpl& context) const;
143
144
    /**
     * Register a KernelFactory which should be used to create Kernels with a particular name.
145
146
     * The Platform takes over ownership of the factory, and will delete it when the Platform itself
     * is deleted.
Robert McGibbon's avatar
Robert McGibbon committed
147
     *
148
149
150
     * @param name     the kernel name for which the factory should be used
     * @param factory  the factory to use for creating Kernels with the specified name
     */
151
    void registerKernelFactory(const std::string& name, KernelFactory* factory);
152
153
    /**
     * Determine whether this Platforms provides implementations of a set of kernels.
Robert McGibbon's avatar
Robert McGibbon committed
154
     *
155
156
157
158
     * @param kernelNames the names of the kernels of interests
     * @return true if this Platform provides implementations of all the kernels in the list,
     * false if there are any which it does not support
     */
Peter Eastman's avatar
Peter Eastman committed
159
    bool supportsKernels(const std::vector<std::string>& kernelNames) const ;
160
    /**
161
     * Create a Kernel object.  If you call this method multiple times for different contexts with the same name,
162
163
164
     * the returned Kernels are independent and do not interact with each other.  This means
     * that it is possible to have multiple simulations in progress at one time without them
     * interfering.
Robert McGibbon's avatar
Robert McGibbon committed
165
     *
166
     * If no KernelFactory has been registered for the specified name, this will throw an exception.
Robert McGibbon's avatar
Robert McGibbon committed
167
     *
168
169
     * @param name the name of the Kernel to get
     * @param context the context for which to create a Kernel
170
171
     * @return a newly created Kernel object
     */
172
    Kernel createKernel(const std::string& name, ContextImpl& context) const;
173
174
175
176
177
178
179
180
181
182
183
184
    /**
     * Register a new Platform.
     */
    static void registerPlatform(Platform* platform);
    /**
     * Get the number of Platforms that have been registered.
     */
    static int getNumPlatforms();
    /**
     * Get a registered Platform by index.
     */
    static Platform& getPlatform(int index);
Robert McGibbon's avatar
Robert McGibbon committed
185
186
187
    /**
     * Get any failures caused during the last call to loadPluginsFromDirectory
     */
Robert McGibbon's avatar
Robert McGibbon committed
188
    static std::vector<std::string> getPluginLoadFailures();
189
190
191
192
    /**
     * Get the registered Platform with a particular name.  If no Platform with that name has been
     * registered, this throws an exception.
     */
193
    static Platform& getPlatformByName(const std::string& name);
194
195
    /**
     * Find a Platform which can be used to perform a calculation.
Robert McGibbon's avatar
Robert McGibbon committed
196
     *
197
198
199
200
     * @param kernelNames the names of all kernels which will be needed for the calculation
     * @return the fastest registered Platform which supports all of the requested kernels.  If no
     * Platform exists which supports all of them, this will throw an exception.
     */
Peter Eastman's avatar
Peter Eastman committed
201
    static Platform& findPlatform(const std::vector<std::string>& kernelNames);
202
203
204
205
206
207
208
209
210
211
212
213
    /**
     * Load a dynamic library (DLL) which contains an OpenMM plugin.  Typically, each Platform
     * is distributed as a separate dynamic library.  This method can then be called at runtime
     * to load each available library.  Each library should contain an initializer function to
     * register any Platforms and KernelFactories that it contains.
     *
     * If the file does not exist or cannot be loaded, an exception is thrown.
     *
     * @param file   the path to the dynamic library file.  This is interpreted using the operating
     *               system's rules for loading libraries.  Typically it may be either an absolute path
     *               or relative to a set of standard locations.
     */
214
    static void loadPluginLibrary(const std::string& file);
215
216
217
218
    /**
     * Load multiple dynamic libraries (DLLs) which contain OpenMM plugins from a single directory.
     * This method loops over every file contained in the specified directory and calls loadPluginLibrary()
     * for each one.  If an error occurs while trying to load a particular file, that file is simply
Robert McGibbon's avatar
Robert McGibbon committed
219
     * ignored. You can retrieve a list of all such errors by calling getPluginLoadFailures().
220
221
222
223
     *
     * @param directory    the path to the directory containing libraries to load
     * @return the names of all files which were successfully loaded as libraries
     */
224
    static std::vector<std::string> loadPluginsFromDirectory(const std::string& directory);
225
226
227
228
229
    /**
     * Get the default directory from which to load plugins.  If the environment variable
     * OPENMM_PLUGIN_DIR is set, this returns its value.  Otherwise, it returns a platform
     * specific default location.
     *
230
231
232
233
234
235
236
     * On unix-like systems, OPENMM_PLUGIN_DIR is allowed to either be a
     * single, fully-qualified path (e.g., /foo/plugins) or a ':'-concatenated
     * set of fully-qualified paths (e.g., /foo/plugins:bar/plugins). On
     * windows-like systems, the same is true, but the path separator is '\\'
     * and the path concatenator is ';'. If an identically-named plugin is
     * encountered twice it will be loaded at both points; be careful!!!
     *
237
238
     * @return the path to the default plugin directory
     */
Peter Eastman's avatar
Peter Eastman committed
239
    static const std::string& getDefaultPluginsDirectory();
240
241
242
243
    /**
     * Get a string containing the version number of the OpenMM library.
     */
    static const std::string& getOpenMMVersion();
244
245
246
247
248
249
250
251
252
253
protected:
    /**
     * Get the ContextImpl for a Context.
     */
    ContextImpl& getContextImpl(Context& context) const;
    /**
     * Get the ContextImpl for a Context.
     */
    const ContextImpl& getContextImpl(const Context& context) const;
    std::vector<std::string> platformProperties;
254
    std::map<std::string, std::string> deprecatedPropertyReplacements;
255
private:
256
    friend class ContextImpl;
257
    std::map<std::string, KernelFactory*> kernelFactories;
258
    std::map<std::string, std::string> defaultProperties;
259
    static std::vector<Platform*>& getPlatforms();
Robert McGibbon's avatar
Robert McGibbon committed
260
    static std::vector<std::string> pluginLoadFailures;
261
262
};

Robert McGibbon's avatar
Robert McGibbon committed
263

264
265
266
} // namespace OpenMM

#endif /*OPENMM_PLATFORM_H_*/