Я застрял с проблемой, чтобы этот цикл итераторов работал на 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 ??
}
Во-первых, я заметил, что ваша программа состоит из перемещения vector<KeyPoint>
в vector<Point2f>
состав. У OpenCV есть действительно хороший однострочный текст, чтобы сделать это для вас:
using namespace cv;
KeyPoint::convert(key_pts1, points1); //vector<KeyPoint> to vector<Point2f>
Теперь поговорим о графических процессорах. Оказывается, что 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
Сейчас, device_matches
это просто массив C, а не вектор STL. Итак, у вас нет итераторов. Вместо этого вы должны просто использовать обычные индексы массива. Если вы действительно хотите итераторы на GPU, посмотрите на Библиотека тяги. Thrust действительно удобен, но недостатком является то, что Thrust предоставляет только определенный набор предварительно запеченных функций.
Главный вопрос заключается в том, хотите ли вы выполнить эту конкретную часть вашей программы на графическом процессоре. Я бы порекомендовал использовать GPU для действительно ресурсоемких задач (например, для фактического сопоставления объектов), но перемещение данных между форматами данных (как в коде вашего примера) на много порядков дешевле, чем сопоставление объектов.
Кроме того, имейте в виду, что вам часто приходится структурировать данные на GPU иначе, чем на CPU. Эта реструктуризация не обязательно требует больших вычислительных затрат, но вам нужно выделить некоторое время, чтобы проработать ее на доске, вырвать волосы и т. Д. Наконец, если вы серьезно относитесь к графическим процессорам, возможно, стоит поработать через несколько простых примеров программирования на GPU (я наслаждался Доктор Доббс Суперкомпьютинг для Масс), посещая GPU / параллельный класс или разговаривая с друзьями-GPU-хакерами.
Других решений пока нет …