cuda, pycuda - как писать комплексные числа - ошибки: класс "cuComplex" не имеет члена "i" - PullRequest
0 голосов
/ 14 января 2012

У меня трудности с использованием комплексных чисел в cuda, pycuda. ​​

У меня есть это в C:

#include <complex>
typedef std::complex<double> cmplx;
....
cmplx j(0.,1.);   

Кроме того, в том же коде:

#include <boost/python.hpp>
#include <boost/array.hpp>
...
typedef std::vector< boost::array<std::complex<double>,3 > > ComplexFieldType;
typedef std::vector< boost::array<double,3> > RealFieldType;
...
__global__ void compute(RealFieldType const & Rs,ComplexFieldType const & M,..)
...

Как я могу преобразовать это, чтобы использовать его с Pycuda?Я пытался вот так (в соответствии с книгой 'cuda by example'):

struct cuComplex {
    float real;
    float imag;
    cuComplex(float a,float b): real(a),imag(b){} 
    cuComplex operator *(const cuComplex& a) {
    return cuComplex(real*a.real -imag*a.imag ,imag*a.real +real*a.imag);
    }
cuComplex operator +(const cuComplex& a) {
    return cuComplex(real+a.real ,imag+a.imag);
    };  

cuComplex j(0.,1.);    //instead of  cmplx j(0.,1.);  

 __global__ void compute(float *Rs,cuComplex * M,..)  //instead of RealFieldType const & Rs,ComplexFieldType const & M
....

Некоторые ошибки, которые я принимаю:

Инициализация члена данных не разрешена

в этом объявлении нет класса хранения или спецификатора типа

Спасибо!

-------------------- -EDIT- ---------------------------------------------

Я сделал следующее, используя #include <pycuda-complex.hpp> (относительно вышеизложенного):

pycuda::complex<float> cmplx;

cmplx j(0.,1.);

и что касается typedef std::vector< boost::array<std::complex<double>,3 > > ComplexFieldType;

и ComplexFieldType const & M, внутри глобальной функции я попытался просто "float * M" или "cmplx * M".

До сих пор я получаю сообщение об ошибке:

переменная "cmplx" не является именем типа

Если я использую pycuda :: complex cmplx;, тогда я получаю:

идентификатор "cmplx" не определен

имя, за которым следует "::", должно быть именем класса или пространства имен

Также:

выражение должно иметь указатель на тип объекта (но, возможно, это из другой части кода)

Ответы [ 2 ]

2 голосов
/ 14 января 2012

На самом деле неясно, что вы на самом деле пытаетесь сделать (если вы действительно знаете себя), и вопрос становится все более запутанным по мере того, как редактирование и комментарии появляются. Но чтобы немного расширить ответ Андреаса, вот простой, компилируемый фрагмент кода CUDA, который правильно использует собственный сложный тип pycuda:

#include <pycuda-complex.hpp>

template<typename T>
__global__ void kernel(const T * x, const T *y, T *z)
{
    int tid = threadIdx.x + blockDim.x * blockIdx.x;

    z[tid] = x[tid] + y[tid];
}


typedef pycuda::complex<float> scmplx;
typedef pycuda::complex<double> dcmplx;

template void kernel<float>(const float *, const float *, float *);
template void kernel<double>(const double *, const double *, double *);
template void kernel<scmplx>(const scmplx *, const scmplx *, scmplx *);
template void kernel<dcmplx>(const dcmplx *, const dcmplx *, dcmplx *);

Это дает вам одинарные и двойные реальные и сложные версии тривиального ядра и компилирует с nvcc что-то вроде этого:

$ nvcc -arch=sm_20 -Xptxas="-v" -I$HOME/pycuda-2011.1.2/src/cuda -c scmplx.cu 
ptxas info    : Compiling entry function '_Z6kernelIN6pycuda7complexIdEEEvPKT_S5_PS3_' for 'sm_20'
ptxas info    : Used 12 registers, 44 bytes cmem[0], 168 bytes cmem[2], 4 bytes cmem[16]
ptxas info    : Compiling entry function '_Z6kernelIN6pycuda7complexIfEEEvPKT_S5_PS3_' for 'sm_20'
ptxas info    : Used 8 registers, 44 bytes cmem[0], 168 bytes cmem[2]
ptxas info    : Compiling entry function '_Z6kernelIdEvPKT_S2_PS0_' for 'sm_20'
ptxas info    : Used 8 registers, 44 bytes cmem[0], 168 bytes cmem[2]
ptxas info    : Compiling entry function '_Z6kernelIfEvPKT_S2_PS0_' for 'sm_20'
ptxas info    : Used 4 registers, 44 bytes cmem[0], 168 bytes cmem[2]

Возможно, это как-то ответит на ваш вопрос ....

2 голосов
/ 14 января 2012

Используйте

#include <pycuda-complex.hpp>

{
  pycuda::complex<float> x(5, 17);
}

Тот же интерфейс, что и std::complex<>, фактически полученный из версии STLport этого.

...