deepstream-nvinferserver

nvinferserver的插件和底层库在DS6.3上开源了。这样nvinferserver和nvinfer推理就都开源了,有什么问题,可以直接调代码。

NvDsInferTensorMeta{

  /** Array of pointers to the output host buffers for the batch / frame / object. */

  void **out_buf_ptrs_host;

  /** Array of pointers to the output device buffers for the batch / frame / object. */

  void **out_buf_ptrs_dev;

  /** GPU device ID on which the device buffers have been allocated. */

}

问题1, out_buf_ptrs_host和out_buf_ptrs_dev在nvinfer和nvinferserver中有什么区别呢?

可以从插件层往底层查这个问题,在nvinfer中,赋值的地方是:

attach_tensor_output_meta{

    meta->out_buf_ptrs_host = new void *[meta->num_output_layers];

    meta->out_buf_ptrs_dev = new void *[meta->num_output_layers];

。。。。。。

      meta->out_buf_ptrs_dev[i] =

          (uint8_t *) batch_output->outputDeviceBuffers[i] +

          info.inferDims.numElements * get_element_size (info.dataType) * j;

      meta->out_buf_ptrs_host[i] =

          (uint8_t *) batch_output->hostBuffers[info.bindingIndex] +

          info.inferDims.numElements * get_element_size (info.dataType) * j;

。。。。。。

}

那就得去底层找outputDeviceBuffers和hostBuffers。

在InferPostprocessor::postProcessHost中,可以看到outputDeviceBuffers指向GPU的buffer。

        batchOutput.outputDeviceBuffers[i] =

            batch.m_DeviceBuffers[m_OutputLayerInfo[i].bindingIndex];

在InferPostprocessor::postProcessHost中,可以看到hostBuffers指向m_HostBuffers,那m_HostBuffers从哪里来?

        batchOutput.hostBuffers[i] =

            batch.m_HostBuffers[i] ? batch.m_HostBuffers[i]->ptr() : nullptr;

在InferPostprocessor::copyBuffersToHostMemory中,因为needOutputCopyB4Processing一直是true,所以必然进入如下判断,从m_DeviceBuffers中拷贝数据到m_HostBuffers。

if (!info.isInput && needOutputCopyB4Processing())

{

cudaMemcpyAsync(batch.m_HostBuffers[info.bindingIndex]->ptr(),

                    batch.m_DeviceBuffers[info.bindingIndex],

 } 

在nvinferserver中,逻辑是不一样的,在插件的attachTensorOutputMeta中,out_buf_ptrs_dev赋的空,只有out_buf_ptrs_host可用。

{

        void *bufPtr = buf->getBufPtr(batchIdx);

        meta->out_buf_ptrs_host[i] = bufPtr;

        meta->out_buf_ptrs_dev[i] = nullptr;

}

以为nvinferserver的CAPI为例,nvinferserver在做推理的时候,需要指定输出的回调函数,也就是TrtISBackend::allocateResponseBuf,在nvdsinferserver_common.proto中,可以找到输出buffer的支持的类型, triton默认输出gpubuffer类型。

/** Tensor memory type
 */
enum MemoryType {
  MEMORY_TYPE_DEFAULT = 0;
  MEMORY_TYPE_CPU = 1;
  MEMORY_TYPE_GPU = 2;
}

在memTypeFromDsProto中,会将配置转为内部类型。

memTypeFromDsProto(ic::MemoryType t)

{

    static const std::unordered_map sTypes{

        {ic::MEMORY_TYPE_DEFAULT, InferMemType::kNone},

        {ic::MEMORY_TYPE_CPU, InferMemType::kCpuCuda},

        {ic::MEMORY_TYPE_GPU, InferMemType::kGpuCuda},

    };

}

nvinerserver会强行想triton的返回值转成hostcpu类型,在InferCudaContext::acquireTensorHostBuf中创建hostbuffer, 在Postprocessor::postCudaImpl中,通过 cudaMemcpyAsync(outBufPtr, inBufPtr把gpubuffer拷贝到cpubuffer。

因为out_buf_ptrs_host指向的是hostcpu类型的buffer。

你可能感兴趣的:(deepstream,deepstream,计算机视觉)