Files
TheRock/rocm-systems/projects/hip-tests/catch/unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

581 lines
19 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
/**
* @addtogroup hipMemCreate hipMemCreate
* @{
* @ingroup VirtualMemoryManagementTest
* `hipError_t hipMemCreate (hipMemGenericAllocationHandle_t* handle,
* size_t size,
* const hipMemAllocationProp* prop,
* unsigned long long flags)` -
* Creates a host-resident, NUMA-aware physical memory allocation using
* hipMemLocationTypeHostNuma / hipMemLocationTypeHostNumaCurrent.
*/
#include <numa.h>
#include <vector>
#include <hip_test_kernels.hh>
#include <hip_test_common.hh>
#include "hip_vmm_common.hh"
#define THREADS_PER_BLOCK 512
#define DATA_SIZE (1 << 13)
namespace {
// Square the input data in place.
__global__ void square_kernel(int* buff) {
int i = threadIdx.x + blockDim.x * blockIdx.x;
int temp = buff[i] * buff[i];
buff[i] = temp;
}
// Build a host-NUMA allocation property for the given location type / id.
hipMemAllocationProp makeHostNumaProp(hipMemLocationType locType, int id) {
hipMemAllocationProp prop{};
prop.type = hipMemAllocationTypePinned;
prop.location.type = locType;
prop.location.id = id;
prop.requestedHandleTypes = hipMemHandleTypeNone;
return prop;
}
// NUMA nodes this process is actually permitted to allocate on. Under a
// cpuset-partitioned environment (e.g. Kubernetes/Docker CI slices) the process
// may be restricted to a subset of the hardware nodes; allocating on an excluded
// node yields memory the CPU cannot fault in (SIGBUS on direct access). Use the
// allowed set rather than numa_max_node() so tests only exercise usable nodes.
std::vector<int> allowedNumaNodes() {
std::vector<int> nodes;
struct bitmask* mask = numa_get_mems_allowed();
if (mask == nullptr) {
return nodes;
}
const int maxNode = numa_max_node();
for (int node = 0; node <= maxNode; ++node) {
if (numa_bitmask_isbitset(mask, node)) {
nodes.push_back(node);
}
}
numa_free_nodemask(mask);
return nodes;
}
} // namespace
/**
* Test Description
* ------------------------
* - Query allocation granularity for host-NUMA location types and verify
* it is non-zero for every NUMA node and for the "current" variant.
* ------------------------
* - unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 7.0
*/
HIP_TEST_CASE(Unit_hipMemCreate_HostNuma_Granularity) {
CTX_CREATE();
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, 0));
checkVMMSupported(device);
if (numa_available() < 0) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
const std::vector<int> nodes = allowedNumaNodes();
if (nodes.empty()) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
SECTION("hipMemLocationTypeHostNuma per node") {
for (int node : nodes) {
hipMemAllocationProp prop = makeHostNumaProp(hipMemLocationTypeHostNuma, node);
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
}
}
SECTION("hipMemLocationTypeHostNumaCurrent") {
hipMemAllocationProp prop = makeHostNumaProp(hipMemLocationTypeHostNumaCurrent, 0);
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
}
CTX_DESTROY();
}
/**
* Test Description
* ------------------------
* - Allocate and release host-NUMA physical memory for different multiples
* of granularity, for every NUMA node and the "current" variant.
* ------------------------
* - unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 7.0
*/
HIP_TEST_CASE(Unit_hipMemCreate_HostNuma_BasicAllocDealloc) {
CTX_CREATE();
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, 0));
checkVMMSupported(device);
if (numa_available() < 0) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
const std::vector<int> nodes = allowedNumaNodes();
if (nodes.empty()) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
hipMemLocationType locType = hipMemLocationTypeHostNuma;
int locId = 0;
SECTION("hipMemLocationTypeHostNuma first allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.front();
}
SECTION("hipMemLocationTypeHostNuma last allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.back();
}
SECTION("hipMemLocationTypeHostNumaCurrent") {
locType = hipMemLocationTypeHostNumaCurrent;
locId = 0;
}
hipMemAllocationProp prop = makeHostNumaProp(locType, locId);
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
hipMemGenericAllocationHandle_t handle;
for (int mul = 1; mul < 16; ++mul) {
HIP_CHECK(hipMemCreate(&handle, granularity * mul, &prop, 0));
HIP_CHECK(hipMemRelease(handle));
}
CTX_DESTROY();
}
/**
* Test Description
* ------------------------
* - Allocate host-NUMA physical memory, map it to a VA range, grant device
* access, copy host->VMM->host and verify the data round-trips.
* ------------------------
* - unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 7.0
*/
HIP_TEST_CASE(Unit_hipMemCreate_HostNuma_ChkDev2HstMemcpy) {
constexpr int N = DATA_SIZE;
const size_t buffer_size = N * sizeof(int);
CTX_CREATE();
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, 0));
checkVMMSupported(device);
if (numa_available() < 0) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
const std::vector<int> nodes = allowedNumaNodes();
if (nodes.empty()) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
hipMemLocationType locType = hipMemLocationTypeHostNuma;
int locId = 0;
SECTION("hipMemLocationTypeHostNuma first allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.front();
}
SECTION("hipMemLocationTypeHostNuma last allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.back();
}
SECTION("hipMemLocationTypeHostNumaCurrent") {
locType = hipMemLocationTypeHostNumaCurrent;
locId = 0;
}
hipMemAllocationProp prop = makeHostNumaProp(locType, locId);
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
const size_t size_mem = ((buffer_size + granularity - 1) / granularity) * granularity;
hipMemGenericAllocationHandle_t handle;
HIP_CHECK(hipMemCreate(&handle, size_mem, &prop, 0));
void* ptrA = nullptr;
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, handle, 0));
hipMemAccessDesc accessDesc = {};
accessDesc.location.type = hipMemLocationTypeDevice;
accessDesc.location.id = device;
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
std::vector<int> A_h(N), B_h(N);
for (int idx = 0; idx < N; ++idx) {
A_h[idx] = idx;
}
HIP_CHECK(hipMemcpyHtoD(reinterpret_cast<hipDeviceptr_t>(ptrA), A_h.data(), buffer_size));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), reinterpret_cast<hipDeviceptr_t>(ptrA), buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
HIP_CHECK(hipMemRelease(handle));
CTX_DESTROY();
}
/**
* Test Description
* ------------------------
* - Allocate host-NUMA physical memory, map it, grant device access, copy
* data to it, launch a kernel to square the values and verify the result.
* ------------------------
* - unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 7.0
*/
HIP_TEST_CASE(Unit_hipMemCreate_HostNuma_ChkWithKerLaunch) {
constexpr int N = DATA_SIZE;
const size_t buffer_size = N * sizeof(int);
CTX_CREATE();
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, 0));
checkVMMSupported(device);
if (numa_available() < 0) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
const std::vector<int> nodes = allowedNumaNodes();
if (nodes.empty()) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
hipMemLocationType locType = hipMemLocationTypeHostNuma;
int locId = 0;
SECTION("hipMemLocationTypeHostNuma first allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.front();
}
SECTION("hipMemLocationTypeHostNuma last allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.back();
}
SECTION("hipMemLocationTypeHostNumaCurrent") {
locType = hipMemLocationTypeHostNumaCurrent;
locId = 0;
}
hipMemAllocationProp prop = makeHostNumaProp(locType, locId);
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
const size_t size_mem = ((buffer_size + granularity - 1) / granularity) * granularity;
hipMemGenericAllocationHandle_t handle;
HIP_CHECK(hipMemCreate(&handle, size_mem, &prop, 0));
void* ptrA = nullptr;
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, handle, 0));
HIP_CHECK(hipMemRelease(handle));
hipMemAccessDesc accessDesc = {};
accessDesc.location.type = hipMemLocationTypeDevice;
accessDesc.location.id = device;
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
std::vector<int> A_h(N), B_h(N), C_h(N);
for (int idx = 0; idx < N; ++idx) {
A_h[idx] = idx;
C_h[idx] = idx * idx;
}
HIP_CHECK(hipMemcpyHtoD(reinterpret_cast<hipDeviceptr_t>(ptrA), A_h.data(), buffer_size));
hipLaunchKernelGGL(square_kernel, dim3(N / THREADS_PER_BLOCK), dim3(THREADS_PER_BLOCK), 0, 0,
reinterpret_cast<int*>(ptrA));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), reinterpret_cast<hipDeviceptr_t>(ptrA), buffer_size));
HIP_CHECK(hipDeviceSynchronize());
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), C_h.data()));
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
* Test Description
* ------------------------
* - Allocate host-NUMA memory, grant both host and device access, then verify
* the CPU can directly read/write the mapping and the GPU observes the same
* memory (host writes -> kernel squares in place -> CPU reads result). This
* exercises the host-resident, CPU-accessible nature of the allocation.
*
* - NOTE: the actual NUMA node residency is NOT asserted here. The backing is
* a dma-buf / GTT mapping managed by the amdgpu driver, not a normal anonymous
* VMA, so userspace NUMA introspection (move_pages(), get_mempolicy(),
* /proc/self/numa_maps) cannot resolve its node. Node selection is a code-level
* guarantee in ROCclr (hostVmemAlloc picks cpu_agents_[node]'s pool); verifying
* it from userspace would require root-only KFD topology/debugfs.
* ------------------------
* - unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 7.0
*/
HIP_TEST_CASE(Unit_hipMemCreate_HostNuma_HostAndDeviceAccess) {
constexpr int N = DATA_SIZE;
const size_t buffer_size = N * sizeof(int);
CTX_CREATE();
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, 0));
checkVMMSupported(device);
if (numa_available() < 0) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
const std::vector<int> nodes = allowedNumaNodes();
if (nodes.empty()) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
hipMemLocationType locType = hipMemLocationTypeHostNuma;
int locId = 0;
SECTION("hipMemLocationTypeHostNuma first allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.front();
}
SECTION("hipMemLocationTypeHostNuma last allowed node") {
locType = hipMemLocationTypeHostNuma;
locId = nodes.back();
}
SECTION("hipMemLocationTypeHostNumaCurrent") {
locType = hipMemLocationTypeHostNumaCurrent;
locId = 0;
}
hipMemAllocationProp prop = makeHostNumaProp(locType, locId);
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
const size_t size_mem = ((buffer_size + granularity - 1) / granularity) * granularity;
hipMemGenericAllocationHandle_t handle;
HIP_CHECK(hipMemCreate(&handle, size_mem, &prop, 0));
void* ptrA = nullptr;
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, handle, 0));
hipMemAccessDesc descs[2] = {};
descs[0].location.type = hipMemLocationTypeHost;
descs[0].location.id = 0;
descs[0].flags = hipMemAccessFlagsProtReadWrite;
descs[1].location.type = hipMemLocationTypeDevice;
descs[1].location.id = device;
descs[1].flags = hipMemAccessFlagsProtReadWrite;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &descs[0], 1));
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &descs[1], 1));
// CPU writes directly into the host-resident mapping.
int* hostPtr = reinterpret_cast<int*>(ptrA);
for (int idx = 0; idx < N; ++idx) {
hostPtr[idx] = idx;
}
// GPU squares the same memory in place.
hipLaunchKernelGGL(square_kernel, dim3(N / THREADS_PER_BLOCK), dim3(THREADS_PER_BLOCK), 0, 0,
reinterpret_cast<int*>(ptrA));
HIP_CHECK(hipDeviceSynchronize());
// CPU reads the GPU's results back directly.
for (int idx = 0; idx < N; ++idx) {
REQUIRE(hostPtr[idx] == idx * idx);
}
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
HIP_CHECK(hipMemRelease(handle));
CTX_DESTROY();
}
/**
* Test Description
* ------------------------
* - Path-coverage for granting host access via a NUMA-typed access descriptor
* (hipMemLocationTypeHostNuma / hipMemLocationTypeHostNumaCurrent) instead of the
* generic hipMemLocationTypeHost. Grants host access with the NUMA-typed
* descriptor, then verifies a CPU read/write round-trip through the GPU.
*
* - NOTE: this only exercises the code path; it does NOT assert NUMA-specific
* behavior. In hipMemSetAccess the location names the *accessor*, not placement.
* ROCr grants CPU access node-agnostically: EnableAccess only checks
* device_type == kAmdCpuDevice and mmaps via the memory's owner agent, discarding
* which CPU/NUMA agent was passed. So HostNuma / HostNumaCurrent / Host access
* descriptors are behaviorally identical; this test guards that they are all
* accepted and functional, not that they differ.
* ------------------------
* - unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 7.0
*/
HIP_TEST_CASE(Unit_hipMemCreate_HostNuma_NumaTypedAccess) {
constexpr int N = DATA_SIZE;
const size_t buffer_size = N * sizeof(int);
CTX_CREATE();
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, 0));
checkVMMSupported(device);
if (numa_available() < 0) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
const std::vector<int> nodes = allowedNumaNodes();
if (nodes.empty()) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
// Vary the host-access descriptor's location type/id (the accessor), keeping the
// allocation itself on the first allowed NUMA node.
hipMemLocationType accessType = hipMemLocationTypeHostNuma;
int accessId = nodes.front();
SECTION("access via hipMemLocationTypeHostNuma first allowed node") {
accessType = hipMemLocationTypeHostNuma;
accessId = nodes.front();
}
SECTION("access via hipMemLocationTypeHostNuma last allowed node") {
accessType = hipMemLocationTypeHostNuma;
accessId = nodes.back();
}
SECTION("access via hipMemLocationTypeHostNumaCurrent") {
accessType = hipMemLocationTypeHostNumaCurrent;
accessId = 0;
}
hipMemAllocationProp prop = makeHostNumaProp(hipMemLocationTypeHostNuma, nodes.front());
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
const size_t size_mem = ((buffer_size + granularity - 1) / granularity) * granularity;
hipMemGenericAllocationHandle_t handle;
HIP_CHECK(hipMemCreate(&handle, size_mem, &prop, 0));
void* ptrA = nullptr;
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, handle, 0));
// Grant host access via the NUMA-typed descriptor under test.
hipMemAccessDesc hostDesc = {};
hostDesc.location.type = accessType;
hostDesc.location.id = accessId;
hostDesc.flags = hipMemAccessFlagsProtReadWrite;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &hostDesc, 1));
// Grant device access so the GPU can operate on it.
hipMemAccessDesc devDesc = {};
devDesc.location.type = hipMemLocationTypeDevice;
devDesc.location.id = device;
devDesc.flags = hipMemAccessFlagsProtReadWrite;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &devDesc, 1));
int* hostPtr = reinterpret_cast<int*>(ptrA);
for (int idx = 0; idx < N; ++idx) {
hostPtr[idx] = idx;
}
hipLaunchKernelGGL(square_kernel, dim3(N / THREADS_PER_BLOCK), dim3(THREADS_PER_BLOCK), 0, 0,
reinterpret_cast<int*>(ptrA));
HIP_CHECK(hipDeviceSynchronize());
for (int idx = 0; idx < N; ++idx) {
REQUIRE(hostPtr[idx] == idx * idx);
}
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
HIP_CHECK(hipMemRelease(handle));
CTX_DESTROY();
}
/**
* Test Description
* ------------------------
* - Negative tests for host-NUMA hipMemCreate: invalid NUMA node ids and
* invalid flags.
* ------------------------
* - unit/virtualMemoryManagement/hipMemCreateHostNuma.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 7.0
*/
HIP_TEST_CASE(Unit_hipMemCreate_HostNuma_Negative) {
CTX_CREATE();
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, 0));
checkVMMSupported(device);
if (numa_available() < 0) {
HIP_SKIP_TEST(HipTest::SkipReason::kHostNumaUnavailable);
}
const int numNodes = numa_max_node() + 1;
hipMemAllocationProp prop = makeHostNumaProp(hipMemLocationTypeHostNuma, 0);
size_t granularity = 0;
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
hipMemGenericAllocationHandle_t handle;
SECTION("HostNuma id out of range") {
prop.location.id = numNodes; // one past the last valid node
REQUIRE(hipMemCreate(&handle, granularity, &prop, 0) == hipErrorInvalidValue);
}
SECTION("HostNuma id negative") {
prop.location.id = -1;
REQUIRE(hipMemCreate(&handle, granularity, &prop, 0) == hipErrorInvalidValue);
}
SECTION("HostNuma non-zero flags") {
REQUIRE(hipMemCreate(&handle, granularity, &prop, 1) == hipErrorInvalidValue);
}
SECTION("HostNuma size not a multiple of granularity") {
REQUIRE(hipMemCreate(&handle, granularity - 1, &prop, 0) == hipErrorInvalidValue);
}
CTX_DESTROY();
}
/**
* End doxygen group VirtualMemoryManagementTest.
* @}
*/