Я пытаюсь изучить CUDA, написав базовый код, который, надеюсь, поставит меня в лучшем положении для преобразования моего существующего кода на C++ в CUDA (для исследования).CUDA - Простое комплексное умножение чисел
Мне нужно сделать довольно сложную обработку чисел, поэтому я написал этот очень простой код, чтобы умножить массив комплексных чисел с реальным числом в ядре графического ядра.
#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) Я ожидал сложный двойной массив (0, 5i) для всех элементов «j» после следующей строки кода. Тем не менее, я получаю все 0s. Почему это?
j[i] = make_cuDoubleComplex(0, 5);
2) Почему я не могу напечатать свой массив с помощью cout? Строка кода, показанная ниже, дает следующую ошибку: ни один оператор «< <» не соответствует этим операндам. Как я могу исправить это, не используя printf?
cout << "\nJ = " << j[i];
3) Функция ГПУ 'FUNC', который должен выдавать массив (0, 10i) в качестве окончательного ответа дает случайные значения, такие как эти:
CALC = -1.#QNAN0
CALC = -1.#QNAN0
CALC = -9255963134931783100000000...000.. etc
CALC = -9255963134931783100000000...000.. etc
4) для данного фактическое исследование, комплексный массив «j» будет задан в формате сложного (двойного), а не cuDoubleComplex. Могу ли я выполнять аналогичные операции с массивом «j» сложных (двойных) с помощью функции «func»? Если нет, каковы мои варианты?
Я думаю, что я хорошо объяснил себя, но не стесняйтесь задавать любые последующие вопросы. Новое на C++, а также CUDA так неплохо: D
Что произошло, когда вы пытались умножить * одиночный * комплексное число на вещественное число в ядре GPU? – Beta