0

このイテレータのループを CUDA で動作させるには問題があります。誰でもここで助けることができますか?

std::vector<cv::DMatch>  matches;
std::vector<cv::KeyPoint> key_pts1, key_pts2;
std::vector<cv::Point2f> points1, points2;
for (std::vector<cv::DMatch>::const_iterator itr = matches.begin(); itr!= matches.end(); ++it) 
        {                   
            float x = key_pts1[itr->queryIdx].pt.x;
            float y = key_pts1[itr->queryIdx].pt.y;
            points1.push_back(cv::Point2f(x,y));                
            x = key_pts2[itr->trainIdx].pt.x;
            y = key_pts2[itr->trainIdx].pt.y;
            points2.push_back(cv::Point2f(x,y));            
        }

上記の CUDA への変換 - 並列処理は、私には非常に難しいと思われます。

void dmatchLoopHomography(float *itr, float *match_being, float *match_end, float      *keypoint_1, float *keypoint_2, float *pts1, float *pts2)
{
float x, y;
// allocate memory in GPU memory
unsigned char *mtch_begin, *mtch_end, *keypt_1, *keypt_2, points1, *points2; 
cudaHostGetDevicePointer(&mtch_begin, match_being, 0);
cudaHostGetDevicePointer(&mtch_end, match_end, 0);
cudaHostGetDevicePointer(&keypt_1, keypoint_1, 0);
cudaHostGetDevicePointer(&keypt_2, keypoint_2, 0);
cudaHostGetDevicePointer(&points1, pts1, 0);
cudaHostGetDevicePointer(&points2, pts2, 0);

//dim3 blocks(16, 16); 
dim3 threads(itr, itr); 
//kernal
dmatchLoopHomography_ker<<<itr,itr>>>(mtch_begin, mtch_end, keypt_1, keypt_2, points1. points2)
cudaThreadSynchronize();    
}

 __global__ void dmatchLoopHomography_ker(float *itr, float *match_being, float *match_end, float *keypoint_1, float *keypoint_2, float *pts1, float *pts2)
{
 //how do I go about it ??
}
4

1 に答える 1

2

最初に、あなたのプログラムはvector<KeyPoint>a をvector<Point2f>構造体に移動することで構成されていることに気付きました。OpenCV には、これを行うための非常に優れたワンライナーがあります。

using namespace cv;
KeyPoint::convert(key_pts1, points1); //vector<KeyPoint> to vector<Point2f>

さて、GPU の話をしましょう。cudaHostGetDevicePointer()メモリを割り当てていないことがわかりました。cudaMalloc()メモリの割り当てが必要になります。例えば:

//compile with nvcc, not gcc
float* device_matches;
int match_length = matches.end() - matches.begin();
cudaMalloc(&device_matches, match_length*sizeof(float));
//do the same as above for key_pts1, key_pts2, points1, and points2

は、STL ベクトルでdevice_matchesはなく、単純な C 配列です。したがって、イテレータはありません。代わりに、通常の配列インデックスを使用する必要があります。本当に GPU でイテレータが必要な場合は、Thrust ライブラリを参照してください。Thrust は非常に便利ですが、欠点は、Thrust が事前に作成された関数の特定のセットしか提供しないことです。


より大きな問題は、プログラムのこの特定の部分を GPU で実行するかどうかです。本当に計算集約的なもの (たとえば、実際の機能マッチング) には GPU を使用することをお勧めしますが、(サンプル コードのように) データ形式間でデータを移動することは、機能マッチングよりも桁違いに安価です。

また、多くの場合、GPU では CPU とは異なる方法でデータを構造化する必要があることに注意してください。この再構築は、必ずしも計算コストがかかるわけではありませんが、ホワイトボードで作業したり、髪の毛をかきむしったりする時間を取っておく必要があります。いくつかの単純な GPU プログラミングの例 ( Dr. Dobbs Supercomputing for the Masses チュートリアルを楽しんだ)、GPU/並列クラスを受講する、または GPU ハッカーの友人と話すことを通じて。

于 2012-11-10T06:03:52.727 に答える