diff --git a/PG-PuReMD/Makefile.am b/PG-PuReMD/Makefile.am index 5681e43a93fcb419f27e62ae25e3d72e5ee8740c..c5c84052219e835a12a5529ceff6223a524dd1a3 100644 --- a/PG-PuReMD/Makefile.am +++ b/PG-PuReMD/Makefile.am @@ -16,15 +16,15 @@ NVCCFLAGS += --compiler-options "$(DEFS) $(NVCC_OPT_CODE_DEFS) -O3 -funroll-loop endif -bin_PROGRAMS = bin/pg-puremd -bin_pg_puremd_SOURCES = src/allocate.c src/basic_comm.c src/ffield.c src/grid.c src/list.c \ +lib_LTLIBRARIES = lib/libpuremd.la +lib_libpuremd_la_SOURCES = src/allocate.c src/basic_comm.c src/ffield.c src/grid.c src/list.c \ src/lookup.c src/io_tools.c src/reset_tools.c src/restart.c src/random.c \ src/tool_box.c src/traj.c src/analyze.c src/box.c src/system_props.c \ src/control.c src/comm_tools.c src/geo_tools.c src/lin_alg.c src/neighbors.c \ src/charges.c src/bond_orders.c src/multi_body.c src/bonds.c src/valence_angles.c \ src/hydrogen_bonds.c src/torsion_angles.c src/nonbonded.c src/forces.c \ - src/integrate.c src/init_md.c src/parallelreax.c -include_HEADERS = src/reax_types.h src/index_utils.h \ + src/integrate.c src/init_md.c src/puremd.c +lib_libpuremd_la_SOURCES += src/reax_types.h src/index_utils.h \ src/allocate.h src/basic_comm.h src/ffield.h src/grid.h src/list.h \ src/lookup.h src/io_tools.h src/reset_tools.h src/restart.h src/random.h src/vector.h \ src/tool_box.h src/traj.h src/analyze.h src/box.h src/system_props.h \ @@ -32,9 +32,10 @@ include_HEADERS = src/reax_types.h src/index_utils.h \ src/charges.h src/bond_orders.h src/multi_body.h src/bonds.h src/valence_angles.h \ src/hydrogen_bonds.h src/torsion_angles.h src/nonbonded.h src/forces.h \ src/integrate.h src/init_md.h +include_HEADERS = src/puremd.h if USE_CUDA -bin_pg_puremd_SOURCES += src/cuda/cuda_utils.cu src/cuda/cuda_allocate.cu src/cuda/cuda_environment.cu \ +lib_libpuremd_la_SOURCES += src/cuda/cuda_utils.cu src/cuda/cuda_allocate.cu src/cuda/cuda_environment.cu \ src/cuda/cuda_system_props.cu src/cuda/cuda_reduction.cu src/cuda/cuda_box.cu src/cuda/cuda_list.cu \ src/cuda/cuda_copy.cu src/cuda/cuda_reset_tools.cu src/cuda/cuda_random.cu \ src/cuda/cuda_neighbors.cu src/cuda/cuda_bond_orders.cu src/cuda/cuda_bonds.cu \ @@ -43,7 +44,7 @@ bin_pg_puremd_SOURCES += src/cuda/cuda_utils.cu src/cuda/cuda_allocate.cu src/cu src/cuda/cuda_charges.cu src/cuda/cuda_lin_alg.cu \ src/cuda/cuda_nonbonded.cu src/cuda/cuda_integrate.cu src/cuda/cuda_post_evolve.cu \ src/cuda/cuda_init_md.cu src/cuda/cuda_lookup.cu -include_HEADERS += src/cuda/cuda_helpers.h src/cuda/cuda_shuffle.h \ +lib_libpuremd_la_SOURCES += src/cuda/cuda_helpers.h src/cuda/cuda_shuffle.h \ src/cuda/cuda_utils.h src/cuda/cuda_allocate.h src/cuda/cuda_environment.h \ src/cuda/cuda_system_props.h src/cuda/cuda_reduction.h src/cuda/cuda_box.h src/cuda/cuda_list.h \ src/cuda/cuda_copy.h src/cuda/cuda_reset_tools.h src/cuda/cuda_random.h src/cuda/cuda_vector.h \ @@ -55,20 +56,28 @@ include_HEADERS += src/cuda/cuda_helpers.h src/cuda/cuda_shuffle.h \ src/cuda/cuda_init_md.h src/cuda/cuda_lookup.h if DEBUG -bin_pg_puremd_SOURCES += src/cuda/cuda_validation.cu -include_HEADERS += src/cuda/cuda_validation.h +lib_libpuremd_la_SOURCES += src/cuda/cuda_validation.cu +lib_libpuremd_la_SOURCES += src/cuda/cuda_validation.h endif # dummy source to cause C linking -nodist_EXTRA_bin_pg_puremd_SOURCES = src/dummy.c - +nodist_EXTRA_lib_libpuremd_la_SOURCES = src/dummy.c endif +lib_libpuremd_la_CFLAGS = $(AM_CFLAGS) $(MPI_CFLAGS) $(CFLAGS) +lib_libpuremd_la_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) +lib_libpuremd_la_LIBADD = $(AM_LDADD) $(MPI_LIBS) $(LDADD) -lstdc++ +lib_libpuremd_la_LDFLAGS = -version-info 1:0:0 +if USE_CUDA +lib_libpuremd_la_CFLAGS += $(CUDA_CFLAGS) +lib_libpuremd_la_LIBADD += $(CUDA_LIBS) +endif +bin_PROGRAMS = bin/pg-puremd +bin_pg_puremd_SOURCES = src/driver.c bin_pg_puremd_CFLAGS = $(AM_CFLAGS) $(MPI_CFLAGS) $(CFLAGS) -bin_pg_puremd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -bin_pg_puremd_LDADD = $(AM_LDADD) $(MPI_LIBS) $(LDADD) -lstdc++ - +bin_pg_puremd_CPPFLAGS = -I src $(AM_CPPFLAGS) $(CPPFLAGS) +bin_pg_puremd_LDADD = lib/libpuremd.la $(AM_LDADD) $(MPI_LIBS) $(LDADD) -lstdc++ if USE_CUDA bin_pg_puremd_CFLAGS += $(CUDA_CFLAGS) bin_pg_puremd_LDADD += $(CUDA_LIBS) diff --git a/PG-PuReMD/aclocal.m4 b/PG-PuReMD/aclocal.m4 index e1a7adedccfa9f18035be1d931ad439b6df5dc38..8206dbb643189be5c98f9d5fa31a85ad053315ff 100644 --- a/PG-PuReMD/aclocal.m4 +++ b/PG-PuReMD/aclocal.m4 @@ -56,6 +56,66 @@ m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) +# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_AR([ACT-IF-FAIL]) +# ------------------------- +# Try to determine the archiver interface, and trigger the ar-lib wrapper +# if it is needed. If the detection of archiver interface fails, run +# ACT-IF-FAIL (default is to abort configure with a proper error message). +AC_DEFUN([AM_PROG_AR], +[AC_BEFORE([$0], [LT_INIT])dnl +AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([ar-lib])dnl +AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) +: ${AR=ar} + +AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], + [AC_LANG_PUSH([C]) + am_cv_ar_interface=ar + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], + [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + ]) + AC_LANG_POP([C])]) + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + m4_default([$1], + [AC_MSG_ERROR([could not determine $AR interface])]) + ;; +esac +AC_SUBST([AR])dnl +]) + # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. @@ -1153,3 +1213,8 @@ AC_SUBST([am__untar]) m4_include([../m4/acx_mpi.m4]) m4_include([../m4/ax_compiler_vendor.m4]) m4_include([../m4/ax_cuda.m4]) +m4_include([../m4/libtool.m4]) +m4_include([../m4/ltoptions.m4]) +m4_include([../m4/ltsugar.m4]) +m4_include([../m4/ltversion.m4]) +m4_include([../m4/lt~obsolete.m4]) diff --git a/PG-PuReMD/configure.ac b/PG-PuReMD/configure.ac index bd79fae4f44e55a3bfef67f00beb8458d4094fd3..ff85bf947cc35b417af4c257b625a6365339aee1 100644 --- a/PG-PuReMD/configure.ac +++ b/PG-PuReMD/configure.ac @@ -10,8 +10,9 @@ sav_CFLAGS="$CFLAGS" AM_INIT_AUTOMAKE([1.15 subdir-objects -Wall -Werror foreign]) # Enable silent build rules by default. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [AC_SUBST([AM_DEFAULT_VERBOSITY],[1])]) -#LT_PREREQ([2.2]) -#LT_INIT([dlopen]) +AM_PROG_AR +LT_PREREQ([2.2]) +LT_INIT([dlopen]) AC_CONFIG_MACRO_DIR([../m4]) diff --git a/PG-PuReMD/src/driver.c b/PG-PuReMD/src/driver.c new file mode 100644 index 0000000000000000000000000000000000000000..10e86b412d588607b69bbd51f4f02cfb1e7feb47 --- /dev/null +++ b/PG-PuReMD/src/driver.c @@ -0,0 +1,70 @@ + +/*---------------------------------------------------------------------- + SerialReax - Reax Force Field Simulator + + Copyright (2010) Purdue University + Hasan Metin Aktulga, haktulga@cs.purdue.edu + Joseph Fogarty, jcfogart@mail.usf.edu + Sagar Pandit, pandit@usf.edu + Ananth Y Grama, ayg@cs.purdue.edu + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 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 General Public License for more details: + <http://www.gnu.org/licenses/>. + ----------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> + +#include "puremd.h" + +#define INVALID_INPUT (-1) + + +static void usage( char * argv[] ) +{ + fprintf( stderr, "usage: ./%s geometry_file force_field_params_file control_file\n", argv[0] ); +} + + +int main( int argc, char* argv[] ) +{ + void *handle; + int ret; + + MPI_Init( &argc, &argv ); + + if ( argc != 4 ) + { + usage( argv ); + MPI_Abort( MPI_COMM_WORLD, INVALID_INPUT ); + } + + handle = setup( argv[1], argv[2], argv[3] ); + ret = PUREMD_FAILURE; + + if ( handle != NULL ) + { + ret = simulate( handle ); + } + + MPI_Finalized( &ret ); + if ( !ret ) + { + MPI_Finalize( ); + } + + if ( ret == PUREMD_SUCCESS ) + { + ret = cleanup( handle ); + } + + return (ret == PUREMD_SUCCESS) ? 0 : (-1); +} diff --git a/PG-PuReMD/src/ffield.c b/PG-PuReMD/src/ffield.c index 96d2e6b22de0fa56e1cfac417466d58905213cc2..0878882172cfcbe2adcfa775b2bdd905089ed8ca 100644 --- a/PG-PuReMD/src/ffield.c +++ b/PG-PuReMD/src/ffield.c @@ -30,7 +30,7 @@ #endif -void Read_Force_Field( char *ffield_file, reax_interaction *reax, +void Read_Force_Field_File( char *ffield_file, reax_interaction *reax, reax_system *system, control_params *control ) { FILE *fp; diff --git a/PG-PuReMD/src/ffield.h b/PG-PuReMD/src/ffield.h index 6b11374252f3922a59268071aa700ecfa6d61e5f..d847366fc115fec9df6c16de34eca3239ef09eef 100644 --- a/PG-PuReMD/src/ffield.h +++ b/PG-PuReMD/src/ffield.h @@ -29,7 +29,7 @@ extern "C" { #endif -void Read_Force_Field( char*, reax_interaction*, reax_system *, control_params* ); +void Read_Force_Field_File( char*, reax_interaction*, reax_system *, control_params* ); #ifdef __cplusplus } diff --git a/PG-PuReMD/src/geo_tools.c b/PG-PuReMD/src/geo_tools.c index ecc1866cde7c9208dc5bc4e5ebac3aa7bcc83b28..24c5092aa0fe4090a40cc06e92a91ce62248357f 100644 --- a/PG-PuReMD/src/geo_tools.c +++ b/PG-PuReMD/src/geo_tools.c @@ -67,7 +67,7 @@ void Count_Geo_Atoms( FILE *geo, reax_system *system ) } -void Read_Geo( char* geo_file, reax_system* system, control_params *control, +void Read_Geo_File( char* geo_file, reax_system* system, control_params *control, simulation_data *data, storage *workspace, mpi_datatypes *mpi_data ) { int i, j, serial, top; @@ -79,7 +79,7 @@ void Read_Geo( char* geo_file, reax_system* system, control_params *control, reax_atom *atom; /* open the geometry file */ - geo = sfopen( geo_file, "r", "Read_Geo::geo" ); + geo = sfopen( geo_file, "r", "Read_Geo_File::geo" ); /* read box information */ fscanf( geo, CUSTOM_BOXGEO_FORMAT, @@ -136,7 +136,7 @@ void Read_Geo( char* geo_file, reax_system* system, control_params *control, } } - sfclose( geo, "Read_Geo::geo" ); + sfclose( geo, "Read_Geo_File::geo" ); #if defined(DEBUG_FOCUS) fprintf( stderr, "p%d: finished reading the geo file\n", system->my_rank ); @@ -247,7 +247,7 @@ void Count_PDB_Atoms( FILE *geo, reax_system *system ) } -void Read_PDB( char* pdb_file, reax_system* system, control_params *control, +void Read_PDB_File( char* pdb_file, reax_system* system, control_params *control, simulation_data *data, storage *workspace, mpi_datatypes *mpi_data ) { FILE *pdb; @@ -264,7 +264,7 @@ void Read_PDB( char* pdb_file, reax_system* system, control_params *control, rvec x; reax_atom *atom; - pdb = sfopen( pdb_file, "r", "Read_PDB::pdb" ); + pdb = sfopen( pdb_file, "r", "Read_PDB_File::pdb" ); /* allocate memory for tokenizing pdb lines */ Allocate_Tokenizer_Space( &s, &s1, &tmp ); @@ -451,14 +451,14 @@ void Read_PDB( char* pdb_file, reax_system* system, control_params *control, } } - sfclose( pdb, "Read_PDB::pdb" ); + sfclose( pdb, "Read_PDB_File::pdb" ); } /* PDB serials are written without regard to the order, we'll see if this * cause trouble, if so we'll have to rethink this approach * Also, we do not write connect lines yet. */ -void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, +void Write_PDB_File( reax_system* system, reax_list* bonds, simulation_data *data, control_params *control, mpi_datatypes *mpi_data, output_controls *out_control ) { int i, cnt, me, np, buffer_req, buffer_len; @@ -477,7 +477,7 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, np = control->nprocs; /* Allocation*/ - line = smalloc( sizeof(char) * PDB_ATOM_FORMAT_O_LENGTH, "Write_PDB::line" ); + line = smalloc( sizeof(char) * PDB_ATOM_FORMAT_O_LENGTH, "Write_PDB_File::line" ); if ( me == MASTER_NODE ) { buffer_req = system->bigN * PDB_ATOM_FORMAT_O_LENGTH; @@ -487,7 +487,7 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, buffer_req = system->n * PDB_ATOM_FORMAT_O_LENGTH; } - buffer = smalloc( sizeof(char) * buffer_req, "Write_PDB::buffer" ); + buffer = smalloc( sizeof(char) * buffer_req, "Write_PDB_File::buffer" ); pdb = NULL; line[0] = 0; @@ -512,7 +512,7 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, sprintf( fname, "%s-%d.pdb", control->sim_name, data->step ); - pdb = sfopen( fname, "w", "Write_PDB::pdb" ); + pdb = sfopen( fname, "w", "Write_PDB_File::pdb" ); fprintf( pdb, PDB_CRYST1_FORMAT_O, "CRYST1", system->big_box.box_norms[0], system->big_box.box_norms[1], @@ -563,7 +563,7 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, if ( me == MASTER_NODE) { fprintf( pdb, "%s", buffer ); - sfclose( pdb, "Write_PDB::pdb" ); + sfclose( pdb, "Write_PDB_File::pdb" ); } /* Writing connect information */ @@ -585,6 +585,6 @@ void Write_PDB( reax_system* system, reax_list* bonds, simulation_data *data, } */ - sfree( buffer, "Write_PDB::buffer" ); - sfree( line, "Write_PDB::line" ); + sfree( buffer, "Write_PDB_File::buffer" ); + sfree( line, "Write_PDB_File::line" ); } diff --git a/PG-PuReMD/src/geo_tools.h b/PG-PuReMD/src/geo_tools.h index 16f2b823e666929499aadd393e01f7ae108328b5..dc8f1adc9dc73f602fa5deebe5939d6d7d8b45ec 100644 --- a/PG-PuReMD/src/geo_tools.h +++ b/PG-PuReMD/src/geo_tools.h @@ -115,13 +115,13 @@ COLUMNS DATA TYPE FIELD DEFINITION extern "C" { #endif -void Read_Geo( char*, reax_system*, control_params*, +void Read_Geo_File( char*, reax_system*, control_params*, simulation_data*, storage*, mpi_datatypes* ); -void Read_PDB( char*, reax_system*, control_params*, +void Read_PDB_File( char*, reax_system*, control_params*, simulation_data*, storage*, mpi_datatypes* ); -void Write_PDB( reax_system*, reax_list*, simulation_data*, +void Write_PDB_File( reax_system*, reax_list*, simulation_data*, control_params*, mpi_datatypes*, output_controls* ); #ifdef __cplusplus diff --git a/PG-PuReMD/src/parallelreax.c b/PG-PuReMD/src/parallelreax.c deleted file mode 100644 index 58a95d403746a145f5393cbed36d1a812d79e6f6..0000000000000000000000000000000000000000 --- a/PG-PuReMD/src/parallelreax.c +++ /dev/null @@ -1,563 +0,0 @@ -/*---------------------------------------------------------------------- - PuReMD - Purdue ReaxFF Molecular Dynamics Program - - Copyright (2010) Purdue University - Hasan Metin Aktulga, haktulga@cs.purdue.edu - Joseph Fogarty, jcfogart@mail.usf.edu - Sagar Pandit, pandit@usf.edu - Ananth Y Grama, ayg@cs.purdue.edu - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 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 General Public License for more details: - <http://www.gnu.org/licenses/>. - ----------------------------------------------------------------------*/ - -#include "reax_types.h" - -#include "allocate.h" -#include "analyze.h" -#include "comm_tools.h" -#include "control.h" -#include "ffield.h" -#include "forces.h" -#include "geo_tools.h" -#include "init_md.h" -#include "integrate.h" -#include "io_tools.h" -#include "neighbors.h" -#include "reset_tools.h" -#include "restart.h" -#include "system_props.h" -#include "tool_box.h" -#include "traj.h" -#include "vector.h" - -#ifdef HAVE_CUDA - #include "cuda/cuda_copy.h" - #include "cuda/cuda_environment.h" - #include "cuda/cuda_forces.h" - #include "cuda/cuda_init_md.h" - #include "cuda/cuda_neighbors.h" - #include "cuda/cuda_post_evolve.h" - #include "cuda/cuda_reset_tools.h" - #include "cuda/cuda_system_props.h" - #include "cuda/cuda_utils.h" - #if defined(DEBUG) - #include "cuda/cuda_validation.h" - #endif -#endif - -/* CUDA-specific globals */ -reax_list **dev_lists; -storage *dev_workspace; -void *scratch; -void *host_scratch; -int BLOCKS, BLOCKS_POW_2, BLOCK_SIZE; -int BLOCKS_N, BLOCKS_POW_2_N; -int MATVEC_BLOCKS; - - -void Read_Control_Files( char *geo_file, char *ffield_file, char *control_file, - reax_system *system, control_params *control, simulation_data *data, - storage *workspace, output_controls *out_control, mpi_datatypes *mpi_data ) -{ - Read_Force_Field( ffield_file, &(system->reax_param), system, control ); - - Read_Control_File( control_file, control, out_control ); - - if ( control->geo_format == CUSTOM ) - { - Read_Geo( geo_file, system, control, data, workspace, mpi_data ); - } - else if ( control->geo_format == PDB ) - { - Read_PDB( geo_file, system, control, data, workspace, mpi_data ); - } - else if ( control->geo_format == ASCII_RESTART ) - { - Read_Restart( geo_file, system, control, data, workspace, mpi_data ); - control->restart = 1; - } - else if ( control->geo_format == BINARY_RESTART ) - { - Read_Binary_Restart( geo_file, system, control, data, workspace, mpi_data ); - control->restart = 1; - } - else - { - fprintf( stderr, "unknown geo file format. terminating!\n" ); - MPI_Abort( MPI_COMM_WORLD, INVALID_GEO ); - } -} - - -void Post_Evolve( reax_system* system, control_params* control, - simulation_data* data, storage* workspace, reax_list** lists, - output_controls *out_control, mpi_datatypes *mpi_data ) -{ - int i; - rvec diff, cross; - - /* remove translational and rotational velocity of the center of mass from system */ - if ( control->ensemble != NVE && control->remove_CoM_vel && - data->step % control->remove_CoM_vel == 0 ) - { - /* compute velocity of the center of mass */ - Compute_Center_of_Mass( system, data, mpi_data, mpi_data->comm_mesh3D ); - - for ( i = 0; i < system->n; i++ ) - { - /* remove translational term */ - rvec_ScaledAdd( system->my_atoms[i].v, -1.0, data->vcm ); - - /* remove rotational term */ - rvec_ScaledSum( diff, 1.0, system->my_atoms[i].x, -1.0, data->xcm ); - rvec_Cross( cross, data->avcm, diff ); - rvec_ScaledAdd( system->my_atoms[i].v, -1.0, cross ); - } - } - - /* compute kinetic energy of system */ - Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); - - if ( (out_control->energy_update_freq > 0 - && data->step % out_control->energy_update_freq == 0) - || (out_control->write_steps > 0 - && data->step % out_control->write_steps == 0) ) - { - Compute_Total_Energy( system, data, MPI_COMM_WORLD ); - } -} - - -#ifdef HAVE_CUDA -int Cuda_Post_Evolve( reax_system* system, control_params* control, - simulation_data* data, storage* workspace, reax_list** lists, - output_controls *out_control, mpi_datatypes *mpi_data ) -{ - /* remove trans & rot velocity of the center of mass from system */ - if ( control->ensemble != NVE && control->remove_CoM_vel && - data->step % control->remove_CoM_vel == 0 ) - { - /* compute velocity of the center of mass */ - Cuda_Compute_Center_of_Mass( system, data, mpi_data, mpi_data->comm_mesh3D ); - - post_evolve_velocities( system, data ); - } - - /* compute kinetic energy of the system */ - Cuda_Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); - - return SUCCESS; -} -#endif - - -static void usage( char* argv[] ) -{ - fprintf( stderr, "usage: ./%s geometry_file force_field_params_file control_file\n", argv[0] ); -} - - -int main( int argc, char* argv[] ) -{ - reax_system *system; - control_params *control; - simulation_data *data; - storage *workspace; - reax_list **lists; - output_controls *out_control; - mpi_datatypes *mpi_data; - int i, ret, retries; - real t_start = 0, t_elapsed; -#if defined(DEBUG) - real t_begin, t_end; -#endif - - MPI_Init( &argc, &argv ); - - if ( argc != 4 ) - { - usage( argv ); - MPI_Abort( MPI_COMM_WORLD, INVALID_INPUT ); - } - -#ifdef HAVE_CUDA - system = smalloc( sizeof(reax_system), "main::system" ); - control = smalloc( sizeof(control_params), "main::control" ); - data = smalloc( sizeof(simulation_data), "main::data" ); - workspace = smalloc( sizeof(storage), "main::workspace" ); - lists = smalloc( sizeof(reax_list *) * LIST_N, "main::lists" ); - for ( i = 0; i < LIST_N; ++i ) - { - lists[i] = smalloc( sizeof(reax_list), "main::lists[i]" ); - lists[i]->allocated = FALSE; - } - out_control = smalloc( sizeof(output_controls), "main::out_control" ); - mpi_data = smalloc( sizeof(mpi_datatypes), "main::mpi_data" ); - - /* allocate auxiliary data structures (GPU) */ - dev_workspace = smalloc( sizeof(storage), "main::dev_workspace" ); - dev_lists = smalloc ( sizeof(reax_list *) * LIST_N, "main::dev_lists" ); - for ( i = 0; i < LIST_N; ++i ) - { - dev_lists[i] = smalloc( sizeof(reax_list), "main::dev_lists[i]" ); - dev_lists[i]->allocated = FALSE; - } - - /* setup MPI environment */ - MPI_Comm_size( MPI_COMM_WORLD, &(control->nprocs) ); - MPI_Comm_rank( MPI_COMM_WORLD, &(system->my_rank) ); - - /* read system config files */ - Read_Control_Files( argv[1], argv[2], argv[3], system, control, - data, workspace, out_control, mpi_data ); - - /* setup the CUDA Device for this process */ - Setup_Cuda_Environment( system->my_rank, control->nprocs, control->gpus_per_node ); - -#if defined(DEBUG) - print_device_mem_usage( ); -#endif - - /* init blocks sizes */ - init_blocks( system ); - - if ( system->my_rank == MASTER_NODE ) - { - t_start = Get_Time( ); - } - - Cuda_Initialize( system, control, data, workspace, lists, out_control, mpi_data ); - -#if defined(__CUDA_DEBUG__) - Pure_Initialize( system, control, data, workspace, lists, out_control, mpi_data ); -#endif - -#if defined(DEBUG) - print_device_mem_usage( ); -#endif - - /* init the blocks sizes for cuda kernels */ - init_blocks( system ); - - /* compute f_0 */ - Comm_Atoms( system, control, data, workspace, mpi_data, TRUE ); - Sync_Atoms( system ); - Sync_Grid( &system->my_grid, &system->d_my_grid ); - init_blocks( system ); - - Cuda_Reset( system, control, data, workspace, lists ); - -#if defined(__CUDA_DEBUG__) - Reset( system, control, data, workspace, lists ); -#endif - - Cuda_Generate_Neighbor_Lists( system, data, workspace, lists ); - -#if defined(__CUDA_DEBUG__) - Generate_Neighbor_Lists( system, data, workspace, lists ); -#endif - -#if defined(__CUDA_DEBUG__) - Compute_Forces( system, control, data, workspace, - lists, out_control, mpi_data ); -#endif - - Cuda_Compute_Forces( system, control, data, workspace, lists, - out_control, mpi_data ); - -#if defined (__CUDA_DEBUG__) - Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); -#endif - - Cuda_Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); - -#if defined(__CUDA_DEBUG__) - validate_device( system, data, workspace, lists ); -#endif - -#if !defined(__CUDA_DEBUG__) - Output_Results( system, control, data, lists, out_control, mpi_data ); -#endif - -#if defined(DEBUG) - fprintf( stderr, "p%d: step%d completed\n", system->my_rank, data->step ); - MPI_Barrier( MPI_COMM_WORLD ); -#endif - - ++data->step; - retries = 0; - while ( data->step <= control->nsteps && retries < MAX_RETRIES ) - { - ret = SUCCESS; - - if ( control->T_mode && retries == 0 ) - { - Temperature_Control( control, data ); - } - -#if defined(DEBUG) - t_begin = Get_Time(); -#endif - -#if defined(__CUDA_DEBUG__) - ret = control->Evolve( system, control, data, workspace, - lists, out_control, mpi_data ); -#endif - - ret = control->Cuda_Evolve( system, control, data, workspace, - lists, out_control, mpi_data ); - -#if defined(DEBUG) - t_end = Get_Timing_Info( t_begin ); - fprintf( stderr, " Evolve time: %f \n", t_end ); -#endif - -#if defined(DEBUG) - t_begin = Get_Time(); -#endif - - if ( ret == SUCCESS ) - { - ret = Cuda_Post_Evolve( system, control, data, workspace, lists, - out_control, mpi_data ); - } - -#if defined(__CUDA_DEBUG__) - Post_Evolve(system, control, data, workspace, lists, out_control, mpi_data); -#endif - -#if defined(DEBUG) - t_end = Get_Timing_Info( t_begin ); - fprintf( stderr, " Post Evolve time: %f \n", t_end ); -#endif - - if ( ret == SUCCESS ) - { - data->timing.num_retries = retries; - -#if !defined(__CUDA_DEBUG__) - Output_Results( system, control, data, lists, out_control, mpi_data ); -#endif - -// Analysis(system, control, data, workspace, lists, out_control, mpi_data); - - /* dump restart info */ -// if ( out_control->restart_freq && -// (data->step-data->prev_steps) % out_control->restart_freq == 0 ) -// { -// if( out_control->restart_format == WRITE_ASCII ) -// { -// Write_Restart( system, control, data, out_control, mpi_data ); -// } -// else if( out_control->restart_format == WRITE_BINARY ) -// { -// Write_Binary_Restart( system, control, data, out_control, mpi_data ); -// } -// } - -#if defined(DEBUG) - fprintf( stderr, "p%d: step%d completed\n", system->my_rank, data->step ); - MPI_Barrier( MPI_COMM_WORLD ); -#endif - - ++data->step; - retries = 0; - } - else - { - ++retries; - -#if defined(DEBUG) - fprintf( stderr, "[INFO] p%d: retrying step %d...\n", system->my_rank, data->step ); -#endif - } - } - - if ( retries >= MAX_RETRIES ) - { - fprintf( stderr, "[ERROR] Maximum retries reached for this step (%d). Terminating...\n", - retries ); - MPI_Abort( MPI_COMM_WORLD, MAX_RETRIES_REACHED ); - } - -#if defined(__CUDA_DEBUG__) - /* vaildate the results in debug mode */ - validate_device( system, data, workspace, lists ); -#endif - -#else - system = smalloc( sizeof(reax_system), "main::system" ); - control = smalloc( sizeof(control_params), "main::control" ); - data = smalloc( sizeof(simulation_data), "main::data" ); - workspace = smalloc( sizeof(storage), "main::workspace" ); - lists = smalloc( sizeof(reax_list *) * LIST_N, "main::lists" ); - for ( i = 0; i < LIST_N; ++i ) - { - lists[i] = smalloc( sizeof(reax_list), "main::lists[i]" ); - lists[i]->allocated = FALSE; - } - out_control = smalloc( sizeof(output_controls), "main::out_control" ); - mpi_data = smalloc( sizeof(mpi_datatypes), "main::mpi_data" ); - - /* setup MPI environment */ - MPI_Comm_size( MPI_COMM_WORLD, &control->nprocs ); - MPI_Comm_rank( MPI_COMM_WORLD, &system->my_rank ); - - /* read config files */ - Read_Control_Files( argv[1], argv[2], argv[3], system, control, - data, workspace, out_control, mpi_data ); - - if ( system->my_rank == MASTER_NODE ) - { - t_start = Get_Time( ); - } - - Initialize( system, control, data, workspace, lists, out_control, mpi_data ); - - /* compute f_0 */ - Comm_Atoms( system, control, data, workspace, mpi_data, TRUE ); - - Reset( system, control, data, workspace, lists ); - - if ( ret == FAILURE ) - { - ReAllocate( system, control, data, workspace, lists, mpi_data ); - } - - ret = Generate_Neighbor_Lists( system, data, workspace, lists ); - - if ( ret != SUCCESS ) - { - fprintf( stderr, "[ERROR] cannot generate initial neighbor lists. Terminating...\n" ); - MPI_Abort( MPI_COMM_WORLD, CANNOT_INITIALIZE ); - } - - ret = Compute_Forces( system, control, data, workspace, lists, out_control, mpi_data ); - - if ( ret != SUCCESS ) - { - fprintf( stderr, "[ERROR] cannot compute initial forces. Terminating...\n" ); - MPI_Abort( MPI_COMM_WORLD, CANNOT_INITIALIZE ); - } - - Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); - - Compute_Total_Energy( system, data, MPI_COMM_WORLD ); - - Output_Results( system, control, data, lists, out_control, mpi_data ); - - Check_Energy( data ); - - retries = 0; - ++data->step; - while ( data->step <= control->nsteps && retries < MAX_RETRIES ) - { - ret = SUCCESS; - - if ( control->T_mode && retries == 0 ) - { - Temperature_Control( control, data ); - } - - ret = control->Evolve( system, control, data, workspace, - lists, out_control, mpi_data ); - - if ( ret == SUCCESS ) - { - Post_Evolve(system, control, data, workspace, lists, out_control, mpi_data); - } - - if ( ret == SUCCESS ) - { - data->timing.num_retries = retries; - - Output_Results( system, control, data, lists, out_control, mpi_data ); - -// Analysis(system, control, data, workspace, lists, out_control, mpi_data); - - /* dump restart info */ - if ( out_control->restart_freq && - (data->step - data->prev_steps) % out_control->restart_freq == 0 ) - { - if ( out_control->restart_format == WRITE_ASCII ) - { - Write_Restart( system, control, data, out_control, mpi_data ); - } - else if ( out_control->restart_format == WRITE_BINARY ) - { - Write_Binary_Restart( system, control, data, out_control, mpi_data ); - } - } - - Check_Energy( data ); - - ++data->step; - retries = 0; - } - else - { - ++retries; - -#if defined(DEBUG) - fprintf( stderr, "[INFO] p%d: retrying step %d...\n", system->my_rank, data->step ); -#endif - } - } - - if ( retries >= MAX_RETRIES ) - { - fprintf( stderr, "[ERROR] Maximum retries reached for this step (%d). Terminating...\n", - retries ); - MPI_Abort( MPI_COMM_WORLD, MAX_RETRIES_REACHED ); - } - -#endif - - /* end of the simulation, write total simulation time */ - if ( system->my_rank == MASTER_NODE ) - { - t_elapsed = Get_Timing_Info( t_start ); - fprintf( out_control->out, "Total Simulation Time: %.2f secs\n", t_elapsed ); - } - -// Write_PDB( &system, &lists[BONDS], &out_control ); - - Close_Output_Files( system, control, out_control, mpi_data ); - -#if defined(TEST_ENERGY) || defined(TEST_FORCES) -// Integrate_Results(control); -#endif - -#if defined(DEBUG) - fprintf( stderr, "p%d has reached the END\n", system->my_rank ); -#endif - - MPI_Finalized( &ret ); - if ( !ret ) - { - MPI_Finalize( ); - } - - sfree( mpi_data, "main::mpi_data" ); - sfree( out_control, "main::out_control" ); - for ( i = 0; i < LIST_N; ++i ) - { - sfree( lists[i], "main::lists[i]" ); - } - sfree( lists, "main::lists" ); - sfree( workspace, "main::workspace" ); - sfree( data, "main::data" ); - sfree( control, "main::control" ); - sfree( system, "main::system" ); - - return 0; -} diff --git a/PG-PuReMD/src/puremd.c b/PG-PuReMD/src/puremd.c new file mode 100644 index 0000000000000000000000000000000000000000..9439ac9696ccbe3ad4de222dffb279ee304d18b8 --- /dev/null +++ b/PG-PuReMD/src/puremd.c @@ -0,0 +1,649 @@ +/*---------------------------------------------------------------------- + PuReMD - Purdue ReaxFF Molecular Dynamics Program + + Copyright (2010) Purdue University + Hasan Metin Aktulga, haktulga@cs.purdue.edu + Joseph Fogarty, jcfogart@mail.usf.edu + Sagar Pandit, pandit@usf.edu + Ananth Y Grama, ayg@cs.purdue.edu + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 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 General Public License for more details: + <http://www.gnu.org/licenses/>. + ----------------------------------------------------------------------*/ + +#include "puremd.h" + +#include "allocate.h" +#include "analyze.h" +#include "comm_tools.h" +#include "control.h" +#include "ffield.h" +#include "forces.h" +#include "geo_tools.h" +#include "init_md.h" +#include "integrate.h" +#include "io_tools.h" +#include "neighbors.h" +#include "reset_tools.h" +#include "restart.h" +#include "system_props.h" +#include "tool_box.h" +#include "traj.h" +#include "vector.h" + +#ifdef HAVE_CUDA + #include "cuda/cuda_copy.h" + #include "cuda/cuda_environment.h" + #include "cuda/cuda_forces.h" + #include "cuda/cuda_init_md.h" + #include "cuda/cuda_neighbors.h" + #include "cuda/cuda_post_evolve.h" + #include "cuda/cuda_reset_tools.h" + #include "cuda/cuda_system_props.h" + #include "cuda/cuda_utils.h" + #if defined(DEBUG) + #include "cuda/cuda_validation.h" + #endif +#endif + +/* CUDA-specific globals */ +reax_list **dev_lists; +storage *dev_workspace; +void *scratch; +void *host_scratch; +int BLOCKS, BLOCKS_POW_2, BLOCK_SIZE; +int BLOCKS_N, BLOCKS_POW_2_N; +int MATVEC_BLOCKS; + + +static void Read_Config_Files( const char * const geo_file, const char * const ffield_file, + const char * const control_file, + reax_system *system, control_params *control, simulation_data *data, + storage *workspace, output_controls *out_control, mpi_datatypes *mpi_data ) +{ + Read_Force_Field_File( ffield_file, &system->reax_param, system, control ); + + Read_Control_File( control_file, control, out_control ); + + if ( control->geo_format == CUSTOM ) + { + Read_Geo_File( geo_file, system, control, data, workspace, mpi_data ); + } + else if ( control->geo_format == PDB ) + { + Read_PDB_File( geo_file, system, control, data, workspace, mpi_data ); + } + else if ( control->geo_format == ASCII_RESTART ) + { + Read_Restart_File( geo_file, system, control, data, workspace, mpi_data ); + control->restart = 1; + } + else if ( control->geo_format == BINARY_RESTART ) + { + Read_Binary_Restart_File( geo_file, system, control, data, workspace, mpi_data ); + control->restart = 1; + } + else + { + fprintf( stderr, "[ERROR] unknown geo file format. terminating!\n" ); + MPI_Abort( MPI_COMM_WORLD, INVALID_GEO ); + } +} + + +static void Post_Evolve( reax_system* system, control_params* control, + simulation_data* data, storage* workspace, reax_list** lists, + output_controls *out_control, mpi_datatypes *mpi_data ) +{ + int i; + rvec diff, cross; + + /* remove translational and rotational velocity of the center of mass from system */ + if ( control->ensemble != NVE && control->remove_CoM_vel && + data->step % control->remove_CoM_vel == 0 ) + { + /* compute velocity of the center of mass */ + Compute_Center_of_Mass( system, data, mpi_data, mpi_data->comm_mesh3D ); + + for ( i = 0; i < system->n; i++ ) + { + /* remove translational term */ + rvec_ScaledAdd( system->my_atoms[i].v, -1.0, data->vcm ); + + /* remove rotational term */ + rvec_ScaledSum( diff, 1.0, system->my_atoms[i].x, -1.0, data->xcm ); + rvec_Cross( cross, data->avcm, diff ); + rvec_ScaledAdd( system->my_atoms[i].v, -1.0, cross ); + } + } + + /* compute kinetic energy of system */ + Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); + + if ( (out_control->energy_update_freq > 0 + && data->step % out_control->energy_update_freq == 0) + || (out_control->write_steps > 0 + && data->step % out_control->write_steps == 0) ) + { + Compute_Total_Energy( system, data, MPI_COMM_WORLD ); + } +} + + +#ifdef HAVE_CUDA +static void Cuda_Post_Evolve( reax_system* system, control_params* control, + simulation_data* data, storage* workspace, reax_list** lists, + output_controls *out_control, mpi_datatypes *mpi_data ) +{ + /* remove trans & rot velocity of the center of mass from system */ + if ( control->ensemble != NVE && control->remove_CoM_vel && + data->step % control->remove_CoM_vel == 0 ) + { + /* compute velocity of the center of mass */ + Cuda_Compute_Center_of_Mass( system, data, mpi_data, mpi_data->comm_mesh3D ); + + post_evolve_velocities( system, data ); + } + + /* compute kinetic energy of the system */ + Cuda_Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); +} +#endif + + +void* setup( const char * const geo_file, const char * const ffield_file, + const char * const control_file ) +{ + int i; + puremd_handle *pmd_handle; + + /* top-level allocation */ + pmd_handle = (puremd_handle*) smalloc( sizeof(puremd_handle), + "setup::pmd_handle" ); + + /* second-level allocations */ + pmd_handle->system = smalloc( sizeof(reax_system), + "Setup::pmd_handle->system" ); + pmd_handle->control = smalloc( sizeof(control_params), + "Setup::pmd_handle->control" ); + pmd_handle->data = smalloc( sizeof(simulation_data), + "Setup::pmd_handle->data" ); + pmd_handle->workspace = smalloc( sizeof(storage), + "Setup::pmd_handle->workspace" ); + pmd_handle->lists = smalloc( sizeof(reax_list *) * LIST_N, + "Setup::pmd_handle->lists" ); + for ( i = 0; i < LIST_N; ++i ) + { + pmd_handle->lists[i] = smalloc( sizeof(reax_list), + "Setup::pmd_handle->lists[i]" ); + pmd_handle->lists[i]->allocated = FALSE; + } + pmd_handle->out_control = smalloc( sizeof(output_controls), + "Setup::pmd_handle->out_control" ); + pmd_handle->mpi_data = smalloc( sizeof(mpi_datatypes), + "Setup::pmd_handle->mpi_data" ); + +#ifdef HAVE_CUDA + /* allocate auxiliary data structures (GPU) */ + dev_workspace = smalloc( sizeof(storage), "Setup::dev_workspace" ); + dev_lists = smalloc ( sizeof(reax_list *) * LIST_N, "Setup::dev_lists" ); + for ( i = 0; i < LIST_N; ++i ) + { + dev_lists[i] = smalloc( sizeof(reax_list), "Setup::dev_lists[i]" ); + dev_lists[i]->allocated = FALSE; + } +#endif + + pmd_handle->output_enabled = TRUE; + pmd_handle->callback = NULL; + + /* setup MPI environment */ + MPI_Comm_size( MPI_COMM_WORLD, &pmd_handle->control->nprocs ); + MPI_Comm_rank( MPI_COMM_WORLD, &pmd_handle->system->my_rank ); + + /* read system config files */ + Read_Config_Files( geo_file, ffield_file, control_file, + pmd_handle->system, pmd_handle->control, pmd_handle->data, + pmd_handle->workspace, pmd_handle->out_control, pmd_handle->mpi_data ); + +#ifdef HAVE_CUDA + /* setup the CUDA Device for this process */ + Setup_Cuda_Environment( system->my_rank, control->nprocs, control->gpus_per_node ); + +#if defined(DEBUG) + print_device_mem_usage( ); +#endif + + /* init blocks sizes */ + init_blocks( system ); +#endif + + return (void*) pmd_handle; +} + + +int setup_callback( const void * const handle, const callback_function callback ) +{ + int ret; + puremd_handle *pmd_handle; + + + ret = PUREMD_FAILURE; + + if ( handle != NULL && callback != NULL ) + { + pmd_handle = (puremd_handle*) handle; + pmd_handle->callback = callback; + ret = PUREMD_SUCCESS; + } + + return ret; +} + + +int simulate( const void * const handle ) +{ + int ret, retries; + reax_system *system; + control_params *control; + simulation_data *data; + storage *workspace; + reax_list **lists; + output_controls *out_control; + mpi_datatypes *mpi_data; + puremd_handle *pmd_handle; + real t_start = 0, t_elapsed; +#if defined(DEBUG) + real t_begin, t_end; +#endif + + ret = PUREMD_FAILURE; + + if ( handle != NULL ) + { + pmd_handle = (puremd_handle*) handle; + + system = pmd_handle->system; + control = pmd_handle->control; + data = pmd_handle->data; + workspace = pmd_handle->workspace; + lists = pmd_handle->lists; + out_control = pmd_handle->out_control; + mpi_data = pmd_handle->mpi_data; + +#ifdef HAVE_CUDA + if ( system->my_rank == MASTER_NODE ) + { + t_start = Get_Time( ); + } + + Cuda_Initialize( system, control, data, workspace, lists, out_control, mpi_data ); + +#if defined(__CUDA_DEBUG__) + Pure_Initialize( system, control, data, workspace, lists, out_control, mpi_data ); +#endif + +#if defined(DEBUG) + print_device_mem_usage( ); +#endif + + /* init the blocks sizes for cuda kernels */ + init_blocks( system ); + + /* compute f_0 */ + Comm_Atoms( system, control, data, workspace, mpi_data, TRUE ); + Sync_Atoms( system ); + Sync_Grid( &system->my_grid, &system->d_my_grid ); + init_blocks( system ); + + Cuda_Reset( system, control, data, workspace, lists ); + +#if defined(__CUDA_DEBUG__) + Reset( system, control, data, workspace, lists ); +#endif + + Cuda_Generate_Neighbor_Lists( system, data, workspace, lists ); + +#if defined(__CUDA_DEBUG__) + Generate_Neighbor_Lists( system, data, workspace, lists ); +#endif + +#if defined(__CUDA_DEBUG__) + Compute_Forces( system, control, data, workspace, + lists, out_control, mpi_data ); +#endif + + Cuda_Compute_Forces( system, control, data, workspace, lists, + out_control, mpi_data ); + +#if defined (__CUDA_DEBUG__) + Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); +#endif + + Cuda_Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); + +#if defined(__CUDA_DEBUG__) + validate_device( system, data, workspace, lists ); +#endif + +#if !defined(__CUDA_DEBUG__) + Output_Results( system, control, data, lists, out_control, mpi_data ); +#endif + +#if defined(DEBUG) + fprintf( stderr, "p%d: step%d completed\n", system->my_rank, data->step ); + MPI_Barrier( MPI_COMM_WORLD ); +#endif + + ++data->step; + retries = 0; + while ( data->step <= control->nsteps && retries < MAX_RETRIES ) + { + ret = SUCCESS; + + if ( control->T_mode && retries == 0 ) + { + Temperature_Control( control, data ); + } + +#if defined(DEBUG) + t_begin = Get_Time(); +#endif + +#if defined(__CUDA_DEBUG__) + ret = control->Evolve( system, control, data, workspace, + lists, out_control, mpi_data ); +#endif + + ret = control->Cuda_Evolve( system, control, data, workspace, + lists, out_control, mpi_data ); + +#if defined(DEBUG) + t_end = Get_Timing_Info( t_begin ); + fprintf( stderr, " Evolve time: %f \n", t_end ); +#endif + +#if defined(DEBUG) + t_begin = Get_Time( ); +#endif + + if ( ret == SUCCESS ) + { + Cuda_Post_Evolve( system, control, data, workspace, lists, + out_control, mpi_data ); + +#if defined(__CUDA_DEBUG__) + Post_Evolve( system, control, data, workspace, lists, out_control, mpi_data ); +#endif + } + +#if defined(DEBUG) + t_end = Get_Timing_Info( t_begin ); + fprintf( stderr, " Post Evolve time: %f \n", t_end ); +#endif + + if ( ret == SUCCESS ) + { + data->timing.num_retries = retries; + +#if !defined(__CUDA_DEBUG__) + Output_Results( system, control, data, lists, out_control, mpi_data ); +#endif + +// Analysis( system, control, data, workspace, lists, out_control, mpi_data ); + + /* dump restart info */ +// if ( out_control->restart_freq && +// (data->step-data->prev_steps) % out_control->restart_freq == 0 ) +// { +// if( out_control->restart_format == WRITE_ASCII ) +// { +// Write_Restart_File( system, control, data, out_control, mpi_data ); +// } +// else if( out_control->restart_format == WRITE_BINARY ) +// { +// Write_Binary_Restart_File( system, control, data, out_control, mpi_data ); +// } +// } + +#if defined(DEBUG) + fprintf( stderr, "p%d: step%d completed\n", system->my_rank, data->step ); + MPI_Barrier( MPI_COMM_WORLD ); +#endif + + ++data->step; + retries = 0; + } + else + { + ++retries; + +#if defined(DEBUG) + fprintf( stderr, "[INFO] p%d: retrying step %d...\n", system->my_rank, data->step ); +#endif + } + } + + if ( retries >= MAX_RETRIES ) + { + fprintf( stderr, "[ERROR] Maximum retries reached for this step (%d). Terminating...\n", + retries ); + MPI_Abort( MPI_COMM_WORLD, MAX_RETRIES_REACHED ); + } + +#if defined(__CUDA_DEBUG__) + /* vaildate the results in debug mode */ + validate_device( system, data, workspace, lists ); +#endif + +#else + if ( system->my_rank == MASTER_NODE ) + { + t_start = Get_Time( ); + } + + Initialize( system, control, data, workspace, lists, out_control, mpi_data ); + + /* compute f_0 */ + Comm_Atoms( system, control, data, workspace, mpi_data, TRUE ); + + Reset( system, control, data, workspace, lists ); + + if ( ret == FAILURE ) + { + ReAllocate( system, control, data, workspace, lists, mpi_data ); + } + + ret = Generate_Neighbor_Lists( system, data, workspace, lists ); + + if ( ret != SUCCESS ) + { + fprintf( stderr, "[ERROR] cannot generate initial neighbor lists. Terminating...\n" ); + MPI_Abort( MPI_COMM_WORLD, CANNOT_INITIALIZE ); + } + + ret = Compute_Forces( system, control, data, workspace, lists, out_control, mpi_data ); + + if ( ret != SUCCESS ) + { + fprintf( stderr, "[ERROR] cannot compute initial forces. Terminating...\n" ); + MPI_Abort( MPI_COMM_WORLD, CANNOT_INITIALIZE ); + } + + Compute_Kinetic_Energy( system, data, mpi_data->comm_mesh3D ); + + Compute_Total_Energy( system, data, MPI_COMM_WORLD ); + + Output_Results( system, control, data, lists, out_control, mpi_data ); + + Check_Energy( data ); + + retries = 0; + ++data->step; + while ( data->step <= control->nsteps && retries < MAX_RETRIES ) + { + ret = SUCCESS; + + if ( control->T_mode && retries == 0 ) + { + Temperature_Control( control, data ); + } + + ret = control->Evolve( system, control, data, workspace, + lists, out_control, mpi_data ); + + if ( ret == SUCCESS ) + { + Post_Evolve(system, control, data, workspace, lists, out_control, mpi_data); + } + + if ( ret == SUCCESS ) + { + data->timing.num_retries = retries; + + Output_Results( system, control, data, lists, out_control, mpi_data ); + +// Analysis( system, control, data, workspace, lists, out_control, mpi_data ); + + /* dump restart info */ + if ( out_control->restart_freq && + (data->step - data->prev_steps) % out_control->restart_freq == 0 ) + { + if ( out_control->restart_format == WRITE_ASCII ) + { + Write_Restart_File( system, control, data, out_control, mpi_data ); + } + else if ( out_control->restart_format == WRITE_BINARY ) + { + Write_Binary_Restart_File( system, control, data, out_control, mpi_data ); + } + } + + Check_Energy( data ); + + ++data->step; + retries = 0; + } + else + { + ++retries; + +#if defined(DEBUG) + fprintf( stderr, "[INFO] p%d: retrying step %d...\n", system->my_rank, data->step ); +#endif + } + } + + if ( retries >= MAX_RETRIES ) + { + fprintf( stderr, "[ERROR] Maximum retries reached for this step (%d). Terminating...\n", + retries ); + MPI_Abort( MPI_COMM_WORLD, MAX_RETRIES_REACHED ); + } + +#endif + + /* end of the simulation, write total simulation time */ + if ( system->my_rank == MASTER_NODE ) + { + t_elapsed = Get_Timing_Info( t_start ); + fprintf( out_control->out, "Total Simulation Time: %.2f secs\n", t_elapsed ); + } + +// Write_PDB_File( &system, &lists[BONDS], &out_control ); + + Close_Output_Files( system, control, out_control, mpi_data ); + +#if defined(TEST_ENERGY) || defined(TEST_FORCES) +// Integrate_Results(control); +#endif + +#if defined(DEBUG) + fprintf( stderr, "p%d has reached the END\n", system->my_rank ); +#endif + + ret = PUREMD_SUCCESS; + } + + return ret; +} + + +int cleanup( const void * const handle ) +{ + int i, ret; + puremd_handle *pmd_handle; + + ret = PUREMD_FAILURE; + + if ( handle != NULL ) + { + pmd_handle = (puremd_handle*) handle; + + //TODO +// Finalize( pmd_handle->system, pmd_handle->control, pmd_handle->data, +// pmd_handle->workspace, &pmd_handle->lists, pmd_handle->out_control, +// pmd_handle->output_enabled ); + + sfree( pmd_handle->mpi_data, "cleanup::pmd_handle->mpi_data" ); + sfree( pmd_handle->out_control, "cleanup::pmd_handle->out_control" ); + for ( i = 0; i < LIST_N; ++i ) + { + sfree( pmd_handle->lists[i], "cleanup::pmd_handle->lists[i]" ); + } + sfree( pmd_handle->lists, "cleanup::pmd_handle->lists" ); + sfree( pmd_handle->workspace, "cleanup::pmd_handle->workspace" ); + sfree( pmd_handle->data, "cleanup::pmd_handle->data" ); + sfree( pmd_handle->control, "cleanup::pmd_handle->control" ); + sfree( pmd_handle->system, "cleanup::pmd_handle->system" ); + + sfree( pmd_handle, "cleanup::pmd_handle" ); + + ret = PUREMD_SUCCESS; + } + + return ret; +} + + +reax_atom* get_atoms( const void * const handle ) +{ + puremd_handle *pmd_handle; + reax_atom *atoms; + + atoms = NULL; + + if ( handle != NULL ) + { + pmd_handle = (puremd_handle*) handle; + atoms = pmd_handle->system->my_atoms; + } + + return atoms; +} + + +int set_output_enabled( const void * const handle, const int enabled ) +{ + int ret; + puremd_handle *pmd_handle; + + ret = PUREMD_FAILURE; + + if ( handle != NULL ) + { + pmd_handle = (puremd_handle*) handle; + pmd_handle->output_enabled = enabled; + ret = PUREMD_SUCCESS; + } + + return ret; +} diff --git a/PG-PuReMD/src/puremd.h b/PG-PuReMD/src/puremd.h new file mode 100644 index 0000000000000000000000000000000000000000..b51f854c860cf02d427a80ff1287721f1d01758e --- /dev/null +++ b/PG-PuReMD/src/puremd.h @@ -0,0 +1,54 @@ +/*---------------------------------------------------------------------- + SerialReax - Reax Force Field Simulator + + Copyright (2010) Purdue University + Hasan Metin Aktulga, haktulga@cs.purdue.edu + Joseph Fogarty, jcfogart@mail.usf.edu + Sagar Pandit, pandit@usf.edu + Ananth Y Grama, ayg@cs.purdue.edu + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 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 General Public License for more details: + <http://www.gnu.org/licenses/>. + ----------------------------------------------------------------------*/ + +#ifndef __PUREMD_H_ +#define __PUREMD_H_ + +#include "reax_types.h" + + +#define PUREMD_SUCCESS (0) +#define PUREMD_FAILURE (-1) + + +#ifdef __cplusplus +extern "C" { +#endif + +void* setup( const char * const, const char * const, + const char * const ); + +int setup_callback( const void * const, const callback_function ); + +int simulate( const void * const ); + +int cleanup( const void * const ); + +reax_atom* get_atoms( const void * const ); + +int set_output_enabled( const void * const, const int ); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/PG-PuReMD/src/reax_types.h b/PG-PuReMD/src/reax_types.h index e08d2b9b0ac8cbc67d78701d93bec03a219cbc48..57d7e414017c4882c80c594566965132289eeefa 100644 --- a/PG-PuReMD/src/reax_types.h +++ b/PG-PuReMD/src/reax_types.h @@ -548,6 +548,7 @@ typedef struct molecule molecule; typedef struct LR_data LR_data; typedef struct cubic_spline_coef cubic_spline_coef; typedef struct LR_lookup_table LR_lookup_table; +typedef struct puremd_handle puremd_handle; /* function pointer definitions */ @@ -563,6 +564,8 @@ typedef real (*lookup_function)( real ); typedef void (*message_sorter)( reax_system*, int, int, int, mpi_out_data* ); /**/ typedef void (*unpacker)( reax_system*, int, void*, int, neighbor_proc*, int ); +/**/ +typedef void (*callback_function)(reax_atom*, simulation_data*, reax_list*); /* struct definitions */ @@ -2458,6 +2461,30 @@ struct LR_lookup_table }; +/* Handle for working with an instance of the PuReMD library */ +struct puremd_handle +{ + /* System info. struct pointer */ + reax_system *system; + /* System struct pointer */ + control_params *control; + /* Control parameters struct pointer */ + simulation_data *data; + /* Internal workspace struct pointer */ + storage *workspace; + /* Reax interaction list struct pointer */ + reax_list **lists; + /* Output controls struct pointer */ + output_controls *out_control; + /* MPI datatypes struct pointer */ + mpi_datatypes *mpi_data; + /* TRUE if file I/O for simulation output enabled, FALSE otherwise */ + int output_enabled; + /* Callback for getting simulation state at the end of each time step */ + callback_function callback; +}; + + /* CUDA-specific globals */ extern reax_list **dev_lists; extern storage *dev_workspace; diff --git a/PG-PuReMD/src/restart.c b/PG-PuReMD/src/restart.c index 19e0e0a37caea16e728b97c202cd3641a074ca2e..73908ea80b122a1580ee7a0cbb8a41c7437b0cce 100644 --- a/PG-PuReMD/src/restart.c +++ b/PG-PuReMD/src/restart.c @@ -29,7 +29,7 @@ #include "vector.h" -void Write_Binary_Restart( reax_system *system, control_params *control, +void Write_Binary_Restart_File( reax_system *system, control_params *control, simulation_data *data, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -49,7 +49,7 @@ void Write_Binary_Restart( reax_system *system, control_params *control, { /* master handles the restart file */ sprintf( fname, "%s.res%d", control->sim_name, data->step ); - fres = sfopen( fname, "wb", "Write_Binary_Restart::fres" ); + fres = sfopen( fname, "wb", "Write_Binary_Restart_File::fres" ); /* master can write the header by itself */ res_header.step = data->step; @@ -64,12 +64,12 @@ void Write_Binary_Restart( reax_system *system, control_params *control, /* master needs to allocate space for all atoms */ buffer = scalloc( system->bigN, sizeof(restart_atom), - "Write_Binary_Restart::buffer" ); + "Write_Binary_Restart_File::buffer" ); } else { buffer = scalloc( system->n, sizeof(restart_atom), - "Write_Binary_Restart::buffer" ); + "Write_Binary_Restart_File::buffer" ); } /* fill in the buffers */ @@ -108,14 +108,14 @@ void Write_Binary_Restart( reax_system *system, control_params *control, if ( me == MASTER_NODE ) { fwrite( buffer, system->bigN, sizeof(restart_atom), fres ); - sfclose( fres, "Write_Binary_Restart::fres" ); + sfclose( fres, "Write_Binary_Restart_File::fres" ); } - sfree( buffer, "Write_Binary_Restart::buffer" ); + sfree( buffer, "Write_Binary_Restart_File::buffer" ); } -void Write_Restart( reax_system *system, control_params *control, +void Write_Restart_File( reax_system *system, control_params *control, simulation_data *data, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -135,7 +135,7 @@ void Write_Restart( reax_system *system, control_params *control, if ( me == MASTER_NODE ) { sprintf( fname, "%s.res%d", control->sim_name, data->step ); - fres = sfopen( fname, "w", "Write_Restart::fres" ); + fres = sfopen( fname, "w", "Write_Restart_File::fres" ); /* write the header - only master writes it */ fprintf( fres, RESTART_HEADER, @@ -156,7 +156,7 @@ void Write_Restart( reax_system *system, control_params *control, buffer_req = system->n * RESTART_LINE_LEN + 1; } - buffer = smalloc( sizeof(char) * buffer_req, "Write_Restart::buffer" ); + buffer = smalloc( sizeof(char) * buffer_req, "Write_Restart_File::buffer" ); line[0] = 0; buffer[0] = 0; @@ -200,10 +200,10 @@ void Write_Restart( reax_system *system, control_params *control, if ( me == MASTER_NODE ) { fprintf( fres, "%s", buffer ); - sfclose( fres, "Write_Restart::fres" ); + sfclose( fres, "Write_Restart_File::fres" ); } - sfree( buffer, "Write_Restart::buffer" ); - sfree( line, "Write_Restart::line" ); + sfree( buffer, "Write_Restart_File::buffer" ); + sfree( line, "Write_Restart_File::line" ); } @@ -235,7 +235,7 @@ void Count_Binary_Restart_Atoms( FILE *fres, reax_system *system ) } -void Read_Binary_Restart( char *res_file, reax_system *system, +void Read_Binary_Restart_File( char *res_file, reax_system *system, control_params *control, simulation_data *data, storage *workspace, mpi_datatypes *mpi_data ) { @@ -245,7 +245,7 @@ void Read_Binary_Restart( char *res_file, reax_system *system, restart_atom res_atom; reax_atom *p_atom; - fres = sfopen( res_file, "rb", "Read_Binary_Restart::fres" ); + fres = sfopen( res_file, "rb", "Read_Binary_Restart_File::fres" ); /* first read the header lines */ fread( &res_header, sizeof(restart_header), 1, fres ); @@ -305,7 +305,7 @@ void Read_Binary_Restart( char *res_file, reax_system *system, } } - sfclose( fres, "Read_Binary_Restart::fres" ); + sfclose( fres, "Read_Binary_Restart_File::fres" ); data->step = data->prev_steps; // nsteps is updated based on the number of steps in the previous run @@ -350,7 +350,7 @@ void Count_Restart_Atoms( FILE *fres, reax_system *system ) } -void Read_Restart( char *res_file, reax_system *system, +void Read_Restart_File( char *res_file, reax_system *system, control_params *control, simulation_data *data, storage *workspace, mpi_datatypes *mpi_data ) { @@ -362,13 +362,13 @@ void Read_Restart( char *res_file, reax_system *system, rvec x_temp, v_temp; rtensor box; - fres = sfopen( res_file, "r", "Read_Restart::fres" ); + fres = sfopen( res_file, "r", "Read_Restart_File::fres" ); - s = smalloc( sizeof(char) * MAX_LINE, "Read_Restart::s" ); - tmp = smalloc( sizeof(char*) * MAX_TOKENS, "Read_Restart::tmp" ); + s = smalloc( sizeof(char) * MAX_LINE, "Read_Restart_File::s" ); + tmp = smalloc( sizeof(char*) * MAX_TOKENS, "Read_Restart_File::tmp" ); for (i = 0; i < MAX_TOKENS; i++) { - tmp[i] = smalloc( sizeof(char) * MAX_LINE, "Read_Restart::tmp[i]" ); + tmp[i] = smalloc( sizeof(char) * MAX_LINE, "Read_Restart_File::tmp[i]" ); } //read first header lines @@ -486,15 +486,15 @@ void Read_Restart( char *res_file, reax_system *system, top++; } } - sfclose( fres, "Read_Restart::fres" ); + sfclose( fres, "Read_Restart_File::fres" ); /* free memory allocations at the top */ for ( i = 0; i < MAX_TOKENS; i++ ) { - sfree( tmp[i], "Read_Restart::tmp[i]" ); + sfree( tmp[i], "Read_Restart_File::tmp[i]" ); } - sfree( tmp, "Read_Restart::tmp" ); - sfree( s, "Read_Restart::s" ); + sfree( tmp, "Read_Restart_File::tmp" ); + sfree( s, "Read_Restart_File::s" ); data->step = data->prev_steps; // nsteps is updated based on the number of steps in the previous run diff --git a/PG-PuReMD/src/restart.h b/PG-PuReMD/src/restart.h index 3d13a5a17256457829224a20f32c4d9f7305a06b..9f37e641c0c982dacaeb09e78f11afa2ec94c653 100644 --- a/PG-PuReMD/src/restart.h +++ b/PG-PuReMD/src/restart.h @@ -45,16 +45,16 @@ extern "C" { #endif -void Write_Binary_Restart( reax_system*, control_params*, +void Write_Binary_Restart_File( reax_system*, control_params*, simulation_data*, output_controls*, mpi_datatypes* ); -void Write_Restart( reax_system*, control_params*, +void Write_Restart_File( reax_system*, control_params*, simulation_data*, output_controls*, mpi_datatypes* ); -void Read_Binary_Restart( char*, reax_system*, control_params*, +void Read_Binary_Restart_File( char*, reax_system*, control_params*, simulation_data*, storage*, mpi_datatypes* ); -void Read_Restart( char*, reax_system*, control_params*, +void Read_Restart_File( char*, reax_system*, control_params*, simulation_data*, storage*, mpi_datatypes* ); #ifdef __cplusplus