From c80c92aa39498dc3b204710fbc464fd0f9e8dc76 Mon Sep 17 00:00:00 2001 From: Sergey Kosukhin Date: Fri, 11 Feb 2022 09:23:47 +0100 Subject: serialbox: add new package (#28872) --- .../builtin/packages/serialbox/nag/examples.patch | 27 +++ .../repos/builtin/packages/serialbox/nag/ftg.patch | 31 ++++ .../builtin/packages/serialbox/nag/interface.patch | 9 + .../repos/builtin/packages/serialbox/package.py | 183 +++++++++++++++++++++ .../builtin/packages/serialbox/ppser_py3.patch | 23 +++ 5 files changed, 273 insertions(+) create mode 100644 var/spack/repos/builtin/packages/serialbox/nag/examples.patch create mode 100644 var/spack/repos/builtin/packages/serialbox/nag/ftg.patch create mode 100644 var/spack/repos/builtin/packages/serialbox/nag/interface.patch create mode 100644 var/spack/repos/builtin/packages/serialbox/package.py create mode 100644 var/spack/repos/builtin/packages/serialbox/ppser_py3.patch diff --git a/var/spack/repos/builtin/packages/serialbox/nag/examples.patch b/var/spack/repos/builtin/packages/serialbox/nag/examples.patch new file mode 100644 index 0000000000..91857d0d6c --- /dev/null +++ b/var/spack/repos/builtin/packages/serialbox/nag/examples.patch @@ -0,0 +1,27 @@ +# This patch is applicable starting version 2.3.1 +--- a/examples/fortran/simple/m_ser.F90 ++++ b/examples/fortran/simple/m_ser.F90 +@@ -38 +38 @@ USE utils_ppser, ONLY: & +- REAL(KIND=8), DIMENSION(:,:,:) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(:,:,:) :: a +@@ -59 +59 @@ USE utils_ppser, ONLY: & +- REAL(KIND=8), DIMENSION(:,:,:) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(:,:,:) :: a +@@ -91,2 +91,2 @@ USE utils_ppser, ONLY: & +- REAL(KIND=8), DIMENSION(:,:,:) :: a +- REAL(KIND=8) :: rprecision ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(:,:,:) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)) :: rprecision +@@ -97 +97 @@ USE utils_ppser, ONLY: & +- prefix_ref='SerialboxTest',rprecision=rprecision,rperturb=1.0e-5_8) ++ prefix_ref='SerialboxTest',rprecision=rprecision,rperturb=REAL(1.0e-5,SELECTED_REAL_KIND(15))) +--- a/examples/fortran/simple/main_consumer.F90 ++++ b/examples/fortran/simple/main_consumer.F90 +@@ -14 +14 @@ PROGRAM main_consumer +- REAL(KIND=8), DIMENSION(5,5,5) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(5,5,5) :: a +--- a/examples/fortran/simple/main_producer.F90 ++++ b/examples/fortran/simple/main_producer.F90 +@@ -14 +14 @@ PROGRAM main_producer +- REAL(KIND=8), DIMENSION(5,5,5) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(5,5,5) :: a diff --git a/var/spack/repos/builtin/packages/serialbox/nag/ftg.patch b/var/spack/repos/builtin/packages/serialbox/nag/ftg.patch new file mode 100644 index 0000000000..6794227a91 --- /dev/null +++ b/var/spack/repos/builtin/packages/serialbox/nag/ftg.patch @@ -0,0 +1,31 @@ +# This patch is applicable starting version 2.3.1 +--- a/src/serialbox-fortran/m_ser_ftg.f90 ++++ b/src/serialbox-fortran/m_ser_ftg.f90 +@@ -822,5 +822,5 @@ SUBROUTINE ftg_write_logical_1d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + +@@ -853,5 +853,5 @@ SUBROUTINE ftg_write_logical_2d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + +@@ -886,5 +886,5 @@ SUBROUTINE ftg_write_logical_3d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + +@@ -919,5 +919,5 @@ SUBROUTINE ftg_write_logical_4d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + diff --git a/var/spack/repos/builtin/packages/serialbox/nag/interface.patch b/var/spack/repos/builtin/packages/serialbox/nag/interface.patch new file mode 100644 index 0000000000..abb79bf396 --- /dev/null +++ b/var/spack/repos/builtin/packages/serialbox/nag/interface.patch @@ -0,0 +1,9 @@ +# This patch is applicable starting version 2.0.1 +--- a/src/serialbox-fortran/utils_ppser.f90 ++++ b/src/serialbox-fortran/utils_ppser.f90 +@@ -33 +33 @@ MODULE utils_ppser +-USE iso_fortran_env ++USE f90_unix_proc; USE iso_fortran_env +@@ -66 +66 @@ SUBROUTINE ppser_initialize(directory, prefix, mode, prefix_ref, mpi_rank, rprec +- REAL(KIND=8), OPTIONAL, INTENT(IN) :: rprecision, rperturb ++ REAL(KIND=SELECTED_REAL_KIND(15)), OPTIONAL, INTENT(IN) :: rprecision, rperturb diff --git a/var/spack/repos/builtin/packages/serialbox/package.py b/var/spack/repos/builtin/packages/serialbox/package.py new file mode 100644 index 0000000000..49f57249d3 --- /dev/null +++ b/var/spack/repos/builtin/packages/serialbox/package.py @@ -0,0 +1,183 @@ +# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + + +class Serialbox(CMakePackage): + """Serialbox is a serialization library and tools for C/C++, Python3 and + Fortran. Serialbox is used in several projects for building validation + frameworks against reference runs.""" + + homepage = "https://github.com/GridTools/serialbox" + url = "https://github.com/GridTools/serialbox/archive/v2.6.1.tar.gz" + + maintainers = ['skosukhin'] + + version('2.6.1', sha256='b795ce576e8c4fd137e48e502b07b136079c595c82c660cfa2e284b0ef873342') + version('2.6.0', sha256='9199f8637afbd7f2b3c5ba932d1c63e9e14d553a0cafe6c29107df0e04ee9fae') + version('2.5.4', sha256='f4aee8ef284f58e6847968fe4620e222ac7019d805bbbb26c199e4b6a5094fee') + version('2.5.3', sha256='696499b3f43978238c3bcc8f9de50bce2630c07971c47c9e03af0324652b2d5d') + + variant('c', default=True, description='enable C interface') + variant('python', default=False, description='enable Python interface') + variant('fortran', default=False, description='enable Fortran interface') + variant('ftg', default=False, + description='enable FortranTestGenerator frontend') + variant('sdb', default=False, description='enable stencil debugger') + variant('shared', default=True, description='build shared libraries') + variant('examples', default=False, description='build the examples') + variant('logging', default=True, + description='enable the logging infrastructure') + variant('async-api', default=True, + description='enable the asynchronous API') + variant('netcdf', default=False, + description='build the NetCDF archive backend') + variant('std-filesystem', default=True, + description='use std::experimental::filesystem (no dependency on ' + 'compiled boost libs)') + + depends_on('cmake@3.12:', type='build') + # We might be provided with an external vanilla cmake, and we need one with + # with https://gitlab.kitware.com/cmake/cmake/-/merge_requests/5025 + depends_on('cmake@3.19:', when='%pgi', type='build') + + depends_on('boost@1.54:', type='build') + depends_on('boost+filesystem+system', + when='~std-filesystem', type=('build', 'link')) + + depends_on('netcdf-c', when='+netcdf') + + depends_on('python@3.4:', when='+python', type=('build', 'run')) + depends_on('py-numpy', when='+python', type=('build', 'run')) + + # pp_ser fails to process source files containing Unicode character with + # Python 3 (https://github.com/GridTools/serialbox/pull/249): + patch('ppser_py3.patch', when='@2.2.1:') + + # NAG patches: + patch('nag/interface.patch', when='@2.0.1:%nag+fortran') + patch('nag/examples.patch', when='@2.3.1:%nag+fortran+examples') + patch('nag/ftg.patch', when='@2.3.1:%nag+ftg') + + conflicts('+ftg', when='~fortran', + msg='the FortranTestGenerator frontend requires the Fortran ' + 'interface') + conflicts('+ftg', when='@:2.2.999', + msg='the FortranTestGenerator frontend is supported only ' + 'starting version 2.3.0') + conflicts('+sdb', when='~python', + msg='the stencil debugger requires the Python interface') + conflicts('+fortran', when='~c', + msg='the Fortran interface requires the C interface') + conflicts('+python', when='~c', + msg='the Python interface requires the C interface') + conflicts('+python', when='~shared', + msg='the Python interface requires the shared libraries') + + def patch(self): + # The following is implemented as a method to avoid having two sets of + # almost identical patch files: one with the CR symbols (for versions + # 2.5.x) and one without them (for versions 2.6.x). + + # Remove hard-coded -march=native + # (see https://github.com/GridTools/serialbox/pull/233): + if self.spec.satisfies('@2.0.1:2.6.0'): + filter_file( + r'^(\s*set\(CMAKE_CXX_FLAGS.*-march=native)', + r'#\1', 'CMakeLists.txt') + + # Do not fallback to boost::filesystem: + if '+std-filesystem' in self.spec: + filter_file( + r'(message\()' + r'STATUS( "std::experimental::filesystem not found).*("\))', + r'\1FATAL_ERROR\2\3', 'CMakeLists.txt') + + @property + def libs(self): + query_parameters = self.spec.last_query.extra_parameters + + shared = '+shared' in self.spec + + query2libraries = { + tuple(): ['libSerialboxCore'], + ('c', 'fortran'): [ + 'libSerialboxFortran', + 'libSerialboxC', + 'libSerialboxCore', + ], + ('c',): [ + 'libSerialboxC', + 'libSerialboxCore', + ], + ('fortran',): [ + 'libSerialboxFortran', + 'libSerialboxC', + 'libSerialboxCore' + ] + } + + key = tuple(sorted(query_parameters)) + libraries = query2libraries[key] + + if self.spec.satisfies('@2.5.0:2.5'): + libraries = [ + '{0}{1}'.format(name, 'Shared' if shared else 'Static') + for name in libraries] + + libs = find_libraries( + libraries, root=self.prefix, shared=shared, recursive=True) + + if libs: + return libs + + msg = 'Unable to recursively locate {0} libraries in {1}' + raise spack.error.NoLibrariesError( + msg.format(self.spec.name, self.spec.prefix)) + + def flag_handler(self, name, flags): + cmake_flags = [] + + if name == 'cxxflags': + # Intel (at least up to version 19.0.1, version 19.0.4 works) and + # PGI (at least up to version 19.9, version 20.1.0 works) compilers + # have problems with C++11 name mangling. An attempt to link to + # libSerialboxCore leads to: + # undefined reference to + # `std::experimental::filesystem::v1::__cxx11::path:: + # _M_find_extension[abi:cxx11]() const' + if any(self.spec.satisfies('{0}+std-filesystem'.format(x)) + for x in ['%intel@:19.0.1', '%pgi@:19.9']): + cmake_flags.append('-D_GLIBCXX_USE_CXX11_ABI=0') + + return flags, None, (cmake_flags or None) + + def cmake_args(self): + args = [ + '-DBOOST_ROOT:PATH=%s' % self.spec['boost'].prefix, + # https://cmake.org/cmake/help/v3.15/module/FindBoost.html#boost-cmake + self.define('Boost_NO_BOOST_CMAKE', True), + self.define_from_variant('SERIALBOX_ENABLE_C', 'c'), + self.define_from_variant('SERIALBOX_ENABLE_PYTHON', 'python'), + self.define_from_variant('SERIALBOX_ENABLE_FORTRAN', 'fortran'), + self.define_from_variant('SERIALBOX_ENABLE_FTG', 'ftg'), + self.define_from_variant('SERIALBOX_ENABLE_SDB', 'sdb'), + self.define_from_variant('SERIALBOX_BUILD_SHARED', 'shared'), + self.define_from_variant('SERIALBOX_EXAMPLES', 'examples'), + self.define_from_variant('SERIALBOX_LOGGING', 'logging'), + self.define_from_variant('SERIALBOX_ASYNC_API', 'async-api'), + # CMake scripts of Serialbox (at least up to version 2.6.0) are + # broken and do not instruct the compiler to link to the OpenSSL + # libraries: + self.define('SERIALBOX_USE_OPENSSL', False), + self.define_from_variant('SERIALBOX_ENABLE_EXPERIMENTAL_FILESYSTEM', + 'std-filesystem'), + self.define_from_variant('SERIALBOX_USE_NETCDF', 'netcdf'), + self.define('SERIALBOX_TESTING', self.run_tests), + ] + + if '+netcdf' in self.spec: + args.append('-DNETCDF_ROOT:PATH=%s' % self.spec['netcdf-c'].prefix) + + return args diff --git a/var/spack/repos/builtin/packages/serialbox/ppser_py3.patch b/var/spack/repos/builtin/packages/serialbox/ppser_py3.patch new file mode 100644 index 0000000000..1a15de7274 --- /dev/null +++ b/var/spack/repos/builtin/packages/serialbox/ppser_py3.patch @@ -0,0 +1,23 @@ +# This patch is applicable starting version 2.2.1 +--- a/src/serialbox-python/pp_ser/pp_ser.py ++++ b/src/serialbox-python/pp_ser/pp_ser.py +@@ -51 +51 @@ __email__ = 'oliver.fuhrer@meteoswiss.ch' +-def to_ascii(text): ++def open23(name, mode='r'): +@@ -53 +53,9 @@ def to_ascii(text): +- return bytes(text, 'ascii') ++ return open(name, mode, ++ encoding=(None if 'b' in mode else 'UTF-8')) ++ else: ++ return open(name, mode) ++ ++ ++def bytes23(text): ++ if sys.version_info[0] == 3: ++ return bytes(text, 'UTF-8') +@@ -815 +823 @@ class PpSer: +- input_file = open(os.path.join(self.infile), 'r') ++ input_file = open23(os.path.join(self.infile), 'r') +@@ -860 +868 @@ class PpSer: +- output_file.write(to_ascii(self.__outputBuffer)) ++ output_file.write(bytes23(self.__outputBuffer)) -- cgit v1.2.3-60-g2f50