Skip to content
27 changes: 24 additions & 3 deletions easybuild/easyblocks/c/cuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@author: Robert Mijakovic (LuxProvide S.A.)
"""
import os
import re
import stat

from distutils.version import LooseVersion
Expand All @@ -43,8 +44,8 @@
from easybuild.framework.easyconfig import CUSTOM
from easybuild.tools.build_log import EasyBuildError
from easybuild.tools.config import IGNORE
from easybuild.tools.filetools import adjust_permissions, copy_dir, patch_perl_script_autoflush
from easybuild.tools.filetools import remove_file, symlink, which, write_file
from easybuild.tools.filetools import adjust_permissions, change_dir, copy_dir, expand_glob_paths
from easybuild.tools.filetools import patch_perl_script_autoflush, remove_file, symlink, which, write_file
from easybuild.tools.run import run_cmd, run_cmd_qa
from easybuild.tools.systemtools import AARCH64, POWER, X86_64, get_cpu_architecture, get_shared_lib_ext
import easybuild.tools.environment as env
Expand Down Expand Up @@ -201,7 +202,10 @@ def install_step(self):
run_cmd("/bin/sh " + patch['path'] + " --accept-eula --silent --installdir=" + self.installdir)

def post_install_step(self):
"""Create wrappers for the specified host compilers and generate the appropriate stub symlinks"""
"""
Create wrappers for the specified host compilers, generate the appropriate stub symlinks and create version
independent pkgconfig files
"""
def create_wrapper(wrapper_name, wrapper_comp):
"""Create for a particular compiler, with a particular name"""
wrapper_f = os.path.join(self.installdir, 'bin', wrapper_name)
Expand Down Expand Up @@ -243,6 +247,17 @@ def create_wrapper(wrapper_name, wrapper_comp):
# Also create the lib dir as a symlink
symlink('lib64', os.path.join(new_stubs_dir, 'lib'), use_abspath_source=False)

# Packages like xpra look for version independent pc files.
# See e.g. https://github.com/Xpra-org/xpra/blob/master/setup.py#L206
# Distros provide these files, so let's do it here too
pkgconfig_dir = os.path.join(self.installdir, 'pkgconfig')
pc_files = expand_glob_paths([os.path.join(pkgconfig_dir, '*.pc')])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't always work apparently, fails with CUDA 10.1.105 because there are no pkgconfig files included at all:

No files found using glob pattern
'/user/gent/400/vsc40023/eb_arcaninescratch/CO7/skylake-ib/software/CUDA/10.1.105-GCC-8.2.0-2.31.1/pkgconfig/*.pc`

So this should be guarded with:

if os.path.exists(pkgconfig_dir):

@damianam Does that make sense to you?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the 10.x versions we have installed have a pkgconfig dir. So it's clearly needed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the module generation needs to have this protected. Don't add nonexisting paths to PKG_CONFIG_PATH

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Update coming

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed an update to address that. Note that I readded some of the pc files in the sanity check list. That's because those files are explicitly checked by other tools (and actually nvjpeg.pc is the whole reason for this PR), so I guess it makes sense to add them. Or are they not present in older CUDA releases?

change_dir(pkgconfig_dir)
for pc_file in pc_files:
pc_file = os.path.basename(pc_file)
link = re.sub('-[0-9]*.?[0-9]*(.[0-9]*)?.pc', '.pc', pc_file)
symlink(pc_file, link, use_abspath_source=False)

super(EB_CUDA, self).post_install_step()

def sanity_check_step(self):
Expand All @@ -266,6 +281,11 @@ def sanity_check_step(self):
custom_paths['files'].append(os.path.join("extras", "CUPTI", "lib64", "libcupti.%s") % shlib_ext)
custom_paths['dirs'].append(os.path.join("extras", "CUPTI", "include"))

# Just a subset of files are checked, since the whole list is likely to change, and irrelevant in most cases
# anyway
pc_files = ['cublas.pc', 'cudart.pc', 'cuda.pc', 'nvidia-ml.pc', 'nvjpeg.pc']
custom_paths['files'].append(os.path.join('pkgconfig', x) for x in pc_files)

super(EB_CUDA, self).sanity_check_step(custom_paths=custom_paths)

def make_module_extra(self):
Expand Down Expand Up @@ -308,6 +328,7 @@ def make_module_req_guess(self):
'LD_LIBRARY_PATH': lib_path,
'LIBRARY_PATH': ['lib64', os.path.join('stubs', 'lib64')],
'CPATH': inc_path,
'PKG_CONFIG_PATH': ['pkgconfig'],
})

return guesses