Проблема в простом коде CUDA, передающем сложные данные с хоста на устройство

У меня есть следующий код, скопированный из Интернета, и я пытаюсь скомпилировать на сервере с установленной Tesla C2075, должен поддерживать двойную точность, я также компилирую код с флагом sm_20

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cuda_runtime.h>
#include <cuComplex.h>
#include <cublas_v2.h>

using namespace std;

typedef double2 Complex;

#define m 1024
#define n 300
#define k 1024

int main(int argc, char *argv[])
{
Complex _A[m*k], _B[k*n];
Complex *A, *B;

cudaMalloc((void**)&A, m*k*sizeof(Complex));
cudaMalloc((void**)&B, k*n*sizeof(Complex));

for (int i=0; i<m*k; i++) _A[i] = make_cuDoubleComplex(rand()/(double)RAND_MAX, rand()/(double)RAND_MAX);;
for (int i=0; i<k*n; i++) _B[i] = make_cuDoubleComplex(rand()/(double)RAND_MAX, rand()/(double)RAND_MAX);

cudaMemcpy( A, _A, (m*k)*sizeof(Complex), cudaMemcpyHostToDevice );
cudaMemcpy( B, _B, (k*n)*sizeof(Complex), cudaMemcpyHostToDevice );

return 0;
}

Он компилируется, но во время выполнения всегда возвращает «Ошибка сегментации (дамп памяти)». Это что-то не так с кодом? Благодарю.

0

Решение

Ваши массивы _A а также _B скорее всего, слишком велики для размещения в стеке. Быстрое исправление состоит в том, чтобы переместить массивы в глобальную область видимости. Лучшим решением является их динамическое распределение с использованием new и удаление следующим образом:

Complex *_A = new Complex[m*k];
Complex *_B = new Complex[k*n];
...
delete [] _A;
delete [] _B;

Еще лучший вариант, поскольку вы используете C ++, это использовать std :: vector:

std::vector < Complex > _A(m*k);
std::vector < Complex > _B(k*n);

// But now to get the pointer you need this:
cudaMemcpy( A, &_A[0], (m*k)*sizeof(Complex), cudaMemcpyHostToDevice );
// etc.

Тот &_A[0] Синтаксис означает: взять адрес первого элемента вектора, который совпадает с указателем на весь массив. Причина, по которой вектор предпочтительнее, чем выделение памяти вручную, заключается в том, что уничтожение / освобождение происходит автоматически, когда переменная выходит из области видимости, что важно для написания кода, безопасного для исключений.

Вам также понадобится #include <vector>

3

Другие решения

Других решений пока нет …