mirror of
git://nv-tegra.nvidia.com/tegra/nv-sci-src/nvsci_samples.git
synced 2025-12-22 09:21:21 +03:00
2eba699906039d6615aae4967f6ea79bfe44a40a - event_sample_app/block_pool.c f3abb0a884f0647204ad32ff51255c4712e52120 - event_sample_app/Makefile 9ee49033e077ac5c8bf458a04c91dd3dbed9633d - event_sample_app/event_loop.h b33adce6eb1bbc7af23f6c37b6a635479e18a66a - event_sample_app/block_returnsync.c a56041c06b6bc1d3812b72b399d7d78dd7895485 - event_sample_app/block_limiter.c ca34c957759f7a010f0cbbbf9bedc03a2c98092b - event_sample_app/block_c2c.c 8d6d0ec3aa8e374a1d2a5fedc9dd24ff7bbdb731 - event_sample_app/block_multicast.c a76149a2531899e35843d939f60ad8979d8cf65f - event_sample_app/block_consumer_uc1.c 9da8763e4af4b4b7278507a3ebfe2c68a7a24585 - event_sample_app/util.h 2bf7e1383d6e8913c9b0a6a8bdd48fe63d8098d0 - event_sample_app/block_producer_uc1.c a54abf82eaa2d888e379ab4596ba68ce264e80b5 - event_sample_app/block_info.h 080a6efe263be076c7046e70e31098c2bbed0f6d - event_sample_app/block_presentsync.c 7dd10e5ea71f0c4a09bbe1f9f148f67a13ee098c - event_sample_app/util.c bc1a6f9017b28e5707c166a658a35e6b3986fdf4 - event_sample_app/usecase1.h 317f43efc59638bf1eae8303f0c79eafb059241a - event_sample_app/block_ipc.c 40361c8f0b68f7d5207db2466ce08c19c0bf1c90 - event_sample_app/event_loop_service.c efad113d0107e5d8f90146f3102a7c0ed22f1a35 - event_sample_app/event_loop_threads.c 2908615cebcf36330b9850c57e8745bf324867b2 - event_sample_app/block_queue.c 36ed68eca1a7800cf0d94e763c9fc352ee8cda1e - event_sample_app/block_common.c 675f75d61bd0226625a8eaaf0e503c9e976c8d61 - event_sample_app/main.c c3b26619dd07d221e953fc5dc29a50dcb95a8b97 - rawstream/Makefile 1fbb82e2281bb2e168c87fd20903bbed898ca160 - rawstream/rawstream_cuda.c 1d96498fe3c922f143f7e50e0a32b099714060ad - rawstream/rawstream_consumer.c d077dafc9176686f6d081026225325c2a303a60e - rawstream/rawstream_producer.c 54ae655edddda7dcabe22fbf0b27c3f617978851 - rawstream/rawstream.h d5ffeef3c7ad2af6f6f31385db7917b5ef9a7438 - rawstream/rawstream_ipc_linux.c 81e3d6f8ff5252797a7e9e170b74df6255f54f1b - rawstream/rawstream_main.c Change-Id: I0f4e671693eb0addfe8d0e6532cc8f240cb6c778
235 lines
7.3 KiB
C
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);
|
|
}
|
|
}
|
|
|