fftw: simplify the recipe and make use of specific targets (#12889)
* fftw: grouped precisions in a single variant * fftw: simd options are now based on target features and not on variants * fftw: simplified computing the selected precisions
This commit is contained in:
parent
46e319ecd4
commit
2cd800306d
1 changed files with 68 additions and 123 deletions
|
@ -3,12 +3,12 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
from spack import *
|
import os
|
||||||
from spack.spec import ConflictsInSpecError
|
import os.path
|
||||||
|
|
||||||
import llnl.util.lang
|
import llnl.util.lang
|
||||||
# os is used for rename, etc in patch()
|
|
||||||
import os
|
from spack import *
|
||||||
|
|
||||||
|
|
||||||
class Fftw(AutotoolsPackage):
|
class Fftw(AutotoolsPackage):
|
||||||
|
@ -20,7 +20,7 @@ class Fftw(AutotoolsPackage):
|
||||||
library of choice for most applications."""
|
library of choice for most applications."""
|
||||||
|
|
||||||
homepage = "http://www.fftw.org"
|
homepage = "http://www.fftw.org"
|
||||||
url = "http://www.fftw.org/fftw-3.3.4.tar.gz"
|
url = "http://www.fftw.org/fftw-3.3.4.tar.gz"
|
||||||
list_url = "http://www.fftw.org/download.html"
|
list_url = "http://www.fftw.org/download.html"
|
||||||
|
|
||||||
version('3.3.8', '8aac833c943d8e90d51b697b27d4384d')
|
version('3.3.8', '8aac833c943d8e90d51b697b27d4384d')
|
||||||
|
@ -35,84 +35,32 @@ class Fftw(AutotoolsPackage):
|
||||||
patch('pgi-3.3.6-pl2.patch', when="@3.3.6-pl2%pgi", level=0)
|
patch('pgi-3.3.6-pl2.patch', when="@3.3.6-pl2%pgi", level=0)
|
||||||
|
|
||||||
variant(
|
variant(
|
||||||
'float', default=True,
|
'precision', values=any_combination_of(
|
||||||
description='Produces a single precision version of the library')
|
'float', 'double', 'long_double', 'quad'
|
||||||
variant(
|
).prohibit_empty_set().with_default('float,double'),
|
||||||
'double', default=True,
|
description='Build the selected floating-point precision libraries'
|
||||||
description='Produces a double precision version of the library')
|
)
|
||||||
variant(
|
|
||||||
'long_double', default=True,
|
|
||||||
description='Produces a long double precision version of the library')
|
|
||||||
variant(
|
|
||||||
'quad', default=False,
|
|
||||||
description='Produces a quad precision version of the library '
|
|
||||||
'(works only with GCC and libquadmath)')
|
|
||||||
variant('openmp', default=False, description="Enable OpenMP support.")
|
variant('openmp', default=False, description="Enable OpenMP support.")
|
||||||
variant('mpi', default=True, description='Activate MPI support')
|
variant('mpi', default=True, description='Activate MPI support')
|
||||||
variant(
|
variant(
|
||||||
'pfft_patches', default=False,
|
'pfft_patches', default=False,
|
||||||
description='Add extra transpose functions for PFFT compatibility')
|
description='Add extra transpose functions for PFFT compatibility')
|
||||||
|
|
||||||
variant(
|
|
||||||
'simd',
|
|
||||||
default='generic-simd128,generic-simd256',
|
|
||||||
values=(
|
|
||||||
'sse', 'sse2', 'avx', 'avx2', 'avx512', # Intel
|
|
||||||
'avx-128-fma', 'kcvi', # Intel
|
|
||||||
'altivec', 'vsx', # IBM
|
|
||||||
'neon', # ARM
|
|
||||||
'generic-simd128', 'generic-simd256' # Generic
|
|
||||||
),
|
|
||||||
description='Optimizations that are enabled in this build',
|
|
||||||
multi=True
|
|
||||||
)
|
|
||||||
variant('fma', default=False, description='Activate support for fma')
|
|
||||||
|
|
||||||
depends_on('mpi', when='+mpi')
|
depends_on('mpi', when='+mpi')
|
||||||
depends_on('automake', type='build', when='+pfft_patches')
|
depends_on('automake', type='build', when='+pfft_patches')
|
||||||
depends_on('autoconf', type='build', when='+pfft_patches')
|
depends_on('autoconf', type='build', when='+pfft_patches')
|
||||||
depends_on('libtool', type='build', when='+pfft_patches')
|
depends_on('libtool', type='build', when='+pfft_patches')
|
||||||
|
|
||||||
# https://github.com/FFTW/fftw3/commit/902d0982522cdf6f0acd60f01f59203824e8e6f3
|
# https://github.com/FFTW/fftw3/commit/902d0982522cdf6f0acd60f01f59203824e8e6f3
|
||||||
conflicts('%gcc@8:8.9999', when="@3.3.7")
|
conflicts('%gcc@8:8.9999', when="@3.3.7")
|
||||||
|
conflicts('precision=long_double', when='@2.1.5',
|
||||||
|
msg='Long double precision is not supported in FFTW 2')
|
||||||
|
conflicts('precision=quad', when='@2.1.5',
|
||||||
|
msg='Quad precision is not supported in FFTW 2')
|
||||||
|
|
||||||
provides('fftw-api@2', when='@2.1.5')
|
provides('fftw-api@2', when='@2.1.5')
|
||||||
provides('fftw-api@3', when='@3:')
|
provides('fftw-api@3', when='@3:')
|
||||||
|
|
||||||
def flag_handler(self, name, flags):
|
|
||||||
arch = ""
|
|
||||||
spec = self.spec
|
|
||||||
target_simds = {
|
|
||||||
('x86_64',): ('sse', 'sse2', 'avx', 'avx2', 'avx512',
|
|
||||||
'avx-128-fma', 'kcvi'),
|
|
||||||
('ppc', 'ppc64le', 'power7'): ('altivec', 'vsx'),
|
|
||||||
('arm',): ('neon',)
|
|
||||||
}
|
|
||||||
|
|
||||||
if spec.satisfies("platform=cray"):
|
|
||||||
# FIXME; It is assumed that cray is x86_64.
|
|
||||||
# If you support arm on cray, you need to fix it.
|
|
||||||
arch = "x86_64"
|
|
||||||
|
|
||||||
for targets, simds in target_simds.items():
|
|
||||||
if (
|
|
||||||
(arch not in targets)
|
|
||||||
and str(spec.target.family) not in targets
|
|
||||||
):
|
|
||||||
if any(spec.satisfies('simd={0}'.format(x)) for x in simds):
|
|
||||||
raise ConflictsInSpecError(
|
|
||||||
spec,
|
|
||||||
[(
|
|
||||||
spec,
|
|
||||||
spec.architecture.target,
|
|
||||||
spec.variants['simd'],
|
|
||||||
'simd={0} are valid only on {1}'.format(
|
|
||||||
','.join(target_simds[targets]),
|
|
||||||
','.join(targets)
|
|
||||||
)
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
return (flags, None, None)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def libs(self):
|
def libs(self):
|
||||||
|
|
||||||
|
@ -157,6 +105,11 @@ def autoreconf(self, spec, prefix):
|
||||||
autoreconf = which('autoreconf')
|
autoreconf = which('autoreconf')
|
||||||
autoreconf('-ifv')
|
autoreconf('-ifv')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def selected_precisions(self):
|
||||||
|
"""Precisions that have been selected in this build"""
|
||||||
|
return self.spec.variants['precision'].value
|
||||||
|
|
||||||
def configure(self, spec, prefix):
|
def configure(self, spec, prefix):
|
||||||
# Base options
|
# Base options
|
||||||
options = [
|
options = [
|
||||||
|
@ -184,68 +137,60 @@ def configure(self, spec, prefix):
|
||||||
if '+mpi' in spec:
|
if '+mpi' in spec:
|
||||||
options.append('--enable-mpi')
|
options.append('--enable-mpi')
|
||||||
|
|
||||||
# SIMD support
|
# Specific SIMD support. Note there's SSE support too for float, but
|
||||||
float_options, double_options = [], []
|
# given that it can be activated only for float and that most machines
|
||||||
if spec.satisfies('@3:', strict=True):
|
# are new enough to have SSE2 it has been skipped not to complicate the
|
||||||
for opts in (float_options, double_options):
|
# recipe further.
|
||||||
opts += self.enable_or_disable('simd')
|
simd_features = ['sse2', 'avx', 'avx2', 'avx512', 'avx-128-fma',
|
||||||
opts += self.enable_or_disable('fma')
|
'kcvi', 'altivec', 'vsx', 'neon']
|
||||||
|
simd_options = []
|
||||||
|
for feature in simd_features:
|
||||||
|
msg = '--enable-{0}' if feature in spec.target else '--disable-{0}'
|
||||||
|
simd_options.append(msg.format(feature))
|
||||||
|
|
||||||
|
# If no features are found, enable the generic ones
|
||||||
|
if not any(f in spec.target for f in simd_features):
|
||||||
|
simd_options += [
|
||||||
|
'--enable-generic-simd128',
|
||||||
|
'--enable-generic-simd256'
|
||||||
|
]
|
||||||
|
|
||||||
|
simd_options += [
|
||||||
|
'--enable-fma' if 'fma' in spec.target else '--disable-fma'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Double is the default precision, for all the others we need
|
||||||
|
# to enable the corresponding option.
|
||||||
|
enable_precision = {
|
||||||
|
'float': ['--enable-float'],
|
||||||
|
'double': None,
|
||||||
|
'long_double': ['--enable-long-double'],
|
||||||
|
'quad': ['--enable-quad-precision']
|
||||||
|
}
|
||||||
|
|
||||||
|
# Different precisions must be configured and compiled one at a time
|
||||||
configure = Executable('../configure')
|
configure = Executable('../configure')
|
||||||
|
for precision in self.selected_precisions:
|
||||||
|
opts = (enable_precision[precision] or []) + options[:]
|
||||||
|
|
||||||
# Build double/float/long double/quad variants
|
# SIMD optimizations are available only for float and double
|
||||||
if '+double' in spec:
|
# starting from FFTW 3
|
||||||
with working_dir('double', create=True):
|
if precision in ('float', 'double') and spec.satisfies('@3:'):
|
||||||
configure(*(options + double_options))
|
opts += simd_options
|
||||||
if '+float' in spec:
|
|
||||||
with working_dir('float', create=True):
|
with working_dir(precision, create=True):
|
||||||
configure('--enable-float', *(options + float_options))
|
configure(*opts)
|
||||||
if spec.satisfies('@3:+long_double'):
|
|
||||||
with working_dir('long-double', create=True):
|
def for_each_precision_make(self, *targets):
|
||||||
configure('--enable-long-double', *options)
|
for precision in self.selected_precisions:
|
||||||
if spec.satisfies('@3:+quad'):
|
with working_dir(precision):
|
||||||
with working_dir('quad', create=True):
|
make(*targets)
|
||||||
configure('--enable-quad-precision', *options)
|
|
||||||
|
|
||||||
def build(self, spec, prefix):
|
def build(self, spec, prefix):
|
||||||
if '+double' in spec:
|
self.for_each_precision_make()
|
||||||
with working_dir('double'):
|
|
||||||
make()
|
|
||||||
if '+float' in spec:
|
|
||||||
with working_dir('float'):
|
|
||||||
make()
|
|
||||||
if spec.satisfies('@3:+long_double'):
|
|
||||||
with working_dir('long-double'):
|
|
||||||
make()
|
|
||||||
if spec.satisfies('@3:+quad'):
|
|
||||||
with working_dir('quad'):
|
|
||||||
make()
|
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
spec = self.spec
|
self.for_each_precision_make('check')
|
||||||
if '+double' in spec:
|
|
||||||
with working_dir('double'):
|
|
||||||
make("check")
|
|
||||||
if '+float' in spec:
|
|
||||||
with working_dir('float'):
|
|
||||||
make("check")
|
|
||||||
if spec.satisfies('@3:+long_double'):
|
|
||||||
with working_dir('long-double'):
|
|
||||||
make("check")
|
|
||||||
if spec.satisfies('@3:+quad'):
|
|
||||||
with working_dir('quad'):
|
|
||||||
make("check")
|
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
if '+double' in spec:
|
self.for_each_precision_make('install')
|
||||||
with working_dir('double'):
|
|
||||||
make("install")
|
|
||||||
if '+float' in spec:
|
|
||||||
with working_dir('float'):
|
|
||||||
make("install")
|
|
||||||
if spec.satisfies('@3:+long_double'):
|
|
||||||
with working_dir('long-double'):
|
|
||||||
make("install")
|
|
||||||
if spec.satisfies('@3:+quad'):
|
|
||||||
with working_dir('quad'):
|
|
||||||
make("install")
|
|
||||||
|
|
Loading…
Reference in a new issue