An illegal memory access was encountered ||| CUDA
Пишу программу, которая решает СЛАУ методом Гаусса. Решается она на процессоре и на видеокарте с целью замерить скорость вычислений. На процессоре все работает отлично. Но вот с видеокартой некоторые проблемы. Снизу в коде помечены комментарием методы, которые генерируют ошибку "an illegal memory access was encountered". Я делал все по образцу сложения векторов, по крайней мере старался. Проверил, что за грани массивов, с которыми работают функции на стороне видеокарты, ничего не заходит, вторжения в чужую память вроде как нет. Подскажите, пожалуйста, в чем моя проблема?
void FillMatrix(double **a1, double *b1, double **a2, double *b2, int n) {
cout << "Коэффициенты и свободные члены:" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
a1[i][j] = rand() % 1000;
a2[i][j] = a1[i][j];
//cout << "a[" << i << "," << j << "] = " << a1[i][j] << endl;
//cin >> a[i][j];
}
b1[i] = rand() % 1000;
b2[i] = b1[i];
//cout << "y[" << i << "] = " << b1[i] << endl;
//cin >> b[i];
}
}
__global__ void DirectMoveMP(double **a, double *b, int *n) {
int idx = threadIdx.x + blockIdx.x * blockDim.x;
double d;
if (idx < *n && idx > -1) {
for (int j = idx + 1; j < *n; j++)
{
d = a[j][idx] / a[idx][idx]; // формула (1)
for (int i = idx; i < *n; i++)
{
a[j][i] = a[j][i] - d * a[idx][i]; // формула (2)
}
b[j] = b[j] - d * b[idx]; // формула (3)
}
}
//cudaDeviceSynchronize();
}
__global__ void InversMoveMP(double **a, double *x, double *b, int *n) {
//int idx = *n - threadIdx.x - 1;
int idx = threadIdx.x + blockIdx.x * blockDim.x;
double d, s;
if (idx >= 0 && idx < *n) {
d = 0;
for (int j = idx + 1; j < *n; j++)
{
s = a[idx][j] * x[j]; // формула (4)
d = d + s; // формула (4)
}
x[idx] = (b[idx] - d) / a[idx][idx]; // формула (4)
}
//cudaDeviceSynchronize();
}
int main()
{
srand(time(NULL));
setlocale(LC_ALL, "ru");
int n;
cout << "Порядок: ";
cin >> n;
double **a1 = new double *[n+1];
double **a2 = new double *[n+1];
for (int i = 0; i < n; i++) {
a1[i] = new double[n+1];
a2[i] = new double[n+1];
}
double *b1 = new double[n+1];
double *b2 = new double[n+1];
double *x1 = new double[n+1];
double *x2 = new double[n+1];
FillMatrix(a1, b1, a2, b2, n);
double **dev_a2 = 0, *dev_b2 = 0, *dev_x2 = 0;
int *dev_n = 0;
int size = sizeof(double)*n;
cudaSetDevice(0);
cudaError_t cudaStatus;
cudaMalloc((void**)&dev_a2, size*n);
cudaMalloc((void**)&dev_b2, size);
cudaMalloc((void**)&dev_x2, size);
cudaMalloc((void**)&dev_n, sizeof(int));
cudaMemcpy(dev_a2, a2, size*n, cudaMemcpyKind::cudaMemcpyHostToDevice);
cudaMemcpy(dev_b2, b2, size, cudaMemcpyKind::cudaMemcpyHostToDevice);
cudaMemcpy(dev_n, &n, sizeof(int), cudaMemcpyKind::cudaMemcpyHostToDevice);
cudaDeviceSynchronize();
int threadsPerBlock = 1024;
int blocksPerGrid = (n + threadsPerBlock - 1) / threadsPerBlock;
cudaEvent_t start, stop;
float time = 1;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
//-------------------GPU------------------------------------
DirectMoveMP << <blocksPerGrid, threadsPerBlock >> > (dev_a2, dev_b2, dev_n);
cudaDeviceSynchronize();
InversMoveMP << <blocksPerGrid, threadsPerBlock >> > (dev_a2, dev_x2, dev_b2, dev_n);
//----------------------------------------------------------
cudaStatus = cudaDeviceSynchronize();
if (cudaStatus == cudaSuccess) {
printf("All is ok");
}
cudaEventRecord(stop, 0);
cudaStatus = cudaEventElapsedTime(&time, start, stop);
if(cudaStatus != cudaSuccess) {
printf("\nError 'cudaEventElapsedTime': %s\n\n", cudaGetErrorString(cudaStatus));
} // ТУТ ОШИБКА an illegal memory access was encountered
printf("Time to generate: %3.1f ms \n\n", time);
cudaStatus = cudaMemcpy(x2, dev_x2, size, cudaMemcpyKind::cudaMemcpyDeviceToHost);// ТУТ ОШИБКА an illegal memory access was encountered
if (cudaStatus != cudaSuccess) {
printf("Error'cudaMemcpy(...,cudaMemcpyKind::cudaMemcpyDeviceToHost)': %s\n\n", cudaGetErrorString(cudaStatus));
}
cudaDeviceSynchronize();
unsigned int startCPU = clock();
//-----------CPU-------------
DirectMove(a1, b1, n);
InversMove(a1, x1, b1, n);
//---------------------------
unsigned int stopCPU = clock();
cout << "Время на CPU: " << (stopCPU-startCPU)/1000000.0 << " с" << endl;
cout << "Решение системы(CPU): " << endl;
//for (int i = 0; i < n; i++) cout << "x[" << i << "] = " << x1[i] << " " << endl;
cout << "Решение системы(GPU): " << endl;
//for (int i = 0; i < n; i++) cout << "x[" << i << "] = " << x2[i] << " " << endl;
cudaFree(dev_a2);
cudaFree(dev_b2);
cudaFree(dev_x2);
cudaFree(dev_n);
return 0;
}
Ответы (1 шт):
Ну а что вы делаете здесь?:
cudaMalloc((void**)&dev_a2, size*n);
cudaMalloc((void**)&dev_b2, size);
cudaMalloc((void**)&dev_x2, size);
cudaMalloc((void**)&dev_n, sizeof(int));
cudaMemcpy(dev_a2, a2, size*n, cudaMemcpyKind::cudaMemcpyHostToDevice);
cudaMemcpy(dev_b2, b2, size, cudaMemcpyKind::cudaMemcpyHostToDevice);
cudaMemcpy(dev_n, &n, sizeof(int), cudaMemcpyKind::cudaMemcpyHostToDevice);
Вы понимаете что куда копируете? Вы понимаете, что a2 это массив указателей? Вы не можете использовать указатели на память выделенную на cpu с gpu (если только это у вас не встроенная видеокарта)
UPD чтобы исправить проблему вам нужно всего-то скопировать данные, а не укзатели на них