From 966a71d751af69ad1cd9abf5f12c57c6ed37a19f Mon Sep 17 00:00:00 2001 From: Peter Kasson Date: Tue, 17 Dec 2013 13:49:38 -0800 Subject: [PATCH] Patch for Native Client builds. This patch contains the source changes necessary to compile Gromacs for Native Client. Patch is based on original work by Ivan Krasin, additional changes from Joseph Coffland. Also included are a few compiler warning fixes and a minor FAHCORE tweak. Change-Id: I085c52ff1d8e45ec8ffb8c56f5877313d6225bb2 --- CMakeLists.txt | 8 ++++++++ include/main.h | 4 ++-- src/contrib/fftw/CMakeLists.txt | 8 +++++++- src/gmxlib/checkpoint.c | 25 +++++++++++-------------- src/gmxlib/copyrite.c | 2 +- src/gmxlib/futil.c | 9 +++------ src/gmxlib/gmx_detect_hardware.c | 2 +- src/gmxlib/main.c | 9 +++++---- src/gmxlib/string2.c | 3 ++- src/gmxlib/thread_mpi/impl.h | 3 +++ src/gmxlib/thread_mpi/p2p_buffer.c | 2 ++ src/gmxlib/thread_mpi/pthreads.c | 5 ++++- src/kernel/genalg.c | 2 ++ src/kernel/md.c | 4 ++++ src/kernel/runner.c | 5 ++++- 15 files changed, 59 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d184aec89f..40881ef155 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1055,6 +1055,14 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "BlueGene") endif() endif() +option(GMX_NACL "Configure for Native Client builds" OFF) +if (GMX_NACL) + list(APPEND GMX_EXTRA_LIBRARIES nosys) + set(GMX_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lnosys") + set(GMX_NO_NICE 1) +endif() +mark_as_advanced(GMX_NACL) + if(GMX_FAHCORE) set(COREWRAP_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/../corewrap" CACHE STRING "Path to swindirect.h") diff --git a/include/main.h b/include/main.h index 3e9c7f60f1..ed107f625a 100644 --- a/include/main.h +++ b/include/main.h @@ -48,10 +48,10 @@ extern "C" { #endif -char *gmx_gethostname(char *name, size_t len); +int gmx_gethostname(char *name, size_t len); /* Sets the hostname to the value given by gethostname, if available, * and to "unknown" otherwise. name should have at least size len. - * Returns name. + * Returns 0 on success, -1 on error. */ GMX_LIBGMX_EXPORT diff --git a/src/contrib/fftw/CMakeLists.txt b/src/contrib/fftw/CMakeLists.txt index d91bb8ba1a..1ed712f548 100644 --- a/src/contrib/fftw/CMakeLists.txt +++ b/src/contrib/fftw/CMakeLists.txt @@ -26,6 +26,11 @@ if(${GMX_CPU_ACCELERATION} MATCHES "^(SSE|AVX)") set(GMX_BUILD_OWN_FFTW_OPTIMIZATION_CONFIGURATION --enable-sse2 CACHE INTERNAL "Optimization flags for FFTW compilation") endif() +# Allow cross-compiles +if (TARGET_HOST) + set(GMX_BUILD_OWN_FFTW_TARGET --host=${TARGET_HOST}) +endif() + # Machinery for running the external project set(EXTERNAL_FFTW_VERSION 3.3.2) include(ExternalProject) @@ -40,7 +45,8 @@ message(WARNING "The GROMACS build will download FFTW ${EXTERNAL_FFTW_VERSION} a URL "http://www.fftw.org/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz" CONFIGURE_COMMAND /configure --prefix= --libdir=/lib --disable-fortran ${GMX_BUILD_OWN_FFTW_SHARED_FLAG} ${GMX_BUILD_OWN_FFTW_OPTIMIZATION_CONFIGURATION} - ${GMX_BUILD_OWN_FFTW_PREC}) + ${GMX_BUILD_OWN_FFTW_PREC} + ${GMX_BUILD_OWN_FFTW_TARGET}) externalproject_get_property(fftwBuild INSTALL_DIR) string(TOUPPER "${FFTW}" UPPERFFTW) diff --git a/src/gmxlib/checkpoint.c b/src/gmxlib/checkpoint.c index ae1e316f45..5976e97955 100644 --- a/src/gmxlib/checkpoint.c +++ b/src/gmxlib/checkpoint.c @@ -70,6 +70,7 @@ #include "network.h" #include "gmx_random.h" #include "checkpoint.h" +#include "main.h" #include "futil.h" #include "string2.h" #include @@ -844,14 +845,7 @@ static void do_cpt_header(XDR *xd, gmx_bool bRead, int *file_version, if (!bRead) { snew(fhost, 255); -#ifdef HAVE_UNISTD_H - if (gethostname(fhost, 255) != 0) - { - sprintf(fhost, "unknown"); - } -#else - sprintf(fhost, "unknown"); -#endif + gmx_gethostname(fhost, 255); } do_cpt_string_err(xd, bRead, "GROMACS version", version, list); do_cpt_string_err(xd, bRead, "GROMACS build time", btime, list); @@ -1770,7 +1764,7 @@ static void read_checkpoint(const char *fn, FILE **pfplog, t_fileio *chksum_file; FILE * fplog = *pfplog; unsigned char digest[16]; -#ifndef GMX_NATIVE_WINDOWS +#if !defined __native_client__ && !defined GMX_NATIVE_WINDOWS struct flock fl; /* don't initialize here: the struct order is OS dependent! */ #endif @@ -1783,7 +1777,7 @@ static void read_checkpoint(const char *fn, FILE **pfplog, " while the simulation uses %d SD or BD nodes,\n" " continuation will be exact, except for the random state\n\n"; -#ifndef GMX_NATIVE_WINDOWS +#if !defined __native_client__ && !defined GMX_NATIVE_WINDOWS fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; @@ -2080,11 +2074,14 @@ static void read_checkpoint(const char *fn, FILE **pfplog, * will succeed, but a second process can also lock the file. * We should probably try to detect this. */ -#ifndef GMX_NATIVE_WINDOWS - if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl) - == -1) -#else +#if defined __native_client__ + errno = ENOSYS; + if (1) + +#elif defined GMX_NATIVE_WINDOWS if (_locking(fileno(gmx_fio_getfp(chksum_file)), _LK_NBLCK, LONG_MAX) == -1) +#else + if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl) == -1) #endif { if (errno == ENOSYS) diff --git a/src/gmxlib/copyrite.c b/src/gmxlib/copyrite.c index ebba038223..f7ede977cb 100644 --- a/src/gmxlib/copyrite.c +++ b/src/gmxlib/copyrite.c @@ -693,7 +693,7 @@ void gmx_print_version_info(FILE *fp) #else fprintf(fp, "Precision: single\n"); #endif - fprintf(fp, "Memory model: %lu bit\n", 8*sizeof(void *)); + fprintf(fp, "Memory model: %u bit\n", (unsigned)(8*sizeof(void *))); #ifdef GMX_THREAD_MPI fprintf(fp, "MPI library: thread_mpi\n"); diff --git a/src/gmxlib/futil.c b/src/gmxlib/futil.c index a9e957c3c3..07a9cb4285 100644 --- a/src/gmxlib/futil.c +++ b/src/gmxlib/futil.c @@ -124,10 +124,7 @@ void push_ps(FILE *fp) #ifdef ffclose #undef ffclose #endif -#endif - -#ifndef GMX_FAHCORE -#ifndef HAVE_PIPES +#if (!defined(HAVE_PIPES) && !defined(__native_client__)) static FILE *popen(const char *nm, const char *mode) { gmx_impl("Sorry no pipes..."); @@ -141,8 +138,8 @@ static int pclose(FILE *fp) return 0; } -#endif -#endif +#endif /* !defined(HAVE_PIPES) && !defined(__native_client__) */ +#endif /* GMX_FAHCORE */ int ffclose(FILE *fp) { diff --git a/src/gmxlib/gmx_detect_hardware.c b/src/gmxlib/gmx_detect_hardware.c index 600b6f3766..a1c38df268 100644 --- a/src/gmxlib/gmx_detect_hardware.c +++ b/src/gmxlib/gmx_detect_hardware.c @@ -558,7 +558,7 @@ static void gmx_detect_gpus(FILE *fplog, const t_commrec *cr, if (rank_local == 0) { - char detection_error[STRLEN], sbuf[STRLEN]; + char detection_error[STRLEN] = "", sbuf[STRLEN]; if (detect_cuda_gpus(&hwinfo_g->gpu_info, detection_error) != 0) { diff --git a/src/gmxlib/main.c b/src/gmxlib/main.c index 60ab55b4ee..37c84f73eb 100644 --- a/src/gmxlib/main.c +++ b/src/gmxlib/main.c @@ -237,22 +237,23 @@ void check_multi_large_int(FILE *log, const gmx_multisim_t *ms, } -char *gmx_gethostname(char *name, size_t len) +int gmx_gethostname(char *name, size_t len) { if (len < 8) { gmx_incons("gmx_gethostname called with len<8"); } -#ifdef HAVE_UNISTD_H +#if defined(HAVE_UNISTD_H) && !defined(__native_client__) if (gethostname(name, len-1) != 0) { strncpy(name, "unknown", 8); + return -1; } + return 0; #else strncpy(name, "unknown", 8); + return -1; #endif - - return name; } diff --git a/src/gmxlib/string2.c b/src/gmxlib/string2.c index 71a2618cc5..d9b31c6314 100644 --- a/src/gmxlib/string2.c +++ b/src/gmxlib/string2.c @@ -67,6 +67,7 @@ #include "smalloc.h" #include "gmx_fatal.h" #include "macros.h" +#include "main.h" #include "string2.h" #include "futil.h" @@ -243,7 +244,7 @@ void nice_header (FILE *out, const char *fn) #ifdef HAVE_PWD_H uid = getuid(); pw = getpwuid(uid); - gh = gethostname(buf, 255); + gh = gmx_gethostname(buf, 255); /* pw returns null on error (e.g. compute nodes lack /etc/passwd) */ user = pw ? pw->pw_name : unk; #else diff --git a/src/gmxlib/thread_mpi/impl.h b/src/gmxlib/thread_mpi/impl.h index 94d0646302..962e80c923 100644 --- a/src/gmxlib/thread_mpi/impl.h +++ b/src/gmxlib/thread_mpi/impl.h @@ -40,6 +40,9 @@ library. It contains the definitions for all the internal data structures and the prototypes for all the internal functions that aren't static. */ +#ifdef HAVE_CONFIG_H +#include +#endif #ifdef HAVE_UNISTD_H #include diff --git a/src/gmxlib/thread_mpi/p2p_buffer.c b/src/gmxlib/thread_mpi/p2p_buffer.c index dfcd86b86c..c2d4c407c1 100644 --- a/src/gmxlib/thread_mpi/p2p_buffer.c +++ b/src/gmxlib/thread_mpi/p2p_buffer.c @@ -62,9 +62,11 @@ int MPI_Buffer_attach(void* buffer, int size) { + return 0; } int MPI_Buffer_detach(void* buffer_addr, int* size) { + return 0; } diff --git a/src/gmxlib/thread_mpi/pthreads.c b/src/gmxlib/thread_mpi/pthreads.c index f3bd0fb0dd..0db93eac8d 100644 --- a/src/gmxlib/thread_mpi/pthreads.c +++ b/src/gmxlib/thread_mpi/pthreads.c @@ -436,8 +436,8 @@ static inline int tMPI_Thread_mutex_init_once(tMPI_Thread_mutex_t *mtx) goto err; } } + ret = pthread_mutex_unlock( &(mutex_init) ); } - ret = pthread_mutex_unlock( &(mutex_init) ); return ret; err: pthread_mutex_unlock( &(mutex_init) ); @@ -766,6 +766,9 @@ void tMPI_Thread_exit(void *value_ptr) int tMPI_Thread_cancel(tMPI_Thread_t thread) { + #ifdef __native_client__ + return ENOSYS; + #endif return pthread_cancel(thread->th); } diff --git a/src/kernel/genalg.c b/src/kernel/genalg.c index 27f9b5ac84..1e9abdc6d9 100644 --- a/src/kernel/genalg.c +++ b/src/kernel/genalg.c @@ -66,7 +66,9 @@ #include #include #include +#ifdef HAVE_MEMORY_H #include +#endif #include "typedefs.h" #include "smalloc.h" #include "futil.h" diff --git a/src/kernel/md.c b/src/kernel/md.c index 81fca912a8..61f620a67b 100644 --- a/src/kernel/md.c +++ b/src/kernel/md.c @@ -1461,6 +1461,10 @@ double do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[], fcReportProgress( ir->nsteps, step ); } +#if defined(__native_client__) + fcCheckin(MASTER(cr)); +#endif + /* sync bCPT and fc record-keeping */ if (bCPT && MASTER(cr)) { diff --git a/src/kernel/runner.c b/src/kernel/runner.c index 68ea884a0b..392429f33e 100644 --- a/src/kernel/runner.c +++ b/src/kernel/runner.c @@ -1278,7 +1278,10 @@ int mdrunner(gmx_hw_opt_t *hw_opt, } #ifdef GMX_FAHCORE - fcRegisterSteps(inputrec->nsteps, inputrec->init_step); + if (MASTER(cr)) + { + fcRegisterSteps(inputrec->nsteps, inputrec->init_step); + } #endif /* NMR restraints must be initialized before load_checkpoint, -- 2.11.4.GIT