Added HPC Challenge Benchmark (#18323)
* HPCC Benchmark: added HPC Challenge (HPCC) benchmark * HPCC Benchmark: modified error message on lack of fftw2 interface in MKL * hpcc: fixed styling add one more installation example * hpcc: styling fix Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com> * hpcc: changed include and lib location setter Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com> * hpcc: fixed styling add one more installation example * hpcc: removed readme.md * hpcc: develop repo now is in github * hpcc: march arguments are set explicitly in case of intel compilers, added -restrict flag, which needed for older intel compilers (at least <=19.0.5.281) Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
This commit is contained in:
parent
3a5746c6c7
commit
12078382b6
207
var/spack/repos/builtin/packages/hpcc/package.py
Normal file
207
var/spack/repos/builtin/packages/hpcc/package.py
Normal file
@ -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)
|
Loading…
Reference in New Issue
Block a user