Apply consistent code formatting across the repo. Add clang-format and pre-commit hooks.

This commit is contained in:
Rob Armstrong
2025-03-27 10:30:07 -07:00
parent 2cd58fbc9a
commit ceab6e8bcc
782 changed files with 107230 additions and 106548 deletions

View File

@@ -34,4 +34,3 @@ Download and install the [CUDA Toolkit 12.8](https://developer.nvidia.com/cuda-d
Make sure the dependencies mentioned in [Dependencies]() section above are installed.
## References (for more details)

View File

@@ -27,162 +27,165 @@
#include "cudaNvSciBufMultiplanar.h"
NvSciBufModule module;
NvSciBufObj buffObj;
CUuuid uuid;
NvSciBufObj buffObj;
CUuuid uuid;
void flipBits(uint8_t *pBuff, uint32_t size) {
void flipBits(uint8_t *pBuff, uint32_t size)
{
for (uint32_t i = 0; i < size; i++) {
pBuff[i] = (~pBuff[i]);
}
}
// Compare input and generated image files
void compareFiles(std::string &path1, std::string &path2) {
bool result = true;
void compareFiles(std::string &path1, std::string &path2)
{
bool result = true;
FILE *fp1, *fp2;
int ch1, ch2;
int ch1, ch2;
fp1 = fopen(path1.c_str(), "rb");
fp2 = fopen(path2.c_str(), "rb");
if (!fp1) {
result = false;
printf("File %s open failed in %s line %d\n", path1.c_str(), __FILE__, __LINE__);
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
if (!fp2) {
result = false;
printf("File %s open failed in %s line %d\n", path2.c_str(), __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
do {
ch1 = getc(fp1);
do {
ch1 = getc(fp1);
ch2 = getc(fp2);
if (ch1 != ch2) {
result = false;
if (ch1 != ch2) {
result = false;
break;
}
} while(ch1 != EOF && ch2 != EOF);
}
} while (ch1 != EOF && ch2 != EOF);
if (result) {
printf("Input file : %s and output file : %s match SUCCESS\n", path1.c_str(), path2.c_str());
}
}
else {
printf("Input file : %s and output file : %s match FAILURE\n", path1.c_str(), path2.c_str());
}
if (fp1) {
fclose(fp1);
}
if (fp2) {
fclose(fp2);
}
}
}
void Caller::init() {
void Caller::init()
{
checkNvSciErrors(NvSciBufAttrListCreate(module, &attrList));
attrListOut = NULL;
}
void Caller::deinit() {
void Caller::deinit()
{
NvSciBufAttrListFree(attrList);
checkCudaErrors(cudaDestroyExternalMemory(extMem));
}
// Set NvSciBufImage attribute values in the attribute list
void Caller::setAttrListImageMultiPlanes(int imageWidth, int imageHeight) {
NvSciBufType bufType = NvSciBufType_Image;
NvSciBufAttrValImageLayoutType layout = NvSciBufImage_BlockLinearType;
bool cpuAccessFlag = false;
NvSciBufAttrValAccessPerm perm = NvSciBufAccessPerm_ReadWrite;
NvSciRmGpuId gpuid;
bool vpr = false;
int32_t planeCount = PLANAR_NUM_PLANES;
int drvVersion;
// Set NvSciBufImage attribute values in the attribute list
void Caller::setAttrListImageMultiPlanes(int imageWidth, int imageHeight)
{
NvSciBufType bufType = NvSciBufType_Image;
NvSciBufAttrValImageLayoutType layout = NvSciBufImage_BlockLinearType;
bool cpuAccessFlag = false;
NvSciBufAttrValAccessPerm perm = NvSciBufAccessPerm_ReadWrite;
NvSciRmGpuId gpuid;
bool vpr = false;
int32_t planeCount = PLANAR_NUM_PLANES;
int drvVersion;
// Dimensions of the imported image in the YUV 420 planar format
int32_t planeWidths[] = {imageWidth, imageWidth/2, imageWidth/2};
int32_t planeHeights[] = {imageHeight, imageHeight/2, imageHeight/2};
int32_t planeWidths[] = {imageWidth, imageWidth / 2, imageWidth / 2};
int32_t planeHeights[] = {imageHeight, imageHeight / 2, imageHeight / 2};
NvSciBufAttrKeyValuePair keyPair;
NvSciBufAttrKeyValuePair pairArray[ATTR_SIZE];
NvSciBufAttrValColorFmt planeColorFmts[] =
{ NvSciColor_Y8, NvSciColor_V8, NvSciColor_U8 };
NvSciBufAttrValImageScanType planeScanType[] =
{ NvSciBufScan_ProgressiveType };
NvSciBufAttrValColorFmt planeColorFmts[] = {NvSciColor_Y8, NvSciColor_V8, NvSciColor_U8};
NvSciBufAttrValImageScanType planeScanType[] = {NvSciBufScan_ProgressiveType};
memcpy(&gpuid.bytes, &uuid.bytes, sizeof(uuid.bytes));
NvSciBufAttrKeyValuePair imgBuffAttrsArr[] = {
{ NvSciBufGeneralAttrKey_Types, &bufType, sizeof(bufType) },
{ NvSciBufGeneralAttrKey_NeedCpuAccess, &cpuAccessFlag,
sizeof(cpuAccessFlag) },
{ NvSciBufGeneralAttrKey_RequiredPerm, &perm, sizeof(perm) },
{ NvSciBufGeneralAttrKey_GpuId, &gpuid, sizeof(gpuid) },
{ NvSciBufImageAttrKey_Layout, &layout, sizeof(layout) },
{ NvSciBufImageAttrKey_VprFlag, &vpr, sizeof(vpr) },
{ NvSciBufImageAttrKey_PlaneCount, &planeCount, sizeof(planeCount) },
{ NvSciBufImageAttrKey_PlaneColorFormat, planeColorFmts,
sizeof(planeColorFmts) },
{ NvSciBufImageAttrKey_PlaneWidth, planeWidths, sizeof(planeWidths) },
{ NvSciBufImageAttrKey_PlaneHeight, planeHeights,
sizeof(planeHeights) },
{ NvSciBufImageAttrKey_PlaneScanType, planeScanType,
sizeof(planeScanType) },
{NvSciBufGeneralAttrKey_Types, &bufType, sizeof(bufType)},
{NvSciBufGeneralAttrKey_NeedCpuAccess, &cpuAccessFlag, sizeof(cpuAccessFlag)},
{NvSciBufGeneralAttrKey_RequiredPerm, &perm, sizeof(perm)},
{NvSciBufGeneralAttrKey_GpuId, &gpuid, sizeof(gpuid)},
{NvSciBufImageAttrKey_Layout, &layout, sizeof(layout)},
{NvSciBufImageAttrKey_VprFlag, &vpr, sizeof(vpr)},
{NvSciBufImageAttrKey_PlaneCount, &planeCount, sizeof(planeCount)},
{NvSciBufImageAttrKey_PlaneColorFormat, planeColorFmts, sizeof(planeColorFmts)},
{NvSciBufImageAttrKey_PlaneWidth, planeWidths, sizeof(planeWidths)},
{NvSciBufImageAttrKey_PlaneHeight, planeHeights, sizeof(planeHeights)},
{NvSciBufImageAttrKey_PlaneScanType, planeScanType, sizeof(planeScanType)},
};
std::vector<NvSciBufAttrKeyValuePair> imgBuffAttrsVec(imgBuffAttrsArr,
imgBuffAttrsArr+(sizeof(imgBuffAttrsArr)/sizeof(imgBuffAttrsArr[0])));
std::vector<NvSciBufAttrKeyValuePair> imgBuffAttrsVec(
imgBuffAttrsArr, imgBuffAttrsArr + (sizeof(imgBuffAttrsArr) / sizeof(imgBuffAttrsArr[0])));
memset(pairArray, 0, sizeof(NvSciBufAttrKeyValuePair) * imgBuffAttrsVec.size());
std::copy(imgBuffAttrsVec.begin(), imgBuffAttrsVec.end(), pairArray);
checkNvSciErrors(NvSciBufAttrListSetAttrs(attrList, pairArray, imgBuffAttrsVec.size()));
}
cudaNvSciBufMultiplanar::cudaNvSciBufMultiplanar(size_t width, size_t height, std::vector<int> &deviceIds)
: imageWidth(width),
imageHeight(height) {
mCudaDeviceId = deviceIds[0];
attrListReconciled = NULL;
attrListConflict = NULL;
checkNvSciErrors(NvSciBufModuleOpen(&module));
initCuda(mCudaDeviceId);
}
: imageWidth(width)
, imageHeight(height)
{
mCudaDeviceId = deviceIds[0];
attrListReconciled = NULL;
attrListConflict = NULL;
checkNvSciErrors(NvSciBufModuleOpen(&module));
initCuda(mCudaDeviceId);
}
void cudaNvSciBufMultiplanar::initCuda(int devId) {
int major = 0, minor = 0, drvVersion;
void cudaNvSciBufMultiplanar::initCuda(int devId)
{
int major = 0, minor = 0, drvVersion;
NvSciRmGpuId gpuid;
checkCudaErrors(cudaSetDevice(mCudaDeviceId));
checkCudaErrors(cudaDeviceGetAttribute(
&major, cudaDevAttrComputeCapabilityMajor, mCudaDeviceId));
checkCudaErrors(cudaDeviceGetAttribute(
&minor, cudaDevAttrComputeCapabilityMinor, mCudaDeviceId));
printf(
"[cudaNvSciBufMultiplanar] GPU Device %d: \"%s\" with compute capability "
"%d.%d\n\n",
mCudaDeviceId, _ConvertSMVer2ArchName(major, minor), major, minor);
checkCudaErrors(cudaDeviceGetAttribute(&major, cudaDevAttrComputeCapabilityMajor, mCudaDeviceId));
checkCudaErrors(cudaDeviceGetAttribute(&minor, cudaDevAttrComputeCapabilityMinor, mCudaDeviceId));
printf("[cudaNvSciBufMultiplanar] GPU Device %d: \"%s\" with compute capability "
"%d.%d\n\n",
mCudaDeviceId,
_ConvertSMVer2ArchName(major, minor),
major,
minor);
checkCudaDrvErrors(cuDriverGetVersion(&drvVersion));
if (drvVersion <= 11030) {
checkCudaDrvErrors(cuDeviceGetUuid(&uuid, devId));
} else {
}
else {
checkCudaDrvErrors(cuDeviceGetUuid_v2(&uuid, devId));
}
}
/*
/*
Caller1 flips a YUV image which is allocated to nvscibuf APIs and copied into CUDA Array.
It is mapped to CUDA surface and bit flip is done. Caller2 in the same thread copies
It is mapped to CUDA surface and bit flip is done. Caller2 in the same thread copies
CUDA Array to a YUV image file. The original image is compared with the double bit
flipped image.
*/
void cudaNvSciBufMultiplanar::runCudaNvSciBufPlanar(std::string &imageFilename, std::string &imageFilenameOut) {
void cudaNvSciBufMultiplanar::runCudaNvSciBufPlanar(std::string &imageFilename, std::string &imageFilenameOut)
{
cudaArray_t levelArray1[PLANAR_NUM_PLANES];
cudaArray_t levelArray2[PLANAR_NUM_PLANES];
Caller caller1;
Caller caller2;
Caller caller1;
Caller caller2;
int numPlanes = PLANAR_NUM_PLANES;
caller1.init();
@@ -191,23 +194,23 @@ void cudaNvSciBufMultiplanar::runCudaNvSciBufPlanar(std::string &imageFilename,
// Set NvSciBufImage attribute values in the attribute list
caller1.setAttrListImageMultiPlanes(imageWidth, imageHeight);
caller2.setAttrListImageMultiPlanes(imageWidth, imageHeight);
// Reconcile attribute lists and allocate NvSciBuf object
reconcileAttrList(&caller1.attrList, &caller2.attrList);
reconcileAttrList(&caller1.attrList, &caller2.attrList);
caller1.copyExtMemToMultiPlanarArrays();
for (int i = 0; i < numPlanes; i++) {
checkCudaErrors(cudaGetMipmappedArrayLevel(&levelArray1[i], caller1.multiPlanarArray[i], 0));
checkCudaErrors(cudaGetMipmappedArrayLevel(&levelArray1[i], caller1.multiPlanarArray[i], 0));
}
caller1.copyYUVToCudaArrayAndFlipBits(imageFilename, levelArray1);
caller2.copyExtMemToMultiPlanarArrays();
for (int i = 0; i < numPlanes; i++) {
checkCudaErrors(cudaGetMipmappedArrayLevel(&levelArray2[i], caller2.multiPlanarArray[i], 0));
checkCudaErrors(cudaGetMipmappedArrayLevel(&levelArray2[i], caller2.multiPlanarArray[i], 0));
}
// Maps cudaArray to surface memory and launches a kernel to flip bits
launchFlipSurfaceBitsKernel(levelArray2, caller2.multiPlanarWidth, caller2.multiPlanarHeight, numPlanes);
// Synchronization can be done using nvSciSync when non CUDA callers and cross-process signaler-waiter
// Synchronization can be done using nvSciSync when non CUDA callers and cross-process signaler-waiter
// applications are involved. Please refer to the cudaNvSci sample library for more details.
checkCudaDrvErrors(cuCtxSynchronize());
printf("Bit flip of the surface memory done\n");
@@ -225,66 +228,69 @@ void cudaNvSciBufMultiplanar::runCudaNvSciBufPlanar(std::string &imageFilename,
}
// Map NvSciBufObj to cudaMipmappedArray
void Caller::copyExtMemToMultiPlanarArrays() {
void Caller::copyExtMemToMultiPlanarArrays()
{
checkNvSciErrors(NvSciBufObjGetAttrList(buffObj, &attrListOut));
memset(pairArrayOut, 0, sizeof(NvSciBufAttrKeyValuePair) * PLANE_ATTR_SIZE);
cudaExternalMemoryHandleDesc memHandleDesc;
cudaExternalMemoryHandleDesc memHandleDesc;
cudaExternalMemoryMipmappedArrayDesc mipmapDesc = {0};
cudaChannelFormatDesc desc = {0};
cudaExtent extent = {0};
pairArrayOut[PLANE_SIZE].key = NvSciBufImageAttrKey_Size; // Datatype: @c uint64_t
pairArrayOut[PLANE_ALIGNED_SIZE].key = NvSciBufImageAttrKey_PlaneAlignedSize; // Datatype: @c uint64_t[]
pairArrayOut[PLANE_OFFSET].key = NvSciBufImageAttrKey_PlaneOffset; // Datatype: @c uint64_t[]
pairArrayOut[PLANE_HEIGHT].key = NvSciBufImageAttrKey_PlaneHeight; // Datatype: @c uint32_t[]
pairArrayOut[PLANE_WIDTH].key = NvSciBufImageAttrKey_PlaneWidth; // Datatype: @c int32_t[]
pairArrayOut[PLANE_CHANNEL_COUNT].key = NvSciBufImageAttrKey_PlaneChannelCount; // Datatype: @c uint8_t
pairArrayOut[PLANE_BITS_PER_PIXEL].key = NvSciBufImageAttrKey_PlaneBitsPerPixel;// Datatype: @c uint32_t[]
pairArrayOut[PLANE_COUNT].key = NvSciBufImageAttrKey_PlaneCount; // Datatype: @c uint32_t
checkNvSciErrors(NvSciBufAttrListGetAttrs(attrListOut, pairArrayOut, (PLANE_ATTR_SIZE)));
uint64_t size = *(uint64_t*)pairArrayOut[PLANE_SIZE].value;
uint64_t *planeAlignedSize = (uint64_t*)pairArrayOut[PLANE_ALIGNED_SIZE].value;
int32_t *planeWidth = (int32_t*)pairArrayOut[PLANE_WIDTH].value;
int32_t *planeHeight = (int32_t*)pairArrayOut[PLANE_HEIGHT].value;
uint64_t *planeOffset = (uint64_t*)pairArrayOut[PLANE_OFFSET].value;
uint8_t planeChannelCount = *(uint8_t*)pairArrayOut[PLANE_CHANNEL_COUNT].value;
uint32_t *planeBitsPerPixel = (uint32_t*)pairArrayOut[PLANE_BITS_PER_PIXEL].value;
uint32_t planeCount = *(uint32_t*)pairArrayOut[PLANE_COUNT].value;
cudaChannelFormatDesc desc = {0};
cudaExtent extent = {0};
pairArrayOut[PLANE_SIZE].key = NvSciBufImageAttrKey_Size; // Datatype: @c uint64_t
pairArrayOut[PLANE_ALIGNED_SIZE].key = NvSciBufImageAttrKey_PlaneAlignedSize; // Datatype: @c uint64_t[]
pairArrayOut[PLANE_OFFSET].key = NvSciBufImageAttrKey_PlaneOffset; // Datatype: @c uint64_t[]
pairArrayOut[PLANE_HEIGHT].key = NvSciBufImageAttrKey_PlaneHeight; // Datatype: @c uint32_t[]
pairArrayOut[PLANE_WIDTH].key = NvSciBufImageAttrKey_PlaneWidth; // Datatype: @c int32_t[]
pairArrayOut[PLANE_CHANNEL_COUNT].key = NvSciBufImageAttrKey_PlaneChannelCount; // Datatype: @c uint8_t
pairArrayOut[PLANE_BITS_PER_PIXEL].key = NvSciBufImageAttrKey_PlaneBitsPerPixel; // Datatype: @c uint32_t[]
pairArrayOut[PLANE_COUNT].key = NvSciBufImageAttrKey_PlaneCount; // Datatype: @c uint32_t
checkNvSciErrors(NvSciBufAttrListGetAttrs(attrListOut, pairArrayOut, (PLANE_ATTR_SIZE)));
uint64_t size = *(uint64_t *)pairArrayOut[PLANE_SIZE].value;
uint64_t *planeAlignedSize = (uint64_t *)pairArrayOut[PLANE_ALIGNED_SIZE].value;
int32_t *planeWidth = (int32_t *)pairArrayOut[PLANE_WIDTH].value;
int32_t *planeHeight = (int32_t *)pairArrayOut[PLANE_HEIGHT].value;
uint64_t *planeOffset = (uint64_t *)pairArrayOut[PLANE_OFFSET].value;
uint8_t planeChannelCount = *(uint8_t *)pairArrayOut[PLANE_CHANNEL_COUNT].value;
uint32_t *planeBitsPerPixel = (uint32_t *)pairArrayOut[PLANE_BITS_PER_PIXEL].value;
uint32_t planeCount = *(uint32_t *)pairArrayOut[PLANE_COUNT].value;
numPlanes = planeCount;
for (int i = 0; i < numPlanes; i++) {
multiPlanarWidth[i] = planeWidth[i];
multiPlanarWidth[i] = planeWidth[i];
multiPlanarHeight[i] = planeHeight[i];
}
memset(&memHandleDesc, 0, sizeof(memHandleDesc));
memHandleDesc.type = cudaExternalMemoryHandleTypeNvSciBuf;
memHandleDesc.type = cudaExternalMemoryHandleTypeNvSciBuf;
memHandleDesc.handle.nvSciBufObject = buffObj;
memHandleDesc.size = size;
memHandleDesc.size = size;
checkCudaErrors(cudaImportExternalMemory(&extMem, &memHandleDesc));
desc = cudaCreateChannelDesc(planeBitsPerPixel[0], 0, 0, 0, cudaChannelFormatKindUnsigned);
memset(&mipmapDesc, 0, sizeof(mipmapDesc));
mipmapDesc.numLevels = 1;
mipmapDesc.numLevels = 1;
for (int i = 0; i < numPlanes; i++) {
for (int i = 0; i < numPlanes; i++) {
memset(&extent, 0, sizeof(extent));
extent.width = planeWidth[i];
extent.height = planeHeight[i];
extent.depth = 0;
mipmapDesc.offset = planeOffset[i];
extent.width = planeWidth[i];
extent.height = planeHeight[i];
extent.depth = 0;
mipmapDesc.offset = planeOffset[i];
mipmapDesc.formatDesc = desc;
mipmapDesc.extent = extent;
mipmapDesc.flags = cudaArraySurfaceLoadStore;;
mipmapDesc.extent = extent;
mipmapDesc.flags = cudaArraySurfaceLoadStore;
;
checkCudaErrors(cudaExternalMemoryGetMappedMipmappedArray(&multiPlanarArray[i], extMem, &mipmapDesc));
}
}
void cudaNvSciBufMultiplanar::reconcileAttrList(NvSciBufAttrList *attrList1, NvSciBufAttrList *attrList2) {
attrList[0] = *attrList1;
attrList[1] = *attrList2;
void cudaNvSciBufMultiplanar::reconcileAttrList(NvSciBufAttrList *attrList1, NvSciBufAttrList *attrList2)
{
attrList[0] = *attrList1;
attrList[1] = *attrList2;
bool isReconciled = false;
checkNvSciErrors(NvSciBufAttrListReconcile(attrList, 2, &attrListReconciled, &attrListConflict));
@@ -294,38 +300,40 @@ void cudaNvSciBufMultiplanar::reconcileAttrList(NvSciBufAttrList *attrList1, NvS
}
// YUV 420 image is flipped and copied to cuda Array which is mapped to nvsciBuf
void Caller::copyYUVToCudaArrayAndFlipBits(std::string &path, cudaArray_t *cudaArr) {
FILE *fp = NULL;
void Caller::copyYUVToCudaArrayAndFlipBits(std::string &path, cudaArray_t *cudaArr)
{
FILE *fp = NULL;
uint8_t *pYBuff, *pUBuff, *pVBuff, *pChroma;
uint8_t *pBuff = NULL;
uint8_t *pBuff = NULL;
uint32_t uvOffset[numPlanes] = {0}, copyWidthInBytes[numPlanes] = {0}, copyHeight[numPlanes] = {0};
uint32_t width = multiPlanarWidth[0];
uint32_t width = multiPlanarWidth[0];
uint32_t height = multiPlanarHeight[0];
fp = fopen(path.c_str(), "rb");
if (!fp) {
printf("CudaProducer: Error opening file: %s in %s line %d\n", path.c_str(), __FILE__, __LINE__);
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
pBuff = (uint8_t*)malloc((width * height * PLANAR_CHROMA_WIDTH_ORDER * PLANAR_CHROMA_HEIGHT_ORDER) * sizeof(unsigned char));
pBuff = (uint8_t *)malloc((width * height * PLANAR_CHROMA_WIDTH_ORDER * PLANAR_CHROMA_HEIGHT_ORDER)
* sizeof(unsigned char));
if (!pBuff) {
printf("CudaProducer: Failed to allocate image buffer in %s line %d\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
// Y V U order in the buffer. Fully planar formats use
// Y V U order in the buffer. Fully planar formats use
// three planes to store the Y, Cb and Cr components separately.
pYBuff = pBuff;
pYBuff = pBuff;
pVBuff = pYBuff + width * height;
pUBuff = pVBuff + (width / PLANAR_CHROMA_WIDTH_ORDER) * (height / PLANAR_CHROMA_HEIGHT_ORDER);
pUBuff = pVBuff + (width / PLANAR_CHROMA_WIDTH_ORDER) * (height / PLANAR_CHROMA_HEIGHT_ORDER);
for (uint32_t i = 0; i < height; i++) {
if (fread(pYBuff, width, 1, fp) != 1) {
printf("ReadYUVFrame: Error reading file: %s in %s line %d\n", path.c_str(), __FILE__, __LINE__);
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
flipBits(pYBuff, width);
pYBuff += width;
}
pChroma = pVBuff;
for (uint32_t i = 0; i < height / PLANAR_CHROMA_HEIGHT_ORDER; i++) {
if (fread(pChroma, width / PLANAR_CHROMA_WIDTH_ORDER, 1, fp) != 1) {
@@ -335,7 +343,7 @@ void Caller::copyYUVToCudaArrayAndFlipBits(std::string &path, cudaArray_t *cudaA
flipBits(pChroma, width);
pChroma += width / PLANAR_CHROMA_WIDTH_ORDER;
}
pChroma = pUBuff;
for (uint32_t i = 0; i < height / PLANAR_CHROMA_HEIGHT_ORDER; i++) {
if (fread(pChroma, width / PLANAR_CHROMA_WIDTH_ORDER, 1, fp) != 1) {
@@ -345,22 +353,26 @@ void Caller::copyYUVToCudaArrayAndFlipBits(std::string &path, cudaArray_t *cudaA
flipBits(pChroma, width);
pChroma += width / PLANAR_CHROMA_WIDTH_ORDER;
}
uvOffset[0] = 0;
copyHeight[0] = height;
copyHeight[1] = height / PLANAR_CHROMA_HEIGHT_ORDER;
copyHeight[2] = height / PLANAR_CHROMA_HEIGHT_ORDER;
uvOffset[0] = 0;
copyHeight[0] = height;
copyHeight[1] = height / PLANAR_CHROMA_HEIGHT_ORDER;
copyHeight[2] = height / PLANAR_CHROMA_HEIGHT_ORDER;
copyWidthInBytes[0] = width;
// Width of the second and third planes is half of the first plane.
copyWidthInBytes[1] = width / PLANAR_CHROMA_WIDTH_ORDER;
copyWidthInBytes[2] = width / PLANAR_CHROMA_WIDTH_ORDER;
uvOffset[1] = width * height;
uvOffset[2] = uvOffset[1] + (width / PLANAR_CHROMA_WIDTH_ORDER) * (height / PLANAR_CHROMA_HEIGHT_ORDER);
// Width of the second and third planes is half of the first plane.
copyWidthInBytes[1] = width / PLANAR_CHROMA_WIDTH_ORDER;
copyWidthInBytes[2] = width / PLANAR_CHROMA_WIDTH_ORDER;
uvOffset[1] = width * height;
uvOffset[2] = uvOffset[1] + (width / PLANAR_CHROMA_WIDTH_ORDER) * (height / PLANAR_CHROMA_HEIGHT_ORDER);
for (int i = 0; i < numPlanes; i++) {
checkCudaDrvErrors(cuCtxSynchronize());
checkCudaErrors(cudaMemcpy2DToArray(
cudaArr[i], 0, 0, (void *)(pBuff + uvOffset[i]), copyWidthInBytes[i],
copyWidthInBytes[i], copyHeight[i],
cudaMemcpyHostToDevice));
checkCudaErrors(cudaMemcpy2DToArray(cudaArr[i],
0,
0,
(void *)(pBuff + uvOffset[i]),
copyWidthInBytes[i],
copyWidthInBytes[i],
copyHeight[i],
cudaMemcpyHostToDevice));
}
if (fp) {
@@ -374,61 +386,67 @@ void Caller::copyYUVToCudaArrayAndFlipBits(std::string &path, cudaArray_t *cudaA
printf("Image %s copied to CUDA Array and bit flip done\n", path.c_str());
}
// Copy Cuda Array in YUV 420 format to a file
void Caller::copyCudaArrayToYUV(std::string &path, cudaArray_t *cudaArr) {
FILE *fp = NULL;
int bufferSize;
uint32_t width = multiPlanarWidth[0];
uint32_t height = multiPlanarHeight[0];
uint32_t copyWidthInBytes=0, copyHeight=0;
// Copy Cuda Array in YUV 420 format to a file
void Caller::copyCudaArrayToYUV(std::string &path, cudaArray_t *cudaArr)
{
FILE *fp = NULL;
int bufferSize;
uint32_t width = multiPlanarWidth[0];
uint32_t height = multiPlanarHeight[0];
uint32_t copyWidthInBytes = 0, copyHeight = 0;
uint8_t *pCudaCopyMem = NULL;
fp = fopen(path.c_str(), "wb+");
if (!fp) {
printf("WriteFrame: file open failed %s in %s line %d\n", path.c_str(), __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
for (int i = 0; i < numPlanes; i++) {
if (i == 0) {
bufferSize = width * height;
bufferSize = width * height;
copyWidthInBytes = width;
copyHeight = height;
copyHeight = height;
pCudaCopyMem = (uint8_t *)malloc(bufferSize);
if (pCudaCopyMem == NULL) {
printf("pCudaCopyMem malloc failed in %s line %d\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
}
}
else {
bufferSize = ((height / PLANAR_CHROMA_HEIGHT_ORDER) * (width / PLANAR_CHROMA_WIDTH_ORDER));
bufferSize = ((height / PLANAR_CHROMA_HEIGHT_ORDER) * (width / PLANAR_CHROMA_WIDTH_ORDER));
copyWidthInBytes = width / PLANAR_CHROMA_WIDTH_ORDER;
copyHeight = height / PLANAR_CHROMA_HEIGHT_ORDER;
copyHeight = height / PLANAR_CHROMA_HEIGHT_ORDER;
}
memset(pCudaCopyMem, 0, bufferSize);
checkCudaErrors(cudaMemcpy2DFromArray(
(void *)pCudaCopyMem, copyWidthInBytes, cudaArr[i], 0, 0,
copyWidthInBytes, copyHeight,
cudaMemcpyDeviceToHost));
checkCudaErrors(cudaMemcpy2DFromArray((void *)pCudaCopyMem,
copyWidthInBytes,
cudaArr[i],
0,
0,
copyWidthInBytes,
copyHeight,
cudaMemcpyDeviceToHost));
checkCudaDrvErrors(cuCtxSynchronize());
if (fwrite(pCudaCopyMem, bufferSize, 1, fp) != 1) {
printf("Cuda consumer: output file write failed in %s line %d\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
}
printf("Output file : %s saved\n", path.c_str());
if (fp) {
fclose(fp);
fp = NULL;
}
}
}
void cudaNvSciBufMultiplanar::tearDown(Caller *caller1, Caller *caller2) {
void cudaNvSciBufMultiplanar::tearDown(Caller *caller1, Caller *caller2)
{
caller1->deinit();
caller2->deinit();
NvSciBufObjFree(buffObj);

View File

@@ -27,61 +27,69 @@
#ifndef CUDA_NVSCIBUF_MULTIPLANAR_H
#define CUDA_NVSCIBUF_MULTIPLANAR_H
#include <cuda.h>
#include <cuda_runtime.h>
#include <helper_cuda.h>
#include <nvscibuf.h>
#include <vector>
#include <cuda.h>
#include <helper_cuda.h>
#define PLANAR_NUM_PLANES 3
#define PLANAR_CHROMA_WIDTH_ORDER 2
#define PLANAR_NUM_PLANES 3
#define PLANAR_CHROMA_WIDTH_ORDER 2
#define PLANAR_CHROMA_HEIGHT_ORDER 2
#define ATTR_SIZE 20
#define ATTR_SIZE 20
#define DEFAULT_GPU 0
#define checkNvSciErrors(call) \
do { \
NvSciError _status = call; \
if (NvSciError_Success != _status) { \
printf( \
"NVSCI call in file '%s' in line %i returned" \
" %d, expected %d\n", \
__FILE__, __LINE__, _status, NvSciError_Success); \
fflush(stdout); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define checkNvSciErrors(call) \
do { \
NvSciError _status = call; \
if (NvSciError_Success != _status) { \
printf("NVSCI call in file '%s' in line %i returned" \
" %d, expected %d\n", \
__FILE__, \
__LINE__, \
_status, \
NvSciError_Success); \
fflush(stdout); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define checkCudaDrvErrors(call) \
do { \
CUresult err = call; \
if (CUDA_SUCCESS != err) { \
const char *errorStr = NULL; \
cuGetErrorString(err, &errorStr); \
printf( \
"checkCudaDrvErrors() Driver API error" \
" = %04d \"%s\" from file <%s>, " \
"line %i.\n", \
err, errorStr, __FILE__, __LINE__); \
exit(EXIT_FAILURE); \
} \
} while (0)
do { \
CUresult err = call; \
if (CUDA_SUCCESS != err) { \
const char *errorStr = NULL; \
cuGetErrorString(err, &errorStr); \
printf("checkCudaDrvErrors() Driver API error" \
" = %04d \"%s\" from file <%s>, " \
"line %i.\n", \
err, \
errorStr, \
__FILE__, \
__LINE__); \
exit(EXIT_FAILURE); \
} \
} while (0)
extern void launchFlipSurfaceBitsKernel(cudaArray_t *levelArray, int32_t *multiPlanarWidth,
int32_t *multiPlanarHeight, int numPlanes);
extern void launchFlipSurfaceBitsKernel(cudaArray_t *levelArray,
int32_t *multiPlanarWidth,
int32_t *multiPlanarHeight,
int numPlanes);
class Caller {
class Caller
{
private:
NvSciBufAttrList attrListOut;
NvSciBufAttrList attrListOut;
NvSciBufAttrKeyValuePair pairArrayOut[ATTR_SIZE];
cudaExternalMemory_t extMem;
int32_t numPlanes;
cudaExternalMemory_t extMem;
int32_t numPlanes;
public:
NvSciBufAttrList attrList;
NvSciBufAttrList attrList;
cudaMipmappedArray_t multiPlanarArray[PLANAR_NUM_PLANES];
int32_t multiPlanarWidth[PLANAR_NUM_PLANES];
int32_t multiPlanarHeight[PLANAR_NUM_PLANES];
int32_t multiPlanarWidth[PLANAR_NUM_PLANES];
int32_t multiPlanarHeight[PLANAR_NUM_PLANES];
void init();
void deinit();
@@ -92,15 +100,17 @@ public:
};
class cudaNvSciBufMultiplanar {
class cudaNvSciBufMultiplanar
{
private:
size_t imageWidth;
size_t imageHeight;
int mCudaDeviceId;
int deviceCnt;
size_t imageWidth;
size_t imageHeight;
int mCudaDeviceId;
int deviceCnt;
NvSciBufAttrList attrList[2];
NvSciBufAttrList attrListReconciled;
NvSciBufAttrList attrListConflict;
public:
cudaNvSciBufMultiplanar(size_t imageWidth, size_t imageHeight, std::vector<int> &deviceIds);
void initCuda(int devId);
@@ -110,15 +120,15 @@ public:
};
enum NvSciBufImageAttributes {
PLANE_SIZE,
PLANE_SIZE,
PLANE_ALIGNED_SIZE,
PLANE_OFFSET,
PLANE_HEIGHT,
PLANE_WIDTH,
PLANE_CHANNEL_COUNT,
PLANE_HEIGHT,
PLANE_WIDTH,
PLANE_CHANNEL_COUNT,
PLANE_BITS_PER_PIXEL,
PLANE_COUNT,
PLANE_ATTR_SIZE
};
#endif // CUDA_NVSCIBUF_MULTIPLANAR_H
#endif // CUDA_NVSCIBUF_MULTIPLANAR_H

View File

@@ -27,13 +27,14 @@
#include <cuda.h>
#include <helper_cuda.h>
static __global__ void flipSurfaceBits(cudaSurfaceObject_t surfObj, int width, int height) {
char data;
static __global__ void flipSurfaceBits(cudaSurfaceObject_t surfObj, int width, int height)
{
char data;
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
if (x < width && y < height) {
// Read from input surface
surf2Dread(&data, surfObj, x, y);
surf2Dread(&data, surfObj, x, y);
// Write to output surface
data = ~data;
surf2Dwrite(data, surfObj, x, y);
@@ -41,24 +42,23 @@ static __global__ void flipSurfaceBits(cudaSurfaceObject_t surfObj, int width, i
}
// Copy cudaArray to surface memory and launch the CUDA kernel
void launchFlipSurfaceBitsKernel(
cudaArray_t *levelArray,
int32_t *multiPlanarWidth,
int32_t *multiPlanarHeight,
int numPlanes) {
void launchFlipSurfaceBitsKernel(cudaArray_t *levelArray,
int32_t *multiPlanarWidth,
int32_t *multiPlanarHeight,
int numPlanes)
{
cudaSurfaceObject_t surfObject[numPlanes] = {0};
cudaResourceDesc resDesc;
for (int i = 0; i < numPlanes; i++) {
cudaResourceDesc resDesc;
for (int i = 0; i < numPlanes; i++) {
memset(&resDesc, 0, sizeof(resDesc));
resDesc.resType = cudaResourceTypeArray;
resDesc.resType = cudaResourceTypeArray;
resDesc.res.array.array = levelArray[i];
checkCudaErrors(cudaCreateSurfaceObject(&surfObject[i], &resDesc));
dim3 threadsperBlock(16, 16);
dim3 numBlocks((multiPlanarWidth[i] + threadsperBlock.x - 1) / threadsperBlock.x,
(multiPlanarHeight[i] + threadsperBlock.y - 1) / threadsperBlock.y);
(multiPlanarHeight[i] + threadsperBlock.y - 1) / threadsperBlock.y);
flipSurfaceBits<<<numBlocks, threadsperBlock>>>(surfObject[i], multiPlanarWidth[i], multiPlanarHeight[i]);
}
}

View File

@@ -25,48 +25,48 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cuda.h>
#include <vector>
#include "cudaNvSciBufMultiplanar.h"
#include <helper_image.h>
#include <vector>
#include "cudaNvSciBufMultiplanar.h"
#define MAX_FILE_SIZE 100
int main(int argc, const char **argv) {
int numOfGPUs = 0;
std::vector<int> deviceIds;
(cudaGetDeviceCount(&numOfGPUs));
int main(int argc, const char **argv)
{
int numOfGPUs = 0;
std::vector<int> deviceIds;
(cudaGetDeviceCount(&numOfGPUs));
printf("%d GPUs found\n", numOfGPUs);
if (!numOfGPUs) {
exit(EXIT_WAIVED);
} else {
for (int devID = 0; devID < numOfGPUs; devID++) {
int major = 0, minor = 0;
(cudaDeviceGetAttribute(
&major, cudaDevAttrComputeCapabilityMajor, devID));
(cudaDeviceGetAttribute(
&minor, cudaDevAttrComputeCapabilityMinor, devID));
if (major >= 6) {
deviceIds.push_back(devID);
}
printf("%d GPUs found\n", numOfGPUs);
if (!numOfGPUs) {
exit(EXIT_WAIVED);
}
if (deviceIds.size() == 0) {
printf(
"cudaNvSciBufMultiplanar requires one or more GPUs of Pascal(SM 6.0) or higher "
"archs\nWaiving..\n");
exit(EXIT_WAIVED);
else {
for (int devID = 0; devID < numOfGPUs; devID++) {
int major = 0, minor = 0;
(cudaDeviceGetAttribute(&major, cudaDevAttrComputeCapabilityMajor, devID));
(cudaDeviceGetAttribute(&minor, cudaDevAttrComputeCapabilityMinor, devID));
if (major >= 6) {
deviceIds.push_back(devID);
}
}
if (deviceIds.size() == 0) {
printf("cudaNvSciBufMultiplanar requires one or more GPUs of Pascal(SM 6.0) or higher "
"archs\nWaiving..\n");
exit(EXIT_WAIVED);
}
}
}
std::string image_filename = sdkFindFilePath("yuv_planar_img1.yuv", argv[0]);
std::string image_filename_out = "image_out.yuv";
uint32_t imageWidth = 720;
uint32_t imageHeight = 480;
std::string image_filename = sdkFindFilePath("yuv_planar_img1.yuv", argv[0]);
std::string image_filename_out = "image_out.yuv";
uint32_t imageWidth = 720;
uint32_t imageHeight = 480;
printf("input image %s , width = %d, height = %d\n", image_filename.c_str(), imageWidth, imageHeight);
printf("input image %s , width = %d, height = %d\n", image_filename.c_str(), imageWidth, imageHeight);
cudaNvSciBufMultiplanar cudaNvSciBufMultiplanarApp(imageWidth, imageHeight, deviceIds);
cudaNvSciBufMultiplanarApp.runCudaNvSciBufPlanar(image_filename, image_filename_out);
cudaNvSciBufMultiplanar cudaNvSciBufMultiplanarApp(imageWidth, imageHeight, deviceIds);
cudaNvSciBufMultiplanarApp.runCudaNvSciBufPlanar(image_filename, image_filename_out);
return EXIT_SUCCESS;
}
return EXIT_SUCCESS;
}