Я хочу умножить два массива, и у меня возникла проблема с Cuda RunTime API. Произошла ошибка: API-интерфейс CUDA Runtime Error 11: неверный аргумент. Какой аргумент? Помоги мне, пожалуйста
Код:
// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <fstream>
// includes, project
#include <cufft.h>
#include <cuda.h>
#include <cutil_inline.h>
#include <shrQATest.h>
#define SIGNAL_SIZE 8192
#define SIGNAL_COUNT 384
// Complex data type
typedef float2 Complex;
static __device__ __host__ inline Complex ComplexMul(Complex, Complex);
static __device__ __host__ inline Complex ComplexAdd(Complex );
static __global__ void ComplexPointwiseMA(Complex* , Complex* , Complex* );
// Complex addition
static __device__ __host__ inline Complex ComplexAdd(Complex a,Complex b)
{
Complex c;
c.x = a.x + b.x;
c.y = a.y + b.y;
return c;
}
// Complex multiplication
static __device__ __host__ inline Complex ComplexMul(Complex a, Complex b)
{
Complex c;
c.x = a.x * b.x - a.y * b.y;
c.y = a.x * b.y + a.y * b.x;
return c;
}
// Complex Mul 'n Add function
static __global__ void ComplexPointwiseMA(Complex* mas1, Complex* mas2, Complex*mas_tmp)
{
const int numThreads = blockDim.x * gridDim.x;
const int threadID = blockIdx.x * blockDim.x + threadIdx.x;
int j=0, k=0;
Complex c;
int size=SIGNAL_COUNT*SIGNAL_SIZE;
for (int i = threadID; i <size; i += numThreads)
{
if((i%SIGNAL_SIZE==0)&&(j<SIGNAL_COUNT))
j++;
c=ComplexMul(mas1[i], mas2[j]);
mas_tmp[k]=ComplexAdd(mas_tmp[k],c);
if(k>=SIGNAL_SIZE-1)
k=0;
else
k++;
}
}
int main(int argc, char** argv)
{
int threads_per_block=256;
int blocks_per_grid=16;
//dim3 dimBlock(SIGNAL_COUNT, SIGNAL_SIZE); // threads
//dim3 dimGrid(SIGNAL_COUNT); // 384 blocks in a grid
cudaEvent_t start, stop;
float elapsedTime;
//shrQAStart(argc, argv);
cudaEventCreate(&start);
cudaEventCreate(&stop);
// For random
srand(1001);
// Allocate host memory for the mass
Complex* mas_tmp=NULL;
mas_tmp =new Complex [SIGNAL_COUNT*SIGNAL_SIZE];
Complex* mas1=NULL;
mas1 =new Complex [SIGNAL_COUNT*SIGNAL_SIZE];
for(unsigned int i = 0; i <SIGNAL_COUNT*SIGNAL_SIZE; ++i)
{
mas1[i].x = rand() / (float)RAND_MAX;
mas1[i].y = rand() / (float)RAND_MAX;
}
Complex* mas2=NULL;
mas2 =new Complex [SIGNAL_COUNT];
for(unsigned int i = 0; i < SIGNAL_COUNT; ++i)
{
mas2[i].x = rand() / (float)RAND_MAX;
mas2[i].y = rand() / (float)RAND_MAX;
}
// Timer
cudaEventRecord(start,0);
// Allocate device memory for mass
Complex* mastmp_=NULL; // temporary
cutilSafeCall(cudaMalloc(&mastmp_, SIGNAL_SIZE*SIGNAL_COUNT*sizeof(Complex)));
Complex* mas1_=NULL; // signal
cutilSafeCall(cudaMalloc(&mas1_, SIGNAL_SIZE*SIGNAL_COUNT*sizeof(Complex)));
Complex* mas2_=NULL; // coefficient
cutilSafeCall(cudaMalloc(&mas2_, SIGNAL_COUNT*sizeof(Complex)));
// Copy host data to device
cutilSafeCall(cudaMemcpy(mas1_, mas1, SIGNAL_SIZE*SIGNAL_COUNT*sizeof(Complex), cudaMemcpyHostToDevice));
cutilSafeCall(cudaMemcpy(mas2_, mas2, SIGNAL_COUNT*sizeof(Complex), cudaMemcpyHostToDevice));
// Calling Mul 'n Add function
ComplexPointwiseMA<<<blocks_per_grid, threads_per_block>>>(mas1_, mas2_, mastmp_);
// Check if kernel execution generated and error
cutilCheckMsg("Kernel execution failed [ ComplexPointwiseMA ]");
// Copy device memory to host
cutilSafeCall(cudaMemcpy(mastmp_, mas_tmp, SIGNAL_SIZE*SIGNAL_COUNT*sizeof(Complex), cudaMemcpyDeviceToHost));
cudaEventRecord(stop,0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start,stop);
printf("Time %3.10f ms\n", elapsedTime);
// Free memory
free(mas1);
free(mas2);
free(mas_tmp);
cudaEventDestroy(start);
cudaEventDestroy(stop);
cutilSafeCall(cudaFree(mas1_));
cutilSafeCall(cudaFree(mas2_));
cutilSafeCall(cudaFree(mastmp_));
cutilDeviceReset();
system ("pause");
return 0;
}
Следующая строка в вашем коде сгенерирует ошибку Invalid Argument
,
// Copy device memory to host
cutilSafeCall(cudaMemcpy(mastmp_, mas_tmp, SIGNAL_SIZE*SIGNAL_COUNT*sizeof(Complex), cudaMemcpyDeviceToHost));
В функции cudaMemcpy
первый аргумент является указателем назначения, а второй аргумент является указателем источника.
Вы указали флаг cudaMemcpyDeviceToHost
но указатели хоста (назначения) и устройства (источника) взаимозаменяемы.
Вы должны сделать это (поменяйте местами первые 2 аргумента):
cutilSafeCall(cudaMemcpy(mas_tmp, mastmp_,SIGNAL_SIZE*SIGNAL_COUNT*sizeof(Complex), cudaMemcpyDeviceToHost));
Других решений пока нет …