Files
nvsci_samples/rawstream/rawstream_cuda.c
svcmobrel-release 5482324389 Updating prebuilts and/or headers
8193be73ce0a488f62034cb87083cdf09f52cd5d - event_sample_app/block_pool.c
a0bd135d707994a41ed3a4234b5f875a268fed4d - event_sample_app/Makefile
44f6de348f8bdd5cb584b3e8cc4b05e9482dddd2 - event_sample_app/event_loop.h
6ff0f1c2d7ef2e2fa9ece6fdc850b58b87207526 - event_sample_app/block_returnsync.c
1158201e78094e9e866fa99095c9ffc2ec9f5a27 - event_sample_app/block_limiter.c
f5e2aea98ba9264ee1068a700222dff8d5d5c7a4 - event_sample_app/block_c2c.c
ef057870dade9af70656b37340e9bcad35d49380 - event_sample_app/block_multicast.c
641e3634da873970b574b23a1024b2e7155b88ff - event_sample_app/block_consumer_uc1.c
ced622a41d1a48dcb23e6a1a02ae9640ef9b837c - event_sample_app/util.h
3a1013021a572887303fb6db245b5b01fe07e9a0 - event_sample_app/block_producer_uc1.c
dac99c442185b020fbdae07bfc1e7df78343eb83 - event_sample_app/block_info.h
b5dd68bec3ae6f9049aad1cb5a86c3db4af02e17 - event_sample_app/block_presentsync.c
e0861e9fe5d160d47d758464146d7192f9c70a5f - event_sample_app/util.c
d7e42e2b6088ff4596abc7256eb018d757a4021e - event_sample_app/usecase1.h
65ffe5af6ae6bc0418f348167c473849d4697e47 - event_sample_app/block_ipc.c
b52e34443ac441a9df48029de944aa0a50d1b101 - event_sample_app/event_loop_service.c
5001f036389a4f7952cb4974dd3323908208ca30 - event_sample_app/event_loop_threads.c
a71ed037f9d77d0944f40f54cf25db8180d007e2 - event_sample_app/block_queue.c
d6bbd17599543f1760d87851150a12a2a842a24d - event_sample_app/block_common.c
40f949c4c37ab4aa4a84182b345f3de6fceab39b - event_sample_app/main.c
458833ab233a725c067bf9b1fc60ef39872eee80 - rawstream/Makefile
1fbb82e2281bb2e168c87fd20903bbed898ca160 - rawstream/rawstream_cuda.c
e26c09f1ad1a3a7d2c29dae1b38d3fd90c23af6e - rawstream/rawstream_consumer.c
2bed038ca070aa5dccd6b672a98f093340e829bb - rawstream/rawstream_producer.c
3df4e5c00a3dc002ee9877e282bd28ffa87fa6f0 - rawstream/rawstream.h
d5ffeef3c7ad2af6f6f31385db7917b5ef9a7438 - rawstream/rawstream_ipc_linux.c
f28c1cd5fe26b6dc5930d5556b54364c9b91767c - rawstream/rawstream_main.c

Change-Id: Icdf4312706c30fbcfa1533fba5277879e8d77aec
2025-01-21 05:25:22 -08:00

235 lines
7.3 KiB
C

/*
* Copyright (c) 2020-2021 NVIDIA Corporation. All Rights Reserved.
*
* NVIDIA Corporation and its licensors retain all intellectual property and
* proprietary rights in and to this software and related documentation. Any
* use, reproduction, disclosure or distribution of this software and related
* documentation without an express license agreement from NVIDIA Corporation
* is strictly prohibited.
*/
#include "rawstream.h"
// Initialize CUDA info
bool setupCuda(CudaClientInfo* info)
{
int cudaErr;
info->deviceId = 0;
info->stream = NULL;
info->signalerSem = NULL;
info->waiterSem = NULL;
info->bufCopy = NULL;
int numOfGPUs = 0;
cudaErr = cudaGetDeviceCount(&numOfGPUs);
if (cudaSuccess != cudaErr) {
fprintf(stderr, "Failed to get compute-capable devices (%d)\n", cudaErr);
return false;
}
cudaErr = cudaSetDevice(info->deviceId);
if (cudaSuccess != cudaErr) {
fprintf(stderr, "Failed to set CUDA device (%d)\n", cudaErr);
return false;
}
cudaErr = cuDeviceGetUuid(&info->uuid, info->deviceId);
if (CUDA_SUCCESS != cudaErr) {
fprintf(stderr, "Failed to query CUDA UUID (%d)\n", cudaErr);
return false;
}
return true;
}
// Create CUDA sync objects and map to imported NvSciSync
bool setupCudaSync(CudaClientInfo* info,
NvSciSyncObj sciSignalObj,
NvSciSyncObj sciWaitObj)
{
cudaExternalSemaphoreHandleDesc extSemDesc;
int cudaErr;
// Create CUDA stream for signaling and waiting
cudaErr = cudaStreamCreateWithFlags(&info->stream,
cudaStreamNonBlocking);
if (cudaSuccess != cudaErr) {
fprintf(stderr,
"Unable to create CUDA stream (%d)\n",
cudaErr);
return false;
}
// Import signaler sync object to CUDA semaphore
memset(&extSemDesc, 0, sizeof(extSemDesc));
extSemDesc.type = cudaExternalSemaphoreHandleTypeNvSciSync;
extSemDesc.handle.nvSciSyncObj = sciSignalObj;
cudaErr = cudaImportExternalSemaphore(&info->signalerSem, &extSemDesc);
if (cudaSuccess != cudaErr) {
fprintf(stderr,
"Unable to import signal sync object to CUDA (%d)\n",
cudaErr);
return false;
}
// Import waiter sync object to CUDA semaphore
memset(&extSemDesc, 0, sizeof(extSemDesc));
extSemDesc.type = cudaExternalSemaphoreHandleTypeNvSciSync;
extSemDesc.handle.nvSciSyncObj = sciWaitObj;
cudaErr = cudaImportExternalSemaphore(&info->waiterSem, &extSemDesc);
if (cudaSuccess != cudaErr) {
fprintf(stderr,
"Unable to import wait sync object to CUDA (%d)\n",
cudaErr);
return false;
}
return true;
}
// Extract info from buffer attributes needed by CUDA
bool setupCudaBufAttr(CudaClientInfo* info,
NvSciBufAttrList attrs)
{
NvSciBufAttrKeyValuePair queryKeyValue[] = {
{ NvSciBufGeneralAttrKey_Types, NULL, 0 },
{ NvSciBufRawBufferAttrKey_Size, NULL, 0 },
};
NvSciError sciErr = NvSciBufAttrListGetAttrs(attrs, queryKeyValue, 2);
if (NvSciError_Success != sciErr) {
fprintf(stderr, "Unable to query buffer type/size (%x)\n", sciErr);
return false;
}
// TODO: Original sample queries BufType but doesn't seem to do anything
// with it. Might not be needed.
info->bufType = *((NvSciBufType*)(queryKeyValue[0].value));
info->bufSize = *((uint64_t*)(queryKeyValue[1].value));
// Allocate storage for a copy of the buffer contents
info->bufCopy = (uint8_t*)malloc(info->bufSize);
if (NULL == info->bufCopy) {
fprintf(stderr, "Unable to allocate buffer copy\n");
return false;
}
(void)memset(info->bufCopy, 0, info->bufSize);
return true;
}
// Import NvSciBuf into CUDA
bool setupCudaBuffer(CudaClientInfo* info,
Buffer* buf)
{
int cudaErr;
// Import buffer to cuda as external memory
cudaExternalMemoryHandleDesc memHandleDesc;
memset(&memHandleDesc, 0, sizeof(memHandleDesc));
memHandleDesc.type = cudaExternalMemoryHandleTypeNvSciBuf;
memHandleDesc.handle.nvSciBufObject = buf->obj;
memHandleDesc.size = info->bufSize;
cudaErr = cudaImportExternalMemory(&buf->extMem, &memHandleDesc);
if (cudaSuccess != cudaErr) {
fprintf(stderr,
"Unable to import buffer to CUDA (%d)\n",
cudaErr);
return false;
}
// Map to cuda memory buffer
cudaExternalMemoryBufferDesc bufferDesc;
memset(&bufferDesc, 0, sizeof(bufferDesc));
bufferDesc.size = info->bufSize;
bufferDesc.offset = 0;
cudaErr = cudaExternalMemoryGetMappedBuffer((void *)&buf->ptr,
buf->extMem,
&bufferDesc);
if (cudaSuccess != cudaErr) {
fprintf(stderr, "Unable to map CUDA buffer (%d)\n", cudaErr);
return false;
}
return true;
}
// Tell CUDA to wait for the fence associated with a buffer
bool waitCudaFence(CudaClientInfo* info,
Buffer* buf)
{
cudaExternalSemaphoreWaitParams waitParams;
memset(&waitParams, 0, sizeof(waitParams));
waitParams.params.nvSciSync.fence = &buf->fence;
waitParams.flags = 0;
int cudaErr = cudaWaitExternalSemaphoresAsync(&info->waiterSem,
&waitParams,
1,
info->stream);
if (cudaSuccess != cudaErr) {
fprintf(stderr, "Unable to wait for fence (%d)\n", cudaErr);
return false;
}
NvSciSyncFenceClear(&buf->fence);
return true;
}
// Tell CUDA to generate a fence for a buffer
bool signalCudaFence(CudaClientInfo* info,
Buffer* buf)
{
cudaExternalSemaphoreSignalParams signalParams;
memset(&signalParams, 0, sizeof(signalParams));
signalParams.params.nvSciSync.fence = &buf->fence;
signalParams.flags = 0;
int cudaErr = cudaSignalExternalSemaphoresAsync(&info->signalerSem,
&signalParams,
1,
info->stream);
if (cudaSuccess != cudaErr) {
fprintf(stderr, "Unable to signal fence (%d)\n", cudaErr);
return false;
}
return true;
}
void deinitCuda(CudaClientInfo* info)
{
if (NULL != info->bufCopy) {
free(info->bufCopy);
info->bufCopy = NULL;
}
if (NULL != info->signalerSem) {
(void)cudaDestroyExternalSemaphore(info->signalerSem);
info->signalerSem = NULL;
}
if (NULL != info->waiterSem) {
(void)cudaDestroyExternalSemaphore(info->waiterSem);
info->waiterSem = NULL;
}
if (NULL != info->stream) {
(void)cudaStreamDestroy(info->stream);
info->stream = NULL;
}
}
void deinitCudaBuffer(Buffer* buf, int num)
{
int i;
for (i = 0; i < num; ++i) {
if (NULL != buf[i].ptr)
cudaFree(buf[i].ptr);
if (NULL != buf[i].extMem)
(void)cudaDestroyExternalMemory(buf[i].extMem);
if (NULL != buf[i].obj)
NvSciBufObjFree(buf[i].obj);
}
}