2015-12-01 45 views
0

我很困惑,我知道CUDA和其他庫允許使用模板結構作爲函子。因此,我設計了幾個人的神經網絡類:C++ struct函子作爲函數模板參數

struct sigmoid 
{ 
    sigmoid()=default;               
    __device__ float operator()(const float x) const                      
    {                                  
     float exp_val = __expf(-x);                          
     float denom = __fadd_rz(1.f,exp_val);                        
     return __fdividef(1.f,denom);             
    }                  
};  

當我用這個一個CUDA內核,它的使用是有點簡單:

activate<sigmoid><<num_blocks_x,block_threads_x>>>(sigmoid(),output_ptr); 

爲:

template <typename F>                              
__global__ void activate(F const& func, float * input)                      
{                                   
    int x = blockIdx.x * blockDim.x + threadIdx.x;                       
    input[x] = func(input[x]);                           
} 

但是我想打包函數模板調用CUDA內核的方法,然後將其轉發給它:

template <class A>                            
thrust::host_vector<float> propagate (                        
             A func,                 
             thrust::device_vector<float> & input               
            ) const; 

我已經實現了它到一個單獨的頭,它被包含在聲明類的頭的末尾。

class ann 
{ 
... 
}; 
#include ann_imp.hpp 

而且小鬼頭:

template <class A> inline                             
__host__ thrust::host_vector<float> ann::propagate (                      
                 A func,                    
                 thrust::device_vector<float> & input            
                ) const                     
{ 
    activate<func><<<num_blocks_x,block_threads_x>>>(func(),output_ptr); 
} 

然而,當我打電話的實際propagate方法我遇到麻煩:

net.propagate<sigmoid>(sigmoid(), in_vec1); 

產地:

error: function "sigmoid::operator()" cannot be called with the given argument list 
      object type is: sigmoid 

當我不要使用operator()但只有類型名稱:

xor_net.propagate<sigmoid>(sigmoid, in_vec1); 

我得到:

error: type name is not allowed 

使用一個實際的對象產生了同樣的錯誤:

sigmoid func; 
xor_net.propagate<sigmoid>(func, in_vec1); 

我已經試過玩弄的參數是A const& func等等,但無濟於事。

如何傳遞一個struct functor,然後將其轉發給CUDA內核?

編輯 沒有包裝,只需調用所需的活化功能:

activate<sigmoid><<<num_blocks_x,block_threads_x>>>(sigmoid(),output_ptr); 

回答

1

您有:

__device__ float operator()(const float x) const ... 

功能需要float類型的參數。你是從ann::propagate爲調用它:

activate<func><<<num_blocks_x,block_threads_x>>>(func(),output_ptr); 
               ^^^^^^ 

我相信這條線必須是:

activate<A><<<num_blocks_x,block_threads_x>>>(func,output_ptr); 
     ^^^^         ^^^^^  
     Fix the type       Use the object. 
+0

這個工作!現在我更加困惑。爲什麼當調用'propagate'而不是調用'activate'時出錯? 當我不使用包裝,我不得不稱之爲:'激活<<<...,...> >>(乙狀結腸(),PTR);' –

+0

@Alex,我不知道該怎麼回答,沒有看到完整的錯誤堆棧。 –

+0

@R Sahu我做了編輯。當我沒有使用任何模板,包裝,只(直)稱爲'activate'所有我所要做的就是調用'乙狀結腸()'作爲CUDA內核PARAM,並使用類型名。爲什麼包裝會得到錯誤,而不是cuda內核調用? –