#include "memtestG80_core.h"
-#include "gmx_fatal.h"
-#include "string2.h"
-
-#define BMARK_MEM 80
-
-#define QUICK_MEM 250
-#define QUICK_TESTS MOD_20_32BIT | LOGIC_4_ITER_SHMEM | RANDOM_BLOCKS
-#define QUICK_ITER 3
-
-#define FULL_MEM -1
-#define FULL_TESTS 0x3FFF
-#define FULL_ITER 25
-
+/*! \cond TEST */
#ifdef _DEBUG_
#undef _DEBUG_
#endif
#define _DEBUG_ 0
-#if _DEBUG_ == 1
+#if _DEBUG_ >= 1
+#define debug stderr
#define DUPME(msg) printf("---> %s\n", msg);
#else
#define DUPME(msg) ;
#endif
+/*! \endcond TEST*/
+
+#if _DEBUG_ == 0/* no gromacs utils in debug mode */
+#include "gmx_fatal.h"
+#include "string2.h"
+#endif
+
+#define QUICK_MEM 250 /*!< Amount of memory to be used in quick memtest. */
+#define QUICK_TESTS MOD_20_32BIT | LOGIC_4_ITER_SHMEM | RANDOM_BLOCKS /*!< Bitflag with type of tests
+ to run in quick memtest. */
+#define QUICK_ITER 3 /*!< Number of iterations in quick memtest. */
+
+#define FULL_TESTS 0x3FFF /*!< Bitflag with all test set on for full memetest. */
+#define FULL_ITER 25 /*!< Number of iterations in full memtest. */
+
+#define TIMED_TESTS MOD_20_32BIT | LOGIC_4_ITER_SHMEM | RANDOM_BLOCKS /*!< Bitflag with type of tests to
+ run in time constrained memtest. */
+/*! Number of supported GPUs */
#define NB_GPUS (sizeof(SupportedGPUs)/sizeof(SupportedGPUs[0]))
/*
TODO add proper gromacs logging?
*/
-/** Bit-flags which refer to memtestG80 test types and are used in do_memtest to specify which tests to run. */
+/*! Bit-flags which refer to memtestG80 test types and are used in do_memtest to specify which tests to run. */
enum memtest_G80_test_types {
MOVING_INVERSIONS_10 = 0x1,
MOVING_INVERSIONS_RAND = 0x2,
LOGIC_4_ITER_SHMEM = 0x1000
};
-/* List of GPUs that we want to support. */
// TODO put this list into an external file and include it so that the list is easily accessible
-/** List of supported GPU names. */
+/*! List of supported GPUs. */
static const char * const SupportedGPUs[] = {
/* GT400 */
"Geforce GTX 480",
"Quadro Plex 2100 D4"
};
+/*! \cond TEST */
#ifndef _string2_h
-#include <string.h>
-/* string trimming function - duplicated from ~/src/gmxlib/string2.c -
- only used if this file is compiled in debug mode (_DEBUG_ > 0)
- */
-void ltrim (char *str)
-{
- char *tr;
- int c;
-
- if (!str)
- return;
-
- tr = strdup (str);
- c = 0;
- while ((tr[c] == ' ') || (tr[c] == '\t'))
- c++;
-
- strcpy (str,tr+c);
- free (tr);
-}
-
-void rtrim (char *str)
-{
- int nul;
-
- if (!str)
- return;
-
- nul = strlen(str)-1;
- while ((nul > 0) && ((str[nul] == ' ') || (str[nul] == '\t')) ) {
- str[nul] = '\0';
- nul--;
- }
-}
-
-void trim (char *str)
-{
- ltrim (str);
- rtrim (str);
-}
+/* debug functions, see @the end */
+void ltrim (char *);
+void rtrim (char *);
+void trim (char *);
+int gmx_strncasecmp(const char*, const char*, int);
#endif
+/*! \endcond TEST */
+
-/** Runs sanity checks and returned properties of a device with given id or the one that has
- * already been selected in the case if of dev_id == -1.
+/*!
+ * \brief Runs GPU sanity checks.
+ * Returnes properties of a device with given id or the one that has
+ * already been initialized earlier in the case if of dev_id == -1.
*
- * @param dev_id the device id of the GPU or -1 if the device has laredy been selected
- * @param dev_prop pointer to the structure in which the device properties will be returned
+ * \param[in] dev_id the device id of the GPU or -1 if the device has laredy been selected
+ * \param[out] dev_prop pointer to the structure in which the device properties will be returned
*/
static int do_sanity_checks(int dev_id, cudaDeviceProp *dev_prop)
{
if ((dev_id != -1) && (cu_err = cudaSetDevice(dev_id)) != cudaSuccess)
{
- fprintf(stderr, "Error %d while switching to device #%d: %s\n", cu_err, dev_id,
+ fprintf(stderr, "Error %d while switching to device #%d: %s\n", cu_err, dev_id,
cudaGetErrorString(cu_err));
return -1;
}
return 0;
}
-/**
- * Checks whether the GPU with the given name is supported or not. In case of a positive
- * answer returns 1, otherwise 0;
- *
- * @param dev_id the device id of the GPU or -1 if the device has laredy been selected
- * @param gpu_name the name of the CUDA device
- * @returns 1 if the device is supported, otherwise 0
+/*!
+ * \brief Checks whether the GPU with the given name is supported.
+ *
+ * \param[in] gpu_name the name of the CUDA device
+ * \returns 1 if the device is supported, otherwise 0
*/
static int is_supported_gpu_n(char *gpuName)
{
return 0;
}
-/**
- * Checks whether the GPU with the given device id is supported or not. In case of a positive
- * answer returns 1, otherwise 0;
+/*! \brief Checks whether the GPU with the given device id is supported.
*
- * @param dev_id the device id of the GPU or -1 if the device has laredy been selected
- * @param gpu_name the name of the CUDA device
- * @returns 1 if the device is supported, otherwise 0
+ * \param[in] dev_id the device id of the GPU or -1 if the device has laredy been selected
+ * \param[out] gpu_name Set to contain the name of the CUDA device, if NULL passed, no device name is set.
+ * \returns 1 if the device is supported, otherwise 0
*/
-
int is_supported_cuda_gpu(int dev_id, char *gpu_name)
{
cudaDeviceProp dev_prop;
if (do_sanity_checks(dev_id, &dev_prop) != 0)
return -1;
- strcpy(gpu_name, dev_prop.name);
+ if (gpu_name != NULL)
+ {
+ strcpy(gpu_name, dev_prop.name);
+ }
return is_supported_gpu_n(dev_prop.name);
}
-/**
- * Runs a set of memory tests specified by the given bit-flags. In case if an error is detected
- * it stops without finishing the remainings steps/iterations and returns greater then zero value.
- * In case of other errors (e.g. kernel launch errors, device querying erros) -1 is returned.
+/*!
+ * \brief Runs a set of memory tests specified by the given bit-flags.
+ * Tries to allocate and do the test on \p megs Mb memory or
+ * the greatest amount that can be allocated (>10Mb).
+ * In case if an error is detected it stops without finishing the remainings
+ * steps/iterations and returns greater then zero value.
+ * In case of other errors (e.g. kernel launch errors, device querying erros)
+ * -1 is returned.
*
- * @param which_tests - variable with bit-flags of the requested tests
- * @param megs - amount of memory that will be tested in MB
- * @param iter - number of iterations
- * @returns - 0 if no error was detected, otherwise >0
+ * \param[in] which_tests variable with bit-flags of the requested tests
+ * \param[in] megs amount of memory that will be tested in MB
+ * \param[in] iter number of iterations
+ * \returns 0 if no error was detected, otherwise >0
*/
static int do_memtest(unsigned int which_tests, int megs, int iter)
{
return err_count;
}
-/**
- * Runs a quick memory test and returns 0 in case if no error is detected. If an error is detected it stops
- * before completing the test and returns a value greater then 0. In case of other errors
- * (e.g. kernel launch errors, device querying erros) -1 is returned.
+/*! \brief Runs a quick memory test and returns 0 in case if no error is detected.
+ * If an error is detected it stops before completing the test and returns a
+ * value greater then 0. In case of other errors (e.g. kernel launch errors,
+ * device querying erros) -1 is returned.
*
- * @param dev_id the device id of the GPU or -1 if the device has laredy been selected
- * @returns 0 if no error was detected, otherwise >0
+ * \param[in] dev_id the device id of the GPU or -1 if the device has laredy been selected
+ * \returns 0 if no error was detected, otherwise >0
*/
int do_quick_memtest(int dev_id)
{
return -1;
}
- devmem = dev_prop.totalGlobalMem/(1024*1024); // in MiB
-
if (debug)
{
+ devmem = dev_prop.totalGlobalMem/(1024*1024); // in MiB
fprintf(debug, ">> Running QUICK memtests on %d MiB (out of total %d MiB), %d iterations\n",
QUICK_MEM, devmem, QUICK_ITER);
}
return res;
}
-/**
- * Runs a full memory test and returns 0 in case if no error is detected. If an error is detected it stops
- * before completing the test and returns a value greater then 0. In case of other errors
- * (e.g. kernel launch errors, device querying erros) -1 is returned.
+/*! \brief Runs a full memory test and returns 0 in case if no error is detected.
+ * If an error is detected it stops before completing the test and returns a
+ * value greater then 0. In case of other errors (e.g. kernel launch errors,
+ * device querying erros) -1 is returned.
*
- * @param dev_id the device id of the GPU or -1 if the device has laredy been selected
- * @returns 0 if no error was detected, otherwise >0
+ * \param[in] dev_id the device id of the GPU or -1 if the device has laredy been selected
+ * \returns 0 if no error was detected, otherwise >0
*/
int do_full_memtest(int dev_id)
}
devmem = dev_prop.totalGlobalMem/(1024*1024); // in MiB
- if (debug) { fprintf(debug, ">> Running FULL memtests on %d MiB (out of total %d MiB), %d iterations\n",
- devmem, devmem, FULL_ITER); }
+ if (debug)
+ {
+ fprintf(debug, ">> Running FULL memtests on %d MiB (out of total %d MiB), %d iterations\n",
+ devmem, devmem, FULL_ITER);
+ }
+
+ /* do all test on the entire memory */
res = do_memtest(FULL_TESTS, devmem, FULL_ITER);
if (debug)
return res;
}
-/**
- * Runs a time constrained memory test and returns 0 in case if no error is detected. If an error is detected
- * it stops before completing the test and returns a value greater then zero. In case of other errors
- * (e.g. kernel launch errors, device querying erros) -1 is returned. Note, that test iterations are not
- * interrupted therefor the total runtime of the test will always be multipple of one iteration's runtime.
+/*! \brief Runs a time constrained memory test and returns 0 in case if no error is detected.
+ * If an error is detected it stops before completing the test and returns a value greater
+ * than zero. In case of other errors (e.g. kernel launch errors, device querying erros) -1
+ * is returned. Note, that test iterations are not interrupted therefor the total runtime of
+ * the test will always be multipple of one iteration's runtime.
*
- * @param dev_id the device id of the GPU or -1 if the device has laredy been selected
- * @param time_constr the time limit of the testing
- * @returns 0 if no error was detected, otherwise >0
+ * \param[in] dev_id the device id of the GPU or -1 if the device has laredy been selected
+ * \param[in] time_constr the time limit of the testing
+ * \returns 0 if no error was detected, otherwise >0
*/
-
int do_timed_memtest(int dev_id, int time_constr)
{
cudaDeviceProp dev_prop;
}
devmem = dev_prop.totalGlobalMem/(1024*1024); // in MiB
- if (debug) { fprintf(debug, ">> Running time constrained memtests on %d MiB (out of total %d MiB), time limit of %d s \n",
- devmem, devmem, time_constr); }
+ if (debug)
+ {
+ fprintf(debug, ">> Running time constrained memtests on %d MiB (out of total %d MiB), time limit of %d s \n",
+ devmem, devmem, time_constr);
+ }
+
+ /* do the TIMED_TESTS set, one step at a time on the entire memory
+ that can be allocated, and stop when the given time is exceeded */
while ( (getTimeMilliseconds() - startt) < time_constr)
- {
- res = do_memtest(QUICK_TESTS, devmem, 1);
+ {
+ res = do_memtest(TIMED_TESTS, devmem, 1);
if (res != 0) break;
}
if (dev_id != -1) cudaThreadExit();
return res;
}
-/*******************************************************/
+/*! \cond TEST */
+
+/*******************************************************
+ * The code below is for testing purposes. */
int do_custom_memtest(int dev_id)
{
cudaDeviceProp dev_prop;
// tester.deallocate();
// devmem = dev_prop.totalGlobalMem/(1024*1024); // in MiB
- mem2test = BMARK_MEM;
+ mem2test = 80;
#if _DEBUG_ >= 1
- printf(">> Running CUSTOM memtests [%x] on %d MiB (out of total %d MiB), %d iterations\n",
- QUICK_TESTS, mem2test, devmem, 1);
+ printf(">> Running CUSTOM memtests [%x] on %d MiB, %d iterations\n",
+ QUICK_TESTS, mem2test, 1);
#endif
res = do_memtest(QUICK_TESTS, mem2test, 1);
}
#if _DEBUG_ > 1
-/**
+/*!
* Only for debugging purposes, compile with:
* nvcc -DLINUX -D_DEBUG_=2 -L -O -Xcompiler -Wall memtestG80_core.o gmx_gpu_utils.cu -o gmx_gpu_utils_test
*/
int dev_id = 0;
char msg[100];
sprintf(msg, "Device #%d supported: ", dev_id);
- switch (is_supported_cuda_gpu(dev_id))
+ switch (is_supported_cuda_gpu(dev_id, NULL))
{
case -1: strcat(msg, "error occured"); break;
case 0: strcat(msg, "no"); break;
printf("Doing memtest.\n");
printf("quick memtest result: %d\n", do_quick_memtest(dev_id));
+ printf("timed memtest result: %d\n", do_timed_memtest(dev_id, 15));
printf("full memtest result: %d\n", do_full_memtest(dev_id));
return 0;
}
#endif
+
+
+#ifndef _string2_h
+#include <string.h>
+/*
+ Functions only used if this file is compiled in debug mode (_DEBUG_ > 0)
+ when the gromacs version are not available.
+ - string trimming function - duplicated from ~/src/gmxlib/string2.c
+ - case agnostic straing compare
+ */
+static void ltrim (char *str)
+{
+ char *tr;
+ int c;
+
+ if (!str)
+ return;
+
+ tr = strdup (str);
+ c = 0;
+ while ((tr[c] == ' ') || (tr[c] == '\t'))
+ c++;
+
+ strcpy (str,tr+c);
+ free (tr);
+}
+
+static void rtrim (char *str)
+{
+ int nul;
+
+ if (!str)
+ return;
+
+ nul = strlen(str)-1;
+ while ((nul > 0) && ((str[nul] == ' ') || (str[nul] == '\t')) ) {
+ str[nul] = '\0';
+ nul--;
+ }
+}
+
+static void trim (char *str)
+{
+ ltrim (str);
+ rtrim (str);
+}
+
+static int gmx_strncasecmp(const char* s1, const char* s2, int len)
+{
+ return strncasecmp(s1, s2, len);
+}
+#endif
+
+/*! \endcond TEST */
using namespace OpenMM;
-/// \cond
+/*! \cond */
#define MEM_ERR_MSG(str) \
"The %s-simulation GPU memory test detected errors. As memory errors would cause incorrect " \
"simulation results, gromacs has aborted execution.\n Make sure that your GPU's memory is not " \
"overclocked and that the device is properly cooled.\n", (str)
-/// \endcond
+/*! \endcond */
-/**
+/*!
* \brief Convert string to integer type.
* \param[in] s String to convert from.
* \param[in] ios_base Basefield format flag that takes any of the following I/O
return !(iss >> f >> t).fail();
}
-/**
+/*!
* \brief Split string around a given delimiter.
* \param[in] s String to split.
* \param[in] delim Delimiter character that defines the boundaries of substring in \p s.
return elems;
}
-/**
+/*!
* \brief Split a string of the form "option=value" into "option" and "value" strings.
* This string corresponds to one option and the associated value from the option list
* in the mdrun -device argument.
}
}
-/**
+/*!
* \brief Compare two strings ignoring case.
* This function is in fact a wrapper around the gromacs function gmx_strncasecmp().
* \param[in] s1 String.
return (gmx_strncasecmp(s1.c_str(), s2.c_str(), max(s1.length(), s2.length())) == 0);
}
-/**
+/*!
* \brief Convert string to upper case.
*
* \param[in] s String to convert to uppercase.
- * \returns The given string converted to uppercase.
+ * \returns The given string converted to uppercase.
*/
static string toUpper(const string &s)
{
return stmp;
}
-#define SIZEOF_PLATFORMS 1 /*!< Number of constant values in platforms option. */
-#define SIZEOF_MEMTESTS 3 /*!< Number of constant values in memtest option. */
-#define SIZEOF_DEVICEIDS 1 /*!< Number of constant values in deviceid options. */
-#define SIZEOF_FORCE_DEV 2 /*!< Number of constant values in force-dev options. */
-
-/** Possible platform options in the mdrun -device option. */
-static const char *devOptStrings[] = { "platform", "deviceid", "memtest", "force-device" };
-/** Enumerated platform options in the mdrun -device option. */
+/*!
+ \name Sizes of constant device option arrays GmxOpenMMPlatformOptions#platforms,
+ GmxOpenMMPlatformOptions#memtests, GmxOpenMMPlatformOptions#deviceid,
+ GmxOpenMMPlatformOptions#force_dev. */
+/* {@ */
+#define SIZEOF_PLATFORMS 1
+#define SIZEOF_MEMTESTS 3
+#define SIZEOF_DEVICEIDS 1
+#define SIZEOF_FORCE_DEV 2
+/* @} */
+
+/*! Possible platform options in the mdrun -device option. */
+static const char *devOptStrings[] = { "platform", "deviceid", "memtest", "force-device" };
+
+/*! Enumerated platform options in the mdrun -device option. */
enum devOpt
{
PLATFORM = 0,
FORCE_DEVICE = 3
};
-/**
+/*!
* \brief Class to extract and manage the platform options in the mdrun -device option.
*
*/
private:
void setOption(const string &opt, const string &val);
- map<string, string> options; /**< Data structure to store the option (name, value) pairs. */
+ map<string, string> options; /*!< Data structure to store the option (name, value) pairs. */
- static const char * const platforms[SIZEOF_PLATFORMS]; /**< Available OpenMM platforms; size #SIZEOF_PLATFORMS */
- static const char * const memtests[SIZEOF_MEMTESTS]; /**< Available types of memory tests, also valid
+ static const char * const platforms[SIZEOF_PLATFORMS]; /*!< Available OpenMM platforms; size #SIZEOF_PLATFORMS */
+ static const char * const memtests[SIZEOF_MEMTESTS]; /*!< Available types of memory tests, also valid
any positive integer >=15; size #SIZEOF_MEMTESTS */
- static const char * const deviceid[SIZEOF_DEVICEIDS]; /**< Possible values for deviceid option;
+ static const char * const deviceid[SIZEOF_DEVICEIDS]; /*!< Possible values for deviceid option;
also valid any positive integer; size #SIZEOF_DEVICEIDS */
- static const char * const force_dev[SIZEOF_FORCE_DEV]; /**< Possible values for for force-device option;
+ static const char * const force_dev[SIZEOF_FORCE_DEV]; /*!< Possible values for for force-device option;
size #SIZEOF_FORCE_DEV */
};
const char * const GmxOpenMMPlatformOptions::deviceid[SIZEOF_DEVICEIDS] = { "0" };
const char * const GmxOpenMMPlatformOptions::force_dev[SIZEOF_FORCE_DEV] = { "no", "yes" };
-/**
+/*!
* \brief Contructor.
* Takes the option list, parses it, checks the options and their values for validity.
* When certain options are not provided by the user, as default value the first item
- * of the respective constant array is taken (GmxOpenMMPlatformOptions::platforms,
- * GmxOpenMMPlatformOptions::memtests, GmxOpenMMPlatformOptions::deviceid,
- * GmxOpenMMPlatformOptions::force_dev).
+ * of the respective constant array is taken (GmxOpenMMPlatformOptions#platforms,
+ * GmxOpenMMPlatformOptions#memtests, GmxOpenMMPlatformOptions#deviceid,
+ * GmxOpenMMPlatformOptions#force_dev).
* \param[in] optionString Option string part of the mdrun -deviceoption parameter.
*/
GmxOpenMMPlatformOptions::GmxOpenMMPlatformOptions(const char *optionString)
}
-/**
- * Returns the value of an option.
+/*!
+ * \brief Returns the value of an option.
* \param[in] opt Name of the option.
*/
string GmxOpenMMPlatformOptions::getOptionValue(const string &opt)
}
}
-/**
- * Setter function - private, only used from contructor.
+/*!
+ * \brief Setter function - private, only used from contructor.
* \param[in] opt Name of the option.
* \param[in] val Value for the option.
*/
options[toUpper(opt)] = val;
}
-/**
- * Removes an option with its value from the map structure. If the option
+/*!
+ * \brief Removes an option with its value from the map structure. If the option
* does not exist, returns without any action.
* \param[in] opt Name of the option.
*/
}
-/**
+/*!
* \brief Container for OpenMM related data structures that represent the bridge
* between the Gromacs data-structures and the OpenMM library and is but it's
* only passed through the API functions as void to disable direct access.
class OpenMMData
{
public:
- System* system; /** The system to simulate. */
- Context* context; /** The OpenMM context in which the simulation is carried out. */
- Integrator* integrator; /** The integrator used in the simulation. */
- bool removeCM; /** If \true remove venter of motion, false otherwise. */
- GmxOpenMMPlatformOptions *platformOpt; /** Platform options. */
+ System* system; /*! The system to simulate. */
+ Context* context; /*! The OpenMM context in which the simulation is carried out. */
+ Integrator* integrator; /*! The integrator used in the simulation. */
+ bool removeCM; /*! If \true remove venter of motion, false otherwise. */
+ GmxOpenMMPlatformOptions *platformOpt; /*! Platform options. */
};
-/**
+/*!
* \brief Runs memtest on the GPU that has alreaby been initialized by OpenMM.
* \param[in] fplog Pointer to gromacs log file.
* \param[in] devId Device id of the GPU to run the test on. TODO: this can be removed!
fflush(stdout);
}
-/*
+/*!
* \brief Does gromacs option checking.
*
* Checks the gromacs mdp options for features unsupported in OpenMM, case in which
- * interrupts the execution. It alsowarn the user about pecularities of OpenMM
+ * interrupts the execution. It also warns the user about pecularities of OpenMM
* implementations.
- * \param[in] ir Gromacs structure for input options, see ::t_inputrec
- * \param[in] top ??? TODO
+ * \param[in] ir Gromacs structure for input options, \see ::t_inputrec
+ * \param[in] top Gromacs topology, \see ::gmx_localtop_t
*/
void checkGmxOptions(t_inputrec *ir, gmx_localtop_t *top)
{
}
-/**
+/*!
* \brief Initialize OpenMM, run sanity/consistency checks, and return a pointer to
* the OpenMMData.
*
* - Gromacs parameters are checked for OpenMM support and consistency;
* - after the OpenMM is initialized memtest executed in the same GPU context.
*
- * \param[in] fplog
- * \param[in] platformOptStr
- * \param[in] cr
- * \param[in] ir
- * \param[in] top_global
- * \param[in] top
- * \param[in] mdatoms
- * \param[in] fr
- * \param[in] state
+ * \param[in] fplog Gromacs log file handler.
+ * \param[in] platformOptStr Platform option string.
+ * \param[in] cr TODO remove!
+ * \param[in] ir The Gromacs input parameters.
+ * \param[in] top_global TODO
+ * \param[in] top TODO
+ * \param[in] mdatoms TODO
+ * \param[in] fr TODO
+ * \param[in] state TODO
*
- * TODO finish the docs for openmm_init.
*/
void* openmm_init(FILE *fplog, const char *platformOptStr,
t_commrec *cr,t_inputrec *ir,
}
}
-/**
- * Integrate one step.
+/*!
+ * \brief Integrate one step.
*
* \param[in] data OpenMMData object created by openmm_init().
*/
}
}
-/**
- * Integrate n steps.
+/*!
+ * \brief Integrate n steps.
*
* \param[in] data OpenMMData object created by openmm_init().
*/
}
}
-/**
- * Clean up the data structures cretead for OpenMM.
+/*!
+ * \brief Clean up the data structures cretead for OpenMM.
*
* \param[in] log Log file pointer.
* \param[in] data OpenMMData object created by openmm_init().
delete d;
}
-/**
+/*!
* \brief Copy the current state information from OpenMM into the Gromacs data structures.
*
* This function results in the requested proprties to be copied from the