diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d4dfde7fd..623eb0dcbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,9 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/include) +# Set module path +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules) + # Make sure Fortran module directory is included when building include_directories(${CMAKE_BINARY_DIR}/include) @@ -35,14 +38,12 @@ set(maxcoord 10 CACHE STRING "Maximum number of nested coordinate levels") add_definitions(-DMAX_COORD=${maxcoord}) #=============================================================================== -# MPI for distributed-memory parallelism / HDF5 for binary output +# MPI for distributed-memory parallelism #=============================================================================== set(MPI_ENABLED FALSE) -if($ENV{FC} MATCHES "h5fc$") - message("-- Detected HDF5 wrapper: $ENV{FC}") -elseif($ENV{FC} MATCHES "h5pfc$") - message("-- Detected parallel HDF5 wrapper: $ENV{FC}") +if($ENV{FC} MATCHES "mpi[^/]*$") + message("-- Detected MPI wrapper: $ENV{FC}") add_definitions(-DMPI) set(MPI_ENABLED TRUE) endif() @@ -53,6 +54,33 @@ if(MPI_ENABLED AND mpif08) add_definitions(-DMPIF08) endif() +#=============================================================================== +# HDF5 for binary output +#=============================================================================== + +# Unfortunately FindHDF5.cmake will always prefer a serial HDF5 installation +# over a parallel installation if both appear on the user's PATH. To get around +# this, we check for the environment variable HDF5_ROOT and if it exists, use it +# to check whether its a parallel version. + +if(DEFINED ENV{HDF5_ROOT} AND EXISTS $ENV{HDF5_ROOT}/bin/h5pcc) + set(HDF5_PREFER_PARALLEL TRUE) +else() + set(HDF5_PREFER_PARALLEL FALSE) +endif() + +find_package(HDF5 COMPONENTS Fortran_HL) +if(NOT HDF5_FOUND) + message(FATAL_ERROR "Could not find HDF5") +endif() +if(HDF5_IS_PARALLEL) + if(NOT MPI_ENABLED) + message(FATAL_ERROR "Parallel HDF5 must be used with MPI.") + endif() + add_definitions(-DPHDF5) + message("-- Using parallel HDF5") +endif() + #=============================================================================== # Set compile/link flags based on which compiler is being used #=============================================================================== @@ -212,6 +240,14 @@ set(program "openmc") file(GLOB source src/*.F90 src/xml/openmc_fox.F90) add_executable(${program} ${source}) +# target_include_directories was added in CMake 2.8.11 and is the recommended +# way to set include directories. For lesser versions, we revert to set_property +if(CMAKE_VERSION VERSION_LESS 2.8.11) + include_directories(${HDF5_INCLUDE_DIRS}) +else() + target_include_directories(${program} PUBLIC ${HDF5_INCLUDE_DIRS}) +endif() + # target_compile_options was added in CMake 2.8.12 and is the recommended way to # set compile flags. Note that this sets the COMPILE_OPTIONS property (also # available only in 2.8.12+) rather than the COMPILE_FLAGS property, which is @@ -225,7 +261,7 @@ endif() # target_link_libraries treats any arguments starting with - but not -l as # linker flags. Thus, we can pass both linker flags and libraries together. -target_link_libraries(${program} ${ldflags} ${libraries} fox_dom) +target_link_libraries(${program} ${ldflags} ${HDF5_LIBRARIES} fox_dom) #=============================================================================== # Install executable, scripts, manpage, license diff --git a/cmake/Modules/FindHDF5.cmake b/cmake/Modules/FindHDF5.cmake new file mode 100644 index 0000000000..1631f01932 --- /dev/null +++ b/cmake/Modules/FindHDF5.cmake @@ -0,0 +1,407 @@ +#.rst: +# FindHDF5 +# -------- +# +# Find HDF5, a library for reading and writing self describing array data. +# +# +# +# This module invokes the HDF5 wrapper compiler that should be installed +# alongside HDF5. Depending upon the HDF5 Configuration, the wrapper +# compiler is called either h5cc or h5pcc. If this succeeds, the module +# will then call the compiler with the -show argument to see what flags +# are used when compiling an HDF5 client application. +# +# The module will optionally accept the COMPONENTS argument. If no +# COMPONENTS are specified, then the find module will default to finding +# only the HDF5 C library. If one or more COMPONENTS are specified, the +# module will attempt to find the language bindings for the specified +# components. The only valid components are C, CXX, Fortran, HL, and +# Fortran_HL. If the COMPONENTS argument is not given, the module will +# attempt to find only the C bindings. +# +# On UNIX systems, this module will read the variable +# HDF5_USE_STATIC_LIBRARIES to determine whether or not to prefer a +# static link to a dynamic link for HDF5 and all of it's dependencies. +# To use this feature, make sure that the HDF5_USE_STATIC_LIBRARIES +# variable is set before the call to find_package. +# +# To provide the module with a hint about where to find your HDF5 +# installation, you can set the environment variable HDF5_ROOT. The +# Find module will then look in this path when searching for HDF5 +# executables, paths, and libraries. +# +# In addition to finding the includes and libraries required to compile +# an HDF5 client application, this module also makes an effort to find +# tools that come with the HDF5 distribution that may be useful for +# regression testing. +# +# This module will define the following variables: +# +# :: +# +# HDF5_INCLUDE_DIRS - Location of the hdf5 includes +# HDF5_INCLUDE_DIR - Location of the hdf5 includes (deprecated) +# HDF5_DEFINITIONS - Required compiler definitions for HDF5 +# HDF5_C_LIBRARIES - Required libraries for the HDF5 C bindings. +# HDF5_CXX_LIBRARIES - Required libraries for the HDF5 C++ bindings +# HDF5_Fortran_LIBRARIES - Required libraries for the HDF5 Fortran bindings +# HDF5_HL_LIBRARIES - Required libraries for the HDF5 high level API +# HDF5_Fortran_HL_LIBRARIES - Required libraries for the high level Fortran +# bindings. +# HDF5_LIBRARIES - Required libraries for all requested bindings +# HDF5_FOUND - true if HDF5 was found on the system +# HDF5_VERSION - HDF5 version in format Major.Minor.Release +# HDF5_LIBRARY_DIRS - the full set of library directories +# HDF5_IS_PARALLEL - Whether or not HDF5 was found with parallel IO support +# HDF5_C_COMPILER_EXECUTABLE - the path to the HDF5 C wrapper compiler +# HDF5_CXX_COMPILER_EXECUTABLE - the path to the HDF5 C++ wrapper compiler +# HDF5_Fortran_COMPILER_EXECUTABLE - the path to the HDF5 Fortran wrapper compiler +# HDF5_DIFF_EXECUTABLE - the path to the HDF5 dataset comparison tool + +#============================================================================= +# Copyright 2015 Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf +# Copyright 2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# This module is maintained by Will Dicharry . + +include(SelectLibraryConfigurations) +include(FindPackageHandleStandardArgs) + +# List of the valid HDF5 components +set( HDF5_VALID_COMPONENTS + C + CXX + Fortran + HL + Fortran_HL +) + +# Validate the list of find components. +if( NOT HDF5_FIND_COMPONENTS ) + set( HDF5_LANGUAGE_BINDINGS "C" ) +else() + # add the extra specified components, ensuring that they are valid. + foreach( component ${HDF5_FIND_COMPONENTS} ) + list( FIND HDF5_VALID_COMPONENTS ${component} component_location ) + if( ${component_location} EQUAL -1 ) + message( FATAL_ERROR + "\"${component}\" is not a valid HDF5 component." ) + else() + list( APPEND HDF5_LANGUAGE_BINDINGS ${component} ) + endif() + endforeach() +endif() + +if(HDF5_PREFER_PARALLEL) + # try to find the HDF5 wrapper compilers + find_program( HDF5_C_COMPILER_EXECUTABLE + NAMES h5pcc h5cc + HINTS ENV HDF5_ROOT + PATH_SUFFIXES bin Bin + DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." ) + mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE ) + + find_program( HDF5_CXX_COMPILER_EXECUTABLE + NAMES h5pc++ h5c++ + HINTS ENV HDF5_ROOT + PATH_SUFFIXES bin Bin + DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." ) + mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE ) + + find_program( HDF5_Fortran_COMPILER_EXECUTABLE + NAMES h5pfc h5fc + HINTS ENV HDF5_ROOT + PATH_SUFFIXES bin Bin + DOC "HDF5 Fortran Wrapper compiler. Used only to detect HDF5 compile flags." ) + mark_as_advanced( HDF5_Fortran_COMPILER_EXECUTABLE ) +else() + # try to find the HDF5 wrapper compilers + find_program( HDF5_C_COMPILER_EXECUTABLE + NAMES h5cc h5pcc + HINTS ENV HDF5_ROOT + PATH_SUFFIXES bin Bin + DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." ) + mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE ) + + find_program( HDF5_CXX_COMPILER_EXECUTABLE + NAMES h5c++ h5pc++ + HINTS ENV HDF5_ROOT + PATH_SUFFIXES bin Bin + DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." ) + mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE ) + + find_program( HDF5_Fortran_COMPILER_EXECUTABLE + NAMES h5fc h5pfc + HINTS ENV HDF5_ROOT + PATH_SUFFIXES bin Bin + DOC "HDF5 Fortran Wrapper compiler. Used only to detect HDF5 compile flags." ) + mark_as_advanced( HDF5_Fortran_COMPILER_EXECUTABLE ) +endif() + +find_program( HDF5_DIFF_EXECUTABLE + NAMES h5diff + HINTS ENV HDF5_ROOT + PATH_SUFFIXES bin Bin + DOC "HDF5 file differencing tool." ) +mark_as_advanced( HDF5_DIFF_EXECUTABLE ) + +# Invoke the HDF5 wrapper compiler. The compiler return value is stored to the +# return_value argument, the text output is stored to the output variable. +macro( _HDF5_invoke_compiler language output return_value ) + if( HDF5_${language}_COMPILER_EXECUTABLE ) + exec_program( ${HDF5_${language}_COMPILER_EXECUTABLE} + ARGS -show + OUTPUT_VARIABLE ${output} + RETURN_VALUE ${return_value} + ) + if( ${${return_value}} EQUAL 0 ) + # do nothing + else() + message( STATUS + "Unable to determine HDF5 ${language} flags from HDF5 wrapper." ) + endif() + endif() +endmacro() + +# Parse a compile line for definitions, includes, library paths, and libraries. +macro( _HDF5_parse_compile_line + compile_line_var + include_paths + definitions + library_paths + libraries ) + + # Match the include paths + string( REGEX MATCHALL "-I([^\" ]+)" include_path_flags + "${${compile_line_var}}" + ) + foreach( IPATH ${include_path_flags} ) + string( REGEX REPLACE "^-I" "" IPATH ${IPATH} ) + string( REPLACE "//" "/" IPATH ${IPATH} ) + list( APPEND ${include_paths} ${IPATH} ) + endforeach() + + # Match the definitions + string( REGEX MATCHALL "-D[^ ]*" definition_flags "${${compile_line_var}}" ) + foreach( DEF ${definition_flags} ) + list( APPEND ${definitions} ${DEF} ) + endforeach() + + # Match the library paths + string( REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags + "${${compile_line_var}}" + ) + + foreach( LPATH ${library_path_flags} ) + string( REGEX REPLACE "^-L" "" LPATH ${LPATH} ) + string( REPLACE "//" "/" LPATH ${LPATH} ) + list( APPEND ${library_paths} ${LPATH} ) + endforeach() + + # now search for the library names specified in the compile line (match -l...) + # match only -l's preceded by a space or comma + # this is to exclude directory names like xxx-linux/ + string( REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags + "${${compile_line_var}}" ) + # strip the -l from all of the library flags and add to the search list + foreach( LIB ${library_name_flags} ) + string( REGEX REPLACE "^[, ]-l" "" LIB ${LIB} ) + list( APPEND ${libraries} ${LIB} ) + endforeach() +endmacro() + +# Try to find HDF5 using an installed hdf5-config.cmake +if( NOT HDF5_FOUND ) + find_package( HDF5 QUIET NO_MODULE ) + if( HDF5_FOUND ) + set( HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR} ) + set( HDF5_LIBRARIES ) + set( HDF5_C_TARGET hdf5 ) + set( HDF5_CXX_TARGET hdf5_cpp ) + set( HDF5_HL_TARGET hdf5_hl ) + set( HDF5_Fortran_TARGET hdf5_fortran ) + set( HDF5_Fortran_HL_TARGET hdf5_hl_fortran ) + foreach( _component ${HDF5_LANGUAGE_BINDINGS} ) + list( FIND HDF5_VALID_COMPONENTS ${_component} _component_location ) + get_target_property( _comp_location ${HDF5_${_component}_TARGET} LOCATION ) + if( _comp_location ) + set( HDF5_${_component}_LIBRARY ${_comp_location} CACHE PATH + "HDF5 ${_component} library" ) + mark_as_advanced( HDF5_${_component}_LIBRARY ) + list( APPEND HDF5_LIBRARIES ${HDF5_${_component}_LIBRARY} ) + endif() + endforeach() + endif() +endif() + +if( NOT HDF5_FOUND ) + _HDF5_invoke_compiler( C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE ) + _HDF5_invoke_compiler( CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE ) + _HDF5_invoke_compiler( Fortran HDF5_Fortran_COMPILE_LINE HDF5_Fortran_RETURN_VALUE ) + set(HDF5_HL_COMPILE_LINE ${HDF5_C_COMPILE_LINE}) + set(HDF5_Fortran_HL_COMPILE_LINE ${HDF5_Fortran_COMPILE_LINE}) + + # seed the initial lists of libraries to find with items we know we need + set( HDF5_C_LIBRARY_NAMES_INIT hdf5 ) + set( HDF5_HL_LIBRARY_NAMES_INIT hdf5_hl ${HDF5_C_LIBRARY_NAMES_INIT} ) + set( HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT} ) + set( HDF5_Fortran_LIBRARY_NAMES_INIT hdf5_fortran + ${HDF5_C_LIBRARY_NAMES_INIT} ) + set( HDF5_Fortran_HL_LIBRARY_NAMES_INIT hdf5hl_fortran hdf5_hl + ${HDF5_Fortran_LIBRARY_NAMES_INIT} ) + + foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} ) + if( HDF5_${LANGUAGE}_COMPILE_LINE ) + _HDF5_parse_compile_line( HDF5_${LANGUAGE}_COMPILE_LINE + HDF5_${LANGUAGE}_INCLUDE_FLAGS + HDF5_${LANGUAGE}_DEFINITIONS + HDF5_${LANGUAGE}_LIBRARY_DIRS + HDF5_${LANGUAGE}_LIBRARY_NAMES + ) + + # take a guess that the includes may be in the 'include' sibling + # directory of a library directory. + foreach( dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) + list( APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include ) + endforeach() + endif() + + # set the definitions for the language bindings. + list( APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS} ) + + # find the HDF5 include directories + if(${LANGUAGE} MATCHES "Fortran") + set(HDF5_INCLUDE_FILENAME hdf5.mod) + else() + set(HDF5_INCLUDE_FILENAME hdf5.h) + endif() + + find_path( HDF5_${LANGUAGE}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME} + HINTS + ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} + ENV + HDF5_ROOT + PATHS + $ENV{HOME}/.local/include + PATH_SUFFIXES + include + Include + ) + mark_as_advanced( HDF5_${LANGUAGE}_INCLUDE_DIR ) + list( APPEND HDF5_INCLUDE_DIRS ${HDF5_${LANGUAGE}_INCLUDE_DIR} ) + + set( HDF5_${LANGUAGE}_LIBRARY_NAMES + ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT} + ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) + + # find the HDF5 libraries + foreach( LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) + if( UNIX AND HDF5_USE_STATIC_LIBRARIES ) + # According to bug 1643 on the CMake bug tracker, this is the + # preferred method for searching for a static library. + # See http://www.cmake.org/Bug/view.php?id=1643. We search + # first for the full static library name, but fall back to a + # generic search on the name if the static search fails. + set( THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d ) + set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} ) + else() + set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ) + set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ) + endif() + find_library( HDF5_${LIB}_LIBRARY_DEBUG + NAMES ${THIS_LIBRARY_SEARCH_DEBUG} + HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + ENV HDF5_ROOT + PATH_SUFFIXES lib Lib ) + find_library( HDF5_${LIB}_LIBRARY_RELEASE + NAMES ${THIS_LIBRARY_SEARCH_RELEASE} + HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + ENV HDF5_ROOT + PATH_SUFFIXES lib Lib ) + select_library_configurations( HDF5_${LIB} ) + list(APPEND HDF5_${LANGUAGE}_LIBRARIES ${HDF5_${LIB}_LIBRARY}) + endforeach() + list( APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) + + # Append the libraries for this language binding to the list of all + # required libraries. + list(APPEND HDF5_LIBRARIES ${HDF5_${LANGUAGE}_LIBRARIES}) + endforeach() + + # We may have picked up some duplicates in various lists during the above + # process for the language bindings (both the C and C++ bindings depend on + # libz for example). Remove the duplicates. It appears that the default + # CMake behavior is to remove duplicates from the end of a list. However, + # for link lines, this is incorrect since unresolved symbols are searched + # for down the link line. Therefore, we reverse the list, remove the + # duplicates, and then reverse it again to get the duplicates removed from + # the beginning. + macro( _remove_duplicates_from_beginning _list_name ) + list( REVERSE ${_list_name} ) + list( REMOVE_DUPLICATES ${_list_name} ) + list( REVERSE ${_list_name} ) + endmacro() + + if( HDF5_INCLUDE_DIRS ) + _remove_duplicates_from_beginning( HDF5_INCLUDE_DIRS ) + endif() + if( HDF5_LIBRARY_DIRS ) + _remove_duplicates_from_beginning( HDF5_LIBRARY_DIRS ) + endif() + if( HDF5_LIBRARIES ) + _remove_duplicates_from_beginning( HDF5_LIBRARIES ) + endif() + + # If the HDF5 include directory was found, open H5pubconf.h to determine if + # HDF5 was compiled with parallel IO support + set( HDF5_IS_PARALLEL FALSE ) + set( HDF5_VERSION "" ) + foreach( _dir IN LISTS HDF5_INCLUDE_DIRS ) + foreach(_hdr "${_dir}/H5pubconf.h" "${_dir}/H5pubconf-64.h" "${_dir}/H5pubconf-32.h") + if( EXISTS "${_hdr}" ) + file( STRINGS "${_hdr}" + HDF5_HAVE_PARALLEL_DEFINE + REGEX "HAVE_PARALLEL 1" ) + if( HDF5_HAVE_PARALLEL_DEFINE ) + set( HDF5_IS_PARALLEL TRUE ) + endif() + unset(HDF5_HAVE_PARALLEL_DEFINE) + + file( STRINGS "${_hdr}" + HDF5_VERSION_DEFINE + REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" ) + if( "${HDF5_VERSION_DEFINE}" MATCHES + "H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+).*\"" ) + set( HDF5_VERSION "${CMAKE_MATCH_1}" ) + endif() + unset(HDF5_VERSION_DEFINE) + endif() + endforeach() + endforeach() + set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL + "HDF5 library compiled with parallel IO support" ) + mark_as_advanced( HDF5_IS_PARALLEL ) + + # For backwards compatibility we set HDF5_INCLUDE_DIR to the value of + # HDF5_INCLUDE_DIRS + if( HDF5_INCLUDE_DIRS ) + set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" ) + endif() + +endif() + +find_package_handle_standard_args( HDF5 + REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS + VERSION_VAR HDF5_VERSION +) diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index e7ba39b646..28ac445ab5 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -4,7 +4,7 @@ module hdf5_interface use h5lt use, intrinsic :: ISO_C_BINDING -#ifdef MPI +#ifdef PHDF5 use message_passing, only: MPI_COMM_WORLD, MPI_INFO_NULL #endif @@ -36,7 +36,7 @@ module hdf5_interface module procedure hdf5_write_integer_4Darray module procedure hdf5_write_long module procedure hdf5_write_string -#ifdef MPI +#ifdef PHDF5 module procedure hdf5_write_double_parallel module procedure hdf5_write_double_1Darray_parallel module procedure hdf5_write_double_2Darray_parallel @@ -66,7 +66,7 @@ module hdf5_interface module procedure hdf5_read_integer_4Darray module procedure hdf5_read_long module procedure hdf5_read_string -#ifdef MPI +#ifdef PHDF5 module procedure hdf5_read_double_parallel module procedure hdf5_read_double_1Darray_parallel module procedure hdf5_read_double_2Darray_parallel @@ -134,7 +134,7 @@ contains end subroutine hdf5_file_close -#ifdef MPI +#ifdef PHDF5 !=============================================================================== ! HDF5_FILE_CREATE_PARALLEL creates HDF5 file with parallel I/O @@ -809,7 +809,7 @@ contains end subroutine hdf5_write_attribute_string -# ifdef MPI +#ifdef PHDF5 !=============================================================================== ! HDF5_WRITE_INTEGER_PARALLEL writes integer scalar data in parallel @@ -1807,6 +1807,6 @@ contains end subroutine hdf5_read_string_parallel -# endif +#endif end module hdf5_interface diff --git a/src/output_interface.F90 b/src/output_interface.F90 index 7ced3c0528..1e08ce4911 100644 --- a/src/output_interface.F90 +++ b/src/output_interface.F90 @@ -96,7 +96,7 @@ contains self % serial = .true. end if -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_file_create(filename, self % hdf5_fh) else @@ -126,7 +126,7 @@ contains self % serial = .true. end if -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_file_open(filename, self % hdf5_fh, mode) else @@ -212,7 +212,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_double(self % hdf5_grp, name_, buffer) else @@ -263,7 +263,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_double(self % hdf5_grp, name_, buffer) else @@ -315,7 +315,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_double_1Darray(self % hdf5_grp, name_, buffer, length) else @@ -368,7 +368,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_double_1Darray(self % hdf5_grp, name_, buffer, length) else @@ -421,7 +421,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_double_2Darray(self % hdf5_grp, name_, buffer, length) else @@ -474,7 +474,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_double_2Darray(self % hdf5_grp, name_, buffer, length) else @@ -527,7 +527,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_double_3Darray(self % hdf5_grp, name_, buffer, length) else @@ -580,7 +580,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_double_3Darray(self % hdf5_grp, name_, buffer, length) else @@ -634,7 +634,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_double_4Darray(self % hdf5_grp, name_, buffer, length) else @@ -689,7 +689,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_double_4Darray(self % hdf5_grp, name_, buffer, length) else @@ -741,7 +741,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_integer(self % hdf5_grp, name_, buffer) else @@ -792,7 +792,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_integer(self % hdf5_grp, name_, buffer) else @@ -844,7 +844,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_integer_1Darray(self % hdf5_grp, name_, buffer, length) else @@ -897,7 +897,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_integer_1Darray(self % hdf5_grp, name_, buffer, length) else @@ -951,7 +951,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_integer_2Darray(self % hdf5_grp, name_, buffer, length) else @@ -1004,7 +1004,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_integer_2Darray(self % hdf5_grp, name_, buffer, length) else @@ -1057,7 +1057,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_integer_3Darray(self % hdf5_grp, name_, buffer, length) else @@ -1110,7 +1110,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_integer_3Darray(self % hdf5_grp, name_, buffer, length) else @@ -1164,7 +1164,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_integer_4Darray(self % hdf5_grp, name_, buffer, length) else @@ -1218,7 +1218,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_integer_4Darray(self % hdf5_grp, name_, buffer, length) else @@ -1270,7 +1270,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_long(self % hdf5_grp, name_, buffer, hdf5_integer8_t) else @@ -1322,7 +1322,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_long(self % hdf5_grp, name_, buffer, hdf5_integer8_t) else @@ -1378,7 +1378,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_write_string(self % hdf5_grp, name_, buffer, n) else @@ -1434,7 +1434,7 @@ contains else self % hdf5_grp = self % hdf5_fh endif -#ifdef MPI +#ifdef PHDF5 if (self % serial) then call hdf5_read_string(self % hdf5_grp, name_, buffer, n) else @@ -1579,11 +1579,11 @@ contains class(BinaryOutput) :: self -#ifdef MPI +#ifdef PHDF5 integer(8) :: offset(1) ! source data offset #endif -#ifdef MPI +#ifdef PHDF5 ! Set size of total dataspace for all procs and rank dims1(1) = n_particles @@ -1662,11 +1662,11 @@ contains class(BinaryOutput) :: self -#ifdef MPI +#ifdef PHDF5 integer(8) :: offset(1) ! offset of data #endif -#ifdef MPI +#ifdef PHDF5 ! Set size of total dataspace for all procs and rank dims1(1) = n_particles diff --git a/tests/run_tests.py b/tests/run_tests.py index aa2eb14cfd..d3b79aa3b1 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -107,12 +107,13 @@ tests = OrderedDict() class Test(object): def __init__(self, name, debug=False, optimize=False, mpi=False, openmp=False, - valgrind=False, coverage=False): + phdf5=False, valgrind=False, coverage=False): self.name = name self.debug = debug self.optimize = optimize self.mpi = mpi self.openmp = openmp + self.phdf5 = phdf5 self.valgrind = valgrind self.coverage = coverage self.success = True @@ -125,9 +126,9 @@ class Test(object): # Check for MPI if self.mpi: - self.fc = PHDF5_DIR + '/bin/h5pfc' + self.fc = os.path.join(MPI_DIR, 'bin', 'mpifort') else: - self.fc = HDF5_DIR + '/bin/h5fc' + self.fc = FC # Sets the build name that will show up on the CDash def get_build_name(self): @@ -159,6 +160,10 @@ class Test(object): os.environ['FC'] = self.fc if self.mpi: os.environ['MPI_DIR'] = MPI_DIR + if self.phdf5: + os.environ['HDF5_ROOT'] = PHDF5_DIR + else: + os.environ['HDF5_ROOT'] = HDF5_DIR rc = call(['ctest', '-S', 'ctestscript.run','-V']) if rc != 0: self.success = False @@ -169,6 +174,10 @@ class Test(object): os.environ['FC'] = self.fc if self.mpi: os.environ['MPI_DIR'] = MPI_DIR + if self.phdf5: + os.environ['HDF5_ROOT'] = PHDF5_DIR + else: + os.environ['HDF5_ROOT'] = HDF5_DIR build_opts = self.build_opts.split() self.cmake += build_opts rc = call(self.cmake) @@ -258,8 +267,8 @@ class Test(object): # Simple function to add a test to the global tests dictionary def add_test(name, debug=False, optimize=False, mpi=False, openmp=False,\ - valgrind=False, coverage=False): - tests.update({name: Test(name, debug, optimize, mpi, openmp, + phdf5=False, valgrind=False, coverage=False): + tests.update({name: Test(name, debug, optimize, mpi, openmp, phdf5, valgrind, coverage)}) # List of all tests that may be run. User can add -C to command line to specify @@ -270,12 +279,15 @@ add_test('hdf5-optimize', optimize=True) add_test('omp-hdf5-normal', openmp=True) add_test('omp-hdf5-debug', openmp=True, debug=True) add_test('omp-hdf5-optimize', openmp=True, optimize=True) -add_test('phdf5-normal', mpi=True) -add_test('phdf5-debug', mpi=True, debug=True) -add_test('phdf5-optimize', mpi=True, optimize=True) -add_test('phdf5-omp-normal', mpi=True, openmp=True) -add_test('phdf5-omp-debug', mpi=True, openmp=True, debug=True) -add_test('phdf5-omp-optimize', mpi=True, openmp=True, optimize=True) +add_test('mpi-hdf5-normal', mpi=True) +add_test('mpi-hdf5-debug', mpi=True, debug=True) +add_test('mpi-hdf5-optimize', mpi=True, optimize=True) +add_test('phdf5-normal', mpi=True, phdf5=True) +add_test('phdf5-debug', mpi=True, phdf5=True, debug=True) +add_test('phdf5-optimize', mpi=True, phdf5=True, optimize=True) +add_test('phdf5-omp-normal', mpi=True, phdf5=True, openmp=True) +add_test('phdf5-omp-debug', mpi=True, phdf5=True, openmp=True, debug=True) +add_test('phdf5-omp-optimize', mpi=True, phdf5=True, openmp=True, optimize=True) add_test('hdf5-debug_valgrind', debug=True, valgrind=True) add_test('hdf5-debug_coverage', debug=True, coverage=True)