Hi everyone,
I’m trying for the first time to use #cufft using #openacc. I reproduce my problem with the following simple example. I have as an input an array of 10 real elements (a
) initialized with 1, and the output (b
) is supposed to be its Fourier transform (b
should be zeros except for b[0] = 10
).
But I encounter a runtime error at the line where cufftPlan1d
is called (please see the code below). However, when CHECK_CUFFT
macro is not used, the program is executed, but with wrong values of b[i] = 0, i = 0, ..., 9.
, in fact, they are simply the initial values of b
.
I would ask two questions:
1- What is the mistake I made that prevent me from getting the correct answer?
2- How to print out the runtime error, or make some additional diagnostic that allows me to figure out this type of error?
I compiled the code with as follows
#!/bin/bash
compileNV=/opt/nvidia/hpc_sdk/Linux_x86_64/2023/compilers/bin/nvc++
#FLAGS="-O2 -g -gopt -Kieee -Minfo=accel -acc=noautoptr,sync,gpu -gpu=cc75,cuda10.2,lineinfo,ptxinfo -cudalib=curand"
FLAGS="-O2 -lm -lcufft -march=native -g -gopt -Kieee -Minfo=accel -acc=noautopar,sync,gpu -gpu=cc75,cuda12.0,lineinfo,ptxinfo -cudalib=curand"
#export NVCOMPILER_ACC_NOTIFY=3
$compileNV -o 1DFFT_GPU example1DFFT_GPU.cpp $FLAGS
Here is the source code:
/* Example of the problem : example1DFFT_GPU.cpp */
#include <iostream>
#include <vector>
#include <cmath>
#include <complex>
#include "openacc.h"
#include <cuda_runtime.h>
#include <cufftXt.h>
#include "../common.h"
int main()
{
const int m = 10;
std::complex<float> a[m];
std::complex<float> b[m];
cufftHandle plan1D;
for(unsigned int i = 0; i < m; i++)
{
a[i] = 1.0;
}
for(unsigned int i = 0; i < m; i++)
{
std::cout << a[i].real() << " , " << a[i].imag() << "\n";
}
#pragma acc data copyin(a[0 : m]) copyout(b[0 : m])
{
CHECK_CUFFT(cufftPlan1d(&plan1D, m, CUFFT_C2C, 1));
CHECK_CUFFT(cufftSetStream(plan1D, (cudaStream_t) acc_get_cuda_stream(acc_async_sync)));
#pragma acc host_data use_device(a, b)
{
CHECK_CUFFT(cufftExecC2C( plan1D,
(cufftComplex *) a,
(cufftComplex *) b,
CUFFT_FORWARD));
}
}
for(unsigned int i = 0; i < m; i++)
{
std::cout << b[i].real() << " , " << b[i].imag() << "\n";
}
CHECK_CUFFT(cufftDestroy(plan1D));
return 0;
}
Her is the common.h
file
/* common.h file */
#include <sys/time.h>
/**
* @brief This piece of code is copied from
*
* https://github.com/deeperlearning/professional-cuda-c-programming/blob/master/examples/common/common.h
*
*/
#ifndef _COMMON_H
#define _COMMON_H
#define CHECK(call) \
{ \
const cudaError_t error = call; \
if (error != cudaSuccess) \
{ \
fprintf(stderr, "Error: %s:%d, ", __FILE__, __LINE__); \
fprintf(stderr, "code: %d, reason: %s\n", error, \
cudaGetErrorString(error)); \
} \
}
#define CHECK_CUFFT(call) \
{ \
cufftResult err; \
if ( (err = (call)) != CUFFT_SUCCESS) \
{ \
fprintf(stderr, "Got CUFFT error %d at %s:%d\n", err, __FILE__, \
__LINE__); \
exit(1); \
} \
}
#endif // _COMMON_H
thanks for your help