alpaka
alpaka copied to clipboard
add tags for each alpaka accelerator
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
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>;
};
@psychocoderHPC does it mean that all possible accelerator tags will always be defined, even if the corresponding accelerators and backends are not available ?
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>>
@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 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.
@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 https://github.com/alpaka-group/alpaka/issues/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
~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.
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.
I implemented a prototype of acc tags in vinkuja: https://github.com/alpaka-group/vikunja/pull/88/commits/565823f87f7710c83786be476f73ee4275115d89
I used vikunja, because I have a use case for the acc tags and also for memory visibility tags (see this issue: https://github.com/alpaka-group/alpaka/issues/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.
tags are implemented in PR #1804