Após os testes com o a biblioteca CUDA 4.1 RC 2 GPU conforme o post anterior, agora compilei a openCV também com a lib TBB e CUDA. Resultado: Performance computacional além da imaginação. Tudo isto em função da programação paralela. Escrito em C++.O TBB se encarrega na adaptação do software, ou seja determinando o número ideal de threads e tornando uma realidade a programação multinúcleo.
Deixo neste post, as alterações necessárias no código fonte da bibliotec openCV 2.3.1 para compilara com o gcc 4.6.2 no openSUSE 12.1 e com a biblioteca CUDA 4.1.
No arquivo modules/gpu/src/imgproc.cpp: Linha 762:
Trocar:
ppSafeCall( nppiRectStdDev_32s32f_C1R(src.ptr<Npp32s>(), static_cast<int>(src.step), sqr.ptr<Npp32f>(), static_cast<int>(sqr.step), dst.ptr<Npp32f>(), static_cast<int>(dst.step), sz, nppRect) );
Por:
nppSafeCall( nppiRectStdDev_32s32f_C1R(src.ptr<Npp32s>(), static_cast<int>(src.step), sqr.ptr<Npp64f>(), static_cast<int>(sqr.step), dst.ptr<Npp32f>(), static_cast<int>(dst.step), sz, nppRect) ); No arquivo modules/gpu/src/graphcuts.cpp linha 80 Trocar: nppSafeCall( nppiGraphcut_32s8u(terminals.ptr<Npp32s>(), leftTransp.ptr<Npp32s>(), rightTransp.ptr<Npp32s>(), top.ptr<Npp32s>(), bottom.ptr<Npp32s>(), static_cast<int>(terminals.step), static_cast<int>(leftTransp.step), sznpp, labels.ptr<Npp8u>(), static_cast<int>(labels.step), buf.ptr<Npp8u>()) ); Por: nppSafeCall( nppiGraphcut_32s8u(terminals.ptr<Npp32s>(), leftTransp.ptr<Npp32s>(), rightTransp.ptr<Npp32s>(), top.ptr<Npp32s>(), bottom.ptr<Npp32s>(), static_cast<int>(terminals.step), static_cast<int>(leftTransp.step), sznpp, labels.ptr<Npp8u>(), static_cast<int>(labels.step), pState) ); Inserir na linha 67 NppiGraphcutState *pState; Npp8u *pDeviceMem; Adicionar o linha 75 abaixo da funcao nppSafeCall cudaSafeCall( cudaMalloc((void **)& pDeviceMem, bufsz) ); Comentar a linha 78 //if ((size_t)bufsz > buf.cols * buf.rows * buf.elemSize()) // buf.create(1, bufsz, CV_8U); Inserir na linha 80 após o comentário. nppSafeCall( nppiGraphcutInitAlloc(sznpp, &pState, pDeviceMem) ); No final do metodo cv::gpu::graphcut, linha 91 inserir nppSafeCall ( nppiGraphcutFree(pState)); cudaSafeCall( cudaFree(pDeviceMem) ); No arquivo modules/gpu/src/element_operations.cpp Comente as linhas 297 ate a 304 // case CV_8UC4: // nppSafeCall( nppiAbsDiff_8u_C4R(src1.ptr<Npp8u>(), static_cast<int>(src1.step), src2.ptr<Npp8u>(), static_cast<int>(src2.step), // dst.ptr<Npp8u>(), static_cast<int>(dst.step), sz) ); // break; // case CV_16UC1: // nppSafeCall( nppiAbsDiff_16u_C1R(src1.ptr<Npp32s>(), static_cast<int>(src1.step), src2.ptr<Npp32s>(), static_cast<int>(src2.step), // dst.ptr<Npp32s>(), static_cast<int>(dst.step), sz) ); // break; No arquivo modules/gpu/src/matrix_reductions.cpp Inserir na linha 117 int nBufferSize; nppiMeanStdDev8uC1RGetBufferHostSize (sz, &nBufferSize); Npp8u * pDeviceBuffer; cudaSafeCall( cudaMalloc((void **)& pDeviceBuffer, nBufferSize) ); Modificar a linha 124 Trocar: nppSafeCall( nppiMean_StdDev_8u_C1R(src.ptr<Npp8u>(), static_cast<int>(src.step), sz, dbuf, (double*)dbuf + 1) ); Por: nppSafeCall( nppiMean_StdDev_8u_C1R(src.ptr<Npp8u>(), static_cast<int>(src.step), sz, pDeviceBuffer, dbuf, (double*)dbuf + 1) ); Modificar a linha 126 Trocar: cudaSafeCall( cudaDeviceSynchronize() ); Por: cudaSafeCall( cudaFree(pDeviceBuffer) );