diff --git a/Custom_Hooks/eb_hooks.py b/Custom_Hooks/eb_hooks.py index 1aa463c96688e1be7143479902f029c816968938..24a85cd86f60c01fbee7a99d3181b33f1af2ef0e 100644 --- a/Custom_Hooks/eb_hooks.py +++ b/Custom_Hooks/eb_hooks.py @@ -47,11 +47,22 @@ VETOED_INSTALLATIONS = { 'juwelsbooster': ['impi', 'impi-settings', 'BullMPI', 'BullMPI-settings'], 'juwels': ['BullMPI', 'BullMPI-settings'], 'jurecadc': [''], - 'jurecabooster': ['OpenMPI', 'OpenMPI-settings', 'CUDA', 'nvidia-driver', 'UCX', 'NVHPC', 'BullMPI', 'BullMPI-settings'], + 'jurecabooster': [ + 'OpenMPI', 'OpenMPI-settings', + 'CUDA', 'nvidia-driver', + 'UCX', 'UCX-settings', + 'NCCL', 'NCCL-settings', 'NVHPC', + 'BullMPI', 'BullMPI-settings' + ], 'jusuf': ['impi', 'impi-settings', 'BullMPI', 'BullMPI-settings'], 'hdfml': ['BullMPI', 'BullMPI-settings'], } +TWEAKABLE_DEPENDENCIES = { + 'UCX': 'default', + 'CUDA': '11.5', +} + common_site_contact = 'Support <sc@fz-juelich.de>' # Also maintain a list of CUDA enabled compilers @@ -106,8 +117,10 @@ def get_user_info(): if name and email: return [name, email] else: - print_warning(f"\n'jutil' is not present and 'SITE_CONTACT_NAME' or 'SITE_CONTACT_EMAIL' are not defined\n" - "Please defined both in your environment and try again\n") + print_warning( + f"\n'jutil' is not present and 'SITE_CONTACT_NAME' or 'SITE_CONTACT_EMAIL' are not defined\n" + "Please defined both in your environment and try again\n" + ) exit(1) else: return ['CI user', 'ci_user@fz-juelich.de'] @@ -183,90 +196,66 @@ def inject_site_contact(ec, site_contacts): # ec[key] = value return ec - def parse_hook(ec, *args, **kwargs): """Custom parse hook to manage installations intended for JSC systems.""" - + # First of all check if this should be installed installation_vetoer(ec) - ec_dict = ec.asdict() - # Compilers are are a family (in the Lmod sense) - if ec.name in SUPPORTED_COMPILERS: - key = "modluafooter" - value = 'family("compiler")' - if key in ec_dict: - if not value in ec_dict[key]: - ec[key] = "\n".join([ec[key], value]) - else: - ec[key] = value - ec.log.info("[parse hook] Injecting Lmod compiler family") - # Supported compilers should also be recursively unloaded - key = "recursive_module_unload" - if not key in ec_dict or ec_dict[key] is None: - ec[key] = True - ec.log.info( - "[parse hook] Injecting recursive module unloading for supported compiler" - ) + # Process compiler options + ec = inject_compiler_features(ec) - # Update the dict - ec_dict = ec.asdict() - # MPIs are a family (in the Lmod sense) and require to load mpi-settings - if ec.name in SUPPORTED_MPIS and '/p/software' in install_path().lower(): - key = "modluafooter" - value = ''' -if not ( isloaded("mpi-settings") ) then - load("mpi-settings") -end -family("mpi") - ''' - if key in ec_dict: - if not value in ec_dict[key]: - ec[key] = "\n".join([ec[key], value]) - else: - ec[key] = value - ec.log.info( - "[parse hook] Injecting Lmod mpi family and mpi-settings loading") + # Process MPI options + ec = inject_mpi_features(ec) - # Check if we need to use 'modaltsoftname' - if ec.name in REQUIRE_MODALTSOFTNAME: - key = "modaltsoftname" - if not key in ec_dict or ec_dict[key] is None: - ec[key] = REQUIRE_MODALTSOFTNAME[ec.name] - ec.log.info( - "[parse hook] Injecting modaltsoftname '%s' for '%s'", - key, - REQUIRE_MODALTSOFTNAME[ec.name], - ) + # Change module name if applicable + ec = inject_modaltsoftname(ec) - # Check if the module should be installed as hidden - hidden_pkgs = os.getenv('EASYBUILD_HIDE_DEPS', '').split(',') - if ec.name in hidden_pkgs: - key = "hidden" - if not key in ec_dict or ec_dict[key] is False: - ec[key] = True - ec.log.info( - "[parse hook] Hiding software found in $EASYBUILD_HIDE_DEPS: %s", - ec.name, - ) + ec = inject_hidden_property(ec) - # Update the dict - ec_dict = ec.asdict() - # Check if CUDA is in the dependencies, if so add the GPU Lmod tag - if ( - "CUDA" in [dep[0] for dep in iter(ec_dict["dependencies"])] - or ec_dict["toolchain"]["name"] in CUDA_ENABLED_TOOLCHAINS - ): - key = "modluafooter" - value = 'add_property("arch","gpu")' - if key in ec_dict: - if not value in ec_dict[key]: - ec[key] = "\n".join([ec_dict[key], value]) + ec = inject_gpu_property(ec) + + ec = inject_site_contact_and_user_labels(ec) + + ec = tweak_dependencies(ec) + + # If we are parsing we are not searching, in this case if the easyconfig is + # located in the search path, warn that it's dependencies will (most probably) + # not be resolved + if build_option("robot"): + search_paths = build_option("search_paths") or [] + robot_paths = list( + set(build_option("robot_path") + build_option("robot"))) + if ec.path: + ec_dir_path = os.path.dirname(os.path.abspath(ec.path)) else: - ec[key] = value - ec.log.info("[parse hook] Injecting gpu as Lmod arch property") + ec_dir_path = '' + if any(search_path in ec_dir_path for search_path in search_paths) and not any( + robot_path in ec_dir_path for robot_path in robot_paths + ): + raise EasyBuildError( + "\nYou are attempting to install an easyconfig distributed with " + "EasyBuild but are not properly configured to resolve dependencies " + "for this case. Please add additonal options:\n" + " eb --robot=$EASYBUILD_ROBOT:$EBROOTEASYBUILD/easybuild/easyconfigs --try-update-deps ...." + ) + +def tweak_dependencies(ec): + for dep_type in ["dependencies", "builddependencies"]: + dependencies = ec[dep_type] + # Check for dependencies to be tweaked. This assumes simply that the version is + # being overwritten + for dep_to_tweak in TWEAKABLE_DEPENDENCIES: + for dep in dependencies: + if dep_to_tweak in dep[0]: + list_dep = list(dep) + list_dep[1] = TWEAKABLE_DEPENDENCIES[dep_to_tweak] + dependencies[dependencies.index(dep)] = tuple(list_dep) + ec[dep_type] = dependencies - # Update the dict + return ec + +def inject_site_contact_and_user_labels(ec): ec_dict = ec.asdict() # Check where installations are going to go and add appropriate site contact # not sure of a fool-proof way to do this, let's just try a heuristic @@ -298,27 +287,96 @@ family("mpi") installer_name, installer_email, default_contact=False) ec = inject_site_contact(ec, site_contacts) - # If we are parsing we are not searching, in this case if the easyconfig is - # located in the search path, warn that it's dependencies will (most probably) - # not be resolved - if build_option("robot"): - search_paths = build_option("search_paths") or [] - robot_paths = list( - set(build_option("robot_path") + build_option("robot"))) - if ec.path: - ec_dir_path = os.path.dirname(os.path.abspath(ec.path)) + return ec + +def inject_gpu_property(ec): + ec_dict = ec.asdict() + # Check if CUDA is in the dependencies, if so add the GPU Lmod tag + if ( + "CUDA" in [dep[0] for dep in iter(ec_dict["dependencies"])] + or ec_dict["toolchain"]["name"] in CUDA_ENABLED_TOOLCHAINS + ): + key = "modluafooter" + value = 'add_property("arch","gpu")' + if key in ec_dict: + if not value in ec_dict[key]: + ec[key] = "\n".join([ec_dict[key], value]) else: - ec_dir_path = '' - if any(search_path in ec_dir_path for search_path in search_paths) and not any( - robot_path in ec_dir_path for robot_path in robot_paths - ): - raise EasyBuildError( - "\nYou are attempting to install an easyconfig distributed with " - "EasyBuild but are not properly configured to resolve dependencies " - "for this case. Please add additonal options:\n" - " eb --robot=$EASYBUILD_ROBOT:$EBROOTEASYBUILD/easybuild/easyconfigs --try-update-deps ...." + ec[key] = value + ec.log.info("[parse hook] Injecting gpu as Lmod arch property") + + return ec + +def inject_hidden_property(ec): + ec_dict = ec.asdict() + # Check if the module should be installed as hidden + hidden_pkgs = os.getenv('EASYBUILD_HIDE_DEPS', '').split(',') + if ec.name in hidden_pkgs: + key = "hidden" + if not key in ec_dict or ec_dict[key] is False: + ec[key] = True + ec.log.info( + "[parse hook] Hiding software found in $EASYBUILD_HIDE_DEPS: %s", + ec.name, + ) + return ec + +def inject_modaltsoftname(ec): + ec_dict = ec.asdict() + # Check if we need to use 'modaltsoftname' + if ec.name in REQUIRE_MODALTSOFTNAME: + key = "modaltsoftname" + if not key in ec_dict or ec_dict[key] is None: + ec[key] = REQUIRE_MODALTSOFTNAME[ec.name] + ec.log.info( + "[parse hook] Injecting modaltsoftname '%s' for '%s'", + key, + REQUIRE_MODALTSOFTNAME[ec.name], ) + return ec +def inject_mpi_features(ec): + ec_dict = ec.asdict() + # MPIs are a family (in the Lmod sense) and require to load mpi-settings + if ec.name in SUPPORTED_MPIS and '/p/software' in install_path().lower(): + key = "modluafooter" + value = ''' +if not ( isloaded("mpi-settings") ) then + load("mpi-settings") +end +family("mpi") + ''' + if key in ec_dict: + if not value in ec_dict[key]: + ec[key] = "\n".join([ec[key], value]) + else: + ec[key] = value + ec.log.info( + "[parse hook] Injecting Lmod mpi family and mpi-settings loading") + + return ec + +def inject_compiler_features(ec): + ec_dict = ec.asdict() + # Compilers are are a family (in the Lmod sense) + if ec.name in SUPPORTED_COMPILERS: + key = "modluafooter" + value = 'family("compiler")' + if key in ec_dict: + if not value in ec_dict[key]: + ec[key] = "\n".join([ec[key], value]) + else: + ec[key] = value + ec.log.info("[parse hook] Injecting Lmod compiler family") + # Supported compilers should also be recursively unloaded + key = "recursive_module_unload" + if not key in ec_dict or ec_dict[key] is None: + ec[key] = True + ec.log.info( + "[parse hook] Injecting recursive module unloading for supported compiler" + ) + + return ec def pre_ready_hook(self, *args, **kwargs): "When we are building something, do some checks for bad behaviour" diff --git a/Golden_Repo/u/UCX/UCX-1.11.2.eb b/Golden_Repo/u/UCX/UCX-1.11.2.eb index 4f551f94a789b4c058bf4aa0ce989cf37c339c76..51b9f5d34c11ee207148a6453bc071558f94df07 100644 --- a/Golden_Repo/u/UCX/UCX-1.11.2.eb +++ b/Golden_Repo/u/UCX/UCX-1.11.2.eb @@ -9,8 +9,6 @@ An open-source production grade communication framework for data centric and high-performance applications """ -site_contacts = 'Damian Alvarez <d.alvarez@fz-juelich.de>' - toolchain = SYSTEM toolchainopts = {'pic': True} @@ -31,7 +29,7 @@ osdependencies = [OS_PKG_IBVERBS_DEV] dependencies = [ ('zlib', '1.2.11'), ('numactl', '2.0.14'), - ('CUDA', '11.4'), + ('CUDA', '11.5'), ] configopts = '--with-verbs ' # Build OpenFabrics support diff --git a/Golden_Repo/u/UCX/UCX-default.eb b/Golden_Repo/u/UCX/UCX-default.eb new file mode 100644 index 0000000000000000000000000000000000000000..5d10ef922f947217c12d1587ebb4e4cafd4704bf --- /dev/null +++ b/Golden_Repo/u/UCX/UCX-default.eb @@ -0,0 +1,79 @@ +easyblock = 'ConfigureMake' + +name = 'UCX' +version = 'default' +local_realversion = '1.11.2' + +homepage = 'https://www.openucx.org/' +description = """Unified Communication X +An open-source production grade communication framework for data centric +and high-performance applications +""" + +toolchain = SYSTEM +toolchainopts = {'pic': True} + +source_urls = ['https://github.com/openucx/ucx/releases/download/v%(local_realversion)s'] +sources = ['%%(namelower)s-%s.tar.gz' % local_realversion] +checksums = [ + 'deebf86a5344fc2bd9e55449f88c650c4514928592807c9bc6fe4190e516c6df', # ucx-1.11.2.tar.gz +] + +builddependencies = [ + ('binutils', '2.37'), + ('Autotools', '20210726'), + ('pkg-config', '0.29.2'), +] + +osdependencies = [OS_PKG_IBVERBS_DEV] + +dependencies = [ + ('zlib', '1.2.11'), + ('numactl', '2.0.14'), + ('CUDA', '11.5'), +] + +configopts = '--with-verbs ' # Build OpenFabrics support +configopts += '--without-java ' +configopts += '--disable-doxygen-doc ' + +# Enable machine-specific optimizations, default: NO +configopts += '--enable-optimizations ' +# configopts += '--enable-tuning ' # Enable parameter tuning in run-time, default: NO +# Enable thread support in UCP and UCT, default: NO +configopts += '--enable-mt ' +configopts += '--disable-debug ' +configopts += '--disable-logging ' +configopts += '--disable-assertions ' +configopts += '--disable-params-check ' +configopts += '--disable-dependency-tracking ' +configopts += '--with-cuda=$EBROOTCUDA ' + +configopts += '--enable-cma ' # Enable Cross Memory Attach + +# Compile with IB Reliable Connection support +configopts += '--with-rc ' +# Compile with IB Unreliable Datagram support +configopts += '--with-ud ' +# Compile with IB Dynamic Connection support +configopts += '--with-dc ' +configopts += '--with-mlx5-dv ' # Compile with mlx5 Direct Verbs support +configopts += '--with-ib-hw-tm ' # Compile with IB Tag Matching support +configopts += '--with-dm ' # Compile with Device Memory support + +configopts += '--with-avx ' # Compile with AVX +configopts += '--with-gdrcopy ' # Compile with GDRCopy + +# Compile without IB Connection Manager support +configopts += '--without-cm ' + +buildopts = 'V=1' + +sanity_check_paths = { + 'files': ['bin/ucx_info', 'bin/ucx_perftest', 'bin/ucx_read_profile'], + 'dirs': ['include', 'lib', 'share'] +} + +sanity_check_commands = ["ucx_info -d"] + +moduleclass = 'system'