bc6f29c04a
* Fix and enable VMM tests on cuda * Minor syntax fixes --------- Co-authored-by: Rahul Manocha <rmanocha@amd.com>
604 строки
22 KiB
C++
604 строки
22 KiB
C++
/*
|
|
Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
*/
|
|
|
|
/**
|
|
* @addtogroup hipMemExportToShareableHandle hipMemExportToShareableHandle
|
|
* @{
|
|
* @ingroup VirtualMemoryManagementTest
|
|
* `hipError_t hipMemImportFromShareableHandle(hipMemGenericAllocationHandle_t *handle,
|
|
* void *osHandle,
|
|
* hipMemAllocationHandleType shHandleType)` -
|
|
* Imports an allocation from a requested shareable handle type.
|
|
*/
|
|
|
|
#include <hip_test_common.hh>
|
|
#include "hip_vmm_common.hh"
|
|
|
|
#define DATA_SIZE (1 << 13)
|
|
#define THREADS_PER_BLOCK 512
|
|
typedef int ShareableHandle;
|
|
|
|
/**
|
|
Kernel to perform Square of input data.
|
|
*/
|
|
static __global__ void square_kernel(int* Buff) {
|
|
int i = threadIdx.x + blockDim.x * blockIdx.x;
|
|
int temp = Buff[i] * Buff[i];
|
|
Buff[i] = temp;
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* - Basic sanity test.
|
|
* ------------------------
|
|
* - unit/virtualMemoryManagement/hipMemImportFromShareableHandle.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - Host specific (LINUX)
|
|
* - HIP_VERSION >= 6.1
|
|
*/
|
|
TEST_CASE("Unit_hipMemImportFromShareableHandle_Positive_Basic") {
|
|
CTX_CREATE();
|
|
|
|
hipDevice_t device;
|
|
HIP_CHECK(hipDeviceGet(&device, 0));
|
|
checkVMMSupported(device);
|
|
|
|
hipMemAllocationProp prop = {};
|
|
prop.type = hipMemAllocationTypePinned;
|
|
prop.requestedHandleTypes = hipMemHandleTypePosixFileDescriptor;
|
|
prop.location.type = hipMemLocationTypeDevice;
|
|
prop.location.id = device;
|
|
|
|
size_t granularity;
|
|
HIP_CHECK(
|
|
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
|
|
|
|
hipMemGenericAllocationHandle_t handle;
|
|
HIP_CHECK(hipMemCreate(&handle, granularity * 2, &prop, 0));
|
|
ShareableHandle shareable_handle;
|
|
HIP_CHECK(hipMemExportToShareableHandle(&shareable_handle, handle,
|
|
hipMemHandleTypePosixFileDescriptor, 0));
|
|
hipMemGenericAllocationHandle_t imported_handle;
|
|
HIP_CHECK(hipMemImportFromShareableHandle(&imported_handle,
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(shareable_handle)),
|
|
hipMemHandleTypePosixFileDescriptor));
|
|
HIP_CHECK(hipMemRelease(handle));
|
|
HIP_CHECK(hipMemRelease(imported_handle));
|
|
|
|
CTX_DESTROY();
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* - Negative parameters test.
|
|
* ------------------------
|
|
* - unit/virtualMemoryManagement/hipMemImportFromShareableHandle.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - Host specific (LINUX)
|
|
* - HIP_VERSION >= 6.1
|
|
*/
|
|
TEST_CASE("Unit_hipMemImportFromShareableHandle_Negative_Parameters") {
|
|
CTX_CREATE();
|
|
|
|
hipDevice_t device;
|
|
HIP_CHECK(hipDeviceGet(&device, 0));
|
|
checkVMMSupported(device);
|
|
|
|
hipMemAllocationProp prop = {};
|
|
prop.type = hipMemAllocationTypePinned;
|
|
prop.requestedHandleTypes = hipMemHandleTypePosixFileDescriptor;
|
|
prop.location.type = hipMemLocationTypeDevice;
|
|
prop.location.id = device;
|
|
|
|
size_t granularity;
|
|
HIP_CHECK(
|
|
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
|
|
|
|
hipMemGenericAllocationHandle_t handle;
|
|
HIP_CHECK(hipMemCreate(&handle, granularity * 2, &prop, 0));
|
|
|
|
void* shareable_handle = nullptr;
|
|
HIP_CHECK(hipMemExportToShareableHandle(&shareable_handle, handle,
|
|
hipMemHandleTypePosixFileDescriptor, 0));
|
|
|
|
hipMemGenericAllocationHandle_t imported_handle;
|
|
|
|
SECTION("handle == nullptr") {
|
|
HIP_CHECK_ERROR(hipMemImportFromShareableHandle(nullptr, shareable_handle,
|
|
hipMemHandleTypePosixFileDescriptor),
|
|
hipErrorInvalidValue);
|
|
}
|
|
|
|
SECTION("shareableHandle == nullptr") {
|
|
HIP_CHECK_ERROR(hipMemImportFromShareableHandle(&imported_handle, nullptr,
|
|
hipMemHandleTypePosixFileDescriptor),
|
|
hipErrorInvalidValue);
|
|
}
|
|
|
|
HIP_CHECK(hipMemRelease(handle));
|
|
CTX_DESTROY();
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* - Multiprocess functionality test. Create Vmm handle in Parent
|
|
* Process and export it to Child Process using Sockets. The Child
|
|
* Process imports this handle via sockets and uses this handle
|
|
* to perform VMM operations.
|
|
* ------------------------
|
|
* - unit/virtualMemoryManagement/hipMemImportFromShareableHandle.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - Host specific (LINUX)
|
|
* - HIP_VERSION >= 6.2
|
|
*/
|
|
TEST_CASE("Unit_hipMemImportFromShareableHandle_MulProc_ChldUseHdl") {
|
|
constexpr int N = DATA_SIZE;
|
|
size_t buffer_size = N * sizeof(int);
|
|
int fd[2], fdSig[2];
|
|
REQUIRE(pipe(fd) == 0);
|
|
REQUIRE(pipe(fdSig) == 0);
|
|
|
|
auto pid = fork();
|
|
REQUIRE(pid >= 0);
|
|
|
|
if (pid == 0) { // child
|
|
REQUIRE(close(fd[1]) == 0);
|
|
REQUIRE(close(fdSig[0]) == 0);
|
|
CTX_CREATE();
|
|
// Wait for parent process to create the socket.
|
|
size_t size_mem = 0;
|
|
REQUIRE(read(fd[0], &size_mem, sizeof(size_t)) >= 0);
|
|
// Open Socket as client
|
|
ipcSocketCom sockObj(false);
|
|
hipShareableHdl shHandle;
|
|
// Signal Parent process that Child is ready to receive msg
|
|
int sig = 0;
|
|
REQUIRE(write(fdSig[1], &sig, sizeof(int)) >= 0);
|
|
// receive message from parent provess
|
|
checkSysCallErrors(sockObj.recvShareableHdl(&shHandle));
|
|
hipMemGenericAllocationHandle_t imported_handle;
|
|
// import the sareable handle
|
|
HIP_CHECK(hipMemImportFromShareableHandle(&imported_handle,
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(shHandle)),
|
|
hipMemHandleTypePosixFileDescriptor));
|
|
// Allocate virtual address range
|
|
void* ptrA;
|
|
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
|
|
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, imported_handle, 0));
|
|
// Set access
|
|
hipMemAccessDesc accessDesc = {};
|
|
accessDesc.location.type = hipMemLocationTypeDevice;
|
|
accessDesc.location.id = 0;
|
|
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
|
|
// Make the address accessible to GPU 0
|
|
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
|
|
std::vector<int> A_h(N), B_h(N), C_h(N);
|
|
// Initialize with data
|
|
for (size_t 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));
|
|
// Invoke kernel
|
|
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());
|
|
// validate
|
|
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), C_h.data()));
|
|
|
|
// free resources
|
|
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
|
|
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
|
|
CTX_DESTROY();
|
|
checkSysCallErrors(sockObj.closeThisSock());
|
|
REQUIRE(close(fd[0]) == 0);
|
|
REQUIRE(close(fdSig[1]) == 0);
|
|
exit(0);
|
|
} else { // parent
|
|
REQUIRE(close(fd[0]) == 0);
|
|
REQUIRE(close(fdSig[1]) == 0);
|
|
CTX_CREATE();
|
|
|
|
hipDevice_t device;
|
|
HIP_CHECK(hipDeviceGet(&device, 0));
|
|
checkVMMSupported(device);
|
|
// Set property
|
|
hipMemAllocationProp prop = {};
|
|
prop.type = hipMemAllocationTypePinned;
|
|
prop.requestedHandleTypes = hipMemHandleTypePosixFileDescriptor;
|
|
prop.location.type = hipMemLocationTypeDevice;
|
|
prop.location.id = device;
|
|
// Set Granularity of the VMM memory
|
|
size_t granularity;
|
|
HIP_CHECK(
|
|
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
|
|
REQUIRE(granularity > 0);
|
|
size_t size_mem = ((granularity + buffer_size - 1) / granularity) * granularity;
|
|
hipMemGenericAllocationHandle_t handle;
|
|
HIP_CHECK(hipMemCreate(&handle, size_mem, &prop, 0));
|
|
|
|
hipShareableHdl shareable_handle;
|
|
HIP_CHECK(hipMemExportToShareableHandle(&shareable_handle, handle,
|
|
hipMemHandleTypePosixFileDescriptor, 0));
|
|
// Create the socket for communication as Server
|
|
ipcSocketCom sockObj(true);
|
|
// Signal child process that socket is ready
|
|
REQUIRE(write(fd[1], &size_mem, sizeof(size_t)) >= 0);
|
|
// Wait for the child process to receive msg
|
|
int sig = 0;
|
|
REQUIRE(read(fdSig[0], &sig, sizeof(int)) >= 0);
|
|
checkSysCallErrors(sockObj.sendShareableHdl(shareable_handle, pid));
|
|
// Wait for child process to exit.
|
|
int status;
|
|
REQUIRE(wait(&status) >= 0);
|
|
REQUIRE(status == 0);
|
|
// Free all resources
|
|
checkSysCallErrors(sockObj.closeThisSock());
|
|
HIP_CHECK(hipMemRelease(handle));
|
|
CTX_DESTROY();
|
|
REQUIRE(close(fd[1]) == 0);
|
|
REQUIRE(close(fdSig[0]) == 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* - Multiprocess functionality test. Create Vmm handle in Parent
|
|
* Process and export it to Child Process using Sockets. The Child
|
|
* Process imports this handle via sockets. Both Parent and Child Process
|
|
* uses this handle to perform VMM operations.
|
|
* ------------------------
|
|
* - unit/virtualMemoryManagement/hipMemImportFromShareableHandle.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - Host specific (LINUX)
|
|
* - HIP_VERSION >= 6.2
|
|
*/
|
|
TEST_CASE("Unit_hipMemImportFromShareableHandle_MulProc_ParntChldUseHdl") {
|
|
constexpr int N = DATA_SIZE;
|
|
size_t buffer_size = N * sizeof(int);
|
|
int fd[2], fdSig[2];
|
|
REQUIRE(pipe(fd) == 0);
|
|
REQUIRE(pipe(fdSig) == 0);
|
|
|
|
// Create data buffer
|
|
std::vector<int> A_h(N), B_h(N), C_h(N);
|
|
// Initialize with data
|
|
for (size_t idx = 0; idx < N; idx++) {
|
|
A_h[idx] = idx;
|
|
C_h[idx] = idx * idx;
|
|
}
|
|
|
|
auto pid = fork();
|
|
REQUIRE(pid >= 0);
|
|
|
|
if (pid == 0) { // child
|
|
REQUIRE(close(fd[1]) == 0);
|
|
REQUIRE(close(fdSig[0]) == 0);
|
|
CTX_CREATE();
|
|
// Wait for parent process to create the socket.
|
|
size_t size_mem = 0;
|
|
REQUIRE(read(fd[0], &size_mem, sizeof(size_t)) >= 0);
|
|
|
|
// Open Socket as client
|
|
ipcSocketCom sockObj(false);
|
|
hipShareableHdl shHandle;
|
|
|
|
// Signal Parent process that Child is ready to receive msg
|
|
int sig = 0;
|
|
REQUIRE(write(fdSig[1], &sig, sizeof(int)) >= 0);
|
|
|
|
// receive message from parent provess
|
|
checkSysCallErrors(sockObj.recvShareableHdl(&shHandle));
|
|
hipMemGenericAllocationHandle_t imported_handle;
|
|
|
|
// import the sareable handle
|
|
HIP_CHECK(hipMemImportFromShareableHandle(&imported_handle,
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(shHandle)),
|
|
hipMemHandleTypePosixFileDescriptor));
|
|
// Allocate virtual address range
|
|
void* ptrA;
|
|
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
|
|
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, imported_handle, 0));
|
|
// Set access
|
|
hipMemAccessDesc accessDesc = {};
|
|
accessDesc.location.type = hipMemLocationTypeDevice;
|
|
accessDesc.location.id = 0;
|
|
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
|
|
// Make the address accessible to GPU 0
|
|
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
|
|
HIP_CHECK(hipMemcpyHtoD(reinterpret_cast<hipDeviceptr_t>(ptrA), A_h.data(), buffer_size));
|
|
// Invoke kernel
|
|
hipLaunchKernelGGL(square_kernel, dim3(N / THREADS_PER_BLOCK), dim3(THREADS_PER_BLOCK), 0, 0,
|
|
reinterpret_cast<int*>(ptrA));
|
|
HIP_CHECK(hipDeviceSynchronize());
|
|
|
|
// free resources
|
|
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
|
|
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
|
|
checkSysCallErrors(sockObj.closeThisSock());
|
|
REQUIRE(close(fd[0]) == 0);
|
|
REQUIRE(close(fdSig[1]) == 0);
|
|
CTX_DESTROY();
|
|
exit(0);
|
|
} else { // parent
|
|
REQUIRE(close(fd[0]) == 0);
|
|
REQUIRE(close(fdSig[1]) == 0);
|
|
CTX_CREATE();
|
|
hipDevice_t device;
|
|
HIP_CHECK(hipDeviceGet(&device, 0));
|
|
checkVMMSupported(device);
|
|
// Set property
|
|
hipMemAllocationProp prop = {};
|
|
prop.type = hipMemAllocationTypePinned;
|
|
prop.requestedHandleTypes = hipMemHandleTypePosixFileDescriptor;
|
|
prop.location.type = hipMemLocationTypeDevice;
|
|
prop.location.id = device;
|
|
// Set Granularity of the VMM memory
|
|
size_t granularity;
|
|
HIP_CHECK(
|
|
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
|
|
REQUIRE(granularity > 0);
|
|
size_t size_mem = ((granularity + buffer_size - 1) / granularity) * granularity;
|
|
hipMemGenericAllocationHandle_t handle;
|
|
HIP_CHECK(hipMemCreate(&handle, size_mem, &prop, 0));
|
|
|
|
hipShareableHdl shareable_handle;
|
|
HIP_CHECK(hipMemExportToShareableHandle(&shareable_handle, handle,
|
|
hipMemHandleTypePosixFileDescriptor, 0));
|
|
|
|
// Allocate virtual address range
|
|
void* ptrA;
|
|
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
|
|
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, handle, 0));
|
|
// Set access
|
|
hipMemAccessDesc accessDesc = {};
|
|
accessDesc.location.type = hipMemLocationTypeDevice;
|
|
accessDesc.location.id = device;
|
|
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
|
|
// Make the address accessible to GPU 0
|
|
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
|
|
|
|
// Create the socket for communication as Server
|
|
ipcSocketCom sockObj(true);
|
|
// Signal child process that socket is ready
|
|
REQUIRE(write(fd[1], &size_mem, sizeof(size_t)) >= 0);
|
|
// Wait for the child process to receive msg
|
|
int sig = 0;
|
|
REQUIRE(read(fdSig[0], &sig, sizeof(int)) >= 0);
|
|
checkSysCallErrors(sockObj.sendShareableHdl(shareable_handle, pid));
|
|
// Wait for child process to exit.
|
|
int status;
|
|
REQUIRE(wait(&status) >= 0);
|
|
REQUIRE(status == 0);
|
|
|
|
// Check results of Vmm data processing in child
|
|
HIP_CHECK(hipMemcpyDtoH(B_h.data(), reinterpret_cast<hipDeviceptr_t>(ptrA), buffer_size));
|
|
// validate
|
|
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), C_h.data()));
|
|
|
|
// Free all resources
|
|
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
|
|
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
|
|
HIP_CHECK(hipMemRelease(handle));
|
|
checkSysCallErrors(sockObj.closeThisSock());
|
|
CTX_DESTROY();
|
|
REQUIRE(close(fd[1]) == 0);
|
|
REQUIRE(close(fdSig[0]) == 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* - Multiprocess functionality test. Create Vmm handle in Parent
|
|
* Process and export it to Grand Child Process using Sockets. The Grand
|
|
* Child Process imports this handle via sockets. The Grand Child Process
|
|
* uses this handle to perform VMM operations.
|
|
* ------------------------
|
|
* - unit/virtualMemoryManagement/hipMemImportFromShareableHandle.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - Host specific (LINUX)
|
|
* - HIP_VERSION >= 6.2
|
|
*/
|
|
TEST_CASE("Unit_hipMemImportFromShareableHandle_MulProc_GrndChldUseHdl") {
|
|
constexpr int N = DATA_SIZE;
|
|
size_t buffer_size = N * sizeof(int);
|
|
int fd[2], fdSig[2], fdpid[2];
|
|
REQUIRE(pipe(fd) == 0);
|
|
REQUIRE(pipe(fdSig) == 0);
|
|
REQUIRE(pipe(fdpid) == 0);
|
|
auto pid = fork();
|
|
REQUIRE(pid >= 0);
|
|
|
|
if (pid == 0) { // child
|
|
auto pid2 = fork();
|
|
if (pid2 == 0) { // grandchild
|
|
REQUIRE(close(fd[1]) == 0);
|
|
REQUIRE(close(fdSig[0]) == 0);
|
|
// Wait for parent process to create the socket.
|
|
size_t size_mem = 0;
|
|
REQUIRE(read(fd[0], &size_mem, sizeof(size_t)) >= 0);
|
|
CTX_CREATE();
|
|
|
|
// Open Socket as client
|
|
ipcSocketCom sockObj(false);
|
|
hipShareableHdl shHandle;
|
|
|
|
// Signal Parent process that Child is ready to receive msg
|
|
int sig = 0;
|
|
REQUIRE(write(fdSig[1], &sig, sizeof(int)) >= 0);
|
|
|
|
// receive message from parent provess
|
|
checkSysCallErrors(sockObj.recvShareableHdl(&shHandle));
|
|
hipMemGenericAllocationHandle_t imported_handle;
|
|
|
|
// import the sareable handle
|
|
HIP_CHECK(hipMemImportFromShareableHandle(&imported_handle,
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(shHandle)),
|
|
hipMemHandleTypePosixFileDescriptor));
|
|
// Allocate virtual address range
|
|
void* ptrA;
|
|
HIP_CHECK(hipMemAddressReserve(&ptrA, size_mem, 0, 0, 0));
|
|
HIP_CHECK(hipMemMap(ptrA, size_mem, 0, imported_handle, 0));
|
|
// Set access
|
|
hipMemAccessDesc accessDesc = {};
|
|
accessDesc.location.type = hipMemLocationTypeDevice;
|
|
accessDesc.location.id = 0;
|
|
accessDesc.flags = hipMemAccessFlagsProtReadWrite;
|
|
// Make the address accessible to GPU 0
|
|
HIP_CHECK(hipMemSetAccess(ptrA, size_mem, &accessDesc, 1));
|
|
std::vector<int> A_h(N), B_h(N), C_h(N);
|
|
// Initialize with data
|
|
for (size_t 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));
|
|
// Invoke kernel
|
|
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());
|
|
// validate
|
|
REQUIRE(true == std::equal(B_h.begin(), B_h.end(), C_h.data()));
|
|
|
|
// free resources
|
|
HIP_CHECK(hipMemUnmap(ptrA, size_mem));
|
|
HIP_CHECK(hipMemAddressFree(ptrA, size_mem));
|
|
CTX_DESTROY();
|
|
checkSysCallErrors(sockObj.closeThisSock());
|
|
REQUIRE(close(fd[0]) == 0);
|
|
REQUIRE(close(fdSig[1]) == 0);
|
|
exit(0);
|
|
} else {
|
|
int status;
|
|
REQUIRE(close(fdpid[0]) == 0);
|
|
REQUIRE(write(fdpid[1], &pid2, sizeof(pid2)) >= 0);
|
|
REQUIRE(wait(&status) >= 0);
|
|
REQUIRE(status == 0);
|
|
REQUIRE(close(fdpid[1]) == 0);
|
|
exit(0);
|
|
}
|
|
} else { // parent
|
|
REQUIRE(close(fd[0]) == 0);
|
|
REQUIRE(close(fdSig[1]) == 0);
|
|
REQUIRE(close(fdpid[1]) == 0);
|
|
int pid_grChld = 0;
|
|
REQUIRE(read(fdpid[0], &pid_grChld, sizeof(pid_grChld)) >= 0);
|
|
CTX_CREATE();
|
|
hipDevice_t device;
|
|
HIP_CHECK(hipDeviceGet(&device, 0));
|
|
checkVMMSupported(device);
|
|
// Set property
|
|
hipMemAllocationProp prop = {};
|
|
prop.type = hipMemAllocationTypePinned;
|
|
prop.requestedHandleTypes = hipMemHandleTypePosixFileDescriptor;
|
|
prop.location.type = hipMemLocationTypeDevice;
|
|
prop.location.id = device;
|
|
// Set Granularity of the VMM memory
|
|
size_t granularity;
|
|
HIP_CHECK(
|
|
hipMemGetAllocationGranularity(&granularity, &prop, hipMemAllocationGranularityMinimum));
|
|
REQUIRE(granularity > 0);
|
|
size_t size_mem = ((granularity + buffer_size - 1) / granularity) * granularity;
|
|
hipMemGenericAllocationHandle_t handle;
|
|
HIP_CHECK(hipMemCreate(&handle, size_mem, &prop, 0));
|
|
|
|
hipShareableHdl shareable_handle;
|
|
HIP_CHECK(hipMemExportToShareableHandle(&shareable_handle, handle,
|
|
hipMemHandleTypePosixFileDescriptor, 0));
|
|
|
|
// Create the socket for communication as Server
|
|
ipcSocketCom sockObj(true);
|
|
// Signal child process that socket is ready
|
|
REQUIRE(write(fd[1], &size_mem, sizeof(size_t)) >= 0);
|
|
// Wait for the child process to receive msg
|
|
int sig = 0;
|
|
REQUIRE(read(fdSig[0], &sig, sizeof(int)) >= 0);
|
|
checkSysCallErrors(sockObj.sendShareableHdl(shareable_handle, pid_grChld));
|
|
// Wait for child process to exit.
|
|
int status;
|
|
REQUIRE(wait(&status) >= 0);
|
|
REQUIRE(status == 0);
|
|
|
|
// Free all resources
|
|
HIP_CHECK(hipMemRelease(handle));
|
|
CTX_DESTROY();
|
|
checkSysCallErrors(sockObj.closeThisSock());
|
|
REQUIRE(close(fd[1]) == 0);
|
|
REQUIRE(close(fdSig[0]) == 0);
|
|
REQUIRE(close(fdpid[0]) == 0);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Unit_hipMemImportFromShareableHandle_Capture") {
|
|
CTX_CREATE();
|
|
|
|
hipDevice_t device;
|
|
HIP_CHECK(hipDeviceGet(&device, 0));
|
|
checkVMMSupported(device);
|
|
|
|
hipMemAllocationProp allocation_prop = {};
|
|
allocation_prop.type = hipMemAllocationTypePinned;
|
|
allocation_prop.requestedHandleTypes = hipMemHandleTypePosixFileDescriptor;
|
|
allocation_prop.location.type = hipMemLocationTypeDevice;
|
|
allocation_prop.location.id = device;
|
|
|
|
size_t granularity = 0;
|
|
HIP_CHECK(hipMemGetAllocationGranularity(&granularity, &allocation_prop,
|
|
hipMemAllocationGranularityMinimum));
|
|
|
|
hipMemGenericAllocationHandle_t allocation_handle;
|
|
HIP_CHECK(hipMemCreate(&allocation_handle, granularity * 2, &allocation_prop, 0));
|
|
ShareableHandle shareable_handle;
|
|
HIP_CHECK(hipMemExportToShareableHandle(&shareable_handle, allocation_handle,
|
|
hipMemHandleTypePosixFileDescriptor, 0));
|
|
hipMemGenericAllocationHandle_t imported_handle;
|
|
hipStream_t stream = nullptr;
|
|
HIP_CHECK(hipStreamCreate(&stream));
|
|
|
|
GENERATE_CAPTURE();
|
|
BEGIN_CAPTURE(stream);
|
|
HIP_CHECK(hipMemImportFromShareableHandle(&imported_handle,
|
|
reinterpret_cast<void*>(static_cast<uintptr_t>(shareable_handle)),
|
|
hipMemHandleTypePosixFileDescriptor));
|
|
END_CAPTURE(stream);
|
|
|
|
HIP_CHECK(hipStreamDestroy(stream));
|
|
HIP_CHECK(hipMemRelease(allocation_handle));
|
|
CTX_DESTROY();
|
|
}
|
|
/**
|
|
* End doxygen group VirtualMemoryManagementTest.
|
|
* @}
|
|
*/
|