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で使用するように変換するにはどうすればよいですか? 私はこのようにsthを試しました(本「例によるcuda」によると):

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」だけを試しました。

今まで、私はエラーが発生しています:

変数「cmlx」は型名ではありません

pycuda::complex cmplx; を使用する場合 、そして私は得る:

識別子「cmlx」は定義されていません

"::" が後に続く名前は、クラスまたは名前空間の名前でなければなりません

また:

式はオブジェクトへのポインター型でなければなりません (ただし、これはコードの別の部分からのものである可能性があります)

4

2 に答える 2

2

あなたが実際に何をしようとしているのか(実際に自分自身を知っている場合)は本当に明確ではなく、編集やコメントが進むにつれて、質問は次第に混乱していきます。しかし、Andreasの答えを少し拡張するために、pycudaネイティブ複合型を正しく使用する単純でコンパイル可能なCUDAコードを次に示します。

#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 に答える
2

使用する

#include <pycuda-complex.hpp>

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

と同じインターフェイスstd::complex<>で、実際にはその STLport バージョンから派生しています。

于 2012-01-13T22:35:42.727 に答える