From 6aad738c62256a80d62a3a81169a1d9a7dc759ef Mon Sep 17 00:00:00 2001 From: Dylan Jude Date: Mon, 18 May 2026 20:41:44 -1000 Subject: [PATCH 1/6] added device.memoryFree() routine to get free memory of device. Note: memoryFree + memoryAllocated != totalMemory because memoryAllocated includes only OCCA-allocated memory --- include/occa/core/device.hpp | 16 ++++++++++++++++ src/core/device.cpp | 7 +++++++ src/occa/internal/core/device.hpp | 2 ++ src/occa/internal/modes/cuda/device.cpp | 6 ++++++ src/occa/internal/modes/cuda/device.hpp | 1 + src/occa/internal/modes/cuda/polyfill.hpp | 4 ++++ src/occa/internal/modes/cuda/utils.cpp | 8 ++++++++ src/occa/internal/modes/cuda/utils.hpp | 1 + src/occa/internal/modes/hip/device.cpp | 6 ++++++ src/occa/internal/modes/hip/device.hpp | 1 + src/occa/internal/modes/hip/polyfill.hpp | 4 ++++ src/occa/internal/modes/hip/utils.cpp | 8 ++++++++ src/occa/internal/modes/hip/utils.hpp | 1 + src/occa/internal/modes/serial/device.cpp | 4 ++++ src/occa/internal/modes/serial/device.hpp | 1 + tests/src/core/device.cpp | 13 +++++++++++++ 16 files changed, 83 insertions(+) diff --git a/include/occa/core/device.hpp b/include/occa/core/device.hpp index b0461f232..05fbcdb93 100644 --- a/include/occa/core/device.hpp +++ b/include/occa/core/device.hpp @@ -334,6 +334,22 @@ namespace occa { */ udim_t memorySize() const; + /** + * @startDoc{memoryFree} + * + * Description: + * Finds how much device memory is currently free, accounting for + * allocations made outside of OCCA. For host-based backends (Serial, + * OpenMP) this reports system-wide free memory, not a per-process + * budget. + * + * Description: + * Returns the free memory in bytes. + * + * @endDoc + */ + udim_t memoryFree() const; + /** * @startDoc{memoryAllocated} * diff --git a/src/core/device.cpp b/src/core/device.cpp index 45fbdd42b..080309faa 100644 --- a/src/core/device.cpp +++ b/src/core/device.cpp @@ -233,6 +233,13 @@ namespace occa { return 0; } + udim_t device::memoryFree() const { + if (modeDevice) { + return modeDevice->memoryFree(); + } + return 0; + } + udim_t device::memoryAllocated() const { if (modeDevice) { return modeDevice->bytesAllocated; diff --git a/src/occa/internal/core/device.hpp b/src/occa/internal/core/device.hpp index a90ae19f0..41cef4f3a 100644 --- a/src/occa/internal/core/device.hpp +++ b/src/occa/internal/core/device.hpp @@ -121,6 +121,8 @@ namespace occa { virtual modeMemoryPool_t* createMemoryPool(const occa::json &props)=0; virtual udim_t memorySize() const = 0; + + virtual udim_t memoryFree() const { return 0; } // |=============================== virtual void* unwrap() = 0; diff --git a/src/occa/internal/modes/cuda/device.cpp b/src/occa/internal/modes/cuda/device.cpp index bdc09d8d9..06be1d6df 100644 --- a/src/occa/internal/modes/cuda/device.cpp +++ b/src/occa/internal/modes/cuda/device.cpp @@ -446,6 +446,12 @@ namespace occa { udim_t device::memorySize() const { return cuda::getDeviceMemorySize(cuDevice); } + + udim_t device::memoryFree() const { + OCCA_CUDA_ERROR("Device: Setting Context", + cuCtxSetCurrent(cuContext)); + return cuda::getDeviceMemoryFree(); + } //================================== void* device::unwrap() { diff --git a/src/occa/internal/modes/cuda/device.hpp b/src/occa/internal/modes/cuda/device.hpp index 6ce555b6d..f9a8bf342 100644 --- a/src/occa/internal/modes/cuda/device.hpp +++ b/src/occa/internal/modes/cuda/device.hpp @@ -100,6 +100,7 @@ namespace occa { modeMemoryPool_t* createMemoryPool(const occa::json &props) override; udim_t memorySize() const override; + udim_t memoryFree() const override; //================================ void* unwrap() override; diff --git a/src/occa/internal/modes/cuda/polyfill.hpp b/src/occa/internal/modes/cuda/polyfill.hpp index b06284e02..4396f22f4 100644 --- a/src/occa/internal/modes/cuda/polyfill.hpp +++ b/src/occa/internal/modes/cuda/polyfill.hpp @@ -187,6 +187,10 @@ namespace occa { return OCCA_CUDA_IS_NOT_ENABLED; } + inline CUresult cuMemGetInfo(size_t *free, size_t *total) { + return OCCA_CUDA_IS_NOT_ENABLED; + } + inline CUresult cuMemAllocHost(void **pp, size_t bytesize) { return OCCA_CUDA_IS_NOT_ENABLED; } diff --git a/src/occa/internal/modes/cuda/utils.cpp b/src/occa/internal/modes/cuda/utils.cpp index 4bd4f506e..e9c2e8761 100644 --- a/src/occa/internal/modes/cuda/utils.cpp +++ b/src/occa/internal/modes/cuda/utils.cpp @@ -44,6 +44,14 @@ namespace occa { return bytes; } + udim_t getDeviceMemoryFree() { + size_t freeBytes = 0; + size_t totalBytes = 0; + OCCA_CUDA_ERROR("Finding free memory on device", + cuMemGetInfo(&freeBytes, &totalBytes)); + return freeBytes; + } + std::string getVersion() { std::stringstream ss; ss << ((int) (CUDA_VERSION / 1000)) diff --git a/src/occa/internal/modes/cuda/utils.hpp b/src/occa/internal/modes/cuda/utils.hpp index df65e0e8e..1b5612656 100644 --- a/src/occa/internal/modes/cuda/utils.hpp +++ b/src/occa/internal/modes/cuda/utils.hpp @@ -17,6 +17,7 @@ namespace occa { int getDeviceCount(); CUdevice getDevice(const int id); udim_t getDeviceMemorySize(CUdevice device); + udim_t getDeviceMemoryFree(); std::string getVersion(); diff --git a/src/occa/internal/modes/hip/device.cpp b/src/occa/internal/modes/hip/device.cpp index 56678c6b7..67f1696a3 100644 --- a/src/occa/internal/modes/hip/device.cpp +++ b/src/occa/internal/modes/hip/device.cpp @@ -419,6 +419,12 @@ namespace occa { udim_t device::memorySize() const { return hip::getDeviceMemorySize(hipDevice); } + + udim_t device::memoryFree() const { + OCCA_HIP_ERROR("Device: Setting Device", + hipSetDevice(deviceID)); + return hip::getDeviceMemoryFree(); + } //================================== void* device::unwrap() { diff --git a/src/occa/internal/modes/hip/device.hpp b/src/occa/internal/modes/hip/device.hpp index b988b729d..ffb803467 100644 --- a/src/occa/internal/modes/hip/device.hpp +++ b/src/occa/internal/modes/hip/device.hpp @@ -90,6 +90,7 @@ namespace occa { modeMemoryPool_t* createMemoryPool(const occa::json &props) override; udim_t memorySize() const override; + udim_t memoryFree() const override; //================================ void* unwrap() override; diff --git a/src/occa/internal/modes/hip/polyfill.hpp b/src/occa/internal/modes/hip/polyfill.hpp index 936fd366a..387a9ce7f 100644 --- a/src/occa/internal/modes/hip/polyfill.hpp +++ b/src/occa/internal/modes/hip/polyfill.hpp @@ -203,6 +203,10 @@ namespace occa { return OCCA_HIP_IS_NOT_ENABLED; } + inline hipError_t hipMemGetInfo(size_t *free, size_t *total) { + return OCCA_HIP_IS_NOT_ENABLED; + } + inline hipError_t hipFree(hipDeviceptr_t dptr) { return OCCA_HIP_IS_NOT_ENABLED; } diff --git a/src/occa/internal/modes/hip/utils.cpp b/src/occa/internal/modes/hip/utils.cpp index 7b90aef41..b2239597e 100644 --- a/src/occa/internal/modes/hip/utils.cpp +++ b/src/occa/internal/modes/hip/utils.cpp @@ -37,6 +37,14 @@ namespace occa { return bytes; } + udim_t getDeviceMemoryFree() { + size_t freeBytes = 0; + size_t totalBytes = 0; + OCCA_HIP_ERROR("Finding free memory on device", + hipMemGetInfo(&freeBytes, &totalBytes)); + return freeBytes; + } + std::string getVersion() { std::stringstream ss; int driverVersion = 0; diff --git a/src/occa/internal/modes/hip/utils.hpp b/src/occa/internal/modes/hip/utils.hpp index 9e5d300b2..c580eda2e 100644 --- a/src/occa/internal/modes/hip/utils.hpp +++ b/src/occa/internal/modes/hip/utils.hpp @@ -13,6 +13,7 @@ namespace occa { int getDeviceCount(); hipDevice_t getDevice(const int id); udim_t getDeviceMemorySize(hipDevice_t device); + udim_t getDeviceMemoryFree(); std::string getVersion(); diff --git a/src/occa/internal/modes/serial/device.cpp b/src/occa/internal/modes/serial/device.cpp index 97376e0ec..1865b3685 100644 --- a/src/occa/internal/modes/serial/device.cpp +++ b/src/occa/internal/modes/serial/device.cpp @@ -477,6 +477,10 @@ namespace occa { udim_t device::memorySize() const { return sys::SystemInfo::load().memory.total; } + + udim_t device::memoryFree() const { + return sys::SystemInfo::load().memory.available; + } //================================== void* device::unwrap() { diff --git a/src/occa/internal/modes/serial/device.hpp b/src/occa/internal/modes/serial/device.hpp index 5796c1a49..4092afb50 100644 --- a/src/occa/internal/modes/serial/device.hpp +++ b/src/occa/internal/modes/serial/device.hpp @@ -72,6 +72,7 @@ namespace occa { modeMemoryPool_t* createMemoryPool(const occa::json &props) override; udim_t memorySize() const override; + udim_t memoryFree() const override; //================================ void* unwrap() override; diff --git a/tests/src/core/device.cpp b/tests/src/core/device.cpp index 10d701185..257a83beb 100644 --- a/tests/src/core/device.cpp +++ b/tests/src/core/device.cpp @@ -4,15 +4,28 @@ void testProperties(); void testWrapMemory(); void testUnwrap(); +void testMemoryStats(); int main(const int argc, const char **argv) { testProperties(); testWrapMemory(); testUnwrap(); + testMemoryStats(); return 0; } +void testMemoryStats() { + occa::device device({{"mode", "Serial"}}); + + const occa::udim_t total = device.memorySize(); + const occa::udim_t free = device.memoryFree(); + + ASSERT_GT(total, (occa::udim_t) 0); + ASSERT_GT(free, (occa::udim_t) 0); + ASSERT_LE(free, total); +} + void testProperties() { occa::device device; From a65d849b16492154e7d70192764cc2f26f927bb5 Mon Sep 17 00:00:00 2001 From: Dylan Jude Date: Mon, 18 May 2026 20:53:04 -1000 Subject: [PATCH 2/6] added spack repo package.py file --- scripts/spack/packages/occa/package.py | 58 ++++++++++++++++++++++++++ scripts/spack/repo.yaml | 2 + 2 files changed, 60 insertions(+) create mode 100644 scripts/spack/packages/occa/package.py create mode 100644 scripts/spack/repo.yaml diff --git a/scripts/spack/packages/occa/package.py b/scripts/spack/packages/occa/package.py new file mode 100644 index 000000000..444dc4039 --- /dev/null +++ b/scripts/spack/packages/occa/package.py @@ -0,0 +1,58 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack.package import * + + +class Occa(CMakePackage): + """OCCA: Portable approach for parallel architectures.""" + + homepage = "https://libocca.org" + git = "https://github.com/dylanjude/occa.git" + url = "https://github.com/dylanjude/occa/archive/refs/tags/v2.0.0.tar.gz" + + maintainers("dylanjude") + license("MIT") + + version("main", branch="main") + version("2.0.0", sha256="f2521901fed5d199193d54c7db4186479a974bdae92ac97779c47fa2bb68badd") + version("1.6.0", sha256="b863a24171000097121aff5c43dadf22416c143824598a51c653689fd917794f") + version("1.5.0", sha256="b939f826f3e970b45aa77089568995399355fcdad3bc787b60cf73eb4962b0b7") + version("1.4.0", sha256="5995288615f45dd2cf2f3e13b9e04c3b89edde1e014d36c6da014c11b9adb4a7") + + variant("cuda", default=True, description="Activates support for CUDA") + variant("hip", default=False, description="Activates support for HIP") + variant("openmp", default=True, description="Activates support for OpenMP") + variant("opencl", default=False, description="Activates support for OpenCL") + variant("dpcpp", default=False, description="Activates support for DPCPP") + + depends_on("c", type="build") + depends_on("cxx", type="build") + + depends_on("cuda", when="+cuda") + depends_on("hip", when="+hip") + + depends_on("cmake", type="build") + + def cmake_args(self): + args = [ + self.define("CMAKE_BUILD_TYPE", "Release"), + self.define_from_variant("OCCA_ENABLE_CUDA", "cuda"), + self.define_from_variant("OCCA_ENABLE_HIP", "hip"), + self.define_from_variant("OCCA_ENABLE_OPENMP", "openmp"), + self.define_from_variant("OCCA_ENABLE_OPENCL", "opencl"), + self.define_from_variant("OCCA_ENABLE_DPCPP", "dpcpp"), + ] + return args + + def setup_dependent_build_environment(self, env, dependent_spec): + env.set("OCCA_INSTALL_DIR", self.prefix) + env.set("OCCA_DIR", self.prefix) + env.set("OCCA_HOME", self.prefix) + + def setup_run_environment(self, env): + env.set("OCCA_INSTALL_DIR", self.prefix) + env.set("OCCA_DIR", self.prefix) + env.set("OCCA_HOME", self.prefix) diff --git a/scripts/spack/repo.yaml b/scripts/spack/repo.yaml new file mode 100644 index 000000000..a720fa7a1 --- /dev/null +++ b/scripts/spack/repo.yaml @@ -0,0 +1,2 @@ +repo: + namespace: occa From f240ccc86de02dbbdada6e3f358ad82c28fdfbd4 Mon Sep 17 00:00:00 2001 From: Dylan Jude Date: Tue, 19 May 2026 08:01:32 -1000 Subject: [PATCH 3/6] modified device.hash function to use device uuid --- src/occa/internal/modes/cuda/device.cpp | 8 +++++++- src/occa/internal/modes/cuda/polyfill.hpp | 5 +++++ src/occa/internal/modes/hip/device.cpp | 16 +++++++++++++++- src/occa/internal/modes/hip/polyfill.hpp | 5 +++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/occa/internal/modes/cuda/device.cpp b/src/occa/internal/modes/cuda/device.cpp index 06be1d6df..ddcf653f2 100644 --- a/src/occa/internal/modes/cuda/device.cpp +++ b/src/occa/internal/modes/cuda/device.cpp @@ -82,7 +82,13 @@ namespace occa { std::stringstream ss; ss << "major: " << archMajorVersion << ' ' << "minor: " << archMinorVersion; - hash_ = occa::hash(ss.str()); + + CUuuid uuid; + OCCA_CUDA_ERROR("Getting device UUID", + cuDeviceGetUuid(&uuid, cuDevice)); + + hash_ = (occa::hash(ss.str()) + ^ occa::hash(uuid.bytes, sizeof(uuid.bytes))); } return hash_; } diff --git a/src/occa/internal/modes/cuda/polyfill.hpp b/src/occa/internal/modes/cuda/polyfill.hpp index 4396f22f4..736622483 100644 --- a/src/occa/internal/modes/cuda/polyfill.hpp +++ b/src/occa/internal/modes/cuda/polyfill.hpp @@ -16,6 +16,7 @@ namespace occa { //---[ Types ]------------------------ struct _CUdeviceptr {}; + struct CUuuid { char bytes[16]; }; typedef struct _CUcontext* CUcontext; typedef int CUdevice; typedef struct _CUdeviceptr* CUdeviceptr; @@ -160,6 +161,10 @@ namespace occa { return OCCA_CUDA_IS_NOT_ENABLED; } + inline CUresult cuDeviceGetUuid(CUuuid *uuid, CUdevice dev) { + return OCCA_CUDA_IS_NOT_ENABLED; + } + // ---[ Event ]--------------------- inline CUresult cuEventCreate(CUevent *phEvent, unsigned int Flags) { return OCCA_CUDA_IS_NOT_ENABLED; diff --git a/src/occa/internal/modes/hip/device.cpp b/src/occa/internal/modes/hip/device.cpp index 67f1696a3..79c652e25 100644 --- a/src/occa/internal/modes/hip/device.cpp +++ b/src/occa/internal/modes/hip/device.cpp @@ -71,7 +71,21 @@ namespace occa { hash_t device::hash() const { if (!hash_.initialized) { - hash_ = occa::hash(arch); +#if !defined(HIP_VERSION) || (HIP_VERSION >= 50200000) + hipUUID uuid; + OCCA_HIP_ERROR("Getting device UUID", + hipDeviceGetUuid(&uuid, hipDevice)); + + hash_ = (occa::hash(arch) + ^ occa::hash(uuid.bytes, sizeof(uuid.bytes))); +#else + char pciId[64] = {0}; + OCCA_HIP_ERROR("Getting device PCI bus ID", + hipDeviceGetPCIBusId(pciId, sizeof(pciId), hipDevice)); + + hash_ = (occa::hash(arch) + ^ occa::hash(std::string(pciId))); +#endif } return hash_; } diff --git a/src/occa/internal/modes/hip/polyfill.hpp b/src/occa/internal/modes/hip/polyfill.hpp index 387a9ce7f..cadd6baf2 100644 --- a/src/occa/internal/modes/hip/polyfill.hpp +++ b/src/occa/internal/modes/hip/polyfill.hpp @@ -17,6 +17,7 @@ // are indistinguisable inside the occa namespace namespace occa { //---[ Types ]------------------------ + struct hipUUID { char bytes[16]; }; typedef struct _hipCtx_t* hipCtx_t; typedef int hipDevice_t; typedef void* hipDeviceptr_t; @@ -207,6 +208,10 @@ namespace occa { return OCCA_HIP_IS_NOT_ENABLED; } + inline hipError_t hipDeviceGetUuid(hipUUID *uuid, hipDevice_t dev) { + return OCCA_HIP_IS_NOT_ENABLED; + } + inline hipError_t hipFree(hipDeviceptr_t dptr) { return OCCA_HIP_IS_NOT_ENABLED; } From 9a0f8d6e35fc1d1d5b77f4e7d7c57ae9e0cc9b05 Mon Sep 17 00:00:00 2001 From: Dylan Jude Date: Fri, 22 May 2026 10:22:37 -1000 Subject: [PATCH 4/6] added device::name to get a semantic name of devices --- include/occa/core/device.hpp | 15 +++++++++++++++ src/core/device.cpp | 7 +++++++ src/occa/internal/core/device.hpp | 1 + src/occa/internal/modes/cuda/device.cpp | 5 +++++ src/occa/internal/modes/hip/device.cpp | 5 +++++ src/occa/internal/modes/serial/device.cpp | 1 + 6 files changed, 34 insertions(+) diff --git a/include/occa/core/device.hpp b/include/occa/core/device.hpp index 05fbcdb93..600ce7b3b 100644 --- a/include/occa/core/device.hpp +++ b/include/occa/core/device.hpp @@ -297,6 +297,21 @@ namespace occa { */ const std::string& arch() const; + /** + * @startDoc{name} + * + * Description: + * Returns a human-readable name for the physical device. + * For GPU backends this is the product name (e.g. "NVIDIA RTX A4000"). + * For host-based backends this returns "CPU". + * + * Returns: + * The device name string. + * + * @endDoc + */ + const std::string& name() const; + const occa::json& kernelProperties() const; occa::json kernelProperties(const occa::json &additionalProps) const; diff --git a/src/core/device.cpp b/src/core/device.cpp index 080309faa..c3d5c2b3b 100644 --- a/src/core/device.cpp +++ b/src/core/device.cpp @@ -183,6 +183,13 @@ namespace occa { : noArch); } + const std::string& device::name() const { + static const std::string noName = "No Name"; + return (modeDevice + ? modeDevice->name + : noName); + } + const occa::json& device::kernelProperties() const { assertInitialized(); return (const occa::json&) modeDevice->properties["kernel"]; diff --git a/src/occa/internal/core/device.hpp b/src/occa/internal/core/device.hpp index 41cef4f3a..03f68907f 100644 --- a/src/occa/internal/core/device.hpp +++ b/src/occa/internal/core/device.hpp @@ -11,6 +11,7 @@ namespace occa { public: std::string mode; std::string arch; + std::string name; occa::json properties; bool needsLauncherKernel; diff --git a/src/occa/internal/modes/cuda/device.cpp b/src/occa/internal/modes/cuda/device.cpp index ddcf653f2..ceb73129e 100644 --- a/src/occa/internal/modes/cuda/device.cpp +++ b/src/occa/internal/modes/cuda/device.cpp @@ -61,6 +61,11 @@ namespace occa { getDeviceArchVersion(cuDevice, archMajorVersion, archMinorVersion); arch = getDeviceArch(cuDevice); + + char deviceName[1024]; + OCCA_CUDA_ERROR("Device: Getting Device Name", + cuDeviceGetName(deviceName, 1024, cuDevice)); + name = std::string(deviceName); } device::~device() { diff --git a/src/occa/internal/modes/hip/device.cpp b/src/occa/internal/modes/hip/device.cpp index 79c652e25..7e6820a5a 100644 --- a/src/occa/internal/modes/hip/device.cpp +++ b/src/occa/internal/modes/hip/device.cpp @@ -61,6 +61,11 @@ namespace occa { kernelProps["compiler_flags"] = compilerFlags; arch = getDeviceArch(deviceID); + + hipDeviceProp_t hipProps; + OCCA_HIP_ERROR("Device: Getting Device Properties", + hipGetDeviceProperties(&hipProps, deviceID)); + name = std::string(hipProps.name); } device::~device() { } diff --git a/src/occa/internal/modes/serial/device.cpp b/src/occa/internal/modes/serial/device.cpp index 1865b3685..ed523c07a 100644 --- a/src/occa/internal/modes/serial/device.cpp +++ b/src/occa/internal/modes/serial/device.cpp @@ -17,6 +17,7 @@ namespace occa { occa::modeDevice_t(properties_) { // TODO: Maybe theres something more descriptive we can populate here arch = std::string("CPU"); + name = std::string("CPU"); } bool device::hasSeparateMemorySpace() const { From bab9ce34b7cfc59e202325d99366dbf11132dcef Mon Sep 17 00:00:00 2001 From: Dylan Jude Date: Thu, 4 Jun 2026 14:20:01 -1000 Subject: [PATCH 5/6] add OCCA_FORK_EXTENSIONS macro to signal fork-specific API availability Co-Authored-By: Claude Sonnet 4.6 --- include/occa/defines/occa.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/occa/defines/occa.hpp b/include/occa/defines/occa.hpp index e9446f7fc..df05eeadc 100644 --- a/include/occa/defines/occa.hpp +++ b/include/occa/defines/occa.hpp @@ -17,4 +17,7 @@ #define OCCA_DEFAULT_MEM_BYTE_ALIGN 32 +// Defined in this fork to signal availability of device.name() and device.memoryFree() +#define OCCA_FORK_EXTENSIONS 1 + #endif From e2d4da5782e042c8a8e811b0d77eb3d69df7b329 Mon Sep 17 00:00:00 2001 From: Jay Sitaraman Date: Fri, 28 Aug 2026 11:09:58 -0700 Subject: [PATCH 6/6] Modify cuda prefetch sync that was weakly supported in cuda 12 --- src/occa/internal/modes/cuda/utils.cpp | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/occa/internal/modes/cuda/utils.cpp b/src/occa/internal/modes/cuda/utils.cpp index e9c2e8761..9819c1560 100644 --- a/src/occa/internal/modes/cuda/utils.cpp +++ b/src/occa/internal/modes/cuda/utils.cpp @@ -193,11 +193,26 @@ namespace occa { ? ((cuda::device*) device.getModeDevice())->cuDevice : CU_DEVICE_CPU); +#if CUDA_VERSION >= 11020 + // CUDA 11.2+ replaced the CUdevice argument with a CUmemLocation + CUmemLocation location; + location.type = (device.mode() == "CUDA") + ? CU_MEM_LOCATION_TYPE_DEVICE + : CU_MEM_LOCATION_TYPE_HOST; + location.id = cuDevice; + + OCCA_CUDA_ERROR("Advising about unified memory", + cuMemAdvise(((cuda::memory*) mem.getModeMemory())->cuPtr, + (size_t) bytes_, + advice, + location)); +#else OCCA_CUDA_ERROR("Advising about unified memory", cuMemAdvise(((cuda::memory*) mem.getModeMemory())->cuPtr, (size_t) bytes_, advice, cuDevice)); +#endif #else OCCA_FORCE_ERROR("CUDA version [" << cuda::getVersion() @@ -223,11 +238,27 @@ namespace occa { ? ((cuda::device*) device.getModeDevice())->cuDevice : CU_DEVICE_CPU); occa::stream stream = device.getStream(); +#if CUDA_VERSION >= 11020 + // CUDA 11.2+ replaced the CUdevice argument with a CUmemLocation plus flags + CUmemLocation location; + location.type = (device.mode() == "CUDA") + ? CU_MEM_LOCATION_TYPE_DEVICE + : CU_MEM_LOCATION_TYPE_HOST; + location.id = cuDevice; + + OCCA_CUDA_ERROR("Prefetching unified memory", + cuMemPrefetchAsync(((cuda::memory*) mem.getModeMemory())->cuPtr, + (size_t) bytes_, + location, + 0, + *((CUstream*) stream.getModeStream())) ); +#else OCCA_CUDA_ERROR("Prefetching unified memory", cuMemPrefetchAsync(((cuda::memory*) mem.getModeMemory())->cuPtr, (size_t) bytes_, cuDevice, *((CUstream*) stream.getModeStream())) ); +#endif #else OCCA_FORCE_ERROR("CUDA version [" << cuda::getVersion()