0

我很难在 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 an 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
....
    

我犯的一些错误是:

不允许使用数据成员初始化程序

此声明没有存储类或类型说明符

谢谢!

----------------- - 编辑- ------------- ------------------

我使用#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”未定义

后跟“::”的名称必须是类或命名空间名称

还:

表达式必须具有指向对象的类型(但也许这是来自代码的另一部分)

4

2 回答 2

2

采用

#include <pycuda-complex.hpp>

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

与 相同的接口std::complex<>,实际上是从 STLport 版本派生的。

于 2012-01-13T22:35:42.727 回答
2

真的不清楚您实际上要做什么(如果您真的了解自己),并且随着编辑和评论的进行,问题变得越来越混乱。但是为了稍微扩展 Andreas 的答案,这里有一段简单的、可编译的 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]

也许这在某种程度上可以回答您的问题....

于 2012-01-14T16:04:23.897 回答