Operators

The operator describes the operation applied to each element of a range of input elements. There are two ways to define an operator: a lambda or a functor.

Lambda

int main(){
    // ...

    // The lambda needs the attribute ALPAKA_FN_HOST_ACC
    auto incTwo = [] ALPAKA_FN_HOST_ACC (){ return val + 1; };

    vikunja::transform::deviceTransform<Acc>(
        devAcc,
        queueAcc,
        extent[Dim::value - 1u],
        deviceNativePtr,
        deviceNativePtr,
        incTwo // Operator
);

    return 0;
}

Functor

struct IncOne
{
    // The operator() function needs the attribute ALPAKA_FN_HOST_ACC
    // and must be const
    template<typename TData>
    ALPAKA_FN_HOST_ACC TData operator()(TData const val) const
    {
        return val + 1;
    }
};

int main(){
    // ...

    IncOne incOne;

    vikunja::transform::deviceTransform<Acc>(
        devAcc,
        queueAcc,
        extent[Dim::value - 1u],
        deviceNativePtr,
        deviceNativePtr,
        incOne // Operator
);

    return 0;
}

The functor object must fullfil the requirements of std::is_trivially_copyable. Compared to a lambda, the functor allows the creation of additional member variables and functions.

struct MightFunctor {
private:
    int const m_max;

    ALPAKA_FN_HOST_ACC int crop_value(int const v) const {
        return (v < m_max) ? v : m_max;
    }

public:

    MightFunctor(int const max) : m_max(max) {}

    ALPAKA_FN_HOST_ACC TData operator()(TData const val) const
    {
        return crop_value(val);
    }
}

int main(){
    // ...

    MightFunctor mightFunctor(42);

    // ...

    return 0;

}

Warning

Global functions and std::function are not allowed as functor objects for the vikunja algorithm due to a limitation of the CUDA accelerator.

https://nvidia.github.io/libcudacxx/standard_api/utility_library/functional.html

Other methods, such as function pointers, have not been tested. Due to the different programming models of the aplaka accelerators, it is not possible to say whether they work with all of them or not without extensive testing.

Operator Types

Depending on the algorithm, the operator requires a different number of input arguments. Currently, the vikunja algorithm requires a unary (one data input) or binary (two data inputs) operator. A vikunja-specific property of the operator is that they can have an additional acc argument, which is required for any device-specific functions (such as math functions).

struct BinaryOperatorWithoutAccObject
{
    template<typename TData>
    ALPAKA_FN_HOST_ACC TData operator()(TData const i, TData const j) const
    {
        return i + j;
    }
};

struct BinaryOperatorWithAccObject
{
    template<typename TAcc, typename TData>
    ALPAKA_FN_HOST_ACC TData operator()(TAcc const& acc, TData const i, TData const j) const
    {
        return alpaka::math::max(acc, i, j);
    }

Please read the alpaka documentation for more information about available device functions.

Warning

The acc object also allows access to functions that can break the functionality of the vikunja algorithm, such as using the thread index for a manual memory access.