1{
2 lib,
3 fetchFromGitHub,
4 llvmPackages_18,
5 python3,
6 cmake,
7 boost,
8 libxml2,
9 libffi,
10 makeWrapper,
11 config,
12 cudaPackages,
13 rocmPackages_6,
14 ompSupport ? true,
15 openclSupport ? false,
16 rocmSupport ? config.rocmSupport,
17 cudaSupport ? config.cudaSupport,
18 autoAddDriverRunpath,
19 runCommand,
20 callPackage,
21 symlinkJoin,
22 nix-update-script,
23}:
24let
25 inherit (llvmPackages) stdenv;
26 rocmPackages = rocmPackages_6;
27 llvmPackages = llvmPackages_18;
28in
29stdenv.mkDerivation (finalAttrs: {
30 pname = "adaptivecpp";
31 version = "25.02.0";
32
33 src = fetchFromGitHub {
34 owner = "AdaptiveCpp";
35 repo = "AdaptiveCpp";
36 tag = "v${finalAttrs.version}";
37 sha256 = "sha256-vXfw8+xn3/DYxUKp3QGdQ8sEbDwyk+8jDCyuvQOXigc=";
38 };
39
40 # do not use old FindCUDA cmake module
41 postPatch = ''
42 rm cmake/FindCUDA.cmake
43 '';
44
45 # we may be able to get away with just wrapping hipcc and nothing more
46 # this is mainly so that if acpp tries doing <PATH_TO_HIPCC>/../amdgcn/bitcode
47 rocmMerged = symlinkJoin {
48 name = "rocm-merged";
49 paths = with rocmPackages; [
50 clr
51 rocm-core
52 rocm-device-libs
53 rocm-runtime
54 ];
55 buildInputs = [ makeWrapper ];
56 postBuild = ''
57 wrapProgram $out/bin/hipcc \
58 --add-flags "--rocm-device-lib-path=$out/amdgcn/bitcode"
59 '';
60 };
61
62 nativeBuildInputs = [
63 cmake
64 makeWrapper
65 ]
66 ++ lib.optionals cudaSupport [
67 autoAddDriverRunpath
68 cudaPackages.cuda_nvcc
69 ];
70
71 buildInputs = [
72 libxml2
73 libffi
74 boost
75 python3
76 llvmPackages.openmp
77 llvmPackages.libclang.dev
78 llvmPackages.llvm
79 ]
80 ++ lib.optionals cudaSupport [
81 cudaPackages.cuda_cudart
82 (lib.getOutput "stubs" cudaPackages.cuda_cudart)
83 ];
84
85 # adaptivecpp makes use of clangs internal headers. Its cmake does not successfully discover them automatically on nixos, so we supply the path manually
86 cmakeFlags = [
87 (lib.cmakeFeature "CLANG_INCLUDE_PATH" "${llvmPackages.libclang.dev}/include")
88 (lib.cmakeBool "WITH_CPU_BACKEND" ompSupport)
89 (lib.cmakeBool "WITH_CUDA_BACKEND" cudaSupport)
90 (lib.cmakeBool "WITH_ROCM_BACKEND" rocmSupport)
91 (lib.cmakeBool "WITH_OPENCL_BACKEND" openclSupport)
92 ]
93 ++ lib.optionals rocmSupport [
94 (lib.cmakeFeature "HIPCC_COMPILER" "${finalAttrs.rocmMerged}/bin/hipcc")
95 (lib.cmakeFeature "ROCM_PATH" "${finalAttrs.rocmMerged}")
96 ];
97
98 # this hardening option breaks rocm builds
99 hardeningDisable = [ "zerocallusedregs" ];
100
101 passthru = {
102 tests =
103 # Loosely based on the AdaptiveCpp GitHub CI: https://github.com/AdaptiveCpp/AdaptiveCpp/blob/develop/.github/workflows/linux.yml
104 # This may be overkill, especially as this won't be run on GPU on the CI
105 let
106 runner = targets: enablePstlTests: callPackage ./tests.nix { inherit enablePstlTests; };
107 run =
108 runner: cmd: mask:
109 runCommand cmd { } ''
110 # the test runner wants to write to $HOME/.acpp, so we need to have it point to a real directory
111 mkdir home
112 export HOME=`pwd`/home
113
114 ACPP_VISIBILITY_MASK="${mask}" ${runner}/bin/${cmd} && touch $out
115 '';
116 runSycl = runner: mask: run runner "sycl_tests" mask;
117 runPstl = runner: mask: run runner "pstl_tests" mask;
118 runner-omp = runner "omp" false;
119 runner-sscp = runner "generic" true;
120 in
121 {
122 inherit runner-omp runner-sscp;
123 sycl-omp = runSycl runner-omp "omp";
124 sycl-sscp = runSycl runner-sscp "omp";
125 pstl-sscp = runPstl runner-sscp "omp";
126 }
127 // lib.optionalAttrs rocmSupport (
128 let
129 runner-rocm = runner "hip:gfx906" false;
130 runner-rocm-integrated-multipass = runner "omp;hip:gfx906" false;
131 runner-rocm-explicit-multipass = runner "omp;hip.explicit-multipass:gfx906;cuda:sm_61" false;
132 in
133 {
134 inherit runner-rocm runner-rocm-integrated-multipass runner-rocm-explicit-multipass;
135 sycl-rocm = runSycl runner-rocm "omp;hip";
136 sycl-rocm-imp = runSycl runner-rocm-integrated-multipass "omp;hip";
137 sycl-rocm-emp = runSycl runner-rocm-explicit-multipass "omp;hip";
138 sycl-rocm-sscp = runSycl runner-sscp "omp;hip";
139 pstl-rocm-sscp = runPstl runner-sscp "omp;hip";
140 }
141 )
142 // lib.optionalAttrs cudaSupport (
143 let
144 runner-cuda = runner "cuda:sm_60" false;
145 runner-cuda-integrated-multipass = runner "omp;cuda_61" true;
146 runner-cuda-explicit-multipass = runner "omp;cuda.explicit-multipass:sm_61;hip:gfx906" false;
147 in
148 {
149 inherit runner-cuda runner-cuda-integrated-multipass runner-cuda-explicit-multipass;
150 sycl-cuda = runSycl runner-cuda "omp;cuda";
151 sycl-cuda-imp = runSycl runner-cuda-integrated-multipass "omp;cuda";
152 sycl-cuda-emp = runSycl runner-cuda-explicit-multipass "omp;cuda";
153 sycl-cuda-sscp = runSycl runner-sscp "omp;cuda";
154 pstl-cuda-imp = runPstl runner-cuda-integrated-multipass "omp;cuda";
155 pstl-cuda-sscp = runPstl runner-sscp "omp;cuda";
156 }
157 );
158
159 updateScript = nix-update-script { };
160 };
161
162 meta = {
163 homepage = "https://github.com/AdaptiveCpp/AdaptiveCpp";
164 description = "Multi-backend implementation of SYCL for CPUs and GPUs";
165 mainProgram = "acpp";
166 maintainers = with lib.maintainers; [ yboettcher ];
167 license = lib.licenses.bsd2;
168 };
169})