relion: add altcpu variant and fix fftw (#30097)
This package was not setting FFTW when +mklfft was used with +cuda.
Since both were set to 'True', the default build was not linked to
any FFTW, leading to a run time error. It seems MKL support was
conflated with alternative CPU acceleration support. This PR does the
following:
- adds the altcpu variant to specify non-GPU/CPU acceleration
- sets a conflict between +altcpu and +cuda
- sets an FFTW implementation
- sets fltk+xft when +gui to get a decent looking GUI interface
- sets tbb dependency only when +altcpu
- adds dependency on ctffind
- adds variant and dependency on motioncor2
- sets defaults for
    - qsub template location
    - ctffind location
    - motioncor2 location
Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
			
			
This commit is contained in:
		@@ -36,35 +36,52 @@ class Relion(CMakePackage, CudaPackage):
 | 
				
			|||||||
    variant('cuda', default=True, description="enable compute on gpu")
 | 
					    variant('cuda', default=True, description="enable compute on gpu")
 | 
				
			||||||
    variant('double', default=True, description="double precision (cpu) code")
 | 
					    variant('double', default=True, description="double precision (cpu) code")
 | 
				
			||||||
    variant('double-gpu', default=False, description="double precision gpu")
 | 
					    variant('double-gpu', default=False, description="double precision gpu")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # if built with purpose=cluster then relion will link to gpfs libraries
 | 
					    # if built with purpose=cluster then relion will link to gpfs libraries
 | 
				
			||||||
    # if that's not desirable then use purpose=desktop
 | 
					    # if that's not desirable then use purpose=desktop
 | 
				
			||||||
    variant('purpose', default='cluster', values=('cluster', 'desktop'),
 | 
					    variant('purpose', default='cluster', values=('cluster', 'desktop'),
 | 
				
			||||||
            description="build relion for use in cluster or desktop")
 | 
					            description="build relion for use in cluster or desktop")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    variant('build_type', default='RelWithDebInfo',
 | 
					    variant('build_type', default='RelWithDebInfo',
 | 
				
			||||||
            description='The build type to build',
 | 
					            description='The build type to build',
 | 
				
			||||||
            values=('Debug', 'Release', 'RelWithDebInfo',
 | 
					            values=('Debug', 'Release', 'RelWithDebInfo',
 | 
				
			||||||
                    'Profiling', 'Benchmarking'))
 | 
					                    'Profiling', 'Benchmarking'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # these new values were added in relion 3
 | 
				
			||||||
 | 
					    # do not seem to cause problems with < 3
 | 
				
			||||||
    variant('mklfft', default=True, description='Use MKL rather than FFTW for FFT')
 | 
					    variant('mklfft', default=True, description='Use MKL rather than FFTW for FFT')
 | 
				
			||||||
    variant('allow_ctf_in_sagd', default=True, description='Allow CTF-modulation in SAGD, as specified in Claim 1 of patent US10,282,513B2')
 | 
					    variant('allow_ctf_in_sagd', default=True, description='Allow CTF-modulation in SAGD, as specified in Claim 1 of patent US10,282,513B2')
 | 
				
			||||||
 | 
					    variant('altcpu', default=False, description='Use CPU acceleration', when='~cuda')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    variant('external_motioncor2',
 | 
				
			||||||
 | 
					            default=False,
 | 
				
			||||||
 | 
					            description='Have external motioncor2 available in addition to '
 | 
				
			||||||
 | 
					            'Relion builtin')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    depends_on('mpi')
 | 
					    depends_on('mpi')
 | 
				
			||||||
    depends_on('cmake@3:', type='build')
 | 
					    depends_on('cmake@3:', type='build')
 | 
				
			||||||
    depends_on('fftw precision=float,double', when='~mklfft')
 | 
					    depends_on('fftw precision=float,double', when='~mklfft')
 | 
				
			||||||
    depends_on('fltk', when='+gui')
 | 
					
 | 
				
			||||||
 | 
					    # use the +xft variant so the interface is not so horrible looking
 | 
				
			||||||
 | 
					    depends_on('fltk+xft', when='+gui')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    depends_on('libtiff')
 | 
					    depends_on('libtiff')
 | 
				
			||||||
    depends_on('libpng', when='@4:')
 | 
					    depends_on('libpng', when='@4:')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    depends_on('cuda', when='+cuda')
 | 
					    depends_on('cuda', when='+cuda')
 | 
				
			||||||
    depends_on('cuda@9:', when='@3: +cuda')
 | 
					    depends_on('cuda@9:', when='@3: +cuda')
 | 
				
			||||||
    depends_on('tbb', when='~cuda')
 | 
					    depends_on('tbb', when='+altcpu')
 | 
				
			||||||
    depends_on('mkl', when='~cuda +mklfft')
 | 
					    depends_on('mkl', when='+mklfft')
 | 
				
			||||||
 | 
					    depends_on('ctffind', type='run')
 | 
				
			||||||
 | 
					    depends_on('motioncor2', type='run', when='+external_motioncor2')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # TODO: more externals to add
 | 
				
			||||||
 | 
					    # Spack packages needed
 | 
				
			||||||
 | 
					    # - Gctf
 | 
				
			||||||
 | 
					    # - ResMap
 | 
				
			||||||
    patch('0002-Simple-patch-to-fix-intel-mkl-linking.patch', when='@:3.1.1 os=ubuntu18.04')
 | 
					    patch('0002-Simple-patch-to-fix-intel-mkl-linking.patch', when='@:3.1.1 os=ubuntu18.04')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def cmake_args(self):
 | 
					    def cmake_args(self):
 | 
				
			||||||
 | 
					 | 
				
			||||||
        carch = self.spec.variants['cuda_arch'].value[0]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        args = [
 | 
					        args = [
 | 
				
			||||||
            '-DCMAKE_C_FLAGS=-g',
 | 
					            '-DCMAKE_C_FLAGS=-g',
 | 
				
			||||||
            '-DCMAKE_CXX_FLAGS=-g',
 | 
					            '-DCMAKE_CXX_FLAGS=-g',
 | 
				
			||||||
@@ -72,20 +89,24 @@ def cmake_args(self):
 | 
				
			|||||||
            '-DDoublePrec_CPU=%s' % ('+double' in self.spec),
 | 
					            '-DDoublePrec_CPU=%s' % ('+double' in self.spec),
 | 
				
			||||||
            '-DDoublePrec_GPU=%s' % ('+double-gpu' in self.spec),
 | 
					            '-DDoublePrec_GPU=%s' % ('+double-gpu' in self.spec),
 | 
				
			||||||
            '-DALLOW_CTF_IN_SAGD=%s' % ('+allow_ctf_in_sagd' in self.spec),
 | 
					            '-DALLOW_CTF_IN_SAGD=%s' % ('+allow_ctf_in_sagd' in self.spec),
 | 
				
			||||||
 | 
					            '-DMKLFFT=%s' % ('+mklfft' in self.spec),
 | 
				
			||||||
 | 
					            '-DALTCPU=%s' % ('+altcpu' in self.spec),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if '+cuda' in self.spec:
 | 
					        if '+cuda' in self.spec:
 | 
				
			||||||
            # relion+cuda requires selecting cuda_arch
 | 
					            carch = self.spec.variants['cuda_arch'].value[0]
 | 
				
			||||||
            if not carch:
 | 
					 | 
				
			||||||
                raise ValueError("select cuda_arch when building with +cuda")
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                args += ['-DCUDA=ON', '-DCudaTexture=ON',
 | 
					 | 
				
			||||||
                         '-DCUDA_ARCH=%s' % (carch)]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # these new values were added in relion 3
 | 
					            # relion+cuda requires selecting cuda_arch
 | 
				
			||||||
        # do not seem to cause problems with < 3
 | 
					            if carch == 'none':
 | 
				
			||||||
        else:
 | 
					                raise ValueError(
 | 
				
			||||||
            args += ['-DMKLFFT=%s' % ('+mklfft' in self.spec), '-DALTCPU=ON']
 | 
					                    'Must select a value for cuda_arch'
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                args += [
 | 
				
			||||||
 | 
					                    '-DCUDA=ON',
 | 
				
			||||||
 | 
					                    '-DCudaTexture=ON',
 | 
				
			||||||
 | 
					                    '-DCUDA_ARCH=%s' % (carch),
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return args
 | 
					        return args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -93,3 +114,19 @@ def patch(self):
 | 
				
			|||||||
        # Remove flags not recognized by the NVIDIA compilers
 | 
					        # Remove flags not recognized by the NVIDIA compilers
 | 
				
			||||||
        if self.spec.satisfies('%nvhpc'):
 | 
					        if self.spec.satisfies('%nvhpc'):
 | 
				
			||||||
            filter_file('-std=c99', '-c99', 'src/apps/CMakeLists.txt')
 | 
					            filter_file('-std=c99', '-c99', 'src/apps/CMakeLists.txt')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # set up some defaults
 | 
				
			||||||
 | 
					        filter_file(r'(#define DEFAULTQSUBLOCATION).*',
 | 
				
			||||||
 | 
					                    r'\1 "{0}"'.format(join_path(self.spec.prefix.bin,
 | 
				
			||||||
 | 
					                                                 'relion_qsub.csh')),
 | 
				
			||||||
 | 
					                    join_path('src', 'pipeline_jobs.h'))
 | 
				
			||||||
 | 
					        filter_file(r'(#define DEFAULTCTFFINDLOCATION).*',
 | 
				
			||||||
 | 
					                    r'\1 "{0}"'.format(join_path(
 | 
				
			||||||
 | 
					                        self.spec['ctffind'].prefix.bin, 'ctffind')),
 | 
				
			||||||
 | 
					                    join_path('src', 'pipeline_jobs.h'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if '+external_motioncor2' in self.spec:
 | 
				
			||||||
 | 
					            filter_file(r'(#define DEFAULTMOTIONCOR2LOCATION).*',
 | 
				
			||||||
 | 
					                        r'\1 "{0}"'.format(join_path(
 | 
				
			||||||
 | 
					                            self.spec['motioncor2'].prefix.bin, 'MotionCor2')),
 | 
				
			||||||
 | 
					                        join_path('src', 'pipeline_jobs.h'))
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user