diff --git a/.devops/nix/rocm-modules-10/amdsmi/default.nix b/.devops/nix/rocm-modules-10/amdsmi/default.nix new file mode 100644 index 0000000000..3e77819773 --- /dev/null +++ b/.devops/nix/rocm-modules-10/amdsmi/default.nix @@ -0,0 +1,106 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + pkg-config, + libdrm, + libnl, + libmnl, + python, + wrapPython, + autoPatchelfHook, +}: + +let + esmi_ib_src = fetchFromGitHub { + owner = "amd"; + repo = "esmi_ib_library"; + # ROCm 10 pins this exact commit in projects/amdsmi/CMakeLists.txt + rev = "d494a3194ceb4cc4dbb2debf9fcbe8773c6d3bef"; + hash = "sha256-StSYzyIujaH8UJIRpfJC0lf+oVT9fWflJgQONvRqu70="; + }; +in +stdenv.mkDerivation (finalAttrs: { + pname = "amdsmi"; + version = "10.0.0"; + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/amdsmi" + "shared" + ]; + hash = "sha256-yhgSwRk9vL40bmnAE3im7DOXy6uMA7NTZxPp5fQC7Qo="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/amdsmi"; + + postPatch = '' + # ROCm 10 dropped the raw -L link line from the goamdsmi shim, so only the + # target rename is still needed here. + substituteInPlace goamdsmi_shim/CMakeLists.txt \ + --replace-fail "amd_smi)" ${"'"}''${AMD_SMI_TARGET})' + # ROCm 10 replaced the tag comparison with an offline-safe check: it only + # fetches when esmi_ib_library/src/e_smi.c is absent, which the copy below + # satisfies. + + sed -i '/^struct drm_color_ctm_3x4 {/,/^};/d' include/libdrm/drm_mode.h + + # Manually unpack esmi_ib_src and add amd_hsmp.h so execute-process git clone doesn't run + cp -rf --no-preserve=mode ${esmi_ib_src} ./esmi_ib_library + mkdir -p ./esmi_ib_library/include/asm + cp ./include/amd_smi/impl/amd_hsmp.h ./esmi_ib_library/include/asm/amd_hsmp.h + ''; + + # ROCm 10 moved the vendored DRM headers from include/amd_smi/impl/amdgpu_drm.h + # to include/libdrm/, so amdsmi#165 no longer applies. The fix is still needed: + # drm_color_ctm_3x4 is defined by current system libdrm, and the vendored copy + # is unused and not part of the amdsmi public interface. + patches = [ ]; + + nativeBuildInputs = [ + cmake + pkg-config + wrapPython + autoPatchelfHook + ]; + + buildInputs = [ + libdrm + # ROCm 10's amdsmi uses system netlink via pkg-config (libnl-3.0, libmnl) + libnl + libmnl + ]; + + cmakeFlags = [ + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + postInstall = '' + mkdir -p $out/${python.sitePackages} + ln -s $out/share/amd_smi/amdsmi $out/${python.sitePackages}/amdsmi + + makeWrapperArgs=(--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ libdrm ]}) + wrapPythonProgramsIn $out + rm $out/bin/amd-smi + ln -sf $out/libexec/amdsmi_cli/amdsmi_cli.py $out/bin/amd-smi + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "System management interface for AMD GPUs supported by ROCm"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/amdsmi"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = [ "x86_64-linux" ]; + mainProgram = "amd-smi"; + }; +}) diff --git a/.devops/nix/rocm-modules-10/amdsmi/drm-struct-redefinition-fix.patch b/.devops/nix/rocm-modules-10/amdsmi/drm-struct-redefinition-fix.patch new file mode 100644 index 0000000000..caf23edcef --- /dev/null +++ b/.devops/nix/rocm-modules-10/amdsmi/drm-struct-redefinition-fix.patch @@ -0,0 +1,35 @@ +From b8b4a6bcfe35ba9539a120cfd16573123ddd9241 Mon Sep 17 00:00:00 2001 +From: "Sv. Lockal" +Date: Mon, 15 Dec 2025 03:46:35 +0800 +Subject: [PATCH] Fix compilation with libdrm-2.4.130 + +Fix error: redefinition of 'struct drm_color_ctm_3x4'. + +drm_color_ctm_3x4 structure is now defined in https://github.com/torvalds/linux/commit/e5719e7f19009d4fbedf685fc22eec9cd8de154f#diff-4c51fb416ec7cc69566cd7b795ee57eb070aa1006ad65d6962081f039ffb2718 + +As this structure is unused and not a part of amdsmi public interface, +it is safe to remove it. +--- + include/amd_smi/impl/amdgpu_drm.h | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/include/amd_smi/impl/amdgpu_drm.h b/include/amd_smi/impl/amdgpu_drm.h +index b56a5ac4b..0e483d13b 100644 +--- a/include/amd_smi/impl/amdgpu_drm.h ++++ b/include/amd_smi/impl/amdgpu_drm.h +@@ -1625,15 +1625,6 @@ struct drm_amdgpu_info_uq_metadata { + #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ + #define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ + +-/* FIXME wrong namespace! */ +-struct drm_color_ctm_3x4 { +- /* +- * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude +- * (not two's complement!) format. +- */ +- __u64 matrix[12]; +-}; +- + #if defined(__cplusplus) + } + #endif diff --git a/.devops/nix/rocm-modules-10/aotriton/default.nix b/.devops/nix/rocm-modules-10/aotriton/default.nix new file mode 100644 index 0000000000..3db4fc2021 --- /dev/null +++ b/.devops/nix/rocm-modules-10/aotriton/default.nix @@ -0,0 +1,176 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + rocm-cmake, + clr, + python3, + ninja, + xz, + writableTmpDirAsHomeHook, + pkg-config, + gpuTargets ? clr.localGpuTargets or clr.gpuTargets, + # for passthru.tests + aotriton, + hello, +}: +let + supportedTargets = lib.lists.intersectLists [ + # aotriton GPU support list: + # https://github.com/ROCm/aotriton/blob/main/v2python/gpu_targets.py + "gfx90a" + "gfx942" + "gfx950" + # some gfx1100 kernels fail with error: branch size exceeds simm16 + # but build proceeds and those ops will fallback so it's ok + "gfx1100" + "gfx1151" + "gfx1150" + "gfx1201" + "gfx1200" + ] gpuTargets; + anySupportedTargets = supportedTargets != [ ]; + # Pick a single arbitrary target to speed up shim build when we can't support our target + supportedTargets' = + if anySupportedTargets then lib.concatStringsSep ";" supportedTargets else "gfx1200"; +in +stdenv.mkDerivation (finalAttrs: { + pname = "aotriton${lib.optionalString (!anySupportedTargets) "-shim"}"; + version = "0.11.1b"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "aotriton"; + tag = finalAttrs.version; + hash = "sha256-F7JjyS+6gMdCpOFLldTsNJdVzzVwd6lwW7+V8ZOZfig="; + leaveDotGit = true; + # fetch all submodules except unused triton submodule that is ~500MB + postFetch = '' + cd $out + git reset --hard HEAD + for submodule in $(git config --file .gitmodules --get-regexp path | awk '{print $2}' | grep '^third_party/' | grep -v '^third_party/triton$'); do + git submodule update --init --recursive "$submodule" + done + find "$out" -name .git -print0 | xargs -0 rm -rf + ''; + }; + + cmakeBuildType = "RelWithDebInfo"; + separateDebugInfo = true; + __structuredAttrs = true; + strictDeps = true; + # Only set big-parallel when we are building kernels, no-image mode build is faster + requiredSystemFeatures = if anySupportedTargets then [ "big-parallel" ] else [ ]; + + env = { + AOTRITON_CI_SUPPLIED_SHA1 = finalAttrs.version; + ROCM_PATH = "${clr}"; + CFLAGS = "-w -g1 -gz -Wno-c++11-narrowing"; + CXXFLAGS = finalAttrs.env.CFLAGS; + TRITON_STORE_BINARY_ONLY = 1; # reduce triton disk space usage + }; + + nativeBuildInputs = [ + cmake + rocm-cmake + pkg-config + python3 + ninja + clr + writableTmpDirAsHomeHook # venv wants to cache in ~ + ]; + + buildInputs = [ + clr + xz + ] + ++ (with python3.pkgs; [ + wheel + packaging + pyyaml + numpy + filelock + iniconfig + pluggy + pybind11 + pandas + triton + ]); + + # Excerpt from README: + # Note: do not run ninja separately, due to the limit of the current build system, + # ninja install will run the whole build process unconditionally. + dontBuild = true; + # This builds+installs + installPhase = '' + runHook preInstall + ninja install + runHook postInstall + ''; + # tests are intended to be ran manually as test/ python scripts and need accelerator + doCheck = false; + doInstallCheck = false; + + # Need to set absolute paths to VENV and its PYTHON or + # build fails with "AOTRITON_INHERIT_SYSTEM_SITE_TRITON is enabled + # but triton is not available … no such file or directory" + # Set via a preConfigure hook so a valid absolute path can be + # picked if nix-shell is used against this package + preConfigure = '' + cmakeFlagsArray+=( + "-DVENV_DIR=$(pwd)/build/venv/" + "-DVENV_BIN_PYTHON=$(pwd)/build/venv/bin/python" + ) + ''; + + cmakeFlags = [ + # Disable building kernels if no supported targets are enabled + (lib.cmakeBool "AOTRITON_NOIMAGE_MODE" (!anySupportedTargets)) + # Use preinstalled triton from our python's site-packages + (lib.cmakeBool "AOTRITON_INHERIT_SYSTEM_SITE_TRITON" true) + # Circular dependency + (lib.cmakeBool "AOTRITON_USE_TORCH" false) + # FP32 kernels are optional, turn them off to speed up builds and save space + # Perf sensitive code should be using BF16 or F16 + (lib.cmakeBool "AOTRITON_ENABLE_FP32_INPUTS" false) + # Avoid kernels being skipped if build host is overloaded + (lib.cmakeFeature "AOTRITON_GPU_BUILD_TIMEOUT" "0") + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + (lib.cmakeFeature "CMAKE_INSTALL_BINDIR" "bin") + (lib.cmakeFeature "CMAKE_INSTALL_LIBDIR" "lib") + (lib.cmakeFeature "CMAKE_INSTALL_INCLUDEDIR" "include") + # Note: build will warn "AMDGPU_TARGETS was not set, and system GPU detection was unsuccsesful." + # but this can safely be ignored, aotriton uses a different approach to pass targets + (lib.cmakeFeature "AOTRITON_TARGET_ARCH" supportedTargets') + ]; + + passthru.tests = { + # regression test that aotriton so doesn't crash in static constructor + # currently known to fail on rocm toolchain but fine with default stdenv + ld-preload-into-hello = stdenv.mkDerivation { + name = "aotriton-basic-load-test"; + nativeBuildInputs = [ hello ]; + buildCommand = '' + set -e + LD_PRELOAD=${ + aotriton.override { + gpuTargets = [ ]; + } + }/lib/libaotriton_v2.so ${hello}/bin/hello > /dev/null + echo "ld-preload-into-hello" > $out + ''; + }; + }; + + meta = { + description = "ROCm Ahead of Time (AOT) Triton Math Library"; + homepage = "https://github.com/ROCm/aotriton"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + # ld: error: unable to insert .comment after .comment + broken = stdenv.cc.isClang; + }; +}) diff --git a/.devops/nix/rocm-modules-10/aqlprofile/default.nix b/.devops/nix/rocm-modules-10/aqlprofile/default.nix new file mode 100644 index 0000000000..cf221df554 --- /dev/null +++ b/.devops/nix/rocm-modules-10/aqlprofile/default.nix @@ -0,0 +1,42 @@ +{ + lib, + stdenv, + clr, + cmake, + fetchFromGitHub, + rocmUpdateScript, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "aqlprofile"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/aqlprofile" + "shared" + ]; + hash = "sha256-74HjB5Ughu17rSRx9mfCCsPJI4TVyXnT4aU7vIbm7ak="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/aqlprofile"; + + env.CXXFLAGS = "-DROCP_LD_AQLPROFILE=1"; + + nativeBuildInputs = [ + cmake + clr + ]; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "AQLPROFILE library for AMD HSA runtime API extension support"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/aqlprofile"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/clr/cmake-find-x11-libgl.patch b/.devops/nix/rocm-modules-10/clr/cmake-find-x11-libgl.patch new file mode 100644 index 0000000000..5a36a2c2c7 --- /dev/null +++ b/.devops/nix/rocm-modules-10/clr/cmake-find-x11-libgl.patch @@ -0,0 +1,40 @@ +diff --git a/rocclr/cmake/ROCclr.cmake b/rocclr/cmake/ROCclr.cmake +index 3f233b72f..67bdc62ee 100644 +--- a/rocclr/cmake/ROCclr.cmake ++++ b/rocclr/cmake/ROCclr.cmake +@@ -44,6 +44,19 @@ find_package(Threads REQUIRED) + + find_package(AMD_OPENCL) + ++# Find X11 package ++find_package(X11 REQUIRED) ++if(NOT X11_FOUND) ++ message(FATAL_ERROR "X11 libraries not found") ++endif() ++ ++# Find OpenGL package ++find_package(OpenGL REQUIRED) ++if(NOT OpenGL_FOUND) ++ message(FATAL_ERROR "OpenGL not found") ++endif() ++ ++ + add_library(rocclr STATIC) + + include(ROCclrCompilerOptions) +@@ -123,9 +136,14 @@ target_include_directories(rocclr PUBLIC + ${ROCCLR_SRC_DIR}/device + ${ROCCLR_SRC_DIR}/elf + ${ROCCLR_SRC_DIR}/include ++ ${X11_INCLUDE_DIR} ++ ${OPENGL_INCLUDE_DIR} + ${AMD_OPENCL_INCLUDE_DIRS}) + +-target_link_libraries(rocclr PUBLIC Threads::Threads) ++target_link_libraries(rocclr PUBLIC ++ Threads::Threads ++ ${X11_LIBRARIES} ++ ${OPENGL_LIBRARIES}) + # IPC on Windows is not supported + if(UNIX) + target_link_libraries(rocclr PUBLIC rt) diff --git a/.devops/nix/rocm-modules-10/clr/default.nix b/.devops/nix/rocm-modules-10/clr/default.nix new file mode 100644 index 0000000000..886ae1fff7 --- /dev/null +++ b/.devops/nix/rocm-modules-10/clr/default.nix @@ -0,0 +1,335 @@ +{ + lib, + stdenv, + callPackage, + fetchFromGitHub, + fetchpatch, + rocmUpdateScript, + makeWrapper, + cmake, + perl, + hip-common, + hipcc, + rocm-device-libs, + rocm-comgr, + rocm-runtime, + rocm-core, + roctracer, + rocminfo, + rocm-smi, + rocprofiler-register, + symlinkJoin, + numactl, + libffi, + zstd, + zlib, + libGL, + libxml2, + libx11, + python3Packages, + llvm, + khronos-ocl-icd-loader, + gcc-unwrapped, + writeShellScriptBin, + localGpuTargets ? null, +}: + +let + inherit (rocm-core) ROCM_LIBPATCH_VERSION; + # HIP_CLANG_PATH or ROCM_PATH/llvm + # Note: relying on ROCM_PATH/llvm is bad for cross + hipClang = symlinkJoin { + name = "hipClang"; + paths = [ + # FIXME: if we don't put this first aotriton build fails with ld.lld: -flavor gnu + # Probably wrapper jank + llvm.bintools.bintools + llvm.rocm-toolchain + ]; + postBuild = '' + rm -rf $out/{include,lib,share,etc,nix-support,usr} + ''; + }; + hipClangPath = "${hipClang}/bin"; + wrapperArgs = [ + "--prefix PATH : $out/bin" + "--prefix LD_LIBRARY_PATH : ${rocm-runtime}" + "--set HIP_PLATFORM amd" + "--set HIP_PATH $out" + "--set HIP_CLANG_PATH ${hipClangPath}" + "--set DEVICE_LIB_PATH ${rocm-device-libs}/amdgcn/bitcode" + "--set HSA_PATH ${rocm-runtime}" + "--set ROCM_PATH $out" + ]; + amdclang = writeShellScriptBin "amdclang" '' + exec ${hipClang}/bin/clang "$@" + ''; + amdclangxx = writeShellScriptBin "amdclang++" '' + exec ${hipClang}/bin/clang++ "$@" + ''; +in +stdenv.mkDerivation (finalAttrs: { + pname = "clr"; + version = "10.0.0"; + + outputs = [ + "out" + "icd" + ]; + + __structuredAttrs = true; + strictDeps = true; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/clr" + "shared" + ]; + hash = "sha256-MKgP9xrSz/1cRrBYUR669wja6XojKOj5Qp/GEvaUM7Q="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/clr"; + + nativeBuildInputs = [ + makeWrapper + cmake + perl + python3Packages.python + python3Packages.cppheaderparser + amdclang + amdclangxx + ]; + + buildInputs = [ + llvm.llvm + numactl + libGL + libxml2 + libx11 + khronos-ocl-icd-loader + hipClang + libffi + zstd + zlib + rocprofiler-register + ]; + + propagatedBuildInputs = [ + rocm-core + rocm-device-libs + rocm-comgr + rocm-runtime + rocminfo + hipClangPath + ]; + + cmakeBuildType = "RelWithDebInfo"; + separateDebugInfo = true; + + cmakeFlags = [ + "-DCMAKE_POLICY_DEFAULT_CMP0072=NEW" # Prefer newer OpenGL libraries + "-DCLR_BUILD_HIP=ON" + "-DCLR_BUILD_OCL=ON" + "-DHIP_COMMON_DIR=${hip-common}" + "-DHIPCC_BIN_DIR=${hipcc}/bin" + "-DHIP_PLATFORM=amd" + "-DPROF_API_HEADER_PATH=${roctracer.src}/inc/ext" + "-DROCM_PATH=${rocminfo}" + "-DBUILD_ICD=ON" + "-DAMD_ICD_LIBRARY_DIR=${khronos-ocl-icd-loader}" + + # Temporarily set variables to work around upstream CMakeLists issue + # Can be removed once https://github.com/ROCm/rocm-cmake/issues/121 is fixed + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_INSTALL_LIBDIR=lib" + ]; + + env.LLVM_DIR = ""; + + patches = [ + ./cmake-find-x11-libgl.patch + (fetchpatch { + # [PATCH] rocclr: Extend HIP ISA compatibility checks + hash = "sha256-3MsDL+OQg24wH1RDhbao74RuIbzEAmduwla9KOPzQ/M="; + url = "https://github.com/GZGavinZhao/rocm-systems/commit/039cb23b24d739adb8c0f9de8b550d9f557de031.patch"; + relative = "projects/clr"; + }) + ]; + + postPatch = '' + patchShebangs hipamd/*.sh + patchShebangs hipamd/src + + # We're not on Windows so these are never installed to hipcc... + substituteInPlace hipamd/CMakeLists.txt \ + --replace-fail "install(PROGRAMS \''${HIPCC_BIN_DIR}/hipcc.bat DESTINATION bin)" "" \ + --replace-fail "install(PROGRAMS \''${HIPCC_BIN_DIR}/hipconfig.bat DESTINATION bin)" "" + + substituteInPlace hipamd/src/hip_embed_pch.sh \ + --replace-fail "\''$LLVM_DIR/bin/clang" "${hipClangPath}/clang" \ + --replace-fail "\''$LLVM_DIR/bin/llvm-mc" "${lib.getExe' llvm.bintools.bintools "llvm-mc"}" + + substituteInPlace opencl/khronos/icd/loader/icd_platform.h \ + --replace-fail '#define ICD_VENDOR_PATH "/etc/OpenCL/vendors/";' \ + '#define ICD_VENDOR_PATH "/run/opengl-driver/etc/OpenCL/vendors/";' + ''; + + postInstall = '' + chmod +x $out/bin/* + patchShebangs $out/bin + + cp ${amdclang}/bin/* $out/bin/ + cp ${amdclangxx}/bin/* $out/bin/ + + for prog in hip{cc,config}; do + wrapProgram $out/bin/$prog ${lib.concatStringsSep " " wrapperArgs} + done + + mkdir -p $out/nix-support/ + echo ' + export HIP_PATH="${placeholder "out"}" + export HIP_PLATFORM=amd + export HIP_DEVICE_LIB_PATH="${rocm-device-libs}/amdgcn/bitcode" + export NIX_CC_USE_RESPONSE_FILE=0 + export HIP_CLANG_PATH="${hipClangPath}" + export ROCM_LIBPATCH_VERSION="${ROCM_LIBPATCH_VERSION}" + export HSA_PATH="${rocm-runtime}"' > $out/nix-support/setup-hook + + # Just link rocminfo, it's easier + ln -s ${rocminfo}/bin/* $out/bin + ln -s ${rocm-core}/include/* $out/include/ + + # Replace rocm-opencl-icd functionality + mkdir -p $icd/etc/OpenCL/vendors + echo "$out/lib/libamdocl64.so" > $icd/etc/OpenCL/vendors/amdocl64.icd + + # add version info to output (downstream rocmPackages look for this) + ln -s ${rocm-core}/.info/ $out/.info + + ln -s ${hipClang} $out/llvm + ''; + + # libamdhip64.so dlopens its own bare name for hipGetProcAddress symbol resolution, + # same pattern with libhiprtc.so, so add own lib directory to all .so's + # RPATHs so they can find themselves and neighbouring libs + # Must be in postFixup so it runs after patchelf --shrink-rpath which removes + # the apparently useless rpath + postFixup = '' + patchelf --add-rpath "$out/lib" "$out"/lib/*.so + ''; + + disallowedRequisites = [ + gcc-unwrapped + ]; + + passthru = { + # All known and valid general GPU targets + # We cannot use this for each ROCm library, as each defines their own supported targets + # See: https://github.com/ROCm/ROCm/blob/77cbac4abab13046ee93d8b5bf410684caf91145/README.md#library-target-matrix + gpuTargets = lib.forEach [ + # "9-generic" # can handle all Vega variants + "900" # MI25, Vega 56/64 + # "902" # Vega 8 + # "909" # Renoir Vega APU + # "90c" # Renoir Vega APU + # Past this point cards need their own kernels for perf despite gfx9-generic compat + "906" # MI50/60, Radeon VII - adds dot product & mixed precision FMA ops + "908" # MI100 - adds MFMA (matrix fused multiply-add) ops + "90a" # MI210/MI250 - additional MFMA variants + # "9-4-generic" - since only 942 is valid for 6.4 target it directly + # 940/1 - never released publicly, maybe HPE cray specific MI3xx? + "942" # MI300A/X, MI325X + "950" # MI350X, MI355X + # "10-1-generic" # fine for all RDNA1 cards + "1010" + # "10-3-generic" + "1030" # W6800, various Radeon cards + # 1100 through 1103 = RDNA3 + # "11-generic" # will handle 7600, hopefully ryzen AI series iGPUs + "1100" + "1101" + "1102" + "1103" # RDNA3 iGPU like Radeon 780M + "1150" # Strix Point + "1151" # Strix Halo + # "12-generic" + "1200" # RX 9060 + "1201" # RX 9070 + XT + ] (target: "gfx${target}"); + + inherit hipClangPath; + + updateScript = rocmUpdateScript { inherit finalAttrs; }; + + impureTests = { + # bash $(nix-build -A rocmPackages.clr.impureTests.rocm-smi) + rocm-smi = callPackage ./test-rocm-smi.nix { + inherit rocm-smi; + clr = finalAttrs.finalPackage; + }; + # Simple subset of opencl-cts test_basic + opencl-cts = callPackage ./test-opencl-cts.nix { + clr = finalAttrs.finalPackage; + }; + generic-arch = callPackage ./test-isa-compat.nix { + clr = finalAttrs.finalPackage; + name = "generic-arch"; + offloadArches = [ + "gfx9-generic" + "gfx10-1-generic" + "gfx10-3-generic" + "gfx11-generic" + "gfx12-generic" + ]; + }; + isa-compat = callPackage ./test-isa-compat.nix { + clr = finalAttrs.finalPackage; + name = "isa-compat"; + offloadArches = [ + "gfx900" + "gfx1010" + "gfx1030" + ]; + }; + spirv = callPackage ./test-isa-compat.nix { + clr = finalAttrs.finalPackage; + name = "spirv"; + offloadArches = [ + "amdgcnspirv" + ]; + }; + hiprtc-type-traits = callPackage ./test-hiprtc-type-traits.nix { + clr = finalAttrs.finalPackage; + inherit rocm-smi; + }; + }; + + selectGpuTargets = + { + supported ? [ ], + }: + supported; + gpuArchSuffix = ""; + } + // lib.optionalAttrs (localGpuTargets != null) { + inherit localGpuTargets; + gpuArchSuffix = "-" + (builtins.concatStringsSep "-" localGpuTargets); + selectGpuTargets = + { + supported ? [ ], + }: + if supported == [ ] then localGpuTargets else lib.lists.intersectLists localGpuTargets supported; + }; + + meta = { + description = "AMD Common Language Runtime for hipamd, opencl, and rocclr"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/clr"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/clr/test-hiprtc-type-traits.cpp b/.devops/nix/rocm-modules-10/clr/test-hiprtc-type-traits.cpp new file mode 100644 index 0000000000..39a99f39ea --- /dev/null +++ b/.devops/nix/rocm-modules-10/clr/test-hiprtc-type-traits.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#define CHECK_HIP(expr) do { \ + if ((expr) != hipSuccess) { \ + std::cerr << #expr << " failed" << std::endl; \ + return 1; \ + } \ +} while(0) + +#define CHECK_HIPRTC(expr) do { \ + hiprtcResult _res = (expr); \ + if (_res != HIPRTC_SUCCESS) { \ + std::cerr << #expr << " failed: " << hiprtcGetErrorString(_res) << std::endl; \ + hiprtcGetProgramLogSize(prog, &log_size); \ + if (log_size > 0) { \ + std::string log(log_size, '\0'); \ + hiprtcGetProgramLog(prog, log.data()); \ + std::cerr << "Compile log:\n" << log << std::endl; \ + } \ + return 1; \ + } \ +} while(0) + +static const char* kernelSource = R"( + #include + + extern "C" __global__ void test_kernel(int* out) { + static_assert(std::is_same::type>::value, + "type_traits not working"); + out[0] = 5; + } +)"; + +int main() { + hiprtcProgram prog; + size_t log_size = 0; + CHECK_HIPRTC(hiprtcCreateProgram(&prog, kernelSource, "test.hip", 0, nullptr, nullptr)); + CHECK_HIPRTC(hiprtcCompileProgram(prog, 0, nullptr)); + + size_t code_size; + CHECK_HIPRTC(hiprtcGetCodeSize(prog, &code_size)); + std::string code(code_size, '\0'); + CHECK_HIPRTC(hiprtcGetCode(prog, code.data())); + hiprtcDestroyProgram(&prog); + + hipModule_t module; + hipFunction_t kernel; + CHECK_HIP(hipModuleLoadData(&module, code.data())); + CHECK_HIP(hipModuleGetFunction(&kernel, module, "test_kernel")); + + int* d_out; + int h_out = 0; + CHECK_HIP(hipMalloc(&d_out, sizeof(int))); + void* args[] = { &d_out }; + CHECK_HIP(hipModuleLaunchKernel(kernel, 1, 1, 1, 1, 1, 1, 0, nullptr, args, nullptr)); + CHECK_HIP(hipMemcpy(&h_out, d_out, sizeof(int), hipMemcpyDeviceToHost)); + + if (h_out != 5) { + std::cerr << "Kernel output mismatch: expected 5, got " << h_out << std::endl; + return 1; + } + + std::cout << "HIPRTC type_traits test passed (output=" << h_out << ")" << std::endl; + return 0; +} diff --git a/.devops/nix/rocm-modules-10/clr/test-hiprtc-type-traits.nix b/.devops/nix/rocm-modules-10/clr/test-hiprtc-type-traits.nix new file mode 100644 index 0000000000..f0f3628fcd --- /dev/null +++ b/.devops/nix/rocm-modules-10/clr/test-hiprtc-type-traits.nix @@ -0,0 +1,57 @@ +{ + lib, + stdenv, + makeImpureTest, + clr, + rocm-smi, +}: +# minimal hiprtc test that compiles a kernel using at runtime +# mirrors an migraphx workload, better test/iteration UX to be able to confirm +# with just a build up to clr +let + hiprtc-test = stdenv.mkDerivation { + pname = "hiprtc-type-traits-test"; + version = "0"; + + dontUnpack = true; + + nativeBuildInputs = [ clr ]; + + buildPhase = '' + runHook preBuild + hipcc -o hiprtc-test ${./test-hiprtc-type-traits.cpp} -lhiprtc + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp hiprtc-test $out/bin/ + runHook postInstall + ''; + }; +in +makeImpureTest { + name = "hiprtc-type-traits"; + testedPackage = "rocmPackages.clr"; + + sandboxPaths = [ + "/sys" + "/dev/dri" + "/dev/kfd" + ]; + + nativeBuildInputs = [ + hiprtc-test + rocm-smi + ]; + + testScript = '' + rocm-smi + hiprtc-test + ''; + + meta = { + teams = [ lib.teams.rocm ]; + }; +} diff --git a/.devops/nix/rocm-modules-10/clr/test-isa-compat.nix b/.devops/nix/rocm-modules-10/clr/test-isa-compat.nix new file mode 100644 index 0000000000..2eca8edbff --- /dev/null +++ b/.devops/nix/rocm-modules-10/clr/test-isa-compat.nix @@ -0,0 +1,74 @@ +{ + lib, + stdenv, + makeImpureTest, + fetchFromGitHub, + clr, + rocm-smi, + name, + offloadArches, +}: + +let + # TODO: swap to another tiny test if this breaks; upstream is archived but fine for now + vectoradd = stdenv.mkDerivation { + pname = "rocm-hip-vectoradd"; + version = "2024-04-11"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "HIP-Examples"; + rev = "cdf9d101acd9a3fc89ee750f73c1f1958cbd5cc3"; + hash = "sha256-/I1KmOBFbEZIjA1vRE+2tPTtEKtOgazjCbnZtr+87E0="; + }; + + nativeBuildInputs = [ + clr + ]; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin + amdclang++ -x hip -o $out/bin/vectoradd \ + ${lib.concatMapStringsSep " " (arch: "--offload-arch=${arch}") offloadArches} \ + vectorAdd/vectoradd_hip.cpp + + runHook postInstall + ''; + + meta = { + description = "vectorAdd HIP example for ROCm"; + homepage = "https://github.com/ROCm/HIP-Examples"; + license = lib.licenses.unfree; + platforms = lib.platforms.linux; + teams = [ lib.teams.rocm ]; + }; + }; + +in +makeImpureTest { + inherit name; + testedPackage = "rocmPackages.clr"; + + sandboxPaths = [ + "/sys" + "/dev/dri" + "/dev/kfd" + ]; + + nativeBuildInputs = [ + vectoradd + rocm-smi + ]; + + testScript = '' + rocm-smi + + vectoradd + ''; + + meta = { + teams = [ lib.teams.rocm ]; + }; +} diff --git a/.devops/nix/rocm-modules-10/clr/test-opencl-cts.nix b/.devops/nix/rocm-modules-10/clr/test-opencl-cts.nix new file mode 100644 index 0000000000..77929531f9 --- /dev/null +++ b/.devops/nix/rocm-modules-10/clr/test-opencl-cts.nix @@ -0,0 +1,28 @@ +{ + lib, + makeImpureTest, + opencl-cts, + clr, +}: + +makeImpureTest { + name = "opencl-cts"; + testedPackage = "rocmPackages.clr"; + + sandboxPaths = [ + "/sys" + "/dev/dri" + "/dev/kfd" + ]; + + nativeBuildInputs = [ opencl-cts ]; + OCL_ICD_VENDORS = "${clr.icd}/etc/OpenCL/vendors"; + + testScript = '' + test_basic arraycopy arrayreadwrite astype barrier vector_swizzle work_item_functions + ''; + + meta = { + teams = [ lib.teams.rocm ]; + }; +} diff --git a/.devops/nix/rocm-modules-10/clr/test-rocm-smi.nix b/.devops/nix/rocm-modules-10/clr/test-rocm-smi.nix new file mode 100644 index 0000000000..e03655907c --- /dev/null +++ b/.devops/nix/rocm-modules-10/clr/test-rocm-smi.nix @@ -0,0 +1,27 @@ +{ + lib, + makeImpureTest, + clinfo, + clr, + rocm-smi, +}: + +makeImpureTest { + name = "rocm-smi"; + testedPackage = "rocmPackages.clr"; + nativeBuildInputs = [ + clinfo + rocm-smi + ]; + OCL_ICD_VENDORS = "${clr.icd}/etc/OpenCL/vendors"; + + testScript = '' + # Test fails if the number of platforms is 0 + clinfo | grep -E 'Number of platforms * [1-9]' + rocm-smi | grep -A1 GPU + ''; + + meta = { + teams = [ lib.teams.rocm ]; + }; +} diff --git a/.devops/nix/rocm-modules-10/composable_kernel/base.nix b/.devops/nix/rocm-modules-10/composable_kernel/base.nix new file mode 100644 index 0000000000..d4e8cbc26f --- /dev/null +++ b/.devops/nix/rocm-modules-10/composable_kernel/base.nix @@ -0,0 +1,205 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + rocminfo, + python3, + hipify, + gitMinimal, + gtest, + jemalloc, + zstd, + buildTests ? false, + buildExamples ? false, + # limits prebuilt kernel selection to those needed for MIOPEN (currently "*conv*") + # Other kernels can still be used if treating CK as a header only library + # and building specific instances, as done with ck4inductor/torch + miOpenReqLibsOnly ? true, + withDeprecatedKernels ? false, + gpuTargets ? ( + clr.localGpuTargets or [ + "gfx900" + "gfx906" + "gfx908" + "gfx90a" + "gfx942" + "gfx950" + "gfx10-3-generic" + "gfx11-generic" + "gfx12-generic" + ] + ), +}: +let + projectRoot = "projects/composablekernel"; +in +stdenv.mkDerivation (finalAttrs: { + preBuild = '' + echo "This derivation isn't intended to be built directly and only exists to be overridden and built in chunks"; + exit 1 + ''; + + pname = "composable_kernel_base"; + version = "10.0.0"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildExamples [ + "example" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + projectRoot + "shared" + ]; + hash = "sha256-zwJ8jPv9gtMc0PHNQuu6R0kgO59uDfPtrVZ8Tv3Wwjs="; + }; + sourceRoot = "${finalAttrs.src.name}/${projectRoot}"; + + nativeBuildInputs = [ + # Deliberately not using ninja + # because we're jankily composing build outputs from multiple drvs + # ninja won't believe they're up to date + gitMinimal + cmake + rocminfo + clr + hipify + zstd + python3 + ]; + + buildInputs = [ + rocm-cmake + clr + zstd + ]; + + strictDeps = true; + enableParallelBuilding = true; + env.ROCM_PATH = clr; + # Speed up build by ~7% with jemalloc (template torture test workload means allocation heavy clang invocations) + env.LD_PRELOAD = "${jemalloc}/lib/libjemalloc.so"; + env.MALLOC_CONF = "background_thread:true,metadata_thp:auto,dirty_decay_ms:10000,muzzy_decay_ms:10000"; + + cmakeFlags = [ + (lib.cmakeBool "MIOPEN_REQ_LIBS_ONLY" miOpenReqLibsOnly) + (lib.cmakeBool "BUILD_MHA_LIB" (!miOpenReqLibsOnly)) + (lib.cmakeBool "DISABLE_DL_KERNELS" true) + (lib.cmakeBool "DISABLE_DPP_KERNELS" true) + (lib.cmakeBool "CK_TIME_KERNEL" false) + "-DCMAKE_MODULE_PATH=${clr}/hip/cmake" + "-DCMAKE_POLICY_DEFAULT_CMP0069=NEW" + "-DDL_KERNELS=OFF" + # CK_USE_CODEGEN Required for migraphx which uses device_gemm_multiple_d.hpp + # but migraphx requires an incompatible fork of CK and fails anyway + # "-DCK_USE_CODEGEN=ON" + # It might be worth skipping fp64 in future with this: + # "-DDTYPES=fp32;fp16;fp8;bf16;int8" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DBUILD_DEV=OFF" + "-DBUILD_MHA_LIB=ON" + "-DROCM_PATH=${clr}" + "-DENABLE_CLANG_CPP_CHECKS=OFF" + "-DCMAKE_HIP_COMPILER_ROCM_ROOT=${clr}" + + # FP8 can build for 908/90a but very slow build + # and produces unusably slow kernels that are huge + "-DCK_USE_FP8_ON_UNSUPPORTED_ARCH=OFF" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + # We intentionally set GPU_ARCHS and not AMD/GPU_TARGETS + # per readme this is required if archs are dissimilar + # In rocm-6.3.x not setting any arch flag worked + # but setting dissimilar arches always failed + "-DGPU_ARCHS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DGOOGLETEST_DIR=${gtest.src}" # Custom linker names + ]; + + patches = [ + # Hacky fix for failure for some targets when all targets are selected out + # for a non-optional at link time kernel + ./fix-empty-offload-targets.diff + ]; + + postPatch = + # Reduce configure time by preventing thousands of clang-tidy targets being added + # We will never call them + # Never build profiler + '' + substituteInPlace library/src/utility/CMakeLists.txt library/src/tensor_operation_instance/gpu/CMakeLists.txt \ + --replace-fail clang_tidy_check '#clang_tidy_check' + substituteInPlace CMakeLists.txt \ + --replace-fail "add_subdirectory(profiler)" "" + substituteInPlace cmake/EnableCompilerWarnings.cmake \ + --replace-fail "-Werror" "" + '' + + lib.optionalString (!withDeprecatedKernels) '' + substituteInPlace include/ck/ck.hpp \ + --replace-fail "CK_BUILD_DEPRECATED 1" "CK_BUILD_DEPRECATED 0" + '' + # Optionally remove tests + + lib.optionalString (!buildTests) '' + substituteInPlace CMakeLists.txt \ + --replace-fail "add_subdirectory(test)" "" + substituteInPlace codegen/CMakeLists.txt \ + --replace-fail "include(ROCMTest)" "" + '' + # Optionally remove examples + + lib.optionalString (!buildExamples) '' + substituteInPlace CMakeLists.txt \ + --replace-fail "add_subdirectory(example)" "" + ''; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/test_* $test/bin + '' + + lib.optionalString buildExamples '' + mkdir -p $example/bin + mv $out/bin/example_* $example/bin + ''; + + passthru = { + inherit gpuTargets miOpenReqLibsOnly; + composable_kernel_src = "${finalAttrs.src}/${projectRoot}"; + + updateScript = rocmUpdateScript { inherit finalAttrs; }; + anyGfx9Target = lib.lists.any (lib.strings.hasPrefix "gfx9") gpuTargets; + anyMfmaTarget = + (lib.lists.intersectLists gpuTargets [ + "gfx908" + "gfx90a" + "gfx942" + "gfx950" + ]) != [ ]; + }; + + meta = { + description = "Performance portable programming model for machine learning tensor operators"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/composablekernel"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + broken = true; # this base package shouldn't be built directly + }; +}) diff --git a/.devops/nix/rocm-modules-10/composable_kernel/ck4inductor.nix b/.devops/nix/rocm-modules-10/composable_kernel/ck4inductor.nix new file mode 100644 index 0000000000..d41ac17f82 --- /dev/null +++ b/.devops/nix/rocm-modules-10/composable_kernel/ck4inductor.nix @@ -0,0 +1,42 @@ +{ + buildPythonPackage, + python, + composable_kernel, + lib, + rocm-toolchain, + setuptools, + setuptools-scm, +}: +buildPythonPackage { + pyproject = true; + pname = "ck4inductor"; + build-system = [ + setuptools + setuptools-scm + ]; + inherit (composable_kernel) version src sourceRoot; + pythonImportsCheck = [ + "ck4inductor" + "ck4inductor.universal_gemm.gen_instances" + "ck4inductor.universal_gemm.gen_instances" + "ck4inductor.universal_gemm.op" + ]; + propagatedBuildInputs = [ + # At runtime will fail to compile anything with ck4inductor without this + # can't easily use in checks phase because most of the compiler machinery is in torch + rocm-toolchain + ]; + checkPhase = '' + if [ ! -d "$out/${python.sitePackages}/ck4inductor" ]; then + echo "ck4inductor isn't at the expected location in $out/${python.sitePackages}/ck4inductor" + exit 1 + fi + ''; + meta = { + description = "Pytorch inductor backend which uses composable_kernel universal GEMM implementations"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/composablekernel"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +} diff --git a/.devops/nix/rocm-modules-10/composable_kernel/default.nix b/.devops/nix/rocm-modules-10/composable_kernel/default.nix new file mode 100644 index 0000000000..ae0707fabb --- /dev/null +++ b/.devops/nix/rocm-modules-10/composable_kernel/default.nix @@ -0,0 +1,319 @@ +{ + lib, + clr, + composable_kernel_base, +}: + +let + inherit (composable_kernel_base) miOpenReqLibsOnly; + parts = { + _mha = { + enabled = !miOpenReqLibsOnly; + # mha takes ~3hrs on 64 cores on an EPYC milan system at ~2.5GHz + # big-parallel builders are one gen newer and clocked ~30% higher but only 24 cores + # Should be <10h timeout but might be cutting it close + # TODO: work out how to split this into smaller chunks instead of all 3k mha instances together + # mha_0,1,2, search ninja target file for the individual instances, split by the index? + # TODO: can we prune the generated instances down to only what in practice are used with popular models + # when using flash-attention + MHA kernels? + targets = [ + "device_mha_instance" + ]; + extraCmakeFlags = [ "-DHIP_CLANG_NUM_PARALLEL_JOBS=2" ]; + }; + gemm_multiply_multiply = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_gemm_multiply_multiply_instance" + ]; + extraCmakeFlags = [ "-DHIP_CLANG_NUM_PARALLEL_JOBS=2" ]; + onlyFor = [ + "gfx942" + "gfx950" + ]; + }; + gemm_multiply_multiply_wp = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_gemm_multiply_multiply_wp_instance" + ]; + extraCmakeFlags = [ "-DHIP_CLANG_NUM_PARALLEL_JOBS=2" ]; + onlyFor = [ + "gfx942" + "gfx950" + ]; + }; + grouped_conv_bwd = { + targets = [ + "device_grouped_conv1d_bwd_weight_instance" + "device_grouped_conv2d_bwd_data_instance" + "device_grouped_conv2d_bwd_weight_instance" + ]; + }; + grouped_conv_fwd = { + targets = [ + "device_grouped_conv1d_fwd_instance" + "device_grouped_conv2d_fwd_instance" + "device_grouped_conv2d_fwd_bias_bnorm_clamp_instance" + "device_grouped_conv2d_fwd_bias_clamp_instance" + "device_grouped_conv2d_fwd_clamp_instance" + "device_grouped_conv2d_fwd_dynamic_op_instance" + ]; + }; + grouped_conv_bwd_3d1 = { + targets = [ + "device_grouped_conv3d_bwd_data_instance" + "device_grouped_conv3d_bwd_data_bilinear_instance" + "device_grouped_conv3d_bwd_data_scale_instance" + ]; + }; + grouped_conv_bwd_3d2 = { + targets = [ + "device_grouped_conv3d_bwd_weight_instance" + "device_grouped_conv3d_bwd_weight_bilinear_instance" + "device_grouped_conv3d_bwd_weight_scale_instance" + ]; + }; + grouped_conv_fwd_3d1 = { + targets = [ + "device_grouped_conv3d_fwd_instance" + "device_grouped_conv3d_fwd_clamp_instance" + "device_grouped_conv3d_fwd_bias_bnorm_clamp_instance" + "device_grouped_conv3d_fwd_bias_clamp_instance" + "device_grouped_conv3d_fwd_bilinear_instance" + "device_grouped_conv3d_fwd_convinvscale_instance" + "device_grouped_conv3d_fwd_convscale_instance" + "device_grouped_conv3d_fwd_convscale_add_instance" + ]; + }; + grouped_conv_fwd_3d2 = { + targets = [ + "device_grouped_conv3d_fwd_convscale_relu_instance" + "device_grouped_conv3d_fwd_dynamic_op_instance" + "device_grouped_conv3d_fwd_scale_instance" + "device_grouped_conv3d_fwd_scaleadd_ab_instance" + "device_grouped_conv3d_fwd_scaleadd_scaleadd_relu_instance" + ]; + }; + grouped_conv_fwd_nd = { + targets = [ + "device_grouped_convnd_bwd_weight_instance" + ]; + }; + batched_gemm1 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_batched_gemm_instance" + "device_batched_gemm_b_scale_instance" + "device_batched_gemm_multi_d_instance" + "device_batched_gemm_add_relu_gemm_add_instance" + "device_batched_gemm_bias_permute_instance" + "device_batched_gemm_gemm_instance" + "device_batched_gemm_reduce_instance" + "device_batched_gemm_softmax_gemm_instance" + ]; + }; + batched_gemm2 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_batched_gemm_softmax_gemm_permute_instance" + "device_grouped_gemm_instance" + "device_grouped_gemm_bias_instance" + "device_grouped_gemm_fastgelu_instance" + "device_grouped_gemm_fixed_nk_instance" + "device_grouped_gemm_fixed_nk_multi_abd_instance" + "device_grouped_gemm_tile_loop_instance" + ]; + }; + gemm_universal1 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_gemm_universal_instance" + "device_gemm_universal_batched_instance" + ]; + }; + gemm_universal2 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_gemm_universal_reduce_instance" + "device_gemm_universal_streamk_instance" + ]; + }; + gemm_other1 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_gemm_instance" + "device_gemm_b_scale_instance" + "device_gemm_ab_scale_instance" + "device_gemm_add_instance" + "device_gemm_add_add_fastgelu_instance" + "device_gemm_add_fastgelu_instance" + "device_gemm_add_multiply_instance" + "device_gemm_add_relu_instance" + ]; + }; + gemm_other2 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_gemm_add_relu_add_layernorm_instance" + "device_gemm_add_silu_instance" + "device_gemm_bias_add_reduce_instance" + "device_gemm_bilinear_instance" + "device_gemm_fastgelu_instance" + "device_gemm_multi_abd_instance" + "device_gemm_multiply_add_instance" + "device_gemm_reduce_instance" + "device_gemm_splitk_instance" + "device_gemm_streamk_instance" + ]; + }; + conv = { + targets = [ + "device_conv1d_bwd_data_instance" + "device_conv2d_bwd_data_instance" + "device_conv2d_fwd_instance" + "device_conv2d_fwd_bias_relu_instance" + "device_conv2d_fwd_bias_relu_add_instance" + "device_conv3d_bwd_data_instance" + ]; + }; + pool = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_avg_pool2d_bwd_instance" + "device_avg_pool3d_bwd_instance" + "device_pool2d_fwd_instance" + "device_pool3d_fwd_instance" + "device_max_pool_bwd_instance" + ]; + }; + other0 = { + targets = [ + "device_quantization_instance" + ]; + }; + other1 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_batchnorm_instance" + "device_contraction_bilinear_instance" + "device_contraction_scale_instance" + "device_elementwise_instance" + "device_elementwise_normalization_instance" + ]; + }; + other2 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_column_to_image_instance" + "device_image_to_column_instance" + "device_permute_scale_instance" + "device_reduce_instance" + ]; + }; + other3 = { + enabled = !miOpenReqLibsOnly; + targets = [ + "device_normalization_bwd_data_instance" + "device_normalization_bwd_gamma_beta_instance" + "device_normalization_fwd_instance" + "device_softmax_instance" + "device_transpose_instance" + ]; + }; + }; + tensorOpBuilder = + { + part, + targets, + extraCmakeFlags ? [ ], + requiredSystemFeatures ? [ "big-parallel" ], + enabled ? true, + onlyFor ? [ ], + }: + let + supported = + enabled + && (onlyFor == [ ] || (lib.lists.intersectLists composable_kernel_base.gpuTargets onlyFor) != [ ]); + in + if supported then + (composable_kernel_base.overrideAttrs (old: { + inherit requiredSystemFeatures; + pname = "composable_kernel${clr.gpuArchSuffix}-${part}"; + makeTargets = targets; + preBuild = '' + echo "Building ${part}" + makeFlagsArray+=($makeTargets) + substituteInPlace $(find ./ -name "Makefile" -type f) \ + --replace-fail '.NOTPARALLEL:' '.UNUSED_NOTPARALLEL:' + ''; + + # Compile parallelism adjusted based on available RAM + # Never uses less than NIX_BUILD_CORES/4, never uses more than NIX_BUILD_CORES + # CK uses an unusually high amount of memory per core in the build step + # Nix/nixpkgs doesn't really have any infra to tell it that this build is unusually memory hungry + # So, bodge. Otherwise you end up having to build all of ROCm with a low core limit when + # it's only this package that has trouble. + preConfigure = old.preConfigure or "" + '' + MEM_GB_TOTAL=$(awk '/MemTotal/ { printf "%d \n", $2/1024/1024 }' /proc/meminfo) + MEM_GB_AVAILABLE=$(awk '/MemAvailable/ { printf "%d \n", $2/1024/1024 }' /proc/meminfo) + APPX_GB=$((MEM_GB_AVAILABLE > MEM_GB_TOTAL ? MEM_GB_TOTAL : MEM_GB_AVAILABLE)) + MAX_CORES=$((1 + APPX_GB/3)) + MAX_CORES=$((MAX_CORES < NIX_BUILD_CORES/3 ? NIX_BUILD_CORES/3 : MAX_CORES)) + export NIX_BUILD_CORES="$((NIX_BUILD_CORES > MAX_CORES ? MAX_CORES : NIX_BUILD_CORES))" + echo "Picked new core limit NIX_BUILD_CORES=$NIX_BUILD_CORES based on available mem: $APPX_GB GB" + cmakeFlagsArray+=( + "-DCK_PARALLEL_COMPILE_JOBS=$NIX_BUILD_CORES" + ) + ''; + cmakeFlags = old.cmakeFlags ++ extraCmakeFlags; + # Early exit after build phase with success, skips fixups etc + # Will get copied back into /build of the final CK + postBuild = '' + find . -name "*.o" -type f | while read -r file; do + mkdir -p "$out/$(dirname "$file")" + cp --reflink=auto "$file" "$out/$file" + done + exit 0 + ''; + meta = old.meta // { + broken = false; + }; + })) + else + null; + composable_kernel_parts = builtins.mapAttrs ( + part: targets: tensorOpBuilder (targets // { inherit part; }) + ) parts; +in + +composable_kernel_base.overrideAttrs ( + finalAttrs: old: { + pname = "composable_kernel${clr.gpuArchSuffix}"; + parts_dirs = builtins.filter (x: x != null) (builtins.attrValues composable_kernel_parts); + disallowedReferences = builtins.filter (x: x != null) (builtins.attrValues composable_kernel_parts); + preBuild = '' + for dir in $parts_dirs; do + find "$dir" -type f -name "*.o" | while read -r file; do + # Extract the relative path by removing the output directory prefix + rel_path="''${file#"$dir/"}" + + # Create parent directory if it doesn't exist + mkdir -p "$(dirname "$rel_path")" + + # Copy the file back to its original location, give it a future timestamp + # so make treats it as up to date + cp --reflink=auto --no-preserve=all "$file" "$rel_path" + touch -d "now +10 hours" "$rel_path" + done + done + ''; + passthru = old.passthru // { + parts = composable_kernel_parts; + }; + meta = old.meta // { + # Builds without any gfx9 fail + broken = !finalAttrs.passthru.anyGfx9Target; + }; + } +) diff --git a/.devops/nix/rocm-modules-10/composable_kernel/fix-empty-offload-targets.diff b/.devops/nix/rocm-modules-10/composable_kernel/fix-empty-offload-targets.diff new file mode 100644 index 0000000000..d314873ff6 --- /dev/null +++ b/.devops/nix/rocm-modules-10/composable_kernel/fix-empty-offload-targets.diff @@ -0,0 +1,23 @@ +diff --git a/library/src/tensor_operation_instance/gpu/CMakeLists.txt b/library/src/tensor_operation_instance/gpu/CMakeLists.txt +index 172f6681b8..d3ddbb2f15 100644 +--- a/library/src/tensor_operation_instance/gpu/CMakeLists.txt ++++ b/library/src/tensor_operation_instance/gpu/CMakeLists.txt +@@ -154,9 +154,15 @@ function(add_instance_library INSTANCE_NAME) + list(FILTER INST_TARGETS INCLUDE REGEX "gfx12") + endif() + set(offload_targets) +- foreach(target IN LISTS INST_TARGETS) +- string(APPEND offload_targets "--offload-arch=${target} ") +- endforeach() ++ if(NOT INST_TARGETS) ++ # No valid GPU targets for this source, compile for 90a as fallback ++ # so the add_device…instances and hip_fatbin… symbols still exist ++ set(offload_targets "--offload-arch=gfx90a") ++ else() ++ foreach(target IN LISTS INST_TARGETS) ++ string(APPEND offload_targets "--offload-arch=${target} ") ++ endforeach() ++ endif() + set_source_files_properties(${source} PROPERTIES COMPILE_FLAGS ${offload_targets}) + list(APPEND INST_OBJ ${source}) + endforeach() diff --git a/.devops/nix/rocm-modules-10/default.nix b/.devops/nix/rocm-modules-10/default.nix new file mode 100644 index 0000000000..0fb3980789 --- /dev/null +++ b/.devops/nix/rocm-modules-10/default.nix @@ -0,0 +1,344 @@ +{ + lib, + config, + callPackage, + newScope, + boost179, + opencv, + python3Packages, + openmpi, + stdenv, + pkgs, +}: + +let + outer = lib.makeScope newScope ( + self: + let + inherit (self) llvm; + origStdenv = stdenv; + pyPackages = python3Packages; + openmpi-orig = openmpi; + rocmClangStdenv = llvm.rocmClangStdenv; + in + { + inherit rocmClangStdenv; + stdenv = rocmClangStdenv; + + rocmUpdateScript = self.callPackage ./update.nix { }; + + ## ROCm ## + llvm = lib.recurseIntoAttrs ( + callPackage ./llvm/default.nix { + # rocm-device-libs is used for .src only + # otherwise would cause infinite recursion + inherit (self) rocm-device-libs; + } + ); + inherit (self.llvm) rocm-toolchain clang openmp; + + rocm-core = self.callPackage ./rocm-core { stdenv = origStdenv; }; + + rocm-cmake = self.callPackage ./rocm-cmake { stdenv = origStdenv; }; + + rocm-device-libs = self.callPackage ./rocm-device-libs { }; + + rocm-runtime = self.callPackage ./rocm-runtime { + stdenv = origStdenv; + }; + + rocm-comgr = self.callPackage ./rocm-comgr { }; + + rocminfo = self.callPackage ./rocminfo { stdenv = origStdenv; }; + + amdsmi = pyPackages.callPackage ./amdsmi { + inherit (self) rocmUpdateScript; + }; + + rocm-smi = pyPackages.callPackage ./rocm-smi { + inherit (self) rocmUpdateScript; + }; + + aqlprofile = self.callPackage ./aqlprofile { }; + + rdc = self.callPackage ./rdc { }; + + rocm-docs-core = python3Packages.callPackage ./rocm-docs-core { }; + + hip-common = self.callPackage ./hip-common { }; + + hipcc = self.callPackage ./hipcc { stdenv = origStdenv; }; + + # Replaces hip, opencl-runtime, and rocclr + clr = self.callPackage ./clr { }; + + aotriton = self.callPackage ./aotriton { stdenv = origStdenv; }; + + hipify = self.callPackage ./hipify { + stdenv = origStdenv; + }; + + # hsakmt was merged into rocm-runtime + hsakmt = self.rocm-runtime; + + rocprofiler = self.callPackage ./rocprofiler { + inherit (llvm) clang; + }; + rocprofiler-register = self.callPackage ./rocprofiler-register { + inherit (llvm) clang; + }; + rocprofiler-sdk = self.callPackage ./rocprofiler-sdk { }; + + rocprof-compute-viewer = self.callPackage ./rocprof-compute-viewer { }; + + rocprof-trace-decoder = self.callPackage ./rocprof-trace-decoder { }; + + roctracer = self.callPackage ./roctracer { }; + + rocgdb = self.callPackage ./rocgdb { }; + + rocdbgapi = self.callPackage ./rocdbgapi { }; + + rocr-debug-agent = self.callPackage ./rocr-debug-agent { }; + + rocprim = self.callPackage ./rocprim { }; + + rocsparse = self.callPackage ./rocsparse { }; + + rocthrust = self.callPackage ./rocthrust { }; + + rocrand = self.callPackage ./rocrand { }; + + hiprand = self.callPackage ./hiprand { }; + + rocfft = self.callPackage ./rocfft { }; + + mscclpp = self.callPackage ./mscclpp { }; + + rccl = self.callPackage ./rccl { }; + + rocshmem = self.callPackage ./rocshmem { }; + + hipcub = self.callPackage ./hipcub { }; + + hipsparse = self.callPackage ./hipsparse { }; + + hipfort = self.callPackage ./hipfort { }; + + hipfft = self.callPackage ./hipfft { }; + + hiprt = self.callPackage ./hiprt { }; + + tensile = pyPackages.callPackage ./tensile { + inherit (self) + rocmUpdateScript + clr + ; + }; + + rocblas = self.callPackage ./rocblas { }; + + rocsolver = self.callPackage ./rocsolver { }; + + rocwmma = self.callPackage ./rocwmma { }; + + rocalution = self.callPackage ./rocalution { }; + + rocmlir-rock = self.callPackage ./rocmlir { + buildRockCompiler = true; + }; + rocmlir = self.rocmlir-rock; + + hipsolver = self.callPackage ./hipsolver { }; + + hipblas-common = self.callPackage ./hipblas-common { }; + + hipblas = self.callPackage ./hipblas { }; + + hipblaslt = self.callPackage ./hipblaslt { }; + + hipsparselt = self.callPackage ./hipsparselt { }; + + # hipTensor - Only supports GFX9 + + composable_kernel_base = self.callPackage ./composable_kernel/base.nix { }; + composable_kernel = self.callPackage ./composable_kernel { }; + + ck4inductor = pyPackages.callPackage ./composable_kernel/ck4inductor.nix { + inherit (self) composable_kernel rocm-toolchain; + }; + + half = self.callPackage ./half { }; + + miopen = self.callPackage ./miopen { + boost = boost179.override { enableStatic = true; }; + }; + + miopen-hip = self.miopen; + + migraphx = self.callPackage ./migraphx { stdenv = origStdenv; }; + + rpp = self.callPackage ./rpp { }; + + rpp-hip = self.rpp.override { useCPU = false; }; + + rpp-cpu = self.rpp.override { useCPU = true; }; + + mivisionx = self.callPackage ./mivisionx { + stdenv = origStdenv; + opencv = opencv.override { enablePython = true; }; + }; + + mivisionx-hip = self.mivisionx.override { + rpp = self.rpp-hip; + useOpenCL = false; + useCPU = false; + }; + + mivisionx-cpu = self.mivisionx.override { + rpp = self.rpp-cpu; + useOpenCL = false; + useCPU = true; + }; + + # Even if config.rocmSupport is false we need rocmSupport true + # version of ucc/ucx in openmpi in this package set + openmpi = openmpi-orig.override ( + prev: + let + ucx = prev.ucx.override { + enableCuda = false; + enableRocm = true; + rocmPackages = self; + }; + in + { + inherit ucx; + ucc = prev.ucc.override { + enableCuda = false; + inherit ucx; + }; + } + ); + mpi = self.openmpi; + + meta = { + # eval all pkgsRocm release attrs with + # nix-eval-jobs --force-recurse pkgs/top-level/release.nix -I . --select "p: p.pkgsRocm" --no-instantiate + release-packagePlatforms = + let + platforms = [ + "x86_64-linux" + ]; + attrPaths = (builtins.fromJSON (builtins.readFile ./release-attrPaths.json)).attrPaths; + in + lib.foldl' ( + acc: path: + if lib.hasAttrByPath (lib.splitString "." path) pkgs then + lib.recursiveUpdate acc (lib.setAttrByPath (lib.splitString "." path) platforms) + else + acc + ) { } attrPaths; + }; + + rocm-bandwidth-test = self.callPackage ./rocm-bandwidth-test { + rocmPackages = self; + }; + + rocm-tests = self.callPackage ./rocm-tests { + rocmPackages = self; + }; + } + // lib.optionalAttrs config.allowAliases { + rpp-opencl = throw '' + 'rpp-opencl' has been removed as it has been broken for a year and has no consuming packages. + Use 'rpp' or 'rpp-cpu' instead. + ''; # Added 2026-03-08 + + rocmPath = throw '' + 'rocm-path' has been removed. If a ROCM_PATH value is required in nixpkgs please + construct one with the minimal set of required deps. + For convenience use outside of nixpkgs consider one of the entries in + 'rocmPackages.meta'. + ''; # Added 2025-09-30 + + rocm-merged-llvm = throw '' + 'rocm-merged-llvm' has been removed. + For 'libllvm' or 'libclang' use 'rocmPackages.llvm.libllvm/clang'. + For a ROCm compiler toolchain use 'rocmPackages.rocm-toolchain'. + If a package uses '$' in CMake from 'libclang' + it may be necessary to convince it to use 'rocm-toolchain' instead. + 'rocm-merged-llvm' avoided this at the cost of significantly bloating closure + size. + ''; # Added 2025-09-30 + + hsa-amd-aqlprofile-bin = lib.warn '' + 'hsa-amd-aqlprofile-bin' has been replaced by 'aqlprofile'. + '' self.aqlprofile; # Added 2025-08-27 + + triton = throw '' + 'rocmPackages.triton' has been removed. Please use python3Packages.triton + ''; # Added 2025-08-24 + + rocm-thunk = throw '' + 'rocm-thunk' has been removed. It's now part of the ROCm runtime. + ''; # Added 2025-3-16 + + clang-ocl = throw '' + 'clang-ocl' has been deprecated upstream. Use ROCm's clang directly. + ''; # Added 2025-3-16 + + miopengemm = throw '' + 'miopengemm' has been deprecated. + ''; # Added 2024-3-3 + + miopen-opencl = throw '' + 'miopen-opencl' has been deprecated. + ''; # Added 2024-3-3 + + mivisionx-opencl = throw '' + 'mivisionx-opencl' has been deprecated. + Other versions of mivisionx are still available. + ''; # Added 2024-3-24 + } + ); + scopeForArches = + arches: + outer.overrideScope ( + _final: prev: { + clr = prev.clr.override { + localGpuTargets = arches; + }; + } + ); +in +outer +// builtins.listToAttrs ( + map (arch: { + name = arch; + value = scopeForArches [ arch ]; + }) outer.clr.gpuTargets +) +// { + gfx9 = scopeForArches [ + "gfx906" + "gfx908" + "gfx90a" + "gfx942" + ]; + gfx10 = scopeForArches [ + "gfx1010" + "gfx1030" + ]; + gfx11 = scopeForArches [ + "gfx1100" + "gfx1101" + "gfx1102" + "gfx1150" + "gfx1151" + ]; + gfx12 = scopeForArches [ + "gfx1200" + "gfx1201" + ]; +} diff --git a/.devops/nix/rocm-modules-10/half/default.nix b/.devops/nix/rocm-modules-10/half/default.nix new file mode 100644 index 0000000000..cdd55d421d --- /dev/null +++ b/.devops/nix/rocm-modules-10/half/default.nix @@ -0,0 +1,35 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "half"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "half"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-If9O5BEeymsLN+C0drZsPSxEWXpJTxeDBGNHNXSumm4="; + }; + + nativeBuildInputs = [ + cmake + rocm-cmake + ]; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "C++ library for half precision floating point arithmetics"; + homepage = "https://github.com/ROCm/half"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.unix; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hip-common/default.nix b/.devops/nix/rocm-modules-10/hip-common/default.nix new file mode 100644 index 0000000000..5495242975 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hip-common/default.nix @@ -0,0 +1,46 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "hip-common"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/hip" + "shared" + ]; + hash = "sha256-v30H6y9zgB5B2AzlxJsKu0mbJMxpi3q45bc3+pbbB8M="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hip"; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + + mkdir -p $out + mv * $out + + runHook postInstall + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "C++ Heterogeneous-Compute Interface for Portability"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/hip"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipblas-common/default.nix b/.devops/nix/rocm-modules-10/hipblas-common/default.nix new file mode 100644 index 0000000000..4c4d0b4251 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipblas-common/default.nix @@ -0,0 +1,43 @@ +{ + lib, + stdenv, + cmake, + fetchFromGitHub, + rocm-cmake, + rocmUpdateScript, +}: +stdenv.mkDerivation (finalAttrs: { + pname = "hipblas-common"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/hipblas-common" + "shared" + ]; + hash = "sha256-XqTpDOCxCrxwUifreTSHDhVgne2CFahMi44VQMPNnjA="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipblas-common"; + + nativeBuildInputs = [ + cmake + ]; + + buildInputs = [ + rocm-cmake + ]; + + strictDeps = true; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + meta = { + description = "Common files shared by hipBLAS and hipBLASLt"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipblas-common"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipblas/default.nix b/.devops/nix/rocm-modules-10/hipblas/default.nix new file mode 100644 index 0000000000..09e1196802 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipblas/default.nix @@ -0,0 +1,135 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + python3, + rocm-cmake, + clr, + gfortran, + hipblas-common, + rocblas, + rocsolver, + rocsparse, + rocprim, + gtest, + lapack-reference, + buildTests ? false, + buildBenchmarks ? false, + buildSamples ? false, + # for passthru.tests + hipblas, +}: + +# Can also use cuBLAS +stdenv.mkDerivation (finalAttrs: { + pname = "hipblas"; + version = "10.0.0"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ] + ++ lib.optionals buildSamples [ + "sample" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/hipblas" + "shared" + ]; + hash = "sha256-/Pr+tj0uZaELnett+sRodpZdaKWE3uX96CKIOPvs5xI="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipblas"; + + postPatch = '' + substituteInPlace library/CMakeLists.txt \ + --replace-fail "find_package(Git REQUIRED)" "" + ''; + + nativeBuildInputs = [ + cmake + # ROCm 10's hipblas needs an interpreter at configure time + python3 + rocm-cmake + clr + gfortran + ]; + + propagatedBuildInputs = [ hipblas-common ]; + + buildInputs = [ + rocblas + rocprim + rocsparse + rocsolver + ] + ++ lib.optionals buildTests [ + gtest + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + lapack-reference + ]; + + cmakeFlags = [ + "-DCMAKE_CXX_COMPILER=${lib.getExe' clr "amdclang++"}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DBUILD_WITH_SOLVER=ON" + "-DAMDGPU_TARGETS=${rocblas.amdgpu_targets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_CLIENTS_TESTS=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_CLIENTS_BENCHMARKS=ON" + ] + ++ lib.optionals buildSamples [ + "-DBUILD_CLIENTS_SAMPLES=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/hipblas-test $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/hipblas-bench $benchmark/bin + '' + + lib.optionalString buildSamples '' + mkdir -p $sample/bin + mv $out/bin/example-* $sample/bin + '' + + lib.optionalString (buildTests || buildBenchmarks || buildSamples) '' + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + passthru.tests.hipblas-tested = hipblas.override { + buildTests = true; + buildBenchmarks = true; + buildSamples = true; + }; + + meta = { + description = "ROCm BLAS marshalling library"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipblas"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipblaslt/Tensile-interning.patch b/.devops/nix/rocm-modules-10/hipblaslt/Tensile-interning.patch new file mode 100644 index 0000000000..acf4443752 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipblaslt/Tensile-interning.patch @@ -0,0 +1,181 @@ +diff --git a/tensilelite/Tensile/Common/Utilities.py b/tensilelite/Tensile/Common/Utilities.py +index 0a9d9db5b3..cb9779eaac 100644 +--- a/tensilelite/Tensile/Common/Utilities.py ++++ b/tensilelite/Tensile/Common/Utilities.py +@@ -24,6 +24,7 @@ + + import functools + import math ++import operator + import os + import sys + import time +@@ -269,8 +270,20 @@ def state(obj): + + + def state_key_ordering(cls): +- def tup(obj): +- return tuple([getattr(obj, k) for k in cls.StateKeys]) ++ # Use operator.attrgetter for efficiency if __slots__ is defined ++ if hasattr(cls, '__slots__'): ++ # attrgetter is faster for slotted classes ++ getter = operator.attrgetter(*cls.StateKeys) ++ if len(cls.StateKeys) == 1: ++ # attrgetter returns scalar for single key, we need tuple ++ def tup(obj): ++ return (getter(obj),) ++ else: ++ tup = getter ++ else: ++ # Fallback for regular classes ++ def tup(obj): ++ return tuple([getattr(obj, k) for k in cls.StateKeys]) + + def lt(a, b): + return tup(a) < tup(b) +diff --git a/tensilelite/Tensile/Contractions.py b/tensilelite/Tensile/Contractions.py +index c0d4e851b1..3f2c2e98c6 100644 +--- a/tensilelite/Tensile/Contractions.py ++++ b/tensilelite/Tensile/Contractions.py +@@ -37,9 +37,60 @@ from Tensile.Toolchain.Component import Assembler + from math import ceil + + MIN_K_FOR_GSU = 32 ++ ++# Interning helpers to reduce memory usage by reusing identical objects ++_free_index_cache = {} ++def intern_free_index(isA, i=None, c=None, d=None, a=None, b=None): ++ key = (isA, i, c, d, a, b) ++ if key not in _free_index_cache: ++ obj = FreeIndex(isA, i, c, d) ++ obj.a = a ++ if b is not None: ++ obj.b = b ++ _free_index_cache[key] = obj ++ return _free_index_cache[key] ++ ++_batch_index_cache = {} ++def intern_batch_index(a=None, b=None, c=None, d=None): ++ key = (a, b, c, d) ++ if key not in _batch_index_cache: ++ obj = BatchIndex(c=c, d=d) ++ obj.a = a ++ obj.b = b ++ _batch_index_cache[key] = obj ++ return _batch_index_cache[key] ++ ++_bound_index_cache = {} ++def intern_bound_index(a=None, b=None, aMirror=False, bMirror=False): ++ key = (a, b, aMirror, bMirror) ++ if key not in _bound_index_cache: ++ obj = BoundIndex(aMirror=aMirror, bMirror=bMirror) ++ obj.a = a ++ obj.b = b ++ _bound_index_cache[key] = obj ++ return _bound_index_cache[key] ++ ++_size_mapping_cache = {} ++def intern_size_mapping(size_mapping): ++ """Intern a SizeMapping instance to reduce redundancy.""" ++ # Build hashable key from StateKeys, converting lists to tuples ++ key_parts = [] ++ for attr in size_mapping.StateKeys: ++ val = getattr(size_mapping, attr) ++ # Convert lists to tuples for hashing ++ if isinstance(val, list): ++ val = tuple(val) ++ key_parts.append(val) ++ key = tuple(key_parts) ++ ++ if key not in _size_mapping_cache: ++ _size_mapping_cache[key] = size_mapping ++ return _size_mapping_cache[key] ++ + @state_key_ordering + class FreeIndex: + StateKeys = ['isA', 'i', 'c', 'd'] ++ __slots__ = ['isA', 'i', 'c', 'd', 'a', 'b'] + + def __init__(self, isA, i=None, c=None, d=None): + self.isA = isA +@@ -50,6 +101,7 @@ class FreeIndex: + @state_key_ordering + class BatchIndex: + StateKeys = ['a', 'b', 'c', 'd'] ++ __slots__ = ['a', 'b', 'c', 'd'] + def __init__(self, a=None, b=None, c=None, d=None): + self.a = a + self.b = b +@@ -59,6 +111,7 @@ class BatchIndex: + @state_key_ordering + class BoundIndex: + StateKeys = ['a', 'b', 'aMirror', 'bMirror'] ++ __slots__ = ['a', 'b', 'aMirror', 'bMirror'] + def __init__(self, a=None, b=None, aMirror=False, bMirror=False): + self.a = a + self.b = b +@@ -107,6 +160,23 @@ class ProblemType: + for ib, ic in enumerate(d['IndexAssignmentsB']): + indices[ic].b = ib + ++ # Now intern all indices with their final state (including .a and .b) ++ for i, idx in enumerate(indices): ++ if isinstance(idx, FreeIndex): ++ indices[i] = intern_free_index(idx.isA, idx.i, idx.c, idx.d, ++ getattr(idx, 'a', None), getattr(idx, 'b', None)) ++ elif isinstance(idx, BatchIndex): ++ indices[i] = intern_batch_index(getattr(idx, 'a', None), getattr(idx, 'b', None), ++ idx.c, idx.d) ++ elif isinstance(idx, BoundIndex): ++ indices[i] = intern_bound_index(getattr(idx, 'a', None), getattr(idx, 'b', None), ++ idx.aMirror, idx.bMirror) ++ ++ # Update the lists with interned versions ++ freeIndices = [idx for idx in indices if isinstance(idx, FreeIndex)] ++ batchIndices = [idx for idx in indices if isinstance(idx, BatchIndex)] ++ boundIndices = [idx for idx in indices if isinstance(idx, BoundIndex)] ++ + for idx in indices: + assert idx is not None + idxState = state(idx) +@@ -596,6 +666,7 @@ class SizeMapping: + 'nonTemporalA', + 'nonTemporalB', + ] ++ __slots__ = StateKeys + + @classmethod + def FromOriginalState(cls, d): +@@ -751,7 +822,7 @@ class Solution: + info = cls.ReadOriginalInfo(d) + rv.libraryLogicIndex = int(info.get("SolutionIndex", -1)) + +- rv.sizeMapping = SizeMapping.FromOriginalState(d) ++ rv.sizeMapping = intern_size_mapping(SizeMapping.FromOriginalState(d)) + + rv.internalArgsSupport = InternalArgsSupport.FromOriginalState(d) + +diff --git a/tensilelite/Tensile/TensileCreateLibrary/Run.py b/tensilelite/Tensile/TensileCreateLibrary/Run.py +index 730b6b1fff..b0068563a0 100644 +--- a/tensilelite/Tensile/TensileCreateLibrary/Run.py ++++ b/tensilelite/Tensile/TensileCreateLibrary/Run.py +@@ -104,7 +104,6 @@ class KernelCodeGenResult(NamedTuple): + src: str + header: Optional[str] + name: str +- targetObjFilename: str + isa: IsaVersion + wavefrontSize: int + cuoccupancy: int +@@ -127,10 +126,9 @@ def processKernelSource(kernelWriterAssembly, data, splitGSU, kernel) -> KernelC + asmFilename = getKernelFileBase(splitGSU, kernel) + err, src = kernelWriter.getSourceFileString(kernel) + header = kernelWriter.getHeaderFileString(kernel) +- objFilename = kernel._state.get("codeObjectFile", None) + pgr = int(kernel["PrefetchGlobalRead"]) + return KernelCodeGenResult( +- err, src, header, asmFilename, objFilename, tuple(kernel["ISA"]), \ ++ err, src, header, asmFilename, tuple(kernel["ISA"]), \ + kernel["WavefrontSize"], kernel["CUOccupancy"], \ + pgr, kernel["MathClocksUnrolledLoop"] + ) diff --git a/.devops/nix/rocm-modules-10/hipblaslt/TensileCreateLibrary-refactor.patch b/.devops/nix/rocm-modules-10/hipblaslt/TensileCreateLibrary-refactor.patch new file mode 100644 index 0000000000..1accf91426 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipblaslt/TensileCreateLibrary-refactor.patch @@ -0,0 +1,849 @@ +diff --git a/tensilelite/Tensile/Common/Parallel.py b/tensilelite/Tensile/Common/Parallel.py +index 1a2bf9e119..f46100c7b8 100644 +--- a/tensilelite/Tensile/Common/Parallel.py ++++ b/tensilelite/Tensile/Common/Parallel.py +@@ -22,43 +22,58 @@ + # + ################################################################################ + +-import concurrent.futures +-import itertools ++import multiprocessing + import os ++import re + import sys + import time +- +-from joblib import Parallel, delayed ++from functools import partial ++from typing import Any, Callable + + from .Utilities import tqdm + + +-def joblibParallelSupportsGenerator(): +- import joblib +- from packaging.version import Version ++def get_inherited_job_limit() -> int: ++ # 1. Check CMAKE_BUILD_PARALLEL_LEVEL (CMake 3.12+) ++ if 'CMAKE_BUILD_PARALLEL_LEVEL' in os.environ: ++ try: ++ return int(os.environ['CMAKE_BUILD_PARALLEL_LEVEL']) ++ except ValueError: ++ pass + +- joblibVer = joblib.__version__ +- return Version(joblibVer) >= Version("1.4.0") ++ # 2. Parse MAKEFLAGS for -jN ++ makeflags = os.environ.get('MAKEFLAGS', '') ++ match = re.search(r'-j\s*(\d+)', makeflags) ++ if match: ++ return int(match.group(1)) + ++ return -1 + +-def CPUThreadCount(enable=True): +- from .GlobalParameters import globalParameters + ++def CPUThreadCount(enable=True): + if not enable: + return 1 +- else: ++ from .GlobalParameters import globalParameters ++ ++ # Priority order: ++ # 1. Inherited from build system (CMAKE_BUILD_PARALLEL_LEVEL or MAKEFLAGS) ++ # 2. Explicit --jobs flag ++ # 3. Auto-detect ++ inherited_limit = get_inherited_job_limit() ++ cpuThreads = inherited_limit if inherited_limit > 0 else globalParameters["CpuThreads"] ++ ++ if cpuThreads < 1: + if os.name == "nt": +- # Windows supports at most 61 workers because the scheduler uses +- # WaitForMultipleObjects directly, which has the limit (the limit +- # is actually 64, but some handles are needed for accounting). +- cpu_count = min(os.cpu_count(), 61) ++ cpuThreads = os.cpu_count() + else: +- cpu_count = len(os.sched_getaffinity(0)) +- cpuThreads = globalParameters["CpuThreads"] +- if cpuThreads == -1: +- return cpu_count ++ cpuThreads = len(os.sched_getaffinity(0)) + +- return min(cpu_count, cpuThreads) ++ if os.name == "nt": ++ # Windows supports at most 61 workers because the scheduler uses ++ # WaitForMultipleObjects directly, which has the limit (the limit ++ # is actually 64, but some handles are needed for accounting). ++ cpuThreads = min(cpuThreads, 61) ++ return max(1, cpuThreads) + + + def pcallWithGlobalParamsMultiArg(f, args, newGlobalParameters): +@@ -71,19 +86,22 @@ def pcallWithGlobalParamsSingleArg(f, arg, newGlobalParameters): + return f(arg) + + +-def apply_print_exception(item, *args): +- # print(item, args) ++def OverwriteGlobalParameters(newGlobalParameters): ++ from . import GlobalParameters ++ ++ GlobalParameters.globalParameters.clear() ++ GlobalParameters.globalParameters.update(newGlobalParameters) ++ ++ ++def worker_function(args, function, multiArg): ++ """Worker function that executes in the pool process.""" + try: +- if len(args) > 0: +- func = item +- args = args[0] +- return func(*args) ++ if multiArg: ++ return function(*args) + else: +- func, item = item +- return func(item) ++ return function(args) + except Exception: + import traceback +- + traceback.print_exc() + raise + finally: +@@ -98,154 +116,121 @@ def OverwriteGlobalParameters(newGlobalParameters): + GlobalParameters.globalParameters.update(newGlobalParameters) + + +-def ProcessingPool(enable=True, maxTasksPerChild=None): +- import multiprocessing +- import multiprocessing.dummy +- +- threadCount = CPUThreadCount() +- +- if (not enable) or threadCount <= 1: +- return multiprocessing.dummy.Pool(1) +- +- if multiprocessing.get_start_method() == "spawn": +- from . import GlobalParameters +- +- return multiprocessing.Pool( +- threadCount, +- initializer=OverwriteGlobalParameters, +- maxtasksperchild=maxTasksPerChild, +- initargs=(GlobalParameters.globalParameters,), +- ) +- else: +- return multiprocessing.Pool(threadCount, maxtasksperchild=maxTasksPerChild) ++def progress_logger(iterable, total, message, min_log_interval=5.0): ++ """ ++ Generator that wraps an iterable and logs progress with time-based throttling. + ++ Only logs progress if at least min_log_interval seconds have passed since last log. ++ Only prints completion message if task took >= min_log_interval seconds. + +-def ParallelMap(function, objects, message="", enable=True, method=None, maxTasksPerChild=None): ++ Yields (index, item) tuples. + """ +- Generally equivalent to list(map(function, objects)), possibly executing in parallel. +- +- message: A message describing the operation to be performed. +- enable: May be set to false to disable parallelism. +- method: A function which can fetch the mapping function from a processing pool object. +- Leave blank to use .map(), other possiblities: +- - `lambda x: x.starmap` - useful if `function` takes multiple parameters. +- - `lambda x: x.imap` - lazy evaluation +- - `lambda x: x.imap_unordered` - lazy evaluation, does not preserve order of return value. +- """ +- from .GlobalParameters import globalParameters ++ start_time = time.time() ++ last_log_time = start_time ++ log_interval = 1 + (total // 100) + +- threadCount = CPUThreadCount(enable) +- pool = ProcessingPool(enable, maxTasksPerChild) +- +- if threadCount <= 1 and globalParameters["ShowProgressBar"]: +- # Provide a progress bar for single-threaded operation. +- # This works for method=None, and for starmap. +- mapFunc = map +- if method is not None: +- # itertools provides starmap which can fill in for pool.starmap. It provides imap on Python 2.7. +- # If this works, we will use it, otherwise we will fallback to the "dummy" pool for single threaded +- # operation. +- try: +- mapFunc = method(itertools) +- except NameError: +- mapFunc = None +- +- if mapFunc is not None: +- return list(mapFunc(function, tqdm(objects, message))) +- +- mapFunc = pool.map +- if method: +- mapFunc = method(pool) +- +- objects = zip(itertools.repeat(function), objects) +- function = apply_print_exception +- +- countMessage = "" +- try: +- countMessage = " for {} tasks".format(len(objects)) +- except TypeError: +- pass ++ for idx, item in enumerate(iterable): ++ if idx % log_interval == 0: ++ current_time = time.time() ++ if (current_time - last_log_time) >= min_log_interval: ++ print(f"{message}\t{idx+1: 5d}/{total: 5d}") ++ last_log_time = current_time ++ yield idx, item + +- if message != "": +- message += ": " ++ elapsed = time.time() - start_time ++ final_idx = idx + 1 if 'idx' in locals() else 0 + +- print("{0}Launching {1} threads{2}...".format(message, threadCount, countMessage)) +- sys.stdout.flush() +- currentTime = time.time() +- rv = mapFunc(function, objects) +- totalTime = time.time() - currentTime +- print("{0}Done. ({1:.1f} secs elapsed)".format(message, totalTime)) +- sys.stdout.flush() +- pool.close() +- return rv ++ if elapsed >= min_log_interval or last_log_time > start_time: ++ print(f"{message} done in {elapsed:.1f}s!\t{final_idx: 5d}/{total: 5d}") + + +-def ParallelMapReturnAsGenerator(function, objects, message="", enable=True, multiArg=True): +- from .GlobalParameters import globalParameters ++def imap_with_progress(pool, func, iterable, total, message, chunksize): ++ results = [] ++ for _, result in progress_logger(pool.imap(func, iterable, chunksize=chunksize), total, message): ++ results.append(result) ++ return results + +- threadCount = CPUThreadCount(enable) +- print("{0}Launching {1} threads...".format(message, threadCount)) + +- if threadCount <= 1 and globalParameters["ShowProgressBar"]: +- # Provide a progress bar for single-threaded operation. +- callFunc = lambda args: function(*args) if multiArg else lambda args: function(args) +- return [callFunc(args) for args in tqdm(objects, message)] ++def _ParallelMap_generator(worker, objects, objLen, message, chunksize, threadCount, globalParameters, maxtasksperchild): ++ # separate fn because yield makes the entire fn a generator even if unreachable ++ ctx = multiprocessing.get_context('forkserver' if os.name != 'nt' else 'spawn') + +- with concurrent.futures.ProcessPoolExecutor(max_workers=threadCount) as executor: +- resultFutures = (executor.submit(function, *arg if multiArg else arg) for arg in objects) +- for result in concurrent.futures.as_completed(resultFutures): +- yield result.result() ++ with ctx.Pool(processes=threadCount, maxtasksperchild=maxtasksperchild, ++ initializer=OverwriteGlobalParameters, initargs=(globalParameters,)) as pool: ++ for _, result in progress_logger(pool.imap_unordered(worker, objects, chunksize=chunksize), objLen, message): ++ yield result + + + def ParallelMap2( +- function, objects, message="", enable=True, multiArg=True, return_as="list", procs=None ++ function: Callable, ++ objects: Any, ++ message: str = "", ++ enable: bool = True, ++ multiArg: bool = True, ++ minChunkSize: int = 1, ++ maxWorkers: int = -1, ++ maxtasksperchild: int = 1024, ++ return_as: str = "list" + ): ++ """Executes a function over a list of objects in parallel or sequentially. ++ ++ This function is generally equivalent to ``list(map(function, objects))``. However, it provides ++ additional functionality to run in parallel, depending on the 'enable' flag and available CPU ++ threads. ++ ++ Args: ++ function: The function to apply to each item in 'objects'. If 'multiArg' is True, 'function' ++ should accept multiple arguments. ++ objects: An iterable of objects to be processed by 'function'. If 'multiArg' is True, each ++ item in 'objects' should be an iterable of arguments for 'function'. ++ message: Optional; a message describing the operation. Default is an empty string. ++ enable: Optional; if False, disables parallel execution and runs sequentially. Default is True. ++ multiArg: Optional; if True, treats each item in 'objects' as multiple arguments for ++ 'function'. Default is True. ++ return_as: Optional; "list" (default) or "generator_unordered" for streaming results ++ ++ Returns: ++ A list or generator containing the results of applying **function** to each item in **objects**. + """ +- Generally equivalent to list(map(function, objects)), possibly executing in parallel. ++ from .GlobalParameters import globalParameters + +- message: A message describing the operation to be performed. +- enable: May be set to false to disable parallelism. +- multiArg: True if objects represent multiple arguments +- (differentiates multi args vs single collection arg) +- """ +- if return_as in ("generator", "generator_unordered") and not joblibParallelSupportsGenerator(): +- return ParallelMapReturnAsGenerator(function, objects, message, enable, multiArg) ++ threadCount = CPUThreadCount(enable) + +- from .GlobalParameters import globalParameters ++ if not hasattr(objects, "__len__"): ++ objects = list(objects) + +- threadCount = procs if procs else CPUThreadCount(enable) ++ objLen = len(objects) ++ if objLen == 0: ++ return [] if return_as == "list" else iter([]) + +- threadCount = CPUThreadCount(enable) ++ f = (lambda x: function(*x)) if multiArg else function ++ if objLen == 1: ++ print(f"{message}: (1 task)") ++ result = [f(x) for x in objects] ++ return result if return_as == "list" else iter(result) + +- if threadCount <= 1 and globalParameters["ShowProgressBar"]: +- # Provide a progress bar for single-threaded operation. +- return [function(*args) if multiArg else function(args) for args in tqdm(objects, message)] ++ extra_message = ( ++ f": {threadCount} thread(s)" + f", {objLen} tasks" ++ if objLen ++ else "" ++ ) + +- countMessage = "" +- try: +- countMessage = " for {} tasks".format(len(objects)) +- except TypeError: +- pass +- +- if message != "": +- message += ": " +- print("{0}Launching {1} threads{2}...".format(message, threadCount, countMessage)) +- sys.stdout.flush() +- currentTime = time.time() +- +- pcall = pcallWithGlobalParamsMultiArg if multiArg else pcallWithGlobalParamsSingleArg +- pargs = zip(objects, itertools.repeat(globalParameters)) +- +- if joblibParallelSupportsGenerator(): +- rv = Parallel(n_jobs=threadCount, timeout=99999, return_as=return_as)( +- delayed(pcall)(function, a, params) for a, params in pargs +- ) ++ print(f"ParallelMap {message}{extra_message}") ++ ++ if threadCount <= 1: ++ result = [f(x) for x in objects] ++ return result if return_as == "list" else iter(result) ++ ++ if maxWorkers > 0: ++ threadCount = min(maxWorkers, threadCount) ++ ++ chunksize = max(minChunkSize, objLen // 2000) ++ worker = partial(worker_function, function=function, multiArg=multiArg) ++ if return_as == "generator_unordered": ++ # yield results as they complete without buffering ++ return _ParallelMap_generator(worker, objects, objLen, message, chunksize, threadCount, globalParameters, maxtasksperchild) + else: +- rv = Parallel(n_jobs=threadCount, timeout=99999)( +- delayed(pcall)(function, a, params) for a, params in pargs +- ) +- +- totalTime = time.time() - currentTime +- print("{0}Done. ({1:.1f} secs elapsed)".format(message, totalTime)) +- sys.stdout.flush() +- return rv ++ ctx = multiprocessing.get_context('forkserver' if os.name != 'nt' else 'spawn') ++ with ctx.Pool(processes=threadCount, maxtasksperchild=maxtasksperchild, ++ initializer=OverwriteGlobalParameters, initargs=(globalParameters,)) as pool: ++ return list(imap_with_progress(pool, worker, objects, objLen, message, chunksize)) +diff --git a/tensilelite/Tensile/CustomKernels.py b/tensilelite/Tensile/CustomKernels.py +index ffceb636f5..127b3386a1 100644 +--- a/tensilelite/Tensile/CustomKernels.py ++++ b/tensilelite/Tensile/CustomKernels.py +@@ -24,7 +24,9 @@ + + from . import CUSTOM_KERNEL_PATH + from Tensile.Common.ValidParameters import checkParametersAreValid, validParameters, newMIValidParameters ++from Tensile.CustomYamlLoader import DEFAULT_YAML_LOADER + ++from functools import lru_cache + import yaml + + import os +@@ -58,10 +60,13 @@ def getCustomKernelConfigAndAssembly(name, directory=CUSTOM_KERNEL_PATH): + + return (config, assembly) + ++# getCustomKernelConfig will get called repeatedly on the same file ++# 20x logic loading speedup for aquavanjaram_Cijk_Ailk_Bljk_F8NH_HHS_BH_Bias_HAS_SAB_SAV_freesize_custom_GSUs ++@lru_cache + def readCustomKernelConfig(name, directory=CUSTOM_KERNEL_PATH): + rawConfig, _ = getCustomKernelConfigAndAssembly(name, directory) + try: +- return yaml.safe_load(rawConfig)["custom.config"] ++ return yaml.load(rawConfig, Loader=DEFAULT_YAML_LOADER)["custom.config"] + except yaml.scanner.ScannerError as e: + raise RuntimeError("Failed to read configuration for custom kernel: {0}\nDetails:\n{1}".format(name, e)) + +diff --git a/tensilelite/Tensile/CustomYamlLoader.py b/tensilelite/Tensile/CustomYamlLoader.py +index e03f456fbe..ed7510f2ce 100644 +--- a/tensilelite/Tensile/CustomYamlLoader.py ++++ b/tensilelite/Tensile/CustomYamlLoader.py +@@ -1,6 +1,7 @@ + # Copyright © Advanced Micro Devices, Inc., or its affiliates. + # SPDX-License-Identifier: MIT + ++import sys + import yaml + from pathlib import Path + +@@ -70,7 +71,7 @@ def parse_scalar(loader: yaml.Loader): + elif is_float(value_lower): + return float(value_lower) + +- return value ++ return sys.intern(value) + + def load_yaml_stream(yaml_path: Path, loader_type: yaml.Loader): + with open(yaml_path, 'r') as f: +diff --git a/tensilelite/Tensile/TensileCreateLibrary/Run.py b/tensilelite/Tensile/TensileCreateLibrary/Run.py +index 22d19851a3..348068b3bf 100644 +--- a/tensilelite/Tensile/TensileCreateLibrary/Run.py ++++ b/tensilelite/Tensile/TensileCreateLibrary/Run.py +@@ -26,8 +26,10 @@ import rocisa + + import functools + import glob ++import gc + import itertools + import os ++import resource + import shutil + from pathlib import Path + from timeit import default_timer as timer +@@ -78,6 +80,25 @@ from Tensile.Utilities.Decorators.Timing import timing + from .ParseArguments import parseArguments + + ++def getMemoryUsage(): ++ """Get peak and current memory usage in MB.""" ++ rusage = resource.getrusage(resource.RUSAGE_SELF) ++ peak_memory_mb = rusage.ru_maxrss / 1024 # KB to MB on Linux ++ ++ # Get current memory from /proc/self/status ++ current_memory_mb = 0 ++ try: ++ with open('/proc/self/status') as f: ++ for line in f: ++ if line.startswith('VmRSS:'): ++ current_memory_mb = int(line.split()[1]) / 1024 # KB to MB ++ break ++ except: ++ current_memory_mb = peak_memory_mb # Fallback ++ ++ return (peak_memory_mb, current_memory_mb) ++ ++ + class KernelCodeGenResult(NamedTuple): + err: int + src: str +@@ -115,6 +136,29 @@ def processKernelSource(kernelWriterAssembly, data, outOptions, splitGSU, kernel + ) + + ++def processAndAssembleKernelTCL(kernelWriterAssembly, rocisa_data, outOptions, splitGSU, kernel, assemblyTmpPath, assembler): ++ """ ++ Pipeline function for TCL mode that: ++ 1. Generates kernel source ++ 2. Writes .s file to disk ++ 3. Assembles to .o file ++ 4. Deletes .s file ++ """ ++ result = processKernelSource(kernelWriterAssembly, rocisa_data, outOptions, splitGSU, kernel) ++ return writeAndAssembleKernel(result, assemblyTmpPath, assembler) ++ ++ ++def writeMasterSolutionLibrary(name_lib_tuple, newLibraryDir, splitGSU, libraryFormat): ++ """ ++ Write a master solution library to disk. ++ Module-level function to support multiprocessing. ++ """ ++ name, lib = name_lib_tuple ++ filename = os.path.join(newLibraryDir, name) ++ lib.applyNaming(splitGSU) ++ LibraryIO.write(filename, state(lib), libraryFormat) ++ ++ + def removeInvalidSolutionsAndKernels(results, kernels, solutions, errorTolerant, printLevel: bool, splitGSU: bool): + removeKernels = [] + removeKernelNames = [] +@@ -189,6 +233,24 @@ def writeAssembly(asmPath: Union[Path, str], result: KernelCodeGenResult): + return path, isa, wfsize, minResult + + ++def writeAndAssembleKernel(result: KernelCodeGenResult, asmPath: Union[Path, str], assembler): ++ """Write assembly file and immediately assemble it to .o file""" ++ if result.err: ++ printExit(f"Failed to build kernel {result.name} because it has error code {result.err}") ++ ++ path = Path(asmPath) / f"{result.name}.s" ++ with open(path, "w", encoding="utf-8") as f: ++ f.write(result.src) ++ ++ # Assemble .s -> .o ++ assembler(isaToGfx(result.isa), result.wavefrontSize, str(path), str(path.with_suffix(".o"))) ++ ++ # Delete assembly file immediately to save disk space ++ path.unlink() ++ ++ return KernelMinResult(result.err, result.cuoccupancy, result.pgr, result.mathclk) ++ ++ + def writeHelpers( + outputPath, kernelHelperObjs, KERNEL_HELPER_FILENAME_CPP, KERNEL_HELPER_FILENAME_H + ): +@@ -272,14 +334,15 @@ def writeSolutionsAndKernels( + numAsmKernels = len(asmKernels) + numKernels = len(asmKernels) + assert numKernels == numAsmKernels, "Only assembly kernels are supported in TensileLite" +- asmIter = zip( +- itertools.repeat(kernelWriterAssembly), +- itertools.repeat(rocisa.rocIsa.getInstance().getData()), +- itertools.repeat(outOptions), +- itertools.repeat(splitGSU), +- asmKernels ++ ++ processKernelFn = functools.partial( ++ processKernelSource, ++ kernelWriterAssembly=kernelWriterAssembly, ++ data=rocisa.rocIsa.getInstance().getData(), ++ outOptions=outOptions, ++ splitGSU=splitGSU + ) +- asmResults = ParallelMap2(processKernelSource, asmIter, "Generating assembly kernels", return_as="list") ++ asmResults = ParallelMap2(processKernelFn, asmKernels, "Generating assembly kernels", return_as="list", multiArg=False) + removeInvalidSolutionsAndKernels( + asmResults, asmKernels, solutions, errorTolerant, getVerbosity(), splitGSU + ) +@@ -287,19 +350,21 @@ def writeSolutionsAndKernels( + asmResults, asmKernels, solutions, splitGSU + ) + +- def assemble(ret): +- p, isa, wavefrontsize, _ = ret +- asmToolchain.assembler(isaToGfx(isa), wavefrontsize, str(p), str(p.with_suffix(".o"))) +- +- unaryWriteAssembly = functools.partial(writeAssembly, assemblyTmpPath) +- compose = lambda *F: functools.reduce(lambda f, g: lambda x: f(g(x)), F) ++ # Use functools.partial to bind assemblyTmpPath and assembler ++ writeAndAssembleFn = functools.partial( ++ writeAndAssembleKernel, ++ asmPath=assemblyTmpPath, ++ assembler=asmToolchain.assembler ++ ) + ret = ParallelMap2( +- compose(assemble, unaryWriteAssembly), ++ writeAndAssembleFn, + asmResults, + "Writing assembly kernels", + return_as="list", + multiArg=False, + ) ++ del asmResults ++ gc.collect() + + writeHelpers(outputPath, kernelHelperObjs, KERNEL_HELPER_FILENAME_CPP, KERNEL_HELPER_FILENAME_H) + srcKernelFile = Path(outputPath) / "Kernels.cpp" +@@ -376,40 +441,35 @@ def writeSolutionsAndKernelsTCL( + + uniqueAsmKernels = [k for k in asmKernels if not k.duplicate] + +- def assemble(ret, removeTemporaries: bool): +- asmPath, isa, wavefrontsize, result = ret +- asmToolchain.assembler(isaToGfx(isa), wavefrontsize, str(asmPath), str(asmPath.with_suffix(".o"))) +- if removeTemporaries: +- asmPath.unlink() +- return result +- +- unaryAssemble = functools.partial(assemble, removeTemporaries=removeTemporaries) +- + outOptions = rocisa.rocIsa.getInstance().getOutputOptions() + outOptions.outputNoComment = not disableAsmComments + +- unaryProcessKernelSource = functools.partial( +- processKernelSource, ++ processKernelFn = functools.partial( ++ processAndAssembleKernelTCL, + kernelWriterAssembly, + rocisa.rocIsa.getInstance().getData(), + outOptions, + splitGSU, ++ assemblyTmpPath=assemblyTmpPath, ++ assembler=asmToolchain.assembler + ) + +- unaryWriteAssembly = functools.partial(writeAssembly, assemblyTmpPath) +- compose = lambda *F: functools.reduce(lambda f, g: lambda x: f(g(x)), F) +- ret = ParallelMap2( +- compose(unaryAssemble, unaryWriteAssembly, unaryProcessKernelSource), ++ results = ParallelMap2( ++ processKernelFn, + uniqueAsmKernels, + "Generating assembly kernels", + multiArg=False, + return_as="list" + ) ++ del processKernelFn ++ gc.collect() ++ + passPostKernelInfoToSolution( +- ret, uniqueAsmKernels, solutions, splitGSU ++ results, uniqueAsmKernels, solutions, splitGSU + ) +- # result.src is very large so let garbage collector know to clean up +- del ret ++ del results ++ gc.collect() ++ + buildAssemblyCodeObjectFiles( + asmToolchain.linker, + asmToolchain.bundler, +@@ -508,6 +568,15 @@ def generateKernelHelperObjects(solutions: List[Solution], cxxCompiler: str, isa + return sorted(khos, key=sortByEnum, reverse=True) # Ensure that we write Enum kernel helpers are first in list + + ++def libraryIter(lib: MasterSolutionLibrary): ++ if len(lib.solutions): ++ for i, s in enumerate(lib.solutions.items()): ++ yield (i, *s) ++ else: ++ for _, lazyLib in lib.lazyLibraries.items(): ++ yield from libraryIter(lazyLib) ++ ++ + @timing + def generateLogicDataAndSolutions(logicFiles, args, assembler: Assembler, isaInfoMap): + +@@ -523,26 +592,23 @@ def generateLogicDataAndSolutions(logicFiles, args, assembler: Assembler, isaInf + printSolutionRejectionReason = True + printIndexAssignmentInfo = False + +- fIter = zip( +- logicFiles, +- itertools.repeat(assembler), +- itertools.repeat(splitGSU), +- itertools.repeat(printSolutionRejectionReason), +- itertools.repeat(printIndexAssignmentInfo), +- itertools.repeat(isaInfoMap), +- itertools.repeat(args["LazyLibraryLoading"]), ++ parseLogicFn = functools.partial( ++ LibraryIO.parseLibraryLogicFile, ++ assembler=assembler, ++ splitGSU=splitGSU, ++ printSolutionRejectionReason=printSolutionRejectionReason, ++ printIndexAssignmentInfo=printIndexAssignmentInfo, ++ isaInfoMap=isaInfoMap, ++ lazyLibraryLoading=args["LazyLibraryLoading"] + ) + +- def libraryIter(lib: MasterSolutionLibrary): +- if len(lib.solutions): +- for i, s in enumerate(lib.solutions.items()): +- yield (i, *s) +- else: +- for _, lazyLib in lib.lazyLibraries.items(): +- yield from libraryIter(lazyLib) +- + for library in ParallelMap2( +- LibraryIO.parseLibraryLogicFile, fIter, "Loading Logics...", return_as="generator_unordered" ++ parseLogicFn, logicFiles, "Loading Logics...", ++ return_as="generator_unordered", ++ minChunkSize=24, ++ maxWorkers=32, ++ maxtasksperchild=1, ++ multiArg=False, + ): + _, architectureName, _, _, _, newLibrary = library + +@@ -554,6 +620,9 @@ def generateLogicDataAndSolutions(logicFiles, args, assembler: Assembler, isaInf + else: + masterLibraries[architectureName] = newLibrary + masterLibraries[architectureName].version = args["CodeObjectVersion"] ++ del library, newLibrary ++ ++ gc.collect() + + # Sort masterLibraries to make global soln index values deterministic + solnReIndex = 0 +@@ -751,6 +820,9 @@ def run(): + ) + stop_wsk = timer() + print(f"Time to generate kernels (s): {(stop_wsk-start_wsk):3.2f}") ++ numKernelHelperObjs = len(kernelHelperObjs) ++ del kernelWriterAssembly, kernelHelperObjs ++ gc.collect() + + archs = [ # is this really different than the other archs above? + isaToGfx(arch) +@@ -768,13 +840,10 @@ def run(): + if kName not in solDict: + solDict["%s"%kName] = kernel + +- def writeMsl(name, lib): +- filename = os.path.join(newLibraryDir, name) +- lib.applyNaming(splitGSU) +- LibraryIO.write(filename, state(lib), arguments["LibraryFormat"]) +- + filename = os.path.join(newLibraryDir, "TensileLiteLibrary_lazy_Mapping") + LibraryIO.write(filename, libraryMapping, "msgpack") ++ del libraryMapping ++ gc.collect() + + start_msl = timer() + for archName, newMasterLibrary in masterLibraries.items(): +@@ -791,12 +860,22 @@ def run(): + kName = getKeyNoInternalArgs(s.originalSolution, splitGSU) + s.sizeMapping.CUOccupancy = solDict["%s"%kName]["CUOccupancy"] + +- ParallelMap2(writeMsl, ++ writeFn = functools.partial( ++ writeMasterSolutionLibrary, ++ newLibraryDir=newLibraryDir, ++ splitGSU=splitGSU, ++ libraryFormat=arguments["LibraryFormat"] ++ ) ++ ++ ParallelMap2(writeFn, + newMasterLibrary.lazyLibraries.items(), + "Writing master solution libraries", ++ multiArg=False, + return_as="list") + stop_msl = timer() + print(f"Time to write master solution libraries (s): {(stop_msl-start_msl):3.2f}") ++ del masterLibraries, solutions, kernels, solDict ++ gc.collect() + + if not arguments["KeepBuildTmp"]: + buildTmp = Path(arguments["OutputPath"]).parent / "library" / "build_tmp" +@@ -813,8 +892,11 @@ def run(): + print("") + + stop = timer() ++ peak_memory_mb, current_memory_mb = getMemoryUsage() + + print(f"Total time (s): {(stop-start):3.2f}") + print(f"Total kernels processed: {numKernels}") + print(f"Kernels processed per second: {(numKernels/(stop-start)):3.2f}") +- print(f"KernelHelperObjs: {len(kernelHelperObjs)}") ++ print(f"KernelHelperObjs: {numKernelHelperObjs}") ++ print(f"Peak memory usage (MB): {peak_memory_mb:,.1f}") ++ print(f"Current memory usage (MB): {current_memory_mb:,.1f}") +diff --git a/tensilelite/Tensile/TensileMergeLibrary.py b/tensilelite/Tensile/TensileMergeLibrary.py +index e33c617b6f..ba163e9918 100644 +--- a/tensilelite/Tensile/TensileMergeLibrary.py ++++ b/tensilelite/Tensile/TensileMergeLibrary.py +@@ -303,8 +303,7 @@ def avoidRegressions(originalDir, incrementalDir, outputPath, forceMerge, noEff= + logicsFiles[origFile] = origFile + logicsFiles[incFile] = incFile + +- iters = zip(logicsFiles.keys()) +- logicsList = ParallelMap2(loadData, iters, "Loading Logics...", return_as="list") ++ logicsList = ParallelMap2(loadData, logicsFiles.keys(), "Loading Logics...", return_as="list", multiArg=False) + logicsDict = {} + for i, _ in enumerate(logicsList): + logicsDict[logicsList[i][0]] = logicsList[i][1] +diff --git a/tensilelite/Tensile/TensileUpdateLibrary.py b/tensilelite/Tensile/TensileUpdateLibrary.py +index 5ff265d0ed..c1803a6349 100644 +--- a/tensilelite/Tensile/TensileUpdateLibrary.py ++++ b/tensilelite/Tensile/TensileUpdateLibrary.py +@@ -26,7 +26,7 @@ from . import LibraryIO + from .Tensile import addCommonArguments, argUpdatedGlobalParameters + + from .Common import assignGlobalParameters, print1, restoreDefaultGlobalParameters, HR, \ +- globalParameters, architectureMap, ensurePath, ParallelMap, __version__ ++ globalParameters, architectureMap, ensurePath, ParallelMap2, __version__ + + import argparse + import copy +@@ -149,7 +149,7 @@ def TensileUpdateLibrary(userArgs): + for logicFile in logicFiles: + print("# %s" % logicFile) + fIter = zip(logicFiles, itertools.repeat(args.logic_path), itertools.repeat(outputPath)) +- libraries = ParallelMap(UpdateLogic, fIter, "Updating logic files", method=lambda x: x.starmap) ++ libraries = ParallelMap2(UpdateLogic, fIter, "Updating logic files", multiArg=True, return_as="list") + + + def main(): +diff --git a/tensilelite/Tensile/Toolchain/Assembly.py b/tensilelite/Tensile/Toolchain/Assembly.py +index a8b91e8d62..265e1d532c 100644 +--- a/tensilelite/Tensile/Toolchain/Assembly.py ++++ b/tensilelite/Tensile/Toolchain/Assembly.py +@@ -30,7 +30,7 @@ import subprocess + from pathlib import Path + from typing import List, Union, NamedTuple + +-from Tensile.Common import print2 ++from Tensile.Common import print1, print2 + from Tensile.Common.Architectures import isaToGfx + from ..SolutionStructs import Solution + +@@ -92,8 +92,26 @@ def buildAssemblyCodeObjectFiles( + if coName: + coFileMap[asmDir / (coName + extCoRaw)].add(str(asmDir / (kernel["BaseName"] + extObj))) + ++ # Build reference count map for .o files to handle shared object files ++ # (.o files from kernels marked .duplicate in TensileCreateLibrary) ++ objFileRefCount = collections.Counter() ++ for coFileRaw, objFiles in coFileMap.items(): ++ for objFile in objFiles: ++ objFileRefCount[objFile] += 1 ++ ++ sharedObjFiles = {objFile: count for objFile, count in objFileRefCount.items() if count > 1} ++ if sharedObjFiles: ++ print1(f"Found {len(sharedObjFiles)} .o files shared across multiple code objects:") ++ + for coFileRaw, objFiles in coFileMap.items(): + linker(objFiles, str(coFileRaw)) ++ ++ # Delete .o files after linking once usage count reaches 0 ++ for objFile in objFiles: ++ objFileRefCount[objFile] -= 1 ++ if objFileRefCount[objFile] == 0: ++ Path(objFile).unlink() ++ + coFile = destDir / coFileRaw.name.replace(extCoRaw, extCo) + if compress: + bundler.compress(str(coFileRaw), str(coFile), gfx) +diff --git a/tensilelite/Tensile/Toolchain/Component.py b/tensilelite/Tensile/Toolchain/Component.py +index 67fa35e2d8..dde83af4c3 100644 +--- a/tensilelite/Tensile/Toolchain/Component.py ++++ b/tensilelite/Tensile/Toolchain/Component.py +@@ -355,6 +355,7 @@ class Linker(Component): + when invoking the linker, LLVM allows the provision of arguments via a "response file" + Reference: https://llvm.org/docs/CommandLine.html#response-files + """ ++ # FIXME: this prevents threading as clang_args.txt is overwritten + with open(Path.cwd() / "clang_args.txt", "wt") as file: + file.write(" ".join(srcPaths).replace('\\', '\\\\') if os_name == "nt" else " ".join(srcPaths)) + return [*(self.default_args), "-o", destPath, "@clang_args.txt"] +diff --git a/tensilelite/requirements.txt b/tensilelite/requirements.txt +index 60c4c11445..5c8fd66a88 100644 +--- a/tensilelite/requirements.txt ++++ b/tensilelite/requirements.txt +@@ -2,8 +2,6 @@ dataclasses; python_version == '3.6' + packaging + pyyaml + msgpack +-joblib>=1.4.0; python_version >= '3.8' +-joblib>=1.1.1; python_version < '3.8' + simplejson + ujson + orjson diff --git a/.devops/nix/rocm-modules-10/hipblaslt/default.nix b/.devops/nix/rocm-modules-10/hipblaslt/default.nix new file mode 100644 index 0000000000..19768cc1d7 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipblaslt/default.nix @@ -0,0 +1,290 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + rocm-cmake, + rocm-smi, + pkg-config, + clr, + gfortran, + git, + gtest, + boost, + llvm, + msgpack-cxx, + amd-blis, + libxml2, + python3, + python3Packages, + openmp, + hipblas-common, + amdsmi, + lapack-reference, + ncurses, + ninja, + libffi, + jemalloc, + zlib, + zstd, + rocmUpdateScript, + buildTests ? false, + buildSamples ? false, + # hipblaslt supports only devices with MFMA or WMMA + gpuTargets ? (clr.localGpuTargets or clr.gpuTargets), +}: + +let + # hipblaslt is extremely particular about what it will build with + # so intersect with a known supported list and use only those + supportedTargets = ( + lib.lists.intersectLists gpuTargets [ + "gfx908" + "gfx90a" + "gfx942" + "gfx950" + "gfx1100" + "gfx1101" + "gfx1150" + "gfx1151" + "gfx1200" + "gfx1201" + ] + ); + supportsTargetArches = supportedTargets != [ ]; + py = python3.withPackages (ps: [ + ps.pyyaml + ps.setuptools + ps.packaging + ps.nanobind + ps.msgpack + # required by ROCm 10's tensilelite/requirements.txt + ps.joblib + ps.simplejson + ps.ujson + ]); + # workaround: build for one working target if no targets are supported + # a few CXX files are still build for the device + gpuTargets' = + if supportsTargetArches then (lib.concatStringsSep ";" supportedTargets) else "gfx1200"; + compiler = "amdclang++"; + # no-switch due to spammy warnings on some cases with fixme messages + # FIXME(LunNova@): cmake files need patched to include this properly or + # maybe we improve the toolchain to use config files + assemble a sysroot + # so system wide include assumptions work + cFlags = "-Wno-switch -fopenmp -I${lib.getDev zstd}/include -I${amd-blis}/include/blis/ -I${lib.getDev msgpack-cxx}/include"; +in +stdenv.mkDerivation (finalAttrs: { + pname = "hipblaslt${clr.gpuArchSuffix}"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + hash = "sha256-oQO6/vrDjo6CLTPlqY6uF/yl4jYlf1jG1krfr5WwliI="; + sparseCheckout = [ + "projects/hipblaslt" + "shared" + # ROCm 10's shared/stinkytofu includes modules from the repo-root cmake dir + "cmake" + ]; + # Compress the 5ish GiB of yaml files so this .src is under output size limit + postFetch = '' + find $out -name '*.yaml' -path '*/Tensile/Logic/*' -exec ${lib.getExe zstd} --rm {} \; + ''; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipblaslt"; + env.CXX = compiler; + env.CFLAGS = cFlags; + env.CXXFLAGS = cFlags; + # messagepack-compression-support.patch pulls zstd into the msgpack loader, so + # every consumer (including the bench clients) has to link it. + env.LDFLAGS = "-L${lib.getLib zstd}/lib -lzstd"; + env.ROCM_PATH = "${clr}"; + env.TENSILE_ROCM_ASSEMBLER_PATH = lib.getExe' clr "amdclang++"; + env.TENSILE_GEN_ASSEMBLY_TOOLCHAIN = lib.getExe' clr "amdclang++"; + env.LD_PRELOAD = "${jemalloc}/lib/libjemalloc.so"; + env.MALLOC_CONF = "background_thread:true,metadata_thp:auto,dirty_decay_ms:10000,muzzy_decay_ms:10000"; + requiredSystemFeatures = [ "big-parallel" ]; + + __structuredAttrs = true; + strictDeps = true; + + outputs = [ + "out" + # benchmarks are non-optional + "benchmark" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildSamples [ + "sample" + ]; + + patches = [ + # parallel-buildSourceCodeObjectFile.diff is applied through postPatch below: + # ROCm 10 moved the compiler call into a timing_context block, so the diff's + # context no longer matches. + # Support loading zstd compressed .dat files, required to keep output under + # hydra size limit + ./messagepack-compression-support.patch + # ./TensileCreateLibrary-refactor.patch and ./Tensile-interning.patch are + # dropped: rocm-libraries#2073 was never merged, and ROCm 10 restructured + # TensileCreateLibrary enough that the diffs no longer apply. ROCm 10 still + # uses joblib, which is supplied through the python env below. + ]; + + preConfigure = '' + # ROCm 10's tensilelite caches generated helpers under $HOME/.tensile, which + # is /homeless-shelter in the nix sandbox. + export HOME=$TMPDIR + find . -name '*.yaml.zst' -path '*/Tensile/Logic/*' -exec zstd -d --rm {} \; + ''; + + postPatch = '' + # Upstream issue asking for parallel-jobs to be specified properly: + # https://github.com/ROCm/rocm-libraries/issues/1242 + substituteInPlace tensilelite/Tensile/Toolchain/Source.py \ + --replace-fail \ + ' objPath = str(tmpObjDir / objFilename)' \ + ' objPath = str(tmpObjDir / objFilename) + compiler.default_args += ["-parallel-jobs=8"]' + + # messagepack-compression-support.patch needs ; ROCm 10 reordered the + # includes in this file so the patch's first hunk no longer applies. + substituteInPlace tensilelite/src/msgpack/MessagePack.cpp \ + --replace-fail \ + '#include ' \ + '#include + +#include ' + + # ROCm 10 dropped cmake/dependencies.cmake and no longer does + # find_package(Git REQUIRED), so nothing to strip here any more. + substituteInPlace CMakeLists.txt \ + --replace-fail " LANGUAGES CXX" " LANGUAGES CXX C ASM" + ''; + + doCheck = false; + doInstallCheck = true; + + nativeBuildInputs = [ + cmake + # ROCm 10's shared/origami does find_package(Git REQUIRED) + git + rocm-cmake + py + clr + gfortran + pkg-config + ninja + rocm-smi + zstd + ]; + + buildInputs = [ + llvm.llvm + clr + rocm-cmake + hipblas-common + # ROCm 10's hipblaslt does find_package(amd_smi REQUIRED) + amdsmi + amd-blis + rocm-smi + openmp + libffi + ncurses + lapack-reference + + # Tensile deps - not optional, building without tensile isn't actually supported + msgpack-cxx + libxml2 + python3Packages.msgpack + zlib + zstd + ] + ++ lib.optionals buildTests [ + gtest + ]; + + cmakeFlags = [ + (lib.cmakeFeature "Boost_INCLUDE_DIR" "${lib.getDev boost}/include") # msgpack FindBoost fails to find boost + (lib.cmakeFeature "GPU_TARGETS" gpuTargets') + (lib.cmakeBool "BUILD_TESTING" buildTests) + (lib.cmakeBool "HIPBLASLT_ENABLE_BLIS" true) + (lib.cmakeBool "HIPBLASLT_BUILD_TESTING" buildTests) + (lib.cmakeBool "HIPBLASLT_ENABLE_SAMPLES" buildSamples) + (lib.cmakeBool "HIPBLASLT_ENABLE_DEVICE" supportsTargetArches) + # FIXME: Enable for ROCm 7.x + (lib.cmakeBool "HIPBLASLT_ENABLE_ROCROLLER" false) + "-DCMAKE_C_COMPILER=amdclang" + "-DCMAKE_HIP_COMPILER=${compiler}" + "-DCMAKE_CXX_COMPILER=${compiler}" + "-DROCM_FOUND=ON" # hipblaslt tries to download rocm-cmake if this isn't set + "-DBLIS_ROOT=${amd-blis}" + "-DBLIS_LIB=${amd-blis}/lib/libblis-mt.so" + "-DBLIS_INCLUDE_DIR=${amd-blis}/include/blis/" + "-DBLA_PREFER_PKGCONFIG=ON" + "-DFETCHCONTENT_SOURCE_DIR_NANOBIND=${python3Packages.nanobind.src}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DHIPBLASLT_ENABLE_MARKER=Off" + ]; + + postInstall = + # Compress msgpack .dat files to stay under hydra output size limit + # Relies on messagepack-compression-support.patch + '' + for file in $out/lib/hipblaslt/library/*.dat; do + zstd -19 --long -f "$file" -o "$file.tmp" && mv "$file.tmp" "$file" + done + '' + # Move binaries to appropriate outputs and delete leftover /bin + + '' + mkdir -p $benchmark/bin + # ROCm 10 also installs hipblaslt-cotenant{,-kernel} and hipblaslt-perf. + mv $out/bin/hipblaslt-{api-overhead,bench*,cotenant*,perf} $out/bin/*.yaml $out/bin/*.py $benchmark/bin + ${lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/hipblas-test $test/bin + ''} + ${lib.optionalString buildSamples '' + mkdir -p $sample/bin + mv $out/bin/example-* $sample/bin + ''} + rmdir $out/bin + ''; + + installCheckPhase = + # Verify compression worked and .dat files aren't huge + '' + runHook preInstallCheck + find "$out" -type f -name "*.dat" -size "+2M" -exec sh -c ' + echo "ERROR: oversized .dat file, check for issues with install compression: {}" >&2 + exit 1 + ' {} \; + echo "Verified .dat files in $out are not huge" + runHook postInstallCheck + ''; + + # If this is false there are no kernels in the output lib + # supporting the target device + # so if it's an optional dep it's best to not depend on it + # Some packages like torch need hipblaslt to compile + # and are fine ignoring it at runtime if it's not supported + # so we have to support building an empty hipblaslt + passthru.supportsTargetArches = supportsTargetArches; + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + meta = { + description = "Library that provides general matrix-matrix operations with a flexible API"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipblaslt"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipblaslt/messagepack-compression-support.patch b/.devops/nix/rocm-modules-10/hipblaslt/messagepack-compression-support.patch new file mode 100644 index 0000000000..33020c3a57 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipblaslt/messagepack-compression-support.patch @@ -0,0 +1,47 @@ +diff --git a/Tensile/Source/lib/source/msgpack/MessagePack.cpp b/Tensile/Source/lib/source/msgpack/MessagePack.cpp +index de97929c..dbc397e0 100644 +--- a/tensilelite/src/msgpack/MessagePack.cpp ++++ b/tensilelite/src/msgpack/MessagePack.cpp +@@ -86,6 +88,34 @@ namespace Tensile + return nullptr; + } + ++ // Check if the file is zstd compressed ++ char magic[4]; ++ in.read(magic, 4); ++ bool isCompressed = (in.gcount() == 4 && magic[0] == '\x28' && magic[1] == '\xB5' && magic[2] == '\x2F' && magic[3] == '\xFD'); ++ // Reset file pointer to the beginning ++ in.seekg(0, std::ios::beg); ++ ++ if (isCompressed) { ++ // Decompress zstd file ++ std::vector compressedData((std::istreambuf_iterator(in)), std::istreambuf_iterator()); ++ ++ size_t decompressedSize = ZSTD_getFrameContentSize(compressedData.data(), compressedData.size()); ++ if (decompressedSize == ZSTD_CONTENTSIZE_ERROR || decompressedSize == ZSTD_CONTENTSIZE_UNKNOWN) { ++ if(Debug::Instance().printDataInit()) ++ std::cout << "Error: Unable to determine decompressed size for " << filename << std::endl; ++ return false; ++ } ++ ++ std::vector decompressedData(decompressedSize); ++ size_t dSize = ZSTD_decompress(decompressedData.data(), decompressedSize, compressedData.data(), compressedData.size()); ++ if (ZSTD_isError(dSize)) { ++ if(Debug::Instance().printDataInit()) ++ std::cout << "Error: ZSTD decompression failed for " << filename << std::endl; ++ return false; ++ } ++ ++ msgpack::unpack(result, decompressedData.data(), dSize); ++ } else { + msgpack::unpacker unp; + bool finished_parsing; + constexpr size_t buffer_size = 1 << 19; +@@ -109,6 +139,7 @@ namespace Tensile + + return nullptr; + } ++ } + } + catch(std::runtime_error const& exc) + { diff --git a/.devops/nix/rocm-modules-10/hipblaslt/parallel-buildSourceCodeObjectFile.diff b/.devops/nix/rocm-modules-10/hipblaslt/parallel-buildSourceCodeObjectFile.diff new file mode 100644 index 0000000000..019e7a6123 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipblaslt/parallel-buildSourceCodeObjectFile.diff @@ -0,0 +1,12 @@ +diff --git a/tensilelite/Tensile/Toolchain/Source.py b/tensilelite/Tensile/Toolchain/Source.py +index c9862e6c..dfa5ba40 100644 +--- a/tensilelite/Tensile/Toolchain/Source.py ++++ b/tensilelite/Tensile/Toolchain/Source.py +@@ -102,6 +102,7 @@ def buildSourceCodeObjectFiles( + coPaths= [] + + objPath = str(tmpObjDir / objFilename) ++ compiler.default_args += ["-parallel-jobs=8"] + compiler(str(includeDir), cmdlineArchs, str(kernelPath), objPath) + + for target in bundler.targets(objPath): diff --git a/.devops/nix/rocm-modules-10/hipcc/default.nix b/.devops/nix/rocm-modules-10/hipcc/default.nix new file mode 100644 index 0000000000..f3cb9462e1 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipcc/default.nix @@ -0,0 +1,47 @@ +{ + lib, + stdenv, + llvm, + cmake, + lsb-release, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "hipcc"; + # In-tree with ROCm LLVM + inherit (llvm.llvm) version; + src = llvm.llvm.monorepoSrc; + sourceRoot = "${finalAttrs.src.name}/amd/hipcc"; + strictDeps = true; + + nativeBuildInputs = [ + llvm.rocm-toolchain + cmake + ]; + + buildInputs = [ + llvm.clang-unwrapped + ]; + + postPatch = '' + substituteInPlace src/hipBin_amd.h \ + --replace-fail "/usr/bin/lsb_release" "${lsb-release}/bin/lsb_release" + ''; + + cmakeFlags = [ + "-DCMAKE_BUILD_TYPE=Release" + ]; + postInstall = '' + rm -r $out/hip/bin + ln -s $out/bin $out/hip/bin + ''; + + meta = { + description = "Compiler driver utility that calls clang or nvcc"; + homepage = "https://github.com/ROCm/HIPCC"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipcub/default.nix b/.devops/nix/rocm-modules-10/hipcub/default.nix new file mode 100644 index 0000000000..6d3b5717ff --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipcub/default.nix @@ -0,0 +1,100 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocprim, + clr, + gtest, + gbenchmark, + buildTests ? false, + buildBenchmarks ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +# CUB can also be used as a backend instead of rocPRIM. +stdenv.mkDerivation (finalAttrs: { + pname = "hipcub"; + version = "10.0.0"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/hipcub" + "shared" + ]; + hash = "sha256-d7rsd+kCaX4cxAQWuGHIx8Dxx+DFm4vLXFU3VZq6CxU="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipcub"; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + ]; + + buildInputs = [ + rocprim + ] + ++ lib.optionals buildTests [ + gtest + ] + ++ lib.optionals buildBenchmarks [ + gbenchmark + ]; + + cmakeFlags = [ + "-DHIP_ROOT_DIR=${clr}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TEST=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_BENCHMARK=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/test_* $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/benchmark_* $benchmark/bin + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Thin wrapper library on top of rocPRIM or CUB"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipcub"; + license = lib.licenses.bsd3; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipfft/default.nix b/.devops/nix/rocm-modules-10/hipfft/default.nix new file mode 100644 index 0000000000..b8634c392f --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipfft/default.nix @@ -0,0 +1,121 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + rocfft, + gtest, + boost, + fftw, + fftwFloat, + openmp, + buildTests ? false, + buildBenchmarks ? false, + buildSamples ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +# Can also use cuFFT +stdenv.mkDerivation (finalAttrs: { + pname = "hipfft"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ] + ++ lib.optionals buildSamples [ + "sample" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/hipfft" + "shared" + ]; + fetchSubmodules = true; + hash = "sha256-EtxZuxBPx6trTN9iC7uri2+UR0Eolp919Ry4U1PEqNA="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipfft"; + + nativeBuildInputs = [ + clr + cmake + rocm-cmake + ]; + + buildInputs = [ + rocfft + ] + ++ lib.optionals (buildTests || buildBenchmarks || buildSamples) [ + gtest + boost + fftw + fftwFloat + openmp + ]; + + cmakeFlags = [ + "-DCMAKE_C_COMPILER=hipcc" + "-DCMAKE_CXX_COMPILER=hipcc" + "-DCMAKE_MODULE_PATH=${clr}/lib/cmake/hip" + "-DHIP_ROOT_DIR=${clr}" + "-DHIP_PATH=${clr}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_CLIENTS_TESTS=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_CLIENTS_RIDER=ON" + ] + ++ lib.optionals buildSamples [ + "-DBUILD_CLIENTS_SAMPLES=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/hipfft-test $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/hipfft-rider $benchmark/bin + '' + + lib.optionalString buildSamples '' + mkdir -p $sample/bin + mv clients/staging/hipfft_* $sample/bin + patchelf $sample/bin/hipfft_* --shrink-rpath --allowed-rpath-prefixes "$NIX_STORE" + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "FFT marshalling library"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipfft"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipfort/default.nix b/.devops/nix/rocm-modules-10/hipfort/default.nix new file mode 100644 index 0000000000..e167ce3a09 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipfort/default.nix @@ -0,0 +1,62 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + gfortran, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "hipfort"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "hipfort"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-XaB4jauCN41tgD1YHHA2td/yckwfMBemBe/iL0SCxQo="; + }; + + nativeBuildInputs = [ + cmake + rocm-cmake + gfortran + ]; + + cmakeFlags = [ + "-DHIPFORT_COMPILER=${gfortran}/bin/gfortran" + "-DHIPFORT_AR=${gfortran.cc}/bin/gcc-ar" + "-DHIPFORT_RANLIB=${gfortran.cc}/bin/gcc-ranlib" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + postPatch = '' + patchShebangs bin + + substituteInPlace bin/hipfc bin/mymcpu \ + --replace "/bin/cat" "cat" + + substituteInPlace bin/CMakeLists.txt \ + --replace "/bin/mkdir" "mkdir" \ + --replace "/bin/cp" "cp" \ + --replace "/bin/sed" "sed" \ + --replace "/bin/chmod" "chmod" \ + --replace "/bin/ln" "ln" + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Fortran interfaces for ROCm libraries"; + homepage = "https://github.com/ROCm/hipfort"; + license = lib.licenses.mit; # mitx11 + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipify/default.nix b/.devops/nix/rocm-modules-10/hipify/default.nix new file mode 100644 index 0000000000..f833cada2d --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipify/default.nix @@ -0,0 +1,66 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + llvm, + zlib, + zstd, + perl, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "hipify"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "HIPIFY"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-LC0lnYetV7RPVw92zew6za6bDH4zmnERXUM4MVaRVtc="; + }; + + strictDeps = true; + + nativeBuildInputs = [ + cmake + perl + llvm.rocm-toolchain + ]; + + buildInputs = [ + llvm.llvm + llvm.clang-unwrapped + perl + zlib + zstd + ]; + + env.CXXFLAGS = "-I${lib.getInclude llvm.llvm}/include -I${lib.getInclude llvm.clang-unwrapped}/include"; + + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace-fail "\''${LLVM_TOOLS_BINARY_DIR}/clang" "${llvm.rocm-toolchain}/bin/clang" + chmod +x bin/* + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + postInstall = '' + rm $out/bin/hipify-perl + chmod +x $out/bin/* + chmod +x $out/libexec/* + patchShebangs $out/bin/ + patchShebangs $out/libexec/ + ln -s $out/{libexec/hipify,bin}/hipify-perl + ''; + + meta = { + description = "Convert CUDA to Portable C++ Code"; + homepage = "https://github.com/ROCm/HIPIFY"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hiprand/default.nix b/.devops/nix/rocm-modules-10/hiprand/default.nix new file mode 100644 index 0000000000..a57aa6c888 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hiprand/default.nix @@ -0,0 +1,78 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + rocrand, + gtest, + buildTests ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "hiprand"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/hiprand" + "shared" + ]; + hash = "sha256-bjcwjN1dNukhoDAbiSpATlK6dtAwM8bOJTe3IjhdwwY="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hiprand"; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + ]; + + buildInputs = [ rocrand ] ++ (lib.optionals buildTests [ gtest ]); + + cmakeFlags = [ + "-DHIP_ROOT_DIR=${clr}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TEST=ON" + ]; + + postInstall = lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/test_* $test/bin + rm -r $out/bin/hipRAND + # Fail if bin/ isn't actually empty + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "HIP wrapper for rocRAND and cuRAND"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hiprand"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hiprt/default.nix b/.devops/nix/rocm-modules-10/hiprt/default.nix new file mode 100644 index 0000000000..bd2a9f6f11 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hiprt/default.nix @@ -0,0 +1,61 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + clr, + python3, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "hiprt"; + version = "3.0.3.a1525e7"; + + src = fetchFromGitHub { + owner = "GPUOpen-LibrariesAndSDKs"; + repo = "HIPRT"; + tag = finalAttrs.version; + hash = "sha256-7r7KO+WuXOeQQhYLYpJRrD4ZqVsBOqaD2NGD15CWnoo="; + }; + + postPatch = '' + substituteInPlace contrib/Orochi/contrib/hipew/src/hipew.cpp --replace-fail '"/opt/rocm/hip/lib/' '"${clr}/lib' + substituteInPlace hiprt/hiprt_libpath.h --replace-fail '"/opt/rocm/hip/lib/' '"${clr}/lib/' + ''; + + nativeBuildInputs = [ + cmake + python3 + ]; + + buildInputs = [ + clr + ]; + + cmakeFlags = [ + (lib.cmakeBool "BAKE_KERNEL" false) + (lib.cmakeBool "BAKE_COMPILED_KERNEL" false) + (lib.cmakeBool "BITCODE" true) + (lib.cmakeBool "PRECOMPILE" true) + # needs accelerator + (lib.cmakeBool "NO_UNITTEST" true) + (lib.cmakeBool "FORCE_DISABLE_CUDA" true) + ]; + + postInstall = '' + mv $out/bin $out/lib + ln -sr $out/lib/libhiprt*64.so $out/lib/libhiprt64.so + install -v -Dm644 ../scripts/bitcodes/hiprt*_amd_lib_linux.bc $out/lib/ + ''; + + meta = { + homepage = "https://gpuopen.com/hiprt"; + description = "Ray tracing library for HIP"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ + mksafavi + ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipsolver/default.nix b/.devops/nix/rocm-modules-10/hipsolver/default.nix new file mode 100644 index 0000000000..10c6a7164a --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipsolver/default.nix @@ -0,0 +1,117 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + gfortran, + rocblas, + rocsolver, + rocsparse, + suitesparse, + gtest, + lapack-reference, + buildTests ? false, + buildBenchmarks ? false, + buildSamples ? false, +}: + +# Can also use cuSOLVER +stdenv.mkDerivation (finalAttrs: { + pname = "hipsolver"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ] + ++ lib.optionals buildSamples [ + "sample" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/hipsolver" + "shared" + ]; + hash = "sha256-ts5wuXHoBFZ1WMAk8Ir5cucP75G0SMOWmn3FEH04ZEQ="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipsolver"; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + gfortran + ]; + + buildInputs = [ + rocblas + rocsolver + rocsparse + suitesparse + ] + ++ lib.optionals buildTests [ + gtest + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + lapack-reference + ]; + + cmakeFlags = [ + "-DCMAKE_CXX_COMPILER=hipcc" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DBUILD_WITH_SPARSE=OFF" # FIXME: broken - can't find suitesparse/cholmod, looks fixed in master + ] + ++ lib.optionals buildTests [ + "-DBUILD_CLIENTS_TESTS=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_CLIENTS_BENCHMARKS=ON" + ] + ++ lib.optionals buildSamples [ + "-DBUILD_CLIENTS_SAMPLES=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/hipsolver-test $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/hipsolver-bench $benchmark/bin + '' + + lib.optionalString buildSamples '' + mkdir -p $sample/bin + mv clients/staging/example-* $sample/bin + patchelf $sample/bin/example-* --shrink-rpath --allowed-rpath-prefixes "$NIX_STORE" + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm SOLVER marshalling library"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipsolver"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipsparse/default.nix b/.devops/nix/rocm-modules-10/hipsparse/default.nix new file mode 100644 index 0000000000..749abeae27 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipsparse/default.nix @@ -0,0 +1,148 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocsparse, + clr, + gfortran, + gtest, + openmp, + buildTests ? false, + buildBenchmarks ? false, + buildSamples ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +# This can also use cuSPARSE as a backend instead of rocSPARSE +stdenv.mkDerivation (finalAttrs: { + pname = "hipsparse"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildSamples [ + "sample" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/hipsparse" + "shared" + ]; + hash = "sha256-E1chG+giFtf02fjutoV4yM2XvrQKjgXRSvxs0NBBkvI="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipsparse"; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + gfortran + ]; + + buildInputs = [ + rocsparse + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + gtest + ] + ++ lib.optionals (buildTests || buildSamples) [ + openmp + ]; + + cmakeFlags = [ + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + (lib.cmakeBool "BUILD_CLIENTS_TESTS" buildTests) + (lib.cmakeBool "BUILD_CLIENTS_BENCHMARKS" buildBenchmarks) + (lib.cmakeBool "BUILD_CLIENTS_SAMPLES" buildSamples) + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ]; + + # We have to manually generate the matrices + # CMAKE_MATRICES_DIR seems to be reset in clients/tests/CMakeLists.txt + postPatch = lib.optionalString buildTests '' + mkdir -p matrices + + ln -s ${rocsparse.passthru.matrices.matrix-01}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-02}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-03}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-04}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-05}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-06}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-07}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-08}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-09}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-10}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-11}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-12}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-13}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-14}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-15}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-16}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-17}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-18}/*.mtx matrices + ln -s ${rocsparse.passthru.matrices.matrix-19}/*.mtx matrices + + # Not used by the original cmake, causes an error + rm matrices/*_b.mtx + + echo "deps/convert.cpp -> deps/mtx2csr" + hipcc deps/convert.cpp -O3 -o deps/mtx2csr + + for mat in $(ls -1 matrices | cut -d "." -f 1); do + echo "mtx2csr: $mat.mtx -> $mat.bin" + deps/mtx2csr matrices/$mat.mtx matrices/$mat.bin + unlink matrices/$mat.mtx + done + + substituteInPlace clients/tests/CMakeLists.txt \ + --replace "\''${PROJECT_BINARY_DIR}/matrices" "/build/source/matrices" + ''; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/hipsparse-test $test/bin + mv /build/source/matrices $test + rmdir $out/bin + '' + + lib.optionalString buildSamples '' + mkdir -p $sample/bin + mv clients/staging/example_* $sample/bin + patchelf --set-rpath $out/lib:${ + lib.makeLibraryPath ( + finalAttrs.buildInputs + ++ [ + clr + gfortran.cc + ] + ) + } $sample/bin/example_* + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm SPARSE marshalling library"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipsparse"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/hipsparselt/default.nix b/.devops/nix/rocm-modules-10/hipsparselt/default.nix new file mode 100644 index 0000000000..424ec1e5c3 --- /dev/null +++ b/.devops/nix/rocm-modules-10/hipsparselt/default.nix @@ -0,0 +1,123 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + ninja, + git, + pkg-config, + rocm-cmake, + rocm-smi, + clr, + hipsparse, + openmp, + llvm, + msgpack-cxx, + libxml2, + zlib, + zstd, + python3, + python3Packages, + # hipsparselt only supports gfx942/gfx950 + gpuTargets ? (clr.localGpuTargets or clr.gpuTargets), +}: + +let + supportedTargets = ( + lib.lists.intersectLists gpuTargets [ + "gfx942" + "gfx950" + ] + ); + supportsTargetArches = supportedTargets != [ ]; + py = python3.withPackages (ps: [ + ps.pyyaml + ps.setuptools + ps.packaging + ps.nanobind + ps.msgpack + ps.joblib + ]); + compiler = "amdclang++"; +in +stdenv.mkDerivation (finalAttrs: { + pname = "hipsparselt${clr.gpuArchSuffix}"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-Al/0yZPn/wqtBFQU1FcGoSquDMObk6HQ3D5sSh5biHg="; + sparseCheckout = [ + "projects/hipsparselt" + "projects/hipblaslt/tensilelite" + "projects/hipblaslt/cmake" + "projects/hipblaslt/device-library" + "shared/origami" + ]; + }; + sourceRoot = "${finalAttrs.src.name}/projects/hipsparselt"; + + env.CXX = compiler; + env.ROCM_PATH = "${clr}"; + env.TENSILE_ROCM_ASSEMBLER_PATH = lib.getExe' clr "amdclang++"; + env.TENSILE_GEN_ASSEMBLY_TOOLCHAIN = lib.getExe' clr "amdclang++"; + requiredSystemFeatures = [ "big-parallel" ]; + + __structuredAttrs = true; + strictDeps = true; + + nativeBuildInputs = [ + cmake + ninja + git + pkg-config + rocm-cmake + rocm-smi + py + clr + ]; + + buildInputs = [ + llvm.llvm + clr + rocm-cmake + hipsparse + openmp + msgpack-cxx + libxml2 + python3Packages.msgpack + zlib + zstd + ]; + + cmakeFlags = [ + (lib.cmakeFeature "GPU_TARGETS" (lib.concatStringsSep ";" supportedTargets)) + (lib.cmakeBool "HIPSPARSELT_ENABLE_DEVICE" supportsTargetArches) + (lib.cmakeBool "HIPSPARSELT_ENABLE_CLIENT" false) + (lib.cmakeBool "HIPSPARSELT_BUILD_TESTING" false) + (lib.cmakeBool "HIPSPARSELT_ENABLE_MARKER" false) + (lib.cmakeBool "HIPBLASLT_ENABLE_ROCROLLER" false) + (lib.cmakeBool "HIPBLASLT_ENABLE_MARKER" false) + (lib.cmakeFeature "CMAKE_C_COMPILER" "amdclang") + (lib.cmakeFeature "CMAKE_HIP_COMPILER" compiler) + (lib.cmakeFeature "CMAKE_CXX_COMPILER" compiler) + (lib.cmakeFeature "FETCHCONTENT_SOURCE_DIR_NANOBIND" "${python3Packages.nanobind.src}") + (lib.cmakeFeature "CMAKE_INSTALL_BINDIR" "bin") + (lib.cmakeFeature "CMAKE_INSTALL_LIBDIR" "lib") + (lib.cmakeFeature "CMAKE_INSTALL_INCLUDEDIR" "include") + ]; + + passthru.supportsTargetArches = supportsTargetArches; + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm hipSPARSELt - a SPARSE marshalling library"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/hipsparselt"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/llvm/clang-bodge-ignore-systemwide-incls.diff b/.devops/nix/rocm-modules-10/llvm/clang-bodge-ignore-systemwide-incls.diff new file mode 100644 index 0000000000..5f44dbe156 --- /dev/null +++ b/.devops/nix/rocm-modules-10/llvm/clang-bodge-ignore-systemwide-incls.diff @@ -0,0 +1,23 @@ +diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp +index 57368104c914..71c57f72078e 100644 +--- a/lib/Driver/ToolChains/Linux.cpp ++++ b/lib/Driver/ToolChains/Linux.cpp +@@ -640,6 +640,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + return; + + // LOCAL_INCLUDE_DIR ++ if (!SysRoot.empty()) + addSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/local/include")); + // TOOL_INCLUDE_DIR + AddMultilibIncludeArgs(DriverArgs, CC1Args); +@@ -672,8 +673,10 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + // Add an include of '/include' directly. This isn't provided by default by + // system GCCs, but is often used with cross-compiling GCCs, and harmless to + // add even when Clang is acting as-if it were a system compiler. ++ if (!SysRoot.empty()) + addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include")); + ++ if (!SysRoot.empty()) + addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include")); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl()) diff --git a/.devops/nix/rocm-modules-10/llvm/clang-log-jobs.diff b/.devops/nix/rocm-modules-10/llvm/clang-log-jobs.diff new file mode 100644 index 0000000000..3a3a712c8b --- /dev/null +++ b/.devops/nix/rocm-modules-10/llvm/clang-log-jobs.diff @@ -0,0 +1,40 @@ +diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp +index 06f5e7e7e335..8407d664886a 100644 +--- a/lib/Driver/Compilation.cpp ++++ b/lib/Driver/Compilation.cpp +@@ -340,6 +340,9 @@ private: + void Compilation::ExecuteJobs(const JobList &Jobs, + FailingCommandList &FailingCommands, + bool LogOnly) const { ++ // If >1 job, log as each job finishes so can see progress while building many offloads ++ const bool logJobs = Jobs.size() > 1; ++ auto start_time = std::chrono::steady_clock::now(); + // According to UNIX standard, driver need to continue compiling all the + // inputs on the command line even one of them failed. + // In all but CLMode, execute all the jobs unless the necessary inputs for the +@@ -364,11 +367,25 @@ void Compilation::ExecuteJobs(const JobList &Jobs, + + JS.setJobState(Next, JobScheduler::JS_RUN); + auto Work = [&, Next]() { ++ auto job_start_time = std::chrono::steady_clock::now(); + const Command *FailingCommand = nullptr; + if (int Res = ExecuteCommand(*Next, FailingCommand, LogOnly)) { + FailingCommands.push_back(std::make_pair(Res, FailingCommand)); + JS.setJobState(Next, JobScheduler::JS_FAIL); + } else { ++ if (logJobs && Next) { ++ auto now = std::chrono::steady_clock::now(); ++ auto job_duration = std::chrono::duration_cast(now - job_start_time).count(); ++ auto duration = std::chrono::duration_cast(now - start_time).count(); ++ if (duration > 10 && job_duration > 0) { ++ if (Next->getOutputFilenames().empty()) ++ if (Next->getExecutable()) llvm::errs() << "Job completed: " << Next->getExecutable() << "\n"; ++ else (llvm::errs() << "Job completed: "), Next->Print(llvm::errs(), "\n", true); ++ else ++ llvm::errs() << "Job completed: " << Next->getOutputFilenames().front().c_str() << "\n"; ++ } ++ } ++ + JS.setJobState(Next, JobScheduler::JS_DONE); + } + }; diff --git a/.devops/nix/rocm-modules-10/llvm/default.nix b/.devops/nix/rocm-modules-10/llvm/default.nix new file mode 100644 index 0000000000..fe1cb9e46f --- /dev/null +++ b/.devops/nix/rocm-modules-10/llvm/default.nix @@ -0,0 +1,521 @@ +{ + lib, + stdenv, + # LLVM version closest to ROCm fork to override + llvmPackages_22, + overrideCC, + lndir, + rocm-device-libs, + fetchFromGitHub, + runCommand, + symlinkJoin, + rdfind, + zstd, + gcc-unwrapped, + glibc, + libffi, + libxml2, + removeReferencesTo, + fetchpatch, + # Build compilers and stdenv suitable for profiling + # leaving compressed line tables (-g1 -gz) unstripped + # TODO: Should also apply to downstream packages which use rocmClangStdenv? + profilableStdenv ? false, + # FIXME: proper two-stage bootstrap & PGO/BOLT/LTO + # LTO currently disabled due to llvm 22 vs 22.1 bitcode mismatch between + # llvmPackages_22 (22.1) and ROCm LLVM (22.0). Uses new bitcode attr + # 105 nocreateundeforpoison fails to link hipify. + # Whether to use LTO when building the ROCm toolchain + # Slows down this toolchain's build, for typical ROCm usecase + # time saved building composable_kernel and other heavy packages + # will outweight that. ~3-4% speedup multiplied by thousands + # of corehours. + withLto ? false, + # whether rocm stdenv uses libcxx (clang c++ stdlib) instead of gcc stdlibc++ + withLibcxx ? false, +}: + +let + version = "10.0.0"; + # major version of this should be the clang version ROCm forked from + rocmLlvmVersion = "23.0.0-rocm"; + # llvmPackages_base version should match rocmLlvmVersion + # so libllvm's bitcode is compatible with the built toolchain + llvmPackages_base = llvmPackages_22; + llvmPackagesNoBintools = llvmPackages_base.override { + bootBintools = null; + bootBintoolsNoLibc = null; + }; + + stdenvToBuildRocmLlvm = + if withLibcxx then + overrideCC llvmPackagesNoBintools.libcxxStdenv llvmPackagesNoBintools.clangUseLLVM + else + # oddly fuse-ld=lld fails without this override + overrideCC llvmPackagesNoBintools.stdenv ( + llvmPackagesNoBintools.libstdcxxClang.override { + inherit (llvmPackages_base) bintools; + } + ); + + gcc-include = runCommand "gcc-include" { } '' + mkdir -p $out + ln -s ${gcc-unwrapped}/include/ $out/ + ln -s ${gcc-unwrapped}/lib/ $out/ + ''; + + disallowedRefsForToolchain = [ + stdenv.cc + stdenv.cc.cc + stdenv.cc.bintools + gcc-unwrapped + stdenvToBuildRocmLlvm + stdenvToBuildRocmLlvm.cc + stdenvToBuildRocmLlvm.cc.cc + ]; + # A prefix for use as the GCC prefix when building rocm-toolchain + gcc-prefix-headers = symlinkJoin { + name = "gcc-prefix-headers"; + paths = [ + glibc.dev + gcc-unwrapped.out + ]; + disallowedRequisites = [ + glibc.dev + gcc-unwrapped.out + ]; + postBuild = '' + rm -rf $out/{bin,libexec,nix-support,lib64,share,etc} + rm $out/lib/gcc/x86_64-unknown-linux-gnu/*/plugin/include/auto-host.h + + mkdir /build/tmpout + mv $out/* /build/tmpout + cp -Lr --no-preserve=mode /build/tmpout/* $out/ + set -x + versionedIncludePath="$(echo $out/include/c++/*/)" + mv $versionedIncludePath/* $out/include/c++/ + rm -rf $versionedIncludePath/ + ''; + }; + gcc-prefix = symlinkJoin { + name = "gcc-prefix"; + paths = [ + gcc-prefix-headers + glibc + gcc-unwrapped.lib + ]; + disallowedRequisites = [ + glibc.dev + gcc-unwrapped.out + ]; + postBuild = '' + rm -rf $out/{bin,libexec,nix-support,lib64,share,etc} + rm $out/lib/ld-linux-x86-64.so.2 + ln -s $out $out/x86_64-unknown-linux-gnu + ''; + }; + llvmSrc = fetchFromGitHub { + owner = "ROCm"; + repo = "llvm-project"; + rev = "therock-10.0"; + hash = "sha256-s2nBt1Hhc03vtosrUaTr+OBCTWsCfZk5GDmziYlCE54="; + }; + llvmMajorVersion = lib.versions.major rocmLlvmVersion; + # An llvmPackages (pkgs/development/compilers/llvm/) built from ROCm LLVM's source tree + llvmPackagesRocm = llvmPackages_base.override (_old: { + stdenv = stdenvToBuildRocmLlvm; + + # not setting gitRelease = because that causes patch selection logic to use git patches + # ROCm LLVM is closer to 20 official + # gitRelease = {}; officialRelease = null; + officialRelease = { }; # Set but empty because we're overriding everything from it. + # this version determines which patches are applied + version = rocmLlvmVersion; + src = llvmSrc; + monorepoSrc = llvmSrc; + doCheck = false; + }); + refsToRemove = builtins.concatStringsSep " -t " [ + stdenvToBuildRocmLlvm + stdenvToBuildRocmLlvm.cc + stdenvToBuildRocmLlvm.cc.cc + stdenv.cc + stdenv.cc.cc + stdenv.cc.bintools + ]; + # Hacky way to avoid nixfmt indenting the entire scope body suggested by @emilazy + overrideLlvmPackagesRocm = + f: + let + overridenScope = llvmPackagesRocm.overrideScope (final: prev: f { inherit final prev; }); + in + { + inherit (overridenScope) + # Expose only a limited set of packages that we care about for ROCm + bintools + compiler-rt + compiler-rt-libc + clang + clang-unwrapped + libcxx + lld + llvm + rocm-toolchain + rocmClangStdenv + openmp + ; + }; + sysrootCompiler = + { + cc, + name, + paths, + linkPaths, + }: + let + linked = symlinkJoin { inherit name paths; }; + in + runCommand name + { + pname = name; + # If this is erroring, try why-depends --precise on the symlinkJoin of inputs to look for the problem + # nix why-depends --precise .#rocmPackages.llvm.rocm-toolchain.linked /store/path/its/not/allowed + disallowedRequisites = disallowedRefsForToolchain; + passthru.linked = linked; + linkPaths = linkPaths; + passAsFile = [ "linkPaths" ]; + # TODO(@LunNova): Try to use --sysroot with clang in its original location instead of + # relying on copying the binary? + # $clang/bin/clang++ --sysroot=$rocm-toolchain is not equivalent + # to a clang copied to $rocm-toolchain/bin here, have not yet figured out why + } + '' + mkdir -p $out/ + cp --reflink=auto -rL ${linked}/* $out/ + chmod -R +rw $out + mkdir -p $out/usr + ln -s $out/ $out/usr/local + # we don't need mixed 32 bit, the presence of lib64 is used by LLVM to decide it's a multilib sysroot + rm -rf $out/lib64 + rm -rf $out/lib/cmake $out/lib/lib*.a + mkdir -p $out/lib/clang/${llvmMajorVersion}/lib/linux/ + ln -s $out/lib/linux/libclang_rt.* $out/lib/clang/${llvmMajorVersion}/lib/linux/ + mkdir -p $out/lib/clang/${llvmMajorVersion}/lib/${stdenv.hostPlatform.config}/ + for f in $out/lib/linux/*-${stdenv.hostPlatform.parsed.cpu.name}.*; do + [ -e "$f" ] || continue + base="$(basename "$f" | sed 's/-${stdenv.hostPlatform.parsed.cpu.name}\././')" + ln -sf "$f" "$out/lib/clang/${llvmMajorVersion}/lib/${stdenv.hostPlatform.config}/$base" + done + + find $out -type f -exec sed -i "s|${cc.out}|$out|g" {} + + find $out -type f -exec sed -i "s|${cc.dev}|$out|g" {} + + + # Clang config file: redirect resource dir to the sysroot (where compiler-rt + # lives) and set GCC install prefix for header/library search + cat > $out/bin/${stdenv.hostPlatform.config}.cfg <> $out/nix-support/setup-hook + echo 'export CXX=clang++' >> $out/nix-support/setup-hook + ''; + tablegenUsage = x: !(lib.strings.hasInfix "llvm-tblgen" x); + llvmTargetsFlag = "-DLLVM_TARGETS_TO_BUILD=AMDGPU;${ + { + "x86_64" = "X86"; + "aarch64" = "AArch64"; + } + .${stdenv.targetPlatform.parsed.cpu.name} + or (throw "Unsupported CPU architecture: ${stdenv.targetPlatform.parsed.cpu.name}") + }"; + llvmMeta = { + # TODO(@LunNova): it would be nice to support aarch64 for rocmPackages + platforms = [ "x86_64-linux" ]; + }; + # TODO(@LunNova): Some of this might be worth supporting in llvmPackages, dropping from here + commonCmakeFlags = [ + llvmTargetsFlag + # Compression support is required for compressed offload kernels + # Set FORCE_ON so that failure to find the compression lib will be a build error + (lib.cmakeFeature "LLVM_ENABLE_ZSTD" "FORCE_ON") + # required for threaded ThinLTO to work + (lib.cmakeBool "LLVM_ENABLE_THREADS" true) + # third-party/benchmark is broken in rocm-7.2.0 + # error: '__COUNTER__' is a C2y extension [-Werror,-Wc2y-extensions] + (lib.cmakeBool "LLVM_INCLUDE_BENCHMARKS" false) + # LLVM tries to call git to embed VCS info if FORCE_VC_ aren't set + (lib.cmakeFeature "LLVM_FORCE_VC_REVISION" "rocm-${version}") + (lib.cmakeFeature "LLVM_FORCE_VC_REPOSITORY" "https://github.com/ROCm/llvm-project") + (lib.cmakeFeature "LLVM_VERSION_SUFFIX" "") + (lib.cmakeBool "LLVM_ENABLE_LIBCXX" withLibcxx) + (lib.cmakeFeature "CLANG_DEFAULT_CXX_STDLIB" (if withLibcxx then "libc++" else "libstdc++")) + (lib.cmakeFeature "CLANG_VENDOR" "nixpkgs-AMD") + (lib.cmakeFeature "CLANG_REPOSITORY_STRING" "https://github.com/ROCm/llvm-project/tree/rocm-${version}") + ] + ++ lib.optionals withLibcxx [ + (lib.cmakeFeature "CLANG_DEFAULT_RTLIB" "compiler-rt") + ] + ++ lib.optionals withLto [ + (lib.cmakeBool "CMAKE_INTERPROCEDURAL_OPTIMIZATION" true) + (lib.cmakeBool "LLVM_ENABLE_FATLTO" false) + ] + ++ lib.optionals (withLto && stdenvToBuildRocmLlvm.cc.isClang) [ + (lib.cmakeFeature "LLVM_ENABLE_LTO" "FULL") + (lib.cmakeFeature "LLVM_USE_LINKER" "lld") + ]; + + llvmExtraCflags = lib.concatStringsSep " " ( + lib.optionals (stdenv.hostPlatform.system == "x86_64-linux") [ + # Unprincipled decision to build x86_64 ROCm clang for at least skylake and tune for zen3+ + # In practice building the ROCm package set with anything earlier than zen3 is annoying + # and earlier than skylake is implausible due to too few cores and too little RAM + # Speeds up composable_kernel builds by ~4% + # If this causes trouble in practice we can drop this. Set since 2025-03-24. + "-march=skylake" + "-mtune=znver3" + ] + ++ lib.optionals profilableStdenv [ + # compressed line only debug info for profiling + "-gz" + "-g1" + ] + ); + inherit (llvmPackagesRocm) libcxx; +in +overrideLlvmPackagesRocm (s: { + libllvm = (s.prev.libllvm.override { }).overrideAttrs (old: { + patches = [ + # The LLVM 22 select-ptr backports nixpkgs carries are already in + # ROCm 10's LLVM 23 tree, so they no longer apply. + ] + ++ old.patches + ++ [ + ./perf-increase-namestring-size.patch + # The v64i8 VBMI shuffle fixes (nixpkgs #497745) are already merged in + # ROCm 10's LLVM 23 tree; re-applying them is detected as reversed. + # TODO: consider reapplying "Don't include aliases in RegisterClassInfo::IgnoreCSRForAllocOrder" + # it was reverted as it's a pessimization for non-GPU archs, but this compiler + # is used mostly for amdgpu + ]; + dontStrip = profilableStdenv; + hardeningDisable = [ "all" ]; + nativeBuildInputs = old.nativeBuildInputs ++ [ removeReferencesTo ]; + buildInputs = old.buildInputs ++ [ + zstd + ]; + preFixup = '' + moveToOutput "lib/lib*.a" "$dev" + moveToOutput "lib/cmake" "$dev" + sed -Ei "s|$lib/lib/(lib[^/]*)\.a|$dev/lib/\1.a|g" $dev/lib/cmake/llvm/*.cmake + ''; + env = (old.env or { }) // { + NIX_CFLAGS_COMPILE = "${(old.env or { }).NIX_CFLAGS_COMPILE or ""} ${llvmExtraCflags}"; + }; + cmakeFlags = (builtins.filter tablegenUsage old.cmakeFlags) ++ commonCmakeFlags; + # Ensure we don't leak refs to compiler that was used to bootstrap this LLVM + disallowedReferences = (old.disallowedReferences or [ ]) ++ disallowedRefsForToolchain; + postFixup = '' + ${old.postFixup or ""} + find $lib -type f -exec remove-references-to -t ${refsToRemove} {} + + ''; + meta = old.meta // llvmMeta; + }); + lld = + (s.prev.lld.override { + }).overrideAttrs + (old: { + dontStrip = profilableStdenv; + hardeningDisable = [ "all" ]; + nativeBuildInputs = old.nativeBuildInputs ++ [ + removeReferencesTo + ]; + buildInputs = old.buildInputs ++ [ + zstd + ]; + env = (old.env or { }) // { + NIX_CFLAGS_COMPILE = "${(old.env or { }).NIX_CFLAGS_COMPILE or ""} ${llvmExtraCflags}"; + }; + cmakeFlags = (builtins.filter tablegenUsage old.cmakeFlags) ++ commonCmakeFlags; + # Ensure we don't leak refs to compiler that was used to bootstrap this LLVM + disallowedReferences = (old.disallowedReferences or [ ]) ++ disallowedRefsForToolchain; + postFixup = '' + ${old.postFixup or ""} + find $lib -type f -exec remove-references-to -t ${refsToRemove} {} + + ''; + meta = old.meta // llvmMeta; + }); + clang-unwrapped = ( + (s.prev.clang-unwrapped.override { + enableClangToolsExtra = false; + }).overrideAttrs + (old: { + passthru = old.passthru // { + inherit gcc-prefix; + }; + patches = + # The scan-build-py cmake option (llvm/llvm-project#172727) is already + # in ROCm 10's LLVM 23 tree. + [ + ] + ++ old.patches + ++ [ + # Never add FHS include paths + ./clang-bodge-ignore-systemwide-incls.diff + # ./clang-log-jobs.diff is dropped for ROCm 10: its second hunk no longer + # applies to LLVM 23's lib/Driver/Compilation.cpp, and it only adds + # progress logging to keep long builds from looking idle. + ./opt-offload-compress-on-by-default.patch + ./perf-shorten-gcclib-include-paths.patch + # The GetBundleIDsInFile backport does not compile against LLVM 23's + # OffloadBundler API (raw_ostream* vs bool at OffloadBundler.cpp:1103). + # Nothing in this module set references the symbol. + ]; + # ROCm 7.2 commits 4dda51261a6 "Replace hostexec with upstream rpc" + # and 2ca1509d6d2 "Put the RTL, Back!", added CGEmitEmissaryExec.cpp which + # includes ../../openmp/device/include/EmissaryIds.h, breaking + # standalone clang builds. The upstream PR llvm/llvm-project#175265 + # ("[OpenMP] support for Emissary APIs") moves EmissaryIds.h into + # clang/lib/Headers/ so this should not be needed once that lands + # and ROCm rebases onto it. + postUnpack = '' + ${old.postUnpack or ""} + mkdir -p "''${sourceRoot}/openmp/device/include" + ln -s "${llvmSrc}/openmp/device/include/EmissaryIds.h" "''${sourceRoot}/openmp/device/include/" + ''; + hardeningDisable = [ "all" ]; + nativeBuildInputs = old.nativeBuildInputs ++ [ + removeReferencesTo + ]; + buildInputs = old.buildInputs ++ [ + zstd + ]; + env = (old.env or { }) // { + NIX_CFLAGS_COMPILE = "${(old.env or { }).NIX_CFLAGS_COMPILE or ""} ${llvmExtraCflags}"; + }; + dontStrip = profilableStdenv; + # Ensure we don't leak refs to compiler that was used to bootstrap this LLVM + disallowedReferences = (old.disallowedReferences or [ ]) ++ disallowedRefsForToolchain; + # Enable structured attrs for separateDebugInfo, because it is required with disallowedReferences set + __structuredAttrs = true; + # https://github.com/llvm/llvm-project/blob/6976deebafa8e7de993ce159aa6b82c0e7089313/clang/cmake/caches/DistributionExample-stage2.cmake#L9-L11 + cmakeFlags = + # TODO: Remove in followup, tblgen now works correctly but would rebuild + (builtins.filter tablegenUsage old.cmakeFlags) ++ commonCmakeFlags; + preFixup = '' + ${toString old.preFixup or ""} + moveToOutput "lib/lib*.a" "$dev" + moveToOutput "lib/cmake" "$dev" + mkdir -p $dev/lib/clang/ + ln -s $lib/lib/clang/${llvmMajorVersion} $dev/lib/clang/ + sed -Ei "s|$lib/lib/(lib[^/]*)\.a|$dev/lib/\1.a|g" $dev/lib/cmake/clang/*.cmake + ''; + postFixup = '' + ${toString old.postFixup or ""} + find $lib -type f -exec remove-references-to -t ${refsToRemove} {} + + find $dev -type f -exec remove-references-to -t ${refsToRemove} {} + + ''; + meta = old.meta // llvmMeta; + }) + ); + # A clang that understands standard include searching in a GNU sysroot and will put GPU libs in include path + # in the right order + # and expects its libc to be in the sysroot + rocm-toolchain = + with s.final; + (sysrootCompiler { + cc = clang-unwrapped; + name = "rocm-toolchain"; + paths = [ + clang-unwrapped.out + clang-unwrapped.lib + bintools.out + compiler-rt.out + openmp.out + openmp.dev + ] + ++ lib.optionals withLibcxx [ + libcxx + ] + ++ lib.optionals (!withLibcxx) [ + glibc + glibc.dev + ]; + linkPaths = [ + bintools.bintools.out + ] + ++ lib.optionals (!withLibcxx) [ + gcc-include.out + ]; + }) + // { + version = llvmMajorVersion; + cc = rocm-toolchain; + libllvm = llvm; + isClang = true; + isGNU = false; + }; + compiler-rt-libc = s.prev.compiler-rt-libc.overrideAttrs (old: { + meta = old.meta // llvmMeta; + }); + compiler-rt = s.final.compiler-rt-libc; + clang = s.final.rocm-toolchain; + + rocmClangStdenv = with s.final; overrideCC (if withLibcxx then libcxxStdenv else stdenv) clang; + + # Projects + openmp = + with s.final; + (llvmPackagesRocm.openmp.override { + llvm = llvm; + clang-unwrapped = clang-unwrapped; + }).overrideAttrs + (old: { + disallowedReferences = (old.disallowedReferences or [ ]) ++ disallowedRefsForToolchain; + nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ + removeReferencesTo + ]; + # LLVM 23 removed openmp's legacy standalone build; it must be configured + # through the runtimes directory instead. nixpkgs' openmp src is a subset + # of the monorepo that omits runtimes/, so build from the full tree. + src = llvmSrc; + sourceRoot = "${llvmSrc.name}/runtimes"; + # unpackPhase only makes sourceRoot writable, but openmp's install steps + # write back into ../openmp/runtime/exports, so widen it to the checkout. + postUnpack = '' + ${old.postUnpack or ""} + chmod -R u+w "''${sourceRoot%/*}" + ''; + cmakeFlags = + old.cmakeFlags + ++ commonCmakeFlags + ++ [ + "-DLLVM_ENABLE_RUNTIMES=openmp" + "-DDEVICELIBS_ROOT=${rocm-device-libs.src}" + # OMPD support is broken in ROCm 6.3+ Haven't investigated why. + "-DLIBOMP_OMPD_SUPPORT:BOOL=FALSE" + "-DLIBOMP_OMPD_GDB_SUPPORT:BOOL=FALSE" + ]; + buildInputs = old.buildInputs ++ [ + clang-unwrapped + zstd + libxml2 + libffi + ]; + postFixup = '' + ${old.postFixup or ""} + ln -s $out/lib/libomp.so $dev/lib/libomp.so + ''; + }); + # AMD has a separate MLIR impl which we package under rocmPackages.rocmlir + # It would be an error to rely on the original mlir package from this scope + mlir = null; +}) diff --git a/.devops/nix/rocm-modules-10/llvm/opt-offload-compress-on-by-default.patch b/.devops/nix/rocm-modules-10/llvm/opt-offload-compress-on-by-default.patch new file mode 100644 index 0000000000..d5cb1a363e --- /dev/null +++ b/.devops/nix/rocm-modules-10/llvm/opt-offload-compress-on-by-default.patch @@ -0,0 +1,22 @@ +From 762511ad9c9cac7769a795cc4df888a1559dca02 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Mon, 16 Dec 2024 14:56:57 -0800 +Subject: [PATCH] [AMDGPU] CommonArgs: Enable offload compression by default + +--- + clang/lib/Driver/ToolChains/CommonArgs.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp +index 33f12fb2d075d..ba35f65210c7a 100644 +--- a/lib/Driver/ToolChains/CommonArgs.cpp ++++ b/lib/Driver/ToolChains/CommonArgs.cpp +@@ -2914,7 +2914,7 @@ void tools::addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C, + void tools::addOffloadCompressArgs(const llvm::opt::ArgList &TCArgs, + llvm::opt::ArgStringList &CmdArgs) { + if (TCArgs.hasFlag(options::OPT_offload_compress, +- options::OPT_no_offload_compress, false)) ++ options::OPT_no_offload_compress, true)) + CmdArgs.push_back("--compress"); + if (TCArgs.hasArg(options::OPT_v)) + CmdArgs.push_back("-verbose"); diff --git a/.devops/nix/rocm-modules-10/llvm/perf-increase-namestring-size.patch b/.devops/nix/rocm-modules-10/llvm/perf-increase-namestring-size.patch new file mode 100644 index 0000000000..84046a5886 --- /dev/null +++ b/.devops/nix/rocm-modules-10/llvm/perf-increase-namestring-size.patch @@ -0,0 +1,28 @@ +From a57eb548d46a37e4aed33eefccc9e6374b579ff9 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Mon, 16 Dec 2024 13:58:54 -0800 +Subject: [PATCH] [AMDGPU] TargetMachine: increase NameString size to 256 + +128 is too small a default for compilers used to build +AMD's rocBLAS, composable_kernel and similar libs because +they use very long symbol names such as +device_gemm_xdl_universal_bf16_bf16_bf16_mk_nk_mn_comp_default_instance + +This fixes spending ~10% of compile time in malloc inside this function. +--- + llvm/lib/Target/TargetMachine.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp +index abd0fdf2390c0..86ce468b75643 100644 +--- a/lib/Target/TargetMachine.cpp ++++ b/lib/Target/TargetMachine.cpp +@@ -270,7 +270,7 @@ MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const { + if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this)) + return TargetSymbol; + +- SmallString<128> NameStr; ++ SmallString<256> NameStr; + getNameWithPrefix(NameStr, GV, TLOF->getMangler()); + return TLOF->getContext().getOrCreateSymbol(NameStr); + } diff --git a/.devops/nix/rocm-modules-10/llvm/perf-shorten-gcclib-include-paths.patch b/.devops/nix/rocm-modules-10/llvm/perf-shorten-gcclib-include-paths.patch new file mode 100644 index 0000000000..b23a3886c3 --- /dev/null +++ b/.devops/nix/rocm-modules-10/llvm/perf-shorten-gcclib-include-paths.patch @@ -0,0 +1,59 @@ +From 8c64deff2a82fcca5b521362193a1fd8b1a0dca7 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Tue, 17 Dec 2024 04:29:11 -0800 +Subject: [PATCH] HACK: Get canonical GCC include path so doesn't have + ../../../../ + +This allows more of the strings used in compilation to fit inside +fixed size stack allocated buffers instead of spilling into the heap +--- + lib/Driver/ToolChains/Gnu.cpp | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp +index 07df9864636..b1201b999f0 100644 +--- a/lib/Driver/ToolChains/Gnu.cpp ++++ b/lib/Driver/ToolChains/Gnu.cpp +@@ -3326,29 +3326,33 @@ static bool addLibStdCXXIncludePaths(llvm::vfs::FileSystem &vfs, + if (!vfs.exists(IncludeDir)) + return false; + ++ SmallString<260> CanonicalIncludeDir; ++ if (vfs.getRealPath(IncludeDir, CanonicalIncludeDir)) ++ return false; ++ + // Debian native gcc uses g++-multiarch-incdir.diff which uses + // include/x86_64-linux-gnu/c++/10$IncludeSuffix instead of + // include/c++/10/x86_64-linux-gnu$IncludeSuffix. +- std::string Dir = IncludeDir.str(); + StringRef Include = +- llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); ++ llvm::sys::path::parent_path(llvm::sys::path::parent_path(CanonicalIncludeDir)); + std::string Path = +- (Include + "/" + Triple + Dir.substr(Include.size()) + IncludeSuffix) ++ (Include + "/" + Triple + CanonicalIncludeDir.substr(Include.size()) + IncludeSuffix) + .str(); + if (DetectDebian && !vfs.exists(Path)) + return false; + + // GPLUSPLUS_INCLUDE_DIR +- ToolChain::addSystemInclude(DriverArgs, CC1Args, IncludeDir); ++ ToolChain::addSystemInclude(DriverArgs, CC1Args, CanonicalIncludeDir); + // GPLUSPLUS_TOOL_INCLUDE_DIR. If Triple is not empty, add a target-dependent + // include directory. + if (DetectDebian) + ToolChain::addSystemInclude(DriverArgs, CC1Args, Path); + else if (!Triple.empty()) + ToolChain::addSystemInclude(DriverArgs, CC1Args, +- IncludeDir + "/" + Triple + IncludeSuffix); ++ CanonicalIncludeDir + "/" + Triple + IncludeSuffix); + // GPLUSPLUS_BACKWARD_INCLUDE_DIR +- ToolChain::addSystemInclude(DriverArgs, CC1Args, IncludeDir + "/backward"); ++ if (vfs.exists(CanonicalIncludeDir + "/backward")) ++ ToolChain::addSystemInclude(DriverArgs, CC1Args, CanonicalIncludeDir + "/backward"); + return true; + } + +-- +2.52.0 + diff --git a/.devops/nix/rocm-modules-10/migraphx/default.nix b/.devops/nix/rocm-modules-10/migraphx/default.nix new file mode 100644 index 0000000000..5b79f8213d --- /dev/null +++ b/.devops/nix/rocm-modules-10/migraphx/default.nix @@ -0,0 +1,202 @@ +{ + lib, + stdenv, + callPackage, + fetchFromGitHub, + rocmUpdateScript, + pkg-config, + cmake, + rocm-cmake, + clr, + openmp, + rocblas, + hipblas-common, + hipblas, + hipblaslt, + rocmlir, + miopen, + protobuf, + abseil-cpp, + half, + nlohmann_json, + boost, + msgpack-cxx, + sqlite, + # TODO(@LunNova): Swap to `onednn` once v3 is supported + # Upstream issue: https://github.com/ROCm/AMDMIGraphX/issues/4351 + onednn_2, + blaze, + texliveSmall, + doxygen, + sphinx, + docutils, + ghostscript, + python3Packages, + writableTmpDirAsHomeHook, + buildDocs ? false, + buildTests ? false, + gpuTargets ? clr.gpuTargets, +}: + +let + latex = lib.optionalAttrs buildDocs ( + texliveSmall.withPackages ( + ps: with ps; [ + latexmk + tex-gyre + fncychap + wrapfig + capt-of + framed + needspace + tabulary + varwidth + titlesec + epstopdf + ] + ) + ); +in +stdenv.mkDerivation (finalAttrs: { + pname = "migraphx"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildDocs [ + "doc" + ] + ++ lib.optionals buildTests [ + "test" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "AMDMIGraphX"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-raYsrMZASdEIxSstk14b38q9dt5EOq3rKidoFvobnxk="; + }; + + nativeBuildInputs = [ + pkg-config + cmake + rocm-cmake + clr + python3Packages.python + ] + ++ lib.optionals buildDocs [ + latex + doxygen + sphinx + docutils + ghostscript + python3Packages.sphinx-rtd-theme + python3Packages.breathe + writableTmpDirAsHomeHook + ]; + + buildInputs = [ + openmp + rocblas + hipblas-common + hipblas + hipblaslt + rocmlir + miopen + protobuf + half + nlohmann_json + boost + msgpack-cxx + sqlite + onednn_2 + blaze + python3Packages.pybind11 + python3Packages.onnx + ]; + + env.LDFLAGS = "-Wl,--allow-shlib-undefined"; + + cmakeFlags = [ + "-DMIGRAPHX_ENABLE_GPU=ON" + "-DMIGRAPHX_ENABLE_CPU=ON" + "-DMIGRAPHX_ENABLE_FPGA=ON" + "-DMIGRAPHX_ENABLE_MLIR=ON" + "-DCMAKE_C_COMPILER=amdclang" + "-DCMAKE_CXX_COMPILER=amdclang++" + "-DCMAKE_VERBOSE_MAKEFILE=ON" + "-DEMBED_USE=CArrays" # Fixes error with lld + "-DDMIGRAPHX_ENABLE_PYTHON=ON" + "-DROCM_PATH=${clr}" + "-DHIP_ROOT_DIR=${clr}" + # migraphx relies on an incompatible fork of composable_kernel + # migraphxs relies on miopen which relies on current composable_kernel + # impossible to build with this ON; we can't link both of them even if we package both + "-DMIGRAPHX_USE_COMPOSABLEKERNEL=OFF" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ]; + + postPatch = '' + export CXXFLAGS+=" -w -isystem${rocmlir}/include/rocmlir -I${half}/include -I${lib.getInclude abseil-cpp}/include -I${hipblas-common}/include -I${lib.getInclude protobuf}/include" + patchShebangs tools + + # `error: '__clang_hip_runtime_wrapper.h' file not found [clang-diagnostic-error]` + substituteInPlace CMakeLists.txt \ + --replace "set(MIGRAPHX_TIDY_ERRORS ALL)" "" + + # Fix Unicode minus sign (U+2212) in comment that breaks EMBED_USE=CArrays + # The embed mechanism generates char[] arrays that can't store unicode − + # which has values >127 + substituteInPlace src/targets/gpu/kernels/include/migraphx/kernels/bit.hpp \ + --replace-fail "// popcount(~(x | −x))" "// popcount(~(x | -x))" + '' + + lib.optionalString (!buildDocs) '' + substituteInPlace CMakeLists.txt \ + --replace "add_subdirectory(doc)" "" + '' + + lib.optionalString (!buildTests) '' + substituteInPlace CMakeLists.txt \ + --replace "add_subdirectory(test)" "" + ''; + + # Unfortunately, it seems like we have to call make on this manually + preInstall = lib.optionalString buildDocs '' + make -j$NIX_BUILD_CORES doc + cd ../doc/pdf + make -j$NIX_BUILD_CORES + cd - + ''; + + postInstall = + lib.optionalString buildDocs '' + mv ../doc/html $out/share/doc/migraphx + mv ../doc/pdf/MIGraphX.pdf $out/share/doc/migraphx + '' + + lib.optionalString buildTests '' + mkdir -p $test/bin + mv bin/test_* $test/bin + patchelf $test/bin/test_* --shrink-rpath --allowed-rpath-prefixes "$NIX_STORE" + ''; + + passthru.impureTests = { + # NIXPKGS_ALLOW_UNFREE=1 bash $(nix-build -A rocmPackages.migraphx.impureTests.migraphx-driver) + migraphx-driver = callPackage ./test-migraphx-driver.nix { + migraphx = finalAttrs.finalPackage; + }; + }; + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "AMD's graph optimization engine"; + homepage = "https://github.com/ROCm/AMDMIGraphX"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/migraphx/test-migraphx-driver.nix b/.devops/nix/rocm-modules-10/migraphx/test-migraphx-driver.nix new file mode 100644 index 0000000000..c34c5a8a71 --- /dev/null +++ b/.devops/nix/rocm-modules-10/migraphx/test-migraphx-driver.nix @@ -0,0 +1,47 @@ +{ + lib, + fetchurl, + makeImpureTest, + writableTmpDirAsHomeHook, + migraphx, + clr, + rocm-smi, +}: + +# Verify that a ≈50MiB resnet onnx can run with migraphx +let + resnet18 = fetchurl { + url = "https://huggingface.co/onnxmodelzoo/resnet18_Opset18_timm/resolve/main/resnet18_Opset18_timm.onnx"; + hash = "sha256-u2Io20n72qoA9atRsFIWb0zHF1WdJYgHQdMWfJhJGHA="; + meta.license = lib.licenses.unfree; + }; +in +makeImpureTest { + name = "migraphx-driver"; + testedPackage = "rocmPackages.migraphx"; + + sandboxPaths = [ + "/sys" + "/dev/dri" + "/dev/kfd" + ]; + + nativeBuildInputs = [ + writableTmpDirAsHomeHook + migraphx + clr + rocm-smi + ]; + + # FIXME(@LunNova): tol values are set too high - was seeing high divergence on iGPU + # want this test to be useful for verifying workloads run at all + # and will investigate what's broken for accuracy + testScript = '' + rocm-smi + migraphx-driver verify -O --rms-tol 0.03 --atol 1.0 --rtol 0.01 ${resnet18} + ''; + + meta = { + teams = [ lib.teams.rocm ]; + }; +} diff --git a/.devops/nix/rocm-modules-10/miopen/default.nix b/.devops/nix/rocm-modules-10/miopen/default.nix new file mode 100644 index 0000000000..46aa1b2780 --- /dev/null +++ b/.devops/nix/rocm-modules-10/miopen/default.nix @@ -0,0 +1,349 @@ +{ + lib, + stdenv, + callPackage, + fetchFromGitHub, + fetchpatch, + fetchurl, + runCommand, + pkg-config, + python3, + cmake, + rocm-cmake, + rocblas, + rocmlir, + rocrand, + rocm-runtime, + hipblas-common, + hipblas, + hipblaslt, + clr, + llvm, + composable_kernel, + frugally-deep, + rocm-docs-core, + half, + boost, + sqlite, + symlinkJoin, + bzip2, + lbzip2, + nlohmann_json, + texliveSmall, + doxygen, + sphinx, + zlib, + gtest, + eigen, + rocm-comgr, + roctracer, + python3Packages, + gpuTargets ? clr.localGpuTargets or clr.gpuTargets, + buildDocs ? false, # Needs internet because of rocm-docs-core + buildTests ? false, + withComposableKernel ? true, +}: + +let + # FIXME: cmake files need patched to include this properly + # is deprecated in C++20 and one of MIOpen's vendored headers still + # includes it; clang 23 turns that #warning into an error under -Werror. + cFlags = "-Wno-error=#warnings -Wno-documentation-pedantic --offload-compress -isystem ${hipblas-common}/include -isystem ${hipblas}/include -isystem ${roctracer}/include -isystem ${nlohmann_json}/include -isystem ${sqlite.dev}/include -isystem ${rocrand}/include"; + version = "10.0.0"; + + # Targets outside this list will get + # error: use of undeclared identifier 'CK_BUFFER_RESOURCE_3RD_DWORD' + supportedTargets = lib.intersectLists [ + "gfx900" + "gfx906" + "gfx908" + "gfx90a" + "gfx942" + "gfx950" + "gfx1030" + "gfx1031" + "gfx1100" + "gfx1101" + "gfx1102" + "gfx1150" + "gfx1151" + "gfx1200" + "gfx1201" + ] gpuTargets; + + latex = lib.optionalAttrs buildDocs ( + texliveSmall.withPackages ( + ps: with ps; [ + latexmk + tex-gyre + fncychap + wrapfig + capt-of + framed + needspace + tabulary + varwidth + titlesec + ] + ) + ); + + # for hiprtcCompileProgram (dropout kernels require rocrand in -I at runtime) + hiprtcCompileRocmPath = symlinkJoin { + name = "miopen-hiprtc-compile-rocm-path"; + paths = [ + clr + rocrand + ]; + }; + + # Kernel databases moved from Git LFS to DVC (anonymous s3 bucket s3://therock-dvc/rocm-libraries) + fetchKdb = + name: + { url, hash }: + runCommand "miopen-${name}.kdb" { preferLocalBuild = true; } '' + ${lbzip2}/bin/lbzip2 -ckd ${ + fetchurl { + inherit url hash; + name = "${name}.kdb.bz2"; + } + } > $out + ''; + + kdbs = lib.mapAttrs fetchKdb ( + lib.filterAttrs (name: _: lib.elem name supportedTargets) (import ./kdbs.nix) + ); + + linkKDBsTo = + targetPath: + lib.concatStringsSep "" ( + lib.mapAttrsToList (name: kdb: '' + ln -sf ${kdb} ${targetPath}/${name}.kdb + '') kdbs + ); +in +stdenv.mkDerivation (finalAttrs: { + inherit version; + pname = "miopen"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/miopen" + "shared" + ]; + fetchSubmodules = true; + hash = "sha256-8Ksw1v/nkSSS8ecWJ7CaRnK4JX1Kn6+EMg8GrTzSzhA="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/miopen"; + + env.CFLAGS = cFlags; + env.CXXFLAGS = cFlags; + + # Find zstd and add to target. Mainly for torch. + patches = [ + ./skip-preexisting-dbs.patch + # Both upstream MIOpen commits (e608b432, 3413d2da) are already contained in + # therock-10.0. The ISA-compatibility patch is dropped for the same reason as + # rocBLAS's: kernels here are built for gfx1151 exactly. + ]; + + outputs = [ + "out" + ] + ++ lib.optionals buildDocs [ + "doc" + ] + ++ lib.optionals buildTests [ + "test" + ]; + enableParallelBuilding = true; + env.ROCM_PATH = clr; + env.LD_LIBRARY_PATH = lib.makeLibraryPath [ rocm-runtime ]; + + nativeBuildInputs = [ + pkg-config + # ROCm 10's MIOpen does find_package(Python3 REQUIRED) at configure time + python3 + cmake + rocm-cmake + clr + ]; + + buildInputs = [ + hipblas + hipblas-common + rocblas + rocmlir + half + boost + sqlite + bzip2 + nlohmann_json + # ROCm 10's cmake/ThirdParty.cmake find_package()s these and falls back to + # FetchContent (network) when they are missing. + gtest + eigen + frugally-deep + roctracer + rocrand + hipblaslt + ] + ++ lib.optionals withComposableKernel [ + composable_kernel + ] + ++ lib.optionals buildDocs [ + latex + doxygen + sphinx + rocm-docs-core + python3Packages.sphinx-rtd-theme + python3Packages.breathe + python3Packages.myst-parser + ] + ++ lib.optionals buildTests [ + gtest + zlib + ]; + + cmakeFlags = [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" supportedTargets}" + "-DGPU_TARGETS=${lib.concatStringsSep ";" supportedTargets}" + "-DGPU_ARCHS=${lib.concatStringsSep ";" supportedTargets}" + "-DCMAKE_VERBOSE_MAKEFILE=ON" + "-DCMAKE_MODULE_PATH=${clr}/hip/cmake" + "-DCMAKE_BUILD_TYPE=Release" + + # needs to stream to stdout so bzcat rather than bunzip2 + "-DUNZIPPER=${bzip2}/bin/bzcat" + + "-DCMAKE_C_COMPILER=amdclang" + "-DCMAKE_CXX_COMPILER=amdclang++" + "-DROCM_PATH=${clr}" + # ROCm 10's cmake/ClangToolChain.cmake assumes TheRock's single-prefix layout + # (${ROCM_PATH}/lib/llvm/bin). Point it at the split nix outputs instead: the + # ROCM_CMAKE_PATH branch wants /bin to exist, and it honours an + # explicit ROCM_CMAKE_LLVM_BIN_PATH for the compiler directory. + "-DROCM_CMAKE_PATH=${llvm.rocm-toolchain}" + "-DROCM_CMAKE_LLVM_BIN_PATH=${llvm.rocm-toolchain}/bin" + "-DHIP_ROOT_DIR=${clr}" + (lib.cmakeBool "MIOPEN_USE_ROCBLAS" true) + (lib.cmakeBool "MIOPEN_USE_HIPBLASLT" true) + (lib.cmakeBool "MIOPEN_USE_COMPOSABLEKERNEL" withComposableKernel) + (lib.cmakeBool "MIOPEN_USE_HIPRTC" true) + (lib.cmakeBool "MIOPEN_USE_COMGR" true) + # ROCm 10's MIOpen pulls gtest through FetchContent when testing is enabled, + # which cannot work in the sandbox. Tests are off for this build anyway. + (lib.cmakeBool "BUILD_TESTING" buildTests) + "-DCMAKE_HIP_COMPILER_ROCM_ROOT=${clr}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DMIOPEN_BACKEND=HIP" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TESTS=ON" + "-DMIOPEN_TEST_ALL=ON" + ]; + + postPatch = '' + substituteInPlace cmake/ClangTidy.cmake \ + --replace-fail 'macro(enable_clang_tidy)' 'macro(enable_clang_tidy) + endmacro() + macro(enable_clang_tidy_unused)' \ + --replace-fail 'function(clang_tidy_check TARGET)' 'function(clang_tidy_check TARGET) + return()' + + # src/composable_kernel is gone in ROCm 10 (and CK is disabled for this build). + patchShebangs test fin utils install_deps.cmake + + # ROCm 10's comgr.cpp no longer hardcodes "/opt/rocm": it reads the ROCM_PATH + # env var (MIOPEN_DECLARE_ENV_VAR_STR(ROCM_PATH), src/comgr.cpp:73), which the + # consumer already sets. + '' + + linkKDBsTo "src/kernels" + + '' + mkdir -p build/share/miopen/db/ + '' + + linkKDBsTo "build/share/miopen/db"; + + # Unfortunately, it seems like we have to call make on these manually + postBuild = + lib.optionalString buildDocs '' + python -m sphinx -T -E -b html -d _build/doctrees -D language=en ../docs _build/html + '' + + lib.optionalString buildTests '' + make -j$NIX_BUILD_CORES check + ''; + + postInstall = '' + rm $out/libexec/miopen/install_precompiled_kernels.sh + '' + + linkKDBsTo "$out/share/miopen/db" + + lib.optionalString buildDocs '' + mv ../doc/html $out/share/doc/miopen-hip + '' + + lib.optionalString buildTests '' + mkdir -p $test/bin + mv bin/test_* $test/bin + patchelf --set-rpath $out/lib:${ + lib.makeLibraryPath ( + finalAttrs.buildInputs + ++ [ + clr + rocm-comgr + ] + ) + } $test/bin/* + ''; + + requiredSystemFeatures = [ "big-parallel" ]; + + passthru.impureTests = { + # bash $(nix-build -A rocmPackages.miopen.passthru.impureTests.conv) etc + bnorm = callPackage ./test-runtime-compilation.nix { + miopen = finalAttrs.finalPackage; + name = "bnorm"; + testScript = "MIOpenDriver bnorm -n 16 -c 16 -H 512 -W 512 -m 1 -F 1 -s 1 -r 1"; + }; + conv = callPackage ./test-runtime-compilation.nix { + miopen = finalAttrs.finalPackage; + name = "conv"; + testScript = "MIOpenDriver conv -n 1 -c 1 -H 4 -W 4 -k 1 -y 3 -x 3 -p 0 -q 0 -V 0"; + }; + dropout = callPackage ./test-runtime-compilation.nix { + miopen = finalAttrs.finalPackage; + name = "dropout"; + testScript = "MIOpenDriver dropout -d 64,32,14,14"; + }; + pool = callPackage ./test-runtime-compilation.nix { + miopen = finalAttrs.finalPackage; + name = "pool"; + testScript = "MIOpenDriver pool -W 1x1x4x4 -y 2 -x 2 -p 0 -q 0 -F 1 -V 0"; + }; + }; + passthru.tests = { + # Ensure all .tn.model files can be loaded by whatever version of frugally-deep we have + # This is otherwise hard to verify as MIOpen will only use these models on specific, + # expensive Instinct GPUs + # If MIOpen stops embedding .tn.model files the test will also fail, and can be deleted, + # likely along with the frugally-deep dependency + can-load-models = callPackage ./test-frugally-deep-model-loading.nix { + inherit (finalAttrs) src version; + inherit frugally-deep nlohmann_json; + }; + }; + passthru.updateScript = ./update.sh; + + meta = { + description = "Machine intelligence library for ROCm"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/miopen"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/miopen/kdbs.nix b/.devops/nix/rocm-modules-10/miopen/kdbs.nix new file mode 100644 index 0000000000..d4156a9732 --- /dev/null +++ b/.devops/nix/rocm-modules-10/miopen/kdbs.nix @@ -0,0 +1,27 @@ +# Generated by update.sh +{ + gfx1030 = { + url = "https://therock-dvc.s3.amazonaws.com/rocm-libraries/files/md5/22/c4bd38cc34d3906add061ee57b099b"; + hash = "sha256-LESExp7sFl7osCM7HdVMpzOE0dU7953e2yzgeHSGgfI="; + }; + gfx900 = { + url = "https://therock-dvc.s3.amazonaws.com/rocm-libraries/files/md5/cf/9c12dafe25b15ea1e93088b7b061af"; + hash = "sha256-lFFB5GQFTjUnx3JDx816yH+96OGRt9XvBzfLFFHtUrE="; + }; + gfx906 = { + url = "https://therock-dvc.s3.amazonaws.com/rocm-libraries/files/md5/04/b3be6a15c700ff382e0a5e136010e1"; + hash = "sha256-cn1ODLcUQi+/QJUlWbELukMUj4+b1vjjRhhTseL9tdM="; + }; + gfx908 = { + url = "https://therock-dvc.s3.amazonaws.com/rocm-libraries/files/md5/35/b9082b72e661dc5e37f14de1d9d4ed"; + hash = "sha256-pI30zpZL3OEP3aeLdVpM00nHeTyD5K+XDH47g0W2A+M="; + }; + gfx90a = { + url = "https://therock-dvc.s3.amazonaws.com/rocm-libraries/files/md5/a1/1615323e06c5774fe19cf34c51baef"; + hash = "sha256-TkzSgY3V/Xs5YXfr69TrL8JjqDr1MZMgeBeQ/e2kEjE="; + }; + gfx942 = { + url = "https://therock-dvc.s3.amazonaws.com/rocm-libraries/files/md5/6a/fe97d7bd441fe15280b28b6e3b1748"; + hash = "sha256-fyhnR3+xPFkHLN36dI9UYIhqoVstt5RpareGn2S9lMM="; + }; +} diff --git a/.devops/nix/rocm-modules-10/miopen/skip-preexisting-dbs.patch b/.devops/nix/rocm-modules-10/miopen/skip-preexisting-dbs.patch new file mode 100644 index 0000000000..89be2f4076 --- /dev/null +++ b/.devops/nix/rocm-modules-10/miopen/skip-preexisting-dbs.patch @@ -0,0 +1,22 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d0ffaf983..0b9ed0952 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -554,7 +554,7 @@ endif() + function(unpack_db db_bzip2_file) + get_filename_component(__fname ${db_bzip2_file} NAME_WLE) + add_custom_command(OUTPUT ${KERNELS_BINARY_DIR}/${__fname} +- COMMAND ${UNZIPPER} -dc -k ${db_bzip2_file} > ${KERNELS_BINARY_DIR}/${__fname}) ++ COMMAND test -e ${KERNELS_BINARY_DIR}/${__fname} || ${UNZIPPER} -dc -k ${db_bzip2_file} > ${KERNELS_BINARY_DIR}/${__fname}) + string(REPLACE "." "_" __tname ${__fname}) + add_custom_target(generate_${__tname} ALL DEPENDS ${KERNELS_BINARY_DIR}/${__fname}) + +@@ -563,7 +563,7 @@ function(unpack_db db_bzip2_file) + if(NOT MIOPEN_USE_SQLITE_PERFDB AND __extension STREQUAL ".db") + add_custom_command(OUTPUT ${KERNELS_BINARY_DIR}/${__fname}.txt + DEPENDS sqlite2txt generate_${__tname} +- COMMAND $ ${KERNELS_BINARY_DIR}/${__fname} ${KERNELS_BINARY_DIR}/${__fname}.txt ++ COMMAND test -e ${KERNELS_BINARY_DIR}/${__fname}.txt || $ ${KERNELS_BINARY_DIR}/${__fname} ${KERNELS_BINARY_DIR}/${__fname}.txt + ) + add_custom_target(generate_${__tname}_txt ALL DEPENDS ${KERNELS_BINARY_DIR}/${__fname}.txt) + add_dependencies(generate_kernels generate_${__tname}_txt) diff --git a/.devops/nix/rocm-modules-10/miopen/test-frugally-deep-model-loading.cpp b/.devops/nix/rocm-modules-10/miopen/test-frugally-deep-model-loading.cpp new file mode 100644 index 0000000000..6b64b80999 --- /dev/null +++ b/.devops/nix/rocm-modules-10/miopen/test-frugally-deep-model-loading.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include + +int main() { + std::vector model_files; + std::string src_dir = std::getenv("SRC_DIR") ? std::getenv("SRC_DIR") : "."; + + // collect *tn.model files except _metadata + try { + for (const auto& entry : std::filesystem::recursive_directory_iterator(src_dir)) { + if (entry.is_regular_file()) { + std::string path = entry.path().string(); + if (path.find("tn.model") != std::string::npos && path.find("_metadata.") == std::string::npos) { + model_files.push_back(path); + } + } + } + } catch (const std::exception& e) { + std::cerr << "Error scanning directory: " << e.what() << std::endl; + return 1; + } + + if (model_files.empty()) { + std::cout << "No *.tn.model files found in " << src_dir << std::endl; + return 1; + } + + std::cout << "Found " << model_files.size() << " model files to test" << std::endl; + + int failed_count = 0; + for (const auto& model_file : model_files) { + std::cout << "Loading: " << model_file << " ... "; + std::cout.flush(); + + try { + const auto model = fdeep::load_model(model_file); + std::cout << "OK" << std::endl; + } catch (const std::exception& e) { + std::cout << "FAILED: " << e.what() << std::endl; + failed_count++; + } + } + + if (failed_count > 0) { + std::cerr << "\n" << failed_count << " out of " << model_files.size() + << " models failed to load" << std::endl; + return 1; + } + + std::cout << "\nAll " << model_files.size() << " models loaded successfully!" << std::endl; + return 0; +} diff --git a/.devops/nix/rocm-modules-10/miopen/test-frugally-deep-model-loading.nix b/.devops/nix/rocm-modules-10/miopen/test-frugally-deep-model-loading.nix new file mode 100644 index 0000000000..7f82083d23 --- /dev/null +++ b/.devops/nix/rocm-modules-10/miopen/test-frugally-deep-model-loading.nix @@ -0,0 +1,49 @@ +{ + lib, + stdenv, + eigen, + frugally-deep, + functionalplus, + nlohmann_json, + src, + version, +}: + +stdenv.mkDerivation { + pname = "miopen-frugally-deep-model-test"; + inherit version src; + + dontConfigure = true; + dontInstall = true; + doCheck = true; + + buildPhase = '' + runHook preBuild + + $CXX -std=c++20 \ + -I${lib.getDev eigen}/include/eigen3 \ + -I${lib.getDev functionalplus}/include \ + -I${lib.getDev frugally-deep}/include \ + -I${lib.getDev nlohmann_json}/include \ + ${./test-frugally-deep-model-loading.cpp} \ + -o test_models + + runHook postBuild + ''; + + checkPhase = '' + runHook preCheck + + echo "Running model loading tests..." + SRC_DIR="${src}" ./test_models + mkdir -p $out + + runHook postCheck + ''; + + meta = { + description = "Test that frugally-deep can load MIOpen model files"; + teams = with lib.teams; [ rocm ]; + platforms = lib.platforms.linux; + }; +} diff --git a/.devops/nix/rocm-modules-10/miopen/test-runtime-compilation.nix b/.devops/nix/rocm-modules-10/miopen/test-runtime-compilation.nix new file mode 100644 index 0000000000..c781d36462 --- /dev/null +++ b/.devops/nix/rocm-modules-10/miopen/test-runtime-compilation.nix @@ -0,0 +1,37 @@ +{ + lib, + makeImpureTest, + writableTmpDirAsHomeHook, + miopen, + clr, + rocm-smi, + name, + testScript, +}: + +makeImpureTest { + inherit name; + testedPackage = "rocmPackages.miopen"; + + sandboxPaths = [ + "/sys" + "/dev/dri" + "/dev/kfd" + ]; + + nativeBuildInputs = [ + writableTmpDirAsHomeHook + miopen + clr + rocm-smi + ]; + + testScript = '' + rocm-smi + ${testScript} + ''; + + meta = { + teams = [ lib.teams.rocm ]; + }; +} diff --git a/.devops/nix/rocm-modules-10/miopen/update.sh b/.devops/nix/rocm-modules-10/miopen/update.sh new file mode 100644 index 0000000000..8e2e925857 --- /dev/null +++ b/.devops/nix/rocm-modules-10/miopen/update.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p curl jq nix common-updater-scripts + +set -euo pipefail + +gh_curl() { curl ${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} -sf "$@"; } + +version="${1:-$(gh_curl "https://api.github.com/repos/ROCm/rocm-libraries/releases?per_page=4" \ + | jq -re 'map(.tag_name // .name) + | map(select(test("^rocm-[0-9]+\\.[0-9]+(\\.[0-9]+)?$"))) + | first | ltrimstr("rocm-")')}" + +# main source version +echo "Updating MIOpen to $version" >&2 +update-source-version rocmPackages.miopen "$version" --ignore-same-hash + +# kdbs.nix from s3 bucket +cd "$(dirname "${BASH_SOURCE[0]}")" +bucket="https://therock-dvc.s3.amazonaws.com/rocm-libraries/files/md5" + +# Fetch directory listing; extract name + download_url for .dvc files +dvc_entries=$(gh_curl "https://api.github.com/repos/ROCm/rocm-libraries/contents/projects/miopen/src/kernels?ref=rocm-${version}" \ + | jq -r '.[] | select(.name | endswith(".kdb.bz2.dvc")) | "\(.name)\t\(.download_url)"') + +[[ -n "$dvc_entries" ]] || { echo "No .kdb.bz2.dvc files found, upstream likely changed packaging again" >&2; exit 1; } + +{ + echo "# Generated by update.sh" + echo "{" + + while IFS=$'\t' read -r dvc_file raw_url; do + arch="${dvc_file%.kdb.bz2.dvc}" + md5=$(curl -sf "$raw_url" | awk '/- md5:/{print $3}') + url="${bucket}/${md5:0:2}/${md5:2}" + sri=$(nix --extra-experimental-features nix-command store prefetch-file --json "$url" --name "${arch}.kdb.bz2" | jq -r .hash) + echo " $arch: $sri" >&2 + cat < kdbs.nix + +echo "Wrote kdbs.nix" >&2 diff --git a/.devops/nix/rocm-modules-10/mivisionx/0001-set-__STDC_CONSTANT_MACROS-to-make-rocAL-compile.patch b/.devops/nix/rocm-modules-10/mivisionx/0001-set-__STDC_CONSTANT_MACROS-to-make-rocAL-compile.patch new file mode 100644 index 0000000000..18946835e1 --- /dev/null +++ b/.devops/nix/rocm-modules-10/mivisionx/0001-set-__STDC_CONSTANT_MACROS-to-make-rocAL-compile.patch @@ -0,0 +1,25 @@ +From f0e66bd446d44df1d30faaad520613f5fb7f5916 Mon Sep 17 00:00:00 2001 +From: Martin Schwaighofer +Date: Sat, 30 Mar 2024 15:36:52 +0100 +Subject: [PATCH] set __STDC_CONSTANT_MACROS to make rocAL compile + +--- + CMakeLists.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 42b139b6..509915f1 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -149,6 +149,8 @@ message("-- ${Cyan} -D MIGRAPHX=${MIGRAPHX} [Turn ON/OFF MIGraphX Module (de + message("-- ${Cyan} -D BACKEND=${BACKEND} [Select MIVisionX Backend [options:CPU/OPENCL/HIP](default:HIP)]${ColourReset}") + message("-- ${Cyan} -D BUILD_WITH_AMD_ADVANCE=${BUILD_WITH_AMD_ADVANCE} [Turn ON/OFF Build for AMD advanced GPUs(default:OFF)]${ColourReset}") + ++add_definitions(-D__STDC_CONSTANT_MACROS) ++ + add_subdirectory(amd_openvx) + add_subdirectory(amd_openvx_extensions) + add_subdirectory(utilities) +-- +2.43.0 + diff --git a/.devops/nix/rocm-modules-10/mivisionx/default.nix b/.devops/nix/rocm-modules-10/mivisionx/default.nix new file mode 100644 index 0000000000..dd136895af --- /dev/null +++ b/.devops/nix/rocm-modules-10/mivisionx/default.nix @@ -0,0 +1,138 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + pkg-config, + rpp, + rocblas, + miopen, + migraphx, + openmp, + protobuf, + qtcreator, + opencv, + ffmpeg, + boost, + half, + lmdb, + rapidjson, + rocm-docs-core, + python3Packages, + useOpenCL ? false, + useCPU ? false, + buildDocs ? false, # Needs internet + gpuTargets ? clr.localGpuTargets or [ ], +}: + +stdenv.mkDerivation (finalAttrs: { + pname = + "mivisionx-" + + ( + if (!useOpenCL && !useCPU) then + "hip" + else if (!useOpenCL && !useCPU) then + "opencl" + else + "cpu" + ); + + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "MIVisionX"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-LyiPcZi4vU0R+eI/AbYk8ioewuqET5lCtArtPltJ+Gw="; + }; + + patches = [ + ./0001-set-__STDC_CONSTANT_MACROS-to-make-rocAL-compile.patch + ]; + + nativeBuildInputs = [ + cmake + rocm-cmake + pkg-config + ] + ++ lib.optionals (!useOpenCL && !useCPU) [ + clr + ] + ++ lib.optionals buildDocs [ + rocm-docs-core + python3Packages.python + ]; + + buildInputs = [ + rpp + openmp + half + protobuf + qtcreator + opencv + ffmpeg + boost + lmdb + rapidjson + python3Packages.pybind11 + python3Packages.numpy + ] + ++ lib.optionals (!useOpenCL && !useCPU) [ + miopen + rocblas + migraphx + ]; + + cmakeFlags = [ + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_INSTALL_PREFIX_PYTHON=lib" + # "-DAMD_FP16_SUPPORT=ON" `error: typedef redefinition with different types ('__half' vs 'half_float::half')` + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals (!useOpenCL && !useCPU) [ + "-DROCM_PATH=${clr}" + "-DAMDRPP_PATH=${rpp}" + "-DBACKEND=HIP" + "-DCMAKE_C_COMPILER=hipcc" + "-DCMAKE_CXX_COMPILER=hipcc" + ] + ++ lib.optionals (useOpenCL && !useCPU) [ + "-DBACKEND=OCL" + ] + ++ lib.optionals useCPU [ + "-DBACKEND=CPU" + ]; + + postPatch = '' + ${lib.optionalString (!useOpenCL && !useCPU) '' + # Properly find miopen + substituteInPlace amd_openvx_extensions/CMakeLists.txt \ + --replace-fail "miopen PATHS \''${ROCM_PATH} QUIET" "miopen PATHS ${miopen} QUIET" \ + --replace-fail "\''${ROCM_PATH}/include/miopen/config.h" "${miopen}/include/miopen/config.h" + ''} + ''; + + postBuild = lib.optionalString buildDocs '' + python3 -m sphinx -T -E -b html -d _build/doctrees -D language=en ../docs _build/html + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Set of comprehensive computer vision and machine intelligence libraries, utilities, and applications"; + homepage = "https://github.com/ROCm/MIVisionX"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + broken = useOpenCL; + }; +}) diff --git a/.devops/nix/rocm-modules-10/mscclpp/default.nix b/.devops/nix/rocm-modules-10/mscclpp/default.nix new file mode 100644 index 0000000000..58a0066a48 --- /dev/null +++ b/.devops/nix/rocm-modules-10/mscclpp/default.nix @@ -0,0 +1,45 @@ +{ + fetchFromGitHub, + stdenv, + cmake, + clr, + numactl, + nlohmann_json, +}: +stdenv.mkDerivation { + pname = "mscclpp"; + version = "unstable-2024-12-13"; + src = fetchFromGitHub { + owner = "microsoft"; + repo = "mscclpp"; + rev = "ee75caf365a27b9ab7521cfdda220b55429e5c37"; + hash = "sha256-/mi9T9T6OIVtJWN3YoEe9az/86rz7BrX537lqaEh3ig="; + }; + nativeBuildInputs = [ + cmake + ]; + buildInputs = [ + clr + numactl + ]; + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace-fail "gfx90a gfx941 gfx942" "gfx908 gfx90a gfx942 gfx1030 gfx1100" + ''; + cmakeFlags = [ + "-DMSCCLPP_BYPASS_GPU_CHECK=ON" + "-DMSCCLPP_USE_ROCM=ON" + "-DMSCCLPP_BUILD_TESTS=OFF" + "-DGPU_TARGETS=gfx908;gfx90a;gfx942;gfx1030;gfx1100" + "-DAMDGPU_TARGETS=gfx908;gfx90a;gfx942;gfx1030;gfx1100" + "-DMSCCLPP_BUILD_APPS_NCCL=ON" + "-DMSCCLPP_BUILD_PYTHON_BINDINGS=OFF" + "-DFETCHCONTENT_QUIET=OFF" + "-DFETCHCONTENT_TRY_FIND_PACKAGE_MODE=ALWAYS" + "-DFETCHCONTENT_SOURCE_DIR_JSON=${nlohmann_json.src}" + ]; + env.ROCM_PATH = clr; + meta = { + homepage = "https://github.com/microsoft/mscclpp"; + }; +} diff --git a/.devops/nix/rocm-modules-10/rccl/default.nix b/.devops/nix/rocm-modules-10/rccl/default.nix new file mode 100644 index 0000000000..45c613c073 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rccl/default.nix @@ -0,0 +1,159 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocm-smi, + rocm-core, + pkg-config, + clr, + mscclpp, + perl, + hipify, + python3, + fmt, + gtest, + chrpath, + roctracer, + rocprofiler, + rocprofiler-register, + autoPatchelfHook, + buildTests ? false, + gpuTargets ? (clr.localGpuTargets or [ ]), + # for passthru.tests + rccl, +}: + +let + useAsan = buildTests; + useUbsan = buildTests; + san = lib.optionalString (useAsan || useUbsan) ( + "-fno-gpu-sanitize -fsanitize=undefined " + + (lib.optionalString useAsan "-fsanitize=address -shared-libsan ") + ); +in +# Note: we can't properly test or make use of multi-node collective ops +# https://github.com/NixOS/nixpkgs/issues/366242 tracks kernel support +# kfd_peerdirect support which is on out-of-tree amdkfd in ROCm/ROCK-Kernel-Driver +# infiniband ib_peer_mem support isn't in the mainline kernel but is carried by some distros +stdenv.mkDerivation (finalAttrs: { + pname = "rccl${clr.gpuArchSuffix}"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ]; + + patches = [ + ./rccl-test-missing-iomanip.diff + ./fix_hw_reg_hw_id_gt_gfx10.patch + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rccl"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-A1IQYIDWqu3JLiPQ70G52s1/0ZweQxFlgMUH81qJWmU="; + }; + + requiredSystemFeatures = [ "big-parallel" ]; # Very resource intensive LTO + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + perl + hipify + python3 + pkg-config + autoPatchelfHook # ASAN doesn't add rpath without this + ]; + + buildInputs = [ + rocm-smi + fmt + gtest + roctracer + rocprofiler + rocprofiler-register + mscclpp + ] + ++ lib.optionals buildTests [ + chrpath + ]; + + cmakeFlags = [ + "-DHIP_CLANG_NUM_PARALLEL_JOBS=4" + "-DCMAKE_BUILD_TYPE=Release" + "-DROCM_PATH=${clr}" + "-DHIP_COMPILER=${clr}/bin/amdclang++" + "-DCMAKE_CXX_COMPILER=${clr}/bin/amdclang++" + "-DROCM_PATCH_VERSION=${rocm-core.ROCM_LIBPATCH_VERSION}" + "-DROCM_VERSION=${rocm-core.ROCM_LIBPATCH_VERSION}" + "-DBUILD_BFD=OFF" # Can't get it to detect bfd.h + "-DENABLE_MSCCL_KERNEL=ON" + # FIXME: this is still running a download because if(NOT mscclpp_nccl_FOUND) is commented out T_T + "-DENABLE_MSCCLPP=OFF" + #"-DMSCCLPP_ROOT=${mscclpp}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + # AMD can't make up their minds and keep changing which one is used in different projects. + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + "-DGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TESTS=ON" + ]; + + # -O2 and -fno-strict-aliasing due to UB issues in RCCL :c + # Reported upstream + env.CFLAGS = "-I${clr}/include -I${roctracer}/include -O2 -fno-strict-aliasing ${san}-fno-omit-frame-pointer -momit-leaf-frame-pointer"; + env.CXXFLAGS = "-I${clr}/include -I${roctracer}/include -O2 -fno-strict-aliasing ${san}-fno-omit-frame-pointer -momit-leaf-frame-pointer"; + env.LDFLAGS = "${san}"; + postPatch = '' + patchShebangs src tools + substituteInPlace CMakeLists.txt \ + --replace-fail '${"\${HOST_OS_ID}"}' '"ubuntu"' \ + --replace-fail 'target_include_directories(rccl PRIVATE ''${ROCM_SMI_INCLUDE_DIR})' \ + 'target_include_directories(rccl PRIVATE ''${ROCM_SMI_INCLUDE_DIRS})' + ''; + + postInstall = + lib.optionalString useAsan '' + patchelf --add-needed ${clr}/llvm/lib/linux/libclang_rt.asan-${stdenv.hostPlatform.parsed.cpu.name}.so $out/lib/librccl.so + '' + + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/* $test/bin + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + # This package with sanitizers + manual integration test binaries built + # must be ran manually + passthru.tests.rccl = rccl.override { + buildTests = true; + }; + + meta = { + description = "ROCm communication collectives library"; + homepage = "https://github.com/ROCm/rccl"; + license = with lib.licenses; [ + bsd2 + bsd3 + ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rccl/fix_hw_reg_hw_id_gt_gfx10.patch b/.devops/nix/rocm-modules-10/rccl/fix_hw_reg_hw_id_gt_gfx10.patch new file mode 100644 index 0000000000..c69000814a --- /dev/null +++ b/.devops/nix/rocm-modules-10/rccl/fix_hw_reg_hw_id_gt_gfx10.patch @@ -0,0 +1,33 @@ +fix: __trace_hwreg should use HW_REG_HW_ID1 for all gfx10/11/12 +diff --git a/src/device/common.h b/src/device/common.h +index c6c61021..742885f4 100644 +--- a/src/device/common.h ++++ b/src/device/common.h +@@ -26,8 +26,9 @@ + { __atomic_store_n((DST), (SRC), __ATOMIC_SEQ_CST); } + #endif + +-#if defined(__gfx1100__) || defined(__gfx1101__) || defined(__gfx1102__) || defined(__gfx1200__) || defined(__gfx1201__) +-#define __trace_hwreg() ++#if defined(__GFX10__) || defined(__GFX11__) || defined(__GFX12__) ++#define __trace_hwreg() \ ++ asm volatile ("s_getreg_b32 %0, hwreg(HW_REG_HW_ID1)" : "=s" (collTrace->data_0)); + #else + #define __trace_hwreg() \ + asm volatile ("s_getreg_b32 %0, hwreg(HW_REG_HW_ID)" : "=s" (collTrace->data_0)); +diff --git a/tools/JitterBench/Common.hpp b/tools/JitterBench/Common.hpp +index bad12a1b..b59856a8 100644 +--- a/tools/JitterBench/Common.hpp ++++ b/tools/JitterBench/Common.hpp +@@ -43,9 +43,9 @@ THE SOFTWARE. + #endif + + // Macro for collecting HW_REG_HW_ID +-#if defined(__gfx1100__) || defined(__gfx1101__) || defined(__gfx1102__) || defined(__NVCC__) ++#if defined(__GFX10__) || defined(__GFX11__) || defined(__GFX12__) + #define GetHwId(val) \ +- val = 0 ++ asm volatile ("s_getreg_b32 %0, hwreg(HW_REG_HW_ID1)" : "=s" (val)); + #else + #define GetHwId(val) \ + asm volatile ("s_getreg_b32 %0, hwreg(HW_REG_HW_ID)" : "=s" (val)); diff --git a/.devops/nix/rocm-modules-10/rccl/rccl-test-missing-iomanip.diff b/.devops/nix/rocm-modules-10/rccl/rccl-test-missing-iomanip.diff new file mode 100644 index 0000000000..3cc54a83c1 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rccl/rccl-test-missing-iomanip.diff @@ -0,0 +1,10 @@ +--- a/test/common/TestBed.cpp ++++ b/test/common/TestBed.cpp +@@ -4,6 +4,7 @@ + * See LICENSE.txt for license information + ************************************************************************/ + #include ++#include + #include "TestBed.hpp" + #include + diff --git a/.devops/nix/rocm-modules-10/rdc/default.nix b/.devops/nix/rocm-modules-10/rdc/default.nix new file mode 100644 index 0000000000..c343a13706 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rdc/default.nix @@ -0,0 +1,150 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + pkg-config, + amdsmi, + rocm-smi, + rocm-runtime, + libcap, + libdrm, + grpc, + protobuf, + openssl, + doxygen, + graphviz, + texliveSmall, + gtest, + buildDocs ? true, + buildTests ? false, +}: + +let + latex = lib.optionalAttrs buildDocs ( + texliveSmall.withPackages ( + ps: with ps; [ + changepage + latexmk + varwidth + multirow + hanging + adjustbox + collectbox + stackengine + enumitem + alphalph + wasysym + sectsty + tocloft + newunicodechar + etoc + helvetic + wasy + courier + ] + ) + ); +in +stdenv.mkDerivation (finalAttrs: { + pname = "rdc"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildDocs [ + "doc" + ] + ++ lib.optionals buildTests [ + "test" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rdc" + "shared" + ]; + hash = "sha256-SmySauRxFnEQJVTjGYf4TpmQclTwZG2RZrk3u6ko5Qo="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rdc"; + + patches = [ + # https://github.com/ROCm/rocm-systems/pull/2423 + ./fix-cmake-cxxflags.patch + # https://github.com/ROCm/rocm-systems/pull/2424 + ./fix-libcap-pkgconfig.patch + ]; + + nativeBuildInputs = [ + cmake + pkg-config + protobuf + ] + ++ lib.optionals buildDocs [ + doxygen + graphviz + latex + ]; + + buildInputs = [ + amdsmi + rocm-smi + rocm-runtime + libcap + libdrm + grpc + openssl + ] + ++ lib.optionals buildTests [ + gtest + ]; + + cmakeFlags = [ + "-DCMAKE_VERBOSE_MAKEFILE=ON" + "-DRDC_INSTALL_PREFIX=${placeholder "out"}" + "-DBUILD_RVS=OFF" # TODO: Needs RVS package + "-DBUILD_ROCRTEST=ON" + "-DRSMI_INC_DIR=${rocm-smi}/include" + "-DRSMI_LIB_DIR=${rocm-smi}/lib" + "-DGRPC_ROOT=${grpc}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_INSTALL_LIBEXECDIR=libexec" + "-DCMAKE_INSTALL_DOCDIR=doc" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TESTS=ON" + ]; + + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace-fail "file(STRINGS /etc/os-release LINUX_DISTRO LIMIT_COUNT 1 REGEX \"NAME=\")" "set(LINUX_DISTRO \"NixOS\")" + ''; + + postInstall = '' + find $out/bin -executable -type f -exec \ + patchelf {} --shrink-rpath --allowed-rpath-prefixes "$NIX_STORE" \; + '' + + lib.optionalString buildTests '' + mkdir -p $test + mv $out/bin/rdctst_tests $test/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Simplifies administration and addresses infrastructure challenges in cluster and datacenter environments"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rdc"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rdc/fix-cmake-cxxflags.patch b/.devops/nix/rocm-modules-10/rdc/fix-cmake-cxxflags.patch new file mode 100644 index 0000000000..bf7f3dbb0e --- /dev/null +++ b/.devops/nix/rocm-modules-10/rdc/fix-cmake-cxxflags.patch @@ -0,0 +1,217 @@ +From 92f25181dbf722cb749e445851580df4ea779299 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Sun, 21 Dec 2025 08:01:08 -0800 +Subject: [PATCH 1/2] fix(rdc): set CMAKE_CXX_FLAGS after project() to avoid + clobbering env + +CMAKE_CXX_FLAGS' initial value is set from $CXXFLAGS on project() call +so the previous location ignored CXXFLAGS from env or CMake toolchain +config. + +Ref: https://cmake.org/cmake/help/v4.2/variable/CMAKE_LANG_FLAGS_INIT.html +Fixes: 874a7b438f ("CMAKE - Fix build types") +--- + CMakeLists.txt | 48 +++++++++++++++++++------------------ + 1 file changed, 25 insertions(+), 23 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 907c9fbff42..8b386c7be3d 100755 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -55,29 +55,6 @@ set_property( + PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel" + ) + +-# Set compile flags +-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64 -msse -msse2") +-set(CMAKE_CXX_FLAGS_DEBUG +- "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -DDEBUG" +- CACHE STRING +- "Flags for Debug builds" +-) +-set(CMAKE_CXX_FLAGS_RELEASE +- "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s -DNDEBUG" +- CACHE STRING +- "Flags for Release builds" +-) +-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO +- "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG" +- CACHE STRING +- "Flags for RelWithDebInfo builds" +-) +-set(CMAKE_CXX_FLAGS_MINSIZEREL +- "${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG" +- CACHE STRING +- "Flags for MinSizeRel builds" +-) +- + set(CMAKE_MODULE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/" + CACHE INTERNAL +@@ -155,6 +132,31 @@ project(${RDC} VERSION "${VERSION_STRING}" HOMEPAGE_URL "https://github.com/Rade + # this must go after project() + include(GNUInstallDirs) + ++# NB: CMAKE__FLAGS are initialized from environment (CXXFLAGS et al.) ++# during project(). Setting them before project() discards env and toolchain ++# defaults. Cf. CMAKE__FLAGS_INIT for toolchain overrides. ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64 -msse -msse2") ++set(CMAKE_CXX_FLAGS_DEBUG ++ "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -DDEBUG" ++ CACHE STRING ++ "Flags for Debug builds" ++) ++set(CMAKE_CXX_FLAGS_RELEASE ++ "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s -DNDEBUG" ++ CACHE STRING ++ "Flags for Release builds" ++) ++set(CMAKE_CXX_FLAGS_RELWITHDEBINFO ++ "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG" ++ CACHE STRING ++ "Flags for RelWithDebInfo builds" ++) ++set(CMAKE_CXX_FLAGS_MINSIZEREL ++ "${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG" ++ CACHE STRING ++ "Flags for MinSizeRel builds" ++) ++ + set(COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/common") + + set(GRPC_ROOT_DEFAULT "/usr") + +From 0c8710c3570963b29c709b1cd1f78b15fd73a950 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Sun, 21 Dec 2025 08:13:04 -0800 +Subject: [PATCH 2/2] fix(rdc): don't reimplement CMake default build type flag + logic + +The previous approach was overly complicated and added nothing. CMake already defaults +similar flags for each of the default supported build types. +Additionally, the previous flags broke AArch64 as -m64 -msse are incompatible. +It's not necessary to explicitly set this with modern toolchains. + +Fixes: 874a7b438f ("CMAKE - Fix build types") +Fixes: bc7f01e992 ("Initial RDC commit") +--- + CMakeLists.txt | 25 +--------------------- + example/CMakeLists.txt | 26 ++--------------------- + tests/example/CMakeLists.txt | 24 +-------------------- + 3 files changed, 4 insertions(+), 71 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 8b386c7be3d..251fcddd653 100755 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -132,30 +132,7 @@ project(${RDC} VERSION "${VERSION_STRING}" HOMEPAGE_URL "https://github.com/Rade + # this must go after project() + include(GNUInstallDirs) + +-# NB: CMAKE__FLAGS are initialized from environment (CXXFLAGS et al.) +-# during project(). Setting them before project() discards env and toolchain +-# defaults. Cf. CMAKE__FLAGS_INIT for toolchain overrides. +-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64 -msse -msse2") +-set(CMAKE_CXX_FLAGS_DEBUG +- "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -DDEBUG" +- CACHE STRING +- "Flags for Debug builds" +-) +-set(CMAKE_CXX_FLAGS_RELEASE +- "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s -DNDEBUG" +- CACHE STRING +- "Flags for Release builds" +-) +-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO +- "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG" +- CACHE STRING +- "Flags for RelWithDebInfo builds" +-) +-set(CMAKE_CXX_FLAGS_MINSIZEREL +- "${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG" +- CACHE STRING +- "Flags for MinSizeRel builds" +-) ++add_compile_options(-Wall -Wextra) + + set(COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/common") + +diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt +index 378a2005818..7c51307ec38 100755 +--- a/example/CMakeLists.txt ++++ b/example/CMakeLists.txt +@@ -31,30 +31,6 @@ cmake_minimum_required(VERSION 3.15) + option(CMAKE_VERBOSE_MAKEFILE "Enable verbose output" ON) + option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile commands for linters and autocompleters" ON) + +-# Set compile flags +-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64 -msse -msse2") +-set(CMAKE_CXX_FLAGS_DEBUG +- "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -DDEBUG" +- CACHE STRING +- "Flags for Debug builds" +-) +-# note: no '-s' here unlike other CMakeLists.txt +-set(CMAKE_CXX_FLAGS_RELEASE +- "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG" +- CACHE STRING +- "Flags for Release builds" +-) +-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO +- "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG" +- CACHE STRING +- "Flags for RelWithDebInfo builds" +-) +-set(CMAKE_CXX_FLAGS_MINSIZEREL +- "${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG" +- CACHE STRING +- "Flags for MinSizeRel builds" +-) +- + set(CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard to use") + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) +@@ -66,6 +42,8 @@ endif() + + project(RDC_example) + ++add_compile_options(-Wall -Wextra) ++ + # provides cmake_print_variables(VAR) + include(CMakePrintHelpers) + +diff --git a/tests/example/CMakeLists.txt b/tests/example/CMakeLists.txt +index d5614f387bd..13c2f3857a1 100755 +--- a/tests/example/CMakeLists.txt ++++ b/tests/example/CMakeLists.txt +@@ -22,29 +22,7 @@ message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") + message(" Cmake Example Lib ") + message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") + +-# Set compile flags +-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64 -msse -msse2") +-set(CMAKE_CXX_FLAGS_DEBUG +- "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -DDEBUG" +- CACHE STRING +- "Flags for Debug builds" +-) +-# note: no '-s' here unlike other CMakeLists.txt +-set(CMAKE_CXX_FLAGS_RELEASE +- "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG" +- CACHE STRING +- "Flags for Release builds" +-) +-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO +- "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG" +- CACHE STRING +- "Flags for RelWithDebInfo builds" +-) +-set(CMAKE_CXX_FLAGS_MINSIZEREL +- "${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG" +- CACHE STRING +- "Flags for MinSizeRel builds" +-) ++add_compile_options(-Wall -Wextra) + + # Required Defines first: + diff --git a/.devops/nix/rocm-modules-10/rdc/fix-libcap-pkgconfig.patch b/.devops/nix/rocm-modules-10/rdc/fix-libcap-pkgconfig.patch new file mode 100644 index 0000000000..54e7303ce8 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rdc/fix-libcap-pkgconfig.patch @@ -0,0 +1,57 @@ +From 299f2c770ff0abf07b8f394f154168d2aa78aa60 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Sun, 21 Dec 2025 08:23:01 -0800 +Subject: [PATCH] fix(rdc): use pkg-config to find libcap + +If libcap isn't available in system wide FHS include paths building would fail. +Fix this by using pkg-config to find libcap which provides both the library +to link and include dirs. +--- + CMakeLists.txt | 6 +++--- + rdc_libs/rdc/CMakeLists.txt | 2 +- + server/CMakeLists.txt | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 907c9fbff42..00e0a9dd87d 100755 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -192,9 +192,9 @@ mark_as_advanced( + CPACK_GENERATOR + ) + +-# check if libcap exists +-# needed for sys/capabilities.h +-find_library(LIB_CAP NAMES cap REQUIRED) ++# needed for sys/capability.h ++find_package(PkgConfig REQUIRED) ++pkg_check_modules(LIBCAP REQUIRED IMPORTED_TARGET libcap) + + if(BUILD_STANDALONE AND GRPC_ROOT STREQUAL GRPC_ROOT_DEFAULT) + message( +diff --git a/rdc_libs/rdc/CMakeLists.txt b/rdc_libs/rdc/CMakeLists.txt +index d4e368edca5..f9a3ac4c487 100644 +--- a/rdc_libs/rdc/CMakeLists.txt ++++ b/rdc_libs/rdc/CMakeLists.txt +@@ -71,7 +71,7 @@ set(RDC_LIB_INC_LIST + message("RDC_LIB_INC_LIST=${RDC_LIB_INC_LIST}") + + add_library(${RDC_LIB} SHARED ${RDC_LIB_SRC_LIST} ${RDC_LIB_INC_LIST}) +-target_link_libraries(${RDC_LIB} ${BOOTSTRAP_LIB} pthread amd_smi cap) ++target_link_libraries(${RDC_LIB} ${BOOTSTRAP_LIB} pthread amd_smi PkgConfig::LIBCAP) + target_include_directories( + ${RDC_LIB} + PRIVATE "${PROJECT_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}/include" "${AMD_SMI_INCLUDE_DIR}" +diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt +index baf0d851c86..0a6e71dda1c 100755 +--- a/server/CMakeLists.txt ++++ b/server/CMakeLists.txt +@@ -97,7 +97,7 @@ target_link_libraries( + pthread + rt + gRPC::grpc++ +- cap ++ PkgConfig::LIBCAP + dl + amd_smi + rdc_bootstrap diff --git a/.devops/nix/rocm-modules-10/release-attrPaths-gen.nix b/.devops/nix/rocm-modules-10/release-attrPaths-gen.nix new file mode 100644 index 0000000000..074cf2fe4c --- /dev/null +++ b/.devops/nix/rocm-modules-10/release-attrPaths-gen.nix @@ -0,0 +1,36 @@ +{ + variant, +}: +let + pkgs = import ../../../. { config.allowAliases = false; }; + lib = pkgs.lib; + optionalsWithSuccess = + toTry: next: + let + tried = builtins.tryEval toTry; + in + lib.optionals tried.success (next tried.value); + findAll = + path: obj: + optionalsWithSuccess obj ( + obj: + if obj ? outPath then + optionalsWithSuccess obj.outPath or null ( + outPath: + # filter out unavailable, broken packages, and drvs with broken deps + lib.optional (!((obj ? meta) && (!obj.meta.available or false || obj.meta.broken))) { + p = path; + o = outPath; + } + ) + else if (obj.recurseForDerivations or false) || (obj.recurseForRelease or false) then + lib.concatLists ( + lib.mapAttrsToList ( + name: value: findAll (if path == null then name else path + "." + name) value + ) obj + ) + else + [ ] + ); +in +findAll null (pkgs.${variant} // { recurseForDerivations = true; }) diff --git a/.devops/nix/rocm-modules-10/release-attrPaths-gen.sh b/.devops/nix/rocm-modules-10/release-attrPaths-gen.sh new file mode 100644 index 0000000000..81ac83cfa4 --- /dev/null +++ b/.devops/nix/rocm-modules-10/release-attrPaths-gen.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p jq nixVersions.latest +set -euo pipefail + +# Generate a list of attr paths that are different when enableRocm = true +# Special case python3*Packages to only build the default python3Packages +rocmDir=$(dirname "$(realpath "$0")") + +pkgsTmp=$(mktemp) +pkgsRocmTmp=$(mktemp) +trap "rm -f $pkgsTmp $pkgsRocmTmp" EXIT + +echo "Generating attrPaths to compare for pkgs and pkgsRocm" >&2 + +{ + nix-instantiate --eval --strict --json "$rocmDir/release-attrPaths-gen.nix" \ + --argstr variant pkgs > "$pkgsTmp" & + nix-instantiate --eval --strict --json "$rocmDir/release-attrPaths-gen.nix" \ + --argstr variant pkgsRocm > "$pkgsRocmTmp" & + wait +} + +<"$pkgsRocmTmp" >"$rocmDir/release-attrPaths.json" jq --slurpfile def "$pkgsTmp" ' +{ + "__generatedBy": "'"$0"'", + "attrPaths": [ + ($def[0] | map({(.p): .o}) | add) as $def_map | + .[] | + select( + ($def_map[.p] == null) or + ($def_map[.p] != .o) + ) | + .p | + gsub("python3\\d+Packages"; "python3Packages") + ] | unique +} +' + +echo "Generated $rocmDir/release-attrPaths.json" >&2 diff --git a/.devops/nix/rocm-modules-10/release-attrPaths.json b/.devops/nix/rocm-modules-10/release-attrPaths.json new file mode 100644 index 0000000000..edd4c76adc --- /dev/null +++ b/.devops/nix/rocm-modules-10/release-attrPaths.json @@ -0,0 +1,680 @@ +{ + "__generatedBy": "pkgs/development/rocm-modules/release-attrPaths-gen.sh", + "attrPaths": [ + "adaptivecpp", + "adios2", + "adoptopenjdk-icedtea-web", + "aider-chat-full", + "aider-chat-with-help", + "aitrack", + "alpaca", + "ants", + "appcsxcad", + "arpack-mpi", + "audiobookshelf", + "auto-editor", + "babeldoc", + "backgroundremover", + "bambuddy", + "blender", + "blendfarm", + "btop", + "btop-cuda", + "c3d", + "calibre", + "calibre-no-speech", + "catalyst", + "chatd", + "chickenPackages_5.chickenEggs.mpi", + "cloudcompare", + "colmap", + "contact", + "convertx", + "costa", + "cp2k", + "credsweeper", + "crewai", + "crow-translate", + "csxcad", + "dbcsr", + "deface", + "displaycal", + "dl-poly-classic-mpi", + "dolfinx", + "dtcmp", + "easyocr", + "elastix", + "elmerfem", + "elpa", + "escrotum", + "exhibit", + "exo", + "ezminc", + "f3d", + "ffcast", + "ffmpeg-full", + "ffmpeg_8-full", + "fftwMpi", + "firefox", + "firefox-beta", + "firefox-beta-unwrapped", + "firefox-devedition", + "firefox-devedition-unwrapped", + "firefox-esr-153", + "firefox-esr-153-unwrapped", + "firefox-mobile", + "firefox-unwrapped", + "firefoxpwa", + "firefoxpwa-unwrapped", + "fotema", + "freecad", + "frigate", + "gdcm", + "getdp", + "giph", + "git-sim", + "globalarrays", + "gromacsDoubleMpi", + "gromacsMpi", + "handbrake", + "handy", + "hashcat", + "haskellPackages.mpi-hs", + "haskellPackages.mpi-hs-binary", + "haskellPackages.mpi-hs-cereal", + "haskellPackages.mpi-hs-store", + "hdf5-fortran-mpi", + "hdf5-mpi", + "heretic", + "hieroglyphic", + "highfive-mpi", + "hns", + "howdy", + "hp2p", + "hpcg", + "hpl", + "hypre", + "hyprwhspr-rs", + "icm", + "ieda", + "imagination", + "immich-machine-learning", + "intel-llvm", + "ior", + "itk", + "itk_5", + "itk_5_2", + "kagen", + "kahip", + "kaminpar", + "kdePackages.kdenlive", + "kikoplay", + "lammps-mpi", + "libcircle", + "libmbd", + "libretranslate", + "librewolf", + "librewolf-unwrapped", + "libsupermesh", + "libvdwxc", + "linux-enable-ir-emitter", + "liquidsoap", + "livecaptions", + "llama-cpp", + "llama-cpp-vulkan", + "lms", + "lwgrp", + "maa-assistant-arknights", + "maa-cli", + "magika", + "magika-cli", + "manim", + "manim-slides", + "markitdown", + "markitdown-mcp", + "meshtastic", + "midivisualizer", + "migrate", + "mirtk", + "mokuro", + "monado", + "mpi", + "mpifileutils", + "mrtrix", + "mumps-mpi", + "murmure", + "music-assistant", + "mvapich", + "nest-mpi", + "netcdf-mpi", + "netgen", + "neuron-mpi", + "newelle", + "nwchem", + "obliteratus", + "obs-studio-plugins.obs-backgroundremoval", + "octavePackages.dicom", + "octopus", + "ollama", + "onedpl", + "onnxruntime", + "openai-whisper", + "openems", + "openmpi", + "openseeface", + "opensplat", + "opentrack", + "optiland", + "osu-micro-benchmarks", + "otb", + "oven-media-engine", + "owocr", + "p4est", + "p4est-dbg", + "p4est-sc", + "p4est-sc-dbg", + "paperless-ngx", + "paraview", + "parmmg", + "pcl", + "pdi", + "peek", + "petsc", + "pfft", + "pianotrans", + "piper-phonemize", + "piper-tts", + "pnetcdf", + "pnfft", + "pocket-tts", + "precice", + "printrun", + "python3Packages.accelerate", + "python3Packages.adios2", + "python3Packages.albumentationsx", + "python3Packages.ale-py", + "python3Packages.amd-aiter", + "python3Packages.amd-quark", + "python3Packages.anndata", + "python3Packages.apptools", + "python3Packages.apricot-select", + "python3Packages.argos-translate-files", + "python3Packages.argostranslate", + "python3Packages.array-api-compat", + "python3Packages.array-record", + "python3Packages.arviz", + "python3Packages.arviz-plots", + "python3Packages.asteroid-filterbanks", + "python3Packages.attacut", + "python3Packages.augmax", + "python3Packages.ax-platform", + "python3Packages.bambi", + "python3Packages.baselines", + "python3Packages.beat-this", + "python3Packages.bitsandbytes", + "python3Packages.blosc2", + "python3Packages.botorch", + "python3Packages.brax", + "python3Packages.captum", + "python3Packages.catalyst", + "python3Packages.causal-conv1d", + "python3Packages.chromadb", + "python3Packages.clean-fid", + "python3Packages.cleanlab", + "python3Packages.cleanvision", + "python3Packages.clip", + "python3Packages.clip-anytorch", + "python3Packages.cltk", + "python3Packages.clu", + "python3Packages.cnvkit", + "python3Packages.colbert-ai", + "python3Packages.compressai", + "python3Packages.compressed-tensors", + "python3Packages.conduit", + "python3Packages.conduit-mpi", + "python3Packages.corner", + "python3Packages.crawl4ai", + "python3Packages.credsweeper", + "python3Packages.crewai", + "python3Packages.ctranslate2", + "python3Packages.curated-transformers", + "python3Packages.cut-cross-entropy", + "python3Packages.cvxpy", + "python3Packages.daft", + "python3Packages.dask-mpi", + "python3Packages.dctorch", + "python3Packages.deepdish", + "python3Packages.deepface", + "python3Packages.deepsearch-toolkit", + "python3Packages.deepwave", + "python3Packages.detectron2", + "python3Packages.dicom2nifti", + "python3Packages.diffusers", + "python3Packages.distrax", + "python3Packages.dm-control", + "python3Packages.dm-sonnet", + "python3Packages.docling-core", + "python3Packages.docling-ibm-models", + "python3Packages.e3nn", + "python3Packages.easyocr", + "python3Packages.edward", + "python3Packages.effdet", + "python3Packages.einops", + "python3Packages.emsutil", + "python3Packages.encodec", + "python3Packages.envisage", + "python3Packages.etils", + "python3Packages.evosax", + "python3Packages.executorch", + "python3Packages.experiment-utilities", + "python3Packages.f3d", + "python3Packages.facenet-pytorch", + "python3Packages.fairscale", + "python3Packages.fast-simplification", + "python3Packages.fastai", + "python3Packages.fastembed", + "python3Packages.faster-whisper", + "python3Packages.fastmri", + "python3Packages.fenics-dolfinx", + "python3Packages.fickling", + "python3Packages.finetuning-scheduler", + "python3Packages.firedrake", + "python3Packages.fireworks-ai", + "python3Packages.flammkuchen", + "python3Packages.flash-linear-attention", + "python3Packages.flax", + "python3Packages.flowjax", + "python3Packages.flyingsquid", + "python3Packages.funsor", + "python3Packages.fvcore", + "python3Packages.gdcm", + "python3Packages.gdsfactory", + "python3Packages.geotorch", + "python3Packages.gliner", + "python3Packages.gluonts", + "python3Packages.gpaw", + "python3Packages.gpuctypes", + "python3Packages.gpytorch", + "python3Packages.grad-cam", + "python3Packages.gradio", + "python3Packages.graphtage", + "python3Packages.gstools", + "python3Packages.guidance", + "python3Packages.gymnasium", + "python3Packages.h5io", + "python3Packages.h5py-mpi", + "python3Packages.helium", + "python3Packages.heretic-llm", + "python3Packages.hoomd-blue", + "python3Packages.hoptorch", + "python3Packages.hyper-connections", + "python3Packages.ignite", + "python3Packages.imagededup", + "python3Packages.imgcat", + "python3Packages.insightface", + "python3Packages.invisible-watermark", + "python3Packages.iopath", + "python3Packages.itk", + "python3Packages.jaxopt", + "python3Packages.julius", + "python3Packages.k-diffusion", + "python3Packages.kahip", + "python3Packages.keras", + "python3Packages.kokoro", + "python3Packages.kornia", + "python3Packages.kornia-rs", + "python3Packages.kserve", + "python3Packages.lancedb", + "python3Packages.langchain-chroma", + "python3Packages.langchain-fireworks", + "python3Packages.langchain-huggingface", + "python3Packages.layoutparser", + "python3Packages.lerobot", + "python3Packages.libretranslate", + "python3Packages.libsupermesh", + "python3Packages.liger-kernel", + "python3Packages.lightning", + "python3Packages.linear-operator", + "python3Packages.lion-pytorch", + "python3Packages.llama-cloud", + "python3Packages.llama-index", + "python3Packages.llama-index-cli", + "python3Packages.llama-index-core", + "python3Packages.llama-index-embeddings-google-genai", + "python3Packages.llama-index-embeddings-huggingface", + "python3Packages.llama-index-embeddings-ollama", + "python3Packages.llama-index-embeddings-openai", + "python3Packages.llama-index-embeddings-openai-like", + "python3Packages.llama-index-graph-stores-neo4j", + "python3Packages.llama-index-graph-stores-neptune", + "python3Packages.llama-index-legacy", + "python3Packages.llama-index-llms-ollama", + "python3Packages.llama-index-llms-openai", + "python3Packages.llama-index-llms-openai-like", + "python3Packages.llama-index-node-parser-docling", + "python3Packages.llama-index-readers-database", + "python3Packages.llama-index-readers-file", + "python3Packages.llama-index-readers-json", + "python3Packages.llama-index-readers-s3", + "python3Packages.llama-index-readers-twitter", + "python3Packages.llama-index-readers-txtai", + "python3Packages.llama-index-readers-weather", + "python3Packages.llama-index-vector-stores-chroma", + "python3Packages.llama-index-vector-stores-faiss", + "python3Packages.llama-index-vector-stores-google", + "python3Packages.llama-index-vector-stores-milvus", + "python3Packages.llama-index-vector-stores-postgres", + "python3Packages.llama-index-vector-stores-qdrant", + "python3Packages.llguidance", + "python3Packages.llm-sentence-transformers", + "python3Packages.lm-eval", + "python3Packages.local-attention", + "python3Packages.lpips", + "python3Packages.mace-torch", + "python3Packages.magika", + "python3Packages.manga-ocr", + "python3Packages.manifest-ml", + "python3Packages.manim", + "python3Packages.manimgl", + "python3Packages.markitdown", + "python3Packages.mayavi", + "python3Packages.mdtraj", + "python3Packages.medpy", + "python3Packages.medvol", + "python3Packages.meep", + "python3Packages.meshtastic", + "python3Packages.mflux", + "python3Packages.mhcflurry", + "python3Packages.mim-solvers", + "python3Packages.minari", + "python3Packages.minisbd", + "python3Packages.mistral-common", + "python3Packages.mlcroissant", + "python3Packages.mlx-lm", + "python3Packages.mlx-vlm", + "python3Packages.mmcv", + "python3Packages.mmengine", + "python3Packages.mne", + "python3Packages.moderngl-window", + "python3Packages.monai", + "python3Packages.monotonic-alignment-search", + "python3Packages.monty", + "python3Packages.mpi-pytest", + "python3Packages.mpi4py", + "python3Packages.mtcnn", + "python3Packages.mujoco", + "python3Packages.mujoco-mjx", + "python3Packages.multiscale-spatial-image", + "python3Packages.muon-optimizer", + "python3Packages.napari-nifti", + "python3Packages.nest", + "python3Packages.netgen-mesher", + "python3Packages.ngff-zarr", + "python3Packages.nianet", + "python3Packages.nifty8", + "python3Packages.nnaudio", + "python3Packages.noisereduce", + "python3Packages.numpyro", + "python3Packages.nutpie", + "python3Packages.nvdlfw-inspect", + "python3Packages.onnx-asr", + "python3Packages.onnx-ir", + "python3Packages.onnxruntime", + "python3Packages.onnxscript", + "python3Packages.open-clip-torch", + "python3Packages.openai-whisper", + "python3Packages.opencv4Full", + "python3Packages.openmm-torch", + "python3Packages.opt-einsum-fx", + "python3Packages.optiland", + "python3Packages.optimum", + "python3Packages.optimum-onnx", + "python3Packages.optuna", + "python3Packages.optuna-dashboard", + "python3Packages.orbax-checkpoint", + "python3Packages.orbax-export", + "python3Packages.osqp", + "python3Packages.outlines", + "python3Packages.outlines-core", + "python3Packages.paddlepaddle", + "python3Packages.pandantic", + "python3Packages.pandas-stubs", + "python3Packages.pandera", + "python3Packages.pdfplumber", + "python3Packages.peacasso", + "python3Packages.peft", + "python3Packages.pepit", + "python3Packages.petsc4py", + "python3Packages.petsctools", + "python3Packages.pettingzoo", + "python3Packages.pgmpy", + "python3Packages.piano-transcription-inference", + "python3Packages.piper-phonemize", + "python3Packages.pocket-tts", + "python3Packages.pomegranate", + "python3Packages.pyannote-audio", + "python3Packages.pyannote-pipeline", + "python3Packages.pyg-lib", + "python3Packages.pyglet", + "python3Packages.pykrige", + "python3Packages.pylance", + "python3Packages.pymanopt", + "python3Packages.pymc", + "python3Packages.pymedio", + "python3Packages.pymoo", + "python3Packages.pyotb", + "python3Packages.pypasser", + "python3Packages.pyprecice", + "python3Packages.pyradiomics", + "python3Packages.pyrender", + "python3Packages.pyro-ppl", + "python3Packages.pysbd", + "python3Packages.pyseries", + "python3Packages.pytensor", + "python3Packages.python-csxcad", + "python3Packages.pytmx", + "python3Packages.pytorch-bench", + "python3Packages.pytorch-lightning", + "python3Packages.pytorch-memlab", + "python3Packages.pytorch-metric-learning", + "python3Packages.pytorch-msssim", + "python3Packages.pytorch-pfn-extras", + "python3Packages.pytorch-tabnet", + "python3Packages.pytorch-tokenizers", + "python3Packages.pytorch3d", + "python3Packages.pytorchviz", + "python3Packages.pyvista", + "python3Packages.qpsolvers", + "python3Packages.qutip", + "python3Packages.rapidocr", + "python3Packages.rapidocr-onnxruntime", + "python3Packages.rembg", + "python3Packages.rerun-sdk", + "python3Packages.resize-right", + "python3Packages.retinaface", + "python3Packages.rlax", + "python3Packages.rlcard", + "python3Packages.roma", + "python3Packages.rotary-embedding-torch", + "python3Packages.safetensors", + "python3Packages.sam2", + "python3Packages.scanpy", + "python3Packages.scikit-bio", + "python3Packages.scikit-survival", + "python3Packages.sentence-transformers", + "python3Packages.shap", + "python3Packages.sherpa-onnx", + "python3Packages.shimmy", + "python3Packages.silero-vad", + "python3Packages.simpleitk", + "python3Packages.sirius", + "python3Packages.skorch", + "python3Packages.skrl", + "python3Packages.slepc4py", + "python3Packages.slicer", + "python3Packages.smolagents", + "python3Packages.snorkel", + "python3Packages.spacy", + "python3Packages.spacy-curated-transformers", + "python3Packages.spacy-loggers", + "python3Packages.spacy-lookups-data", + "python3Packages.spacy-transformers", + "python3Packages.speechbrain", + "python3Packages.speechrecognition", + "python3Packages.stable-baselines3", + "python3Packages.stanza", + "python3Packages.staticvectors", + "python3Packages.stytra", + "python3Packages.syne-tune", + "python3Packages.tables", + "python3Packages.tami4edgeapi", + "python3Packages.tensorboardx", + "python3Packages.tensordict", + "python3Packages.tensorflow-datasets", + "python3Packages.tensorflow-probability", + "python3Packages.textacy", + "python3Packages.textnets", + "python3Packages.tf2onnx", + "python3Packages.tianshou", + "python3Packages.tilelang", + "python3Packages.timm", + "python3Packages.tinygrad", + "python3Packages.torch", + "python3Packages.torch-audiomentations", + "python3Packages.torch-c-dlpack-ext", + "python3Packages.torch-cluster", + "python3Packages.torch-einops-utils", + "python3Packages.torch-ema", + "python3Packages.torch-geometric", + "python3Packages.torch-no-triton", + "python3Packages.torch-pitch-shift", + "python3Packages.torch-tb-profiler", + "python3Packages.torchWithVulkan", + "python3Packages.torchWithoutCuda", + "python3Packages.torchao", + "python3Packages.torchaudio", + "python3Packages.torchbench", + "python3Packages.torchcodec", + "python3Packages.torchcrepe", + "python3Packages.torchdata", + "python3Packages.torchdiffeq", + "python3Packages.torchinfo", + "python3Packages.torchio", + "python3Packages.torchlibrosa", + "python3Packages.torchmd-net", + "python3Packages.torchmetrics", + "python3Packages.torchprofile", + "python3Packages.torchrl", + "python3Packages.torchsde", + "python3Packages.torchsnapshot", + "python3Packages.torchsummary", + "python3Packages.torchtitan", + "python3Packages.torchtnt", + "python3Packages.torchvision", + "python3Packages.trainer", + "python3Packages.transformers", + "python3Packages.translatehtml", + "python3Packages.treescope", + "python3Packages.trl", + "python3Packages.ttach", + "python3Packages.txtai", + "python3Packages.ultralytics", + "python3Packages.ultralytics-thop", + "python3Packages.unsloth", + "python3Packages.unsloth-zoo", + "python3Packages.unstructured-inference", + "python3Packages.viser", + "python3Packages.vllm", + "python3Packages.vmas", + "python3Packages.vtk", + "python3Packages.wandb", + "python3Packages.warp-nn", + "python3Packages.webdataset", + "python3Packages.whisperx", + "python3Packages.x-transformers", + "python3Packages.xarray-einstats", + "python3Packages.xformers", + "python3Packages.xgrammar", + "qcsxcad", + "quantum-espresso", + "rabbit-ng", + "ramalama", + "rapidraw", + "raxml-mpi", + "rclip", + "rembg", + "restream", + "rlama", + "rofi-screenshot", + "rtabmap", + "scalapack", + "scalapack-ilp64", + "scipopt-ug", + "seagoat", + "sherpa-onnx", + "siesta", + "siesta-mpi", + "simpleitk", + "sirius", + "sitespeed-io", + "slepc", + "spfft", + "spla", + "stable-diffusion-cpp", + "stable-diffusion-cpp-vulkan", + "superlu_dist", + "tabby", + "tests.home-assistant-components.tami4", + "tests.pkg-config.defaultPkgConfigPackages.ompi", + "tests.pkg-config.defaultPkgConfigPackages.ompi-c", + "tests.pkg-config.defaultPkgConfigPackages.ompi-cxx", + "tests.pkg-config.defaultPkgConfigPackages.ompi-f77", + "tests.pkg-config.defaultPkgConfigPackages.ompi-f90", + "tests.pkg-config.defaultPkgConfigPackages.ompi-fort", + "tests.pkg-config.defaultPkgConfigPackages.tests-combined", + "tests.testers.hasCmakeConfigModules.boost-has-boost_mpi", + "tests.testers.hasCmakeConfigModules.boost_mpi-does-not-have-mpi", + "therion", + "thunderbird", + "thunderbird-153", + "thunderbird-153-unwrapped", + "thunderbird-latest", + "thunderbird-latest-unwrapped", + "thunderbird-unwrapped", + "thunderbirdPackages.thunderbird", + "thunderbirdPackages.thunderbird-153", + "thunderbirdPackages.thunderbird-latest", + "tmpi", + "tocpdf", + "tone", + "trilinos-mpi", + "tt-metal", + "ucc", + "ucx", + "ultralytics", + "umpire", + "unbook", + "unstructured-api", + "vcmi", + "vectorcode", + "vimPlugins.vectorcode-nvim", + "viskores", + "vllm", + "voxtype-onnx", + "vtk", + "vtk-dicom", + "vtk-full", + "vtkWithQt6", + "vtk_9_5", + "vtk_9_6", + "whisper-cpp", + "whisper-cpp-vulkan", + "whisper-ctranslate2", + "whisperx", + "wifite2", + "wlr-layout-ui", + "wyoming-faster-whisper", + "wyoming-piper", + "xyce-parallel" + ] +} diff --git a/.devops/nix/rocm-modules-10/rocalution/default.nix b/.devops/nix/rocm-modules-10/rocalution/default.nix new file mode 100644 index 0000000000..8dd8079632 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocalution/default.nix @@ -0,0 +1,122 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocblas, + rocsparse, + rocprim, + rocrand, + clr, + pkg-config, + openmp, + openmpi, + gtest, + buildTests ? false, + buildBenchmarks ? false, + buildSamples ? false, + gpuTargets ? clr.localGpuTargets or [ ], # gpuTargets = [ "gfx803" "gfx900:xnack-" "gfx906:xnack-" ... ] +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocalution"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ] + ++ lib.optionals buildSamples [ + "sample" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocALUTION"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-yPM26e8tGNpPScIriAPRb+6OZfdpX4PgE0E9bmc3FkU="; + }; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + pkg-config + ]; + + buildInputs = [ + rocblas + rocsparse + rocprim + rocrand + openmp + openmpi + ] + ++ lib.optionals buildTests [ + gtest + ]; + + cmakeFlags = [ + "-DROCM_PATH=${clr}" + "-DHIP_ROOT_DIR=${clr}" + "-DSUPPORT_HIP=ON" + "-DSUPPORT_OMP=ON" + "-DSUPPORT_MPI=ON" + "-DBUILD_CLIENTS_SAMPLES=${if buildSamples then "ON" else "OFF"}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.strings.concatStringsSep ";" gpuTargets}" + "-DGPU_TARGETS=${lib.strings.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_CLIENTS_TESTS=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_CLIENTS_BENCHMARKS=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/rocalution-test $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/rocalution-bench $benchmark/bin + '' + + lib.optionalString buildSamples '' + mkdir -p $sample/bin + mv clients/staging/* $sample/bin + rm $sample/bin/rocalution-test || true + rm $sample/bin/rocalution-bench || true + + patchelf --set-rpath \ + $out/lib:${lib.makeLibraryPath (finalAttrs.buildInputs ++ [ clr ])} \ + $sample/bin/* + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Iterative sparse solvers for ROCm"; + homepage = "https://github.com/ROCm/rocALUTION"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocblas/default.nix b/.devops/nix/rocm-modules-10/rocblas/default.nix new file mode 100644 index 0000000000..e431bf4b9e --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocblas/default.nix @@ -0,0 +1,211 @@ +{ + lib, + stdenv, + fetchFromGitHub, + fetchpatch, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + diffutils, + python3, + tensile, + boost, + msgpack-cxx, + libxml2, + gtest, + gfortran, + openmp, + gitMinimal, + amd-blis, + zstd, + roctracer, + hipblas-common, + amdsmi, + hipblaslt, + python3Packages, + rocm-smi, + pkg-config, + removeReferencesTo, + buildTensile ? true, + buildTests ? true, + buildBenchmarks ? true, + tensileSepArch ? true, + tensileLazyLib ? true, + withHipBlasLt ? true, + gpuTargets ? (clr.localGpuTargets or clr.gpuTargets), +}: + +let + gpuTargets' = lib.concatStringsSep ";" gpuTargets; +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocblas${clr.gpuArchSuffix}"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocblas" + "shared" + ]; + hash = "sha256-8LdII9gSFxuBeJwfQgOW+1/M33nbuR6TwcrD4k6W0Oo="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocblas"; + + outputs = [ "out" ] ++ lib.optional buildBenchmarks "benchmark" ++ lib.optional buildTests "test"; + + nativeBuildInputs = [ + cmake + # no ninja, it buffers console output and nix times out long periods of no output + rocm-cmake + clr + gitMinimal + pkg-config + removeReferencesTo + ] + ++ lib.optionals buildTensile [ + tensile + ]; + + buildInputs = [ + # ROCm 10's rocblas clients do find_package(amd_smi REQUIRED) + amdsmi + python3 + hipblas-common + roctracer + openmp + amd-blis + ] + ++ lib.optionals withHipBlasLt [ + hipblaslt + ] + ++ lib.optionals buildTensile [ + zstd + msgpack-cxx + libxml2 + python3Packages.msgpack + python3Packages.zstandard + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + gtest + gfortran + rocm-smi + ] + ++ lib.optionals (buildTensile || buildTests || buildBenchmarks) [ + python3Packages.pyyaml + ]; + + env.CXXFLAGS = "-fopenmp -I${lib.getDev boost}/include -I${hipblas-common}/include -I${roctracer}/include"; + # Fails to link tests with undefined symbol: cblas_* + env.LDFLAGS = + "-Wl,--as-needed -lzstd" + lib.optionalString (buildTests || buildBenchmarks) " -lcblas"; + env.TENSILE_ROCM_ASSEMBLER_PATH = "${stdenv.cc}/bin/clang++"; + + cmakeFlags = [ + (lib.cmakeFeature "Boost_INCLUDE_DIR" "${lib.getDev boost}/include") # msgpack FindBoost fails to find boost + (lib.cmakeFeature "CMAKE_EXECUTE_PROCESS_COMMAND_ECHO" "STDERR") + (lib.cmakeFeature "CMAKE_Fortran_COMPILER" "${lib.getBin gfortran}/bin/gfortran") + (lib.cmakeFeature "CMAKE_Fortran_COMPILER_AR" "${lib.getBin gfortran}/bin/ar") + (lib.cmakeFeature "CMAKE_Fortran_COMPILER_RANLIB" "${lib.getBin gfortran}/bin/ranlib") + (lib.cmakeFeature "python" "python3") + (lib.cmakeFeature "SUPPORTED_TARGETS" gpuTargets') + (lib.cmakeFeature "AMDGPU_TARGETS" gpuTargets') + (lib.cmakeFeature "GPU_TARGETS" gpuTargets') + (lib.cmakeBool "BUILD_WITH_TENSILE" buildTensile) + (lib.cmakeBool "ROCM_SYMLINK_LIBS" false) + (lib.cmakeFeature "ROCBLAS_TENSILE_LIBRARY_DIR" "lib/rocblas") + (lib.cmakeBool "BUILD_WITH_HIPBLASLT" withHipBlasLt) + (lib.cmakeBool "BUILD_CLIENTS_TESTS" buildTests) + (lib.cmakeBool "BUILD_CLIENTS_BENCHMARKS" buildBenchmarks) + (lib.cmakeBool "BUILD_CLIENTS_SAMPLES" buildBenchmarks) + (lib.cmakeBool "BUILD_OFFLOAD_COMPRESS" true) + # # Temporarily set variables to work around upstream CMakeLists issue + # # Can be removed once https://github.com/ROCm/rocm-cmake/issues/121 is fixed + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_INSTALL_LIBDIR=lib" + ] + ++ lib.optionals buildTensile [ + "-DCPACK_SET_DESTDIR=OFF" + "-DLINK_BLIS=ON" + "-DBLAS_LIBRARY=${amd-blis}/lib/libblis-mt.so" + "-DBLIS_INCLUDE_DIR=${amd-blis}/include/blis/" + "-DBLA_PREFER_PKGCONFIG=ON" + "-DTensile_CODE_OBJECT_VERSION=default" + "-DTensile_LOGIC=asm_full" + "-DTensile_LIBRARY_FORMAT=msgpack" + (lib.cmakeBool "BUILD_WITH_PIP" false) + (lib.cmakeBool "Tensile_SEPARATE_ARCHITECTURES" tensileSepArch) + (lib.cmakeBool "Tensile_LAZY_LIBRARY_LOADING" tensileLazyLib) + ]; + + # The "Extend rocBLAS HIP ISA compatibility" patch does not apply to rocBLAS + # 5.6.0 (rocblas_auxiliary.cpp and tensile_host.cpp were both reworked). It + # lets rocBLAS accept code objects built for a compatible-but-different ISA; + # this build generates Tensile kernels for gfx1151 exactly, so it is not + # needed here. Revisit if a "no kernel image is available" error appears. + patches = [ ]; + + # Pass $NIX_BUILD_CORES to Tensile + postPatch = '' + substituteInPlace cmake/build-options.cmake \ + --replace-fail 'Tensile_CPU_THREADS ""' 'Tensile_CPU_THREADS "$ENV{NIX_BUILD_CORES}"' + '' + # Workaround: libblis detection uses broken absolute paths + # TODO: upstream a proper fix + + '' + substituteInPlace clients/CMakeLists.txt \ + --replace-fail "if ( NOT WIN32 )" "if(OFF)" \ + --replace-fail "else() # WIN32" "elseif(OFF)" + '' + # Fixes sh: line 1: /usr/bin/diff: No such file or directory + # /build/source/clients/gtest/../include/testing_logging.hpp:1117: Failure + + lib.optionalString buildTests '' + substituteInPlace clients/include/testing_logging.hpp \ + --replace-fail "/usr/bin/diff" "${lib.getExe' diffutils "diff"}" + ''; + + postInstall = + # tensile isn't needed at runtime and pulls in ~400MB of python deps + '' + remove-references-to -t ${tensile} \ + "$out/lib/librocblas.so."* + '' + + lib.optionalString buildBenchmarks '' + moveToOutput "bin/*-tune" "$benchmark" + moveToOutput "bin/*-bench" "$benchmark" + moveToOutput "bin/*example*" "$benchmark" + cp "$out/bin/"*.{yaml,txt} "$benchmark/bin" + '' + + lib.optionalString buildTests '' + moveToOutput "bin/*test*" "$test" + cp "$out/bin/"*.{yaml,txt} "$test/bin" + '' + + '' + if [ -d $out/bin ]; then + rm $out/bin/*.{yaml,txt} || true + # ROCm 10 also drops a bin/rocblas/CTestTestfile.cmake in the install tree + rm -rf $out/bin/rocblas + rmdir $out/bin + fi + ''; + + passthru = { + amdgpu_targets = gpuTargets'; + updateScript = rocmUpdateScript { inherit finalAttrs; }; + }; + + enableParallelBuilding = true; + requiredSystemFeatures = [ "big-parallel" ]; + + meta = { + description = "BLAS implementation for ROCm platform"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocblas"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocblas/hiplaslt-unstable-compat.patch b/.devops/nix/rocm-modules-10/rocblas/hiplaslt-unstable-compat.patch new file mode 100644 index 0000000000..4d8c885c8d --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocblas/hiplaslt-unstable-compat.patch @@ -0,0 +1,99 @@ +diff --git a/library/src/hipblaslt_host.cpp b/library/src/hipblaslt_host.cpp +index 8080070c..97d5216e 100644 +--- a/library/src/hipblaslt_host.cpp ++++ b/library/src/hipblaslt_host.cpp +@@ -155,22 +155,22 @@ namespace + hipblaslt_compute_type); + + hipblaslt_ext::GemmProblemType problemType; +- problemType.op_a = (hipblasOperation_t)prob.trans_a; +- problemType.op_b = (hipblasOperation_t)prob.trans_b; +- problemType.type_a = hipblaslt_datatype; +- problemType.type_b = hipblaslt_datatype; +- problemType.type_c = hipblaslt_datatype; +- problemType.type_d = hipblaslt_datatype; +- problemType.type_compute = hipblaslt_compute_type; ++ problemType.setOpA((hipblasOperation_t)prob.trans_a); ++ problemType.setOpB((hipblasOperation_t)prob.trans_b); ++ problemType.setTypeA(hipblaslt_datatype); ++ problemType.setTypeB(hipblaslt_datatype); ++ problemType.setTypeC(hipblaslt_datatype); ++ problemType.setTypeD(hipblaslt_datatype); ++ problemType.setTypeCompute(hipblaslt_compute_type); + + hipblaslt_ext::GemmEpilogue epilogue; + hipblaslt_ext::GemmInputs inputs; +- inputs.a = (void*)(prob.A + prob.buffer_offset_a); +- inputs.b = (void*)(prob.B + prob.buffer_offset_b); +- inputs.c = (void*)(prob.C + prob.buffer_offset_c); +- inputs.d = (void*)(prob.D + prob.buffer_offset_d); +- inputs.alpha = (void*)prob.alpha; +- inputs.beta = (void*)prob.beta; ++ inputs.setA((void*)(prob.A + prob.buffer_offset_a)); ++ inputs.setB((void*)(prob.B + prob.buffer_offset_b)); ++ inputs.setC((void*)(prob.C + prob.buffer_offset_c)); ++ inputs.setD((void*)(prob.D + prob.buffer_offset_d)); ++ inputs.setAlpha((void*)prob.alpha); ++ inputs.setBeta((void*)prob.beta); + + gemm.setProblem(prob.m, + prob.n, +@@ -214,13 +214,13 @@ namespace + hipblaslt_compute_type); + + hipblaslt_ext::GemmProblemType problemType; +- problemType.op_a = (hipblasOperation_t)prob.trans_a; +- problemType.op_b = (hipblasOperation_t)prob.trans_b; +- problemType.type_a = hipblaslt_datatype; +- problemType.type_b = hipblaslt_datatype; +- problemType.type_c = hipblaslt_datatype; +- problemType.type_d = hipblaslt_datatype; +- problemType.type_compute = hipblaslt_compute_type; ++ problemType.setOpA((hipblasOperation_t)prob.trans_a); ++ problemType.setOpB((hipblasOperation_t)prob.trans_b); ++ problemType.setTypeA(hipblaslt_datatype); ++ problemType.setTypeB(hipblaslt_datatype); ++ problemType.setTypeC(hipblaslt_datatype); ++ problemType.setTypeD(hipblaslt_datatype); ++ problemType.setTypeCompute(hipblaslt_compute_type); + + std::vector Ms(prob.batch_count); + std::vector Ns(prob.batch_count); +@@ -251,12 +251,12 @@ namespace + stridecs[batch] = prob.batch_stride_c; + strideds[batch] = prob.batch_stride_d; + batch_counts[batch] = 1; +- inputs[batch].a = (void*)(prob.batch_A[batch] + prob.buffer_offset_a); +- inputs[batch].b = (void*)(prob.batch_B[batch] + prob.buffer_offset_b); +- inputs[batch].c = (void*)(prob.batch_C[batch] + prob.buffer_offset_c); +- inputs[batch].d = (void*)(prob.batch_D[batch] + prob.buffer_offset_d); +- inputs[batch].alpha = (void*)prob.alpha; +- inputs[batch].beta = (void*)prob.beta; ++ inputs[batch].setA((void*)(prob.batch_A[batch] + prob.buffer_offset_a)); ++ inputs[batch].setB((void*)(prob.batch_B[batch] + prob.buffer_offset_b)); ++ inputs[batch].setC((void*)(prob.batch_C[batch] + prob.buffer_offset_c)); ++ inputs[batch].setD((void*)(prob.batch_D[batch] + prob.buffer_offset_d)); ++ inputs[batch].setAlpha((void*)prob.alpha); ++ inputs[batch].setBeta((void*)prob.beta); + } + + gemm.setProblem(Ms, +diff --git a/library/src/tensile_host.cpp b/library/src/tensile_host.cpp +index 1b1289f3..ed463725 100644 +--- a/library/src/tensile_host.cpp ++++ b/library/src/tensile_host.cpp +@@ -271,14 +271,6 @@ namespace + { + return Tensile::LazyLoadingInit::gfx90a; + } +- else if(deviceString.find("gfx940") != std::string::npos) +- { +- return Tensile::LazyLoadingInit::gfx940; +- } +- else if(deviceString.find("gfx941") != std::string::npos) +- { +- return Tensile::LazyLoadingInit::gfx941; +- } + else if(deviceString.find("gfx942") != std::string::npos) + { + return Tensile::LazyLoadingInit::gfx942; diff --git a/.devops/nix/rocm-modules-10/rocdbgapi/default.nix b/.devops/nix/rocm-modules-10/rocdbgapi/default.nix new file mode 100644 index 0000000000..6cabdb339a --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocdbgapi/default.nix @@ -0,0 +1,109 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocm-comgr, + rocm-runtime, + hwdata, + texliveSmall, + doxygen, + graphviz, + writableTmpDirAsHomeHook, + buildDocs ? true, +}: + +let + latex = lib.optionalAttrs buildDocs ( + texliveSmall.withPackages ( + ps: with ps; [ + changepage + latexmk + varwidth + multirow + hanging + adjustbox + collectbox + stackengine + enumitem + alphalph + wasysym + sectsty + tocloft + newunicodechar + etoc + helvetic + wasy + courier + tabularray + ltablex + ninecolors + xltabular + ] + ) + ); +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocdbgapi"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildDocs [ + "doc" + ]; + + buildFlags = lib.optionals buildDocs [ "doc" ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "ROCdbgapi"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-KqvhwfIv8pbr8WbnfAKl71fg5yxbwYcpzZcGU9Htdkc="; + }; + + nativeBuildInputs = [ + cmake + rocm-cmake + ] + ++ lib.optionals buildDocs [ + writableTmpDirAsHomeHook + latex + doxygen + graphviz + ]; + + buildInputs = [ + rocm-comgr + rocm-runtime + hwdata + ]; + + cmakeFlags = [ + "-DPCI_IDS_PATH=${hwdata}/share/hwdata" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + postInstall = lib.optionalString buildDocs '' + mkdir -p $doc/share/doc/amd-dbgapi/ + mv $out/share/html/amd-dbgapi $doc/share/doc/amd-dbgapi/html + rmdir $out/share/html + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Debugger support for control of execution and inspection state of AMD's GPU architectures"; + homepage = "https://github.com/ROCm/ROCdbgapi"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocfft/default.nix b/.devops/nix/rocm-modules-10/rocfft/default.nix new file mode 100644 index 0000000000..17c67b623c --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocfft/default.nix @@ -0,0 +1,170 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + clr, + python3, + rocm-cmake, + sqlite, + boost, + fftw, + fftwFloat, + gtest, + openmp, + rocrand, + hiprand, + gpuTargets ? clr.localGpuTargets or clr.gpuTargets, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocfft${clr.gpuArchSuffix}"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rocfft" + "shared" + ]; + hash = "sha256-RjWMzLX0nBA8ClweJ8YgRTn+Nzt/VUkOoSw3jMQ3IWg="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocfft"; + + nativeBuildInputs = [ + cmake + clr + python3 + rocm-cmake + ]; + + buildInputs = [ + sqlite + hiprand + ]; + + patches = [ + # Fixes build timeout due to no log output during rocfft_aot step + ./log-every-n-aot-jobs.patch + ]; + + cmakeFlags = [ + "-DSQLITE_USE_SYSTEM_PACKAGE=ON" + "-DHIP_PLATFORM=amd" + "-DBUILD_CLIENTS=OFF" + "-DBUILD_SHARED_LIBS=ON" + "-DUSE_HIPRAND=ON" + "-DROCFFT_KERNEL_CACHE_ENABLE=ON" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ]; + + passthru = { + test = stdenv.mkDerivation { + pname = "${finalAttrs.pname}-test"; + inherit (finalAttrs) version src; + + sourceRoot = "${finalAttrs.src.name}/projects/rocfft/clients/tests"; + + nativeBuildInputs = [ + cmake + clr + rocm-cmake + ]; + + buildInputs = [ + boost + fftw + fftwFloat + finalAttrs.finalPackage + gtest + openmp + rocrand + hiprand + ]; + + postInstall = '' + rm -r "$out/lib/fftw" + rmdir "$out/lib" + ''; + }; + + benchmark = stdenv.mkDerivation { + pname = "${finalAttrs.pname}-benchmark"; + inherit (finalAttrs) version src; + + sourceRoot = "${finalAttrs.src.name}/projects/rocfft/clients/rider"; + + nativeBuildInputs = [ + cmake + clr + rocm-cmake + ]; + + buildInputs = [ + boost + finalAttrs.finalPackage + openmp + (python3.withPackages ( + ps: with ps; [ + pandas + scipy + ] + )) + rocrand + ]; + + postInstall = '' + cp -a ../../../scripts/perf "$out/bin" + ''; + }; + + samples = stdenv.mkDerivation { + pname = "${finalAttrs.pname}-samples"; + inherit (finalAttrs) version src; + + sourceRoot = "${finalAttrs.src.name}/projects/rocfft/clients/samples"; + + nativeBuildInputs = [ + cmake + clr + rocm-cmake + ]; + + buildInputs = [ + boost + finalAttrs.finalPackage + openmp + rocrand + ]; + + installPhase = '' + runHook preInstall + mkdir "$out" + cp -a bin "$out" + runHook postInstall + ''; + }; + + updateScript = rocmUpdateScript { inherit finalAttrs; }; + }; + + requiredSystemFeatures = [ "big-parallel" ]; + + meta = { + description = "FFT implementation for ROCm"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocfft"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocfft/log-every-n-aot-jobs.patch b/.devops/nix/rocm-modules-10/rocfft/log-every-n-aot-jobs.patch new file mode 100644 index 0000000000..266f495d3e --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocfft/log-every-n-aot-jobs.patch @@ -0,0 +1,35 @@ +diff --git a/library/src/rocfft_aot_helper.cpp b/library/src/rocfft_aot_helper.cpp +index f0a889f4..452eb37f 100644 +--- a/library/src/rocfft_aot_helper.cpp ++++ b/library/src/rocfft_aot_helper.cpp +@@ -771,26 +771,22 @@ int main(int argc, char** argv) + for(size_t i = 0; i < NUM_THREADS; ++i) + { + threads.emplace_back([&queue, &gpu_archs]() { ++ int compile_count = 0; + while(true) + { + auto item = queue.pop(); + if(item.kernel_name.empty()) + break; + ++ if(++compile_count % 16 == 0) ++ std::cerr << "rocfft_aot_helper processing " << item.kernel_name << std::endl << std::flush; + for(const auto& gpu_arch : gpu_archs) + { +- if(item.sol_arch_name.empty()) ++ if(item.sol_arch_name.empty() || gpu_arch.find(item.sol_arch_name) != std::string::npos) + { + RTCCache::cached_compile( + item.kernel_name, gpu_arch, item.generate_src, generator_sum()); + } +- else if(gpu_arch.find(item.sol_arch_name) != std::string::npos) +- { +- // std::cout << "arch: " << gpu_arch +- // << ", solution-kernel: " << item.kernel_name << std::endl; +- RTCCache::cached_compile( +- item.kernel_name, gpu_arch, item.generate_src, generator_sum()); +- } + } + } + }); diff --git a/.devops/nix/rocm-modules-10/rocgdb/default.nix b/.devops/nix/rocm-modules-10/rocgdb/default.nix new file mode 100644 index 0000000000..e924874da3 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocgdb/default.nix @@ -0,0 +1,113 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + pkg-config, + texinfo, + bison, + flex, + glibc, + zlib, + zstd, + gmp, + mpfr, + ncurses, + expat, + rocdbgapi, + perl, + python3, + babeltrace, + sourceHighlight, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocgdb"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "ROCgdb"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-oml/HLExnnjh7+axeWPZRWecpwK2BnzVOaGvXYhrxKs="; + }; + + nativeBuildInputs = [ + pkg-config + texinfo # For makeinfo + bison + flex + perl # used in mkinstalldirs script during installPhase + python3 + ]; + + buildInputs = [ + zlib + zstd + gmp + mpfr + ncurses + expat + rocdbgapi + python3 + babeltrace + sourceHighlight + ]; + + configureFlags = [ + # Ensure we build the amdgpu target + "--enable-targets=${stdenv.targetPlatform.config},amdgcn-amd-amdhsa" + "--with-amd-dbgapi=yes" + + "--with-iconv-path=${glibc.bin}" + "--enable-tui" + "--with-babeltrace=${babeltrace}" + "--with-python=python3" + "--with-system-zlib" + "--with-system-zstd" + "--enable-64-bit-bfd" + "--with-gmp=${gmp.dev}" + "--with-mpfr=${mpfr.dev}" + "--with-expat=${expat}" + + # So the installed binary is called "rocgdb" instead on plain "gdb" + "--program-prefix=roc" + + # Disable building many components not used or incompatible with the amdgcn target + "--disable-sim" + "--disable-gdbserver" + "--disable-ld" + "--disable-gas" + "--disable-gdbserver" + "--disable-gdbtk" + "--disable-gprofng" + "--disable-shared" + ]; + + postPatch = '' + for file in *; do + if [ -f "$file" ]; then + patchShebangs "$file" + fi + done + ''; + + # The source directory for ROCgdb (based on upstream GDB) contains multiple project + # of GNU’s toolchain (binutils and onther), we only need to install the GDB part. + installPhase = '' + make install-gdb + ''; + + env.CFLAGS = "-Wno-switch -Wno-format-nonliteral -I${zstd.dev}/include -I${zlib.dev}/include -I${expat.dev}/include -I${ncurses.dev}/include"; + env.CXXFLAGS = finalAttrs.env.CFLAGS; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm source-level debugger for Linux, based on GDB"; + homepage = "https://github.com/ROCm/ROCgdb"; + license = lib.licenses.gpl3Plus; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-bandwidth-test/default.nix b/.devops/nix/rocm-modules-10/rocm-bandwidth-test/default.nix new file mode 100644 index 0000000000..3f1df9c06b --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-bandwidth-test/default.nix @@ -0,0 +1,38 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmPackages, + cmake, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocm-bandwidth-test"; + version = "6.3.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm_bandwidth_test"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-dHyfYpRB13wUvim152nZ61McZOQ1zUZFx4dUo2vVqZM="; + }; + + nativeBuildInputs = [ + cmake + ]; + + buildInputs = [ rocmPackages.rocm-runtime ]; + + cmakeFlags = [ + "-DROCT_INC_DIR=${rocmPackages.rocm-runtime}/include/libhsakmt" + ]; + + meta = { + description = "Bandwidth test for AMD GPUs supported by ROCm"; + homepage = "https://github.com/ROCm/rocm_bandwidth_test"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ fangpen ]; + teams = [ lib.teams.rocm ]; + platforms = [ "x86_64-linux" ]; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-cmake/default.nix b/.devops/nix/rocm-modules-10/rocm-cmake/default.nix new file mode 100644 index 0000000000..79323e5f48 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-cmake/default.nix @@ -0,0 +1,34 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + rocm-core, + cmake, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocm-cmake"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-cmake"; + rev = "therock-10.0"; + hash = "sha256-im6UO0crO0Jc27zkTsdvJYPHit8IGlw/vDPGrmP1XqY="; + }; + + nativeBuildInputs = [ cmake ]; + + buildInputs = [ rocm-core ]; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "CMake modules for common build tasks for the ROCm stack"; + homepage = "https://github.com/ROCm/rocm-cmake"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.unix; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-comgr/default.nix b/.devops/nix/rocm-modules-10/rocm-comgr/default.nix new file mode 100644 index 0000000000..245fff480c --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-comgr/default.nix @@ -0,0 +1,83 @@ +{ + lib, + stdenv, + fetchpatch, + cmake, + llvm, + python3, + rocm-device-libs, + zlib, + zstd, +}: + +let + llvmNativeTarget = + if stdenv.hostPlatform.isx86_64 then + "X86" + else if stdenv.hostPlatform.isAarch64 then + "AArch64" + else + throw "Unsupported ROCm LLVM platform"; +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocm-comgr"; + # In-tree with ROCm LLVM + inherit (llvm.llvm) version; + src = llvm.llvm.monorepoSrc; + sourceRoot = "${finalAttrs.src.name}/amd/comgr"; + strictDeps = true; + + patches = [ + # [Comgr] Extend ISA compatibility + (fetchpatch { + hash = "sha256-X2VPGigK582J+a/u2Kg74w25/+CTpVWU9D3Eqgnb2PU="; + url = "https://github.com/GZGavinZhao/rocm-llvm-project/commit/7002dc04863d38c57cfd2e6fc60a1cf5a613fd8e.patch"; + relative = "amd/comgr"; + }) + # The CCOB ISA-compatibility patch (and its output-filename fix) call + # clang::OffloadBundler::GetBundleIDsInFile, which only exists via the + # companion clang patch that no longer compiles against LLVM 23. Upstream + # ROCm 10 provides ListBundleIDsInFile instead, so both are dropped here. + ]; + + postPatch = + # Fix relative path assumption for libllvm + '' + substituteInPlace cmake/opencl_header.cmake \ + --replace-fail "\''${CLANG_CMAKE_DIR}/../../../" "${llvm.clang-unwrapped.lib}" + '' + # Bake LLVM root for cfg/includes or HIPRTC can't find C++ stdlib headers (e.g. ). + + '' + substituteInPlace src/comgr-env.cpp \ + --replace-fail \ + 'return EnvLLVMPath ? EnvLLVMPath : "";' \ + 'return EnvLLVMPath ? EnvLLVMPath : "${llvm.rocm-toolchain}";' + ''; + + nativeBuildInputs = [ + cmake + python3 + ]; + + buildInputs = [ + llvm.llvm + llvm.clang-unwrapped + llvm.lld + rocm-device-libs + zlib + zstd + ]; + + cmakeFlags = [ + "-DLLVM_TARGETS_TO_BUILD=AMDGPU;${llvmNativeTarget}" + ]; + + meta = { + description = "APIs for compiling and inspecting AMDGPU code objects"; + homepage = "https://github.com/ROCm/ROCm-CompilerSupport/tree/amd-stg-open/lib/comgr"; + license = lib.licenses.ncsa; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-comgr/fix-ccob-compat-output-filename.patch b/.devops/nix/rocm-modules-10/rocm-comgr/fix-ccob-compat-output-filename.patch new file mode 100644 index 0000000000..813f419ef3 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-comgr/fix-ccob-compat-output-filename.patch @@ -0,0 +1,11 @@ +--- a/src/comgr-compiler.cpp ++++ b/src/comgr-compiler.cpp +@@ -1425,7 +1425,7 @@ + // Add an output file for each target + SmallString<128> OutputFilePath = OutputDir; + sys::path::append(OutputFilePath, +- OutputPrefix + "-" + CompatEntry + "." + FileExtension); ++ OutputPrefix + "-" + Entry + "." + FileExtension); + + BundlerConfig.TargetNames.emplace_back(CompatEntry); + BundlerConfig.OutputFileNames.emplace_back(OutputFilePath); diff --git a/.devops/nix/rocm-modules-10/rocm-core/default.nix b/.devops/nix/rocm-modules-10/rocm-core/default.nix new file mode 100644 index 0000000000..a3d1039eea --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-core/default.nix @@ -0,0 +1,95 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + writeText, +}: + +# rocm-core is used by most distros for a few purposes: +# - meta package that all rocm packages depend so `apt-get remove rocm-core` removes all rocm packages +# - provide overall ROCM_PATH +# - provide rocm version info and path to rocm version headers +# only the last usage makes sense in nixpkgs +let + padIfSingle = s: if lib.stringLength s == 1 then "0${s}" else s; +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocm-core"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocm-core" + "shared" + ]; + hash = "sha256-7rPhCKGi5vcx3LsqnffCZK6n1lL5hjzMreot2gk/v+c="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocm-core"; + + patches = [ + ./env-rocm-path.patch + ]; + + nativeBuildInputs = [ cmake ]; + env = { + ROCM_LIBPATCH_VERSION = "${lib.versions.major finalAttrs.version}${padIfSingle (lib.versions.minor finalAttrs.version)}${padIfSingle (lib.versions.patch finalAttrs.version)}"; + BUILD_ID = "nixpkgs-${finalAttrs.env.ROCM_LIBPATCH_VERSION}"; + ROCM_BUILD_ID = "${finalAttrs.env.BUILD_ID}"; + }; + cmakeFlags = [ + "-DROCM_LIBPATCH_VERSION=${finalAttrs.env.ROCM_LIBPATCH_VERSION}" + "-DROCM_VERSION=${finalAttrs.version}" + "-DBUILD_ID=${finalAttrs.env.BUILD_ID}" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_LIBEXECDIR=libexec" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DCMAKE_INSTALL_BINDIR=bin" + ]; + + setupHook = writeText "setupHook.sh" '' + export ROCM_VERSION="${finalAttrs.version}" + export ROCM_LIBPATCH_VERSION="${finalAttrs.env.ROCM_LIBPATCH_VERSION}" + export ROCM_BUILD_ID="${finalAttrs.env.ROCM_BUILD_ID}" + ''; + + doInstallCheck = true; + preInstallCheck = + # Test that the CMake config file can be included and sets expected vars + '' + mkdir test_project + pushd test_project + + echo ' + cmake_minimum_required(VERSION 3.16) + project(test_rocm_core) + find_package(rocm-core REQUIRED) + if(NOT DEFINED ROCM_CORE_INCLUDE_DIR) + message(FATAL_ERROR "ROCM_CORE_INCLUDE_DIR not set") + endif() + message(STATUS "Found ROCM_CORE_INCLUDE_DIR: ''${ROCM_CORE_INCLUDE_DIR}") + message(STATUS "Found ROCM_PATH: ''${ROCM_PATH}") + ' > CMakeLists.txt + + CMAKE_PREFIX_PATH="$out" cmake . + popd + + . $out/nix-support/setup-hook + env | grep '^ROCM' + ''; + + passthru.ROCM_LIBPATCH_VERSION = finalAttrs.env.ROCM_LIBPATCH_VERSION; + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Utility for getting the ROCm release version"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rocm-core"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-core/env-rocm-path.patch b/.devops/nix/rocm-modules-10/rocm-core/env-rocm-path.patch new file mode 100644 index 0000000000..a40fa33b90 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-core/env-rocm-path.patch @@ -0,0 +1,22 @@ +In FHS distros rocm-core expects to be installed colocated with a full set of ROCM packages. +In nixpkgs contexts, we don't want rocm-core to be a ROCM_PATH root. +diff --git a/cmake_modules/rocm-core-config.cmake.in b/cmake_modules/rocm-core-config.cmake.in +index f5fe07c..9d72c9c 100644 +--- a/cmake_modules/rocm-core-config.cmake.in ++++ b/cmake_modules/rocm-core-config.cmake.in +@@ -11,7 +11,14 @@ set_and_check(rocm_core_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") + set_and_check(ROCM_CORE_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") + set_and_check(rocm_core_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@") + set_and_check(ROCM_CORE_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@") +-set_and_check(ROCM_PATH "${PACKAGE_PREFIX_DIR}") ++# Set ROCM_PATH with priority: existing value > environment variable > package prefix ++if(NOT DEFINED ROCM_PATH) ++ if(DEFINED ENV{ROCM_PATH}) ++ set(ROCM_PATH "$ENV{ROCM_PATH}") ++ else() ++ set_and_check(ROCM_PATH "${PACKAGE_PREFIX_DIR}") ++ endif() ++endif() + + get_filename_component(ROCM_CORE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + include("${ROCM_CORE_CMAKE_DIR}/rocmCoreTargets.cmake") diff --git a/.devops/nix/rocm-modules-10/rocm-device-libs/cmake.patch b/.devops/nix/rocm-modules-10/rocm-device-libs/cmake.patch new file mode 100644 index 0000000000..8f53d83be4 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-device-libs/cmake.patch @@ -0,0 +1,34 @@ +--- a/cmake/Packages.cmake ++++ b/cmake/Packages.cmake +@@ -12,21 +12,25 @@ + IMPORTED_LOCATION \"${target_path}\")") + endforeach() + configure_file(AMDDeviceLibsConfig.cmake.in +- ${PACKAGE_PREFIX}/AMDDeviceLibsConfig.cmake ++ lib/cmake/AMDDeviceLibs/AMDDeviceLibsConfig.cmake + @ONLY) + + # Generate the install-tree package. + # We do not know the absolute path to the intall tree until we are installed, + # so we calculate it dynamically in AMD_DEVICE_LIBS_PREFIX_CODE and use + # relative paths in the target imports in AMD_DEVICE_LIBS_TARGET_CODE. +-set(AMD_DEVICE_LIBS_PREFIX_CODE " ++if(IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}") ++ set(AMD_DEVICE_LIBS_PREFIX_CODE "set(AMD_DEVICE_LIBS_PREFIX \"${CMAKE_INSTALL_PREFIX}\")") ++else() ++ set(AMD_DEVICE_LIBS_PREFIX_CODE " + # Derive absolute install prefix from config file path. + get_filename_component(AMD_DEVICE_LIBS_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)") +-string(REGEX REPLACE "/" ";" count "${PACKAGE_PREFIX}") +-foreach(p ${count}) +- set(AMD_DEVICE_LIBS_PREFIX_CODE "${AMD_DEVICE_LIBS_PREFIX_CODE} ++ string(REGEX REPLACE "/" ";" count "${PACKAGE_PREFIX}") ++ foreach(p ${count}) ++ set(AMD_DEVICE_LIBS_PREFIX_CODE "${AMD_DEVICE_LIBS_PREFIX_CODE} + get_filename_component(AMD_DEVICE_LIBS_PREFIX \"\${AMD_DEVICE_LIBS_PREFIX}\" PATH)") +-endforeach() ++ endforeach() ++endif() + set(AMD_DEVICE_LIBS_TARGET_CODE) + foreach(target ${AMDGCN_LIB_LIST}) + get_target_property(target_name ${target} ARCHIVE_OUTPUT_NAME) diff --git a/.devops/nix/rocm-modules-10/rocm-device-libs/default.nix b/.devops/nix/rocm-modules-10/rocm-device-libs/default.nix new file mode 100644 index 0000000000..41034d2c64 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-device-libs/default.nix @@ -0,0 +1,67 @@ +{ + lib, + stdenv, + cmake, + ninja, + zlib, + zstd, + llvm, + python3, +}: + +let + llvmNativeTarget = + if stdenv.hostPlatform.isx86_64 then + "X86" + else if stdenv.hostPlatform.isAarch64 then + "AArch64" + else + throw "Unsupported ROCm LLVM platform"; +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocm-device-libs"; + # In-tree with ROCm LLVM + inherit (llvm.llvm) version; + src = llvm.llvm.monorepoSrc; + sourceRoot = "${finalAttrs.src.name}/amd/device-libs"; + strictDeps = true; + __structuredAttrs = true; + + postPatch = + # Use our sysrooted toolchain instead of direct clang target + '' + substituteInPlace cmake/OCL.cmake \ + --replace-fail '$' "${llvm.rocm-toolchain}/bin/clang" + ''; + + patches = [ + ./cmake.patch + ]; + + nativeBuildInputs = [ + cmake + ninja + python3 + llvm.rocm-toolchain + ]; + + buildInputs = [ + llvm.llvm + llvm.clang-unwrapped + zlib + zstd + ]; + + cmakeFlags = [ + "-DLLVM_TARGETS_TO_BUILD=AMDGPU;${llvmNativeTarget}" + ]; + + meta = { + description = "Set of AMD-specific device-side language runtime libraries"; + homepage = "https://github.com/ROCm/ROCm-Device-Libs"; + license = lib.licenses.ncsa; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-docs-core/default.nix b/.devops/nix/rocm-modules-10/rocm-docs-core/default.nix new file mode 100644 index 0000000000..a9aaf3e4cb --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-docs-core/default.nix @@ -0,0 +1,71 @@ +{ + lib, + fetchFromGitHub, + gitUpdater, + buildPythonPackage, + setuptools, + beautifulsoup4, + gitpython, + pydata-sphinx-theme, + pygithub, + sphinx, + breathe, + myst-nb, + myst-parser, + sphinx-book-theme, + sphinx-copybutton, + sphinx-design, + sphinx-external-toc, + sphinx-notfound-page, + pyyaml, + fastjsonschema, +}: + +# FIXME: Move to rocmPackages_common +buildPythonPackage (finalAttrs: { + pname = "rocm-docs-core"; + version = "1.34.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-docs-core"; + rev = "v${finalAttrs.version}"; + hash = "sha256-dVX+e0nk9/GT0idXNvLwCuN8Fh/r0dWIvqToU9cxKxs="; + }; + + buildInputs = [ setuptools ]; + + propagatedBuildInputs = [ + beautifulsoup4 + gitpython + pydata-sphinx-theme + pygithub + sphinx + breathe + myst-nb + myst-parser + sphinx-book-theme + sphinx-copybutton + sphinx-design + sphinx-external-toc + sphinx-notfound-page + pyyaml + fastjsonschema + ]; + + pythonImportsCheck = [ "rocm_docs" ]; + + passthru.updateScript = gitUpdater { rev-prefix = "v"; }; + + meta = { + description = "ROCm Documentation Python package for ReadTheDocs build standardization"; + homepage = "https://github.com/ROCm/rocm-docs-core"; + license = with lib.licenses; [ + mit + cc-by-40 + ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-runtime/default.nix b/.devops/nix/rocm-modules-10/rocm-runtime/default.nix new file mode 100644 index 0000000000..f21917758f --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-runtime/default.nix @@ -0,0 +1,103 @@ +{ + lib, + stdenv, + fetchFromGitHub, + fetchpatch, + rocmUpdateScript, + pkg-config, + cmake, + xxd, + python3, + rocm-device-libs, + rocprofiler-register, + elfutils, + libdrm, + numactl, + llvm, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocm-runtime"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocr-runtime" + "shared" + ]; + hash = "sha256-KVH8jhtjUIRNCF3gid7ZuW+XmSLRJqZtLMY+hOtXggw="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocr-runtime"; + + cmakeBuildType = "RelWithDebInfo"; + separateDebugInfo = true; + __structuredAttrs = true; + strictDeps = true; + + nativeBuildInputs = [ + pkg-config + cmake + xxd # used by create_hsaco_ascii_file.sh + # ROCm 10's trap_handler/CMakeLists.txt generates bytecode streams with a + # Python script, so the interpreter has to be on the build path. + python3 + llvm.rocm-toolchain + ]; + + buildInputs = [ + llvm.clang-unwrapped + llvm.llvm + elfutils + libdrm + numactl + rocprofiler-register + ]; + + cmakeFlags = [ + "-DBUILD_SHARED_LIBS=ON" + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + patches = [ + # The queue-allocation segfault fix (rocm-systems#2850) and the extended HIP + # ISA compatibility check are both already in therock-10.0; re-applying them + # to amd_gpu_agent.cpp is detected as reversed. + # The 1 << 31 UB fix is already in therock-10.0: kfd_ioctl.h uses 1U << 31. + # This causes a circular dependency, aqlprofile relies on hsa-runtime64 + # which is part of rocm-runtime + # Worked around by having rocprofiler load aqlprofile directly + ./remove-hsa-aqlprofile-dep.patch + ]; + + postPatch = '' + patchShebangs --build \ + runtime/hsa-runtime/core/runtime/trap_handler/create_trap_handler_header.sh \ + runtime/hsa-runtime/core/runtime/blit_shaders/create_blit_shader_header.sh \ + runtime/hsa-runtime/image/blit_src/create_hsaco_ascii_file.sh + patchShebangs --host image core runtime + + substituteInPlace CMakeLists.txt \ + --replace 'hsa/include/hsa' 'include/hsa' + + substituteInPlace runtime/hsa-runtime/image/blit_src/CMakeLists.txt \ + --replace-fail 'COMMAND clang' "COMMAND ${llvm.rocm-toolchain}/bin/clang" + + export HIP_DEVICE_LIB_PATH="${rocm-device-libs}/amdgcn/bitcode" + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Platform runtime for ROCm"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rocr-runtime"; + license = lib.licenses.ncsa; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-runtime/queue-failure.patch b/.devops/nix/rocm-modules-10/rocm-runtime/queue-failure.patch new file mode 100644 index 0000000000..f9087144bc --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-runtime/queue-failure.patch @@ -0,0 +1,71 @@ +From b7717446c85d08b2d7c0c60ba3ac0eff11ee6120 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Tue, 20 Jan 2026 12:55:45 -0800 +Subject: [PATCH 1/2] rocm-runtime: fix crash in QueueCreate due to trying to + free non allocated scratch + +if (scratch.main_queue_base != nullptr) before calling ReleaseQueueMainScratch +because ReleaseQueueMainScratch is only valid if main_queue_base is set +and the scope guard can fire for an error allocating the queue. +--- + .../runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp +index 01b01fe869..83db40dacc 100644 +--- a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp ++++ b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp +@@ -1792,7 +1792,9 @@ hsa_status_t GpuAgent::QueueCreate(size_t size, hsa_queue_type32_t queue_type, u + scratch.main_queue_base = nullptr; + scratch.main_queue_process_offset = 0; + +- MAKE_NAMED_SCOPE_GUARD(scratchGuard, [&]() { ReleaseQueueMainScratch(scratch); }); ++ MAKE_NAMED_SCOPE_GUARD(scratchGuard, [&]() { ++ if (scratch.main_queue_base != nullptr) ReleaseQueueMainScratch(scratch); ++ }); + + if (scratch.main_size != 0) { + AcquireQueueMainScratch(scratch); +-- +2.52.0 + + +From 9c1746cd76a703e4d2321dc2ffe85fc61bfd2f21 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Tue, 20 Jan 2026 13:00:32 -0800 +Subject: [PATCH 2/2] rocm-runtime: log for errors in QueueCreate + +--- + .../runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp +index 83db40dacc..ae68732eb5 100644 +--- a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp ++++ b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp +@@ -1799,6 +1799,9 @@ hsa_status_t GpuAgent::QueueCreate(size_t size, hsa_queue_type32_t queue_type, u + if (scratch.main_size != 0) { + AcquireQueueMainScratch(scratch); + if (scratch.main_queue_base == nullptr) { ++ LogPrint(HSA_AMD_LOG_FLAG_INFO, ++ "Failed to allocate scratch memory for queue, size=%zu, node=%u", ++ scratch.main_size, node_id()); + return HSA_STATUS_ERROR_OUT_OF_RESOURCES; + } + } +@@ -1827,7 +1830,11 @@ hsa_status_t GpuAgent::QueueCreate(size_t size, hsa_queue_type32_t queue_type, u + node_id())); + } + +- if (!shared_queue) return HSA_STATUS_ERROR_OUT_OF_RESOURCES; ++ if (!shared_queue) { ++ LogPrint(HSA_AMD_LOG_FLAG_INFO, ++ "Failed to allocate shared queue descriptor memory, node=%u", node_id()); ++ return HSA_STATUS_ERROR_OUT_OF_RESOURCES; ++ } + + auto aql_queue = new AqlQueue(shared_queue, this, size, node_id(), scratch, event_callback, data, + flags); +-- +2.52.0 + diff --git a/.devops/nix/rocm-modules-10/rocm-runtime/remove-hsa-aqlprofile-dep.patch b/.devops/nix/rocm-modules-10/rocm-runtime/remove-hsa-aqlprofile-dep.patch new file mode 100644 index 0000000000..75e568670a --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-runtime/remove-hsa-aqlprofile-dep.patch @@ -0,0 +1,17 @@ +libhsa-amd-aqlprofile64 library is unfree +Bug: https://github.com/ROCm/ROCm/issues/1781 + +ROCm 10 replaced the direct os::LoadLib(kAqlProfileLib) probe in +amd_gpu_agent.cpp with a runtime AqlProfileAvailable() check, so only the +extension-table hunk below is still needed. +--- a/runtime/hsa-runtime/core/runtime/hsa.cpp ++++ b/runtime/hsa-runtime/core/runtime/hsa.cpp +@@ -490,7 +490,7 @@ hsa_status_t hsa_system_get_major_extension_table(uint16_t extension, uint16_t v + return HSA_STATUS_SUCCESS; + } + +- if (extension == HSA_EXTENSION_AMD_AQLPROFILE) { ++ if (0) { + if (version_major != hsa_ven_amd_aqlprofile_VERSION_MAJOR) { + debug_print("aqlprofile API incompatible ver %d, current ver %d\n", + version_major, hsa_ven_amd_aqlprofile_VERSION_MAJOR); diff --git a/.devops/nix/rocm-modules-10/rocm-smi/default.nix b/.devops/nix/rocm-modules-10/rocm-smi/default.nix new file mode 100644 index 0000000000..c0044c938a --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-smi/default.nix @@ -0,0 +1,73 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + pkg-config, + libdrm, + cmake, + wrapPython, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocm-smi"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rocm-smi-lib" + "shared" + ]; + hash = "sha256-Si8SbeVKUBtqk6h2QJ9ssQV68bLq6TvESrYXJuArHd8="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocm-smi-lib"; + + propagatedBuildInputs = [ + libdrm + ]; + + nativeBuildInputs = [ + cmake + wrapPython + pkg-config + ]; + + cmakeFlags = [ + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_LIBEXECDIR=libexec" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + postInstall = + # wrap python programs, but undo two that need to be importable at that path + '' + wrapPythonProgramsIn $out + mv $out/libexec/rocm_smi/.rsmiBindingsInit.py-wrapped $out/libexec/rocm_smi/rsmiBindingsInit.py + mv $out/libexec/rocm_smi/.rsmiBindings.py-wrapped $out/libexec/rocm_smi/rsmiBindings.py + '' + # workaround: propagate libdrm/ manually + # rocm-toolchain doesn't automatically add buildInputs to isystem include path like + # wrapper based toolchains, cmake files often don't find_package(rocm-smi) so + # can't rely on cmake propagated interface + # upstream have been shipping libdrm copied into /opt/rocm + + '' + ln -s ${libdrm.dev}/include/libdrm/ $out/include/ + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "System management interface for AMD GPUs supported by ROCm"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rocm-smi-lib"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = [ "x86_64-linux" ]; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocm-tests/default.nix b/.devops/nix/rocm-modules-10/rocm-tests/default.nix new file mode 100644 index 0000000000..7949158939 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocm-tests/default.nix @@ -0,0 +1,56 @@ +{ + lib, + linkFarm, + clr, + ollama, + python3Packages, + rocmPackages, + magma-hip, + emptyDirectory, + stdenv, +}: +# This package exists purely to have a bunch of passthru.tests attrs +let + availableRocmDrvs = lib.pipe rocmPackages [ + (lib.mapAttrsToList ( + name: value: { + inherit name; + evaluated = builtins.tryEval value; + } + )) + (builtins.filter (x: x.evaluated.success)) + (map (x: { + inherit (x) name; + value = x.evaluated.value; + })) + (builtins.filter (x: lib.isDerivation x.value && (x.value.meta.available or true))) + ]; +in +stdenv.mkDerivation { + name = "rocm-tests"; + nativeBuildInputs = [ + clr + ]; + src = emptyDirectory; + postInstall = "mkdir -p $out"; + passthru.tests = { + ollama = ollama.override { + inherit rocmPackages; + acceleration = "rocm"; + }; + rocmPackagesDerivations = linkFarm "rocmPackagesDerivations" ( + map (x: { + name = x.name; + path = x.value; + }) availableRocmDrvs + ); + torch = python3Packages.torch.override { + inherit rocmPackages; + rocmSupport = true; + cudaSupport = false; + magma-hip = magma-hip.override { + inherit rocmPackages; + }; + }; + }; +} diff --git a/.devops/nix/rocm-modules-10/rocminfo/default.nix b/.devops/nix/rocm-modules-10/rocminfo/default.nix new file mode 100644 index 0000000000..68685fe198 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocminfo/default.nix @@ -0,0 +1,57 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocm-runtime, + busybox, + python3, + gnugrep, +}: + +stdenv.mkDerivation (finalAttrs: { + version = "10.0.0"; + pname = "rocminfo"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocminfo" + "shared" + ]; + hash = "sha256-GC2KKk8WBwAetGyxoy16bQXi2o+NeETyH7rK+RleNGg="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocminfo"; + + strictDeps = true; + + nativeBuildInputs = [ + cmake + rocm-cmake + python3 + ]; + + buildInputs = [ rocm-runtime ]; + cmakeFlags = [ "-DROCRTST_BLD_TYPE=Release" ]; + + prePatch = '' + patchShebangs rocm_agent_enumerator + sed 's,lsmod | grep ,${busybox}/bin/lsmod | ${gnugrep}/bin/grep ,' -i rocminfo.cc + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm Application for Reporting System Info"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rocminfo"; + license = lib.licenses.ncsa; + mainProgram = "rocminfo"; + maintainers = with lib.maintainers; [ lovesegfault ]; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocmlir/default.nix b/.devops/nix/rocm-modules-10/rocmlir/default.nix new file mode 100644 index 0000000000..ef039a40d8 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocmlir/default.nix @@ -0,0 +1,161 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + libxml2, + libedit, + rocm-comgr, + rocm-device-libs, + rocm-runtime, + zstd, + zlib, + ncurses, + python3Packages, + buildRockCompiler ? false, + buildTests ? false, # `argument of type 'NoneType' is not iterable` +}: + +# FIXME: rocmlir has an entire separate LLVM build in a subdirectory this is silly +# It seems to be forked from AMD's own LLVM +# If possible reusing the rocmPackages.llvm build would be better +# Would have to confirm it is compatible with ROCm's tagged LLVM. +# Fairly likely it's not given AMD's track record with forking their own software in incompatible ways +# in subdirs + +# Theoretically, we could have our MLIR have an output +# with the source and built objects so that we can just +# use it as the external LLVM repo for this +let + suffix = if buildRockCompiler then "-rock" else ""; + + llvmNativeTarget = + if stdenv.hostPlatform.isx86_64 then + "X86" + else if stdenv.hostPlatform.isAarch64 then + "AArch64" + else + throw "Unsupported ROCm LLVM platform"; +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocmlir${suffix}"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals (!buildRockCompiler) [ + "external" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocMLIR"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-0OvQT8pX6GbEqUwuauKGI66IHw8dsnt5mIijnzYyiRc="; + }; + + nativeBuildInputs = [ + clr + cmake + rocm-cmake + python3Packages.python + python3Packages.tomli + ]; + + buildInputs = [ + libxml2 + libedit + rocm-comgr + rocm-runtime + rocm-device-libs + ]; + + propagatedBuildInputs = [ + zstd + zlib + ncurses + ]; + + cmakeFlags = [ + (lib.cmakeFeature "LLVM_TARGETS_TO_BUILD" "AMDGPU${ + lib.optionalString (!buildRockCompiler) ";${llvmNativeTarget}" + }") + (lib.cmakeFeature "LLVM_USE_LINKER" "lld") + (lib.cmakeFeature "LLVM_ENABLE_ZSTD" "FORCE_ON") + (lib.cmakeFeature "LLVM_ENABLE_ZLIB" "FORCE_ON") + (lib.cmakeBool "LLVM_ENABLE_LIBCXX" true) + (lib.cmakeBool "LLVM_ENABLE_TERMINFO" true) + (lib.cmakeFeature "ROCM_PATH" "${clr}") + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + (lib.cmakeFeature "CMAKE_INSTALL_BINDIR" "bin") + (lib.cmakeFeature "CMAKE_INSTALL_LIBDIR" "lib") + (lib.cmakeFeature "CMAKE_INSTALL_INCLUDEDIR" "include") + (lib.cmakeBool "MLIR_ENABLE_ROCM_RUNNER" (!buildRockCompiler)) + (lib.cmakeBool "BUILD_FAT_LIBROCKCOMPILER" buildRockCompiler) + ] + ++ lib.optionals buildRockCompiler [ + (lib.cmakeBool "LLVM_INCLUDE_TESTS" false) + ] + ++ lib.optionals (!buildRockCompiler) [ + (lib.cmakeFeature "ROCM_TEST_CHIPSET" "gfx900") + ]; + + postPatch = '' + patchShebangs mlir + patchShebangs external/llvm-project/mlir/lib/Dialect/GPU/AmdDeviceLibsIncGen.py + + # Fixes mlir/lib/Analysis/BufferDependencyAnalysis.cpp:41:19: error: redefinition of 'read' + substituteInPlace mlir/lib/Analysis/BufferDependencyAnalysis.cpp \ + --replace-fail "enum EffectType { read, write, unknown };" "enum class EffectType { read, write, unknown };" + + substituteInPlace mlir/utils/performance/common/CMakeLists.txt \ + --replace-fail " PATHS /opt/rocm" "" + ''; + + dontBuild = true; + doCheck = true; + + # Certain libs aren't being generated, try enabling tests next update + checkTarget = + if buildRockCompiler then + "librockCompiler" + else if buildTests then + "check-rocmlir" + else + "check-rocmlir-build-only"; + + postInstall = + let + libPath = lib.makeLibraryPath [ + zstd + zlib + ncurses + clr + stdenv.cc.cc + ]; + in + lib.optionals (!buildRockCompiler) '' + mkdir -p $external/lib + cp -a external/llvm-project/llvm/lib/{*.a*,*.so*} $external/lib + patchelf --set-rpath $external/lib:$out/lib:${libPath} $external/lib/*.so* + patchelf --set-rpath $out/lib:$external/lib:${libPath} $out/{bin/*,lib/*.so*} + ''; + + passthru.updateScript = rocmUpdateScript { + inherit finalAttrs; + page = "tags"; + }; + + meta = { + description = "MLIR-based convolution and GEMM kernel generator"; + homepage = "https://github.com/ROCm/rocMLIR"; + license = lib.licenses.asl20; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocprim/default.nix b/.devops/nix/rocm-modules-10/rocprim/default.nix new file mode 100644 index 0000000000..f1a2c0501c --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprim/default.nix @@ -0,0 +1,97 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + gtest, + gbenchmark, + buildTests ? false, + buildBenchmarks ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocprim"; + version = "10.0.0"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocprim" + "shared" + ]; + hash = "sha256-/gJGCykUvowsXGmwUCljzvLDaaLMczsLCKxQIIjNzKI="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocprim"; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + ]; + + buildInputs = + lib.optionals buildTests [ + gtest + ] + ++ lib.optionals buildBenchmarks [ + gbenchmark + ]; + + cmakeFlags = [ + "-DHIP_CXX_COMPILER=amdclang++" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TEST=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_BENCHMARK=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/test_* $test/bin + mv $out/bin/rocprim $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/benchmark_* $benchmark/bin + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm parallel primitives"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocprim"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocprof-compute-viewer/default.nix b/.devops/nix/rocm-modules-10/rocprof-compute-viewer/default.nix new file mode 100644 index 0000000000..c14f096684 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprof-compute-viewer/default.nix @@ -0,0 +1,53 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + ninja, + nix-update-script, + qt6, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocprof-compute-viewer"; + version = "0.1.6"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocprof-compute-viewer"; + rev = finalAttrs.version; + hash = "sha256-hjwqU5TxV4p2EjGy5haQfQqItVtYMI7i/VIfrKZvqhE="; + }; + + nativeBuildInputs = [ + cmake + ninja + qt6.wrapQtAppsHook + ]; + + buildInputs = [ + qt6.qtbase + ]; + + # tries to use qt_deploy_runtime_dependencies, but wrapQtAppsHook + # handles that instead + postPatch = '' + substituteInPlace CMakeLists.txt \ + --replace-fail 'install(SCRIPT ''${deploy_script})' "" + ''; + + cmakeFlags = [ + (lib.cmakeFeature "QT_VERSION_MAJOR" "6") + (lib.cmakeBool "RCV_DISABLE_OPENGL" true) + ]; + + passthru.updateScript = nix-update-script { }; + + meta = { + description = "Visualization tool for AMD GPU thread traces from rocprofv3 --att"; + homepage = "https://github.com/ROCm/rocprof-compute-viewer"; + license = lib.licenses.mit; + platforms = lib.platforms.linux; + mainProgram = "rocprof-compute-viewer"; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocprof-trace-decoder/default.nix b/.devops/nix/rocm-modules-10/rocprof-trace-decoder/default.nix new file mode 100644 index 0000000000..6c8160830b --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprof-trace-decoder/default.nix @@ -0,0 +1,85 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmPackages, + cmake, + python3, + nlohmann_json, + gtest, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocprof-trace-decoder"; + version = "0.1.7"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + # No tags (yet?) + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocprof-trace-decoder" + "shared" + ]; + hash = "sha256-DycEdzXKcEjEybZ/IwTelbTgyaRPqVvoUDUtqhfdhQA="; + }; + + sourceRoot = "${finalAttrs.src.name}/projects/rocprof-trace-decoder"; + + patches = [ + ./use-system-dependencies.patch + # PR 3800's test-dependency fix is already in therock-10.0. + ]; + + strictDeps = true; + + nativeBuildInputs = [ cmake ]; + + buildInputs = [ + rocmPackages.rocm-comgr + rocmPackages.rocm-runtime + ]; + + cmakeFlags = [ + (lib.cmakeBool "BUILD_TESTS" finalAttrs.finalPackage.doCheck) + ]; + + nativeCheckInputs = [ + python3 + ]; + + checkInputs = [ + nlohmann_json + gtest + ]; + + preCheck = '' + patchShebangs test + ''; + + checkPhase = + let + # Sanitize tests fail because the UBSan runtime (__ubsan_vptr_type_cache) is not available for + # LD_PRELOAD in the sandbox. + skipPattern = "_sanitize$"; + in + '' + runHook preCheck + + ctest --test-dir . --output-on-failure -E '${skipPattern}' + + runHook postCheck + ''; + + # Upstream unit tests need fixtures we do not ship; not needed for gufo. + doCheck = false; + + meta = { + description = "Library for decoding ROCm thread trace data"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rocprof-trace-decoder"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocprof-trace-decoder/fix-test-dependency.patch b/.devops/nix/rocm-modules-10/rocprof-trace-decoder/fix-test-dependency.patch new file mode 100644 index 0000000000..7278ec6880 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprof-trace-decoder/fix-test-dependency.patch @@ -0,0 +1,15 @@ +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index a923cadce53..95a4d3a807f 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -186,7 +186,9 @@ if(BUILD_INTEGRATION_TESTS) + WORKING_DIRECTORY + ${TEST_BIN_DIR} + FIXTURES_REQUIRED +- unpack_data) ++ unpack_data ++ DEPENDS ++ ${DATA}_execute) + endif() + endforeach(DATA) + endif() diff --git a/.devops/nix/rocm-modules-10/rocprof-trace-decoder/use-system-dependencies.patch b/.devops/nix/rocm-modules-10/rocprof-trace-decoder/use-system-dependencies.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.devops/nix/rocm-modules-10/rocprofiler-register/default.nix b/.devops/nix/rocm-modules-10/rocprofiler-register/default.nix new file mode 100644 index 0000000000..9fe0e0c939 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-register/default.nix @@ -0,0 +1,78 @@ +{ + lib, + stdenv, + numactl, + libpciaccess, + libxml2, + elfutils, + glog, + fmt, + fetchFromGitHub, + rocmUpdateScript, + cmake, + clang, + python3Packages, + fetchpatch, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocprofiler-register"; + version = "10.0.0"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocprofiler-register" + "shared" + ]; + hash = "sha256-DmWJSQYopfkgVHFopPRthyCue87CFtPEJeClckK+GoU="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocprofiler-register"; + + # Both upstream commits nixpkgs backports here (ef7253365c42 CPackComponent, + # c8ad2522083c system fmt/glog) are already contained in therock-10.0. + patches = [ ]; + + nativeBuildInputs = [ + cmake + clang + ]; + + buildInputs = [ + numactl + libpciaccess + libxml2 + elfutils + glog + fmt + + python3Packages.lxml + python3Packages.cppheaderparser + python3Packages.pyyaml + python3Packages.barectf + python3Packages.pandas + ]; + cmakeFlags = [ + "-DROCPROFILER_REGISTER_BUILD_TESTS=0" + "-DROCPROFILER_REGISTER_BUILD_SAMPLES=0" + "-DROCPROFILER_REGISTER_BUILD_GLOG=OFF" + "-DROCPROFILER_REGISTER_BUILD_FMT=OFF" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Profiling with perf-counters and derived metrics"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rocprofiler-register"; + license = lib.licenses.mit; # mitx11 + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0001-rocprofiler-sdk-rename-consumer-test-for-dependent-c.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0001-rocprofiler-sdk-rename-consumer-test-for-dependent-c.patch new file mode 100644 index 0000000000..6090c20c47 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0001-rocprofiler-sdk-rename-consumer-test-for-dependent-c.patch @@ -0,0 +1,14 @@ +From 2868bcf8a340ecd4c564c1bd3210753fbd6aad8c Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sun, 5 Apr 2026 15:14:12 +0000 +Subject: [PATCH] [rocprofiler-sdk] rename consumer-test for dependent change + +This target has been renamed on the develop branch in +https://github.com/ROCm/rocm-systems/commit/a2288eb50bd805e5d6d7dfa98834972083e4356a, +however, that commit requires additional commits in order to apply properly. For now +it is easier to fix this by renaming this target so that the other patch applies +cleanly. +--- + .../lib/rocprofiler-sdk/counters/tests/CMakeLists.txt | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0002-rocprofiler-sdk-add-missing-stl-headers.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0002-rocprofiler-sdk-add-missing-stl-headers.patch new file mode 100644 index 0000000000..e5cd9d7238 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0002-rocprofiler-sdk-add-missing-stl-headers.patch @@ -0,0 +1,54 @@ +From af363337240fb6e4976004900b610317ba459165 Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sat, 4 Apr 2026 21:01:33 +0000 +Subject: [PATCH] [rocprofiler-sdk] add missing stl headers + +These missing includes became apparent when building with +ROCPROFILER_BUILD_GHC_FS=OFF. +--- + source/lib/att-tool/att_lib_wrapper.hpp | 2 ++ + source/lib/rocprofiler-sdk-rocpd/sql.cpp | 1 + + source/lib/rocprofiler-sdk/counters/metrics.cpp | 1 + + source/lib/rocprofiler-sdk/tests/status.cpp | 1 + + 4 files changed, 5 insertions(+) + +diff --git a/source/lib/att-tool/att_lib_wrapper.hpp b/source/lib/att-tool/att_lib_wrapper.hpp +index e7e58c5991..7dcd000a43 100644 +--- a/source/lib/att-tool/att_lib_wrapper.hpp ++++ b/source/lib/att-tool/att_lib_wrapper.hpp +@@ -28,9 +28,11 @@ + #include + + #include ++#include + #include + #include + #include ++#include + #include + + namespace rocprofiler +diff --git a/source/lib/rocprofiler-sdk-rocpd/sql.cpp b/source/lib/rocprofiler-sdk-rocpd/sql.cpp +index b052ec51c3..7e8742686e 100644 +--- a/source/lib/rocprofiler-sdk-rocpd/sql.cpp ++++ b/source/lib/rocprofiler-sdk-rocpd/sql.cpp +@@ -39,6 +39,7 @@ + #include + + #include ++#include + #include + #include + +diff --git a/source/lib/rocprofiler-sdk/counters/metrics.cpp b/source/lib/rocprofiler-sdk/counters/metrics.cpp +index 8adcf0f991..ee3391e904 100644 +--- a/source/lib/rocprofiler-sdk/counters/metrics.cpp ++++ b/source/lib/rocprofiler-sdk/counters/metrics.cpp +@@ -46,6 +46,7 @@ + #include // for dladdr + #include + #include ++#include + #include + #include + #include diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0003-rocprofiler-sdk-add-missing-rocprofiler-sdk-rocprofi.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0003-rocprofiler-sdk-add-missing-rocprofiler-sdk-rocprofi.patch new file mode 100644 index 0000000000..6289aeb8d9 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0003-rocprofiler-sdk-add-missing-rocprofiler-sdk-rocprofi.patch @@ -0,0 +1,31 @@ +From c767eafb393294214e9d25142a9eebebf234892b Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sat, 4 Apr 2026 21:20:32 +0000 +Subject: [PATCH] [rocprofiler-sdk] add missing + rocprofiler-sdk::rocprofiler-sdk-amd-comgr dependencies + +These targets, mostly tests, were missing dependencies on amd comgr. +--- + .../lib/att-tool/waitcnt/tests/CMakeLists.txt | 1 + + source/lib/python/utilities.cmake | 3 ++- + .../counters/tests/CMakeLists.txt | 13 +++++++++--- + .../pc_sampling/parser/tests/CMakeLists.txt | 20 ++++++++++++++----- + .../pc_sampling/tests/CMakeLists.txt | 4 +++- + .../lib/rocprofiler-sdk/tests/CMakeLists.txt | 2 ++ + .../thread_trace/tests/CMakeLists.txt | 1 + + 7 files changed, 34 insertions(+), 10 deletions(-) + +diff --git a/source/lib/python/utilities.cmake b/source/lib/python/utilities.cmake +index 8f51fe971b..e527278f38 100644 +--- a/source/lib/python/utilities.cmake ++++ b/source/lib/python/utilities.cmake +@@ -211,7 +211,8 @@ function(rocprofiler_rocpd_python_bindings _VERSION) + rocprofiler-sdk::rocprofiler-sdk-gotcha + rocprofiler-sdk::rocprofiler-sdk-dw + rocprofiler-sdk::rocprofiler-sdk-static-library +- rocprofiler-sdk::rocprofiler-sdk-rocpd-library) ++ rocprofiler-sdk::rocprofiler-sdk-rocpd-library ++ rocprofiler-sdk::rocprofiler-sdk-amd-comgr) + + # if "Development" is specified instead of "Development.Module", we need to link to + # python libraries diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0004-rocprofiler-sdk-fix-find_package-dependency-scoping-.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0004-rocprofiler-sdk-fix-find_package-dependency-scoping-.patch new file mode 100644 index 0000000000..a9db03cda3 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0004-rocprofiler-sdk-fix-find_package-dependency-scoping-.patch @@ -0,0 +1,80 @@ +From 33058e85d1ee985f9b622bbb2a48199eb55afc20 Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sat, 4 Apr 2026 21:34:58 +0000 +Subject: [PATCH] [rocprofiler-sdk] fix find_package dependency scoping issues + +By default, find_package() packages are only made visible to the current +scope. add_subdirectory() enters a new scope, so the packages searched for +in external/CMakeLists.txt are not visible in any other CMake files. This +causes dependency errors for these dependencies. find_package() packages can +be made visible to the entire project by supplying the GLOBAL argument. + +The GLOBAL keyword was added in CMake version 3.24, hence the minimum required +version is also bumped. Other projects across rocm-systems (rocprofiler-register) +also already require CMake 3.24, so that should not cause any problems. + +See https://github.com/ROCm/rocm-systems/pull/1243, that change fixes the +same problem in rocprofiler-register. +--- + CMakeLists.txt | 2 +- + external/CMakeLists.txt | 8 ++++---- + requirements.txt | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 25f335afb3..0d86e05170 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 3.21 FATAL_ERROR) ++cmake_minimum_required(VERSION 3.24 FATAL_ERROR) + + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND CMAKE_CURRENT_SOURCE_DIR STREQUAL + CMAKE_SOURCE_DIR) +diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt +index cab59c07bd..fcc872d118 100644 +--- a/external/CMakeLists.txt ++++ b/external/CMakeLists.txt +@@ -64,7 +64,7 @@ if(ROCPROFILER_BUILD_TESTS) + mark_as_advanced(BUILD_GMOCK) + mark_as_advanced(GTEST_HAS_ABSL) + else() +- find_package(GTest REQUIRED) ++ find_package(GTest REQUIRED GLOBAL) + target_link_libraries(rocprofiler-sdk-gtest INTERFACE GTest::gtest) + endif() + endif() +@@ -111,7 +111,7 @@ if(ROCPROFILER_BUILD_FMT) + rocprofiler-sdk-fmt SYSTEM + INTERFACE $) + else() +- find_package(fmt REQUIRED) ++ find_package(fmt REQUIRED GLOBAL) + target_link_libraries(rocprofiler-sdk-fmt INTERFACE fmt::fmt) + endif() + +@@ -147,7 +147,7 @@ if(ROCPROFILER_BUILD_YAML_CPP) + rocprofiler-sdk-yaml-cpp + INTERFACE $) + else() +- find_package(yaml-cpp 0.8.0 REQUIRED) ++ find_package(yaml-cpp 0.8.0 REQUIRED GLOBAL) + target_link_libraries(rocprofiler-sdk-yaml-cpp INTERFACE yaml-cpp::yaml-cpp) + endif() + +diff --git a/requirements.txt b/requirements.txt +index de7421da0d..3eb60c088b 100644 +--- a/requirements.txt ++++ b/requirements.txt +@@ -1,7 +1,7 @@ + black + clang-format>=11.0.0,<12.0.0 + clang-tidy>=15.0.0,<20.0.0 +-cmake>=3.21.0 ++cmake>=3.24.0 + cmake-format + dataclasses + flake8 +-- +2.43.0 + diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0005-rocprofiler-sdk-allow-using-system-elfio-dependency.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0005-rocprofiler-sdk-allow-using-system-elfio-dependency.patch new file mode 100644 index 0000000000..9652b8eb21 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0005-rocprofiler-sdk-allow-using-system-elfio-dependency.patch @@ -0,0 +1,76 @@ +From 40b1abf9d3ec8eb3f798946263f144988fa3a416 Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sat, 4 Apr 2026 21:50:57 +0000 +Subject: [PATCH] [rocprofiler-sdk] allow using system elfio dependency + +This adds a new option, ROCPROFILER_BUILD_ELFIO, which can be set to OFF to +make rocprofiler use a system dependency for ELFIO instead of trying to build +it manually. To mimick old behavior, ROCPROFILER_BUILD_ELFIO is set to ON by +default. + +Related: https://github.com/ROCm/rocm-systems/pull/2319 +--- + cmake/rocprofiler_options.cmake | 2 ++ + external/CMakeLists.txt | 33 +++++++++++++++++++-------------- + 2 files changed, 21 insertions(+), 14 deletions(-) + +diff --git a/cmake/rocprofiler_options.cmake b/cmake/rocprofiler_options.cmake +index c29311cc8c..da9ee9ad29 100644 +--- a/cmake/rocprofiler_options.cmake ++++ b/cmake/rocprofiler_options.cmake +@@ -67,6 +67,8 @@ rocprofiler_add_option(ROCPROFILER_BUILD_GOTCHA + "Enable building gotcha library internally" ON) + rocprofiler_add_option(ROCPROFILER_BUILD_YAML_CPP + "Enable building yaml-cpp library internally" ON) ++rocprofiler_add_option(ROCPROFILER_BUILD_ELFIO "Enable building ELFIO library internally" ++ ON) + if(ROCPROFILER_BUILD_TESTS) + rocprofiler_add_option( + ROCPROFILER_BUILD_GTEST +diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt +index fcc872d118..ade8d25c1b 100644 +--- a/external/CMakeLists.txt ++++ b/external/CMakeLists.txt +@@ -201,20 +201,25 @@ target_link_libraries( + INTERFACE $) + + # ELFIO +-rocprofiler_checkout_git_submodule( +- RECURSIVE +- RELATIVE_PATH external/elfio +- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +- REPO_URL https://github.com/serge1/ELFIO.git +- REPO_BRANCH "Release_3.12") +- +-set(ELFIO_BUILD_EXAMPLES OFF) +-set(ELFIO_BUILD_TESTS OFF) +-add_subdirectory(elfio EXCLUDE_FROM_ALL) +-if(TARGET rocprofiler-sdk-elfio) +- get_target_property(ELFIO_INCLUDE_DIR elfio::elfio INTERFACE_INCLUDE_DIRECTORIES) +- target_include_directories(rocprofiler-sdk-elfio SYSTEM +- INTERFACE ${ELFIO_INCLUDE_DIR}) ++if(ROCPROFILER_BUILD_ELFIO) ++ rocprofiler_checkout_git_submodule( ++ RECURSIVE ++ RELATIVE_PATH external/elfio ++ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ++ REPO_URL https://github.com/serge1/ELFIO.git ++ REPO_BRANCH "Release_3.12") ++ ++ set(ELFIO_BUILD_EXAMPLES OFF) ++ set(ELFIO_BUILD_TESTS OFF) ++ add_subdirectory(elfio EXCLUDE_FROM_ALL) ++ if(TARGET rocprofiler-sdk-elfio) ++ get_target_property(ELFIO_INCLUDE_DIR elfio::elfio INTERFACE_INCLUDE_DIRECTORIES) ++ target_include_directories(rocprofiler-sdk-elfio SYSTEM ++ INTERFACE ${ELFIO_INCLUDE_DIR}) ++ endif() ++else() ++ find_package(elfio REQUIRED GLOBAL) ++ target_link_libraries(rocprofiler-sdk-elfio INTERFACE elfio::elfio) + endif() + + # +-- +2.43.0 + diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0006-rocprofiler-sdk-allow-using-system-otf2-dependency.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0006-rocprofiler-sdk-allow-using-system-otf2-dependency.patch new file mode 100644 index 0000000000..5eab70166b --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0006-rocprofiler-sdk-allow-using-system-otf2-dependency.patch @@ -0,0 +1,53 @@ +From 0f81ad1a46df9da7c9653812eded2165d0cd794d Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sat, 4 Apr 2026 21:58:13 +0000 +Subject: [PATCH] [rocprofiler-sdk] allow using system otf2 dependency + +This adds a new option, ROCPROFILER_BUILD_OTF2, which can be set to OFF to +make rocprofiler-sdk use a system dependency for OTF2 instead of trying to +build it manually. To mimick old behavior, ROCPROFILER_BUILD_OTF2 is set to +ON by default. + +Related: https://github.com/ROCm/rocm-systems/pull/2319 +--- + cmake/rocprofiler_options.cmake | 2 ++ + external/CMakeLists.txt | 10 +++++++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/cmake/rocprofiler_options.cmake b/cmake/rocprofiler_options.cmake +index da9ee9ad29..077898a520 100644 +--- a/cmake/rocprofiler_options.cmake ++++ b/cmake/rocprofiler_options.cmake +@@ -69,6 +69,8 @@ rocprofiler_add_option(ROCPROFILER_BUILD_YAML_CPP + "Enable building yaml-cpp library internally" ON) + rocprofiler_add_option(ROCPROFILER_BUILD_ELFIO "Enable building ELFIO library internally" + ON) ++rocprofiler_add_option(ROCPROFILER_BUILD_OTF2 "Enable building OTF2 library internally" ++ ON) + if(ROCPROFILER_BUILD_TESTS) + rocprofiler_add_option( + ROCPROFILER_BUILD_GTEST +diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt +index ade8d25c1b..0c5d4e5fe5 100644 +--- a/external/CMakeLists.txt ++++ b/external/CMakeLists.txt +@@ -225,7 +225,15 @@ endif() + # + # OTF2 + # +-add_subdirectory(otf2) ++if(ROCPROFILER_BUILD_OTF2) ++ add_subdirectory(otf2) ++else() ++ find_package(PkgConfig REQUIRED) ++ pkg_check_modules(OTF2 REQUIRED IMPORTED_TARGET otf2) ++ add_library(otf2 INTERFACE) ++ add_library(otf2::otf2 ALIAS otf2) ++ target_link_libraries(otf2 INTERFACE PkgConfig::OTF2) ++endif() + + rocprofiler_checkout_git_submodule( + RECURSIVE +-- +2.43.0 + diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0007-rocprofiler-sdk-Allow-using-system-json-dependency.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0007-rocprofiler-sdk-Allow-using-system-json-dependency.patch new file mode 100644 index 0000000000..57d77fdf14 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0007-rocprofiler-sdk-Allow-using-system-json-dependency.patch @@ -0,0 +1,73 @@ +From fda4ff3c2389a5a8b57d44fd9be715ade37d576e Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sat, 4 Apr 2026 22:01:44 +0000 +Subject: [PATCH] [rocprofiler-sdk] Allow using system json dependency + +This adds a new option, ROCPROFILER_BUILD_JSON, which can be set to OFF to +make rocprofiler-sdk use a system dependency for nlohmann_json instead of trying +to build it manually. To mimick old behavior, ROCPROFILER_BUILD_JSON is set to +ON by default. + +Related: https://github.com/ROCm/rocm-systems/pull/2319 +--- + cmake/rocprofiler_options.cmake | 2 ++ + external/CMakeLists.txt | 27 ++++++++++++++++----------- + 2 files changed, 18 insertions(+), 11 deletions(-) + +diff --git a/cmake/rocprofiler_options.cmake b/cmake/rocprofiler_options.cmake +index 077898a520..e35a41c95c 100644 +--- a/cmake/rocprofiler_options.cmake ++++ b/cmake/rocprofiler_options.cmake +@@ -71,6 +71,8 @@ rocprofiler_add_option(ROCPROFILER_BUILD_ELFIO "Enable building ELFIO library in + ON) + rocprofiler_add_option(ROCPROFILER_BUILD_OTF2 "Enable building OTF2 library internally" + ON) ++rocprofiler_add_option(ROCPROFILER_BUILD_JSON "Enable building JSON library internally" ++ ON) + if(ROCPROFILER_BUILD_TESTS) + rocprofiler_add_option( + ROCPROFILER_BUILD_GTEST +diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt +index 0c5d4e5fe5..b943be5ad6 100644 +--- a/external/CMakeLists.txt ++++ b/external/CMakeLists.txt +@@ -235,20 +235,25 @@ else() + target_link_libraries(otf2 INTERFACE PkgConfig::OTF2) + endif() + +-rocprofiler_checkout_git_submodule( +- RECURSIVE +- RELATIVE_PATH external/json +- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +- REPO_URL https://github.com/nlohmann/json.git +- REPO_BRANCH "develop") +- + # + # JSON + # +-add_subdirectory(json) +-target_include_directories( +- rocprofiler-sdk-json SYSTEM +- INTERFACE $) ++if(ROCPROFILER_BUILD_JSON) ++ rocprofiler_checkout_git_submodule( ++ RECURSIVE ++ RELATIVE_PATH external/json ++ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ++ REPO_URL https://github.com/nlohmann/json.git ++ REPO_BRANCH "develop") ++ ++ add_subdirectory(json) ++ target_include_directories( ++ rocprofiler-sdk-json SYSTEM ++ INTERFACE $) ++else() ++ find_package(nlohmann_json REQUIRED GLOBAL) ++ target_link_libraries(rocprofiler-sdk-json INTERFACE nlohmann_json::nlohmann_json) ++endif() + + # + # SQLite3 +-- +2.43.0 + diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0008-rocprofiler-sdk-stop-manually-setting-warning-flags-.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0008-rocprofiler-sdk-stop-manually-setting-warning-flags-.patch new file mode 100644 index 0000000000..8e8325448e --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0008-rocprofiler-sdk-stop-manually-setting-warning-flags-.patch @@ -0,0 +1,30 @@ +From ae4cffc06a368893d91be2739bb6482182681efc Mon Sep 17 00:00:00 2001 +From: Robin Voetter +Date: Sat, 4 Apr 2026 22:22:56 +0000 +Subject: [PATCH] [rocprofiler-sdk] stop manually setting warning flags on + integration tests + +The primary motivation for this change is that -Werror is added to the compiler +options unconditionally, which causes problems when compiling these tests during +downstream packaging builds. The rocprofiler-sdk::tests-build-flags and +rocprofiler-sdk::tests-common targets already include these warning flags, and this +target also already handles setting -Werror conditionally based on ROCPROF_BUILD_WERROR. +Some integration tests also set -Wpedantic, these have been left as-is. When +ROCPROF_BUILD_WERROR is set to ON (default), behavior is the same as before this commit. +--- + tests/bin/attachment-test/CMakeLists.txt | 6 +++--- + tests/bin/hip-graph/CMakeLists.txt | 5 +++-- + tests/bin/hip-in-libraries/CMakeLists.txt | 6 +++--- + tests/bin/hsa-code-object/CMakeLists.txt | 1 - + tests/bin/hsa-memory-allocation/CMakeLists.txt | 3 +-- + tests/bin/hsa-queue-dependency/CMakeLists.txt | 1 - + tests/bin/multistream/CMakeLists.txt | 5 +++-- + .../bin/pc-sampling/exec-mask-manipulation/CMakeLists.txt | 6 +++--- + tests/bin/reproducible-dispatch-count/CMakeLists.txt | 8 ++++---- + tests/bin/reproducible-runtime/CMakeLists.txt | 8 ++++---- + tests/bin/scratch-memory/CMakeLists.txt | 3 +-- + tests/bin/simple-transpose/CMakeLists.txt | 8 ++++---- + tests/bin/transpose/CMakeLists.txt | 2 +- + tests/bin/vector-operations/CMakeLists.txt | 2 +- + 14 files changed, 31 insertions(+), 33 deletions(-) + diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/0009-rocprofiler-sdk-guard-ompt-auto-start.patch b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0009-rocprofiler-sdk-guard-ompt-auto-start.patch new file mode 100644 index 0000000000..147d794833 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/0009-rocprofiler-sdk-guard-ompt-auto-start.patch @@ -0,0 +1,50 @@ +From 502d2df0ddd84f0f2fa718b9a02ee0f01f36dac1 Mon Sep 17 00:00:00 2001 +From: Luna Nova +Date: Tue, 2 Jun 2026 01:31:05 -0700 +Subject: [PATCH] [rocprofiler-sdk] don't auto-start OMPT tool before glog is + initialized + +The OpenMP runtime resolves its weak ompt_start_tool to the strong symbol we +export and calls it during OpenMP init. That can fire from an unrelated +library's constructor (observed: OpenBLAS calling omp_get_num_places) while +librocprofiler-sdk is still being dlopen'd. init_logging() then dereferences +glog's gflags FLAGS_vmodule, whose backing pointer is still null until glog's +static initializers run, and the process segfaults on `import torch`. + +The init order is not reliably fixable from here: a dependency cycle among the +ROCm libraries makes the loader run our constructors before libglog's, so a +flag set by our own constructor does not imply glog is ready. Instead gate the +tool start on glog itself, by testing whether gflags has populated FLAGS_vmodule +yet; reading the raw pointer is safe even before construction. It is read via an +asm label because the gflags header only exposes it as a reference, which the +compiler assumes is never null. Declining (nullptr) when glog is not yet ready +is a valid OMPT "no tool" response; deliberate profiling (rocprofv3 preloads the +tool early, before such constructors) is unaffected. +--- + source/lib/rocprofiler-sdk/ompt.cpp | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/source/lib/rocprofiler-sdk/ompt.cpp b/source/lib/rocprofiler-sdk/ompt.cpp +index a9ccc57..3231087 100644 +--- a/source/lib/rocprofiler-sdk/ompt.cpp ++++ b/source/lib/rocprofiler-sdk/ompt.cpp +@@ -199,6 +199,8 @@ finalize_ompt() + } // namespace ompt + } // namespace rocprofiler + ++extern void* const rocprofiler_glog_vmodule_flag asm("_ZN3fLS13FLAGS_vmoduleB5cxx11E"); ++ + extern "C" { + + rocprofiler_status_t +@@ -245,6 +247,8 @@ ompt_start_tool(unsigned int omp_version, const char* runtime_version) ROCPROFIL + ompt_start_tool_result_t* + ompt_start_tool(unsigned int omp_version, const char* runtime_version) + { ++ if(rocprofiler_glog_vmodule_flag == nullptr) return nullptr; ++ + ::rocprofiler::registration::init_logging(); + ::rocprofiler::registration::initialize(); + return rocprofiler_ompt_start_tool(omp_version, runtime_version); +-- +2.54.0 diff --git a/.devops/nix/rocm-modules-10/rocprofiler-sdk/default.nix b/.devops/nix/rocm-modules-10/rocprofiler-sdk/default.nix new file mode 100644 index 0000000000..b2f9167717 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler-sdk/default.nix @@ -0,0 +1,226 @@ +{ + lib, + stdenv, + fetchFromGitHub, + cmake, + symlinkJoin, + git, + ninja, + pkg-config, + clr, + rocm-cmake, + rocm-runtime, + rocprofiler-register, + rocprof-trace-decoder, + aqlprofile, + rocm-comgr, + rocmUpdateScript, + python3, + python3Packages, + libdrm, + elfutils, + sqlite, + otf2, + zlib, + zstd, + xz, + numactl, + fmt, + glog, + gtest, + fetchpatch, + yaml-cpp, + elfio, + nlohmann_json, + makeWrapper, + gpuTargets ? (clr.localGpuTargets or clr.gpuTargets), + buildTests ? false, + buildSamples ? false, +}: + +# FIXME: devendor remaining git submodules: +# external/cereal -> https://github.com/jrmadsen/cereal +# external/gotcha -> https://github.com/jrmadsen/GOTCHA +# external/perfetto -> https://github.com/google/perfetto +# external/ptl -> https://github.com/jrmadsen/PTL + +# rocprofiler-sdk is the home of rocprofv3 +let + # ROCm 10 folded aqlprofile in (pm4_factory.cpp needs ) + # and added the rocpd SQL layer (needs ). Neither subproject picks + # up the wrapper's include paths, and cmakeFlags is a structuredAttrs array so + # two -I flags cannot share one entry: merge both dev trees into one prefix. + extraIncludes = symlinkJoin { + name = "rocprofiler-sdk-extra-includes"; + paths = [ + (lib.getDev libdrm) + (lib.getDev sqlite) + ]; + }; +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocprofiler-sdk"; + version = "10.0.0"; + + outputs = [ + "out" + "dev" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + hash = "sha256-N83wTDI6R66pOnDdxYIS9SZy64o1fyHzj7awRJKXNp0="; + fetchSubmodules = true; + sparseCheckout = [ + "projects/rocprofiler-sdk" + ]; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocprofiler-sdk"; + + strictDeps = true; + + nativeBuildInputs = [ + # ROCm 10's rocprofiler-sdk-tool does find_package(Git REQUIRED) + git + cmake + ninja + pkg-config + clr + python3 + makeWrapper + ]; + + buildInputs = [ + clr + rocm-cmake + rocm-runtime + rocprofiler-register + # ROCm 10's rocprofiler-sdk-tool does find_package(rocprof-trace-decoder REQUIRED) + rocprof-trace-decoder + aqlprofile + rocm-comgr + libdrm + # ROCm 10 folded aqlprofile in (needs ) and added the + # rocpd SQL layer (needs ); both live in the dev outputs. + (lib.getDev libdrm) + (lib.getDev sqlite) + elfutils + sqlite + otf2 + zlib + zstd + xz + numactl + fmt + glog + gtest + yaml-cpp + elfio + nlohmann_json + python3Packages.pybind11 + ]; + + # The three upstream commits nixpkgs backports (system libraries, fmt memory + # header, comgr linkage in the pc-sampling test) are already in therock-10.0. + # The local PR 4721 series is still required: without it the build falls back + # to FetchContent and tries to download elfio/otf2/json during the build. + patches = [ + # 0001 only renamed the consumer test so the rest of the series applied to + # 7.2.3; therock-10.0 already carries that rename. + # 0002 only added /// includes that + # therock-10.0 already has. + ./0003-rocprofiler-sdk-add-missing-rocprofiler-sdk-rocprofi.patch + ./0004-rocprofiler-sdk-fix-find_package-dependency-scoping-.patch + ./0005-rocprofiler-sdk-allow-using-system-elfio-dependency.patch + ./0006-rocprofiler-sdk-allow-using-system-otf2-dependency.patch + ./0007-rocprofiler-sdk-Allow-using-system-json-dependency.patch + # 0008 only touched test targets, so nothing of it survives with tests off. + ]; + + postPatch = '' + # ROCm 10 still misses these STL includes (nixpkgs' 0002 patch no longer + # applies as a whole, but these three files genuinely need them). + sed -i '0,/#include/s//#include \n#include/' \ + source/lib/rocprofiler-sdk-rocpd/sql.cpp + sed -i '0,/#include/s//#include \n#include/' \ + source/lib/rocprofiler-sdk/counters/metrics.cpp + sed -i '0,/#include/s//#include \n#include \n#include/' \ + source/lib/att-tool/att_lib_wrapper.hpp + sed -i '0,/#include/s//#include \n#include/' \ + source/lib/rocprofiler-sdk-rocattach/auxv.cpp + # NixOS' ROCm distribution does not support libomptarget yet + substituteInPlace samples/CMakeLists.txt \ + --replace-fail 'add_subdirectory(openmp_target)' '# add_subdirectory(openmp_target)' + substituteInPlace tests/CMakeLists.txt \ + --replace-fail 'add_subdirectory(openmp-tools)' '# add_subdirectory(openmp-tools)' + substituteInPlace tests/bin/CMakeLists.txt \ + --replace-fail 'add_subdirectory(openmp)' '# add_subdirectory(openmp)' + + # This requires building perfetto's trace-processor-shell via a weird external script + substituteInPlace tests/CMakeLists.txt \ + --replace-fail 'add_subdirectory(pytest-packages)' "" + + patchShebangs source/libexec/rocprofiler-sdk/rocprofiler-sdk-launch-compiler/rocprofiler-sdk-launch-compiler.sh + ''; + + cmakeFlags = [ + (lib.cmakeBool "ROCPROFILER_BUILD_GHC_FS" false) + (lib.cmakeBool "ROCPROFILER_BUILD_FMT" false) + (lib.cmakeBool "ROCPROFILER_BUILD_GLOG" false) + (lib.cmakeBool "ROCPROFILER_BUILD_GTEST" false) + (lib.cmakeBool "ROCPROFILER_BUILD_PYBIND11" false) + (lib.cmakeBool "ROCPROFILER_BUILD_YAML_CPP" false) + (lib.cmakeBool "ROCPROFILER_BUILD_ELFIO" false) + (lib.cmakeBool "ROCPROFILER_BUILD_OTF2" false) + (lib.cmakeBool "ROCPROFILER_BUILD_JSON" false) + (lib.cmakeBool "ROCPROFILER_BUILD_TESTS" buildTests) + (lib.cmakeBool "ROCPROFILER_BUILD_SAMPLES" buildSamples) + (lib.cmakeBool "ROCPROFILER_BUILD_BENCHMARK" false) + (lib.cmakeBool "ROCPROFILER_BUILD_WERROR" false) + # rocprofiler-sdk's CMake file doesn't add this dependency properly. + "-DCMAKE_HIP_FLAGS=-I${rocm-runtime}/include" + "-DCMAKE_CXX_FLAGS=-I${extraIncludes}/include" + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + # Required for rocprofiler-sdk-launch-compiler.sh + "-DCMAKE_INSTALL_LIBEXECDIR=libexec" + "--debug-find-pkg=amd_comgr" + "--trace-source=tests/pc_sampling/CMakeLists.txt" + "--trace-expand" + ] + ++ lib.optionals (buildTests || buildSamples) [ + # rocprofiler-sdk normally doesn't depend on which GPU is in the system, only when + # building tests or samples. + (lib.cmakeFeature "GPU_TARGETS" (lib.concatStringsSep ";" gpuTargets)) + ]; + + doCheck = false; # Requires GPU + + postFixup = '' + patchelf $out/lib/*.so \ + --add-rpath ${aqlprofile}/lib \ + --add-needed libhsa-amd-aqlprofile64.so + + wrapProgram $out/bin/rocprofv3 --add-flags "--att-library-path ${ + lib.makeLibraryPath [ rocprof-trace-decoder ] + }" + ''; + + postInstall = '' + mkdir -p $dev/lib $dev/share/rocprofiler-sdk + mv $out/lib/cmake $dev/lib/ + mv $out/share/rocprofiler-sdk/{samples,tests} $dev/share/rocprofiler-sdk/ + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm GPU performance analysis SDK"; + homepage = "https://github.com/ROCm/rocprofiler-sdk"; + license = lib.licenses.mit; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocprofiler/default.nix b/.devops/nix/rocm-modules-10/rocprofiler/default.nix new file mode 100644 index 0000000000..21b5d4b0e3 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocprofiler/default.nix @@ -0,0 +1,141 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + symlinkJoin, + cmake, + clang, + clr, + aqlprofile, + rocm-core, + rocm-runtime, + rocm-device-libs, + roctracer, + rocdbgapi, + numactl, + libpciaccess, + libxml2, + llvm, + elfutils, + mpi, + gtest, + python3Packages, + gpuTargets ? clr.gpuTargets, +}: + +let + rocmtoolkit-merged = symlinkJoin { + name = "rocmtoolkit-merged"; + + paths = [ + rocm-core + rocm-runtime + rocm-device-libs + roctracer + rocdbgapi + clr + ]; + + postBuild = '' + rm -rf $out/nix-support + ''; + }; +in +stdenv.mkDerivation (finalAttrs: { + pname = "rocprofiler"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rocprofiler" + "shared" + ]; + fetchSubmodules = true; + hash = "sha256-Wo0pymD8LsrdczdIUEEVe5x2Id//KIFkh40kliAQgWo="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocprofiler"; + + nativeBuildInputs = [ + cmake + clang + clr + python3Packages.lxml + python3Packages.cppheaderparser + python3Packages.pyyaml + python3Packages.barectf + python3Packages.pandas + ]; + + buildInputs = [ + llvm.clang-unwrapped + llvm.llvm + numactl + libpciaccess + libxml2 + elfutils + mpi + gtest + aqlprofile + ]; + + propagatedBuildInputs = [ rocmtoolkit-merged ]; + + #HACK: rocprofiler's cmake doesn't add these deps properly + env.CXXFLAGS = "-I${libpciaccess}/include -I${numactl.dev}/include -I${rocmtoolkit-merged}/include -I${elfutils.dev}/include -w"; + + cmakeFlags = [ + "-DCMAKE_MODULE_PATH=${clr}/lib/cmake/hip" + "-DHIP_ROOT_DIR=${clr}" + "-DGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + postPatch = '' + patchShebangs . + + substituteInPlace cmake_modules/rocprofiler_utils.cmake \ + --replace-fail 'function(ROCPROFILER_CHECKOUT_GIT_SUBMODULE)' 'function(ROCPROFILER_CHECKOUT_GIT_SUBMODULE) + return()' + + substituteInPlace CMakeLists.txt \ + --replace-fail 'set(ROCPROFILER_BUILD_TESTS ON)' "" + + substituteInPlace tests-v2/featuretests/profiler/CMakeLists.txt \ + --replace "--build-id=sha1" "--build-id=sha1 --rocm-path=${clr} --rocm-device-lib-path=${rocm-device-libs}/amdgcn/bitcode" + + substituteInPlace test/CMakeLists.txt \ + --replace "\''${ROCM_ROOT_DIR}/amdgcn/bitcode" "${rocm-device-libs}/amdgcn/bitcode" + ''; + + postInstall = '' + # Why do these have the executable bit set? + chmod -x $out/libexec/rocprofiler/counters/*.xml + # rocprof shell script wants to find it in the same bin dir, easiest to symlink in + ln -s ${clr}/bin/rocm_agent_enumerator $out/bin/rocm_agent_enumerator + ''; + + postFixup = '' + patchelf $out/lib/*.so \ + --add-rpath ${aqlprofile}/lib \ + --add-needed libhsa-amd-aqlprofile64.so + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + passthru.rocmtoolkit-merged = rocmtoolkit-merged; + + meta = { + description = "Profiling with perf-counters and derived metrics"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/rocprofiler"; + license = lib.licenses.mit; # mitx11 + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocr-debug-agent/default.nix b/.devops/nix/rocm-modules-10/rocr-debug-agent/default.nix new file mode 100644 index 0000000000..dc10ed2347 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocr-debug-agent/default.nix @@ -0,0 +1,55 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + python3, + clr, + rocdbgapi, + elfutils, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocr-debug-agent"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocr_debug_agent"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-w2Zg4kpuKy68DkVGsBTUsjRZoV/Y/Z3Q8s0oSIR3Ask="; + }; + + nativeBuildInputs = [ + cmake + clr + python3 # TODO: check for scripts that need patchShebangs in output + ]; + + buildInputs = [ + rocdbgapi + elfutils + ]; + + cmakeFlags = [ + "-DCMAKE_MODULE_PATH=${clr}/lib/cmake/hip" + "-DHIP_ROOT_DIR=${clr}" + "-DHIP_PATH=${clr}" + ]; + + # Weird install target + postInstall = '' + rm -rf $out/src + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Library that provides some debugging functionality for ROCr"; + homepage = "https://github.com/ROCm/rocr_debug_agent"; + license = lib.licenses.ncsa; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocrand/default.nix b/.devops/nix/rocm-modules-10/rocrand/default.nix new file mode 100644 index 0000000000..ba292a1f5f --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocrand/default.nix @@ -0,0 +1,98 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + clr, + gtest, + gbenchmark, + buildTests ? false, + buildBenchmarks ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocrand${clr.gpuArchSuffix}"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rocrand" + "shared" + ]; + hash = "sha256-tl++h7LSEXf0jWe007+RIRwYHdB6TKPDpzipj1Emew8="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocrand"; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + ]; + + buildInputs = + lib.optionals buildTests [ + gtest + ] + ++ lib.optionals buildBenchmarks [ + gbenchmark + ]; + + cmakeFlags = [ + "-DHIP_ROOT_DIR=${clr}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TEST=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_BENCHMARK=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/test_* $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/benchmark_* $benchmark/bin + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rm -r $out/bin/rocRAND + # Fail if bin/ isn't actually empty + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Generate pseudo-random and quasi-random numbers"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocrand"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocshmem/default.nix b/.devops/nix/rocm-modules-10/rocshmem/default.nix new file mode 100644 index 0000000000..b7bac8646f --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocshmem/default.nix @@ -0,0 +1,70 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocm-core, + rocm-runtime, + clr, + mpi, + useMpi ? true, + useReverseOffload ? useMpi, + buildExamples ? false, + gpuTargets ? (clr.localGpuTargets or [ ]), +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocshmem${clr.gpuArchSuffix}"; + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocSHMEM"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-7TiUABwCVPvosoLdR8zN+QGiX+OD7iD+HKMLnGMmRYA="; + }; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + ]; + + buildInputs = [ + rocm-runtime + ] + ++ lib.optionals useMpi [ + mpi + ]; + + cmakeFlags = [ + (lib.cmakeFeature "CMAKE_BUILD_TYPE" "Release") + (lib.cmakeBool "CMAKE_POSITION_INDEPENDENT_CODE" true) + (lib.cmakeFeature "CMAKE_CXX_COMPILER" "hipcc") + (lib.cmakeFeature "ROCM_PATH" "${clr}") + (lib.cmakeFeature "ROCM_VERSION" rocm-core.ROCM_LIBPATCH_VERSION) + (lib.cmakeBool "USE_IPC" true) + (lib.cmakeBool "USE_RO" useReverseOffload) + (lib.cmakeBool "USE_SINGLE_NODE" (!useMpi)) + (lib.cmakeBool "USE_EXTERNAL_MPI" useMpi) + (lib.cmakeBool "BUILD_EXAMPLES" buildExamples) + (lib.cmakeFeature "CMAKE_INSTALL_BINDIR" "bin") + (lib.cmakeFeature "CMAKE_INSTALL_LIBDIR" "lib") + (lib.cmakeFeature "CMAKE_INSTALL_INCLUDEDIR" "include") + ] + ++ lib.optionals (gpuTargets != [ ]) [ + (lib.cmakeFeature "GPU_TARGETS" (lib.concatStringsSep ";" gpuTargets)) + ]; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "The ROCm OpenSHMEM (rocSHMEM) runtime"; + homepage = "https://github.com/ROCm/rocSHMEM"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocsolver/default.nix b/.devops/nix/rocm-modules-10/rocsolver/default.nix new file mode 100644 index 0000000000..3185b204c1 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocsolver/default.nix @@ -0,0 +1,136 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocblas, + rocprim, + rocsparse, + clr, + fmt, + gtest, + gfortran, + lapack-reference, + buildTests ? false, + buildBenchmarks ? false, + gpuTargets ? ( + clr.localGpuTargets or [ + "gfx900" + "gfx906" + "gfx908" + "gfx90a" + "gfx942" + "gfx1010" + "gfx1030" + "gfx1100" + "gfx1101" + "gfx1102" + "gfx1150" + "gfx1151" + "gfx1200" + "gfx1201" + ] + ), +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocsolver${clr.gpuArchSuffix}"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rocsolver" + "shared" + ]; + hash = "sha256-n+Y8RheA0UYeSfpvOw5zfwe4VAW5hsKjlCXtBceGhf0="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocsolver"; + + nativeBuildInputs = [ + cmake + # no ninja, it buffers console output and nix times out long periods of no output + rocm-cmake + clr + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + gfortran + ]; + + buildInputs = [ + # FIXME: rocblas and rocsolver can't build in parallel + # but rocsolver doesn't need rocblas' offload builds at build time + # could we build against a rocblas-minimal? + rocblas + rocprim + rocsparse + fmt + ] + ++ lib.optionals buildTests [ + gtest + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + lapack-reference + ]; + + cmakeFlags = [ + "-DHIP_CLANG_NUM_PARALLEL_JOBS=4" + "-DCMAKE_BUILD_TYPE=Release" + "-DCMAKE_VERBOSE_MAKEFILE=ON" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_CLIENTS_TESTS=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_CLIENTS_BENCHMARKS=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/rocsolver-test $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/rocsolver-bench $benchmark/bin + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rmdir $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + requiredSystemFeatures = [ "big-parallel" ]; + + meta = { + description = "ROCm LAPACK implementation"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocsolver"; + license = lib.licenses.bsd2; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + timeout = 14400; # 4 hours + maxSilent = 14400; # 4 hours + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocsparse/default.nix b/.devops/nix/rocm-modules-10/rocsparse/default.nix new file mode 100644 index 0000000000..b6712be8ff --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocsparse/default.nix @@ -0,0 +1,159 @@ +{ + lib, + stdenv, + fetchFromGitHub, + fetchzip, + rocmUpdateScript, + cmake, + rocm-cmake, + rocprim, + rocblas, + clr, + gfortran, + gtest, + boost, + python3Packages, + buildTests ? false, + buildBenchmarks ? false, # Seems to depend on tests + gpuTargets ? clr.localGpuTargets or clr.gpuTargets, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocsparse${clr.gpuArchSuffix}"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rocsparse" + "shared" + ]; + hash = "sha256-hkfBTcLig39al2w8zFTSQQnouaou9wlD6VlvIyFTNMg="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocsparse"; + + nativeBuildInputs = [ + cmake + # no ninja, it buffers console output and nix times out long periods of no output + rocm-cmake + clr + gfortran + ]; + + buildInputs = [ + rocprim + rocblas + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + gtest + boost + python3Packages.python + python3Packages.pyyaml + ]; + + cmakeFlags = [ + "-DCMAKE_CXX_COMPILER=amdclang++" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + "-DBUILD_CLIENTS_TESTS=ON" + "-DCMAKE_MATRICES_DIR=/build/source/matrices" + "-Dpython=python3" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_CLIENTS_BENCHMARKS=ON" + ]; + + # We have to manually generate the matrices + postPatch = lib.optionalString (buildTests || buildBenchmarks) '' + mkdir -p matrices + + ln -s ${finalAttrs.passthru.matrices.matrix-01}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-02}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-03}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-04}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-05}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-06}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-07}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-08}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-09}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-10}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-11}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-12}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-13}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-14}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-15}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-16}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-17}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-18}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-19}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-20}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-21}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-22}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-23}/*.mtx matrices + ln -s ${finalAttrs.passthru.matrices.matrix-24}/*.mtx matrices + + # Not used by the original cmake, causes an error + rm matrices/*_b.mtx + + echo "deps/convert.cpp -> deps/mtx2csr" + hipcc deps/convert.cpp -O3 -o deps/mtx2csr + + for mat in $(ls -1 matrices | cut -d "." -f 1); do + echo "mtx2csr: $mat.mtx -> $mat.csr" + deps/mtx2csr matrices/$mat.mtx matrices/$mat.csr + unlink matrices/$mat.mtx + done + ''; + + postInstall = + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + cp -a $out/bin/* $benchmark/bin + rm $benchmark/bin/rocsparse-test + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + mkdir -p $test/bin + mv $out/bin/* $test/bin + rm $test/bin/rocsparse-bench || true + mv /build/source/matrices $test + rmdir $out/bin + ''; + + passthru = { + matrices = import ./deps.nix { + inherit fetchzip; + mirror1 = "https://sparse.tamu.edu/MM"; + mirror2 = "https://www.cise.ufl.edu/research/sparse/MM"; + }; + + updateScript = rocmUpdateScript { inherit finalAttrs; }; + }; + + meta = { + description = "ROCm SPARSE implementation"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocsparse"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocsparse/deps.nix b/.devops/nix/rocm-modules-10/rocsparse/deps.nix new file mode 100644 index 0000000000..00096ca4bf --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocsparse/deps.nix @@ -0,0 +1,223 @@ +{ + fetchzip, + mirror1, + mirror2, +}: + +{ + matrix-01 = fetchzip { + hash = "sha256-AHur5ZIDZTFRrO2GV0ieXrffq4KUiGWiZ59pv0fUtEQ="; + + urls = [ + "${mirror1}/SNAP/amazon0312.tar.gz" + "${mirror2}/SNAP/amazon0312.tar.gz" + ]; + }; + + matrix-02 = fetchzip { + hash = "sha256-0rSxaN4lQcdaCLsvlgicG70FXUxXeERPiEmQ4MzbRdE="; + + urls = [ + "${mirror1}/Muite/Chebyshev4.tar.gz" + "${mirror2}/Muite/Chebyshev4.tar.gz" + ]; + }; + + matrix-03 = fetchzip { + hash = "sha256-hDzDWDUnHEyFedX/tMNq83ZH8uWyM4xtZYUUAD3rizo="; + + urls = [ + "${mirror1}/FEMLAB/sme3Dc.tar.gz" + "${mirror2}/FEMLAB/sme3Dc.tar.gz" + ]; + }; + + matrix-04 = fetchzip { + hash = "sha256-GmN2yOt/MoX01rKe05aTyB3ypUP4YbQGOITZ0BqPmC0="; + + urls = [ + "${mirror1}/Williams/webbase-1M.tar.gz" + "${mirror2}/Williams/webbase-1M.tar.gz" + ]; + }; + + matrix-05 = fetchzip { + hash = "sha256-gQNjfVyWzNM9RwImJGhkhahRmZz74LzDs1oijL7mI7k="; + + urls = [ + "${mirror1}/Williams/mac_econ_fwd500.tar.gz" + "${mirror2}/Williams/mac_econ_fwd500.tar.gz" + ]; + }; + + matrix-06 = fetchzip { + hash = "sha256-87cdZjntNcTuz5BtO59irhcuRbPllWSbhCEX3Td02qc="; + + urls = [ + "${mirror1}/Williams/mc2depi.tar.gz" + "${mirror2}/Williams/mc2depi.tar.gz" + ]; + }; + + matrix-07 = fetchzip { + hash = "sha256-WRamuJX3D8Tm+k0q67RjUDG3DeNAxhKiaPkk5afY5eU="; + + urls = [ + "${mirror1}/Bova/rma10.tar.gz" + "${mirror2}/Bova/rma10.tar.gz" + ]; + }; + + matrix-08 = fetchzip { + hash = "sha256-5dhkm293Mc3lzakKxHy5W5XIn4Rw+gihVh7gyrjEHXo="; + + urls = [ + "${mirror1}/JGD_BIBD/bibd_22_8.tar.gz" + "${mirror2}/JGD_BIBD/bibd_22_8.tar.gz" + ]; + }; + + matrix-09 = fetchzip { + hash = "sha256-czjLWCjXAjZCk5TGYHaEkwSAzQu3TQ3QyB6eNKR4G88="; + + urls = [ + "${mirror1}/Hamm/scircuit.tar.gz" + "${mirror2}/Hamm/scircuit.tar.gz" + ]; + }; + + matrix-10 = fetchzip { + hash = "sha256-bYuLnJViAIcIejAkh69/bsNAVIDU4wfTLtD+nmHd6FM="; + + urls = [ + "${mirror1}/Sandia/ASIC_320k.tar.gz" + "${mirror2}/Sandia/ASIC_320k.tar.gz" + ]; + }; + + matrix-11 = fetchzip { + hash = "sha256-aDwn8P1khYjo2Agbq5m9ZBInJUxf/knJNvyptt0fak0="; + + urls = [ + "${mirror1}/GHS_psdef/bmwcra_1.tar.gz" + "${mirror2}/GHS_psdef/bmwcra_1.tar.gz" + ]; + }; + + matrix-12 = fetchzip { + hash = "sha256-8OJqA/byhlAZd869TPUzZFdsOiwOoRGfKyhM+RMjXoY="; + + urls = [ + "${mirror1}/HB/nos1.tar.gz" + "${mirror2}/HB/nos1.tar.gz" + ]; + }; + + matrix-13 = fetchzip { + hash = "sha256-FS0rKqmg+uHwsM/yGfQLBdd7LH/rUrdutkNGBD/Mh1I="; + + urls = [ + "${mirror1}/HB/nos2.tar.gz" + "${mirror2}/HB/nos2.tar.gz" + ]; + }; + + matrix-14 = fetchzip { + hash = "sha256-DANnlrNJikrI7Pst9vRedtbuxepyHmCIu2yhltc4Qcs="; + + urls = [ + "${mirror1}/HB/nos3.tar.gz" + "${mirror2}/HB/nos3.tar.gz" + ]; + }; + + matrix-15 = fetchzip { + hash = "sha256-21mUgqjWGUfYgiWwSrKh9vH8Vdt3xzcefmqYNYRpxiY="; + + urls = [ + "${mirror1}/HB/nos4.tar.gz" + "${mirror2}/HB/nos4.tar.gz" + ]; + }; + + matrix-16 = fetchzip { + hash = "sha256-FOuXvGqBBFNkVS6cexmkluret54hCfCOdK+DOZllE4c="; + + urls = [ + "${mirror1}/HB/nos5.tar.gz" + "${mirror2}/HB/nos5.tar.gz" + ]; + }; + + matrix-17 = fetchzip { + hash = "sha256-+7NI1rA/qQxYPpjXKHvAaCZ+LSaAJ4xuJvMRMBEUYxg="; + + urls = [ + "${mirror1}/HB/nos6.tar.gz" + "${mirror2}/HB/nos6.tar.gz" + ]; + }; + + matrix-18 = fetchzip { + hash = "sha256-q3NxJjbwGGcFiQ9nhWfUKgZmdVwCfPmgQoqy0AqOsNc="; + + urls = [ + "${mirror1}/HB/nos7.tar.gz" + "${mirror2}/HB/nos7.tar.gz" + ]; + }; + + matrix-19 = fetchzip { + hash = "sha256-0GAN6qmVfD+tprIigzuUUUwm5KVhkN9X65wMEvFltDY="; + + urls = [ + "${mirror1}/DNVS/shipsec1.tar.gz" + "${mirror2}/DNVS/shipsec1.tar.gz" + ]; + }; + + matrix-20 = fetchzip { + hash = "sha256-f28Du/Urxsiq5NkRmRO10Zz9vvGRjEchquzHzbZpZ7U="; + + urls = [ + "${mirror1}/Cote/mplate.tar.gz" + "${mirror2}/Cote/mplate.tar.gz" + ]; + }; + + matrix-21 = fetchzip { + hash = "sha256-O+Wy0NfCU1hVUOfNR1dJpvDHLBwwa301IRJDrQJnhak="; + + urls = [ + "${mirror1}/Bai/qc2534.tar.gz" + "${mirror2}/Bai/qc2534.tar.gz" + ]; + }; + + matrix-22 = fetchzip { + hash = "sha256-oxMnt8U5Cf1ILWcBdU6W9jdSMMm+U6bIVl8nm3n3+OA="; + + urls = [ + "${mirror1}/Chevron/Chevron2.tar.gz" + "${mirror2}/Chevron/Chevron2.tar.gz" + ]; + }; + + matrix-23 = fetchzip { + hash = "sha256-MFD9BxFI/3IS7yatW121BAI04fbqrXpgYDT5UKjeKcU="; + + urls = [ + "${mirror1}/Chevron/Chevron3.tar.gz" + "${mirror2}/Chevron/Chevron3.tar.gz" + ]; + }; + + matrix-24 = fetchzip { + hash = "sha256-ikS8O51pe1nt3BNyhvfvqCbVL0+bg/da9bqGqeBDkTg="; + + urls = [ + "${mirror1}/Chevron/Chevron4.tar.gz" + "${mirror2}/Chevron/Chevron4.tar.gz" + ]; + }; +} diff --git a/.devops/nix/rocm-modules-10/rocthrust/default.nix b/.devops/nix/rocm-modules-10/rocthrust/default.nix new file mode 100644 index 0000000000..bcc6b125c2 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocthrust/default.nix @@ -0,0 +1,93 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocprim, + clr, + gtest, + buildTests ? false, + buildBenchmarks ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocthrust"; + version = "7.2.3"; + + outputs = [ + "out" + ] + ++ lib.optionals buildTests [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "rocm-${finalAttrs.version}"; + sparseCheckout = [ + "projects/rocthrust" + "shared" + ]; + hash = "sha256-wHEgpmBZCYtvp+OyebrRyfoFz3WQyKWfHPrdzQVL8lY="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocthrust"; + + nativeBuildInputs = [ + cmake + rocm-cmake + rocprim + clr + ]; + + buildInputs = lib.optionals buildTests [ + gtest + ]; + + cmakeFlags = [ + "-DHIP_ROOT_DIR=${clr}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildTests [ + "-DBUILD_TEST=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DBUILD_BENCHMARKS=ON" + ]; + + postInstall = + lib.optionalString buildTests '' + mkdir -p $test/bin + mv $out/bin/{test_*,*.hip} $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/benchmark_* $benchmark/bin + '' + + lib.optionalString (buildTests || buildBenchmarks) '' + rm -rf $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "ROCm parallel algorithm library"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocthrust"; + license = lib.licenses.asl20; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/roctracer/default.nix b/.devops/nix/rocm-modules-10/roctracer/default.nix new file mode 100644 index 0000000000..3c9c06bae3 --- /dev/null +++ b/.devops/nix/rocm-modules-10/roctracer/default.nix @@ -0,0 +1,118 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + clr, + rocm-device-libs, + libxml2, + doxygen, + graphviz, + gcc-unwrapped, + libbacktrace, + rocm-runtime, + python3Packages, + buildDocs ? false, # Nothing seems to be generated, so not making the output + buildTests ? false, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "roctracer"; + version = "10.0.0"; + + outputs = [ + "out" + ] + ++ lib.optionals buildDocs [ + "doc" + ] + ++ lib.optionals buildTests [ + "test" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-systems"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/roctracer" + "shared" + ]; + hash = "sha256-+2PWQW3EKy2jgjD00ha1nxmvoy0DnOL3ykx33JOYg8E="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/roctracer"; + + nativeBuildInputs = [ + cmake + clr + ] + ++ lib.optionals buildDocs [ + doxygen + graphviz + ]; + + buildInputs = [ + libxml2 + libbacktrace + python3Packages.python + python3Packages.cppheaderparser + ]; + + cmakeFlags = [ + "-DCMAKE_MODULE_PATH=${clr}/hip/cmake" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ]; + + env.NIX_CFLAGS_COMPILE = toString [ + # Needed with GCC 12 + "-Wno-error=array-bounds" + ]; + + postPatch = '' + export HIP_DEVICE_LIB_PATH=${rocm-device-libs}/amdgcn/bitcode + '' + + lib.optionalString (!buildTests) '' + substituteInPlace CMakeLists.txt \ + --replace "add_subdirectory(test)" "" + ''; + + # Tests always fail, probably need GPU + # doCheck = buildTests; + + postInstall = + lib.optionalString buildDocs '' + mkdir -p $doc + '' + + lib.optionalString buildTests '' + mkdir -p $test/bin + # Not sure why this is an install target + find $out/test -executable -type f -exec mv {} $test/bin \; + rm $test/bin/{*.sh,*.py} + patchelf --set-rpath $out/lib:${ + lib.makeLibraryPath ( + finalAttrs.buildInputs + ++ [ + clr + gcc-unwrapped.lib + rocm-runtime + ] + ) + } $test/bin/* + rm -rf $out/test + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Tracer callback/activity library"; + homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/roctracer"; + license = lib.licenses.mit; # mitx11 + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rocwmma/0000-dont-fetch-googletest.patch b/.devops/nix/rocm-modules-10/rocwmma/0000-dont-fetch-googletest.patch new file mode 100644 index 0000000000..fa47a3c422 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocwmma/0000-dont-fetch-googletest.patch @@ -0,0 +1,35 @@ +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 0d00883..86ce282 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -30,30 +30,6 @@ cmake_dependent_option( ROCWMMA_BUILD_VALIDATION_TESTS "Build validation tests" + cmake_dependent_option( ROCWMMA_BUILD_BENCHMARK_TESTS "Build benchmarking tests" OFF "ROCWMMA_BUILD_TESTS" OFF ) + cmake_dependent_option( ROCWMMA_BUILD_EXTENDED_TESTS "Build extended test parameter coverage" OFF "ROCWMMA_BUILD_TESTS" OFF ) + +-# Test/benchmark requires additional dependencies +-include( FetchContent ) +- +-FetchContent_Declare( +- googletest +- GIT_REPOSITORY https://github.com/google/googletest.git +- GIT_TAG release-1.12.1 +-) +-FetchContent_GetProperties(googletest) +-if(NOT googletest_POPULATED) +- +- # Fetch the content using default details +- FetchContent_Populate(googletest) +- # Save the shared libs setting, then force to static libs +- set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS}) +- set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Build SHARED libraries" FORCE) +- +- # Add gtest targets as static libs +- add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) +- +- # Restore shared libs setting +- set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD} CACHE INTERNAL "Build SHARED libraries" FORCE) +-endif() +- + set(ROCWMMA_TEST_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) + set(ROCWMMA_COMMON_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hip_device.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rocwmma_gtest_main.cpp) diff --git a/.devops/nix/rocm-modules-10/rocwmma/default.nix b/.devops/nix/rocm-modules-10/rocwmma/default.nix new file mode 100644 index 0000000000..abb4fd3d15 --- /dev/null +++ b/.devops/nix/rocm-modules-10/rocwmma/default.nix @@ -0,0 +1,116 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocm-smi, + clr, + openmp, + gtest, + rocblas, + buildTests ? false, # Will likely fail building because wavefront shifts are not supported for certain archs + buildExtendedTests ? false, + buildBenchmarks ? false, + buildSamples ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rocwmma"; + version = "10.0.0"; + + outputs = [ + "out" + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + "test" + ] + ++ lib.optionals buildBenchmarks [ + "benchmark" + ] + ++ lib.optionals buildSamples [ + "sample" + ]; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "projects/rocwmma" + "shared" + ]; + hash = "sha256-vN0s7lDUK9lEi3jClGZzouWi9Vej0v/gsTe707m+oE0="; + }; + sourceRoot = "${finalAttrs.src.name}/projects/rocwmma"; + + patches = lib.optionals (buildTests || buildBenchmarks) [ + ./0000-dont-fetch-googletest.patch + ]; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + ]; + + buildInputs = [ + openmp + ] + ++ lib.optionals (buildTests || buildBenchmarks) [ + rocm-smi + gtest + rocblas + ]; + + cmakeFlags = [ + "-DROCWMMA_BUILD_TESTS=${if buildTests || buildBenchmarks then "ON" else "OFF"}" + "-DROCWMMA_BUILD_SAMPLES=${if buildSamples then "ON" else "OFF"}" + # Manually define CMAKE_INSTALL_ + # See: https://github.com/NixOS/nixpkgs/pull/197838 + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ] + ++ lib.optionals buildExtendedTests [ + "-DROCWMMA_BUILD_EXTENDED_TESTS=ON" + ] + ++ lib.optionals buildBenchmarks [ + "-DROCWMMA_BUILD_BENCHMARK_TESTS=ON" + "-DROCWMMA_BENCHMARK_WITH_ROCBLAS=ON" + ]; + + postInstall = + lib.optionalString (buildTests || buildBenchmarks) '' + mkdir -p $test/bin + mv $out/bin/{*_test,*-validate} $test/bin + '' + + lib.optionalString buildBenchmarks '' + mkdir -p $benchmark/bin + mv $out/bin/*-bench $benchmark/bin + '' + + lib.optionalString buildSamples '' + mkdir -p $sample/bin + mv $out/bin/sgemmv $sample/bin + mv $out/bin/simple_gemm $sample/bin + mv $out/bin/simple_dlrm $sample/bin + '' + + lib.optionalString (buildTests || buildBenchmarks || buildSamples) '' + rm -rf $out/bin + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Mixed precision matrix multiplication and accumulation"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/projects/rocwmma"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/rpp/default.nix b/.devops/nix/rocm-modules-10/rpp/default.nix new file mode 100644 index 0000000000..ac26ace58a --- /dev/null +++ b/.devops/nix/rocm-modules-10/rpp/default.nix @@ -0,0 +1,77 @@ +{ + lib, + stdenv, + fetchFromGitHub, + rocmUpdateScript, + cmake, + rocm-cmake, + rocm-docs-core, + half, + clr, + openmp, + boost, + python3Packages, + buildDocs ? false, # Needs internet + useCPU ? false, + gpuTargets ? clr.localGpuTargets or [ ], +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "rpp-${if useCPU then "cpu" else "hip"}"; + + version = "7.2.3"; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rpp"; + rev = "rocm-${finalAttrs.version}"; + hash = "sha256-6e4JHKFC2dvtSGo9xbQKzIdUwlHB09pr5C/5xHwP3l4="; + }; + + nativeBuildInputs = [ + cmake + rocm-cmake + clr + ] + ++ lib.optionals buildDocs [ + rocm-docs-core + python3Packages.python + ]; + + buildInputs = [ + half + openmp + boost + ]; + + cmakeFlags = [ + "-DROCM_PATH=${clr}" + "-DCMAKE_INSTALL_BINDIR=bin" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DBACKEND=${if useCPU then "CPU" else "HIP"}" + ] + ++ lib.optionals (gpuTargets != [ ]) [ + "-DAMDGPU_TARGETS=${lib.concatStringsSep ";" gpuTargets}" + ]; + + postPatch = lib.optionalString (!useCPU) '' + # Bad path + substituteInPlace CMakeLists.txt \ + --replace "COMPILER_FOR_HIP \''${ROCM_PATH}/llvm/bin/clang++" "COMPILER_FOR_HIP ${clr}/bin/hipcc" + ''; + + postBuild = lib.optionalString buildDocs '' + python3 -m sphinx -T -E -b html -d _build/doctrees -D language=en ../docs _build/html + ''; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "Comprehensive high-performance computer vision library for AMD processors"; + homepage = "https://github.com/ROCm/rpp"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/tensile/default.nix b/.devops/nix/rocm-modules-10/tensile/default.nix new file mode 100644 index 0000000000..aab8101ed0 --- /dev/null +++ b/.devops/nix/rocm-modules-10/tensile/default.nix @@ -0,0 +1,96 @@ +{ + lib, + fetchFromGitHub, + fetchpatch, + rocmUpdateScript, + buildPythonPackage, + pytestCheckHook, + setuptools, + distro, + pyyaml, + msgpack, + pandas, + joblib, + filelock, + clr, + rich, +}: + +buildPythonPackage (finalAttrs: { + pname = "tensile"; + version = "10.0.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "ROCm"; + repo = "rocm-libraries"; + rev = "therock-10.0"; + sparseCheckout = [ + "shared/tensile" + "shared" + ]; + hash = "sha256-NFeXnmCOpBlbWivmc1Q0/nU8VDqO1y82jMHYWBkKckc="; + }; + sourceRoot = "${finalAttrs.src.name}/shared/tensile"; + + # TODO: It should be possible to run asm caps test ONCE for all supported arches + # We currently disable the test because it's slow and runs each time tensile launches + postPatch = '' + substituteInPlace Tensile/Common.py \ + --replace-fail 'if globalParameters["AssemblerPath"] is not None:' "if False:" + # Add an assert that the fallback 9,0,0 is supported before setting the kernel to it + # If it's not detected as supported we have an issue with compiler paths or the compiler is broken + # and it's better to stop immediately + substituteInPlace Tensile/KernelWriter.py \ + --replace-fail '= (9,0,0)' '= (9,0,0);assert(globalParameters["AsmCaps"][(9,0,0)]["SupportedISA"])' + find . -type f -iname "*.sh" -exec chmod +x {} \; + patchShebangs Tensile + ''; + + buildInputs = [ setuptools ]; + + propagatedBuildInputs = [ + pyyaml + msgpack + pandas + joblib + distro + rich + ]; + + patches = [ + ./tensile-solutionstructs-perf-fix.diff + ./tensile-create-library-dont-copy-twice.diff + (fetchpatch { + # [PATCH] Extend Tensile HIP ISA compatibility + hash = "sha256-ZHXNYSeLkhhNDaIfdqQm68Pxmh1shUL7mAVmh8/I6Xk="; + url = "https://github.com/GZGavinZhao/rocm-libraries/commit/1f7135dfc0cdb175c8f0e5eb71b2d24699942873.patch"; + relative = "shared/tensile"; + }) + ]; + + doCheck = false; # Too many errors, not sure how to set this up properly + + nativeCheckInputs = [ + pytestCheckHook + filelock + clr + ]; + + env = { + dontCheckPythonMetadata = true; + ROCM_PATH = "${clr}"; + }; + + pythonImportsCheck = [ "Tensile" ]; + + passthru.updateScript = rocmUpdateScript { inherit finalAttrs; }; + + meta = { + description = "GEMMs and tensor contractions"; + homepage = "https://github.com/ROCm/rocm-libraries/tree/develop/shared/tensile"; + license = lib.licenses.mit; + teams = [ lib.teams.rocm ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/.devops/nix/rocm-modules-10/tensile/tensile-create-library-dont-copy-twice.diff b/.devops/nix/rocm-modules-10/tensile/tensile-create-library-dont-copy-twice.diff new file mode 100644 index 0000000000..2b680241d9 --- /dev/null +++ b/.devops/nix/rocm-modules-10/tensile/tensile-create-library-dont-copy-twice.diff @@ -0,0 +1,20 @@ +diff --git a/Tensile/TensileCreateLibrary.py b/Tensile/TensileCreateLibrary.py +index a1644606..c6ca2882 100644 +--- a/Tensile/TensileCreateLibrary.py ++++ b/Tensile/TensileCreateLibrary.py +@@ -852,9 +852,14 @@ def copyStaticFiles(outputPath=None): + "KernelHeader.h", + ] + ++ import filecmp + for fileName in libraryStaticFiles: + # copy file +- shutil.copy(os.path.join(globalParameters["SourcePath"], fileName), outputPath) ++ # no need to copy twice if it has already been copied ++ src = os.path.join(globalParameters["SourcePath"], fileName) ++ dst = os.path.join(outputPath, os.path.basename(src)) ++ if not os.path.isfile(dst) or not filecmp.cmp(src, dst): ++ shutil.copyfile(src, dst) + + return libraryStaticFiles + diff --git a/.devops/nix/rocm-modules-10/tensile/tensile-solutionstructs-perf-fix.diff b/.devops/nix/rocm-modules-10/tensile/tensile-solutionstructs-perf-fix.diff new file mode 100644 index 0000000000..7157238042 --- /dev/null +++ b/.devops/nix/rocm-modules-10/tensile/tensile-solutionstructs-perf-fix.diff @@ -0,0 +1,48 @@ +diff --git a/Tensile/SolutionStructs.py b/Tensile/SolutionStructs.py +index f663c6f1..17bcf897 100644 +--- a/Tensile/SolutionStructs.py ++++ b/Tensile/SolutionStructs.py +@@ -4828,24 +4828,26 @@ class Solution(collections.abc.Mapping): + # create a dictionary of lists of parameter values + @staticmethod + def getSerialNaming(objs): ++ valid_params = sorted(validParameters.keys()) + data = {} +- for objIdx in range(0, len(objs)): +- obj = objs[objIdx] +- for paramName in sorted(obj.keys()): +- if paramName in list(validParameters.keys()): +- paramValue = obj[paramName] +- if paramName in data: +- if paramValue not in data[paramName]: +- data[paramName].append(paramValue) +- else: +- data[paramName] = [ paramValue ] +- maxObjs = 1 +- for paramName in data: +- if not isinstance(data[paramName][0],dict): +- data[paramName] = sorted(data[paramName]) +- maxObjs *= len(data[paramName]) +- numDigits = len(str(maxObjs)) +- return [ data, numDigits ] ++ ++ objs = [getattr(obj, "_state", obj) for obj in objs] ++ ++ for param in valid_params: ++ d = [] ++ for obj in objs: ++ if param in obj: ++ v = obj[param] ++ if v not in d: ++ d.append(v) ++ if len(d): ++ if not isinstance(d[0], dict): d.sort() ++ data[param] = d ++ ++ # Calculate max objects using prod() from math module ++ max_objs = math.prod(len(values) for values in data.values()) ++ num_digits = len(str(max_objs)) ++ return data, num_digits + + ######################################## + # Get Name Serial \ No newline at end of file diff --git a/.devops/nix/rocm-modules-10/update.nix b/.devops/nix/rocm-modules-10/update.nix new file mode 100644 index 0000000000..7ffc5f9a7e --- /dev/null +++ b/.devops/nix/rocm-modules-10/update.nix @@ -0,0 +1,63 @@ +{ + lib, + writeScript, +}: + +{ + finalAttrs ? { }, + name ? finalAttrs.pname, + owner ? finalAttrs.src.owner, + repo ? finalAttrs.src.repo, + page ? "releases?per_page=10", + # input: array of [ { tag_name: "rocm-6.x.x", }, ... ]. some entries may have bad names like rocm-test-date we want to skip + # output: first tag_name/name that's a proper version if any + filter ? "map(.tag_name // .name) | map(select(test(\"^rocm-[0-9]+\\\\.[0-9]+(\\\\.[0-9]+)?$\"))) | first | ltrimstr(\"rocm-\")", +}: + +let + pname = + if lib.hasPrefix "rocm-llvm-" name then "llvm.${lib.removePrefix "rocm-llvm-" name}" else name; + + updateScript = writeScript "update.sh" '' + #!/usr/bin/env nix-shell + #!nix-shell -i bash -p curl jq common-updater-scripts + set -euo pipefail + + fetch_releases() { + local api_url="https://api.github.com/repos/${owner}/${repo}/${page}" + if [ "${page}" = "releases" ]; then + api_url="$api_url?per_page=4" + fi + >&2 echo $api_url + curl ''${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} -sL "$api_url" + } + + find_valid_version() { + local releases="$1" + >&2 echo "$releases" + # Wrap in array if not already an array to make handling specific release or tags page the same + >&2 echo jq -r 'if type == "array" then . else [.] end | ${filter}' + echo "$releases" | jq -r 'if type == "array" then . else [.] end | ${filter}' + } + + releases="$(fetch_releases)" + version="$(find_valid_version "$releases")" + + if [ -z "$version" ]; then + echo "No valid version found in the fetched release(s)." >&2 + exit 1 + fi + + IFS='.' read -ra version_arr <<< "$version" + + >&2 echo parsed version "$version_arr" from "$version" + + if (( ''${version_arr[0]} > 7 )); then + echo "'rocmPackages.${pname}' is already at its maximum allowed version.''\nAny further upgrades should go into 'rocmPackages_X.${pname}'." >&2 + exit 1 + fi + + update-source-version rocmPackages.${pname} "$version" --ignore-same-hash + ''; +in +[ updateScript ] diff --git a/CMakeLists.txt b/CMakeLists.txt index 727567ee29..e8979c9488 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,6 +254,16 @@ if (OpenMP_CXX_FOUND) endif() if (ENGINE_ENABLE_HIP) + # ROCm 10 ships AMD clang 23, whose SLP vectorizer widens the blocked WMMA + # GEMM inner loops past the 256-VGPR budget: 67 of 214 instantiations spill + # (8570 VGPRs total) where clang 22 spilled none, costing 16-19% of pp2048. + # Disabling SLP for this translation unit restores it (+3.0% over ROCm 7.2.3 + # at d4096, 3 repetitions). Scoped to the file and to clang 23 or newer so the + # pinned 7.2.3 toolchain is unaffected. See docs and rocm10-spike.md. + if (CMAKE_HIP_COMPILER_VERSION VERSION_GREATER_EQUAL 23) + set_property(SOURCE src/models/qwen/hip/kernels/prefill_quant_gemm.hip + APPEND PROPERTY COMPILE_OPTIONS -fno-slp-vectorize) + endif() set_property(SOURCE src/models/minimax_h3/dit.hip APPEND PROPERTY COMPILE_OPTIONS -O2) target_sources(gufo_core PRIVATE diff --git a/baseline.md b/baseline.md new file mode 100644 index 0000000000..7e569e9059 --- /dev/null +++ b/baseline.md @@ -0,0 +1,65 @@ +# ROCm 7.2.3 Baseline — Qwen3.8-27B UD-Q4_K_XL + +Reference measurement taken before any ROCm 10 packaging work, so the same +sweep can be replayed against a ROCm 10 build and compared directly. + +## Provenance + +| Field | Value | +| --- | --- | +| Date | 2026-09-04 | +| Repository revision | `9008a5e` (clean tree) | +| Toolchain | `nix eval .#default.toolchain --json` | +| ROCm | 7.2.3 (`rocmPackages.clr`) | +| Device HIP compiler | AMD Clang 22 | +| Host compiler | `gcc-wrapper-15.3.0` | +| GPU | gfx1151, AMD Radeon 8060S Graphics, wave size 32, 126976 MiB reported VRAM | +| Host kernel | Linux 7.1.8 | +| Build | `nix build` (default package, gfx1151 + XRT), exit 0 | +| Model | `models/Qwen3.8-27B-UD-Q4_K_XL.gguf`, 16.35 GiB, 27.32 B params | +| Model load | 1.43451 s | + +## Command + +```sh +nix build + +./result/bin/gufo bench \ + --model models/Qwen3.8-27B-UD-Q4_K_XL.gguf \ + --n-prompt 2048 \ + --n-gen 128 \ + --n-depth 4096,8192,12288,16384 \ + --repetitions 1 +``` + +## Results + +Backend ROCm (HIP), `ngl 99`, single repetition, so the reported deviation is +0.00 by construction and these are single-sample points, not distributions. + +| Test | t/s | +| --- | --- | +| pp2048 @ d4096 | 447.15 | +| tg128 @ d4096 | 11.46 | +| pp2048 @ d8192 | 426.25 | +| tg128 @ d8192 | 11.26 | +| pp2048 @ d12288 | 410.09 | +| tg128 @ d12288 | 11.06 | +| pp2048 @ d16384 | 392.43 | +| tg128 @ d16384 | 10.86 | + +Depth scaling across 4096 → 16384: prefill falls 12.2% (447.15 → 392.43), +decode falls 5.2% (11.46 → 10.86). + +## Notes + +- The `model` column prints `Qwen3.8-27B BF16` while the shard is UD-Q4_K_XL. + The size and parameter columns (16.35 GiB / 27.32 B) confirm the intended + shard was loaded; the label comes from GGUF file-type metadata and is not + evidence of a BF16 route. +- Single repetition was chosen to match the canonical depth sweep in + `benchmarks/qwen3.8-27b/README.md`. Repeat with `--repetitions 3` if a + ROCm 10 comparison lands inside a few percent of these numbers, since a + single sample cannot separate that from thermal drift on a shared APU. +- No speculative decoding companion was configured for this run, so these are + plain target-model numbers. diff --git a/hip_probe.cpp b/hip_probe.cpp new file mode 100644 index 0000000000..7ea3ddc247 --- /dev/null +++ b/hip_probe.cpp @@ -0,0 +1,14 @@ +#include +#include +int main() { + int n = 0; + printf("hipGetDeviceCount: %s (n=%d)\n", hipGetErrorString(hipGetDeviceCount(&n)), n); + size_t freeB = 0, totalB = 0; + printf("hipMemGetInfo: %s free=%zu MiB total=%zu MiB\n", + hipGetErrorString(hipMemGetInfo(&freeB, &totalB)), freeB >> 20, totalB >> 20); + hipStream_t s{}; + printf("hipStreamCreate: %s\n", hipGetErrorString(hipStreamCreate(&s))); + void* p = nullptr; + printf("hipMalloc 256MiB: %s\n", hipGetErrorString(hipMalloc(&p, 256ull << 20))); + return 0; +} diff --git a/rocm10-env.sh b/rocm10-env.sh new file mode 100644 index 0000000000..e1bcd07f4d --- /dev/null +++ b/rocm10-env.sh @@ -0,0 +1,47 @@ +# Spike environment: gufo built against the ROCm 10.0.0 TheRock gfx1151 dist. +# Sourced inside `nix develop`, which supplies host deps (gcc, cmake, ninja, +# ICU, CURL, python+triton, ffmpeg, aotriton) but ALSO injects ROCm 7.2.3 +# -isystem paths. Those are stripped here so only ROCm 10 headers are visible. +S=/tmp/claude-1000/-home-mixer-gufo/82572f43-a7d3-4590-ab78-e6037443feed/scratchpad +R=$S/rocm10 +AOT=/nix/store/zxjf0y681b6kfdrak9bfxjw0n6ybizzp-aotriton-0.11.1b + +# Drop every -isystem pair that points at a ROCm 7.2.3 store path. +filter_rocm7() { + printf '%s\n' $1 | paste -d' ' - - | grep -v -E \ + 'clr-7\.2\.3|rocm-core-7\.2\.3|rocm-runtime-7\.2\.3|rocm-comgr|rocprofiler-sdk-7\.2\.3|hipblas|rocblas|miopen|composable[-_]kernel|rocwmma|hipcub|rocprim|hip-common|hipsolver|hipsparse' \ + | tr '\n' ' ' +} +export NIX_CFLAGS_COMPILE="$(filter_rocm7 "$NIX_CFLAGS_COMPILE")" + +# Same for the link line: nix develop adds -L/-rpath into clr-7.2.3, which also +# ships libamdhip64.so.7 and would otherwise win over the ROCm 10 runtime. +# Drops "-L" tokens and "-rpath " pairs together, so the +# stripped link line never leaves a dangling -rpath that swallows the next flag. +export NIX_LDFLAGS="$(printf '%s\n' $NIX_LDFLAGS | awk ' + BEGIN { skip = 0 } + { + if (skip) { skip = 0; next } + if ($0 == "-rpath") { getline nxt; if (nxt ~ /7\.2\.3|rocm-comgr/) next; print $0; print nxt; next } + if ($0 ~ /7\.2\.3|rocm-comgr/) next + print $0 + }' | tr '\n' ' ')" +export NIX_LDFLAGS="-L$R/lib -rpath $R/lib $NIX_LDFLAGS" + +# glibc headers for the unwrapped ROCm 10 amdclang++ device compiler. +GLIBC_INC=$(echo | g++ -E -Wp,-v - 2>&1 | grep -o '/nix/store/[^ ]*glibc[^ ]*-dev/include' | head -1) +# The nix g++ is a wrapper script, so resolve the real gcc prefix through the +# LTO wrapper path and swap libexec -> lib to get clang's --gcc-install-dir. +GCC_LTO=$(g++ -v 2>&1 | grep COLLECT_LTO_WRAPPER | cut -d= -f2) +GCC_INSTALL_DIR=$(dirname "$GCC_LTO" | sed 's|/libexec/gcc/|/lib/gcc/|') + +export ROCM_PATH=$R +export GUFO_HIPCUB_ROOT=$R +export GUFO_ROCPRIM_ROOT=$R +export GUFO_ROCWMMA_ROOT=$R +export PATH=$R/bin:$R/llvm/bin:$PATH +# Link inputs too: the unwrapped amdclang++ has no nix crt/library search path. +GLIBC_LIB=$(dirname "$(g++ -print-file-name=Scrt1.o)") +GCC_LIB=$(dirname "$(g++ -print-file-name=libstdc++.so)") +export HIP_FLAGS="--gcc-install-dir=${GCC_INSTALL_DIR%/} -idirafter ${GLIBC_INC} -B${GLIBC_LIB} -L${GLIBC_LIB} -L${GCC_LIB} -Wl,-rpath,${GCC_LIB} -Wl,-rpath,${GLIBC_LIB}" +export AOT R S diff --git a/rocm10-spike.md b/rocm10-spike.md new file mode 100644 index 0000000000..44bd38fa70 --- /dev/null +++ b/rocm10-spike.md @@ -0,0 +1,394 @@ +# ROCm 10 Spike — Build Works, Runtime Does Not + +Date: 2026-09-04. Companion to `baseline.md` (ROCm 7.2.3 reference numbers). + +Option 1 from the integration plan: build gufo against the ROCm 10 TheRock +`gfx1151` distribution outside Nix, to decide whether packaging ROCm 10 into +`.devops/nix` is worth doing. + +Outcome: **the repository compiles and links cleanly against ROCm 10, but the +ROCm 10 HIP runtime cannot create a stream on this host, so nothing runs.** +No performance comparison was possible. + +## What was tested + +| Item | Value | +| --- | --- | +| Stable dist | `therock-dist-linux-gfx1151-10.0.0.tar.gz`, 1.79 GB, 8.4 GB extracted | +| Stable hash | `sha256-T+q9ny2nI1LfN/bXFKVIR9P+kTwDQfviplQsEWQCS68=` | +| Nightly dist | `therock-dist-linux-gfx1151-10.1.0a20260904.tar.gz` | +| Nightly hash | `sha256-Kpaha5XNzUl871SIP0nu6PVb9WenVR6uS4XG9YbaF2U=` | +| Device compiler | AMD clang 23.0.0git (dist `llvm/bin/amdclang++`) | +| Host compiler | gcc 15.3.0 from `nix develop` | +| aotriton | nixpkgs `aotriton-0.11.1b` (not shipped by TheRock) | + +## What worked + +- **Full build, zero source changes.** 199/199 targets, including all 51 `.hip` + files: the rocWMMA-heavy DeepSeek V4 Flash kernels, the Qwen hipBLASLt GEMM + route, Composable Kernel attention, and both aotriton call sites (v2 in + `src/models/minimax_h3/dit.hip`, v3 in + `src/models/qwen/hip/kernels/attention_split.hip`). Warnings only. +- **Every ROCm dependency resolved into the ROCm 10 tree**: `hip`, `hipblas`, + `hipblaslt`, `rocblas`, `miopen`, Composable Kernel, rocWMMA, hipCUB, + rocPRIM, roctx. Verified through `CMakeCache.txt`. +- **Clean runtime linkage**, no ROCm 7.2.3 objects in the closure: + `libamdhip64.so.7`, `librocblas.so.5`, `libhipblaslt.so.1`, `libMIOpen.so.1`, + `libroctx64.so.4`, `libhiprtc.so.7`, all from the dist. +- **aotriton soname compatibility.** TheRock does not ship aotriton, but ROCm 10 + keeps the `libamdhip64.so.7` soname, so the nixpkgs build (`NEEDED: + libamdhip64.so.7`) loads against the ROCm 10 runtime without patching. + +## The blocker + +`hipStreamCreate` fails on the first call: + +``` +ld.lld: error: undefined hidden symbol: __amd_streamOpsIncrement +ld.lld: error: undefined hidden symbol: __amd_streamOpsDecrement +Error: Creating the executable from LLVM IRs failed. +:3:hip_stream.cpp :333 : hipStreamCreate: Returned hipErrorOutOfMemory +``` + +At first stream creation the HIP runtime JIT-compiles its internal +blit/stream-ops OpenCL program through COMGR 3.3. The final +`AMD_COMGR_ACTION_LINK_RELOCATABLE_TO_EXECUTABLE` step fails to resolve two +symbols, and HIP surfaces that as `hipErrorOutOfMemory` — a misleading error, +not memory pressure. + +Minimal reproducer (`scratchpad/hip_probe.cpp`), no gufo code involved: + +``` +hipGetDeviceCount: no error (n=1) +hipMemGetInfo: no error free=124542 MiB total=126976 MiB +hipStreamCreate: out of memory +hipMalloc 256MiB: no error +``` + +Memory is plainly not the problem: 124 GiB free, and a 256 MiB allocation +succeeds immediately after the failure. + +### Ruled out + +- **Not a stale release.** The 10.1.0a20260904 nightly fails identically. +- **Not hardware or driver enumeration.** ROCm 10 `rocminfo` reports gfx1151 + (queue max 131072) and the aie2p NPU; HSA runtime 1.21 loads. +- **Not environment.** Identical failure under `env -i`, and with + `GPU_MAX_HW_QUEUES=1`, `HSA_MAX_QUEUES=1`, `HSA_ENABLE_SDMA=0`, + `AMD_DIRECT_DISPATCH=0`, `HSA_SCRATCH_SINGLE_LIMIT`, `HIP_DEVICE_LIB_PATH`, + `DEVICE_LIB_PATH`, `ROCM_KPACK_PATH`, `ROCM_KPACK_DISABLE`, and with + `lib/rocm_sysdeps/lib` added to `LD_LIBRARY_PATH`. +- **Not missing or mismatched device libraries.** COMGR extracts its embedded + device libs to a temp tree and links `opencl.bc`; that copy is byte-identical + to the dist's `amdgcn/bitcode/opencl.bc`, and both define all four symbols + (`llvm-nm`: `W __amd_streamOpsIncrement`, `Decrement`, `Wait`, `Write`). + Only `Increment` and `Decrement` fail to resolve; `Wait` and `Write` link. + +The two failing symbols back the stream-ops APIs ROCm 10 added for CUDA parity +(`hipStreamWriteValue32/64`, `hipStreamWaitValue32/64`, `hipStreamBatchMemOp`). +ROCm 7.2.3's `opencl.bc` defines none of them, which is why 7.2.3 never takes +this path. This looks like an upstream defect in the gfx1151 TheRock +distribution, worth filing against ROCm/TheRock with the reproducer above. + +## Update: nixpkgs-style packaging works, and gufo runs on ROCm 10 + +The tarball verdict below was a packaging problem, as suspected. Rebuilding the +ROCm 10 sources through nixpkgs' packaging fixes `hipStreamCreate`: + +``` +=== RUN (nixpkgs-built ROCm 10) === +hipGetDeviceCount: no error (n=1) +hipStreamCreate: no error <- "out of memory" with AMD's tarball +``` + +Same machine, same kernel, same `therock-10.0` sources. The vendored module set +lives in `.devops/nix/rocm-modules-10/`; `scratchpad/rocm10-scope.nix` and +`scratchpad/gufo-rocm10.nix` instantiate it and build gufo against it. + +### Measured: ROCm 10 is slower than 7.2.3 with the current tuning + +Same sweep as `baseline.md` (UD-Q4_K_XL, `--n-prompt 2048 --n-gen 128 +--n-depth 4096,8192,12288,16384 --repetitions 1`). + +| Test | ROCm 7.2.3 | ROCm 10.0.0 | Delta | +| --- | --- | --- | --- | +| pp2048 @ d4096 | 447.15 | 373.50 | -16.5% | +| pp2048 @ d8192 | 426.25 | 355.68 | -16.6% | +| pp2048 @ d12288 | 410.09 | 335.85 | -18.1% | +| pp2048 @ d16384 | 392.43 | 317.44 | -19.1% | +| tg128 @ d4096 | 11.46 | 10.87 | -5.1% | +| tg128 @ d8192 | 11.26 | 10.55 | -6.3% | +| tg128 @ d12288 | 11.06 | 10.55 | -4.6% | +| tg128 @ d16384 | 10.86 | 10.39 | -4.3% | + +Both runs are single-repetition, but a 17-19% prefill drop repeated across four +depths is not thermal drift. + +This is not yet a verdict on ROCm 10. The hipBLASLt plan database +(`src/core/hip/hipblaslt_plan_database.cpp`, tuned with `tune_hipblaslt`) and the +pinned rocBLAS solution indices (`src/models/minimax_h3/dit.hip:53-88`) were both +selected against 7.2.3, and hipBLASLt moved to 1.4.1 and rocBLAS to 5.6.0. The +prefill path is where those tuned plans are used, and prefill is what regressed +most. Re-tuning against the new libraries is the next measurement, not a +speculative optimization. + +### Where the prefill regression is, and one rejected fix + +The Q4_K_XL benchmark never touches hipBLASLt. `gemm_route.hpp:231` routes a +quantized shard to `kHipPrefillQuantDirect`, our own WMMA kernel in +`src/models/qwen/hip/kernels/prefill_quant_gemm.hip`; only dense BF16 shards take +`kHipPrefillBf16LtTryThenBlas`. Two consequences: `tune_hipblaslt` cannot help +this benchmark, and the plan database is irrelevant here (it is opt-in through +`GUFO_HIPBLASLT_PLAN_CACHE` anyway, and was unset in both runs). + +hipBLASLt itself is not the problem. `gufo-kernel-bench --kernel gemm --type bf16` +is within ~2% between the toolchains at every size (4096^3: 6199 vs 6141 GFLOP/s). + +clang 23 does allocate very differently for our WMMA kernels: + +| Kernel | 7.2.3 (clang 22) | 10.0 (clang 23) | +| --- | --- | --- | +| `W8A8BlockedWmmaGEMMKernel<128,128,2,4>` | 138 vgpr / 0 spill | 256 / 156 | +| `W8A8BlockedWmmaGEMMKernel<128,16,4,8>` | 138 / 0 | 200 / 0 | +| `W8A8BlockedWmmaGEMMKernel<128,32,4,4>` | 148 / 0 | 256 / 64 | +| `W8A8BlockedWmmaGEMMKernel<128,64,4,8>` | -- | 256 / 148 | + +**Removing the spills does not help.** `-mllvm -amdgpu-sched-strategy=iterative-minreg` +drops every spill to zero (234/143/182/244 VGPRs, occupancy 5->6, 7->10, 5->8) and +measured *worse*: pp2048@d4096 373.5 -> 288.7, tg128@d4096 10.87 -> 8.80. That +reproduces the finding already recorded above the kernel template: it is +latency-bound, and the scheduling work needed to hit a register target costs more +than the spills. Note the flag was applied to every HIP TU, which is why decode +regressed too; but prefill lost 23% on its own. + +So register pressure is a symptom, not the cause. Remaining hypotheses, in order: +rocWMMA 1.7 fragment codegen versus 7.2.3; instruction-count/ISA diff of the hot +inner loop between clang 22 and 23; and scheduling changes that hurt latency +hiding without changing register counts. + +### Root cause found: clang 23 SLP vectorization, and the fix + +Instruction counts are nearly identical between the toolchains (+-6-9%); the +entire ISA delta is spill traffic and waits: + +| Kernel | metric | clang 22 | clang 23 | +| --- | --- | --- | --- | +| `W8A8...<128,128>` | scratch ops | 0 | 250 | +| | `s_waitcnt` | 124 | 194 | +| `W8A8...<128,64>` | scratch ops | 0 | 174 | +| | `s_waitcnt` | 97 | 165 | + +Across the whole translation unit, 67 of 214 instantiations spill under clang 23 +(8570 VGPRs total) against zero under clang 22, and 76 lose occupancy. The cause +is the SLP vectorizer widening the inner loops past the 256-VGPR budget: + +| variant | spilling kernels | spill VGPRs | occupancy below clang 22 | +| --- | --- | --- | --- | +| clang 23 baseline | 67 | 8570 | 76 | +| `-mllvm -amdgpu-schedule-relaxed-occupancy` | 66 | 8543 | 76 | +| `-O2` | 67 | 8570 | 76 | +| `-mllvm -slp-threshold=20` | 25 | 2183 | 14 | +| **`-fno-slp-vectorize`** | **25** | **2183** | **14** | + +Measured with `-fno-slp-vectorize` (same sweep): + +| Test | 7.2.3 | ROCm 10 | ROCm 10 + no-SLP | vs 7.2.3 | +| --- | --- | --- | --- | --- | +| pp2048 @ d4096 | 447.15 | 373.50 | 461.78 | +3.3% | +| pp2048 @ d8192 | 426.25 | 355.68 | 436.48 | +2.4% | +| pp2048 @ d12288 | 410.09 | 335.85 | 409.25 | -0.2% | +| pp2048 @ d16384 | 392.43 | 317.44 | 375.11 | -4.4% | +| tg128 @ d4096 | 11.46 | 10.87 | 10.85 | -5.3% | +| tg128 @ d16384 | 10.86 | 10.39 | 10.37 | -4.5% | + +Decode is unmoved by the flag (10.87 -> 10.85), so the remaining decode gap has a +different cause and the global flag is not hurting other kernels here. Two open +items: decode at about -5%, and deep-context prefill at -4.4%. + +Reproduce the register comparison with `scratchpad/vgpr-probe2.sh ` +and score a flag with `scratchpad/score.py