From 4c87ef915f917c2262349832966a12127b7700b3 Mon Sep 17 00:00:00 2001 From: Nicolas Richart Date: Sun, 22 May 2016 18:55:29 +0200 Subject: [PATCH] First try at OpenFOAM-extend --- .../packages/openfoam-extend/package.py | 262 ++++++++++++++++++ .../builtin/packages/parmgridgen/package.py | 75 +++++ .../repos/builtin/packages/scotch/package.py | 12 +- 3 files changed, 342 insertions(+), 7 deletions(-) create mode 100644 var/spack/repos/builtin/packages/openfoam-extend/package.py create mode 100644 var/spack/repos/builtin/packages/parmgridgen/package.py diff --git a/var/spack/repos/builtin/packages/openfoam-extend/package.py b/var/spack/repos/builtin/packages/openfoam-extend/package.py new file mode 100644 index 0000000000..6af824df7e --- /dev/null +++ b/var/spack/repos/builtin/packages/openfoam-extend/package.py @@ -0,0 +1,262 @@ +from spack import * +from spack.environment import * + +import multiprocessing +import subprocess +import re +import os + + +class OpenfoamExtend(Package): + """OpenFOAM-extend or foam-extend""" + + version('3.2', git='http://git.code.sf.net/p/foam-extend/foam-extend-3.2') + version('3.1', git='http://git.code.sf.net/p/foam-extend/foam-extend-3.1') + version('3.0', git='http://git.code.sf.net/p/foam-extend/foam-extend-3.0') + + variant('paraview', default=False, description='Enable ParaFOAM') + variant('scotch', default=True, description='Activate Scotch as a possible decomposition library') + variant('ptscotch', default=True, description='Activate PT-Scotch as a possible decomposition library') + variant('metis', default=True, description='Activate Metis as a possible decomposition library') + variant('parmetis', default=True, description='Activate Parmetis as a possible decomposition library') + variant('parmgridgen', default=True, description='Activate Parmgridgen support') + + supported_compilers = {'clang': 'Clang', 'gcc': 'Gcc', 'intel': 'Icc'} + + depends_on('mpi') + depends_on('cmake') + depends_on('python') + depends_on('flex@:2.5.99') + depends_on('bison') + depends_on('m4') + depends_on('hwloc') + depends_on('zlib') + + depends_on('scotch ~ metis', when='~ptscotch+scotch') + depends_on('scotch ~ metis + mpi', when='+ptscotch') + depends_on('metis@5:', when='+metis') + depends_on('parmetis', when='+parmetis') + depends_on('parmgridgen', when='+parmgridgen') + + depends_on('paraview', when='+paraview') + depends_on('qt@:4', when='+paraview') + + def _get_env(self, command): + variable_set = re.compile(r'(.+?)=(.*)') + proc = subprocess.Popen(['bash', '-c', command], + stdout=subprocess.PIPE) + env = {} + for line in proc.stdout: + match_grp = variable_set.match(line) + if match_grp: + env[match_grp.group(1)] = match_grp.group(2) + return env + + def set_arch(self): + (sysname, nodename, release, version, machine) = os.uname() + + if self.compiler.name not in self.supported_compilers: + raise RuntimeError('{0} is not a supported compiler \ + to compile OpenFOAM'.format(self.compiler.name)) + + foam_compiler = self.supported_compilers[self.compiler.name] + if sysname == 'Linux': + arch = 'linux' + if foam_compiler == 'Clang': + raise RuntimeError('OS, compiler combinaison not\ + supported ({0} {1})'.format(sysname, foam_compiler)) + elif sysname == 'Darwin': + if machine == 'x86_64': + arch = 'darwinIntel' + if foam_compiler == 'Icc': + raise RuntimeError('OS, compiler combinaison not\ + supported ({0} {1})'.format(sysname, foam_compiler)) + else: + raise RuntimeError('{0} {1} is not a \ + supported architecture'.format(sysname, machine)) + + return (arch, foam_compiler) + + def get_openfoam_environment(self, env_openfoam): + env_before = self._get_env('env') + + with working_dir(self.stage.source_path): + env_after = self._get_env('source etc/bashrc && env') + + if 'PATH' in env_after: + del env_after['PATH'] + + if 'LD_LIBRARY_PATH' in env_after: + del env_after['LD_LIBRARY_PATH'] + + for key, value in env_after.iteritems(): + if key not in env_before or not value == env_before[key]: + env_openfoam.set(key, value) + + def patch(self): + if '+parmgridgen' in self.spec: + filter_file(r'-lIMlib -lMGridGen', + r'-limlib -lmgrid', + 'src/dbns/Make/options') + filter_file(r'-lMGridGen', + r'-lmgrid', + 'src/fvAgglomerationMethods/MGridGenGamgAgglomeration/Make/options') + + (arch, foam_compiler) = self.set_arch() + + prefs_dict = { + 'compilerInstall': 'System', + 'WM_COMPILER': foam_compiler, + 'WM_ARCH_OPTION': '64', + 'WM_PRECISION_OPTION': 'DP', + 'WM_COMPILE_OPTION': 'SPACKOpt', + 'WM_MPLIB': 'SPACK', + + 'CMAKE_DIR': self.spec['cmake'].prefix, + 'CMAKE_BIN_DIR': self.spec['cmake'].prefix.bin, + 'PYTHON_DIR': self.spec['python'].prefix, + 'PYTHON_BIN_DIR': self.spec['python'].prefix.bin, + + 'FLEX_SYSTEM': 1, + 'FLEX_DIR': self.spec['flex'].prefix, + + 'BISON_SYSTEM': 1, + 'BISON_DIR': self.spec['flex'].prefix, + + 'M4_SYSTEM': 1, + 'M4_DIR': self.spec['m4'].prefix, + + 'ZLIB_SYSTEM': 1, + 'ZLIB_DIR': self.spec['zlib'].prefix, + + 'HWLOC_SYSTEM': 1, + 'HWLOC_DIR': self.spec['hwloc'].prefix, + 'HWLOC_BIN_DIR': self.spec['hwloc'].prefix.bin, + } + + if '+scotch' in self.spec or '+ptscotch' in self.spec: + prefs_dict['SCOTCH_SYSTEM'] = 1 + prefs_dict['SCOTCH_DIR'] = self.spec['scotch'].prefix + prefs_dict['SCOTCH_BIN_DIR'] = self.spec['scotch'].prefix.bin + prefs_dict['SCOTCH_LIB_DIR'] = self.spec['scotch'].prefix.lib + prefs_dict['SCOTCH_INCLUDE_DIR'] = \ + self.spec['scotch'].prefix.include + + if '+metis' in self.spec: + prefs_dict['METIS_SYSTEM'] = 1 + prefs_dict['METIS_DIR'] = self.spec['metis'].prefix + prefs_dict['METIS_BIN_DIR'] = self.spec['metis'].prefix.bin + prefs_dict['METIS_LIB_DIR'] = self.spec['metis'].prefix.lib + prefs_dict['METIS_INCLUDE_DIR'] = self.spec['metis'].prefix.include + + if '+parmetis' in self.spec: + prefs_dict['PARMETIS_SYSTEM'] = 1 + prefs_dict['PARMETIS_DIR'] = self.spec['parmetis'].prefix + prefs_dict['PARMETIS_BIN_DIR'] = self.spec['parmetis'].prefix.bin + prefs_dict['PARMETIS_LIB_DIR'] = self.spec['parmetis'].prefix.lib + prefs_dict['PARMETIS_INCLUDE_DIR'] = \ + self.spec['parmetis'].prefix.include + + if '+parmgridgen' in self.spec: + prefs_dict['PARMGRIDGEN_SYSTEM'] = 1 + prefs_dict['PARMGRIDGEN_DIR'] = self.spec['parmgridgen'].prefix + prefs_dict['PARMGRIDGEN_BIN_DIR'] = \ + self.spec['parmgridgen'].prefix.bin + prefs_dict['PARMGRIDGEN_LIB_DIR'] = \ + self.spec['parmgridgen'].prefix.lib + prefs_dict['PARMGRIDGEN_INCLUDE_DIR'] = \ + self.spec['parmgridgen'].prefix.include + + if '+paraview' in self.spec: + prefs_dict['PARAVIEW_SYSTEM'] = 1 + prefs_dict['PARAVIEW_DIR'] = self.spec['paraview'].prefix, + prefs_dict['PARAVIEW_BIN_DIR'] = self.spec['paraview'].prefix.bin, + prefs_dict['QT_SYSTEM'] = 1 + prefs_dict['QT_DIR'] = self.spec['qt'].prefix, + prefs_dict['QT_BIN_DIR'] = self.spec['qt'].prefix.bin, + + with working_dir('.'): + with open("etc/prefs.sh", "w") as fh: + for key in sorted(prefs_dict): + fh.write('export {0}={1}\n'.format(key, prefs_dict[key])) + + with open("etc/prefs.csh", "w") as fh: + for key in sorted(prefs_dict): + fh.write('setenv {0}={1}\n'.format(key, prefs_dict[key])) + + mpi_info = [ + 'PFLAGS = -DOMPI_SKIP_MPICXX -DMPICH_IGNORE_CXX_SEEK', + 'PINC = -I{0}'.format(self.spec['mpi'].prefix.include), + 'PLIBS = -L{0} -lmpi'.format(self.spec['mpi'].prefix.lib) + ] + + arch_path = ''.join([arch, prefs_dict['WM_ARCH_OPTION'], + foam_compiler]) + option_path = ''.join([arch_path, + prefs_dict['WM_PRECISION_OPTION'], + prefs_dict['WM_COMPILE_OPTION']]) + rule_path = join_path("wmake", "rules", arch_path) + build_path = join_path(self.stage.source_path, 'lib', option_path) + install_path = \ + join_path(self.prefix, + 'foam-extend-{0}'.format(self.version.up_to(2)), + option_path) + + rpaths_foam = ' '.join([ + '{0}{1}'.format(self.compiler.cxx_rpath_arg, + install_path), + '{0}{1}'.format(self.compiler.cxx_rpath_arg, + build_path) + ]) + + compiler_flags = { + 'DBUG': rpaths_foam, + 'OPT': '-O3', + } + + with working_dir(rule_path): + with open('mplibSPACK', "w") as fh: + fh.write('\n'.join(mpi_info)) + + for comp in ['c', 'c++']: + with open('{0}SPACKOpt'.format(comp), "w") as fh: + for key, val in compiler_flags.iteritems(): + fh.write('{0}{1} = {2}\n'.format(comp, key, val)) + + def setup_environment(self, spack_env, run_env): + with working_dir(self.stage.path): + spack_env.set('FOAM_INST_DIR', os.path.abspath('.')) + + (arch, foam_compiler) = self.set_arch() + + run_env.set('FOAM_INST_DIR', self.prefix) + + def install(self, spec, prefix): + self.patch() + + env_openfoam = EnvironmentModifications() + self.get_openfoam_environment(env_openfoam) + env_openfoam.apply_modifications() + + if self.parallel: + os.environ['WM_NCOMPPROCS'] = str(self.make_jobs) \ + if self.make_jobs else str(multiprocessing.cpu_count()) + + # for key in sorted(os.environ): + # print("{0} = {1}".format(key, os.environ[key])) + + allwmake = Executable('./Allwmake') + allwmake() + + install_path = \ + join_path(self.prefix, + 'foam-extend-{0}'.format(self.version.up_to(2))) + + if '+source' in spec: + install_tree('src', join_path(install_path, 'src')) + + install_tree('lib', join_path(install_path, 'lib')) + install_tree('bin', join_path(install_path, 'bin')) + install_tree('applications', join_path(install_path, 'applications')) + install_tree('etc', join_path(install_path, 'etc')) + install_tree('wmake', join_path(install_path, 'wmake')) diff --git a/var/spack/repos/builtin/packages/parmgridgen/package.py b/var/spack/repos/builtin/packages/parmgridgen/package.py new file mode 100644 index 0000000000..11b19f2ec2 --- /dev/null +++ b/var/spack/repos/builtin/packages/parmgridgen/package.py @@ -0,0 +1,75 @@ +############################################################################## +# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License (as +# published by the Free Software Foundation) version 2.1, February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## + +from spack import * + + +class Parmgridgen(Package): + """MGRIDGEN is a serial library written entirely in ANSI C that implements + (serial) algorithms for obtaining a sequence of successive coarse grids + that are well-suited for geometric multigrid methods. + ParMGridGen is the parallel version of MGridGen + """ + + homepage = "http://www-users.cs.umn.edu/~moulitsa/software.html" + url = "http://www-users.cs.umn.edu/~moulitsa/download/ParMGridGen-1.0.tar.gz" + + version('1.0', '2872fa95b7fb91d6bd525490eed62038') + + depends_on('mpi') + + def install(self, spec, prefix): + make_opts = [ + 'make=make', + 'COPTIONS=-fPIC', + 'LDOPTIONS=-fPIC', + 'CC={0}'.format(self.compiler.cc), + 'PARCC={0}'.format(self.spec['mpi'].mpicc), + 'LD={0}'.format(self.compiler.cc), + 'PARLD={0}'.format(self.spec['mpi'].mpicc), + 'LIBDIR=-L../..', + 'PARLIBS=-L../../ -lparmgrid -lmgrid -lm', + 'LIBS=-L../../ -lmgrid -lm', + 'parallel' + ] + + make(*make_opts, parallel=False) + + include_path = join_path(self.prefix, 'include') + lib_path = join_path(self.prefix, 'lib') + bin_path = join_path(self.prefix, 'bin') + + mkdirp(include_path, lib_path, bin_path) + + install("mgridgen.h", include_path) + install("parmgridgen.h", include_path) + + install("MGridGen/IMlib/libIMlib.a", + join_path(lib_path, 'libimlib.a')) + install("libmgrid.a", lib_path) + install("libparmgrid.a", lib_path) + + install("mgridgen", bin_path) + install("parmgridgen", bin_path) diff --git a/var/spack/repos/builtin/packages/scotch/package.py b/var/spack/repos/builtin/packages/scotch/package.py index 3c2b4993ac..2f6e42c439 100644 --- a/var/spack/repos/builtin/packages/scotch/package.py +++ b/var/spack/repos/builtin/packages/scotch/package.py @@ -171,15 +171,13 @@ def install(self, spec, prefix): target == 'ptscotch')) make(target, parallel=can_make_parallel) - # todo change this to take into account darwin systems - lib_ext = '.so' if '+shared' in self.spec else '.a' + lib_ext = dso_suffix if '+shared' in self.spec else 'a' # It seams easier to remove metis wrappers from the folder that will be # installed than to tweak the Makefiles if '+metis' not in self.spec: with working_dir('lib'): - lib_ext = '.so' if '+shared' in self.spec else '.a' - force_remove('libscotchmetis{0}'.format(lib_ext)) - force_remove('libptscotchparmetis{0}'.format(lib_ext)) + force_remove('libscotchmetis.{0}'.format(lib_ext)) + force_remove('libptscotchparmetis.{0}'.format(lib_ext)) with working_dir('include'): force_remove('metis.h') @@ -187,8 +185,8 @@ def install(self, spec, prefix): if '~esmumps' in self.spec and self.spec.version < Version('6.0.0'): with working_dir('lib'): - force_remove('libesmumps{0}'.format(lib_ext)) - force_remove('libptesmumps{0}'.format(lib_ext)) + force_remove('libesmumps.{0}'.format(lib_ext)) + force_remove('libptesmumps.{0}'.format(lib_ext)) with working_dir('include'): force_remove('esmumps.h')