diff options
8 files changed, 411 insertions, 32 deletions
diff --git a/var/spack/repos/builtin/packages/fsl/build_log.patch b/var/spack/repos/builtin/packages/fsl/build_log.patch new file mode 100644 index 0000000000..c0553b4c35 --- /dev/null +++ b/var/spack/repos/builtin/packages/fsl/build_log.patch @@ -0,0 +1,11 @@ +--- a/build 2020-06-29 10:30:36.000000000 -0500 ++++ b/build 2020-11-02 12:34:25.408157699 -0600 +@@ -158,7 +158,7 @@ + fi #full build + + echo "Building projects - see build.log file for progress..." +-./config/common/buildproj $PROJECTS > ./build.log 2>&1 ++./config/common/buildproj $PROJECTS + finalStatus=$? + if [ $finalStatus -eq 0 ]; then + echo "Build completed successfully."; diff --git a/var/spack/repos/builtin/packages/fsl/eddy_Makefile.patch b/var/spack/repos/builtin/packages/fsl/eddy_Makefile.patch new file mode 100644 index 0000000000..22057bf8fd --- /dev/null +++ b/var/spack/repos/builtin/packages/fsl/eddy_Makefile.patch @@ -0,0 +1,11 @@ +--- a/src/eddy/Makefile 2020-07-22 09:11:14.000000000 -0500 ++++ b/src/eddy/Makefile 2020-11-10 23:31:09.898903635 -0600 +@@ -46,7 +46,7 @@ + + CUDACXXFLAGS=-DCOMPILE_GPU + CUDAOBJS=CBFKernelDefinitions.o CBFSparseDiagonalMatrix.o CBFSplineField.o LSResampler_cuda.o DiffusionGP_cuda.o PostEddyCF_cuda.o EddyGpuUtils.o EddyInternalGpuUtils.o CudaVolume.o EddyMatrixKernels.o EddyKernels.o GpuPredictorChunk.o StackResampler.o DerivativeCalculator.o +- CUDALDFLAGS= -Xlinker -rpath $(LIB_CUDA) -L$(LIB_CUDA) -lcublas -lcudart ++ CUDALDFLAGS= -Xlinker -rpath -Xlinker $(LIB_CUDA) -L$(LIB_CUDA) -lcublas -lcudart + ifeq ($(fastbuild),1) + GENCODE_FLAGS := -gencode arch=compute_30,code=sm_30 + endif diff --git a/var/spack/repos/builtin/packages/fsl/fsl_sub_v5.patch b/var/spack/repos/builtin/packages/fsl/fsl_sub_v5.patch new file mode 100644 index 0000000000..561800962a --- /dev/null +++ b/var/spack/repos/builtin/packages/fsl/fsl_sub_v5.patch @@ -0,0 +1,66 @@ +--- a/src/sgeutils/fsl_sub 2017-04-24 05:19:14.000000000 -0500 ++++ b/src/sgeutils/fsl_sub 2020-11-15 17:42:28.100657607 -0600 +@@ -80,7 +80,7 @@ + # "NONE". Note that a user can unset SGE_ROOT if they don't want the + # cluster to be used. + ########################################################################### +-METHOD=SGE ++METHOD=NONE + unset module + if [ "x$SGE_ROOT" = "x" ] ; then + METHOD=NONE +@@ -141,7 +141,9 @@ + + usage () + { +- cat <<EOF ++ case $METHOD in ++ SGE) ++ cat <<EOF + + $command V1.1 - wrapper for job control system such as SGE + +@@ -186,7 +188,23 @@ + bigmem.q: This queue is like the verylong.q but has no memory limits. + + EOF ++ ;; ++ NONE) ++ cat <<EOF + ++$command V1.1 - wrapper for job control system such as SGE ++ ++Usage: $command [options] <command> ++ ++$command gzip *.img *.hdr ++ ++ -t <filename> Specify a task file of commands to execute in parallel ++ -l <logdirname> Where to output logfiles ++ -v Verbose mode. ++ ++EOF ++ ;; ++ esac + exit 1 + } + +@@ -195,8 +213,17 @@ + usage + fi + +-set -- `getopt T:q:a:p:M:j:t:z:N:R:Fvm:l:s: $*` +-result=$? ++case $METHOD in ++ SGE) ++ set -- `getopt T:q:a:p:M:j:t:z:N:R:Fvm:l:s: $*` ++ result=$? ++ ;; ++ NONE) ++ set -- `getopt t:vl: $*` ++ result=$? ++ ;; ++esac ++ + if [ $result != 0 ] ; then + echo "What? Your arguments make no sense!" + fi diff --git a/var/spack/repos/builtin/packages/fsl/fsl_sub_v6.patch b/var/spack/repos/builtin/packages/fsl/fsl_sub_v6.patch new file mode 100644 index 0000000000..e209ba9282 --- /dev/null +++ b/var/spack/repos/builtin/packages/fsl/fsl_sub_v6.patch @@ -0,0 +1,86 @@ +--- a/src/sgeutils/fsl_sub 2020-07-25 09:36:17.000000000 -0500 ++++ b/src/sgeutils/fsl_sub 2020-11-15 17:04:41.484972803 -0600 +@@ -81,7 +81,7 @@ + # "NONE". Note that a user can unset SGE_ROOT if they don't want the + # cluster to be used. + ########################################################################### +-METHOD=SGE ++METHOD=NONE + unset module + if [[ "x$SGE_ROOT" = "x" ]] ; then + METHOD=NONE +@@ -145,7 +145,10 @@ + + usage () + { +- cat <<EOF ++ case "$METHOD" in ++ SGE) ++ ++ cat <<EOF + + $command V1.1 - wrapper for job control system such as SGE + +@@ -190,7 +193,24 @@ + bigmem.q: This queue is like the verylong.q but has no memory limits. + + EOF ++ ;; ++ NONE) ++ ++ cat <<EOF + ++$command V1.1 - wrapper for job control system such as SGE ++ ++Usage: $command [options] <command> ++ ++$command gzip *.img *.hdr ++ ++ -t <filename> Specify a task file of commands to execute in parallel ++ -l <logdirname> Where to output logfiles ++ -v Verbose mode. ++ ++EOF ++ ;; ++ esac + exit 1 + } + +@@ -199,14 +219,29 @@ + usage + fi + +-#if the newer whitespace-safe getopt format is available, use it +-if [[ $(getopt -T >/dev/null 2>&1; echo $?) == 4 ]]; then +- eval set -- $(getopt -s bash T:q:a:p:M:j:t:z:N:R:Fvm:l:s: "$@") +- result=$? +-else +- set -- $(getopt T:q:a:p:M:j:t:z:N:R:Fvm:l:s: "$@") +- result=$? +-fi ++case "$METHOD" in ++ SGE) ++ #if the newer whitespace-safe getopt format is available, use it ++ if [[ $(getopt -T >/dev/null 2>&1; echo $?) == 4 ]]; then ++ eval set -- $(getopt -s bash T:q:a:p:M:j:t:z:N:R:Fvm:l:s: "$@") ++ result=$? ++ else ++ set -- $(getopt T:q:a:p:M:j:t:z:N:R:Fvm:l:s: "$@") ++ result=$? ++ fi ++ ;; ++ NONE) ++ #if the newer whitespace-safe getopt format is available, use it ++ if [[ $(getopt -T >/dev/null 2>&1; echo $?) == 4 ]]; then ++ eval set -- $(getopt -s bash t:vl: "$@") ++ result=$? ++ else ++ set -- $(getopt t:vl: "$@") ++ result=$? ++ fi ++ ;; ++esac ++ + if [[ "$result" != 0 ]] ; then + echo "What? Your arguments make no sense!" + fi diff --git a/var/spack/repos/builtin/packages/fsl/fslpython_install_v5.patch b/var/spack/repos/builtin/packages/fsl/fslpython_install_v5.patch new file mode 100644 index 0000000000..7e22534251 --- /dev/null +++ b/var/spack/repos/builtin/packages/fsl/fslpython_install_v5.patch @@ -0,0 +1,18 @@ +--- a/etc/fslconf/fslpython_install.sh 2017-04-07 10:29:52.000000000 -0500 ++++ b/etc/fslconf/fslpython_install.sh 2020-11-12 13:34:06.665816528 -0600 +@@ -129,7 +129,7 @@ + exit 2 + fi + +-curl_opts='--fail' # Returns 22 on error ++curl_opts='--fail -L' # Returns 22 on error + if [ ${quiet} -eq 1 ]; then + curl_opts="${curl_opts} -s" + fi +@@ -184,4 +184,4 @@ + # binary into $FSLDIR/bin/ + ln -sf "${fslpython_env_dir}/bin/python" "${fsl_dir}/bin/fslpython" + rm "${miniconda_install_log}" +-drop_sudo rmdir "${miniconda_tmp}" +\ No newline at end of file ++drop_sudo rmdir "${miniconda_tmp}" diff --git a/var/spack/repos/builtin/packages/fsl/fslpython_install_v6.patch b/var/spack/repos/builtin/packages/fsl/fslpython_install_v6.patch new file mode 100644 index 0000000000..93eac4cb73 --- /dev/null +++ b/var/spack/repos/builtin/packages/fsl/fslpython_install_v6.patch @@ -0,0 +1,39 @@ +--- a/etc/fslconf/fslpython_install.sh 2020-07-25 09:20:04.000000000 -0500 ++++ b/etc/fslconf/fslpython_install.sh 2020-11-09 20:12:59.458736979 -0600 +@@ -204,19 +204,19 @@ + # - https://github.com/conda/conda/issues/8804 + + # Try to make downloads more resilient +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_read_timeout_secs 240 +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_connect_timeout_secs 20 +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_max_retries 10 +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_backoff_factor 5 +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set safety_checks warn ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_read_timeout_secs 240 ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_connect_timeout_secs 20 ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_max_retries 10 ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set remote_backoff_factor 5 ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set safety_checks warn + + # Channel priority: + # - conda-forge (highest priority) + # - defaults (gets automatically added on the first call) + # - fsl (lowest priority) +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set channel_priority strict +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --add channels conda-forge +-"${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --append channels https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/channel ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --set channel_priority strict ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --add channels conda-forge ++"${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda" config --file "${miniconda_root_dir}"/.condarc --append channels https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/channel + + + ############################## +@@ -229,7 +229,7 @@ + if [ ${quiet} -ne 1 ]; then + echo "Stage 2" + fi +-FSLDIR=$fsl_dir "${miniconda_bin_dir}/conda" env create -v \ ++FSLDIR=$fsl_dir "${miniconda_bin_dir}/python" "${miniconda_bin_dir}/conda-env" create -v \ + -f "${script_dir}/fslpython_environment.yml" \ + 2>> "${miniconda_install_log}" | \ + ${script_dir}/progress.sh 133 ${quiet} 1>> "${miniconda_install_log}" diff --git a/var/spack/repos/builtin/packages/fsl/iconv.patch b/var/spack/repos/builtin/packages/fsl/iconv.patch new file mode 100644 index 0000000000..d62b0f8a7b --- /dev/null +++ b/var/spack/repos/builtin/packages/fsl/iconv.patch @@ -0,0 +1,28 @@ +diff -ru a/src/flameo/Makefile b/src/flameo/Makefile +--- a/src/flameo/Makefile 2018-10-02 08:46:58.000000000 -0500 ++++ b/src/flameo/Makefile 2020-11-07 20:19:56.732547025 -0600 +@@ -6,9 +6,7 @@ + USRLDFLAGS = -L${LIB_NEWMAT} -L${LIB_PROB} -L${LIB_ZLIB} + + UNAME := $(shell uname) +-ifeq (${UNAME},Darwin) +- LIBS = -liconv +-endif ++LIBS = -liconv + + LIBS += -lutils -lnewimage -lmiscmaths -lm -lnewmat -lNewNifti -lcifti -lxml++-2.6 -lxml2 -lboost_filesystem -lboost_system -lznz -lprob -lz + +diff -ru a/src/melodic/Makefile b/src/melodic/Makefile +--- a/src/melodic/Makefile 2020-03-30 08:51:19.000000000 -0500 ++++ b/src/melodic/Makefile 2020-11-07 20:21:45.625518576 -0600 +@@ -11,9 +11,7 @@ + USRLDFLAGS = -L${LIB_NEWMAT} -L${LIB_PROB} -L${LIB_GD} -L${LIB_GDC} -L${LIB_PNG} -L${LIB_ZLIB} + + UNAME := $(shell uname) +-ifeq (${UNAME},Darwin) +- LIBS = -liconv +-endif ++LIBS = -liconv + + LIBS += -lutils -lnewimage -lmiscplot -lmiscpic -lmiscmaths -lNewNifti -lcifti -lxml++-2.6 -lxml2 -lboost_filesystem -lboost_system -lznz -lnewmat -lprob -lm -lgdc -lgd -lpng -lz + diff --git a/var/spack/repos/builtin/packages/fsl/package.py b/var/spack/repos/builtin/packages/fsl/package.py index 35f4978698..5511096e53 100644 --- a/var/spack/repos/builtin/packages/fsl/package.py +++ b/var/spack/repos/builtin/packages/fsl/package.py @@ -8,42 +8,157 @@ from spack.util.environment import EnvironmentModifications import os -class Fsl(Package): +class Fsl(Package, CudaPackage): """FSL is a comprehensive library of analysis tools for FMRI, MRI and DTI - brain imaging data. + brain imaging data.""" - Note: A manual download is required for FSL. - Spack will search your current directory for the download file. - Alternatively, add this file to a mirror so that Spack can find it. - For instructions on how to set up a mirror, see - http://spack.readthedocs.io/en/latest/mirrors.html""" + # NOTE: A manual download is required for FSL. Spack will search your + # current directory for the download file. Alternatively, add this file to + # a mirror so that Spack can find it. For instructions on how to set up a + # mirror, see http://spack.readthedocs.io/en/latest/mirrors.html homepage = "https://fsl.fmrib.ox.ac.uk" url = "file://{0}/fsl-5.0.10-sources.tar.gz".format(os.getcwd()) manual_download = True - version('5.0.10', '64823172a08aad679833240ba64c8e30') + version('6.0.4', sha256='58b88f38e080b05d70724d57342f58e1baf56e2bd3b98506a72b4446cad5033e') + version('5.0.10', sha256='ca183e489320de0e502a7ba63230a7f55098917a519e8c738b005d526e700842') depends_on('python', type=('build', 'run')) depends_on('expat') depends_on('libx11') depends_on('glu') - depends_on('zlib') - depends_on('libpng') - depends_on('boost') - depends_on('sqlite') - - conflicts('%gcc@6:', when='@5.0.10') + depends_on('libiconv') + depends_on('openblas', when='@6:') + depends_on('vtk@:8') + + conflicts('%gcc@:4.7,5.5:') + conflicts('^cuda@9.2:') + conflicts('cuda_arch=none', when='+cuda', + msg='must select a CUDA architecture') + conflicts('platform=darwin', + msg='currently only packaged for linux') + + patch('build_log.patch') + patch('eddy_Makefile.patch', when='@6:') + patch('iconv.patch') + patch('fslpython_install_v5.patch', when='@:5') + patch('fslpython_install_v6.patch', when='@6:') + + # These patches disable FSL's attempts to try to submit a subset of FSL + # computations to an SGE queue system. That auto-submit mechanism only + # works for SGE and requires someone to edit the fsl_sub script to + # accommodate their system. These patches disable the auto submission + # scheme and allow the fsl_sub script to behave the same on all systems, + # and without further modification, whether the computation is submitted to + # a "local" system, like a workstation, or as a batch job to a cluster + # queueing system, regardless of queue system type. + patch('fsl_sub_v5.patch', when='@:5') + patch('fsl_sub_v6.patch', when='@6:') def patch(self): # Uncomment lines in source file to allow building from source with working_dir(join_path(self.stage.source_path, 'etc', 'fslconf')): sourced = FileFilter('fsl.sh') sourced.filter('#FSLCONFDIR', 'FSLCONFDIR') - sourced.filter('#FSLMACHTYPE', 'FSLMACHTYPE') - # Fix error in build script - buildscript = FileFilter('build') - buildscript.filter('mist-clean', 'mist') + + if self.spec.satisfies('@6:'): + sourced.filter('#FSLMACHTYPE', 'FSLMACHTYPE') + else: + sourced.filter(r'#(FSLMACHTYPE).*', r'\1=linux_64-gcc4.8') + + if self.spec.satisfies('@:5'): + with working_dir(join_path(self.stage.source_path, 'config', + 'common')): + buildproj = FileFilter('buildproj') + buildproj.filter(r'(^FSLMACHTYPE).*', r'\1=linux_64-gcc4.8') + + # Capture the settings file + if self.spec.satisfies('@6:'): + settings_file = join_path(self.stage.source_path, 'config', + 'buildSettings.mk') + vtk_file = settings_file + else: + settings_file = join_path(self.stage.source_path, 'config', + 'linux_64-gcc4.8', 'systemvars.mk') + externals_file = join_path(self.stage.source_path, 'config', + 'linux_64-gcc4.8', 'externallibs.mk') + vtk_file = externals_file + + build_settings = FileFilter(settings_file) + vtk_settings = FileFilter(vtk_file) + + build_settings.filter(r'^CUDAVER', '#CUDAVER') + build_settings.filter(r'(^CC)\s*=.*', r'\1 = {0}'.format(spack_cc)) + build_settings.filter(r'(^CXX)\s*=.*', r'\1 = {0}'.format(spack_cxx)) + build_settings.filter(r'(^CXX11)\s*=.*', r'\1 = {0}'.format(spack_cxx)) + + vtk_suffix = self.spec['vtk'].version.up_to(2) + vtk_lib_dir = self.spec['vtk'].prefix.lib64 + vtk_include_dir = join_path(self.spec['vtk'].prefix.include, + 'vtk-{0}'.format(vtk_suffix)) + + vtk_settings.filter(r'(^VTKDIR_INC)\s*=.*', + r'\1 = {0}'.format(vtk_include_dir)) + vtk_settings.filter(r'(^VTKDIR_LIB)\s*=.*', + r'\1 = {0}'.format(vtk_lib_dir)) + vtk_settings.filter(r'(^VTKSUFFIX)\s*=.*', + r'\1 = -{0}'.format(vtk_suffix)) + + if '+cuda' in self.spec: + cuda_arch = self.spec.variants['cuda_arch'].value + cuda_gencode = ' '.join(self.cuda_flags(cuda_arch)) + cuda_installation = self.spec['cuda'].prefix + + build_settings.filter(r'(^CUDA_INSTALLATION)\s*=.*', + r'\1 = {0}'.format(cuda_installation)) + build_settings.filter(r'(^LIB_CUDA)\s*=.*', + r'\1 = {0}'.format( + join_path( + cuda_installation, + 'lib64'))) + build_settings.filter(r'(^INC_CUDA)\s*=.*', + r'\1 = {0}'.format( + join_path( + cuda_installation, + 'include'))) + build_settings.filter(r'(^NVCC11)\s*=.*', + r'\1 = {0}'.format( + join_path( + cuda_installation, 'bin', + 'nvcc'))) + build_settings.filter(r'(^NVCC)\s*=.*', + r'\1 = {0}'.format( + join_path( + cuda_installation, 'bin', + 'nvcc'))) + build_settings.filter(r'(^GENCODE_FLAGS)\s*=.*', + r'\1 = {0}'.format(cuda_gencode)) + + if self.spec.satisfies('@6:'): + build_settings.filter(r'(^EDDYBUILDPARAMETERS)\s*=.*', + r'\1 = "cuda=1" "cpu=1"') + build_settings.filter(r'(^fdt_MASTERBUILD)\s*=.*', + r'\1 = COMPILE_GPU=1') + build_settings.filter(r'(^ptx2_MASTERBUILD)\s*=.*', + r'\1 = COMPILE_GPU=1') + else: + with open(settings_file, 'a') as f: + f.write('COMPILE_GPU=1\n') + else: + build_settings.filter(r'^CUDA_INSTALLATION', '#CUDA_INSTALLATION') + build_settings.filter(r'^GENCODE_FLAGS', '#GENCODE_FLAGS') + build_settings.filter(r'^LIB_CUDA', '#LIB_CUDA') + build_settings.filter(r'^INC_CUDA', '#INC_CUDA') + build_settings.filter(r'^NVCC', '#NVCC') + + if self.spec.satisfies('@6:'): + build_settings.filter(r'(^EDDYBUILDPARAMETERS)\s*=.*', + r'\1 = "cpu=1"') + build_settings.filter(r'(^fdt_MASTERBUILD)\s*=.*', + r'\1 = COMPILE_GPU=0') + build_settings.filter(r'(^ptx2_MASTERBUILD)\s*=.*', + r'\1 = COMPILE_GPU=0') def install(self, spec, prefix): build = Executable('./build') @@ -51,6 +166,20 @@ class Fsl(Package): install_tree('.', prefix) + @run_after('install') + def postinstall(self): + # The PYTHON related environment variables need to be unset here so + # the post install script does not get confused. + vars_to_unset = ['PYTHONPATH', 'PYTHONHOME'] + + with spack.util.environment.preserve_environment(*vars_to_unset): + for v in vars_to_unset: + del os.environ[v] + + script = Executable(join_path(prefix, 'etc', 'fslconf', + 'post_install.sh')) + script('-f', prefix) + def setup_build_environment(self, env): if not self.stage.source_path: self.stage.fetch() @@ -66,18 +195,9 @@ class Fsl(Package): env.extend(EnvironmentModifications.from_sourcing_file(fslsetup)) def setup_run_environment(self, env): - # Here, run-time environment variables are being set manually. - # Normally these would be added to the modulefile at build-time - # by sourcing fsl.sh, but incorrect paths were being set, pointing to - # the staging directory rather than the install directory. + # Set the environment variables after copying tree env.set('FSLDIR', self.prefix) - env.set('FSLOUTPUTTYPE', 'NIFTI_GZ') - env.set('FSLMULTIFILEQUIT', 'TRUE') - env.set('FSLTCLSH', self.prefix.bin.fsltclsh) - env.set('FSLWISH', self.prefix.bin.fslwish) - env.set('FSLLOCKDIR', '') - env.set('FSLMACHINELIST', '') - env.set('FSLREMOTECALL', '') - env.set('FSLGECUDAQ', 'cuda.q') - - env.prepend_path('PATH', self.prefix) + fslsetup = join_path(self.prefix, 'etc', 'fslconf', 'fsl.sh') + + if os.path.isfile(fslsetup): + env.extend(EnvironmentModifications.from_sourcing_file(fslsetup)) |