# Copyright 2013-2023 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.3", sha256="439e359d09bb93d0e58a6e3f928f39c2eae965b6c97f64e67cd42220d6034f77") 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") @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)