{ blas , boost , clblast , cmake , config , cudaPackages , fetchFromGitHub , fftw , fftwFloat , fmt_9 , forge , freeimage , gtest , lapack , lib , libGL , mesa , ocl-icd , opencl-clhpp , pkg-config , python3 , span-lite , stdenv # NOTE: We disable tests by default, because they cannot be run easily on # non-NixOS systems when either CUDA or OpenCL support is enabled (CUDA and # OpenCL need access to drivers that are installed outside of Nix on # non-NixOS systems). , doCheck ? false , cpuSupport ? true , cudaSupport ? config.cudaSupport # OpenCL needs mesa which is broken on Darwin , openclSupport ? !stdenv.isDarwin # This argument lets one run CUDA & OpenCL tests on non-NixOS systems by # telling Nix where to find the drivers. If you know the version of the # NVidia driver that is installed on your system, you can do: # # arrayfire.override { # nvidiaComputeDrivers = # callPackage # (prev.linuxPackages.nvidiaPackages.mkDriver { # version = cudaVersion; # our driver version # sha256_64bit = cudaHash; # sha256 of the .run binary # useGLVND = false; # useProfiles = false; # useSettings = false; # usePersistenced = false; # ... # }) # { libsOnly = true; }; # } , nvidiaComputeDrivers ? null }: # ArrayFire compiles with 64-bit BLAS, but some tests segfault or throw # exceptions, which means that it isn't really supported yet... assert blas.isILP64 == false; stdenv.mkDerivation rec { pname = "arrayfire"; version = "3.9.0"; src = fetchFromGitHub { owner = pname; repo = pname; rev = "v3.9.0"; hash = "sha256-80fxdkaeAQ5u0X/UGPaI/900cdkZ/vXNcOn5tkZ+C3Y="; }; # We cannot use the clfft from Nixpkgs because ArrayFire maintain a fork # of clfft where they've modified the CMake build system, and the # CMakeLists.txt of ArrayFire assumes that we're using that fork. # # This can be removed once ArrayFire upstream their changes. clfft = fetchFromGitHub { owner = pname; repo = "clfft"; rev = "760096b37dcc4f18ccd1aac53f3501a83b83449c"; sha256 = "sha256-vJo1YfC2AJIbbRj/zTfcOUmi0Oj9v64NfA9MfK8ecoY="; }; glad = fetchFromGitHub { owner = pname; repo = "glad"; rev = "ef8c5508e72456b714820c98e034d9a55b970650"; sha256 = "sha256-u9Vec7XLhE3xW9vzM7uuf+b18wZsh/VMtGbB6nMVlno="; }; threads = fetchFromGitHub { owner = pname; repo = "threads"; rev = "4d4a4f0384d1ac2f25b2c4fc1d57b9e25f4d6818"; sha256 = "sha256-qqsT9woJDtQvzuV323OYXm68pExygYs/+zZNmg2sN34="; }; test-data = fetchFromGitHub { owner = pname; repo = "arrayfire-data"; rev = "a5f533d7b864a4d8f0dd7c9aaad5ff06018c4867"; sha256 = "sha256-AWzhsrDXyZrQN2bd0Ng/XlE8v02x7QWTiFTyaAuRXSw="; }; # ArrayFire fails to compile with newer versions of spdlog, so we can't use # the one in Nixpkgs. Once they upgrade, we can switch to using spdlog from # Nixpkgs. spdlog = fetchFromGitHub { owner = "gabime"; repo = "spdlog"; rev = "v1.9.2"; hash = "sha256-GSUdHtvV/97RyDKy8i+ticnSlQCubGGWHg4Oo+YAr8Y="; }; cmakeFlags = [ "-DBUILD_TESTING=ON" # We do not build examples, because building tests already takes long enough... "-DAF_BUILD_EXAMPLES=OFF" # No need to build forge, because it's a separate package "-DAF_BUILD_FORGE=OFF" "-DAF_COMPUTE_LIBRARY='FFTW/LAPACK/BLAS'" # Prevent ArrayFire from trying to download some matrices from the Internet "-DAF_TEST_WITH_MTX_FILES=OFF" # Have to use the header-only version, because we're not using the version # from Nixpkgs. Otherwise, libaf.so won't be able to find the shared # library, because ArrayFire's CMake files do not run the install step of # spdlog. "-DAF_WITH_SPDLOG_HEADER_ONLY=ON" (if cpuSupport then "-DAF_BUILD_CPU=ON" else "-DAF_BUILD_CPU=OFF") (if openclSupport then "-DAF_BUILD_OPENCL=ON" else "-DAF_BUILD_OPENCL=OFF") (if cudaSupport then "-DAF_BUILD_CUDA=ON" else "-DAF_BUILD_CUDA=OFF") ] ++ lib.optionals cudaSupport [ # ArrayFire use deprecated FindCUDA in their CMake files, so we help CMake # locate cudatoolkit. "-DCUDA_LIBRARIES_PATH=${cudaPackages.cudatoolkit}/lib" ]; # ArrayFire have a repo with assets for the examples. Since we don't build # the examples anyway, remove the dependency on assets. patches = [ ./no-assets.patch ./no-download.patch ]; postPatch = '' mkdir -p ./extern/af_glad-src mkdir -p ./extern/af_threads-src mkdir -p ./extern/af_test_data-src mkdir -p ./extern/ocl_clfft-src mkdir -p ./extern/spdlog-src cp -R --no-preserve=mode,ownership ${glad}/* ./extern/af_glad-src/ cp -R --no-preserve=mode,ownership ${threads}/* ./extern/af_threads-src/ cp -R --no-preserve=mode,ownership ${test-data}/* ./extern/af_test_data-src/ cp -R --no-preserve=mode,ownership ${clfft}/* ./extern/ocl_clfft-src/ cp -R --no-preserve=mode,ownership ${spdlog}/* ./extern/spdlog-src/ # libaf.so (the unified backend) tries to load the right shared library at # runtime, and the search paths are hard-coded... We tweak them to point to # the installation directory in the Nix store. substituteInPlace src/api/unified/symbol_manager.cpp \ --replace '"/opt/arrayfire-3/lib/",' \ "\"$out/lib/\", \"/opt/arrayfire-3/lib/\"," ''; inherit doCheck; checkPhase = let LD_LIBRARY_PATH = builtins.concatStringsSep ":" ( [ "${forge}/lib" "${freeimage}/lib" ] ++ lib.optional cudaSupport "${cudaPackages.cudatoolkit}/lib64" # On non-NixOS systems, help the tests find Nvidia drivers ++ lib.optional (nvidiaComputeDrivers != null) "${nvidiaComputeDrivers}/lib" ); ctestFlags = builtins.concatStringsSep " " ( # We have to run with "-j1" otherwise various segfaults occur on non-NixOS systems. [ "--output-on-errors" "-j1" ] # See https://github.com/arrayfire/arrayfire/issues/3484 ++ lib.optional openclSupport "-E '(inverse_dense|cholesky_dense)'" ); in '' export LD_LIBRARY_PATH=${LD_LIBRARY_PATH} '' + # On non-NixOS systems, help the tests find Nvidia drivers lib.optionalString (openclSupport && nvidiaComputeDrivers != null) '' export OCL_ICD_VENDORS=${nvidiaComputeDrivers}/etc/OpenCL/vendors '' + '' # Note: for debugging, enable AF_TRACE=all AF_PRINT_ERRORS=1 ctest ${ctestFlags} ''; buildInputs = [ blas boost.dev boost.out clblast fftw fftwFloat # We need fmt_9 because ArrayFire fails to compile with newer versions. fmt_9 forge freeimage gtest lapack libGL ocl-icd opencl-clhpp span-lite ] ++ lib.optionals cudaSupport [ cudaPackages.cudatoolkit cudaPackages.cudnn cudaPackages.cuda_cccl ] ++ lib.optionals openclSupport [ mesa ]; nativeBuildInputs = [ cmake pkg-config python3 ]; meta = with lib; { description = "General-purpose library for parallel and massively-parallel computations"; longDescription = '' A general-purpose library that simplifies the process of developing software that targets parallel and massively-parallel architectures including CPUs, GPUs, and other hardware acceleration devices."; ''; license = licenses.bsd3; homepage = "https://arrayfire.com/"; platforms = platforms.linux; maintainers = with maintainers; [ chessai twesterhout ]; }; }