class CudaPackage(PackageBase): """Auxiliary class which contains CUDA variant, dependencies and conflicts and is meant to unify and facilitate its usage. """ # FIXME: keep cuda and cuda_arch separate to make usage easier untill # Spack has depends_on(cuda, when='cuda_arch!=None') or alike variant('cuda', default=False, description='Build with CUDA') # see http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list # https://developer.nvidia.com/cuda-gpus variant('cuda_arch', default=None, description='CUDA architecture', values=('20', '30', '32', '35', '50', '52', '53', '60', '61', '62', '70'), multi=True) # see http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#nvcc-examples # and http://llvm.org/docs/CompileCudaWithLLVM.html#compiling-cuda-code @staticmethod def cuda_flags(arch_list): return [('--generate-code arch=compute_{0},code=sm_{0} ' '--generate-code arch=compute_{0},code=compute_{0}').format(s) for s in arch_list] depends_on("cuda@7:", when='+cuda') # CUDA version vs Architecture depends_on("cuda@8:", when='cuda_arch=60') depends_on("cuda@8:", when='cuda_arch=61') depends_on("cuda@8:", when='cuda_arch=62') depends_on("cuda@9:", when='cuda_arch=70') depends_on('cuda@:8.99', when='cuda_arch=20') # Compiler conflicts: # https://gist.github.com/ax3l/9489132 conflicts('%gcc@5:', when='+cuda ^cuda@:7.5') conflicts('%gcc@6:', when='+cuda ^cuda@:8.99') conflicts('%gcc@7:', when='+cuda ^cuda@:9.99') if (platform.system() != "Darwin"): conflicts('%clang@:3.4,3.7:', when='+cuda ^[email protected]') conflicts('%clang@:3.7,4:', when='+cuda ^cuda@8:9') conflicts('%intel@:14,16:', when='+cuda ^[email protected]') conflicts('%intel@:14,17:', when='+cuda ^[email protected]') conflicts('%intel@:14,18:', when='+cuda ^[email protected]:9') # Make sure cuda_arch can not be used without +cuda conflicts('~cuda', when='cuda_arch=20') conflicts('~cuda', when='cuda_arch=30') conflicts('~cuda', when='cuda_arch=32') conflicts('~cuda', when='cuda_arch=35') conflicts('~cuda', when='cuda_arch=50') conflicts('~cuda', when='cuda_arch=52') conflicts('~cuda', when='cuda_arch=53') conflicts('~cuda', when='cuda_arch=60') conflicts('~cuda', when='cuda_arch=61') conflicts('~cuda', when='cuda_arch=62') conflicts('~cuda', when='cuda_arch=70')
class HipPackage(PackageBase): """Auxiliary class which contains HIP variant, dependencies and conflicts and is meant to unify and facilitate its usage. Closely mimics CudaPackage. Maintainers: dtaller """ # https://llvm.org/docs/AMDGPUUsage.html # Possible architectures amdgpu_targets = ( 'gfx701', 'gfx801', 'gfx802', 'gfx803', 'gfx900', 'gfx906', 'gfx908', 'gfx1010', 'gfx1011', 'gfx1012', 'none' ) variant('hip', default=False, description='Enable HIP support') # possible amd gpu targets for hip builds variant('amdgpu_target', default='none', values=amdgpu_targets) depends_on('llvm-amdgpu', when='+hip') depends_on('hsa-rocr-dev', when='+hip') depends_on('hip', when='+hip') # need amd gpu type for hip builds conflicts('amdgpu_target=none', when='+hip') # Make sure non-'none' amdgpu_targets cannot be used without +hip for value in amdgpu_targets[:-1]: conflicts('~hip', when='amdgpu_target=' + value) # https://github.com/ROCm-Developer-Tools/HIP/blob/master/bin/hipcc # It seems that hip-clang does not (yet?) accept this flag, in which case # we will still need to set the HCC_AMDGPU_TARGET environment flag in the # hip package file. But I will leave this here for future development. @staticmethod def hip_flags(amdgpu_target): return '--amdgpu-target={0}'.format(amdgpu_target) # https://llvm.org/docs/AMDGPUUsage.html # Possible architectures (not including 'none' option) @staticmethod def amd_gputargets_list(): return ( 'gfx701', 'gfx801', 'gfx802', 'gfx803', 'gfx900', 'gfx906', 'gfx908', 'gfx1010', 'gfx1011', 'gfx1012' )
class ROCmPackage(PackageBase): """Auxiliary class which contains ROCm variant, dependencies and conflicts and is meant to unify and facilitate its usage. Closely mimics CudaPackage. Maintainers: dtaller """ # https://llvm.org/docs/AMDGPUUsage.html # Possible architectures amdgpu_targets = ( 'gfx701', 'gfx801', 'gfx802', 'gfx803', 'gfx900', 'gfx906', 'gfx908', 'gfx1010', 'gfx1011', 'gfx1012' ) variant('rocm', default=False, description='Enable ROCm support') # possible amd gpu targets for rocm builds variant('amdgpu_target', description='AMD GPU architecture', values=spack.variant.any_combination_of(*amdgpu_targets)) depends_on('llvm-amdgpu', when='+rocm') depends_on('hsa-rocr-dev', when='+rocm') depends_on('hip', when='+rocm') conflicts('^blt@:0.3.6', when='+rocm') # need amd gpu type for rocm builds conflicts('amdgpu_target=none', when='+rocm') # Make sure amdgpu_targets cannot be used without +rocm for value in amdgpu_targets: conflicts('~rocm', when='amdgpu_target=' + value) # https://github.com/ROCm-Developer-Tools/HIP/blob/master/bin/hipcc # It seems that hip-clang does not (yet?) accept this flag, in which case # we will still need to set the HCC_AMDGPU_TARGET environment flag in the # hip package file. But I will leave this here for future development. @staticmethod def hip_flags(amdgpu_target): archs = ",".join(amdgpu_target) return '--amdgpu-target={0}'.format(archs)
class PyAtlinter(PythonPackage): """Interpolation of section images.""" homepage = "https://atlas-interpolation.rtfd.io" git = "[email protected]:project/proj101/atlas_interpolation.git" maintainers = ["EmilieDel", "Stannislav"] version( "0.2.3", url= "https://files.pythonhosted.org/packages/57/d3/4cdfaacccff677b32687cbcfd689727bc7b3a8f4485401aa3eca157e5aaf/atlinter-0.2.3.tar.gz", sha256= "67f102b70bc7eeb450da8af3c19df38610dd081a025f9c04e8f5266d2d0cc6e3", ) version("0.2.2", tag="v0.2.2") version("0.2.1", tag="v0.2.1") version("0.2.0", tag="v0.2.0") version("0.1.1", tag="v0.1.1") version("0.1.0", tag="v0.1.0") variant("cuda", default=False, description="Enable CUDA support") depends_on("[email protected]:", type=("build", "run")) depends_on("py-setuptools", type="build") depends_on("py-setuptools-scm", type="build") # opencv leads to problems: # fatal error: opencv2/opencv.hpp: No such file or directory depends_on("mxnet+cuda~opencv", when="@0.1.1:+cuda", type=("build", "run")) depends_on("mxnet~cuda~opencv", when="@0.1.1:~cuda", type=("build", "run")) depends_on("py-atlannot", when="@0.2.2:", type=("build", "run")) depends_on("[email protected]", type=("build", "run")) depends_on("py-numpy", type=("build", "run")) depends_on("py-pillow", type=("build", "run")) depends_on("py-pytorch-fid", type=("build", "run")) depends_on("py-pynrrd", when="@0.2.2:", type=("build", "run")) depends_on("py-pyyaml", when="@0.1.1:", type=("build", "run")) depends_on("py-requests", type=("build", "run")) depends_on("py-scikit-image", when="@0.2.2:", type=("build", "run")) depends_on("py-scipy", when="@0.1.1:", type=("build", "run")) depends_on("py-torch+cuda", when="+cuda", type=("build", "run")) depends_on("py-torch~cuda~cudnn~nccl", when="~cuda", type=("build", "run")) depends_on("py-torchvision", type=("build", "run"))
class CMakePackage(PackageBase): """Specialized class for packages built using CMake For more information on the CMake build system, see: https://cmake.org/cmake/help/latest/ This class provides three phases that can be overridden: 1. :py:meth:`~.CMakePackage.cmake` 2. :py:meth:`~.CMakePackage.build` 3. :py:meth:`~.CMakePackage.install` They all have sensible defaults and for many packages the only thing necessary will be to override :py:meth:`~.CMakePackage.cmake_args`. For a finer tuning you may also override: +-----------------------------------------------+--------------------+ | **Method** | **Purpose** | +===============================================+====================+ | :py:meth:`~.CMakePackage.root_cmakelists_dir` | Location of the | | | root CMakeLists.txt| +-----------------------------------------------+--------------------+ | :py:meth:`~.CMakePackage.build_directory` | Directory where to | | | build the package | +-----------------------------------------------+--------------------+ The generator used by CMake can be specified by providing the generator attribute. Per https://cmake.org/cmake/help/git-master/manual/cmake-generators.7.html, the format is: [<secondary-generator> - ]<primary_generator>. The full list of primary and secondary generators supported by CMake may be found in the documentation for the version of CMake used; however, at this time Spack supports only the primary generators "Unix Makefiles" and "Ninja." Spack's CMake support is agnostic with respect to primary generators. Spack will generate a runtime error if the generator string does not follow the prescribed format, or if the primary generator is not supported. """ #: Phases of a CMake package phases = ['cmake', 'build', 'install'] #: This attribute is used in UI queries that need to know the build #: system base class build_system_class = 'CMakePackage' build_targets = [] # type: List[str] install_targets = ['install'] build_time_test_callbacks = ['check'] #: The build system generator to use. #: #: See ``cmake --help`` for a list of valid generators. #: Currently, "Unix Makefiles" and "Ninja" are the only generators #: that Spack supports. Defaults to "Unix Makefiles". #: #: See https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html #: for more information. generator = 'Unix Makefiles' # https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html variant('build_type', default='RelWithDebInfo', description='CMake build type', values=('Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel')) # https://cmake.org/cmake/help/latest/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.html variant('ipo', default=False, description='CMake interprocedural optimization') # CMAKE_INTERPROCEDURAL_OPTIMIZATION only exists for CMake >= 3.9 conflicts('+ipo', when='^cmake@:3.8', msg='+ipo is not supported by CMake < 3.9') depends_on('cmake', type='build') @property def archive_files(self): """Files to archive for packages based on CMake""" return [os.path.join(self.build_directory, 'CMakeCache.txt')] @property def root_cmakelists_dir(self): """The relative path to the directory containing CMakeLists.txt This path is relative to the root of the extracted tarball, not to the ``build_directory``. Defaults to the current directory. :return: directory containing CMakeLists.txt """ return self.stage.source_path @property def std_cmake_args(self): """Standard cmake arguments provided as a property for convenience of package writers :return: standard cmake arguments """ # standard CMake arguments std_cmake_args = CMakePackage._std_args(self) std_cmake_args += getattr(self, 'cmake_flag_args', []) return std_cmake_args @staticmethod def _std_args(pkg): """Computes the standard cmake arguments for a generic package""" try: generator = pkg.generator except AttributeError: generator = 'Unix Makefiles' # Make sure a valid generator was chosen valid_primary_generators = ['Unix Makefiles', 'Ninja'] primary_generator = _extract_primary_generator(generator) if primary_generator not in valid_primary_generators: msg = "Invalid CMake generator: '{0}'\n".format(generator) msg += "CMakePackage currently supports the following " msg += "primary generators: '{0}'".\ format("', '".join(valid_primary_generators)) raise InstallError(msg) try: build_type = pkg.spec.variants['build_type'].value except KeyError: build_type = 'RelWithDebInfo' try: ipo = pkg.spec.variants['ipo'].value except KeyError: ipo = False define = CMakePackage.define args = [ '-G', generator, define('CMAKE_INSTALL_PREFIX', pkg.prefix), define('CMAKE_BUILD_TYPE', build_type), ] # CMAKE_INTERPROCEDURAL_OPTIMIZATION only exists for CMake >= 3.9 if pkg.spec.satisfies('^[email protected]:'): args.append(define('CMAKE_INTERPROCEDURAL_OPTIMIZATION', ipo)) if primary_generator == 'Unix Makefiles': args.append(define('CMAKE_VERBOSE_MAKEFILE', True)) if platform.mac_ver()[0]: args.extend([ define('CMAKE_FIND_FRAMEWORK', "LAST"), define('CMAKE_FIND_APPBUNDLE', "LAST"), ]) # Set up CMake rpath args.extend([ define('CMAKE_INSTALL_RPATH_USE_LINK_PATH', False), define('CMAKE_INSTALL_RPATH', spack.build_environment.get_rpaths(pkg)), ]) # CMake's find_package() looks in CMAKE_PREFIX_PATH first, help CMake # to find immediate link dependencies in right places: deps = [d.prefix for d in pkg.spec.dependencies(deptype=('build', 'link'))] deps = filter_system_paths(deps) args.append(define('CMAKE_PREFIX_PATH', deps)) return args @staticmethod def define(cmake_var, value): """Return a CMake command line argument that defines a variable. The resulting argument will convert boolean values to OFF/ON and lists/tuples to CMake semicolon-separated string lists. All other values will be interpreted as strings. Examples: .. code-block:: python [define('BUILD_SHARED_LIBS', True), define('CMAKE_CXX_STANDARD', 14), define('swr', ['avx', 'avx2'])] will generate the following configuration options: .. code-block:: console ["-DBUILD_SHARED_LIBS:BOOL=ON", "-DCMAKE_CXX_STANDARD:STRING=14", "-DSWR:STRING=avx;avx2] """ # Create a list of pairs. Each pair includes a configuration # option and whether or not that option is activated if isinstance(value, bool): kind = 'BOOL' value = "ON" if value else "OFF" else: kind = 'STRING' if isinstance(value, (list, tuple)): value = ";".join(str(v) for v in value) else: value = str(value) return "".join(["-D", cmake_var, ":", kind, "=", value]) def define_from_variant(self, cmake_var, variant=None): """Return a CMake command line argument from the given variant's value. The optional ``variant`` argument defaults to the lower-case transform of ``cmake_var``. This utility function is similar to :py:meth:`~.AutotoolsPackage.with_or_without`. Examples: Given a package with: .. code-block:: python variant('cxxstd', default='11', values=('11', '14'), multi=False, description='') variant('shared', default=True, description='') variant('swr', values=any_combination_of('avx', 'avx2'), description='') calling this function like: .. code-block:: python [define_from_variant('BUILD_SHARED_LIBS', 'shared'), define_from_variant('CMAKE_CXX_STANDARD', 'cxxstd'), define_from_variant('SWR')] will generate the following configuration options: .. code-block:: console ["-DBUILD_SHARED_LIBS:BOOL=ON", "-DCMAKE_CXX_STANDARD:STRING=14", "-DSWR:STRING=avx;avx2] for ``<spec-name> cxxstd=14 +shared swr=avx,avx2`` """ if variant is None: variant = cmake_var.lower() if variant not in self.variants: raise KeyError( '"{0}" is not a variant of "{1}"'.format(variant, self.name)) value = self.spec.variants[variant].value if isinstance(value, (tuple, list)): # Sort multi-valued variants for reproducibility value = sorted(value) return self.define(cmake_var, value) def flags_to_build_system_args(self, flags): """Produces a list of all command line arguments to pass the specified compiler flags to cmake. Note CMAKE does not have a cppflags option, so cppflags will be added to cflags, cxxflags, and fflags to mimic the behavior in other tools.""" # Has to be dynamic attribute due to caching setattr(self, 'cmake_flag_args', []) flag_string = '-DCMAKE_{0}_FLAGS={1}' langs = {'C': 'c', 'CXX': 'cxx', 'Fortran': 'f'} # Handle language compiler flags for lang, pre in langs.items(): flag = pre + 'flags' # cmake has no explicit cppflags support -> add it to all langs lang_flags = ' '.join(flags.get(flag, []) + flags.get('cppflags', [])) if lang_flags: self.cmake_flag_args.append(flag_string.format(lang, lang_flags)) # Cmake has different linker arguments for different build types. # We specify for each of them. if flags['ldflags']: ldflags = ' '.join(flags['ldflags']) ld_string = '-DCMAKE_{0}_LINKER_FLAGS={1}' # cmake has separate linker arguments for types of builds. for type in ['EXE', 'MODULE', 'SHARED', 'STATIC']: self.cmake_flag_args.append(ld_string.format(type, ldflags)) # CMake has libs options separated by language. Apply ours to each. if flags['ldlibs']: libs_flags = ' '.join(flags['ldlibs']) libs_string = '-DCMAKE_{0}_STANDARD_LIBRARIES={1}' for lang in langs: self.cmake_flag_args.append(libs_string.format(lang, libs_flags)) @property def build_dirname(self): """Returns the directory name to use when building the package :return: name of the subdirectory for building the package """ return 'spack-build-%s' % self.spec.dag_hash(7) @property def build_directory(self): """Returns the directory to use when building the package :return: directory where to build the package """ return os.path.join(self.stage.path, self.build_dirname) def cmake_args(self): """Produces a list containing all the arguments that must be passed to cmake, except: * CMAKE_INSTALL_PREFIX * CMAKE_BUILD_TYPE which will be set automatically. :return: list of arguments for cmake """ return [] def cmake(self, spec, prefix): """Runs ``cmake`` in the build directory""" options = self.std_cmake_args options += self.cmake_args() options.append(os.path.abspath(self.root_cmakelists_dir)) with working_dir(self.build_directory, create=True): inspect.getmodule(self).cmake(*options) def build(self, spec, prefix): """Make the build targets""" with working_dir(self.build_directory): if self.generator == 'Unix Makefiles': inspect.getmodule(self).make(*self.build_targets) elif self.generator == 'Ninja': self.build_targets.append("-v") inspect.getmodule(self).ninja(*self.build_targets) def install(self, spec, prefix): """Make the install targets""" with working_dir(self.build_directory): if self.generator == 'Unix Makefiles': inspect.getmodule(self).make(*self.install_targets) elif self.generator == 'Ninja': inspect.getmodule(self).ninja(*self.install_targets) run_after('build')(PackageBase._run_default_build_time_test_callbacks) def check(self): """Searches the CMake-generated Makefile for the target ``test`` and runs it if found. """ with working_dir(self.build_directory): if self.generator == 'Unix Makefiles': self._if_make_target_execute('test', jobs_env='CTEST_PARALLEL_LEVEL') self._if_make_target_execute('check') elif self.generator == 'Ninja': self._if_ninja_target_execute('test', jobs_env='CTEST_PARALLEL_LEVEL') self._if_ninja_target_execute('check') # Check that self.prefix is there after installation run_after('install')(PackageBase.sanity_check_prefix)
class CudaPackage(PackageBase): """Auxiliary class which contains CUDA variant, dependencies and conflicts and is meant to unify and facilitate its usage. Maintainers: ax3l, Rombur """ # https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list # https://developer.nvidia.com/cuda-gpus # https://en.wikipedia.org/wiki/CUDA#GPUs_supported cuda_arch_values = ('10', '11', '12', '13', '20', '21', '30', '32', '35', '37', '50', '52', '53', '60', '61', '62', '70', '72', '75', '80', '86') # FIXME: keep cuda and cuda_arch separate to make usage easier until # Spack has depends_on(cuda, when='cuda_arch!=None') or alike variant('cuda', default=False, description='Build with CUDA') variant('cuda_arch', description='CUDA architecture', values=spack.variant.any_combination_of(*cuda_arch_values)) # https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#nvcc-examples # https://llvm.org/docs/CompileCudaWithLLVM.html#compiling-cuda-code @staticmethod def cuda_flags(arch_list): return [('--generate-code arch=compute_{0},code=sm_{0} ' '--generate-code arch=compute_{0},code=compute_{0}').format(s) for s in arch_list] depends_on('cuda', when='+cuda') # CUDA version vs Architecture # https://en.wikipedia.org/wiki/CUDA#GPUs_supported # https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#deprecated-features depends_on('cuda@:6.0', when='cuda_arch=10') depends_on('cuda@:6.5', when='cuda_arch=11') depends_on('[email protected]:6.5', when='cuda_arch=12') depends_on('[email protected]:6.5', when='cuda_arch=13') depends_on('[email protected]:8.0', when='cuda_arch=20') depends_on('[email protected]:8.0', when='cuda_arch=21') depends_on('[email protected]:10.2', when='cuda_arch=30') depends_on('[email protected]:10.2', when='cuda_arch=32') depends_on('[email protected]:', when='cuda_arch=35') depends_on('[email protected]:', when='cuda_arch=37') depends_on('[email protected]:', when='cuda_arch=50') depends_on('[email protected]:', when='cuda_arch=52') depends_on('[email protected]:', when='cuda_arch=53') depends_on('[email protected]:', when='cuda_arch=60') depends_on('[email protected]:', when='cuda_arch=61') depends_on('[email protected]:', when='cuda_arch=62') depends_on('[email protected]:', when='cuda_arch=70') depends_on('[email protected]:', when='cuda_arch=72') depends_on('[email protected]:', when='cuda_arch=75') depends_on('[email protected]:', when='cuda_arch=80') depends_on('[email protected]:', when='cuda_arch=86') # There are at least three cases to be aware of for compiler conflicts # 1. Linux x86_64 # 2. Linux ppc64le # 3. Mac OS X # CUDA-compiler conflicts are version-to-version specific and are # difficult to express with the current Spack conflict syntax # Linux x86_64 compiler conflicts from here: # https://gist.github.com/ax3l/9489132 arch_platform = ' target=x86_64: platform=linux' conflicts('%gcc@5:', when='+cuda ^cuda@:7.5' + arch_platform) conflicts('%gcc@6:', when='+cuda ^cuda@:8' + arch_platform) conflicts('%gcc@7:', when='+cuda ^cuda@:9.1' + arch_platform) conflicts('%gcc@8:', when='+cuda ^cuda@:10.0.130' + arch_platform) conflicts('%gcc@9:', when='+cuda ^cuda@:10.2.89' + arch_platform) conflicts('%gcc@:4', when='+cuda ^[email protected]:' + arch_platform) conflicts('%gcc@10:', when='+cuda ^cuda@:11.0.2' + arch_platform) conflicts('%gcc@11:', when='+cuda ^cuda@:11.1.0' + arch_platform) conflicts('%pgi@:14.8', when='+cuda ^cuda@:7.0.27' + arch_platform) conflicts('%pgi@:15.3,15.5:', when='+cuda ^[email protected]' + arch_platform) conflicts('%pgi@:16.2,16.0:16.3', when='+cuda ^cuda@8' + arch_platform) conflicts('%pgi@:15,18:', when='+cuda ^[email protected]:9.1' + arch_platform) conflicts('%pgi@:16,19:', when='+cuda ^[email protected]:10' + arch_platform) conflicts('%pgi@:17,20:', when='+cuda ^[email protected]:10.2.89' + arch_platform) conflicts('%pgi@:17,21:', when='+cuda ^[email protected]:11.1.0' + arch_platform) conflicts('%clang@:3.4', when='+cuda ^cuda@:7.5' + arch_platform) conflicts('%clang@:3.7,4:', when='+cuda ^[email protected]:9.0' + arch_platform) conflicts('%clang@:3.7,4.1:', when='+cuda ^[email protected]' + arch_platform) conflicts('%clang@:3.7,5.1:', when='+cuda ^[email protected]' + arch_platform) conflicts('%clang@:3.7,6.1:', when='+cuda ^[email protected]' + arch_platform) conflicts('%clang@:3.7,7.1:', when='+cuda ^[email protected]' + arch_platform) conflicts('%clang@:3.7,8.1:', when='+cuda ^[email protected]:10.1.243' + arch_platform) conflicts('%clang@:3.2,9:', when='+cuda ^[email protected]' + arch_platform) conflicts('%clang@:5', when='+cuda ^[email protected]:' + arch_platform) conflicts('%clang@10:', when='+cuda ^cuda@:11.0.2' + arch_platform) conflicts('%clang@11:', when='+cuda ^cuda@:11.1.0' + arch_platform) # x86_64 vs. ppc64le differ according to NVidia docs # Linux ppc64le compiler conflicts from Table from the docs below: # https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.2/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.1/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.0/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/8.0/cuda-installation-guide-linux/index.html arch_platform = ' target=ppc64le: platform=linux' # information prior to CUDA 9 difficult to find conflicts('%gcc@6:', when='+cuda ^cuda@:9' + arch_platform) conflicts('%gcc@8:', when='+cuda ^cuda@:10.0.130' + arch_platform) conflicts('%gcc@9:', when='+cuda ^cuda@:10.1.243' + arch_platform) # officially, CUDA 11.0.2 only supports the system GCC 8.3 on ppc64le conflicts('%gcc@:4', when='+cuda ^[email protected]:' + arch_platform) conflicts('%gcc@10:', when='+cuda ^cuda@:11.0.2' + arch_platform) conflicts('%gcc@11:', when='+cuda ^cuda@:11.1.0' + arch_platform) conflicts('%pgi', when='+cuda ^cuda@:8' + arch_platform) conflicts('%pgi@:16', when='+cuda ^cuda@:9.1.185' + arch_platform) conflicts('%pgi@:17', when='+cuda ^cuda@:10' + arch_platform) conflicts('%clang@4:', when='+cuda ^cuda@:9.0.176' + arch_platform) conflicts('%clang@5:', when='+cuda ^cuda@:9.1' + arch_platform) conflicts('%clang@6:', when='+cuda ^cuda@:9.2' + arch_platform) conflicts('%clang@7:', when='+cuda ^[email protected]' + arch_platform) conflicts('%[email protected]:', when='+cuda ^cuda@:10.1.105' + arch_platform) conflicts('%[email protected]:', when='+cuda ^cuda@:10.2.89' + arch_platform) conflicts('%clang@:5', when='+cuda ^[email protected]:' + arch_platform) conflicts('%clang@10:', when='+cuda ^cuda@:11.0.2' + arch_platform) conflicts('%clang@11:', when='+cuda ^cuda@:11.1.0' + arch_platform) # Intel is mostly relevant for x86_64 Linux, even though it also # exists for Mac OS X. No information prior to CUDA 3.2 or Intel 11.1 conflicts('%intel@:11.0', when='+cuda ^cuda@:3.1') conflicts('%intel@:12.0', when='+cuda ^[email protected]:') conflicts('%intel@:13.0', when='+cuda ^[email protected]:') conflicts('%intel@:13.2', when='+cuda ^[email protected]:') conflicts('%intel@:14.9', when='+cuda ^cuda@7:') # Intel 15.x is compatible with CUDA 7 thru current CUDA conflicts('%[email protected]:', when='+cuda ^cuda@:8.0.43') conflicts('%[email protected]:', when='+cuda ^cuda@:8.0.60') conflicts('%[email protected]:', when='+cuda ^cuda@:9.9') conflicts('%[email protected]:', when='+cuda ^cuda@:10.0') conflicts('%[email protected]:', when='+cuda ^cuda@:10.1') conflicts('%[email protected]:', when='+cuda ^cuda@:11.1.0') # XL is mostly relevant for ppc64le Linux conflicts('%xl@:12,14:', when='+cuda ^cuda@:9.1') conflicts('%xl@:12,14:15,17:', when='+cuda ^[email protected]') conflicts('%xl@:12,17:', when='+cuda ^cuda@:11.1.0') # Mac OS X # platform = ' platform=darwin' # Apple XCode clang vs. LLVM clang are difficult to specify # with spack syntax. Xcode clang name is `[email protected]` # which precludes ranges being specified. We have proposed # rename XCode clang to `[email protected]` or even # `[email protected] as a possible fix. # Compiler conflicts will be eventual taken from here: # https://docs.nvidia.com/cuda/cuda-installation-guide-mac-os-x/index.html#abstract conflicts('platform=darwin', when='+cuda ^[email protected]:') # Make sure cuda_arch can not be used without +cuda for value in cuda_arch_values: conflicts('~cuda', when='cuda_arch=' + value)
class CMakePackage(PackageBase): """Specialized class for packages built using CMake For more information on the CMake build system, see: https://cmake.org/cmake/help/latest/ This class provides three phases that can be overridden: 1. :py:meth:`~.CMakePackage.cmake` 2. :py:meth:`~.CMakePackage.build` 3. :py:meth:`~.CMakePackage.install` They all have sensible defaults and for many packages the only thing necessary will be to override :py:meth:`~.CMakePackage.cmake_args`. For a finer tuning you may also override: +-----------------------------------------------+--------------------+ | **Method** | **Purpose** | +===============================================+====================+ | :py:meth:`~.CMakePackage.root_cmakelists_dir` | Location of the | | | root CMakeLists.txt| +-----------------------------------------------+--------------------+ | :py:meth:`~.CMakePackage.build_directory` | Directory where to | | | build the package | +-----------------------------------------------+--------------------+ """ #: Phases of a CMake package phases = ['cmake', 'build', 'install'] #: This attribute is used in UI queries that need to know the build #: system base class build_system_class = 'CMakePackage' build_targets = [] install_targets = ['install'] build_time_test_callbacks = ['check'] #: The build system generator to use. #: #: See ``cmake --help`` for a list of valid generators. #: Currently, "Unix Makefiles" and "Ninja" are the only generators #: that Spack supports. Defaults to "Unix Makefiles". #: #: See https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html #: for more information. generator = 'Unix Makefiles' # https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html variant('build_type', default='RelWithDebInfo', description='CMake build type', values=('Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel')) depends_on('cmake', type='build') @property def archive_files(self): """Files to archive for packages based on CMake""" return [os.path.join(self.build_directory, 'CMakeCache.txt')] @property def root_cmakelists_dir(self): """The relative path to the directory containing CMakeLists.txt This path is relative to the root of the extracted tarball, not to the ``build_directory``. Defaults to the current directory. :return: directory containing CMakeLists.txt """ return self.stage.source_path @property def std_cmake_args(self): """Standard cmake arguments provided as a property for convenience of package writers :return: standard cmake arguments """ # standard CMake arguments std_cmake_args = CMakePackage._std_args(self) std_cmake_args += getattr(self, 'cmake_flag_args', []) return std_cmake_args @staticmethod def _std_args(pkg): """Computes the standard cmake arguments for a generic package""" try: generator = pkg.generator except AttributeError: generator = 'Unix Makefiles' # Make sure a valid generator was chosen valid_generators = ['Unix Makefiles', 'Ninja'] if generator not in valid_generators: msg = "Invalid CMake generator: '{0}'\n".format(generator) msg += "CMakePackage currently supports the following " msg += "generators: '{0}'".format("', '".join(valid_generators)) raise InstallError(msg) try: build_type = pkg.spec.variants['build_type'].value except KeyError: build_type = 'RelWithDebInfo' args = [ '-G', generator, '-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix), '-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type), '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON' ] if platform.mac_ver()[0]: args.extend([ '-DCMAKE_FIND_FRAMEWORK:STRING=LAST', '-DCMAKE_FIND_APPBUNDLE:STRING=LAST' ]) # Set up CMake rpath args.append('-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=FALSE') rpaths = ';'.join(spack.build_environment.get_rpaths(pkg)) args.append('-DCMAKE_INSTALL_RPATH:STRING={0}'.format(rpaths)) # CMake's find_package() looks in CMAKE_PREFIX_PATH first, help CMake # to find immediate link dependencies in right places: deps = [ d.prefix for d in pkg.spec.dependencies(deptype=('build', 'link')) ] deps = filter_system_paths(deps) args.append('-DCMAKE_PREFIX_PATH:STRING={0}'.format(';'.join(deps))) return args def flags_to_build_system_args(self, flags): """Produces a list of all command line arguments to pass the specified compiler flags to cmake. Note CMAKE does not have a cppflags option, so cppflags will be added to cflags, cxxflags, and fflags to mimic the behavior in other tools.""" # Has to be dynamic attribute due to caching setattr(self, 'cmake_flag_args', []) flag_string = '-DCMAKE_{0}_FLAGS={1}' langs = {'C': 'c', 'CXX': 'cxx', 'Fortran': 'f'} # Handle language compiler flags for lang, pre in langs.items(): flag = pre + 'flags' # cmake has no explicit cppflags support -> add it to all langs lang_flags = ' '.join( flags.get(flag, []) + flags.get('cppflags', [])) if lang_flags: self.cmake_flag_args.append( flag_string.format(lang, lang_flags)) # Cmake has different linker arguments for different build types. # We specify for each of them. if flags['ldflags']: ldflags = ' '.join(flags['ldflags']) ld_string = '-DCMAKE_{0}_LINKER_FLAGS={1}' # cmake has separate linker arguments for types of builds. for type in ['EXE', 'MODULE', 'SHARED', 'STATIC']: self.cmake_flag_args.append(ld_string.format(type, ldflags)) # CMake has libs options separated by language. Apply ours to each. if flags['ldlibs']: libs_flags = ' '.join(flags['ldlibs']) libs_string = '-DCMAKE_{0}_STANDARD_LIBRARIES={1}' for lang in langs: self.cmake_flag_args.append( libs_string.format(lang, libs_flags)) @property def build_directory(self): """Returns the directory to use when building the package :return: directory where to build the package """ return os.path.join(self.stage.source_path, 'spack-build') def cmake_args(self): """Produces a list containing all the arguments that must be passed to cmake, except: * CMAKE_INSTALL_PREFIX * CMAKE_BUILD_TYPE which will be set automatically. :return: list of arguments for cmake """ return [] def cmake(self, spec, prefix): """Runs ``cmake`` in the build directory""" options = [os.path.abspath(self.root_cmakelists_dir)] options += self.std_cmake_args options += self.cmake_args() with working_dir(self.build_directory, create=True): inspect.getmodule(self).cmake(*options) def build(self, spec, prefix): """Make the build targets""" with working_dir(self.build_directory): if self.generator == 'Unix Makefiles': inspect.getmodule(self).make(*self.build_targets) elif self.generator == 'Ninja': inspect.getmodule(self).ninja(*self.build_targets) def install(self, spec, prefix): """Make the install targets""" with working_dir(self.build_directory): if self.generator == 'Unix Makefiles': inspect.getmodule(self).make(*self.install_targets) elif self.generator == 'Ninja': inspect.getmodule(self).ninja(*self.install_targets) run_after('build')(PackageBase._run_default_build_time_test_callbacks) def check(self): """Searches the CMake-generated Makefile for the target ``test`` and runs it if found. """ with working_dir(self.build_directory): if self.generator == 'Unix Makefiles': self._if_make_target_execute('test') self._if_make_target_execute('check') elif self.generator == 'Ninja': self._if_ninja_target_execute('test') self._if_ninja_target_execute('check') # Check that self.prefix is there after installation run_after('install')(PackageBase.sanity_check_prefix)
class Cns(Package): """CNS The Crystallography & NMR System for structure calculation (1.2 for ARIA + aria patches)""" # FIXME: Add a proper url for your package's homepage here. homepage = "http://cns-online.org" url = "http://cns-online.org/download/v1.21/cns_solve_1.21_all-mp.tar.gz" read_releases('cns', version, resource) # patch to make SETFPEPS (set floating point epsilon work) # see https://ask.bioexcel.eu/t/cns-errors-before-after-recompilation/54 # main patch courtesy of Brian Smith U of Glasgow variant('configuration', default='none', description='where to find the configuration file', validator=check_config_file) variant('fp_epsilon', default=True, description='SETFPEPS required for modern compilers') variant('aria', default=True, description='patches required to run aria') resource( name='aria2.3.2', aria_url='http://aria.pasteur.fr/archives/aria2.3.2.tar.gz', sha256= 'a06e9c256bf876f8bbab244a80b9c52bbd891f14cb956d85bb3bd0312b5cd5c6', destination='.') patch('getarch_darwin_x86_64.patch', when='@1.21', sha256= '42a0d10d7684000d5c4cf1114e14d5549cc19c84b19df4d42419abd7187cf887') patch('machvar_fpeps.patch', when='@1.21+fp_epsilon', sha256= 'a00db99086c63961abe4e19d253590421973a80a9e104ac85dbcc07d472b6485') def install(self, spec, prefix): # edit cns_solve_environment to allow a build shutil.copy('cns_solve_env', 'cns_solve_env.back') filter_file(r"setenv CNS_SOLVE '_CNSsolve_location_'", f"setenv CNS_SOLVE '{self.stage.source_path}'", 'cns_solve_env') # copy over an almost right machine make file we could have got it from v1.3 but this is simpler src_file = 'instlib/machine/supported/intel-x86_64bit-linux/Makefile.header.2.gfortran' dest_file = 'instlib/machine/supported/mac-intel-darwin/Makefile.header.5.gfortran' shutil.move(src_file, dest_file) if not self.spec.satisfies('%fortran@:10.0.0'): # patch the machine make file, can't be done with a patch statement it doesn't exists till we copy it # tried just copying the file from the package directory but it caused a lockup patch = which('patch') patch_file = join_path( package_root, 'nmrpack/packages/cns', 'gfortran_10_allow_argument_mismatch.patch') patch('-p1', '-i', patch_file) if '+aria' in self.spec: from_path = pathlib.Path('aria2.3/cns/src') to_path = 'source' for target_file in from_path.iterdir(): if target_file.is_file() and target_file.suffix in ('.f', '.inc'): print(f'copying {target_file} to {to_path}') shutil.copy(target_file, to_path) if target_file.is_dir(): print(f'copying {target_file} to {to_path}') shutil.copytree(target_file, join_path(to_path, target_file.name)) shutil.copytree(from_path, 'aria2.3_patches_applied') shutil.rmtree('aria2.3') make('install') install_tree('.', prefix) with working_dir(prefix): shutil.move('cns_solve_env.back', 'cns_solve_env') replacement_env = f" setenv CNS_SOLVE '{prefix}'" filter_file(r"setenv CNS_SOLVE '_CNSsolve_location_'", replacement_env, 'cns_solve_env') # remove a leftover from our previous edits os.remove(pathlib.Path(prefix) / pathlib.Path('cns_solve_env' + '~')) @run_after('install') @on_package_attributes(run_tests=True) def test(self): try: import tempfile with tempfile.TemporaryDirectory() as tmp_dir_name: tmp_dir_name = '/tmp' test_inp = f''' stop ''' with open(join_path(tmp_dir_name, 'test.inp'), 'w') as fp: fp.write(test_inp) test_csh = f''' source {self.prefix}/cns_solve_env cns_solve < {tmp_dir_name}/test.inp >& {tmp_dir_name}/test_output.txt ''' with open(join_path(tmp_dir_name, 'test.csh'), 'w') as fp: fp.write(test_csh) csh(join(tmp_dir_name, 'test.csh')) expected = ''' ============================================================ | | | Crystallography & NMR System (CNS) | | CNSsolve | | | ============================================================ Version: 1.2 at patch level 1 Status: General release with ARIA enhancements ============================================================ '''.split("\n") expected = [line.strip() for line in expected if len(line)] ok = True result = '' with open(f"{tmp_dir_name}/test_output.txt", 'r') as file_handle: result = file_handle.readlines() result = [line.strip() for line in result if len(line)] for line in expected: if not line in result: tty.error(f'line --{line}-- not in result') ok = False break if not ok: tty.error(f'''during testing strings {expected} not found in test output") ''') tty.error("") tty.error(f" output was") tty.error("") for line in result: tty.error(line.strip()) except Exception as e: tty.error('there was an error', e) def setup_run_environment(self, env): environment_changes = get_environment_change(self.prefix, CNS_SOLVE_ENV) # print('** environment_changes **', environment_changes) # for name, type, value in environment_changes: if type == PREPEND: env.prepend_path(name, value) elif type == NEW: env.set(name, value) else: raise Exception(f'unexpected change type {type}')
class MesonPackage(PackageBase): """Specialized class for packages built using Meson For more information on the Meson build system, see: https://mesonbuild.com/ This class provides three phases that can be overridden: 1. :py:meth:`~.MesonPackage.meson` 2. :py:meth:`~.MesonPackage.build` 3. :py:meth:`~.MesonPackage.install` They all have sensible defaults and for many packages the only thing necessary will be to override :py:meth:`~.MesonPackage.meson_args`. For a finer tuning you may also override: +-----------------------------------------------+--------------------+ | **Method** | **Purpose** | +===============================================+====================+ | :py:meth:`~.MesonPackage.root_mesonlists_dir` | Location of the | | | root MesonLists.txt| +-----------------------------------------------+--------------------+ | :py:meth:`~.MesonPackage.build_directory` | Directory where to | | | build the package | +-----------------------------------------------+--------------------+ """ #: Phases of a Meson package phases = ['meson', 'build', 'install'] #: This attribute is used in UI queries that need to know the build #: system base class build_system_class = 'MesonPackage' build_targets = [] # type: List[str] install_targets = ['install'] build_time_test_callbacks = ['check'] variant('buildtype', default='debugoptimized', description='Meson build type', values=('plain', 'debug', 'debugoptimized', 'release', 'minsize')) variant('default_library', default='shared', description=' Default library type', values=('shared', 'static', 'both')) variant('strip', default=False, description='Strip targets on install') depends_on('meson', type='build') depends_on('ninja', type='build') @property def archive_files(self): """Files to archive for packages based on Meson""" return [os.path.join(self.build_directory, 'meson-logs/meson-log.txt')] @property def root_mesonlists_dir(self): """The relative path to the directory containing meson.build This path is relative to the root of the extracted tarball, not to the ``build_directory``. Defaults to the current directory. :return: directory containing meson.build """ return self.stage.source_path @property def std_meson_args(self): """Standard meson arguments provided as a property for convenience of package writers :return: standard meson arguments """ # standard Meson arguments std_meson_args = MesonPackage._std_args(self) std_meson_args += getattr(self, 'meson_flag_args', []) return std_meson_args @staticmethod def _std_args(pkg): """Computes the standard meson arguments for a generic package""" try: build_type = pkg.spec.variants['buildtype'].value except KeyError: build_type = 'release' strip = 'true' if '+strip' in pkg.spec else 'false' try: default_library = pkg.spec.variants['default_library'].value except KeyError: default_library = 'shared' args = [ '--prefix={0}'.format(pkg.prefix), # If we do not specify libdir explicitly, Meson chooses something # like lib/x86_64-linux-gnu, which causes problems when trying to # find libraries and pkg-config files. # See https://github.com/mesonbuild/meson/issues/2197 '--libdir={0}'.format(pkg.prefix.lib), '-Dbuildtype={0}'.format(build_type), '-Dstrip={0}'.format(strip), '-Ddefault_library={0}'.format(default_library) ] return args def flags_to_build_system_args(self, flags): """Produces a list of all command line arguments to pass the specified compiler flags to meson.""" # Has to be dynamic attribute due to caching setattr(self, 'meson_flag_args', []) @property def build_directory(self): """Returns the directory to use when building the package :return: directory where to build the package """ return os.path.join(self.stage.source_path, 'spack-build') def meson_args(self): """Produces a list containing all the arguments that must be passed to meson, except: * ``--prefix`` * ``--libdir`` * ``--buildtype`` * ``--strip`` * ``--default_library`` which will be set automatically. :return: list of arguments for meson """ return [] def meson(self, spec, prefix): """Runs ``meson`` in the build directory""" options = [os.path.abspath(self.root_mesonlists_dir)] options += self.std_meson_args options += self.meson_args() with working_dir(self.build_directory, create=True): inspect.getmodule(self).meson(*options) def build(self, spec, prefix): """Make the build targets""" options = ['-v'] options += self.build_targets with working_dir(self.build_directory): inspect.getmodule(self).ninja(*options) def install(self, spec, prefix): """Make the install targets""" with working_dir(self.build_directory): inspect.getmodule(self).ninja(*self.install_targets) run_after('build')(PackageBase._run_default_build_time_test_callbacks) def check(self): """Searches the Meson-generated file for the target ``test`` and runs it if found. """ with working_dir(self.build_directory): self._if_ninja_target_execute('test') self._if_ninja_target_execute('check') # Check that self.prefix is there after installation run_after('install')(PackageBase.sanity_check_prefix)
class Genie(Package): # Genie doesn"t use Autotools """Genie is a neutrino Monte Carlo Generator.""" homepage = "https://www.genie-mc.org" url = "https://github.com/GENIE-MC/Generator/archive/R-3_00_06.tar.gz" git = "https://github.com/GENIE-MC/Generator.git" tags = ["neutrino", "hep"] maintainers = [ # maintainer of this recipe, not affliated with the GENIE collaboration "davehadley", ] version("master", branch="master") version("3.0.6", sha256= "ab56ea85d0c1d09029254365bfe75a1427effa717389753b9e0c1b6c2eaa5eaf") version("3.0.4", sha256= "53f034618fef9f7f0e17d1c4ed72743e4bba590e824b795177a1a8a8486c861e") version("3.0.2", sha256= "34d6c37017b2387c781aea7bc727a0aac0ef45d6b3f3982cc6f3fc82493f65c3") version("3.0.0", sha256= "3953c7d9f1f832dd32dfbc0b9260be59431206c204aec6ab0aa68c01176f2ae6") version("2.12.10", sha256= "c8762db3dcc490f80f8a61268f5b964d4d35b80134b622e89fe2307a836f2a0b") version("2.12.8", sha256= "7ca169a8d9eda7267d28b76b2f3110552852f8eeae263a03cd5139caacebb4ea") version("2.12.6", sha256= "3b450c609875459798ec98e12cf671cc971cbb13345af6d75bd6278d422f3309") version("2.12.4", sha256= "19a4a1633b0847a9f16a44e0c74b9c224ca3bb93975aecf108603c22e807517b") version("2.12.2", sha256= "cbdc45a739878940dadcaaed575b5cad6b5e7035f29605045b1ca557e6faa6d1") version("2.12.0", sha256= "d2b01c80f38d269cb0296b3f2932798ef3f1d51bd130e81274fbfeeb381fac6b") version("2.11.2", sha256= "0f4c25d8ceb7513553671643c9cdac5aa98c40fc8594a5ecb25c077c6b36166e") version("2.11.0", sha256= "1ebe0eb65d797595413632f1cec1cb2621cb8e8d0384a2843799724a79b1d80c") version("2.10.10", sha256= "1dfaadcf1bbaf6e164b612f410c4399301e63497ad6a4891706b1787ac11a7a1") version("2.10.8", sha256= "4f6f5af2062e7c505b76e70547ac2ae304a9790c3e9b9592818d8aebeebc8398") version("2.10.6", sha256= "d00b4288c886f81459fb2967e539f30315d4385f82d1d3f4330298d313f9a176") version("2.10.4", sha256= "df909bf7e1a789ca01794995687da2af803769f0823273a4a3a31678d6d5b0f1") version("2.10.2", sha256= "6abe4e0cdb5e8f5beddf0ccdbebc94c175a9f72592b1cbbffe01b88ee3972bf9") version("2.10.0", sha256= "17bda900c996b6f4f10a7f6a3be94e56c3b8dcdeb2ef8865ca7f20c5fe725291") version("2.9.0", sha256= "8229beb73f65f5af86a77bf141acfbe4a8b68cba9d797aae083a929906f6f2a2") version("2.8.6", sha256= "310dc8e0d17a65e6b9773e398250703a3a6f94ceafe94f599ae0f7b3fecf7e6c") depends_on("root+pythia6") depends_on("pythia6") depends_on("lhapdf", when="@3:") depends_on("lhapdf5", when="@:2") depends_on("log4cpp") depends_on("libxml2") depends_on("gsl") # GENIE does not actually require cmake, but root does. # Spack's concretizer fails with "unsatisfiable constraint" if we don't add this. depends_on("cmake@3:") # GENIE Makefile's think that the spack compiler is invalid. # Disables this check. patch("genie_disable_gopt_with_compiler_check.patch", level=0, when="@2.11:") # Flags for GENIE"s optional but disabled by default features variant( "atmo", default=False, description="Enable GENIE Atmospheric neutrino event generation app") variant( "fnal", default=False, description="Enables FNAL experiment-specific event generation app") variant("nucleondecay", default=False, description="Enable GENIE Nucleon decay event generation app") variant("masterclass", default=False, description="Enable GENIE neutrino masterclass app") variant("t2k", default=False, description="Enable T2K-specific generation app") variant( "vleextension", default=False, description="Enable GENIE very low energy (1 MeV - 100 MeV) extension") phases = ["configure", "build", "install"] def url_for_version(self, version): url = "https://github.com/GENIE-MC/Generator/archive/R-{0}.tar.gz" if version >= Version(3): return url.format("{0}_{1:02d}_{2:02d}".format(*version)) else: return url.format(version.underscored) def setup_build_environment(self, env): env.set("GENIE", self.stage.source_path) return super(Genie, self).setup_build_environment(env) def setup_run_environment(self, env): env.set("GENIE", self.prefix) return super(Genie, self).setup_run_environment(env) def configure(self, spec, prefix): configure = Executable("./configure") args = self._configure_args(spec, prefix) configure(*args) def build(self, spec, prefix): # parallel build is not supported on GENIE 2 self._make(parallel=spec.satisfies("@3:")) def install(self, spec, prefix): # GENIE make install does not support parallel jobs self._make("install", parallel=False) # GENIE requires these files to be present at runtime, but doesn"t install them # so we must install them ourselves # install_tree function is injected into scope by spack build_environment.py install_tree("config", os.sep.join((prefix, "config"))) install_tree("data", os.sep.join((prefix, "data"))) def _configure_args(self, spec, prefix): args = [ "--prefix=" + prefix, "--with-compiler=" + os.environ["CC"], "--with-libxml2-inc={0}{1}libxml2".format( spec["libxml2"].prefix.include, os.sep), "--with-libxml2-lib=" + spec["libxml2"].prefix.lib, "--with-log4cpp-inc=" + spec["log4cpp"].prefix.include, "--with-log4cpp-lib=" + spec["log4cpp"].prefix.lib, "--with-pythia6-lib=" + spec["pythia6"].prefix.lib, ] if self.spec.satisfies("@:2"): args += [ "--enable-lhapdf", "--with-lhapdf-inc=" + spec["lhapdf5"].prefix.include, "--with-lhapdf-lib=" + spec["lhapdf5"].prefix.lib, # must be enabled or some GENIE 2 versions fail to link # this option was removed in GENIE 3 "--enable-rwght", ] else: args += [ "--enable-lhapdf6", "--with-lhapdf6-inc=" + spec["lhapdf"].prefix.include, "--with-lhapdf6-lib=" + spec["lhapdf"].prefix.lib, ] if "+vleextension" in self.spec: args += ["--enable-vle-extension"] if "+t2k" in self.spec: args += ["--enable-t2k"] if "+fnal" in self.spec: args += ["--enable-fnal"] if "+atmo" in self.spec: args += ["--enable-atmo"] if "+nucleondecay" in self.spec: args += ["--enable-nucleon-decay"] if "+masterclass" in self.spec: args += ["--enable-masterclass"] return args def _make(self, *args, **kwargs): parallel = kwargs.get("parallel", False) args = list(self._make_args) + list(args) # make function is injected into scope by spack build_environment.py make(*args, parallel=parallel) @property def _make_args(self): return [ "CC=c++", "CXX=c++", "LD=c++", ]
class CudaPackage(PackageBase): """Auxiliary class which contains CUDA variant, dependencies and conflicts and is meant to unify and facilitate its usage. Maintainers: ax3l, Rombur """ # https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list # https://developer.nvidia.com/cuda-gpus # https://en.wikipedia.org/wiki/CUDA#GPUs_supported cuda_arch_values = ('10', '11', '12', '13', '20', '21', '30', '32', '35', '37', '50', '52', '53', '60', '61', '62', '70', '72', '75', '80', '86') # FIXME: keep cuda and cuda_arch separate to make usage easier until # Spack has depends_on(cuda, when='cuda_arch!=None') or alike variant('cuda', default=False, description='Build with CUDA') variant('cuda_arch', description='CUDA architecture', values=spack.variant.any_combination_of(*cuda_arch_values)) # https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#nvcc-examples # https://llvm.org/docs/CompileCudaWithLLVM.html#compiling-cuda-code @staticmethod def cuda_flags(arch_list): return [('--generate-code arch=compute_{0},code=sm_{0} ' '--generate-code arch=compute_{0},code=compute_{0}').format(s) for s in arch_list] depends_on('cuda', when='+cuda') # CUDA version vs Architecture # https://en.wikipedia.org/wiki/CUDA#GPUs_supported # https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#deprecated-features depends_on('cuda@:6.0', when='cuda_arch=10') depends_on('cuda@:6.5', when='cuda_arch=11') depends_on('[email protected]:6.5', when='cuda_arch=12') depends_on('[email protected]:6.5', when='cuda_arch=13') depends_on('[email protected]:8.0', when='cuda_arch=20') depends_on('[email protected]:8.0', when='cuda_arch=21') depends_on('[email protected]:10.2', when='cuda_arch=30') depends_on('[email protected]:10.2', when='cuda_arch=32') depends_on('[email protected]:', when='cuda_arch=35') depends_on('[email protected]:', when='cuda_arch=37') depends_on('[email protected]:', when='cuda_arch=50') depends_on('[email protected]:', when='cuda_arch=52') depends_on('[email protected]:', when='cuda_arch=53') depends_on('[email protected]:', when='cuda_arch=60') depends_on('[email protected]:', when='cuda_arch=61') depends_on('[email protected]:', when='cuda_arch=62') depends_on('[email protected]:', when='cuda_arch=70') depends_on('[email protected]:', when='cuda_arch=72') depends_on('[email protected]:', when='cuda_arch=75') depends_on('[email protected]:', when='cuda_arch=80') depends_on('[email protected]:', when='cuda_arch=86') # From the NVIDIA install guide we know of conflicts for particular # platforms (linux, darwin), architectures (x86, powerpc) and compilers # (gcc, clang). We don't restrict %gcc and %clang conflicts to # platform=linux, since they should also apply to platform=cray, and may # apply to platform=darwin. We currently do not provide conflicts for # platform=darwin with %apple-clang. # Linux x86_64 compiler conflicts from here: # https://gist.github.com/ax3l/9489132 conflicts('%gcc@5:', when='+cuda ^cuda@:7.5 target=x86_64:') conflicts('%gcc@6:', when='+cuda ^cuda@:8 target=x86_64:') conflicts('%gcc@7:', when='+cuda ^cuda@:9.1 target=x86_64:') conflicts('%gcc@8:', when='+cuda ^cuda@:10.0.130 target=x86_64:') conflicts('%gcc@9:', when='+cuda ^cuda@:10.2.89 target=x86_64:') conflicts('%gcc@:4', when='+cuda ^[email protected]: target=x86_64:') conflicts('%gcc@10:', when='+cuda ^cuda@:11.0.3 target=x86_64:') conflicts('%gcc@11:', when='+cuda ^cuda@:11.1.0 target=x86_64:') conflicts('%pgi@:14.8', when='+cuda ^cuda@:7.0.27 target=x86_64:') conflicts('%pgi@:15.3,15.5:', when='+cuda ^[email protected] target=x86_64:') conflicts('%pgi@:16.2,16.0:16.3', when='+cuda ^cuda@8 target=x86_64:') conflicts('%pgi@:15,18:', when='+cuda ^[email protected]:9.1 target=x86_64:') conflicts('%pgi@:16,19:', when='+cuda ^[email protected]:10 target=x86_64:') conflicts('%pgi@:17,20:', when='+cuda ^[email protected]:10.2.89 target=x86_64:') conflicts('%pgi@:17,21:', when='+cuda ^[email protected]:11.1.0 target=x86_64:') conflicts('%clang@:3.4', when='+cuda ^cuda@:7.5 target=x86_64:') conflicts('%clang@:3.7,4:', when='+cuda ^[email protected]:9.0 target=x86_64:') conflicts('%clang@:3.7,4.1:', when='+cuda ^[email protected] target=x86_64:') conflicts('%clang@:3.7,5.1:', when='+cuda ^[email protected] target=x86_64:') conflicts('%clang@:3.7,6.1:', when='+cuda ^[email protected] target=x86_64:') conflicts('%clang@:3.7,7.1:', when='+cuda ^[email protected] target=x86_64:') conflicts('%clang@:3.7,8.1:', when='+cuda ^[email protected]:10.1.243 target=x86_64:') conflicts('%clang@:3.2,9:', when='+cuda ^[email protected] target=x86_64:') conflicts('%clang@:5', when='+cuda ^[email protected]: target=x86_64:') conflicts('%clang@10:', when='+cuda ^cuda@:11.0.3 target=x86_64:') conflicts('%clang@11:', when='+cuda ^cuda@:11.1.0 target=x86_64:') # x86_64 vs. ppc64le differ according to NVidia docs # Linux ppc64le compiler conflicts from Table from the docs below: # https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.2/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.1/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.0/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/8.0/cuda-installation-guide-linux/index.html # information prior to CUDA 9 difficult to find conflicts('%gcc@6:', when='+cuda ^cuda@:9 target=ppc64le:') conflicts('%gcc@8:', when='+cuda ^cuda@:10.0.130 target=ppc64le:') conflicts('%gcc@9:', when='+cuda ^cuda@:10.1.243 target=ppc64le:') # officially, CUDA 11.0.2 only supports the system GCC 8.3 on ppc64le conflicts('%gcc@:4', when='+cuda ^[email protected]: target=ppc64le:') conflicts('%gcc@10:', when='+cuda ^cuda@:11.0.3 target=ppc64le:') conflicts('%gcc@11:', when='+cuda ^cuda@:11.1.0 target=ppc64le:') conflicts('%pgi', when='+cuda ^cuda@:8 target=ppc64le:') conflicts('%pgi@:16', when='+cuda ^cuda@:9.1.185 target=ppc64le:') conflicts('%pgi@:17', when='+cuda ^cuda@:10 target=ppc64le:') conflicts('%clang@4:', when='+cuda ^cuda@:9.0.176 target=ppc64le:') conflicts('%clang@5:', when='+cuda ^cuda@:9.1 target=ppc64le:') conflicts('%clang@6:', when='+cuda ^cuda@:9.2 target=ppc64le:') conflicts('%clang@7:', when='+cuda ^[email protected] target=ppc64le:') conflicts('%[email protected]:', when='+cuda ^cuda@:10.1.105 target=ppc64le:') conflicts('%[email protected]:', when='+cuda ^cuda@:10.2.89 target=ppc64le:') conflicts('%clang@:5', when='+cuda ^[email protected]: target=ppc64le:') conflicts('%clang@10:', when='+cuda ^cuda@:11.0.3 target=ppc64le:') conflicts('%clang@11:', when='+cuda ^cuda@:11.1.0 target=ppc64le:') # Intel is mostly relevant for x86_64 Linux, even though it also # exists for Mac OS X. No information prior to CUDA 3.2 or Intel 11.1 conflicts('%intel@:11.0', when='+cuda ^cuda@:3.1') conflicts('%intel@:12.0', when='+cuda ^[email protected]:') conflicts('%intel@:13.0', when='+cuda ^[email protected]:') conflicts('%intel@:13.2', when='+cuda ^[email protected]:') conflicts('%intel@:14.9', when='+cuda ^cuda@7:') # Intel 15.x is compatible with CUDA 7 thru current CUDA conflicts('%[email protected]:', when='+cuda ^cuda@:8.0.43') conflicts('%[email protected]:', when='+cuda ^cuda@:8.0.60') conflicts('%[email protected]:', when='+cuda ^cuda@:9.9') conflicts('%[email protected]:', when='+cuda ^cuda@:10.0') conflicts('%[email protected]:', when='+cuda ^cuda@:10.1') conflicts('%[email protected]:', when='+cuda ^cuda@:11.1.0') # XL is mostly relevant for ppc64le Linux conflicts('%xl@:12,14:', when='+cuda ^cuda@:9.1') conflicts('%xl@:12,14:15,17:', when='+cuda ^[email protected]') conflicts('%xl@:12,17:', when='+cuda ^cuda@:11.1.0') # Darwin. # TODO: add missing conflicts for %apple-clang cuda@:10 conflicts('platform=darwin', when='+cuda ^[email protected]:') # Make sure cuda_arch can not be used without +cuda for value in cuda_arch_values: conflicts('~cuda', when='cuda_arch=' + value)
class CudaPackage(PackageBase): """Auxiliary class which contains CUDA variant, dependencies and conflicts and is meant to unify and facilitate its usage. """ # FIXME: keep cuda and cuda_arch separate to make usage easier untill # Spack has depends_on(cuda, when='cuda_arch!=None') or alike variant('cuda', default=False, description='Build with CUDA') # see http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list # https://developer.nvidia.com/cuda-gpus variant('cuda_arch', description='CUDA architecture', values=spack.variant.any_combination_of( '20', '30', '32', '35', '50', '52', '53', '60', '61', '62', '70', '72', '75' )) # see http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#nvcc-examples # and http://llvm.org/docs/CompileCudaWithLLVM.html#compiling-cuda-code @staticmethod def cuda_flags(arch_list): return [('--generate-code arch=compute_{0},code=sm_{0} ' '--generate-code arch=compute_{0},code=compute_{0}').format(s) for s in arch_list] depends_on("cuda@7:", when='+cuda') # CUDA version vs Architecture depends_on("cuda@8:", when='cuda_arch=60') depends_on("cuda@8:", when='cuda_arch=61') depends_on("cuda@8:", when='cuda_arch=62') depends_on("cuda@9:", when='cuda_arch=70') depends_on("cuda@9:", when='cuda_arch=72') depends_on("cuda@10:", when='cuda_arch=75') depends_on('cuda@:8', when='cuda_arch=20') # There are at least three cases to be aware of for compiler conflicts # 1. Linux x86_64 # 2. Linux ppc64le # 3. Mac OS X # Linux x86_64 compiler conflicts from here: # https://gist.github.com/ax3l/9489132 arch_platform = ' arch=x86_64 platform=linux' conflicts('%gcc@5:', when='+cuda ^cuda@:7.5' + arch_platform) conflicts('%gcc@6:', when='+cuda ^cuda@:8' + arch_platform) conflicts('%gcc@7:', when='+cuda ^cuda@:9.1' + arch_platform) conflicts('%gcc@8:', when='+cuda ^[email protected]' + arch_platform) conflicts('%pgi@:14.8', when='+cuda ^cuda@:7.0.27' + arch_platform) conflicts('%pgi@:15.3,15.5:', when='+cuda ^[email protected]' + arch_platform) conflicts('%pgi@:16.2,16.0:16.3', when='+cuda ^cuda@8' + arch_platform) conflicts('%pgi@:15,18:', when='+cuda ^[email protected]:9.1' + arch_platform) conflicts('%pgi@:16', when='+cuda ^[email protected]:10' + arch_platform) conflicts('%clang@:3.4', when='+cuda ^cuda@:7.5' + arch_platform) conflicts('%clang@:3.7,4:', when='+cuda ^[email protected]:9.0' + arch_platform) conflicts('%clang@:3.7,4.1:', when='+cuda ^[email protected]' + arch_platform) conflicts('%clang@:3.7,5.1:', when='+cuda ^[email protected]' + arch_platform) conflicts('%clang@:3.7,6.1:', when='+cuda ^[email protected]' + arch_platform) # x86_64 vs. ppc64le differ according to NVidia docs # Linux ppc64le compiler conflicts from Table from the docs below: # https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.2/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.1/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/9.0/cuda-installation-guide-linux/index.html # https://docs.nvidia.com/cuda/archive/8.0/cuda-installation-guide-linux/index.html arch_platform = ' arch=ppc64le platform=linux' # information prior to CUDA 9 difficult to find conflicts('%gcc@6:', when='+cuda ^cuda@:9' + arch_platform) conflicts('%gcc@8:', when='+cuda ^[email protected]' + arch_platform) conflicts('%pgi', when='+cuda ^cuda@:8' + arch_platform) conflicts('%pgi@:16', when='+cuda ^cuda@:9.1.185' + arch_platform) conflicts('%pgi@:17', when='+cuda ^cuda@:10' + arch_platform) conflicts('%clang@4:', when='+cuda ^cuda@:9.0.176' + arch_platform) conflicts('%clang@5:', when='+cuda ^cuda@:9.1' + arch_platform) conflicts('%clang@6:', when='+cuda ^cuda@:9.2' + arch_platform) conflicts('%clang@7:', when='+cuda ^[email protected]' + arch_platform) # Intel is mostly relevant for x86_64 Linux, even though it also # exists for Mac OS X. conflicts('%intel@:14,16:', when='+cuda ^[email protected]') conflicts('%intel@:14,17:', when='+cuda ^[email protected]') conflicts('%intel@:14,18:', when='+cuda ^[email protected]:9.1') conflicts('%intel@17:18', when='+cuda ^[email protected]:') conflicts('%intel@19:', when='+cuda') # XL is mostly relevant for ppc64le Linux conflicts('%xl@:12,14:', when='+cuda ^cuda@:9.1') conflicts('%xl@:12,14:15,17:', when='+cuda ^[email protected]') conflicts('%xl@17:', when='+cuda ^[email protected]') # Mac OS X # platform = ' platform=darwin' # Apple XCode clang vs. LLVM clang are difficult to specify # with spack syntax. Xcode clang name is `[email protected]` # which precludes ranges being specified. We have proposed # rename XCode clang to `[email protected]` or even # `[email protected] as a possible fix. # Compiler conflicts will be eventual taken from here: # https://docs.nvidia.com/cuda/cuda-installation-guide-mac-os-x/index.html#abstract # Make sure cuda_arch can not be used without +cuda conflicts('~cuda', when='cuda_arch=20') conflicts('~cuda', when='cuda_arch=30') conflicts('~cuda', when='cuda_arch=32') conflicts('~cuda', when='cuda_arch=35') conflicts('~cuda', when='cuda_arch=50') conflicts('~cuda', when='cuda_arch=52') conflicts('~cuda', when='cuda_arch=53') conflicts('~cuda', when='cuda_arch=60') conflicts('~cuda', when='cuda_arch=61') conflicts('~cuda', when='cuda_arch=62') conflicts('~cuda', when='cuda_arch=70') conflicts('~cuda', when='cuda_arch=72') conflicts('~cuda', when='cuda_arch=75')