2012-01-13 22 views
0

我在使用複數cuda,pycuda時遇到了困難。cuda,pycuda - 如何編寫複數 - 錯誤:class「cuComplex」沒有會員「我」

我有這個在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使用它呢? I(根據書的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 
.... 

一些I採取錯誤是:

數據成員的初始值是不允許的

此聲明沒有存儲類別或類型說明符

謝謝!

-------------------- -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,全局函數裏面, 我嘗試了 「浮動* M」 或 「CMPLX * M」。

到現在爲止,我得到錯誤:

變量 「CMPLX」 不是一個類型名稱

如果我使用pycuda ::複雜CMPLX; ,然後我得到:

標識符 「CMPLX」 未定義

名後加 「::」 必須是類或命名空間名稱

另外:

表達式必須具有指針對象類型(但也許這是來自代碼的另一部分)

+0

根據結構定義,它有'real'和'imag'領域,而不是'i'和' r'。還要注意,它們是'float',而不是像你的C代碼中的'double'。 – aland 2012-01-13 20:55:20

+0

好的,謝謝!我現在更新了!我不認爲(也許我錯了)將它們作爲浮點數存放在cuda代碼中是錯誤的(我也嘗試過使用double但仍然是相同的錯誤)。 – George 2012-01-13 21:00:56

+0

@George:錯誤「變量」cmplx「不是類型名稱」應該告訴你一切你需要解決的問題。如果沒有,你需要修改一些基本的C++ - 這是一個非常基本和自我解釋的錯誤。 – talonmies 2012-01-14 15:13:05

回答

2

真的不清楚你實際上想要做什麼(如果你真的瞭解自己),而且隨着編輯和評論的推出,問題會越來越混亂。但要擴大安德烈亞斯的回答一點,這裏是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] 

也許這正好要想辦法回答你的問題....

+0

我正在使用typedef pycuda :: complex cmplx;但它給了我「沒有操作符」*「匹配這些操作數操作數類型是:cmplx * double」,因爲我有一些計算爲「Cn2 = Cn1 * 3.0 - 2.0;」 ,其中Cn2和Cn1是cmplx。謝謝!(我投票) – George 2012-01-14 16:20:33

+0

錯誤信息告訴你,你正在混合單精度和雙精度類型。 '3.0'是一個雙精度常數。 '3.0f'是一個單精度常數。說真的,在你繼續學習之前,花點時間學習一些基本的C++是最好的選擇,因爲很顯然你不會像現在這樣過分。 – talonmies 2012-01-14 16:28:56

+0

:首先謝謝!這就是問題所在。其次,我從來沒有遇到過這樣的問題,因爲我說過我沒有太多的C++經驗,當然,我需要很多鍛鍊! ,項目正在運行!:)無論如何,我也會得到錯誤「表達式必須有指向對象類型」,你有沒有想過?謝謝! – George 2012-01-14 16:35:36

2

使用

#include <pycuda-complex.hpp> 

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

相同的接口,std::complex<>,實際上從該版本的STLport衍生。

+0

:你好安德烈亞斯,你能再次檢查我的帖子嗎?我照你說的做了,但仍然有問題。我更新了。謝謝! – George 2012-01-14 10:35:43