feature: Add host IPC blackbox tests
Related-To: LOCI-3771 Signed-off-by: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
This commit is contained in:
parent
235385abc9
commit
c728b727fc
|
@ -70,6 +70,9 @@ include_directories(common)
|
|||
|
||||
foreach(TEST_NAME ${TEST_TARGETS})
|
||||
if(MSVC)
|
||||
if(${TEST_NAME} STREQUAL "zello_host_ipc_copy_dma_buf")
|
||||
continue()
|
||||
endif()
|
||||
if(${TEST_NAME} STREQUAL "zello_ipc_copy_dma_buf")
|
||||
continue()
|
||||
endif()
|
||||
|
@ -79,6 +82,9 @@ foreach(TEST_NAME ${TEST_TARGETS})
|
|||
if(${TEST_NAME} STREQUAL "zello_export_import_memory")
|
||||
continue()
|
||||
endif()
|
||||
if(${TEST_NAME} STREQUAL "zello_host_export_import_memory")
|
||||
continue()
|
||||
endif()
|
||||
if(${TEST_NAME} STREQUAL "zello_ipc_event")
|
||||
continue()
|
||||
endif()
|
||||
|
|
|
@ -135,7 +135,7 @@ void runClient(int commSocket, uint32_t clientId) {
|
|||
SUCCESS_OR_TERMINATE(zeCommandQueueExecuteCommandLists(cmdQueue, 1, &cmdList, nullptr));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueSynchronize(cmdQueue, std::numeric_limits<uint64_t>::max()));
|
||||
|
||||
// SUCCESS_OR_TERMINATE(zeMemFree(context, zeIpcBuffer));
|
||||
SUCCESS_OR_TERMINATE(zeMemFree(context, zeIpcBuffer));
|
||||
SUCCESS_OR_TERMINATE(zeCommandListDestroy(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueDestroy(cmdQueue));
|
||||
SUCCESS_OR_TERMINATE(zeContextDestroy(context));
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "zello_common.h"
|
||||
#include "zello_ipc_common.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CHILDPROCESSES 4
|
||||
|
||||
int sv[CHILDPROCESSES][2];
|
||||
|
||||
size_t allocSize = 4194304;
|
||||
|
||||
inline void initializeProcess(ze_driver_handle_t &driverHandle,
|
||||
ze_context_handle_t &context,
|
||||
ze_device_handle_t &device,
|
||||
ze_command_queue_handle_t &cmdQueue,
|
||||
ze_command_list_handle_t &cmdList) {
|
||||
SUCCESS_OR_TERMINATE(zeInit(ZE_INIT_FLAG_GPU_ONLY));
|
||||
|
||||
// Retrieve driver
|
||||
uint32_t driverCount = 0;
|
||||
SUCCESS_OR_TERMINATE(zeDriverGet(&driverCount, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeDriverGet(&driverCount, &driverHandle));
|
||||
|
||||
ze_context_desc_t contextDesc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC};
|
||||
SUCCESS_OR_TERMINATE(zeContextCreate(driverHandle, &contextDesc, &context));
|
||||
|
||||
// Retrieve device
|
||||
uint32_t deviceCount = 0;
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGet(driverHandle, &deviceCount, nullptr));
|
||||
|
||||
deviceCount = 1;
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGet(driverHandle, &deviceCount, &device));
|
||||
|
||||
// Print some properties
|
||||
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGetProperties(device, &deviceProperties));
|
||||
|
||||
std::cout << "Device : \n"
|
||||
<< " * name : " << deviceProperties.name << "\n"
|
||||
<< " * vendorId : " << std::hex << deviceProperties.vendorId << "\n";
|
||||
|
||||
// Create command queue
|
||||
uint32_t numQueueGroups = 0;
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGetCommandQueueGroupProperties(device, &numQueueGroups, nullptr));
|
||||
if (numQueueGroups == 0) {
|
||||
std::cerr << "No queue groups found!\n";
|
||||
std::terminate();
|
||||
}
|
||||
std::vector<ze_command_queue_group_properties_t> queueProperties(numQueueGroups);
|
||||
for (auto &queueProperty : queueProperties) {
|
||||
queueProperty.stype = ZE_STRUCTURE_TYPE_COMMAND_QUEUE_GROUP_PROPERTIES;
|
||||
}
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGetCommandQueueGroupProperties(device, &numQueueGroups,
|
||||
queueProperties.data()));
|
||||
|
||||
ze_command_queue_desc_t cmdQueueDesc = {ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC};
|
||||
for (uint32_t i = 0; i < numQueueGroups; i++) {
|
||||
if (queueProperties[i].flags & ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COMPUTE) {
|
||||
cmdQueueDesc.ordinal = i;
|
||||
}
|
||||
}
|
||||
cmdQueueDesc.index = 0;
|
||||
cmdQueueDesc.mode = ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS;
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueCreate(context, device, &cmdQueueDesc, &cmdQueue));
|
||||
|
||||
// Create command list
|
||||
ze_command_list_desc_t cmdListDesc = {ZE_STRUCTURE_TYPE_COMMAND_LIST_DESC};
|
||||
cmdListDesc.commandQueueGroupOrdinal = cmdQueueDesc.ordinal;
|
||||
SUCCESS_OR_TERMINATE(zeCommandListCreate(context, device, &cmdListDesc, &cmdList));
|
||||
}
|
||||
|
||||
void runClient(int commSocket, uint32_t clientId) {
|
||||
std::cout << "Client " << clientId << ", process ID: " << std::dec << getpid() << "\n";
|
||||
|
||||
ze_driver_handle_t driverHandle;
|
||||
ze_context_handle_t context;
|
||||
ze_device_handle_t device;
|
||||
ze_command_queue_handle_t cmdQueue;
|
||||
ze_command_list_handle_t cmdList;
|
||||
initializeProcess(driverHandle, context, device, cmdQueue, cmdList);
|
||||
|
||||
char *heapBuffer = new char[allocSize];
|
||||
for (size_t i = 0; i < allocSize; ++i) {
|
||||
heapBuffer[i] = static_cast<char>(i + 1);
|
||||
}
|
||||
|
||||
// receive the IPC handle for the memory from the other process
|
||||
char payload[ZE_MAX_IPC_HANDLE_SIZE];
|
||||
int handle = recvmsgForIpcHandle(commSocket, payload);
|
||||
if (handle < 0) {
|
||||
std::cerr << "Failing to get IPC memory handle from server\n";
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
// get a memory pointer to the BO associated with the dma_buf handle
|
||||
ze_external_memory_import_fd_t importDesc = {};
|
||||
importDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD;
|
||||
importDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
|
||||
importDesc.fd = handle;
|
||||
|
||||
ze_host_mem_alloc_desc_t hostDesc = {};
|
||||
hostDesc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC;
|
||||
hostDesc.pNext = &importDesc;
|
||||
|
||||
void *zeIpcBuffer;
|
||||
SUCCESS_OR_TERMINATE(zeMemAllocHost(context, &hostDesc, 0, 0, &zeIpcBuffer));
|
||||
|
||||
// get the size of the imported allocation
|
||||
void *ipcPtr = nullptr;
|
||||
size_t ipcSize = 0;
|
||||
SUCCESS_OR_TERMINATE(zeMemGetAddressRange(context, zeIpcBuffer, &ipcPtr, &ipcSize));
|
||||
|
||||
// allocation may be bigger than the size requested originally by the exporter in case
|
||||
// driver has made some alignment adjustments. In this case, allocSize = 4MB, so size
|
||||
// should be the same.
|
||||
if (ipcSize != allocSize) {
|
||||
std::cerr << "Incorrect size returned for imported allocation\n";
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
// Copy from heap to IPC buffer memory
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendMemoryCopy(cmdList, zeIpcBuffer, heapBuffer, ipcSize,
|
||||
nullptr, 0, nullptr));
|
||||
SUCCESS_OR_TERMINATE(zeCommandListClose(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueExecuteCommandLists(cmdQueue, 1, &cmdList, nullptr));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueSynchronize(cmdQueue, std::numeric_limits<uint64_t>::max()));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeMemFree(context, zeIpcBuffer));
|
||||
SUCCESS_OR_TERMINATE(zeCommandListDestroy(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueDestroy(cmdQueue));
|
||||
SUCCESS_OR_TERMINATE(zeContextDestroy(context));
|
||||
|
||||
delete[] heapBuffer;
|
||||
}
|
||||
|
||||
void runServer(bool &validRet) {
|
||||
std::cout << "Server process ID " << std::dec << getpid() << "\n";
|
||||
|
||||
ze_driver_handle_t driverHandle;
|
||||
ze_context_handle_t context;
|
||||
ze_device_handle_t device;
|
||||
ze_command_queue_handle_t cmdQueue;
|
||||
ze_command_list_handle_t cmdList;
|
||||
initializeProcess(driverHandle, context, device, cmdQueue, cmdList);
|
||||
|
||||
void *zeBuffer = nullptr;
|
||||
ze_host_mem_alloc_desc_t hostDesc = {ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC};
|
||||
SUCCESS_OR_TERMINATE(zeMemAllocHost(context, &hostDesc, allocSize, allocSize, &zeBuffer));
|
||||
|
||||
for (uint32_t i = 0; i < CHILDPROCESSES; i++) {
|
||||
// Initialize the IPC buffer
|
||||
int value = 3;
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendMemoryFill(cmdList, zeBuffer, reinterpret_cast<void *>(&value),
|
||||
sizeof(value), allocSize, nullptr, 0, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListClose(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueExecuteCommandLists(cmdQueue, 1, &cmdList, nullptr));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueSynchronize(cmdQueue, std::numeric_limits<uint64_t>::max()));
|
||||
SUCCESS_OR_TERMINATE(zeCommandListReset(cmdList));
|
||||
|
||||
// get the fd handle
|
||||
ze_external_memory_export_fd_t exportFd = {};
|
||||
exportFd.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD;
|
||||
exportFd.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
|
||||
|
||||
ze_memory_allocation_properties_t allocProperties = {};
|
||||
allocProperties.stype = ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES;
|
||||
allocProperties.pNext = &exportFd;
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeMemGetAllocProperties(context, zeBuffer, &allocProperties, nullptr));
|
||||
|
||||
// transmit handle to the client
|
||||
int commSocket = sv[i][0];
|
||||
char payload[ZE_MAX_IPC_HANDLE_SIZE];
|
||||
if (sendmsgForIpcHandle(commSocket, static_cast<int>(exportFd.fd), payload) < 0) {
|
||||
std::cerr << "Failing to send IPC event pool handle to client\n";
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
char *heapBuffer = new char[allocSize];
|
||||
for (size_t i = 0; i < allocSize; ++i) {
|
||||
heapBuffer[i] = static_cast<char>(i + 1);
|
||||
}
|
||||
|
||||
// Wait for child to exit
|
||||
int childStatus;
|
||||
pid_t clientPId = wait(&childStatus);
|
||||
if (clientPId <= 0) {
|
||||
std::cerr << "Client terminated abruptly with error code " << strerror(errno) << "\n";
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
void *validateBuffer = nullptr;
|
||||
ze_device_mem_alloc_desc_t deviceDesc = {ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC};
|
||||
SUCCESS_OR_TERMINATE(zeMemAllocShared(context, &deviceDesc, &hostDesc,
|
||||
allocSize, 1, device, &validateBuffer));
|
||||
|
||||
value = 5;
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendMemoryFill(cmdList, validateBuffer, reinterpret_cast<void *>(&value),
|
||||
sizeof(value), allocSize, nullptr, 0, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendBarrier(cmdList, nullptr, 0, nullptr));
|
||||
|
||||
// Copy from device-allocated memory
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendMemoryCopy(cmdList, validateBuffer, zeBuffer, allocSize,
|
||||
nullptr, 0, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListClose(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueExecuteCommandLists(cmdQueue, 1, &cmdList, nullptr));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueSynchronize(cmdQueue, std::numeric_limits<uint64_t>::max()));
|
||||
|
||||
char *ipcBuffer = static_cast<char *>(validateBuffer);
|
||||
for (uint32_t h = 0; h < allocSize; h++) {
|
||||
if (static_cast<uint32_t>(ipcBuffer[h]) != static_cast<uint32_t>(heapBuffer[h])) {
|
||||
printf("Error: ipcBuffer %d %d, heapBuffer %d\n", h, static_cast<uint32_t>(ipcBuffer[h]), heapBuffer[h]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate stack and buffers have the original data from heapBuffer
|
||||
validRet = (0 == memcmp(heapBuffer, validateBuffer, allocSize));
|
||||
delete[] heapBuffer;
|
||||
}
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeMemFree(context, zeBuffer));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListDestroy(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueDestroy(cmdQueue));
|
||||
SUCCESS_OR_TERMINATE(zeContextDestroy(context));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const std::string blackBoxName = "Zello Export Import";
|
||||
verbose = isVerbose(argc, argv);
|
||||
bool outputValidationSuccessful;
|
||||
|
||||
for (uint32_t i = 0; i < CHILDPROCESSES; i++) {
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv[i]) < 0) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pid_t childPids[CHILDPROCESSES];
|
||||
for (uint32_t i = 0; i < CHILDPROCESSES; i++) {
|
||||
childPids[i] = fork();
|
||||
if (childPids[i] < 0) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
} else if (childPids[i] == 0) {
|
||||
close(sv[i][0]);
|
||||
runClient(sv[i][1], i);
|
||||
close(sv[i][1]);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
runServer(outputValidationSuccessful);
|
||||
|
||||
printResult(false, outputValidationSuccessful, blackBoxName);
|
||||
return outputValidationSuccessful ? 0 : 1;
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "zello_common.h"
|
||||
#include "zello_ipc_common.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CHILDPROCESSES 4
|
||||
|
||||
int sv[CHILDPROCESSES][2];
|
||||
|
||||
size_t allocSize = 131072 + 7; // +7 to break alignment and make it harder
|
||||
|
||||
inline void initializeProcess(ze_driver_handle_t &driverHandle,
|
||||
ze_context_handle_t &context,
|
||||
ze_device_handle_t &device,
|
||||
ze_command_queue_handle_t &cmdQueue,
|
||||
ze_command_list_handle_t &cmdList) {
|
||||
SUCCESS_OR_TERMINATE(zeInit(ZE_INIT_FLAG_GPU_ONLY));
|
||||
|
||||
// Retrieve driver
|
||||
uint32_t driverCount = 0;
|
||||
SUCCESS_OR_TERMINATE(zeDriverGet(&driverCount, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeDriverGet(&driverCount, &driverHandle));
|
||||
|
||||
ze_context_desc_t contextDesc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC};
|
||||
SUCCESS_OR_TERMINATE(zeContextCreate(driverHandle, &contextDesc, &context));
|
||||
|
||||
// Retrieve device
|
||||
uint32_t deviceCount = 0;
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGet(driverHandle, &deviceCount, nullptr));
|
||||
|
||||
deviceCount = 1;
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGet(driverHandle, &deviceCount, &device));
|
||||
|
||||
// Print some properties
|
||||
ze_device_properties_t deviceProperties = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGetProperties(device, &deviceProperties));
|
||||
|
||||
std::cout << "Device : \n"
|
||||
<< " * name : " << deviceProperties.name << "\n"
|
||||
<< " * vendorId : " << std::hex << deviceProperties.vendorId << "\n";
|
||||
|
||||
// Create command queue
|
||||
uint32_t numQueueGroups = 0;
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGetCommandQueueGroupProperties(device, &numQueueGroups, nullptr));
|
||||
if (numQueueGroups == 0) {
|
||||
std::cerr << "No queue groups found!\n";
|
||||
std::terminate();
|
||||
}
|
||||
std::vector<ze_command_queue_group_properties_t> queueProperties(numQueueGroups);
|
||||
for (auto &queueProperty : queueProperties) {
|
||||
queueProperty.stype = ZE_STRUCTURE_TYPE_COMMAND_QUEUE_GROUP_PROPERTIES;
|
||||
}
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGetCommandQueueGroupProperties(device, &numQueueGroups,
|
||||
queueProperties.data()));
|
||||
|
||||
ze_command_queue_desc_t cmdQueueDesc = {ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC};
|
||||
for (uint32_t i = 0; i < numQueueGroups; i++) {
|
||||
if (queueProperties[i].flags & ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COMPUTE) {
|
||||
cmdQueueDesc.ordinal = i;
|
||||
}
|
||||
}
|
||||
cmdQueueDesc.index = 0;
|
||||
cmdQueueDesc.mode = ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS;
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueCreate(context, device, &cmdQueueDesc, &cmdQueue));
|
||||
|
||||
// Create command list
|
||||
ze_command_list_desc_t cmdListDesc = {ZE_STRUCTURE_TYPE_COMMAND_LIST_DESC};
|
||||
cmdListDesc.commandQueueGroupOrdinal = cmdQueueDesc.ordinal;
|
||||
SUCCESS_OR_TERMINATE(zeCommandListCreate(context, device, &cmdListDesc, &cmdList));
|
||||
}
|
||||
|
||||
void runClient(int commSocket, uint32_t clientId) {
|
||||
std::cout << "Client " << clientId << ", process ID:::: " << std::dec << getpid() << "\n";
|
||||
|
||||
ze_driver_handle_t driverHandle;
|
||||
ze_context_handle_t context;
|
||||
ze_device_handle_t device;
|
||||
ze_command_queue_handle_t cmdQueue;
|
||||
ze_command_list_handle_t cmdList;
|
||||
initializeProcess(driverHandle, context, device, cmdQueue, cmdList);
|
||||
|
||||
char *heapBuffer = new char[allocSize];
|
||||
for (size_t i = 0; i < allocSize; ++i) {
|
||||
heapBuffer[i] = static_cast<char>(i + 1);
|
||||
}
|
||||
|
||||
// receive the IPC handle for the memory from the other process
|
||||
ze_ipc_mem_handle_t ipcHandle;
|
||||
|
||||
int handle = recvmsgForIpcHandle(commSocket, ipcHandle.data);
|
||||
if (handle < 0) {
|
||||
std::cerr << "Failing to get IPC memory handle from server\n";
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
memcpy(&ipcHandle, static_cast<void *>(&handle), sizeof(handle));
|
||||
|
||||
// get a memory pointer to the BO associated with the dma_buf handles
|
||||
void *zeIpcBuffer;
|
||||
SUCCESS_OR_TERMINATE(zeMemOpenIpcHandle(context, device, ipcHandle, 0u, &zeIpcBuffer));
|
||||
|
||||
// Copy from heap to IPC buffer memory
|
||||
memcpy(zeIpcBuffer, heapBuffer, allocSize);
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeMemCloseIpcHandle(context, zeIpcBuffer));
|
||||
SUCCESS_OR_TERMINATE(zeCommandListDestroy(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueDestroy(cmdQueue));
|
||||
SUCCESS_OR_TERMINATE(zeContextDestroy(context));
|
||||
|
||||
delete[] heapBuffer;
|
||||
}
|
||||
|
||||
void runServer(bool &validRet) {
|
||||
std::cout << "Server process ID:::: " << std::dec << getpid() << "\n";
|
||||
|
||||
ze_driver_handle_t driverHandle;
|
||||
ze_context_handle_t context;
|
||||
ze_device_handle_t device;
|
||||
ze_command_queue_handle_t cmdQueue;
|
||||
ze_command_list_handle_t cmdList;
|
||||
initializeProcess(driverHandle, context, device, cmdQueue, cmdList);
|
||||
|
||||
void *zeBuffer = nullptr;
|
||||
ze_host_mem_alloc_desc_t hostDesc = {ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC};
|
||||
SUCCESS_OR_TERMINATE(zeMemAllocHost(context, &hostDesc, allocSize, allocSize, &zeBuffer));
|
||||
|
||||
for (uint32_t i = 0; i < CHILDPROCESSES; i++) {
|
||||
// Initialize the IPC buffer
|
||||
int value = 3;
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendMemoryFill(cmdList, zeBuffer, reinterpret_cast<void *>(&value),
|
||||
sizeof(value), allocSize, nullptr, 0, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListClose(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueExecuteCommandLists(cmdQueue, 1, &cmdList, nullptr));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueSynchronize(cmdQueue, std::numeric_limits<uint64_t>::max()));
|
||||
SUCCESS_OR_TERMINATE(zeCommandListReset(cmdList));
|
||||
|
||||
// Get the IPC handle for the previously allocated pointer
|
||||
ze_ipc_mem_handle_t ipcHandle;
|
||||
SUCCESS_OR_TERMINATE(zeMemGetIpcHandle(context, zeBuffer, &ipcHandle));
|
||||
|
||||
// Pass the IPC handle to the other process
|
||||
int dmaBufFd;
|
||||
memcpy(static_cast<void *>(&dmaBufFd), &ipcHandle, sizeof(dmaBufFd));
|
||||
int commSocket = sv[i][0];
|
||||
if (sendmsgForIpcHandle(commSocket, static_cast<int>(dmaBufFd), ipcHandle.data) < 0) {
|
||||
std::cerr << "Failing to send IPC memory handle to client\n";
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
// Wait for child to exit
|
||||
int childStatus;
|
||||
pid_t clientPId = wait(&childStatus);
|
||||
if (clientPId <= 0) {
|
||||
std::cerr << "Client terminated abruptly with error code " << strerror(errno) << "\n";
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
void *validateBuffer = nullptr;
|
||||
ze_device_mem_alloc_desc_t deviceDesc = {ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC};
|
||||
SUCCESS_OR_TERMINATE(zeMemAllocShared(context, &deviceDesc, &hostDesc,
|
||||
allocSize, 1, device, &validateBuffer));
|
||||
|
||||
value = 5;
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendMemoryFill(cmdList, validateBuffer, reinterpret_cast<void *>(&value),
|
||||
sizeof(value), allocSize, nullptr, 0, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendBarrier(cmdList, nullptr, 0, nullptr));
|
||||
|
||||
// Copy from device-allocated memory
|
||||
SUCCESS_OR_TERMINATE(zeCommandListAppendMemoryCopy(cmdList, validateBuffer, zeBuffer, allocSize,
|
||||
nullptr, 0, nullptr));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListClose(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueExecuteCommandLists(cmdQueue, 1, &cmdList, nullptr));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueSynchronize(cmdQueue, std::numeric_limits<uint64_t>::max()));
|
||||
|
||||
char *heapBuffer = new char[allocSize];
|
||||
for (size_t i = 0; i < allocSize; ++i) {
|
||||
heapBuffer[i] = static_cast<char>(i + 1);
|
||||
}
|
||||
|
||||
char *ipcBuffer = static_cast<char *>(validateBuffer);
|
||||
for (uint32_t h = 0; h < allocSize; h++) {
|
||||
if (static_cast<uint32_t>(ipcBuffer[h]) != static_cast<uint32_t>(heapBuffer[h])) {
|
||||
printf("Error: ipcBuffer %d %d, heapBuffer %d\n", h, static_cast<uint32_t>(ipcBuffer[h]), heapBuffer[h]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate stack and buffers have the original data from heapBuffer
|
||||
validRet = (0 == memcmp(heapBuffer, validateBuffer, allocSize));
|
||||
delete[] heapBuffer;
|
||||
}
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeMemFree(context, zeBuffer));
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeCommandListDestroy(cmdList));
|
||||
SUCCESS_OR_TERMINATE(zeCommandQueueDestroy(cmdQueue));
|
||||
SUCCESS_OR_TERMINATE(zeContextDestroy(context));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const std::string blackBoxName = "Zello IPC";
|
||||
verbose = isVerbose(argc, argv);
|
||||
bool outputValidationSuccessful;
|
||||
|
||||
for (uint32_t i = 0; i < CHILDPROCESSES; i++) {
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv[i]) < 0) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pid_t childPids[CHILDPROCESSES];
|
||||
for (uint32_t i = 0; i < CHILDPROCESSES; i++) {
|
||||
childPids[i] = fork();
|
||||
if (childPids[i] < 0) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
} else if (childPids[i] == 0) {
|
||||
close(sv[i][0]);
|
||||
runClient(sv[i][1], i);
|
||||
close(sv[i][1]);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
runServer(outputValidationSuccessful);
|
||||
|
||||
printResult(false, outputValidationSuccessful, blackBoxName);
|
||||
return outputValidationSuccessful ? 0 : 1;
|
||||
}
|
Loading…
Reference in New Issue