У меня есть программа на C, чтобы определить, перекрываются ли 2 набора полигонов. Пользователь вводит 2 набора полигонов (каждый набор данных содержит несколько тысяч полигонов), и программа видит, какой полигон в наборе 1 перекрывается с каким полигоном в наборе 2.
У меня есть 2 структуры, подобные этим:
struct gpc_vertex /* Polygon vertex */
{
double x;
double y;
};
struct gpc_vertex_list /* Polygon contour */
{
int pid; // polygon id
int num_vertices;
double *mbr; // minimum bounding rectangle of the polygon, so always 4 elements
};
У меня есть следующий сегмент кода:
#pragma acc kernels copy(listOfPolygons1[0:polygonCount1], listOfPolygons2[0:polygonCount2], listOfBoolean[0:dump])
for (i=0; i<polygonCount1; i++){
polygon1 = listOfPolygons1[i];
for (j=0; j<polygonCount2; j++){
polygon2 = listOfPolygons2[j];
idx = polygonCount2 * i + j;
listOfBoolean[idx] = isRectOverlap(polygon1.mbr, polygon2.mbr); // line 115
}
}
listOfPolygons1 и listOfPolygons2 (как следует из названия) представляют собой массив gpc_vertex_list. listOfBoolean — это массив целых чисел.
mbr двух полигонов проверяется, чтобы увидеть, не перекрываются ли они, и функция «isRectOverlap» возвращает 1, если они перекрываются, 0, если нет, и помещает значение в listOfBoolean
Проблема
Код компилируется, но не запускается. Он возвращает следующую ошибку:
call to cuEventSynchronize returned error 700: Illegal address during kernel execution
Мое наблюдение
Программа может быть скомпилирована и запущена, если изменить строку 115 на следующую:
isRectOverlap(polygon1.mbr, polygon2.mbr); // without assigning value to listOfBoolean
или это:
listOfBoolean[idx] = 5; // assigning an arbitrary value
(правда результат неверный, но по крайней мере запустить можно)
Вопрос
Кажется, что и "isRectOverlap", и "listOfBoolean" не создают проблемы, если значение не передается из "isRectOverlap" в "listOfBoolean"
Кто-нибудь знает, почему это не может запустить, если я назначу возвращаемое значение из "isRectOverlap" в "listOfBoolean"?
isRectOverlap выглядит следующим образом:
int isRectOverlap(double *shape1, double *shape2){
if (shape1[0] > shape2[2] || shape2[0] > shape1[2]){
return 0;
}
if (shape1[1] < shape2[3] || shape2[1] < shape1[3]){
return 0;
}
return 1;
}
У программы нет проблем, когда она не работает в OpenACC.
Спасибо за помощь
cuEventSynchronize
, который для меня выглядит как cuda.... Ну, я могу ошибаться, так как я не знаком с этим OpenACC - person Eugene Sh.   schedule 05.08.2016