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:
		 Massimiliano Culpo
					Massimiliano Culpo
				
			
				
					committed by
					
						 Adam J. Stewart
						Adam J. Stewart
					
				
			
			
				
	
			
			
			 Adam J. Stewart
						Adam J. Stewart
					
				
			
						parent
						
							46e319ecd4
						
					
				
				
					commit
					2cd800306d
				
			| @@ -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): | ||||||
| @@ -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") |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user