summaryrefslogtreecommitdiff
path: root/var
diff options
context:
space:
mode:
Diffstat (limited to 'var')
-rw-r--r--var/spack/repos/builtin/packages/hpcc/package.py207
1 files changed, 207 insertions, 0 deletions
diff --git a/var/spack/repos/builtin/packages/hpcc/package.py b/var/spack/repos/builtin/packages/hpcc/package.py
new file mode 100644
index 0000000000..9ca9b31dbe
--- /dev/null
+++ b/var/spack/repos/builtin/packages/hpcc/package.py
@@ -0,0 +1,207 @@
+# Copyright 2013-2020 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)
+
+from spack import *
+import os
+import re
+import platform
+
+
+class Hpcc(MakefilePackage):
+ """HPC Challenge is a benchmark suite that measures a range memory access
+ patterns.
+ The HPC Challenge benchmark consists of basically 7 tests:
+ 1) HPL - the Linpack TPP benchmark which measures the floating point
+ rate of execution for solving a linear system of equations.
+ 2) DGEMM - measures the floating point rate of execution of double
+ precision real matrix-matrix multiplication.
+ 3) STREAM - a simple synthetic benchmark program that measures
+ sustainable memory bandwidth (in GB/s) and
+ the corresponding computation rate for simple vector kernel.
+ 4) PTRANS (parallel matrix transpose) - exercises the communications
+ where pairs of processors communicate
+ with each other simultaneously. It is a useful test of the total
+ communications capacity of the network.
+ 5) RandomAccess - measures the rate of integer random updates of memory
+ (GUPS).
+ 6) FFT - measures the floating point rate of execution of double
+ precision complex one-dimensional Discrete Fourier Transform (DFT).
+ 7) Communication bandwidth and latency - a set of tests to measure
+ latency and bandwidth of a number of simultaneous communication
+ patterns; based on b_eff (effective bandwidth benchmark)."""
+
+ homepage = "http://icl.cs.utk.edu/hpcc"
+ url = "http://icl.cs.utk.edu/projectsfiles/hpcc/download/hpcc-1.5.0.tar.gz"
+ git = "https://github.com/icl-utk-edu/hpcc.git"
+
+ version('develop', branch='main')
+ version('1.5.0', sha256='0a6fef7ab9f3347e549fed65ebb98234feea9ee18aea0c8f59baefbe3cf7ffb8')
+
+ variant(
+ 'fft', default='internal', description='FFT library to use',
+ values=('internal', 'fftw2', 'mkl'), multi=False
+ )
+
+ depends_on('gmake', type='build')
+ depends_on('mpi@1.1:')
+ depends_on('blas')
+ depends_on('fftw-api@2+mpi', when='fft=fftw2')
+ depends_on('mkl', when='fft=mkl')
+
+ arch = '{0}-{1}'.format(platform.system(), platform.processor())
+
+ config = {
+ '@SHELL@': '/bin/sh',
+ '@CD@': 'cd',
+ '@CP@': 'cp',
+ '@LN_S@': 'ln -s',
+ '@MKDIR@': 'mkdir',
+ '@RM@': '/bin/rm -f',
+ '@TOUCH@': 'touch',
+ '@ARCHIVER@': 'ar',
+ '@ARFLAGS@': 'r',
+ '@RANLIB@': 'echo',
+ '@ARCH@': arch,
+ '@MPDIR@': '',
+ '@MPINC@': '',
+ '@MPLIB@': '',
+ '@F2CDEFS@': '-DAdd_ -DF77_INTEGER=int -DStringSunStyle',
+ '@LADIR@': '',
+ '@LAINC@': '',
+ '@LALIB@': '',
+ '@CC@': None,
+ '@CCNOOPT@': '',
+ '@CCFLAGS@': '-O3',
+ '@LINKER@': '$(CC)',
+ '@LINKFLAGS@': ''
+ }
+
+ def patch(self):
+ if 'fftw' in self.spec:
+ # spack's fftw2 prefix headers with floating point type
+ filter_file(r"^\s*#include <fftw.h>", "#include <sfftw.h>",
+ "FFT/wrapfftw.h")
+ filter_file(r"^\s*#include <fftw_mpi.h>", "#include <sfftw_mpi.h>",
+ "FFT/wrapmpifftw.h")
+
+ def _write_make_arch(self, spec, prefix):
+ """write make.arch file"""
+ with working_dir('hpl'):
+ # copy template make.arch file
+ make_arch_filename = 'Make.{0}'.format(self.arch)
+ copy(join_path('setup', 'Make.UNKNOWN.in'), make_arch_filename)
+
+ # fill template with values
+ make_arch = FileFilter(make_arch_filename)
+ for k, v in self.config.items():
+ make_arch.filter(k, v)
+
+ def edit(self, spec, prefix):
+ # Message Passing library (MPI)
+ self.config['@MPINC@'] = spec['mpi'].headers.include_flags
+ self.config['@MPLIB@'] = spec['mpi'].libs.search_flags
+
+ lin_alg_libs = []
+ # FFT
+ if self.spec.variants['fft'].value in ('fftw2', 'mkl'):
+ self.config['@LAINC@'] += ' -DUSING_FFTW'
+
+ if self.spec.variants['fft'].value == 'fftw2':
+ self.config['@LAINC@'] += \
+ spec['fftw-api'].headers.include_flags
+ # fftw does not set up libs for version 2
+ lin_alg_libs.append(
+ join_path(spec['fftw-api'].prefix.lib, 'libsfftw_mpi.so'))
+ lin_alg_libs.append(
+ join_path(spec['fftw-api'].prefix.lib, 'libsfftw.so'))
+
+ elif self.spec.variants['fft'].value == 'mkl' and '^mkl' in spec:
+ mklroot = env['MKLROOT']
+ self.config['@LAINC@'] += \
+ ' -I{0}'.format(join_path(mklroot, 'include/fftw'))
+ libfftw2x_cdft = join_path(
+ mklroot, 'lib', 'intel64', 'libfftw2x_cdft_DOUBLE_ilp64.a')
+ libfftw2xc = join_path(
+ mklroot, 'lib', 'intel64', 'libfftw2xc_double_intel.a')
+ if not (os.path.exists(libfftw2x_cdft) and
+ os.path.exists(libfftw2xc)):
+ raise InstallError(
+ "HPCC need fftw2 interface, "
+ "here are brief notes how to make one:\n"
+ "# make fftw2x_cdft interface to mkl\n"
+ "cd $MKLROOT/interfaces/fftw2x_cdft\n"
+ "make libintel64 PRECISION=MKL_DOUBLE "
+ "interface=ilp64 MKLROOT=$MKLROOT\n"
+ "\n"
+ "# make FFTW C wrapper library\n"
+ "cd $MKLROOT/interfaces/fftw2xc\n"
+ "make libintel64 PRECISION=MKL_DOUBLE "
+ "MKLROOT=$MKLROOT\n")
+ lin_alg_libs.append(libfftw2xc)
+ lin_alg_libs.append(libfftw2x_cdft)
+
+ # Linear Algebra library (BLAS or VSIPL)
+ self.config['@LAINC@'] = spec['blas'].headers.include_flags
+ lin_alg_libs = lin_alg_libs + [
+ lib for lib in spec['blas'].libs if lib not in lin_alg_libs]
+
+ # pack all LA/FFT libraries
+ self.config['@LALIB@'] = ' '.join(lin_alg_libs)
+
+ # Compilers / linkers - Optimization flags
+ self.config['@CC@'] = '{0}'.format(spec['mpi'].mpicc)
+
+ # Compiler flags for CPU architecture optimizations
+ if spec.satisfies('%intel'):
+ # with intel-parallel-studio+mpi the '-march' arguments
+ # are not passed to icc
+ arch_opt = spec.target.optimization_flags(
+ spec.compiler.name, spec.compiler.version)
+ self.config['@CCFLAGS@'] = \
+ '-O3 -restrict -ansi-alias -ip {0}'.format(arch_opt)
+ self.config['@CCNOOPT@'] = '-restrict'
+ self._write_make_arch(spec, prefix)
+
+ def build(self, spec, prefix):
+ make('arch={0}'.format(self.arch))
+
+ def check(self):
+ """Simple check that compiled binary is working:
+ launch with 4 MPI processes and check that test finished."""
+ # copy input
+ copy('_hpccinf.txt', 'hpccinf.txt')
+ # run test
+ run = Executable(
+ join_path(os.path.dirname(self.spec['mpi'].mpicc), 'mpirun'))
+ run('-np', '4', './hpcc')
+ # check output
+ hpccoutf = open('hpccoutf.txt', 'rt').read()
+ if not re.search("End of HPC Challenge tests", hpccoutf):
+ raise Exception("Test run was not successfull!")
+
+ def installcheck(self):
+ """Same as check but within prefix location"""
+ with working_dir(self.prefix.share.hpcc):
+ # run test
+ run = Executable(
+ join_path(os.path.dirname(self.spec['mpi'].mpicc), 'mpirun'))
+ run('-np', '4', self.prefix.bin.hpcc)
+ # check output
+ hpccoutf = open('hpccoutf.txt', 'rt').read()
+ if not re.search("End of HPC Challenge tests", hpccoutf):
+ raise Exception("Test run was not successfull!")
+
+ def install(self, spec, prefix):
+ # copy executable
+ mkdirp(self.prefix.bin)
+ install('hpcc', prefix.bin)
+ # copy input example
+ mkdirp(self.prefix.share.hpcc)
+ install('_hpccinf.txt',
+ join_path(self.prefix.share.hpcc, 'hpccinf.txt'))
+ # copy documentation
+ mkdirp(self.prefix.doc.hpcc)
+ install('README.html', self.prefix.doc.hpcc)
+ install('README.txt', self.prefix.doc.hpcc)