2015-11-25 33 views
1

變換我使用CUDA核心做在一個推力矢量乙狀結腸激活:推力:: device_vector使用推力::更換或推力::自定義函子/謂詞

thrust::device_vector<float> output = input; 
float * output_ptr = thrust::raw_pointer_cast(output.data()); 
sigmoid_activation<<<num_blocks_x,block_threads_x>>>(output_ptr); 

在我的內核是:

__device__ float sigmoid_function(float input, float skew) 
{ 
    // -X: Neg X 
    float x_neg = __fmul_rz(-1.f, input); 
    // Y: exponential value 
    float exp_val = __expf(x_neg); 
    // 1 + exp^(-X) 
    float denom = __fadd_rz(1.f, e_to_x_neg); 
    // 1/1 + exp^(-X) 
    float output = __fdividef(1.f, denom); 

    if (skew != 0.0) 
     return _fadd_rz(output, skew); 
    else 
     return output; 
} 

__global__ void sigmoid_activation(float * input float skew) 
{ 
    // Iterate Input vector 
    int x = blockIdx.x * blockDim.x + threadIdx.x; 
    // Update value 
    input[x] = sigmoid_function(input[x], skew); 
} 

我該如何使用推子::用函子/謂詞替換來做同樣的事情?

我所看到的例子是過於簡單化證明這種使用:

thrust::replace(Y.begin(), Y.end(), 1, 10); 

或者第8-9頁

thrust::transform(X.begin(), X.end(), Y.begin(),thrust::negate<int>()); 

回答

1

在「推力快速入門指南」上有一個例子如何創建自己的變換功能。

我想出了一個解決方案,但注意這不會在主機端運行,因爲您使用CUDA內部函數。

代碼

#include <thrust/device_vector.h> 
#include <thrust/transform.h> 
#include <thrust/sequence.h> 
#include <thrust/copy.h> 
#include <thrust/fill.h> 
#include <thrust/replace.h> 
#include <thrust/functional.h> 
#include <iostream> 

template<typename T> 
struct sigmoid_function 
{ 

    float _skew; 

    sigmoid_function(float skew) : _skew(skew) { /*Empty */ } 

    typedef T argument_type; 

    typedef T result_type; 

    __device__ T operator()(const T &x) const { 

    float x_neg = __fmul_rz(-1.f, x); 
    float exp_val = __expf(x_neg); 
    float denom = __fadd_rz(1.f, __expf(-exp_val)); 
    float output = __fdividef(1.f, denom); 

    if (_skew != 0.0) 
     return __fadd_rz(output, _skew); 
    else 
     return output; 
    } 
}; 

int main(void) { 
    // allocate three device_vectors with 10 elements 
    thrust::device_vector<float> X(10); 

    // initialize X to 0,1,2,3, .... 
    thrust::sequence(X.begin(), X.end()); 

    // Before 
    thrust::copy(X.begin(),X.end(),std::ostream_iterator<float>(std::cout, "\n")); 

    // Apply 
    thrust::transform(X.begin(), X.end(), X.begin(), sigmoid_function<float>(0.1)); 

    // After 
    thrust::copy(X.begin(),X.end(),std::ostream_iterator<float>(std::cout, "\n")); 

    return 0; 
} 
+0

非常感謝您!我沒有看到,但我的理解是,大多數推力仿函數使用相同的'struct-operator()()'模式?無論如何,非常感謝。 –

+0

模式是相似的。根據推力函數和它需要的參數個數(C++允許重載函數),它將需要你的函子具有一定數量的參數。 – deathly809