Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tags for each alpaka accelerator #1781

Closed

Conversation

psychocoderHPC
Copy link
Member

We discussed today again in the alpaka meeting that it would be nice to have accelerator tags #1246 so that there is no need to use #ifdef to write traits for accelerators.
I had some free minutes and therefore drafted this PR.

  • Provide a file alpaka/acc/Tags.hpp with tags for each alpaka accelerator.
  • Add a concept to uniquely identifies each accelerator with an acc concept
    tag.

PIConGPU example to show the possible effect of the tag.

Code snipped without tags.

template<typename T_Acc = cupla::AccThreadSeq>
struct GetDefaultStrategy
{
    using type = strategy::StridedCachedSupercells;
};

template<typename T_Acc = cupla::AccThreadSeq>
using GetDefaultStrategy_t = typename GetDefaultStrategy<T_Acc>::type;

#if(ALPAKA_ACC_GPU_CUDA_ENABLED == 1)
template<typename... T_Args>
struct GetDefaultStrategy<alpaka::AccGpuUniformCudaHipRt<alpaka::ApiCudaRt, T_Args...>>
{
    // GPU Utilization is higher compared to `StridedCachedSupercells`
    using type = strategy::CachedSupercells;
};
#endif

#if(ALPAKA_ACC_GPU_HIP_ENABLED == 1)
template<typename... T_Args>
struct GetDefaultStrategy<alpaka::AccGpuUniformCudaHipRt<alpaka::ApiHipRt, T_Args...>>
{
    // GPU Utilization is higher compared to `StridedCachedSupercells`
    using type = strategy::CachedSupercellsScaled<2>;
};
#endif

will be changed to without #ifdef

template<typename T_Acc = cupla::AccThreadSeq, typename = void>
struct GetDefaultStrategy
{
    using type = strategy::StridedCachedSupercells;
};

template<typename T_Acc = cupla::AccThreadSeq>
using GetDefaultStrategy_t = typename GetDefaultStrategy<T_Acc>::type;

template<typename T_Acc>
struct GetDefaultStrategy<T_Acc, std::enable_if_t<alpaka::concepts::ImplementsConcept<alpaka::ConceptAccCuda, T_Acc>::value>>
{
    // GPU Utilization is higher compared to `StridedCachedSupercells`
    using type = strategy::CachedSupercells;
};

template<typename T_Acc>
struct GetDefaultStrategy<T_Acc, std::enable_if_t<alpaka::concepts::ImplementsConcept<alpaka::ConceptAccHip, T_Acc>::value>>
{
    // GPU Utilization is higher compared to `StridedCachedSupercells`
    using type = strategy::CachedSupercellsScaled<2>;
};

CC-ing: @SimeonEhrig

@psychocoderHPC
Copy link
Member Author

psychocoderHPC commented Aug 30, 2022

example how to get the real acc type out of the tag used in a trait

template<typename T_Acc>
struct GetDefaultStrategy<T_Acc, std::enable_if_t<alpaka::concepts::ImplementsConcept<alpaka::ConceptAccHip, T_Acc>::value>>
{
    // this will provide alpaka::AccGpuUniformCudaHipRt<alpaka::ApiHipRt, DimType, IdxType>
    using realAccType = typename concepts::ImplementationBase<alpaka::ConceptAccHip, T_Acc>;
};

- Provide a file `alpaka/acc/Tags.hpp` with tags for each alpaka accelerator.
- Add a concept to unique identify each accelerator with a acc concept
tag.
@fwyzard
Copy link
Contributor

fwyzard commented Aug 30, 2022

@psychocoderHPC does it mean that all possible accelerator tags will always be defined, even if the corresponding accelerators and backends are not available ?

@bernhardmgruber
Copy link
Member

I am not sure the accelerator tags should be provided via the concepts mechanism, since they are not concepts in the C++ sense. E.g. the CUDA and OMP2 accelerator concepts impose the same syntactic requirements. In other words, we cannot turn these into C++20 concepts at some point.

Since tags and accelerators are bijective, I also miss type functions to map between them:

using Tag = alpaka::TagFor<Acc>;
using Acc = alpaka::AccFor<Tag, Dim, Idx>;

Checking whether a type Acc is a certain accelerator, instead of:
alpaka::concepts::ImplementsConcept<alpaka::ConceptAccCuda, Acc>
would look like this:
std::is_same_v<alpaka::Tag<Acc>, alpaka::ConceptAccCuda>

Or multiple:
mp_contains<mp_list<alpaka::ConceptOmp2, alpaka::ConceptOmp4, alpaka::Threads>, alpaka::Tag<Acc>>

@bernhardmgruber
Copy link
Member

@psychocoderHPC does it mean that all possible accelerator tags will always be defined, even if the corresponding accelerators and backends are not available ?

This is my understanding.

@psychocoderHPC
Copy link
Member Author

@psychocoderHPC does it mean that all possible accelerator tags will always be defined, even if the corresponding accelerators and backends are not available ?

In my draft, the tags will always be available and this tag can be used to check what type a "anonymous" accelerator is.
Each tag has a 1:1 relation to an accelerator. This allows writing type traits with an available sfinae template parameter without the ugly #ifdef macro.

@psychocoderHPC
Copy link
Member Author

psychocoderHPC commented Aug 30, 2022

@bernhardmgruber

would look like this:
std::is_same_v<alpaka::Tag<Acc>, alpaka::ConceptAccCuda>

Yes a separate trait is possible too. At the end I like to converge to the suggestion #944 that we can use the tags to write simple interfaces to allocate devices too (note: I am aware that my simple example in the issue is mixing devices and accelerators)

constexpr size_t dim = 1;
auto numDevices = simple:acc::count(simple::acc::GpuCuda);

This draft is a discussion base and I am open to move into all direction to find a useful and practical solution to avoid #ifdef

@SimeonEhrig
Copy link
Member

SimeonEhrig commented Aug 31, 2022

We need also a functionality to specialize functions with tags instead the acc type like in the kernel specialization example: https://github.com/alpaka-group/alpaka/blob/develop/example/kernelSpecialization/src/kernelSpecialization.cpp

After a offline discussion, I recognized it is not useful because it only works, if the the function contains generic code and nothing acc specific, like CUDA built in functions in a kernel specialized for the CUDA acc.

@SimeonEhrig
Copy link
Member

I am not sure the accelerator tags should be provided via the concepts mechanism, since they are not concepts in the C++ sense. E.g. the CUDA and OMP2 accelerator concepts impose the same syntactic requirements. In other words, we cannot turn these into C++20 concepts at some point.

Since tags and accelerators are bijective, I also miss type functions to map between them:

using Tag = alpaka::TagFor<Acc>;
using Acc = alpaka::AccFor<Tag, Dim, Idx>;

Checking whether a type Acc is a certain accelerator, instead of: alpaka::concepts::ImplementsConcept<alpaka::ConceptAccCuda, Acc> would look like this: std::is_same_v<alpaka::Tag<Acc>, alpaka::ConceptAccCuda>

Or multiple: mp_contains<mp_list<alpaka::ConceptOmp2, alpaka::ConceptOmp4, alpaka::Threads>, alpaka::Tag<Acc>>

I already implemented the using Tag = alpaka::TagFor<Acc>; trait in my prototype and a constexpr function to compare an acc type with a tag type.

@SimeonEhrig
Copy link
Member

I implemented a prototype of acc tags in vinkuja: alpaka-group/vikunja@565823f

I used vikunja, because I have a use case for the acc tags and also for memory visibility tags (see this issue: #1362). I want to use both to improve the API of vikunja. Now, my plan is to integrate the prototype for acc tags (and memory visibility later) in alpaka to make it available for all alpaka users.

@SimeonEhrig
Copy link
Member

tags are implemented in PR #1804

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants