Skip to content

fix cudnn hook for non eessi installation #1099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 42 additions & 39 deletions eb_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def parse_hook_freeimage_aarch64(ec, *args, **kwargs):
ec['toolchainopts'] = {}
ec['toolchainopts']['pic'] = True
ec['toolchainopts']['extra_cflags'] = '-DPNG_ARM_NEON_OPT=0'
print_msg("Changed toolchainopts for %s: %s", ec.name, ec['toolchainopts'])
print_msg("Changed toolchainopts for %s: %s", ec.name, ec['toolchainopts'])


def parse_hook_zen4_module_only(ec, eprefix):
Expand Down Expand Up @@ -989,7 +989,7 @@ def post_postproc_cuda(self, *args, **kwargs):
and replace them with a symlink to a corresponding installation under host_injections.
"""
if self.name == 'CUDA':
# This hook only acts on an installation under repositories that _we_ ship (*.eessi.io/versions)
# This hook only acts on an installation under repositories that _we_ ship (*.eessi.io/versions)
eessi_installation = bool(re.search(EESSI_INSTALLATION_REGEX, self.installdir))

if eessi_installation:
Expand Down Expand Up @@ -1048,43 +1048,46 @@ def post_postproc_cudnn(self, *args, **kwargs):
and replace them with a symlink to a corresponding installation under host_injections.
"""

# We need to check if we are doing an EESSI-distributed installation
eessi_installation = bool(re.search(EESSI_INSTALLATION_REGEX, self.installdir))

if self.name == 'cuDNN' and eessi_installation:
print_msg("Replacing files in cuDNN installation that we can not ship with symlinks to host_injections...")

allowlist = ['LICENSE']

# read cuDNN LICENSE, construct allowlist based on section "2. Distribution" that specifies list of files that can be shipped
license_path = os.path.join(self.installdir, 'LICENSE')
search_string = "2. Distribution. The following portions of the SDK are distributable under the Agreement:"
found_search_string = False
with open(license_path) as infile:
for line in infile:
if line.strip().startswith(search_string):
found_search_string = True
# remove search string, split into words, remove trailing
# dots '.' and only retain words starting with a dot '.'
distributable = line[len(search_string):]
# distributable looks like ' the runtime files .so and .dll.'
# note the '.' after '.dll'
for word in distributable.split():
if word[0] == '.':
# rstrip is used to remove the '.' after '.dll'
allowlist.append(word.rstrip('.'))
if not found_search_string:
# search string wasn't found in LICENSE file
raise EasyBuildError("search string '%s' was not found in license file '%s';"
"hence installation may be replaced by symlinks only",
search_string, license_path)

allowlist = sorted(set(allowlist))
self.log.info("Allowlist for files in cuDNN installation that can be redistributed: " + ', '.join(allowlist))

# replace files that are not distributable with symlinks into
# host_injections
replace_non_distributable_files_with_symlinks(self.log, self.installdir, self.name, allowlist)
if self.name == 'cuDNN':
# This hook only acts on an installation under repositories that _we_ ship (*.eessi.io/versions)
eessi_installation = bool(re.search(EESSI_INSTALLATION_REGEX, self.installdir))

if eessi_installation:
print_msg("Replacing files in cuDNN installation that we can not ship with symlinks to host_injections...")

allowlist = ['LICENSE']

# read cuDNN LICENSE, construct allowlist based on section "2. Distribution" that specifies list of files that can be shipped
license_path = os.path.join(self.installdir, 'LICENSE')
search_string = "2. Distribution. The following portions of the SDK are distributable under the Agreement:"
found_search_string = False
with open(license_path) as infile:
for line in infile:
if line.strip().startswith(search_string):
found_search_string = True
# remove search string, split into words, remove trailing
# dots '.' and only retain words starting with a dot '.'
distributable = line[len(search_string):]
# distributable looks like ' the runtime files .so and .dll.'
# note the '.' after '.dll'
for word in distributable.split():
if word[0] == '.':
# rstrip is used to remove the '.' after '.dll'
allowlist.append(word.rstrip('.'))
if not found_search_string:
# search string wasn't found in LICENSE file
raise EasyBuildError("search string '%s' was not found in license file '%s';"
"hence installation may be replaced by symlinks only",
search_string, license_path)

allowlist = sorted(set(allowlist))
self.log.info("Allowlist for files in cuDNN installation that can be redistributed: " + ', '.join(allowlist))

# replace files that are not distributable with symlinks into
# host_injections
replace_non_distributable_files_with_symlinks(self.log, self.installdir, self.name, allowlist)
else:
print_msg(f"EESSI hook to respect cuDDN license not triggered for installation path {self.installdir}")
else:
raise EasyBuildError("cuDNN-specific hook triggered for non-cuDNN easyconfig?!")

Expand Down