libint + cp2k: 2-stage build with 'tune' and 'fortran' variants (#12475)
* libint: switch to 2-stage build for 2.6.0+ * libint: add tune and fortran variants * cp2k: add support for libint >= 2.0 * cp2k: use pkg-config for linking libxc
This commit is contained in:
		 Tiziano Müller
					Tiziano Müller
				
			
				
					committed by
					
						 Massimiliano Culpo
						Massimiliano Culpo
					
				
			
			
				
	
			
			
			 Massimiliano Culpo
						Massimiliano Culpo
					
				
			
						parent
						
							da18ac3a0f
						
					
				
				
					commit
					d99b92febd
				
			| @@ -61,6 +61,14 @@ class Cp2k(MakefilePackage, CudaPackage): | |||||||
|     variant('cuda_blas', default=False, |     variant('cuda_blas', default=False, | ||||||
|             description=('Use CUBLAS for general matrix operations in DBCSR')) |             description=('Use CUBLAS for general matrix operations in DBCSR')) | ||||||
|  |  | ||||||
|  |     HFX_LMAX_RANGE = range(4, 8) | ||||||
|  |  | ||||||
|  |     variant('lmax', | ||||||
|  |             description='Maximum supported angular momentum (HFX and others)', | ||||||
|  |             default='5', | ||||||
|  |             values=list(HFX_LMAX_RANGE), | ||||||
|  |             multi=False) | ||||||
|  |  | ||||||
|     depends_on('python', type='build') |     depends_on('python', type='build') | ||||||
|  |  | ||||||
|     depends_on('fftw@3:', when='~openmp') |     depends_on('fftw@3:', when='~openmp') | ||||||
| @@ -80,11 +88,19 @@ class Cp2k(MakefilePackage, CudaPackage): | |||||||
|     depends_on('libxsmm@1.11:~header-only', when='smm=libxsmm') |     depends_on('libxsmm@1.11:~header-only', when='smm=libxsmm') | ||||||
|     # use pkg-config (support added in libxsmm-1.10) to link to libxsmm |     # use pkg-config (support added in libxsmm-1.10) to link to libxsmm | ||||||
|     depends_on('pkgconfig', type='build', when='smm=libxsmm') |     depends_on('pkgconfig', type='build', when='smm=libxsmm') | ||||||
|  |     # ... and in CP2K 7.0+ for linking to libint2 | ||||||
|  |     depends_on('pkgconfig', type='build', when='@7.0:') | ||||||
|  |  | ||||||
|     # libint & libxc are always statically linked |     # libint & libxc are always statically linked | ||||||
|     depends_on('libint@1.1.4:1.2', when='@3.0:', type='build') |     depends_on('libint@1.1.4:1.2', when='@3.0:6.9', type='build') | ||||||
|  |     for lmax in HFX_LMAX_RANGE: | ||||||
|  |         # libint2 can be linked dynamically again | ||||||
|  |         depends_on('libint@2.6.0:+fortran tune=cp2k-lmax-{0}'.format(lmax), | ||||||
|  |                    when='@7.0: lmax={0}'.format(lmax)) | ||||||
|  |  | ||||||
|     depends_on('libxc@2.2.2:', when='+libxc@:5.5999', type='build') |     depends_on('libxc@2.2.2:', when='+libxc@:5.5999', type='build') | ||||||
|     depends_on('libxc@4.0.3:', when='+libxc@6.0:', type='build') |     depends_on('libxc@4.0.3:', when='+libxc@6.0:6.9', type='build') | ||||||
|  |     depends_on('libxc@4.0.3:', when='+libxc@7.0:') | ||||||
|  |  | ||||||
|     depends_on('mpi@2:', when='+mpi') |     depends_on('mpi@2:', when='+mpi') | ||||||
|     depends_on('scalapack', when='+mpi') |     depends_on('scalapack', when='+mpi') | ||||||
| @@ -169,11 +185,15 @@ def edit(self, spec, prefix): | |||||||
|  |  | ||||||
|         dflags = ['-DNDEBUG'] |         dflags = ['-DNDEBUG'] | ||||||
|         cppflags = [ |         cppflags = [ | ||||||
|             '-D__FFTW3', |  | ||||||
|             '-D__LIBINT', |             '-D__LIBINT', | ||||||
|  |             '-D__FFTW3', | ||||||
|  |             fftw.headers.cpp_flags, | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         if '@:6.9' in spec: | ||||||
|  |             cppflags += [ | ||||||
|                 '-D__LIBINT_MAX_AM=6', |                 '-D__LIBINT_MAX_AM=6', | ||||||
|                 '-D__LIBDERIV_MAX_AM1=5', |                 '-D__LIBDERIV_MAX_AM1=5', | ||||||
|             fftw.headers.cpp_flags, |  | ||||||
|             ] |             ] | ||||||
|  |  | ||||||
|         if '^mpi@3:' in spec: |         if '^mpi@3:' in spec: | ||||||
| @@ -220,6 +240,7 @@ def edit(self, spec, prefix): | |||||||
|         if 'superlu-dist@4.3' in spec: |         if 'superlu-dist@4.3' in spec: | ||||||
|             ldflags.insert(0, '-Wl,--allow-multiple-definition') |             ldflags.insert(0, '-Wl,--allow-multiple-definition') | ||||||
|  |  | ||||||
|  |         if '@:6.9' in spec: | ||||||
|             # libint-1.x.y has to be linked statically to work around |             # libint-1.x.y has to be linked statically to work around | ||||||
|             # inconsistencies in its Fortran interface definition |             # inconsistencies in its Fortran interface definition | ||||||
|             # (short-int vs int) which otherwise causes segfaults at runtime |             # (short-int vs int) which otherwise causes segfaults at runtime | ||||||
| @@ -228,6 +249,9 @@ def edit(self, spec, prefix): | |||||||
|                 os.path.join(spec['libint'].libs.directories[0], 'libderiv.a'), |                 os.path.join(spec['libint'].libs.directories[0], 'libderiv.a'), | ||||||
|                 os.path.join(spec['libint'].libs.directories[0], 'libint.a'), |                 os.path.join(spec['libint'].libs.directories[0], 'libint.a'), | ||||||
|             ]) |             ]) | ||||||
|  |         else: | ||||||
|  |             fcflags += ['$(shell pkg-config --cflags libint2)'] | ||||||
|  |             libs += ['$(shell pkg-config --libs libint2)'] | ||||||
|  |  | ||||||
|         if '+plumed' in self.spec: |         if '+plumed' in self.spec: | ||||||
|             dflags.extend(['-D__PLUMED2']) |             dflags.extend(['-D__PLUMED2']) | ||||||
| @@ -286,14 +310,16 @@ def edit(self, spec, prefix): | |||||||
|                 libs.append(wannier) |                 libs.append(wannier) | ||||||
|  |  | ||||||
|         if '+libxc' in spec: |         if '+libxc' in spec: | ||||||
|             libxc = spec['libxc:fortran,static'] |             cppflags += ['-D__LIBXC'] | ||||||
|             cppflags += [ |  | ||||||
|                 '-D__LIBXC', |  | ||||||
|                 libxc.headers.cpp_flags |  | ||||||
|             ] |  | ||||||
|  |  | ||||||
|  |             if '@:6.9' in spec: | ||||||
|  |                 libxc = spec['libxc:fortran,static'] | ||||||
|  |                 cppflags += [libxc.headers.cpp_flags] | ||||||
|                 ldflags.append(libxc.libs.search_flags) |                 ldflags.append(libxc.libs.search_flags) | ||||||
|                 libs.append(str(libxc.libs)) |                 libs.append(str(libxc.libs)) | ||||||
|  |             else: | ||||||
|  |                 fcflags += ['$(shell pkg-config --cflags libxcf03)'] | ||||||
|  |                 libs += ['$(shell pkg-config --libs libxcf03)'] | ||||||
|  |  | ||||||
|         if '+pexsi' in self.spec: |         if '+pexsi' in self.spec: | ||||||
|             cppflags.append('-D__LIBPEXSI') |             cppflags.append('-D__LIBPEXSI') | ||||||
|   | |||||||
| @@ -3,9 +3,19 @@ | |||||||
| # | # | ||||||
| # SPDX-License-Identifier: (Apache-2.0 OR MIT) | # SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||||||
|  |  | ||||||
|  | import os | ||||||
| from spack import * | from spack import * | ||||||
|  |  | ||||||
|  |  | ||||||
|  | TUNE_VARIANTS = ( | ||||||
|  |     'none', | ||||||
|  |     'cp2k-lmax-4', | ||||||
|  |     'cp2k-lmax-5', | ||||||
|  |     'cp2k-lmax-6', | ||||||
|  |     'cp2k-lmax-7', | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Libint(AutotoolsPackage): | class Libint(AutotoolsPackage): | ||||||
|     """Libint is a high-performance library for computing |     """Libint is a high-performance library for computing | ||||||
|     Gaussian integrals in quantum mechanics. |     Gaussian integrals in quantum mechanics. | ||||||
| @@ -14,6 +24,7 @@ class Libint(AutotoolsPackage): | |||||||
|     homepage = "https://github.com/evaleev/libint" |     homepage = "https://github.com/evaleev/libint" | ||||||
|     url = "https://github.com/evaleev/libint/archive/v2.1.0.tar.gz" |     url = "https://github.com/evaleev/libint/archive/v2.1.0.tar.gz" | ||||||
|  |  | ||||||
|  |     version('2.6.0', sha256='4ae47e8f0b5632c3d2a956469a7920896708e9f0e396ec10071b8181e4c8d9fa') | ||||||
|     version('2.4.2', sha256='86dff38065e69a3a51d15cfdc638f766044cb87e5c6682d960c14f9847e2eac3') |     version('2.4.2', sha256='86dff38065e69a3a51d15cfdc638f766044cb87e5c6682d960c14f9847e2eac3') | ||||||
|     version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4') |     version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4') | ||||||
|     version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019') |     version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019') | ||||||
| @@ -22,6 +33,12 @@ class Libint(AutotoolsPackage): | |||||||
|     version('1.1.6', sha256='f201b0c621df678cfe8bdf3990796b8976ff194aba357ae398f2f29b0e2985a6') |     version('1.1.6', sha256='f201b0c621df678cfe8bdf3990796b8976ff194aba357ae398f2f29b0e2985a6') | ||||||
|     version('1.1.5', sha256='ec8cd4a4ba1e1a98230165210c293632372f0e573acd878ed62e5ec6f8b6174b') |     version('1.1.5', sha256='ec8cd4a4ba1e1a98230165210c293632372f0e573acd878ed62e5ec6f8b6174b') | ||||||
|  |  | ||||||
|  |     variant('fortran', default=False, | ||||||
|  |             description='Build & install Fortran bindings') | ||||||
|  |     variant('tune', default='none', multi=False, | ||||||
|  |             values=TUNE_VARIANTS, | ||||||
|  |             description='Tune libint for use with the given package') | ||||||
|  |  | ||||||
|     # Build dependencies |     # Build dependencies | ||||||
|     depends_on('autoconf@2.52:', type='build') |     depends_on('autoconf@2.52:', type='build') | ||||||
|     depends_on('automake', type='build') |     depends_on('automake', type='build') | ||||||
| @@ -31,6 +48,11 @@ class Libint(AutotoolsPackage): | |||||||
|     depends_on('boost', when='@2:') |     depends_on('boost', when='@2:') | ||||||
|     depends_on('gmp', when='@2:') |     depends_on('gmp', when='@2:') | ||||||
|  |  | ||||||
|  |     for tvariant in TUNE_VARIANTS[1:]: | ||||||
|  |         conflicts('tune={0}'.format(tvariant), when='@:2.5.99', | ||||||
|  |                   msg=('for versions prior to 2.6, tuning for specific' | ||||||
|  |                        'codes/configurations is not supported')) | ||||||
|  |  | ||||||
|     def url_for_version(self, version): |     def url_for_version(self, version): | ||||||
|         base_url = "https://github.com/evaleev/libint/archive" |         base_url = "https://github.com/evaleev/libint/archive" | ||||||
|         if version == Version('1.0.0'): |         if version == Version('1.0.0'): | ||||||
| @@ -45,6 +67,10 @@ def autoreconf(self, spec, prefix): | |||||||
|         aclocal('-I', 'lib/autoconf') |         aclocal('-I', 'lib/autoconf') | ||||||
|         autoconf() |         autoconf() | ||||||
|  |  | ||||||
|  |         if '@2.6.0:' in spec: | ||||||
|  |             # skip tarball creation and removal of dir with generated code | ||||||
|  |             filter_file(r'^(export::.*)\s+tgz$', r'\1', 'export/Makefile') | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def optflags(self): |     def optflags(self): | ||||||
|         flags = '-O2' |         flags = '-O2' | ||||||
| @@ -89,4 +115,60 @@ def configure_args(self): | |||||||
|                 '--with-libint-max-am=5', |                 '--with-libint-max-am=5', | ||||||
|                 '--with-libderiv-max-am1=4' |                 '--with-libderiv-max-am1=4' | ||||||
|             ]) |             ]) | ||||||
|  |  | ||||||
|  |         if '@2.6.0:' in self.spec: | ||||||
|  |             config_args += ['--with-libint-exportdir=generated'] | ||||||
|  |  | ||||||
|  |             tune_value = self.spec.variants['tune'].value | ||||||
|  |             if tune_value.startswith('cp2k'): | ||||||
|  |                 lmax = int(tune_value.split('-lmax-')[1]) | ||||||
|  |                 config_args += [ | ||||||
|  |                     '--enable-eri=1', | ||||||
|  |                     '--enable-eri2=1', | ||||||
|  |                     '--enable-eri3=1', | ||||||
|  |                     '--with-max-am={0}'.format(lmax), | ||||||
|  |                     '--with-eri-max-am={0},{1}'.format(lmax, lmax - 1), | ||||||
|  |                     '--with-eri2-max-am={0},{1}'.format(lmax + 2, lmax + 1), | ||||||
|  |                     '--with-eri3-max-am={0},{1}'.format(lmax + 2, lmax + 1), | ||||||
|  |                     '--with-opt-am=3', | ||||||
|  |                     # keep code-size at an acceptable limit, | ||||||
|  |                     # cf. https://github.com/evaleev/libint/wiki#program-specific-notes: | ||||||
|  |                     '--enable-generic-code', | ||||||
|  |                     '--disable-unrolling', | ||||||
|  |                 ] | ||||||
|  |  | ||||||
|         return config_args |         return config_args | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def build_targets(self): | ||||||
|  |         if '@2.6.0:' in self.spec: | ||||||
|  |             return ['export'] | ||||||
|  |  | ||||||
|  |         return [] | ||||||
|  |  | ||||||
|  |     @when('@2.6.0:') | ||||||
|  |     def install(self, spec, prefix): | ||||||
|  |         """ | ||||||
|  |         Starting from libint 2.6.0 we're using the 2-stage build | ||||||
|  |         to get support for the Fortran bindings, required by some | ||||||
|  |         packages (CP2K notably). | ||||||
|  |         """ | ||||||
|  |  | ||||||
|  |         # upstream says that using configure/make for the generated code | ||||||
|  |         # is deprecated and one should use CMake, but with the currently | ||||||
|  |         # recent 2.7.0.b1 it still doesn't work | ||||||
|  |         with working_dir(os.path.join(self.build_directory, 'generated')): | ||||||
|  |             # straight from the AutotoolsPackage class: | ||||||
|  |             options = [ | ||||||
|  |                 '--prefix={0}'.format(prefix), | ||||||
|  |                 '--enable-shared', | ||||||
|  |                 '--with-cxx-optflags={0}'.format(self.optflags), | ||||||
|  |             ] | ||||||
|  |  | ||||||
|  |             if '+fortran' in spec: | ||||||
|  |                 options += ['--enable-fortran'] | ||||||
|  |  | ||||||
|  |             configure = Executable('./configure') | ||||||
|  |             configure(*options) | ||||||
|  |             make() | ||||||
|  |             make('install') | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user