What is the optimal way to use additional data fields in functors in Thrust?

烈酒焚心 提交于 2019-12-12 02:57:27

问题


What is the proper (or optimal) way to use some constant data in functors used in thrust algorithms like thrust::transform? The naive way I used was simply allocate required arrays inside the functor's operator() method, like this:

struct my_functor {

    __host__ __device__
    float operator()(thrust::tuple<float, float> args) {

        float A[2][10] = {
            { 4.0, 1.0, 8.0, 6.0, 3.0, 2.0, 5.0, 8.0, 6.0, 7.0 },
            { 4.0, 1.0, 8.0, 6.0, 7.0, 9.0, 5.0, 1.0, 2.0, 3.6 }};

        float x1 = thrust::get<0>(args);
        float x2 = thrust::get<1>(args);

        float result = 0.0;
        for (int i = 0; i < 10; ++i)
            result += x1 * A[0][i] + x2 * A[1][i];

        return result;
    }
}

But it seems not very elegant or efficient way. Now I have to develop relatively complicated functor with some matrices (constant, like in the example above) and additional methods used in the functor's operator() method. What is the optimal way to solve such a problem? Thanks.


回答1:


From your last comment, it is clear that what you are really asking about here is functor parameter initialisation. CUDA uses the C++ object model, so structures have class semantics and behaviour. So your example functor

struct my_functor {
    __host__ __device__
    float operator()(thrust::tuple<float, float> args) const {
        float A[2] = {50., 55.6};

        float x1 = thrust::get<0>(args);
        float x2 = thrust::get<1>(args);

        return x1 * A[0]+ x2 * A[1];
    }
}

can be re-written with an empty constructor with intialisation lists to transform hardcoded constants within the functor into runtime assignable values:

struct my_functor {
    float A0, A1;

    __host__ __device__
    my_functor(float _a0, _a1) : A0(_a0), A1(_a1) { }

    __host__ __device__
    float operator()(thrust::tuple<float, float> args) const {
        float x1 = thrust::get<0>(args);
        float x2 = thrust::get<1>(args);

        return x1 * A0 + x2 * A1;
    }
}

You can instantiate as many versions of the functor, each with different constant values, to do whatever it is you are using the functors for in conjunction with the thrust library.



来源:https://stackoverflow.com/questions/30749426/what-is-the-optimal-way-to-use-additional-data-fields-in-functors-in-thrust

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!