cuda、pycuda -- 如何编写复数 -- 错误:类“cuComplex”没有成员“i”

发布于 2024-12-27 02:09:14 字数 2046 浏览 0 评论 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<float> cmplx;

cmplx j(0.,1.);

以及 typedef std::vector boost::array,3> > ComplexFieldType;

ComplexFieldType const & M ,在全局函数内, 我尝试了“float *M”或“cmplx *M”。

到目前为止,我收到错误:

变量“cmplx”不是类型名称

如果我使用 pycuda::complex cmplx; ,然后我得到:

标识符“cmplx”未定义

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

另外:

<块引用>

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

I have difficulties to use complex numbers in cuda,pycuda.

I have this in C:

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

Also,in the same code:

#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,..)
...

    

How can i convert this to use it with pycuda?
I tried sth like this (according to the book '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
....
    

Some of the errors i take are:

data member initializer is not allowed

this declaration has no storage class or type specifier

Thank you!

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

I did the following using #include <pycuda-complex.hpp> (relative to the above) :

pycuda::complex<float> cmplx;

cmplx j(0.,1.);

and as for typedef std::vector< boost::array<std::complex<double>,3 > > ComplexFieldType;

and ComplexFieldType const & M ,inside the global function,
i tried just "float *M " or "cmplx *M".

Until now , i am getting error :

variable "cmplx" is not a type name

If i use pycuda::complex cmplx; ,then i get:

identifier "cmplx" is undefined

name followed by "::" must be a class or namespace name

Also:

expression must have pointer-to-object type (but maybe this is from another part of code)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随心而道 2025-01-03 02:09:14

确实不清楚您实际上想要做什么(如果您确实了解自己),并且随着编辑和评论的不断进行,问题变得越来越混乱。但为了稍微扩展 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]

也许这在某种程度上回答了你的问题......

It really isn't clear what you are actually trying to do (if you actually know yourself), and the question is getting progressively more confused as the edits and comments roll on. But to expand Andreas's answer a little, here is a simple, compilable piece of CUDA code which uses the pycuda native complex type correctly:

#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 *);

This gives you single and double real and complex versions of the trivial kernel and compiles with nvcc something like this:

$ 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]

Perhaps this goes someway to answering your question....

烟柳画桥 2025-01-03 02:09:14

使用

#include <pycuda-complex.hpp>

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

std::complex<> 相同的接口,实际上源自其 STLport 版本。

Use

#include <pycuda-complex.hpp>

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

Same interface as std::complex<>, in fact derived from the STLport version of that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文