Код: Выделить всё
#include
#include
#define N (2048*2048)
#define THREADS_PER_BLOCK 512
__global__ void add(std::complex *a, std::complex *b, std::complex *c)
{
int index = threadIdx.x + blockIdx.x * blockDim.x;
// c[index] = a[index] + b[index];
// c[index] = a[index].real();
c[index] = a[index];
}
int main()
{
// host side
std::complex *a;
std::complex *b;
std::complex *c;
// device side
std::complex *d_a;
std::complex *d_b;
std::complex *d_c;
int size = N * sizeof(std::complex);
/* allocate space for device copies of a, b, c */
cudaMalloc( (void **) &d_a, size );
cudaMalloc( (void **) &d_b, size );
cudaMalloc( (void **) &d_c, size );
/* allocate space for host copies of a, b, c and setup input values */
a = (std::complex*)malloc( size );
b = (std::complex*)malloc( size );
c = (std::complex*)malloc( size );
for( int i = 0; i < N; i++ )
{
a[i] = b[i] = i;
c[i] = 0;
}
cudaMemcpy( d_a, a, size, cudaMemcpyHostToDevice );
cudaMemcpy( d_b, b, size, cudaMemcpyHostToDevice );
add>( d_a, d_b, d_c );
cudaDeviceSynchronize();
cudaMemcpy( c, d_c, size, cudaMemcpyDeviceToHost);
bool success = true;
for( int i = 0; i < N; i++ )
{
// if( c[i] != a[i] + b[i])
if( c[i] != a[i] )
{
printf("c[%d] = %d\n",i,c[i] );
success = false;
break;
}
}
printf("%s\n", success ? "success" : "fail");
free(a);
free(b);
free(c);
cudaFree( d_a );
cudaFree( d_b );
cudaFree( d_c );
return 0;
}
Код: Выделить всё
__global__ void add(std::complex *a, std::complex *b, std::complex *c)
{
int index = threadIdx.x + blockIdx.x * blockDim.x;
// c[index] = a[index] + b[index];
// c[index] = a[index].real();
c[index] = a[index];
}
Код: Выделить всё
c[index] = a[index];
но при изменении на компиляцию со строкой:
Код: Выделить всё
c[index] = a[index] + b[index]; // first one
c[index] = a[index].real(); // second one
complex.cu(10) : ошибка: вызов функции host("std::operator
+") из глобальной функции("add") не разрешен
complex.cu(10): ошибка: идентификатор «std::operator + »
не определен в коде устройства
сообщение об ошибке при переходе на второй вариант выглядит следующим образом:
complex.cu(11): ошибка: вызов constexpr host< /strong> function("real")
из глобальной функции("add") не допускается. Для этого можно использовать экспериментальный
флаг '--expt-relaxed-constexpr'.
1 ошибка обнаружена при компиляции
"/tmp/tmpxft_000157af_00000000 -8_complex.cpp1.ii".
Команда компиляции, которую я использовал:
Код: Выделить всё
/usr/local/cuda-10.2/bin/nvcc -o complex complex.cu
обновление:
После перегрузки оператора+ для std: :complex, приведенный выше код может достичь желаемого результата:
Код: Выделить всё
__host__ __device__ std::complex operator+(const std::complex& a, const std::complex& b)
{
const double* aArg = reinterpret_cast(&a);
const double* bArg = reinterpret_cast(&b);
double retVal[2] = { aArg[0] + bArg[0], aArg[1] + bArg[1] };
return std::move(*reinterpret_cast(retVal));
}
Подробнее здесь: https://stackoverflow.com/questions/665 ... x-operator