diff --git a/.travis.yml b/.travis.yml index ef3fc4b94..663cec101 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ before_install: - test -n $CC && unset CC - sudo apt-get -qq update - sudo apt-get install --yes -qq build-essential autoconf libtool cmake + - sudo apt-get install --yes -qq gfortran - sudo apt-get install --yes -qq libopenmpi-dev openmpi-bin - sudo apt-get install --yes -qq libhdf5-openmpi-dev - (cd $HOME/spack; git describe) || git clone https://github.com/spack/spack $HOME/spack diff --git a/client/src/Makefile.am b/client/src/Makefile.am index ef720c7cf..85b4f8a33 100644 --- a/client/src/Makefile.am +++ b/client/src/Makefile.am @@ -1,11 +1,11 @@ -lib_LTLIBRARIES = libunifycr.la libunifycr_gotcha.la +lib_LTLIBRARIES = libunifycr.la libunifycr_gotcha.la libunifycrf.la libunifycrdir = $(includedir) libunifycr_gotchadir = $(includedir) AM_CFLAGS = -Wall -Wno-strict-aliasing -include_HEADERS = unifycr.h +include_HEADERS = unifycr.h unifycrf.h CLIENT_COMMON_CPPFLAGS = \ -I$(top_builddir)/client \ @@ -68,3 +68,7 @@ libunifycr_gotcha_la_CFLAGS = $(CLIENT_COMMON_CFLAGS) $(GOTCHA_CFLAGS) libunifycr_gotcha_la_LDFLAGS = $(CLIENT_COMMON_LDFLAGS) $(GOTCHA_LDFLAGS) libunifycr_gotcha_la_LIBADD = $(CLIENT_COMMON_LIBADD) -lgotcha +libunifycrf_la_SOURCES = unifycrf.c +libunifycrf_la_CPPFLAGS = $(CLIENT_COMMON_CPPFLAGS) +libunifycrf_la_CFLAGS = $(AM_CFLAGS) $(CLIENT_COMMON_CFLAGS) +libunifycrf_la_LIBADD = libunifycr_gotcha.la diff --git a/client/src/unifycrf.c b/client/src/unifycrf.c new file mode 100644 index 000000000..a98d2db8a --- /dev/null +++ b/client/src/unifycrf.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2017, Lawrence Livermore National Security, LLC. + * Produced at the Lawrence Livermore National Laboratory. + * + * Copyright 2017-2019, UT-Battelle, LLC. + * + * LLNL-CODE-741539 + * All rights reserved. + * + * This is the license for UnifyCR. + * For details, see https://github.com/LLNL/UnifyCR. + * Please read https://github.com/LLNL/UnifyCR/LICENSE for full license text. + */ + +/* This file compiles a normalized interface for Fortran in which: + * - Fortran link names are in lower case + * - Fortran link names have a single trailing underscore + * - boolean true is expected to be 1 + */ + +#include +#include +#include + +#include "unifycr.h" + +/* TODO: enable UNIFYCR_Fint to be configured to be different type */ +typedef int UNIFYCR_Fint; + +#ifdef USE_FORT_STDCALL +# define FORT_CALL __stdcall +#elif defined (USE_FORT_CDECL) +# define FORT_CALL __cdecl +#else +# define FORT_CALL +#endif + +#ifdef USE_FORT_MIXED_STR_LEN +# define FORT_MIXED_LEN_DECL , UNIFYCR_Fint +# define FORT_END_LEN_DECL +# define FORT_MIXED_LEN(a) , UNIFYCR_Fint a +# define FORT_END_LEN(a) +#else +# define FORT_MIXED_LEN_DECL +# define FORT_END_LEN_DECL , UNIFYCR_Fint +# define FORT_MIXED_LEN(a) +# define FORT_END_LEN(a) , UNIFYCR_Fint a +#endif + +#ifdef HAVE_FORTRAN_API +# ifdef FORTRAN_EXPORTS +# define FORTRAN_API __declspec(dllexport) +# else +# define FORTRAN_API __declspec(dllimport) +# endif +#else +# define FORTRAN_API +#endif + +/* convert a Fortran string to a C string, by removing any trailing + * spaces and terminating with a NULL */ +static int unifycr_fstr2cstr(const char* fstr, int flen, char* cstr, int clen) +{ + int rc = 0; + + /* check that our pointers aren't NULL */ + if ((fstr == NULL) || (cstr == NULL)) { + return 1; + } + + /* determine length of Fortran string after removing trailing spaces */ + while ((flen > 0) && (fstr[flen-1] == ' ')) { + flen--; + } + + /* assume we can copy the whole string */ + int len = flen; + if (flen > (clen - 1)) { + /* Fortran string is longer than C buffer, trucnated copy */ + len = clen - 1; + rc = 1; + } + + /* copy the Fortran string to the C string */ + if (len > 0) { + strncpy(cstr, fstr, len); + } + + /* null-terminate the C string */ + if (len >= 0) { + cstr[len] = '\0'; + } + + return rc; +} + +/* convert a C string to a Fortran string, adding trailing spaces + * as necessary */ +static int unifycr_cstr2fstr(const char* cstr, char* fstr, int flen) +{ + int rc = 0; + + /* check that our pointers aren't NULL */ + if ((cstr == NULL) || (fstr == NULL)) { + return 1; + } + + /* determine length of C string */ + int clen = strlen(cstr); + + /* copy the characters from the Fortran string to the C string */ + if (clen <= flen) { + /* C string will fit within our Fortran buffer, copy it over */ + if (clen > 0) { + strncpy(fstr, cstr, clen); + } + + /* fill in trailing spaces */ + while (clen < flen) { + fstr[clen] = ' '; + clen++; + } + } else { + /* C string is longer than Fortran buffer, truncated copy */ + strncpy(fstr, cstr, flen); + rc = 1; + } + + return rc; +} + +/*================================================ + * Mount, Unmount + *================================================*/ + +FORTRAN_API +void FORT_CALL unifycr_mount_(char* prefix FORT_MIXED_LEN(prefix_len), + int* rank, int* size, int* app_id, + int* ierror FORT_END_LEN(prefix_len)) +{ + /* convert name from a Fortran string to C string */ + char prefix_tmp[1024]; + int rc = unifycr_fstr2cstr(prefix, prefix_len, + prefix_tmp, sizeof(prefix_tmp)); + if (rc != 0) { + *ierror = 1; // !UNIFYCR_SUCCESS + return; + } + + int rank_tmp = *rank; + int size_tmp = *size; + int app_id_tmp = *app_id; + *ierror = unifycr_mount(prefix_tmp, rank_tmp, size_tmp, app_id_tmp); + return; +} + +FORTRAN_API +void FORT_CALL unifycr_unmount_(int* ierror) +{ + *ierror = unifycr_unmount(); + return; +} diff --git a/client/src/unifycrf.h b/client/src/unifycrf.h new file mode 100644 index 000000000..e090e6116 --- /dev/null +++ b/client/src/unifycrf.h @@ -0,0 +1,15 @@ +! Copyright (c) 2017, Lawrence Livermore National Security, LLC. +! Produced at the Lawrence Livermore National Laboratory. +! +! Copyright 2017-2019, UT-Battelle, LLC. +! +! LLNL-CODE-741539 +! All rights reserved. +! +! This is the license for UnifyCR. +! For details, see https://github.com/LLNL/UnifyCR. +! Please read https://github.com/LLNL/UnifyCR/LICENSE for full license text. +! +! return codes + INTEGER UNIFYCR_SUCCESS + PARAMETER (UNIFYCR_SUCCESS=0) diff --git a/common/src/Makefile.am b/common/src/Makefile.am index 5012aa8b4..5cb797370 100644 --- a/common/src/Makefile.am +++ b/common/src/Makefile.am @@ -1,5 +1,7 @@ lib_LTLIBRARIES = libunifycr_common.la +include_HEADERS = unifycr_const.h err_enumerator.h + libunifycr_commondir = $(includedir) BASE_SRCS = \ diff --git a/configure.ac b/configure.ac index babbf48db..6d2426761 100755 --- a/configure.ac +++ b/configure.ac @@ -25,6 +25,11 @@ AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROG_LIBTOOL +# fortran support +AC_PROG_FC +AC_FC_LIBRARY_LDFLAGS +AC_FC_DUMMY_MAIN + # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_MODE_T AC_TYPE_OFF_T @@ -152,6 +157,9 @@ AC_CHECK_HEADERS(mntent.h sys/mount.h) # look for MPI and set flags LX_FIND_MPI +AC_LANG_PUSH([Fortran]) +LX_FIND_MPI +AC_LANG_POP # look for leveldb library, sets LEVELDB_CFLAGS/LDFLAGS/LIBS UNIFYCR_AC_LEVELDB diff --git a/examples/src/Makefile.am b/examples/src/Makefile.am index e1ad69b60..e02ec79da 100644 --- a/examples/src/Makefile.am +++ b/examples/src/Makefile.am @@ -2,7 +2,7 @@ libexec_PROGRAMS = \ cr-posix cr-gotcha cr-static \ read-posix read-gotcha read-static \ write-posix write-gotcha write-static \ - writeread-posix writeread-gotcha writeread-static \ + writeread-posix writeread-gotcha writeread-static writeread-ftn \ sysio-write-gotcha sysio-write-static \ sysio-read-gotcha sysio-read-static \ sysio-writeread-gotcha sysio-writeread-static sysio-writeread-posix \ @@ -32,8 +32,15 @@ noinst_HEADERS = \ test_cppflags = $(AM_CPPFLAGS) $(MPI_CFLAGS) \ -I$(top_srcdir)/client/src -I$(top_srcdir)/common/src +test_ftn_flags = $(AM_FCFLAGS) $(MPI_FFLAGS) \ + -I$(top_srcdir)/client/src -I$(top_srcdir)/common/src +test_ftn_ldadd = $(top_builddir)/client/src/libunifycrf.la -lrt -lm $(FCLIBS) +test_ftn_ldflags = $(AM_LDFLAGS) $(MPI_FLDFLAGS) \ + $(FLATCC_LDFLAGS) $(FLATCC_LIBS) + test_gotcha_ldadd = $(top_builddir)/client/src/libunifycr_gotcha.la -lrt -lm -test_gotcha_ldflags = $(AM_LDFLAGS) $(MPI_CLDFLAGS) $(FLATCC_LDFLAGS) $(FLATCC_LIBS) +test_gotcha_ldflags = $(AM_LDFLAGS) $(MPI_CLDFLAGS) \ + $(FLATCC_LDFLAGS) $(FLATCC_LIBS) test_posix_cppflags = $(AM_CPPFLAGS) $(MPI_CFLAGS) -DDISABLE_UNIFYCR test_posix_ldadd = -lrt -lm @@ -180,6 +187,11 @@ writeread_static_CPPFLAGS = $(test_cppflags) writeread_static_LDADD = $(test_static_ldadd) writeread_static_LDFLAGS = $(test_static_ldflags) +writeread_ftn_SOURCES = writeread.f90 +writeread_ftn_FCFLAGS = $(test_ftn_flags) +writeread_ftn_LDADD = $(test_ftn_ldadd) +writeread_ftn_LDFLAGS = $(test_ftn_ldflags) + app_mpiio_gotcha_SOURCES = app-mpiio.c app_mpiio_gotcha_CPPFLAGS = $(test_cppflags) app_mpiio_gotcha_LDADD = $(test_gotcha_ldadd) diff --git a/examples/src/writeread.f90 b/examples/src/writeread.f90 new file mode 100644 index 000000000..9eea4fb97 --- /dev/null +++ b/examples/src/writeread.f90 @@ -0,0 +1,57 @@ + program write_read_F + + implicit none + + include 'mpif.h' + include 'unifycrf.h' + + character*1024 :: basefname = "file" + character*1024 :: fname, file_suffix + character*1024 :: prefix = "/unifycr" + integer(kind=4) :: flag; + integer(kind=4) :: outflags; + integer(kind=4) :: valid; + + integer, parameter :: ni=20, nj=30, nk=45 + integer :: loop_count=5 + + integer(kind=8), dimension(ni,nj,nk) :: W1, R1 + + integer :: ierr, errors, all_errors, nprocs, mynod, ios + integer :: i,j,k,loop + + integer :: writeunit, readunit + integer(kind=8) :: nodeoff + +! integer (kind = 8) :: total_bytes_transferred + real (kind = 8) :: total_bytes_transferred + real (kind = 4) overall_transfer_rate + real (kind = 8) time0, time1, iter_time0, iter_time1 + + call MPI_INIT(ierr) + call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr) + call MPI_COMM_RANK(MPI_COMM_WORLD, mynod, ierr) + + call UNIFYCR_MOUNT(prefix, mynod, nprocs, 0, ierr) + + nodeoff=2**21 + + fname = trim(prefix) // "/" // trim(basefname) // ".ckpt" + + forall(i=1:ni,j=1:nj,k=1:nk) & + W1(i,j,k) = nodeoff*mynod+i+ni*(j-1+nj*(k-1)) + + open(unit=writeunit,file=fname,form='unformatted',action='write') + + write(writeunit,iostat=ios) W1 + close(writeunit) + +! R1 = 0 +! open(unit=readunit,file=fname,form='unformatted',action='read') +! read(readunit,iostat=ios) R1 +! close(readunit) + + call UNIFYCR_UNMOUNT(ierr) + call MPI_FINALIZE(ierr) + + end program write_read_F