Каков оптимальный способ использования дополнительных полей данных в функторах в Thrust?

Каков правильный (или оптимальный) способ использования некоторых постоянных данных в функторах, используемых в thrust алгоритмы, такие как thrust::transform? Наивный способ, которым я воспользовался, это просто выделить необходимые массивы внутри функтора. operator() метод, как это:

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;
    }
}

Но это кажется не очень элегантным или эффективным способом. Теперь мне нужно разработать относительно сложный функтор с некоторыми матрицами (постоянными, как в примере выше) и дополнительными методами, используемыми в функторе. operator() метод. Каков оптимальный способ решения такой проблемы? Благодарю.

1 ответ

Из вашего последнего комментария становится ясно, что вы действительно спрашиваете здесь об инициализации параметра functor. CUDA использует объектную модель C++, поэтому структуры имеют семантику и поведение классов. Так что твой пример функтор

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];
    }
}

может быть переписан с помощью пустого конструктора со списками инициализации для преобразования жестко закодированных констант внутри функтора в присваиваемые значения времени выполнения:

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;
    }
}

Вы можете создать как можно больше версий функтора, каждая с различными значениями констант, чтобы делать то, для чего вы используете функторы в сочетании с библиотекой тяги.

Другие вопросы по тегам