diff --git a/AIEngineModule/src/AIModel_Impl.cpp b/AIEngineModule/src/AIModel_Impl.cpp index 7da8b7a..2ccb1e4 100644 --- a/AIEngineModule/src/AIModel_Impl.cpp +++ b/AIEngineModule/src/AIModel_Impl.cpp @@ -265,14 +265,15 @@ int AIModel_Impl::AIDet(const cv::Mat &inImg, cv::Mat &outimg) { outimg.create(m_pNode_output_0->height, m_pNode_output_0->width, outType); } + // 推理前清零输出:任何一步失败时,保证输出全黑而非未初始化垃圾数据 + outimg.setTo(0); uchar *p_outdata_1 = (uchar *)outimg.data; if (!m_bInitSuccess) { return 2; } - AI_Det_In_1_Out_1(m_pNode_input_0, m_pNode_output_0, p_indata_0, p_outdata_1); - return 0; + return AI_Det_In_1_Out_1(m_pNode_input_0, m_pNode_output_0, p_indata_0, p_outdata_1); } int AIModel_Impl::AIDet(const cv::Mat &inImg, cv::Mat &outimg0, cv::Mat &outimg1) @@ -553,38 +554,89 @@ int AIModel_Impl::GetEngineInfo1(std::shared_ptr &pgpuengine) int AIModel_Impl::AI_Det_In_1_Out_1(Node_Config *pConfig_in, Node_Config *pConfig_out, const unsigned char *p_indata_0, unsigned char *p_outdata_1) { - // printf("=== s1 "); std::shared_ptr pdetStream; if (GetStream(pdetStream) != 0 || !pdetStream) { return -1; } - // printf("=== s2 "); std::lock_guard lock(pdetStream->AI_mutex); - // printf(" ss g %d s %d -- ", pdetStream->nGPUIdx, pdetStream->cuda_stream->nstreamIdx); - // // 设置 显卡ID + // 设置 显卡ID if (!EnsureCudaDevice(pdetStream->nGPUIdx)) { return -1; } - cudaMemcpyAsync(pdetStream->cuda_stream->pstreamNode_input_0->gpu_ImgData, - p_indata_0, pConfig_in->ucharsize, cudaMemcpyHostToDevice, pdetStream->cuda_stream->stream); - // // // 在显存中 图片数据从 uchar 转到 float - Cuda_ucharToFloat_stream((unsigned char *)pdetStream->cuda_stream->pstreamNode_input_0->gpu_ImgData, - (float *)pdetStream->cuda_stream->pstreamNode_input_0->gpu_buffers, pConfig_in->datalength, pdetStream->cuda_stream->stream); + cudaStream_t stream = pdetStream->cuda_stream->stream; + void *gpu_in_ImgData = pdetStream->cuda_stream->pstreamNode_input_0->gpu_ImgData; + void *gpu_in_buffers = pdetStream->cuda_stream->pstreamNode_input_0->gpu_buffers; + void *gpu_out_buffers = pdetStream->cuda_stream->pstreamNode_output_0->gpu_buffers; + void *gpu_out_ImgData = pdetStream->cuda_stream->pstreamNode_output_0->gpu_ImgData; - pdetStream->cuda_stream->context->setTensorAddress(pConfig_in->name.c_str(), pdetStream->cuda_stream->pstreamNode_input_0->gpu_buffers); - pdetStream->cuda_stream->context->setTensorAddress(pConfig_out->name.c_str(), pdetStream->cuda_stream->pstreamNode_output_0->gpu_buffers); + cudaError_t cerr; - pdetStream->cuda_stream->context->enqueueV3(pdetStream->cuda_stream->stream); + // 推理前先把输出显存清零:任何一步失败时,保证输出全黑而非未初始化垃圾数据 + cerr = cudaMemsetAsync(gpu_out_ImgData, 0, pConfig_out->ucharsize, stream); + if (cerr != cudaSuccess) + { + std::fprintf(stderr, "[AIEngine] cudaMemsetAsync(out) failed: %s\n", cudaGetErrorString(cerr)); + return -1; + } - Cuda_FloatTouchar_stream((float *)pdetStream->cuda_stream->pstreamNode_output_0->gpu_buffers, - (unsigned char *)pdetStream->cuda_stream->pstreamNode_output_0->gpu_ImgData, pConfig_out->datalength, pdetStream->cuda_stream->stream); - cudaMemcpyAsync(p_outdata_1, pdetStream->cuda_stream->pstreamNode_output_0->gpu_ImgData, - pConfig_out->ucharsize, cudaMemcpyDeviceToHost, pdetStream->cuda_stream->stream); - cudaStreamSynchronize(pdetStream->cuda_stream->stream); - // printf("**ee g %d s %d ** \n", pdetStream->nGPUIdx, pdetStream->cuda_stream->nstreamIdx); + // 输入数据拷贝到显存 + cerr = cudaMemcpyAsync(gpu_in_ImgData, p_indata_0, pConfig_in->ucharsize, cudaMemcpyHostToDevice, stream); + if (cerr != cudaSuccess) + { + std::fprintf(stderr, "[AIEngine] cudaMemcpyAsync(in) failed: %s\n", cudaGetErrorString(cerr)); + return -1; + } + + // 在显存中 图片数据从 uchar 转到 float + Cuda_ucharToFloat_stream((unsigned char *)gpu_in_ImgData, + (float *)gpu_in_buffers, pConfig_in->datalength, stream); + + if (!pdetStream->cuda_stream->context->setTensorAddress(pConfig_in->name.c_str(), gpu_in_buffers)) + { + std::fprintf(stderr, "[AIEngine] setTensorAddress(in) failed\n"); + return -1; + } + if (!pdetStream->cuda_stream->context->setTensorAddress(pConfig_out->name.c_str(), gpu_out_buffers)) + { + std::fprintf(stderr, "[AIEngine] setTensorAddress(out) failed\n"); + return -1; + } + + if (!pdetStream->cuda_stream->context->enqueueV3(stream)) + { + std::fprintf(stderr, "[AIEngine] enqueueV3 failed\n"); + return -1; + } + + // float 转到 uchar + Cuda_FloatTouchar_stream((float *)gpu_out_buffers, + (unsigned char *)gpu_out_ImgData, pConfig_out->datalength, stream); + + cerr = cudaMemcpyAsync(p_outdata_1, gpu_out_ImgData, + pConfig_out->ucharsize, cudaMemcpyDeviceToHost, stream); + if (cerr != cudaSuccess) + { + std::fprintf(stderr, "[AIEngine] cudaMemcpyAsync(out) failed: %s\n", cudaGetErrorString(cerr)); + return -1; + } + + cerr = cudaStreamSynchronize(stream); + if (cerr != cudaSuccess) + { + std::fprintf(stderr, "[AIEngine] cudaStreamSynchronize failed: %s\n", cudaGetErrorString(cerr)); + return -1; + } + + // kernel 启动失败等异步错误必须通过 cudaGetLastError 捕获 + cerr = cudaGetLastError(); + if (cerr != cudaSuccess) + { + std::fprintf(stderr, "[AIEngine] async cuda error: %s\n", cudaGetErrorString(cerr)); + return -1; + } return 0; }