cvcuda_utils.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "ultra_infer/vision/common/processors/cvcuda_utils.h"
  15. namespace ultra_infer {
  16. namespace vision {
  17. #ifdef ENABLE_CVCUDA
  18. nvcv::ImageFormat CreateCvCudaImageFormat(FDDataType type, int channel,
  19. bool interleaved) {
  20. FDASSERT(channel == 1 || channel == 3 || channel == 4,
  21. "Only support channel be 1/3/4 in CV-CUDA.");
  22. if (type == FDDataType::UINT8) {
  23. if (channel == 1) {
  24. return nvcv::FMT_U8;
  25. } else if (channel == 3) {
  26. return (interleaved ? nvcv::FMT_BGR8 : nvcv::FMT_BGR8p);
  27. } else {
  28. return (interleaved ? nvcv::FMT_BGRA8 : nvcv::FMT_BGRA8p);
  29. }
  30. } else if (type == FDDataType::FP32) {
  31. if (channel == 1) {
  32. return nvcv::FMT_F32;
  33. } else if (channel == 3) {
  34. return (interleaved ? nvcv::FMT_BGRf32 : nvcv::FMT_BGRf32p);
  35. } else {
  36. return (interleaved ? nvcv::FMT_BGRAf32 : nvcv::FMT_BGRAf32p);
  37. }
  38. }
  39. FDASSERT(false, "Data type of %s is not supported.", Str(type).c_str());
  40. return nvcv::FMT_BGRf32;
  41. }
  42. std::shared_ptr<nvcv::TensorWrapData>
  43. CreateCvCudaTensorWrapData(const FDTensor &tensor, Layout layout) {
  44. FDASSERT(tensor.shape.size() == 3, "When create CVCUDA tensor from FD tensor,"
  45. "tensor shape should be 3-Dim,");
  46. int batchsize = 1;
  47. int h = tensor.Shape()[0];
  48. int w = tensor.Shape()[1];
  49. int c = tensor.Shape()[2];
  50. nvcv::TensorDataStridedCuda::Buffer buf;
  51. buf.strides[3] = FDDataTypeSize(tensor.Dtype());
  52. buf.strides[2] = c * buf.strides[3];
  53. buf.strides[1] = w * buf.strides[2];
  54. buf.strides[0] = h * buf.strides[1];
  55. if (layout == Layout::CHW) {
  56. c = tensor.Shape()[0];
  57. h = tensor.Shape()[1];
  58. w = tensor.Shape()[2];
  59. buf.strides[3] = FDDataTypeSize(tensor.Dtype());
  60. buf.strides[2] = w * buf.strides[3];
  61. buf.strides[1] = h * buf.strides[2];
  62. buf.strides[0] = c * buf.strides[1];
  63. }
  64. buf.basePtr = reinterpret_cast<NVCVByte *>(const_cast<void *>(tensor.Data()));
  65. nvcv::Tensor::Requirements req = nvcv::Tensor::CalcRequirements(
  66. batchsize, {w, h},
  67. CreateCvCudaImageFormat(tensor.Dtype(), c, layout == Layout::HWC));
  68. nvcv::TensorDataStridedCuda tensor_data(
  69. nvcv::TensorShape{req.shape, req.rank, req.layout},
  70. nvcv::DataType{req.dtype}, buf);
  71. return std::make_shared<nvcv::TensorWrapData>(tensor_data, nullptr);
  72. }
  73. void *GetCvCudaTensorDataPtr(const nvcv::TensorWrapData &tensor) {
  74. auto data =
  75. dynamic_cast<const nvcv::ITensorDataStridedCuda *>(tensor.exportData());
  76. return reinterpret_cast<void *>(data->basePtr());
  77. }
  78. nvcv::ImageWrapData CreateImageWrapData(const FDTensor &tensor) {
  79. FDASSERT(tensor.shape.size() == 3,
  80. "When create CVCUDA image from FD tensor,"
  81. "tensor shape should be 3-Dim, HWC layout");
  82. int h = tensor.Shape()[0];
  83. int w = tensor.Shape()[1];
  84. int c = tensor.Shape()[2];
  85. nvcv::ImageDataStridedCuda::Buffer buf;
  86. buf.numPlanes = 1;
  87. buf.planes[0].width = w;
  88. buf.planes[0].height = h;
  89. buf.planes[0].rowStride = w * c * FDDataTypeSize(tensor.Dtype());
  90. buf.planes[0].basePtr =
  91. reinterpret_cast<NVCVByte *>(const_cast<void *>(tensor.Data()));
  92. nvcv::ImageWrapData nvimg{nvcv::ImageDataStridedCuda{
  93. nvcv::ImageFormat{CreateCvCudaImageFormat(tensor.Dtype(), c)}, buf}};
  94. return nvimg;
  95. }
  96. void CreateCvCudaImageBatchVarShape(std::vector<FDTensor *> &tensors,
  97. nvcv::ImageBatchVarShape &img_batch) {
  98. for (size_t i = 0; i < tensors.size(); ++i) {
  99. FDASSERT(tensors[i]->device == Device::GPU, "Tensor must on GPU.");
  100. img_batch.pushBack(CreateImageWrapData(*(tensors[i])));
  101. }
  102. }
  103. NVCVInterpolationType CreateCvCudaInterp(int interp) {
  104. // CV-CUDA Interp value is compatible with OpenCV
  105. auto nvcv_interp = NVCVInterpolationType(interp);
  106. // Due to bug of CV-CUDA CUBIC resize, will force to convert CUBIC to LINEAR
  107. if (nvcv_interp == NVCV_INTERP_CUBIC) {
  108. return NVCV_INTERP_LINEAR;
  109. }
  110. return nvcv_interp;
  111. }
  112. #endif
  113. } // namespace vision
  114. } // namespace ultra_infer