Alpaka: Math functions are not ADL-friendly

Created on 30 Sep 2019  路  7Comments  路  Source: alpaka-group/alpaka

The implementation uses hardcoded functions from std in situations like this. It is done consistently for all math functions, I will use exp as an example.

This way is not friendly for ADL in case the argument is a user-defined type with std::is_arithmetic trait enabled and a custom exp implemented, since that implementation would not be found. A standard approach to look for the user-defined first and have std::exp as a fallback is to put using std::exp; inside the function and then call just exp. It looks to me we can do that and I made a toy example which works this way. In terms of implementation, it is awkward for us since we also need the right version of exp for return type deduction (before C++14), and it is not allowed to put using std::exp; just inside the struct (only inside a namespace or function body). So it looks like we would need another wrapper function to resolve all that. And then also to avoid conflicts between our function exp and the one we are ADL-looking for.

Enhancement

Most helpful comment

We could really think about using operator() for all the trait classes instead of a named function.
While doing this, we should probably do it consistently across the whole codebase.

All 7 comments

Add-up: my toy implementation to support ADL is as follows, similar to this SO answer.
In math/exp/ExpStdLib.hpp line 30 insert this:

namespace detail
{
    using std::exp;
    template< typename TArg >
    ALPAKA_FN_HOST static auto expStdLib(
        TArg const & arg)
        -> decltype(exp(arg))
    {
        return exp(arg);
    }
}

and then the exp() definition below becomes

ALPAKA_FN_HOST static auto exp(
    ExpStdLib const & exp_ctx,
    TArg const & arg)
    -> decltype(detail::expStdLib(arg))
{
    alpaka::ignore_unused(exp_ctx);
    return detail::expStdLib(arg);
}

I think we should wait until we switch to C++14 else the codebase will explode.

Offline discussion with @psychocoderHPC : yes, so before C++14 my suggestion would bloat the code base of math implementations. In case we use automatic return type deduction, it gets better and my proxy function is not needed. However, there would be still a problem with exp() name hiding. We should probably make Exp to be a functor instead so that there is operator() and no name collisions.

We could really think about using operator() for all the trait classes instead of a named function.
While doing this, we should probably do it consistently across the whole codebase.

So with other changes made now a fix can be done easier with just transforming this line into

using std::exp;
return exp(arg);

This actually does not have issues with the trait function itself being called exp and the ADL starts working properly. However, I am not sure what to do with CUDA and HIP: for these two will the same work for standard types, as now it is ::exp(arg)?

I encountered this issue as well when using Vc (SIMD library) inside kernel code, where the C math functions are also overloaded for SIMD types.

We discussed this in today's meeting. We will implement this for alpaka 0.7.0.

Assigned to @bernhardmgruber.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ax3l picture ax3l  路  4Comments

tdd11235813 picture tdd11235813  路  4Comments

tdd11235813 picture tdd11235813  路  5Comments

ax3l picture ax3l  路  5Comments

BenjaminW3 picture BenjaminW3  路  6Comments