# 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) import os from spack.package import * class ParallelNetcdf(AutotoolsPackage): """PnetCDF (Parallel netCDF) is a high-performance parallel I/O library for accessing files in format compatibility with Unidata's NetCDF, specifically the formats of CDF-1, 2, and 5. """ homepage = "https://parallel-netcdf.github.io/" git = "https://github.com/Parallel-NetCDF/PnetCDF" url = "https://parallel-netcdf.github.io/Release/pnetcdf-1.11.0.tar.gz" list_url = "https://parallel-netcdf.github.io/wiki/Download.html" maintainers = ['skosukhin'] tags = ['e4s'] test_requires_compiler = True def url_for_version(self, version): if version >= Version('1.11.0'): url = "https://parallel-netcdf.github.io/Release/pnetcdf-{0}.tar.gz" else: url = "https://parallel-netcdf.github.io/Release/parallel-netcdf-{0}.tar.gz" return url.format(version.dotted) version('master', branch='master') version('1.12.2', sha256='3ef1411875b07955f519a5b03278c31e566976357ddfc74c2493a1076e7d7c74') version('1.12.1', sha256='56f5afaa0ddc256791c405719b6436a83b92dcd5be37fe860dea103aee8250a2') version('1.11.2', sha256='d2c18601b364c35b5acb0a0b46cd6e14cae456e0eb854e5c789cf65f3cd6a2a7') version('1.11.1', sha256='0c587b707835255126a23c104c66c9614be174843b85b897b3772a590be45779') version('1.11.0', sha256='a18a1a43e6c4fd7ef5827dbe90e9dcf1363b758f513af1f1356ed6c651195a9f') version('1.10.0', sha256='ed189228b933cfeac3b7b4f8944eb00e4ff2b72cf143365b1a77890980663a09') version('1.9.0', sha256='356e1e1fae14bc6c4236ec11435cfea0ff6bde2591531a4a329f9508a01fbe98') version('1.8.1', sha256='8d7d4c9c7b39bb1cbbcf087e0d726551c50f0cc30d44aed3df63daf3772c9043') version('1.8.0', sha256='ac00bb2333bee96354de9d9c32d3dfdaa919d878098762f146996578b7f0ede9') version('1.7.0', sha256='52f0d106c470a843c6176318141f74a21e6ece3f70ee8fe261c6b93e35f70a94') version('1.6.1', sha256='8cf1af7b640475e3cc931e5fbcfe52484c5055f2fab526691933c02eda388aae') variant('cxx', default=True, description='Build the C++ Interface') variant('fortran', default=True, description='Build the Fortran Interface') variant('pic', default=True, description='Produce position-independent code (for shared libs)') variant('shared', default=True, description='Enable shared library') variant('burstbuffer', default=False, description='Enable burst buffer feature') depends_on('mpi') depends_on('m4', type='build') depends_on('autoconf', when='@master', type='build') depends_on('automake', when='@master', type='build') depends_on('libtool', when='@master', type='build') depends_on('perl', type='build') # Suport for shared libraries was introduced in version 1.9.0 conflicts('+shared', when='@:1.8') conflicts('+burstbuffer', when='@:1.10') # Before 1.10.0, C utility programs (e.g. ncmpigen) were linked without # explicit specification of the Fortran runtime libraries, which is # required when libpnetcdf.so contains Fortran symbols. Libtool sets the # required linking flags implicitly but only if the Fortran compiler # produces verbose output with the '-v' flag (and, due to a bug in Libtool, # when CXX is not set to 'no'; see macro _LT_LANG_FC_CONFIG in libtool.m4 # for more details). The latter is not the case for NAG. Starting 1.10.0, # the required linking flags are explicitly set in the makefiles and # detected using macro AC_FC_LIBRARY_LDFLAGS, which means that we can # override the verbose output flag for Fortran compiler on the command line # (see below). conflicts('+shared', when='@:1.9%nag+fortran') # https://github.com/Parallel-NetCDF/PnetCDF/pull/59 patch('nag_libtool.patch', when='@1.9:1.12.1%nag') # We could apply the patch unconditionally. However, it fixes a problem # that manifests itself only when we build shared libraries with Spack on # a Cray system with PGI compiler. Based on the name of the $CC executable, # Libtool "thinks" that it works with PGI compiler directly but on a Cray # system it actually works with the Cray's wrapper. PGI compiler (at least # since the version 15.7) "understands" two formats of the # '--whole-archive' argument. Unluckily, Cray's wrapper "understands" only # one of them but Libtool switches to another one. The following patch # discards the switching. patch('cray_pgi_libtool_release.patch', when='@1.8:999%pgi+shared platform=cray') # Given that the bug manifests itself in rather specific conditions, it is # not reported upstream. patch('cray_pgi_libtool_master.patch', when='@master%pgi+shared platform=cray') @property def libs(self): libraries = ['libpnetcdf'] query_parameters = self.spec.last_query.extra_parameters if 'shared' in query_parameters: shared = True elif 'static' in query_parameters: shared = False else: shared = '+shared' in self.spec libs = find_libraries( libraries, root=self.prefix, shared=shared, recursive=True ) if libs: return libs msg = 'Unable to recursively locate {0} {1} libraries in {2}' raise spack.error.NoLibrariesError( msg.format('shared' if shared else 'static', self.spec.name, self.spec.prefix)) @when('@master') def autoreconf(self, spec, prefix): with working_dir(self.configure_directory): # We do not specify '-f' because we need to use libtool files from # the repository. autoreconf('-iv') def configure_args(self): args = ['--with-mpi=%s' % self.spec['mpi'].prefix, 'SEQ_CC=%s' % spack_cc] args += self.enable_or_disable('cxx') args += self.enable_or_disable('fortran') flags = { 'CFLAGS': [], 'CXXFLAGS': [], 'FFLAGS': [], 'FCFLAGS': [], } if '+pic' in self.spec: flags['CFLAGS'].append(self.compiler.cc_pic_flag) flags['CXXFLAGS'].append(self.compiler.cxx_pic_flag) flags['FFLAGS'].append(self.compiler.f77_pic_flag) flags['FCFLAGS'].append(self.compiler.fc_pic_flag) # https://github.com/Parallel-NetCDF/PnetCDF/issues/61 if self.spec.satisfies('%gcc@10:'): flags['FFLAGS'].append('-fallow-argument-mismatch') flags['FCFLAGS'].append('-fallow-argument-mismatch') for key, value in sorted(flags.items()): if value: args.append('{0}={1}'.format(key, ' '.join(value))) if self.version >= Version('1.8'): args.append('--enable-relax-coord-bound') if self.version >= Version('1.9'): args += self.enable_or_disable('shared') args.extend(['--enable-static', '--disable-silent-rules']) if self.spec.satisfies('%nag+fortran+shared'): args.extend(['ac_cv_prog_fc_v=-Wl,-v', 'ac_cv_prog_f77_v=-Wl,-v']) if '+burstbuffer' in self.spec: args.append('--enable-burst-buffering') return args examples_src_dir = join_path('examples', 'CXX') @run_after('install') def cache_test_sources(self): """Copy the example source files after the package is installed to an install test subdirectory for use during `spack test run`.""" self.cache_extra_test_sources([self.examples_src_dir]) def test(self): test_dir = join_path(self.test_suite.current_test_cache_dir, self.examples_src_dir) # pnetcdf has many examples to serve as a suitable smoke check. # column_wise was chosen based on the E4S test suite. Other # examples should work as well. test_exe = 'column_wise' options = ['{0}.cpp'.format(test_exe), '-o', test_exe, '-lpnetcdf', '-L{0}'.format(self.prefix.lib), '-I{0}'.format(self.prefix.include)] reason = 'test: compiling and linking pnetcdf example' self.run_test(self.spec['mpi'].mpicxx, options, [], installed=False, purpose=reason, work_dir=test_dir) mpiexe_list = [self.spec['mpi'].prefix.bin.srun, self.spec['mpi'].prefix.bin.mpirun, self.spec['mpi'].prefix.bin.mpiexec] for mpiexe in mpiexe_list: if os.path.isfile(mpiexe): self.run_test(mpiexe, ['-n', '1', test_exe], [], installed=False, purpose='test: pnetcdf smoke test', skip_missing=True, work_dir=test_dir) break self.run_test('rm', ['-f', test_exe], work_dir=test_dir)