我想通過編寫基本代碼學習CUDA,希望能夠將我的現有C++代碼轉換爲CUDA(用於研究)。CUDA - 簡單的複數乘法
我需要做一些複雜的數字操作,所以我寫了這個非常基本的代碼,以便在GPU內核中將實數 與一系列複數相乘。
#include <complex>
#include <iostream>
#include <cmath>
#include "cuda.h"
#include "math.h"
#include "cuComplex.h"
#define n 5
using namespace std;
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
__global__ void func(double *s, cuDoubleComplex *j, cuDoubleComplex *calc) {
int tid = blockIdx.x;
calc[tid] = cuCmul(j[tid], make_cuDoubleComplex(*s, 0));
}
int main(void) {
cuDoubleComplex calc[n+1], *dev_j, *dev_calc;
double *dev_s, s[n+1] = { 2.0, 2.0, 2.0, 2.0, 2.0 };
//complex<double> j[n+1]
cuDoubleComplex j[n+1];
for (int i = 1; i <= n; i++) {
j[i] = make_cuDoubleComplex(0, 5);
cout << "\nJ cout = " << cuCreal(j[i]) << ", " << cuCimag(j[i]);
}
// allocate the memory on the GPU
cudaMalloc((void**)&dev_s, (n+1) * sizeof(double));
cudaMalloc((void**)&dev_j, (n+1) * sizeof(double));
cudaMalloc((void**)&dev_calc, (n+1) * sizeof(double));
cudaMemcpy(dev_s, s, (n+1) * sizeof(double), cudaMemcpyHostToDevice);
cudaMemcpy(dev_j, j, (n+1) * sizeof(double), cudaMemcpyHostToDevice);
func<<<n,1>>>(dev_s, dev_j, dev_calc);
//kernel<<<1,1>>>(a_d);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaMemcpy(calc, dev_calc, (n+1) * sizeof(double), cudaMemcpyDeviceToHost));
//cudaMemcpy(calc, dev_calc, (n+1) * sizeof(double), cudaMemcpyDeviceToHost);
for (int i = 1; i <= n; i++) {
cout << "\nCALC cout = " << cuCreal(calc[i]) << ", " << cuCimag(calc[i]);
}
return 0;
}
最終答案是錯誤的,我也發現了一些其他地方,我沒有得到預期的價值。
1)我期待在下面的代碼行之後爲'j'的所有元素設置一個複雜的(0,5i)雙數組。但是,我獲得全0。這是爲什麼? 2)爲什麼我不能用cout打印數組?下面顯示的代碼行提供了以下錯誤:沒有運算符「< <」與這些操作數匹配。我怎樣才能解決這個問題,而不使用printf?
cout << "\nJ = " << j[i];
3)GPU功能 'FUNC' 應該給出作爲最終答案的(0,10I)的陣列是給隨機值,如這些:
CALC = -1.#QNAN0
CALC = -1.#QNAN0
CALC = -9255963134931783100000000...000.. etc
CALC = -9255963134931783100000000...000.. etc
4)對於我的實際研究中,複數組'j'將以複數(雙)而非cuDoubleComplex的格式給出。我可以使用函數'func'對'j'複數(雙精度)數組執行類似的操作嗎?如果不是,我有什麼選擇?
我想我已經很好地解釋了自己,但隨時可以提出任何後續問題。 新到C++以及CUDA所以是很好的:d
當你試圖通過一個實數的GPU內核乘以* *單複數發生了什麼? – Beta