SWDEV-499927 - Enable Virtual Memory tests on NV platform (#79)

This commit is contained in:
Arandjelovic, Marko
2025-05-13 00:21:38 +02:00
committed by GitHub
parent fd8833cc83
commit dec3869d6d
15 changed files with 256 additions and 333 deletions
@@ -79,6 +79,7 @@ TEST_CASE("Unit_hipMemSetAccess_SetGet") {
size_t buffer_size = N * sizeof(int);
int deviceId = 0;
hipDevice_t device;
CTX_CREATE();
HIP_CHECK(hipDeviceGet(&device, deviceId));
checkVMMSupported(device);
hipMemAllocationProp prop{};
@@ -123,6 +124,7 @@ TEST_CASE("Unit_hipMemSetAccess_SetGet") {
}
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -181,7 +183,7 @@ TEST_CASE("Unit_hipMemSetAccess_MultDevSetGet") {
accessDesc[1].location.id = device1;
accessDesc[1].flags = hipMemAccessFlagsProtReadWrite;
// Make the address accessible to GPU 0 and 1
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc[0], 2));
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, accessDesc, 2));
// Validate using hipMemGetAccess()
hipMemLocation location;
location.type = hipMemLocationTypeDevice;
@@ -214,6 +216,7 @@ TEST_CASE("Unit_hipMemSetAccess_EntireVMMRangeSetGet") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int deviceId = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -248,12 +251,13 @@ TEST_CASE("Unit_hipMemSetAccess_EntireVMMRangeSetGet") {
unsigned long long flags = 0; // NOLINT
HIP_CHECK(hipMemGetAccess(&flags, &location, ptrA));
REQUIRE(flags == hipMemAccessFlagsProtReadWrite);
uint64_t uiptr = reinterpret_cast<uint64_t>(ptrA);
unsigned long long uiptr = reinterpret_cast<unsigned long long>(ptrA);
uiptr += (size_mem - 1);
HIP_CHECK(hipMemGetAccess(&flags, &location, reinterpret_cast<void*>(uiptr)));
HIP_CHECK(hipMemGetAccess(&flags, &location, reinterpret_cast<hipDeviceptr_t>(uiptr)));
REQUIRE(flags == hipMemAccessFlagsProtReadWrite);
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -270,6 +274,7 @@ TEST_CASE("Unit_hipMemGetAccess_NegTst") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int deviceId = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -307,12 +312,13 @@ TEST_CASE("Unit_hipMemGetAccess_NegTst") {
REQUIRE(status == hipErrorInvalidValue);
status = hipMemGetAccess(&flags, nullptr, ptrA);
REQUIRE(status == hipErrorInvalidValue);
uint64_t uiptr = reinterpret_cast<uint64_t>(ptrA);
unsigned long long uiptr = reinterpret_cast<unsigned long long>(ptrA);
uiptr += size_mem;
status = hipMemGetAccess(&flags, &location, reinterpret_cast<void*>(uiptr));
status = hipMemGetAccess(&flags, &location, reinterpret_cast<hipDeviceptr_t>(uiptr));
REQUIRE(status == hipErrorInvalidValue);
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -332,16 +338,20 @@ TEST_CASE("Unit_hipMemSetAccess_FuncTstOnMultDev") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int deviceId = 0, devicecount = 0;
hipDevice_t device;
HIP_CHECK(hipGetDeviceCount(&devicecount));
if (devicecount < 2) {
HipTest::HIP_SKIP_TEST("Machine is Single GPU. Skipping Test..");
return;
}
for (deviceId = 0; deviceId < devicecount; deviceId++) {
HIP_CHECK(hipDeviceGet(&device, deviceId));
checkVMMSupported(device);
HIP_CHECK(hipSetDevice(deviceId));
checkVMMSupported(deviceId);
hipMemAllocationProp prop{};
prop.type = hipMemAllocationTypePinned;
prop.location.type = hipMemLocationTypeDevice;
prop.location.id = device; // Current Devices
prop.location.id = deviceId; // Current Devices
HIP_CHECK(
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
REQUIRE(granularity > 0);
@@ -357,7 +367,7 @@ TEST_CASE("Unit_hipMemSetAccess_FuncTstOnMultDev") {
// Set access
hipMemAccessDesc accessDesc = {};
accessDesc.location.type = hipMemLocationTypeDevice;
accessDesc.location.id = device;
accessDesc.location.id = deviceId;
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
// Make the address accessible to GPU deviceId
std::vector<int> A_h(N), B_h(N);
@@ -371,16 +381,16 @@ TEST_CASE("Unit_hipMemSetAccess_FuncTstOnMultDev") {
for (int idx = 0; idx < N; idx++) {
A_h[idx] = idx * idx;
}
HIP_CHECK(hipSetDevice(deviceId));
// Launch square kernel
hipLaunchKernelGGL(square_kernel, dim3(N / THREADS_PER_BLOCK), dim3(THREADS_PER_BLOCK), 0, 0,
static_cast<int*>(ptrA));
reinterpret_cast<int*>(ptrA));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptrA, buffer_size));
HIP_CHECK(hipDeviceSynchronize());
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));
}
CTX_DESTROY();
}
/**
@@ -402,6 +412,7 @@ TEST_CASE("Unit_hipMemSetAccess_ChangeAccessProp") {
size_t buffer_size = N * sizeof(int);
int dev = 0;
hipDevice_t device;
CTX_CREATE();
HIP_CHECK(hipDeviceGet(&device, dev));
checkVMMSupported(device);
hipMemAllocationProp prop{};
@@ -427,17 +438,7 @@ TEST_CASE("Unit_hipMemSetAccess_ChangeAccessProp") {
hipMemAccessDesc accessDesc = {};
accessDesc.location.type = hipMemLocationTypeDevice;
accessDesc.location.id = device;
SECTION("Change ReadWrite to Read") {
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
HIP_CHECK(hipMemcpyHtoD(ptrA, A_h.data(), buffer_size));
// Change property of virtual memory range to read only
accessDesc.flags = hipMemAccessFlagsProtRead;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
// validate
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptrA, buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
}
SECTION("Change Read to ReadWrite") {
accessDesc.flags = hipMemAccessFlagsProtRead;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
@@ -448,6 +449,7 @@ TEST_CASE("Unit_hipMemSetAccess_ChangeAccessProp") {
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptrA, buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
}
SECTION("Change Inaccessible to ReadWrite") {
accessDesc.flags = hipMemAccessFlagsProtNone;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
@@ -458,22 +460,26 @@ TEST_CASE("Unit_hipMemSetAccess_ChangeAccessProp") {
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptrA, buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
}
#if HT_NVIDIA
SECTION("Check error while writing on Read-Only memory") {
accessDesc.flags = hipMemAccessFlagsProtRead;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
REQUIRE(hipErrorInvalidValue == hipMemcpyHtoD(ptrA, A_h.data(), buffer_size));
}
SECTION("Check error while writing on inaccessible memory") {
accessDesc.flags = hipMemAccessFlagsProtNone;
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
REQUIRE(hipErrorInvalidValue == hipMemcpyHtoD(ptrA, A_h.data(), buffer_size));
}
#endif
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
// Release resources
HIP_CHECK(hipMemRelease(handle));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -489,6 +495,7 @@ TEST_CASE("Unit_hipMemSetAccess_ChangeAccessProp") {
* - HIP_VERSION >= 6.1
*/
TEST_CASE("Unit_hipMemSetAccess_Vmm2UnifiedMemCpy") {
CTX_CREATE();
auto managed = HmmAttrPrint();
if (managed != 1) {
HipTest::HIP_SKIP_TEST("GPU doesn't support managed memory.Skipping Test..");
@@ -531,7 +538,7 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2UnifiedMemCpy") {
ptrA_h[idx] = idx;
}
HIP_CHECK(hipMemcpyHtoD(ptrA, ptrA_h, buffer_size));
HIP_CHECK(hipMalloc(&ptrB, buffer_size));
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&ptrB), buffer_size));
HIP_CHECK(hipMemcpyDtoD(ptrB, ptrA, buffer_size));
HIP_CHECK(hipMemcpyDtoH(ptrB_h, ptrB, buffer_size));
bool bPassed = true;
@@ -542,11 +549,12 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2UnifiedMemCpy") {
}
}
REQUIRE(bPassed == true);
HIP_CHECK(hipFree(ptrB));
HIP_CHECK(hipFree(ptrA_h));
HIP_CHECK(hipFree(ptrB_h));
HIP_CHECK(hipFree(reinterpret_cast<void*>(ptrB)));
HIP_CHECK(hipFree(reinterpret_cast<void*>(ptrA_h)));
HIP_CHECK(hipFree(reinterpret_cast<void*>(ptrB_h)));
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -565,6 +573,7 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2DevMemCpy") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int deviceId = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -597,13 +606,14 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2DevMemCpy") {
A_h[idx] = idx;
}
HIP_CHECK(hipMemcpyHtoD(ptrA, A_h.data(), buffer_size));
HIP_CHECK(hipMalloc(&ptrB, buffer_size));
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&ptrB), buffer_size));
HIP_CHECK(hipMemcpyDtoD(ptrB, ptrA, buffer_size));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptrB, buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
HIP_CHECK(hipFree(ptrB));
HIP_CHECK(hipFree(reinterpret_cast<void*>(ptrB)));
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -622,6 +632,13 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2PeerDevMemCpy") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int devicecount = 0;
HIP_CHECK(hipGetDeviceCount(&devicecount));
if (devicecount < 2) {
HipTest::HIP_SKIP_TEST("Machine is Single GPU. Skipping Test..");
return;
}
int deviceId = 0, value = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -654,8 +671,6 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2PeerDevMemCpy") {
A_h[idx] = idx;
}
HIP_CHECK(hipMemcpyHtoD(ptrA, A_h.data(), buffer_size));
int devicecount = 0;
HIP_CHECK(hipGetDeviceCount(&devicecount));
// Check Peer Access
for (deviceId = 1; deviceId < devicecount; deviceId++) {
int canAccessPeer = 0;
@@ -674,15 +689,22 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2PeerDevMemCpy") {
break;
}
HIP_CHECK(hipSetDevice(deviceId));
hipMemAccessDesc access = {};
access.location.type = hipMemLocationTypeDevice;
access.location.id = deviceId;
access.flags = hipMemAccessFlagsProtReadWrite;
// Make the address accessible to GPU 0
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &access, 1));
hipDeviceptr_t dptr_peer;
HIP_CHECK(hipMalloc(&dptr_peer, buffer_size));
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&dptr_peer), buffer_size));
HIP_CHECK(hipMemcpyDtoD(dptr_peer, ptrA, buffer_size));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), dptr_peer, buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
HIP_CHECK(hipFree(dptr_peer));
HIP_CHECK(hipFree(reinterpret_cast<void*>(dptr_peer)));
}
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -701,6 +723,13 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2PeerPeerMemCpy") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int devicecount = 0;
HIP_CHECK(hipGetDeviceCount(&devicecount));
if (devicecount < 2) {
HipTest::HIP_SKIP_TEST("Machine is Single GPU. Skipping Test..");
return;
}
int deviceId = 0, value = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -733,8 +762,6 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2PeerPeerMemCpy") {
A_h[idx] = idx;
}
HIP_CHECK(hipMemcpyHtoD(ptrA, A_h.data(), buffer_size));
int devicecount = 0;
HIP_CHECK(hipGetDeviceCount(&devicecount));
// Check Peer Access
for (deviceId = 1; deviceId < devicecount; deviceId++) {
std::fill(B_h.begin(), B_h.end(), initializer);
@@ -763,14 +790,16 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2PeerPeerMemCpy") {
}
HIP_CHECK(hipSetDevice(deviceId));
hipDeviceptr_t dptr_peer;
HIP_CHECK(hipMalloc(&dptr_peer, buffer_size));
HIP_CHECK(hipMemcpyPeer(dptr_peer, deviceId, ptrA, 0, buffer_size));
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&dptr_peer), buffer_size));
HIP_CHECK(hipMemcpyPeer(reinterpret_cast<void*>(dptr_peer), deviceId,
reinterpret_cast<void*>(ptrA), 0, buffer_size));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), dptr_peer, buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
HIP_CHECK(hipFree(dptr_peer));
HIP_CHECK(hipFree(reinterpret_cast<void*>(dptr_peer)));
}
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
/**
@@ -790,6 +819,7 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2VMMMemCpy") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int deviceId = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -834,6 +864,7 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2VMMMemCpy") {
HIP_CHECK(hipMemUnmap(ptrB, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrB, size_mem));
CTX_DESTROY();
}
/**
@@ -853,6 +884,13 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2VMMInterDevMemCpy") {
size_t granularity = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
CTX_CREATE();
int devicecount = 0;
HIP_CHECK(hipGetDeviceCount(&devicecount));
if (devicecount < 2) {
HipTest::HIP_SKIP_TEST("Machine is Single GPU. Skipping Test..");
return;
}
int deviceId = 0, value = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -885,8 +923,6 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2VMMInterDevMemCpy") {
A_h[idx] = idx;
}
HIP_CHECK(hipMemcpyHtoD(ptrA, A_h.data(), buffer_size));
int devicecount = 0;
HIP_CHECK(hipGetDeviceCount(&devicecount));
for (deviceId = 1; deviceId < devicecount; deviceId++) {
int canAccessPeer = 0;
hipDevice_t device_other;
@@ -918,7 +954,7 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2VMMInterDevMemCpy") {
// Allocate virtual address range
hipDeviceptr_t ptrB;
HIP_CHECK(hipMemAddressReserve(&ptrB, size_mem_loc, 0, 0, 0));
HIP_CHECK(hipMemMap(ptrB, size_mem_loc, 0, handle, 0));
HIP_CHECK(hipMemMap(ptrB, size_mem_loc, 0, handle_loc, 0));
HIP_CHECK(hipMemRelease(handle_loc));
// Set access
hipMemAccessDesc accessDesc_loc = {};
@@ -927,7 +963,8 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2VMMInterDevMemCpy") {
accessDesc_loc.flags = hipMemAccessFlagsProtReadWrite;
// Make the address accessible to GPU 0
HIP_CHECK(hipMemSetAccess(ptrB, size_mem_loc, &accessDesc_loc, 1));
HIP_CHECK(hipMemcpyPeer(ptrB, deviceId, ptrA, 0, buffer_size));
HIP_CHECK(hipMemcpyPeer(reinterpret_cast<void*>(ptrB), deviceId, reinterpret_cast<void*>(ptrA),
0, buffer_size));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptrB, buffer_size));
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), A_h.data()));
HIP_CHECK(hipMemUnmap(ptrB, size_mem_loc));
@@ -935,6 +972,7 @@ TEST_CASE("Unit_hipMemSetAccess_Vmm2VMMInterDevMemCpy") {
}
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
CTX_DESTROY();
}
class vmm_resize_class {
@@ -1021,9 +1059,9 @@ class vmm_resize_class {
if (idx == 0) {
HIP_CHECK(hipMemMap(ptrVmm, vsize[idx], 0, myhandle, 0));
} else {
uint64_t uiptr = reinterpret_cast<uint64_t>(ptrVmm);
unsigned long long uiptr = reinterpret_cast<unsigned long long>(ptrVmm);
uiptr = uiptr + vsize[idx - 1];
HIP_CHECK(hipMemMap(reinterpret_cast<void*>(uiptr), vsize[idx], 0, myhandle, 0));
HIP_CHECK(hipMemMap(reinterpret_cast<hipDeviceptr_t>(uiptr), vsize[idx], 0, myhandle, 0));
}
idx++;
}
@@ -1063,6 +1101,7 @@ TEST_CASE("Unit_hipMemSetAccess_GrowVMM") {
size_t buffer_size = N * sizeof(int);
int deviceId = 0;
hipDevice_t device;
CTX_CREATE();
HIP_CHECK(hipDeviceGet(&device, deviceId));
checkVMMSupported(device);
// Create VMM Object of size buffer_size
@@ -1090,9 +1129,9 @@ TEST_CASE("Unit_hipMemSetAccess_GrowVMM") {
}
int* ptrB_h = static_cast<int*>(malloc(buffer_size_new));
REQUIRE(ptrB_h != nullptr);
uint64_t uiptr = reinterpret_cast<uint64_t>(ptr);
unsigned long long uiptr = reinterpret_cast<unsigned long long>(ptr);
uiptr = uiptr + buffer_size;
HIP_CHECK(hipMemcpyHtoD(reinterpret_cast<void*>(uiptr), ptrA_h, (buffer_size_new - buffer_size)));
HIP_CHECK(hipMemcpyHtoD(reinterpret_cast<hipDeviceptr_t>(uiptr), ptrA_h, (buffer_size_new - buffer_size)));
HIP_CHECK(hipMemcpyDtoH(ptrB_h, ptr, buffer_size_new));
bool bPassed = true;
for (int idx = 0; idx < Nnew; idx++) {
@@ -1105,6 +1144,7 @@ TEST_CASE("Unit_hipMemSetAccess_GrowVMM") {
free(ptrB_h);
free(ptrA_h);
resizeobj.free_vmm();
CTX_DESTROY();
}
std::atomic<int> bTestPassed{1};
@@ -1122,6 +1162,7 @@ void test_thread(hipDevice_t device) {
ptrA_h[idx] = idx;
}
// Copy to VMM
CTX_CREATE();
HIP_CHECK(hipMemcpyHtoD(ptr, ptrA_h, buffer_size));
int* ptrB_h = static_cast<int*>(malloc(buffer_size));
REQUIRE(ptrB_h != nullptr);
@@ -1141,6 +1182,7 @@ void test_thread(hipDevice_t device) {
free(ptrB_h);
free(ptrA_h);
vmmobj.free_vmm();
CTX_DESTROY();
}
/**
@@ -1156,6 +1198,7 @@ void test_thread(hipDevice_t device) {
* - HIP_VERSION >= 6.1
*/
TEST_CASE("Unit_hipMemSetAccess_Multithreaded") {
CTX_CREATE();
int deviceId = 0;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
@@ -1169,98 +1212,9 @@ TEST_CASE("Unit_hipMemSetAccess_Multithreaded") {
T[i].join();
}
REQUIRE(1 == bTestPassed.load());
CTX_DESTROY();
}
#ifdef __linux__
bool test_mprocess() {
int fd[2];
bool testResult = false;
pid_t childpid;
int testResultChild = 0;
int deviceId = 0;
constexpr int N = DATA_SIZE;
size_t buffer_size = N * sizeof(int);
// create pipe descriptors
pipe(fd);
// fork process
childpid = fork();
if (childpid > 0) { // Parent
close(fd[1]);
hipDeviceptr_t ptr;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
checkVMMSupportedRetVal(device);
// Create VMM Object of size buffer_size
vmm_resize_class vmmobj(&ptr, device, buffer_size);
// Inititalize Host Buffer
std::vector<int> A_h(N), B_h(N);
for (int idx = 0; idx < N; idx++) {
A_h[idx] = idx;
}
// Copy to VMM
HIP_CHECK(hipMemcpyHtoD(ptr, A_h.data(), buffer_size));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptr, buffer_size));
bool bPassed = std::equal(B_h.begin(), B_h.end(), A_h.data());
vmmobj.free_vmm();
// parent will wait to read the device cnt
read(fd[0], &testResultChild, sizeof(int));
if (testResultChild == 0) {
testResult = bPassed & false;
} else {
testResult = bPassed & true;
}
// close the read-descriptor
close(fd[0]);
// wait for child exit
wait(NULL);
} else if (!childpid) { // Child
close(fd[0]);
hipDeviceptr_t ptr;
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, deviceId));
checkVMMSupportedRetVal(device);
// Create VMM Object of size buffer_size
vmm_resize_class vmmobj(&ptr, device, buffer_size);
// Inititalize Host Buffer
std::vector<int> A_h(N), B_h(N);
for (int idx = 0; idx < N; idx++) {
A_h[idx] = idx;
}
// Copy to VMM
HIP_CHECK(hipMemcpyHtoD(ptr, A_h.data(), buffer_size));
HIP_CHECK(hipMemcpyDtoH(B_h.data(), ptr, buffer_size));
int result = 0;
if (true == std::equal(B_h.begin(), B_h.end(), A_h.data())) {
result = 1;
}
vmmobj.free_vmm();
// send the value on the write-descriptor:
write(fd[1], &result, sizeof(int));
// close the write descriptor:
close(fd[1]);
exit(0);
}
return testResult;
}
/**
* Test Description
* ------------------------
* - Multiprocess test: Allocate unique virtual memory chunks from
* multiple processes. Transfer data to these chunks from host and
* execute kernel function on these data. Validate the results.
* ------------------------
* - unit/virtualMemoryManagement/hipMemSetGetAccess.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.1
*/
TEST_CASE("Unit_hipMemSetAccess_MultiProc") { REQUIRE(true == test_mprocess()); }
#endif
/**
* Test Description
* ------------------------
@@ -1277,6 +1231,7 @@ TEST_CASE("Unit_hipMemSetAccess_negative") {
size_t buffer_size = N * sizeof(int);
int deviceId = 0;
hipDevice_t device;
CTX_CREATE();
HIP_CHECK(hipDeviceGet(&device, deviceId));
checkVMMSupported(device);
hipMemAllocationProp prop{};
@@ -1301,65 +1256,79 @@ TEST_CASE("Unit_hipMemSetAccess_negative") {
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
SECTION("nullptr to ptrA") {
REQUIRE(hipMemSetAccess(nullptr, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess((hipDeviceptr_t) nullptr, size_mem, &accessDesc, 1) ==
hipErrorInvalidValue);
}
SECTION("pass zero to size") {
REQUIRE(hipMemSetAccess(&ptrA, 0, &accessDesc, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrA, 0, &accessDesc, 1) == hipErrorInvalidValue);
}
SECTION("pass a size greater than reserved size") {
REQUIRE(hipMemSetAccess(&ptrA, size_mem + 1, &accessDesc, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrA, size_mem + 1, &accessDesc, 1) == hipErrorInvalidValue);
}
SECTION("pass a size less than reserved size") {
REQUIRE(hipMemSetAccess(&ptrA, size_mem - 1, &accessDesc, 1) == hipErrorInvalidValue);
#if HT_AMD
REQUIRE(hipMemSetAccess(ptrA, size_mem - 1, &accessDesc, 1) == hipSuccess);
#else
REQUIRE(hipMemSetAccess(ptrA, size_mem - 1, &accessDesc, 1) == hipErrorInvalidValue);
#endif
}
SECTION("invalid location type") {
accessDesc.location.type = hipMemLocationTypeInvalid;
REQUIRE(hipMemSetAccess(&ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
#if HT_AMD
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1) == hipSuccess);
#else
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
#endif
}
SECTION("invalid id") {
accessDesc.location.id = -1;
REQUIRE(hipMemSetAccess(&ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
}
SECTION("pass location id as > highest device number") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
accessDesc.location.id = numDevices; // set to non existing device
REQUIRE(hipMemSetAccess(&ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
}
SECTION("invalid flag") {
accessDesc.flags = static_cast<hipMemAccessFlags>(-1);
REQUIRE(hipMemSetAccess(&ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
#if HT_AMD
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1) == hipSuccess);
#else
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
#endif
}
SECTION(" pass zero to count") {
REQUIRE(hipMemSetAccess(&ptrA, size_mem, &accessDesc, 0) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 0) == hipErrorInvalidValue);
}
SECTION("pass desc as nullptr") {
REQUIRE(hipMemSetAccess(&ptrA, size_mem, nullptr, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrA, size_mem, nullptr, 1) == hipErrorInvalidValue);
}
SECTION("uninitialized virtual memory") {
hipDeviceptr_t ptrB;
HIP_CHECK(hipMemAddressReserve(&ptrB, size_mem, 0, 0, 0));
REQUIRE(hipMemSetAccess(&ptrB, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrB, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
HIP_CHECK(hipMemAddressFree(ptrB, size_mem));
}
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
SECTION("unmapped virtual memory") {
REQUIRE(hipMemSetAccess(&ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
REQUIRE(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1) == hipErrorInvalidValue);
}
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
HIP_CHECK(hipMemRelease(handle));
CTX_DESTROY();
}
/**