2017-01-11 3 views
-1

Я задал сомнение error: calling a __host__ function from a __global__ function is not allowed, и я получил анс. соответственно, я изменил свой код bt, я не могу получить доступ к d_point [i]. как я могу получить доступ к этому.Ошибка: был обнаружен незаконный доступ к памяти

__global__ void densefun(int *d_counters,float2 *d_points,int d_x_max,int d_y_max,int width,int height, int min_distance,int size) 
{ 
    int i = blockDim.x * blockIdx.x + threadIdx.x; 

    if(i <= size) 
    { 
     float2 point = (d_points)[i]; 
     int x = floorf(point.x); 
     int y = floorf(point.y); 
     printf(" (%d %d)",x,y); 
     if(x < d_x_max && y < d_y_max) 
     { 
      x /= min_distance; 
      y /= min_distance; 
      (d_counters)[y*width+x]++; 
      __syncthreads(); 
     } 
    } 
} 


void DenseSample(const Mat& grey, std::vector<Point2f>& points, const double quality, const int min_distance) 
{ 
    int width = grey.cols/min_distance; 
    int height = grey.rows/min_distance; 
    Mat eig; 
    cornerMinEigenVal(grey, eig, 3, 3); 
    double maxVal = 0; 
    minMaxLoc(eig, 0, &maxVal); 
    const double threshold = maxVal*quality; 
    std::vector<int> counters(width*height); 
    int x_max = min_distance*width; 
    int y_max = min_distance*height; 
    printf("in descriptor size:%ld ",points.size()); 
    int *d_counters; 
    float2 *d_points; 
    cudaMalloc(&d_counters,counters.size()*width*height*sizeof(int)); 
    printf("in cuda point size:%d  ",points.size()); 
    cudaMalloc(&d_points,points.size()*sizeof(float2)); 
    cout<<"points.size() : "<<points.size()<<endl; 
    cudaMemcpy(d_points, &points, points.size()*sizeof(float2), cudaMemcpyHostToDevice); 
    int blk=cvFloor(points.size()/1024)+1; 
    cout<<"blk : "<<blk<<endl; 
    if(points.size()>0) 
    { 
     densefun<<<blk,1024>>>(d_counters,d_points,x_max,y_max,width,height,min_distance, points.size()); 
     cudaError_t err = cudaGetLastError(); 
     if (err != cudaSuccess) 
     printf("Error: %s\n", cudaGetErrorString(err)); 
     cudaMemcpy(&counters, d_counters, counters.size()* width*height*sizeof(int), cudaMemcpyDeviceToHost); 
    } 
    cudaFree(d_counters); 
    cudaFree(d_points); 
    points.clear(); 
    int index = 0; 
    int offset = min_distance/2; 
    for(int i = 0; i < height; i++) 
    for(int j = 0; j < width; j++, index++) 
    { 
     if(counters[index] <= 0) 
     { 
      int x = j*min_distance+offset; 
      int y = i*min_distance+offset; 
      if(eig.at<float>(y, x) > threshold) 
      points.push_back(Point2f(float(x), float(y))); 
     } 
    } 
} 

выхода: по размеру дескриптора : 1605 кегля CUDA: 1605 points.size(): 1605

BLK: 2 Ошибка: незаконный доступ к памяти был обнаружен размера дескриптора: 918 кегля Cuda: 918 points.size(): 918

BLK: 1 ошибки: нелегальный доступ к памяти был обнаружен

+0

Как вы знаете, что доступ к d_points на самом деле является причиной проблемы? – talonmies

+1

Я предполагаю, что вы хотите проверить, должны ли 'x' и' y' быть в пределах ограничений соответственно 'd_x_max' и' d_y_max'. Не следует «if (x pSoLT

+0

Доступ к d_points является причиной проблемы, потому что я попытался напечатать значение x и y, он не печатается. Я пытался, если (x

ответ

1

Вы создаете нить ГИРД с блоком длина 1024 и длина сетки равна

int blk=cvFloor(points.size()/1024)+1;

Который в основном означает, что число потоков будет кратно 1024 больше, чем points.size(). В этом случае с помощью:

int i = blockDim.x * blockIdx.x + threadIdx.x; 
float2 point = (d_points)[i]; 

не может быть успешным, потому что вы можете быть почти уверены, что вы получите из доступа границы памяти. Добавьте условное условие, чтобы этого не произошло.

__global__ void densefun(int *d_counters,float2 *d_points,int d_x_max,int d_y_max,int width, int height, int min_distance) 
{ 
    int i = blockDim.x * blockIdx.x + threadIdx.x; 
    if(i < width * height) 
    { 
     //rest of the code 
    } 

} 

Кроме того, вы не выделяют enugh памяти d_points:

float2 *d_points; 

cudaMalloc(&d_points,points.size()*sizeof(float)); 

Если вы хотите выделить массив float2 (или скопировать на него), необходимо использовать sizeof(float2).

+0

Извините, что редактировал, я неправильно понял, что вы пытались сказать вокруг блока кода. – talonmies

+0

Нет проблем, спасибо за другую часть редактирования! – pSoLT

+0

Спасибо за ан. это было полезно. Добавление условия работает, но только для первой итерации в следующей итерации. –

Смежные вопросы