Skip to content

Commit

Permalink
add memory visibility to raw pointer view
Browse files Browse the repository at this point in the history
CI_FILTER: nope
  • Loading branch information
SimeonEhrig committed May 13, 2024
1 parent 1d7d320 commit bdbd4bc
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 74 deletions.
7 changes: 3 additions & 4 deletions include/alpaka/mem/Visibility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include "alpaka/mem/view/ViewAccessOps.hpp"
#include "alpaka/meta/ForEachType.hpp"
#include "alpaka/meta/IsTuple.hpp"
#include "alpaka/meta/TypeListOps.hpp"

#include <iostream>
Expand All @@ -17,7 +16,7 @@
#define CREATE_MEM_VISIBILITY(mem_name) \
struct mem_name \
{ \
static std::string name() \
static std::string get_name() \
{ \
return #mem_name; \
} \
Expand Down Expand Up @@ -49,7 +48,7 @@ namespace alpaka
template<typename TTYPE>
void operator()(std::vector<std::string>& vs)
{
vs.push_back(TTYPE::name());
vs.push_back(TTYPE::get_name());
}
};
} // namespace detail
Expand Down Expand Up @@ -84,7 +83,7 @@ namespace alpaka
}
else
{
return MemVisibilityType::name();
return MemVisibilityType::get_name();
}
}

Expand Down
70 changes: 46 additions & 24 deletions include/alpaka/mem/view/ViewPlainPtr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@
#include "alpaka/dev/DevCpu.hpp"
#include "alpaka/dev/DevGenericSycl.hpp"
#include "alpaka/dev/DevUniformCudaHipRt.hpp"
#include "alpaka/mem/Visibility.hpp"
#include "alpaka/mem/view/Traits.hpp"
#include "alpaka/mem/view/ViewAccessOps.hpp"
#include "alpaka/meta/DependentFalseType.hpp"
#include "alpaka/meta/TypeListOps.hpp"
#include "alpaka/platform/PlatformCpu.hpp"
#include "alpaka/platform/PlatformCpuSycl.hpp"
#include "alpaka/platform/PlatformCudaRt.hpp"
#include "alpaka/platform/PlatformFpgaSyclIntel.hpp"
#include "alpaka/platform/PlatformGenericSycl.hpp"
#include "alpaka/platform/PlatformGpuSyclIntel.hpp"
#include "alpaka/platform/PlatformHipRt.hpp"
#include "alpaka/vec/Vec.hpp"

#include <type_traits>
Expand All @@ -19,8 +28,14 @@
namespace alpaka
{
//! The memory view to wrap plain pointers.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct ViewPlainPtr final : internal::ViewAccessOps<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<
typename TDev,
typename TElem,
typename TDim,
typename TIdx,
typename TMemVisibility =
typename alpaka::meta::toTuple<typename alpaka::trait::MemVisibility<alpaka::Platform<TDev>>::type>::type>
struct ViewPlainPtr final : internal::ViewAccessOps<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
static_assert(!std::is_const_v<TIdx>, "The idx type of the view can not be const!");

Expand Down Expand Up @@ -49,15 +64,21 @@ namespace alpaka
namespace trait
{
//! The ViewPlainPtr device type trait specialization.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct DevType<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct DevType<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
using type = alpaka::Dev<TDev>;
};

template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct MemVisibility<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
using type = TMemVisibility;
};

//! The ViewPlainPtr device get trait specialization.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct GetDev<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct GetDev<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
static auto getDev(ViewPlainPtr<TDev, TElem, TDim, TIdx> const& view) -> alpaka::Dev<TDev>
{
Expand All @@ -66,48 +87,48 @@ namespace alpaka
};

//! The ViewPlainPtr dimension getter trait.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct DimType<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct DimType<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
using type = TDim;
};

//! The ViewPlainPtr memory element type get trait specialization.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct ElemType<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct ElemType<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
using type = TElem;
};
} // namespace trait

namespace trait
{
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct GetExtents<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct GetExtents<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
ALPAKA_FN_HOST auto operator()(ViewPlainPtr<TDev, TElem, TDim, TIdx> const& view) const
ALPAKA_FN_HOST auto operator()(ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility> const& view) const
{
return view.m_extentElements;
}
};

//! The ViewPlainPtr native pointer get trait specialization.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct GetPtrNative<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct GetPtrNative<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
static auto getPtrNative(ViewPlainPtr<TDev, TElem, TDim, TIdx> const& view) -> TElem const*
static auto getPtrNative(ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility> const& view) -> TElem const*
{
return view.m_pMem;
}

static auto getPtrNative(ViewPlainPtr<TDev, TElem, TDim, TIdx>& view) -> TElem*
static auto getPtrNative(ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>& view) -> TElem*
{
return view.m_pMem;
}
};

template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct GetPitchesInBytes<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct GetPitchesInBytes<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
ALPAKA_FN_HOST auto operator()(ViewPlainPtr<TDev, TElem, TDim, TIdx> const& view) const
{
Expand Down Expand Up @@ -174,18 +195,19 @@ namespace alpaka
};
#endif
//! The ViewPlainPtr offset get trait specialization.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct GetOffsets<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct GetOffsets<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
ALPAKA_FN_HOST auto operator()(ViewPlainPtr<TDev, TElem, TDim, TIdx> const&) const -> Vec<TDim, TIdx>
ALPAKA_FN_HOST auto operator()(ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility> const&) const
-> Vec<TDim, TIdx>
{
return Vec<TDim, TIdx>::zeros();
}
};

//! The ViewPlainPtr idx type trait specialization.
template<typename TDev, typename TElem, typename TDim, typename TIdx>
struct IdxType<ViewPlainPtr<TDev, TElem, TDim, TIdx>>
template<typename TDev, typename TElem, typename TDim, typename TIdx, typename TMemVisibility>
struct IdxType<ViewPlainPtr<TDev, TElem, TDim, TIdx, TMemVisibility>>
{
using type = TIdx;
};
Expand Down
29 changes: 0 additions & 29 deletions include/alpaka/meta/IsTuple.hpp

This file was deleted.

33 changes: 32 additions & 1 deletion include/alpaka/meta/TypeListOps.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* Copyright 2022 Bernhard Manfred Gruber
/* Copyright 2024 Bernhard Manfred Gruber, Simeon Ehrig
* SPDX-License-Identifier: MPL-2.0
*/

#pragma once

#include <tuple>
#include <type_traits>

namespace alpaka::meta
Expand Down Expand Up @@ -35,4 +36,34 @@ namespace alpaka::meta
{
static constexpr bool value = std::is_same_v<Head, Value> || Contains<List<Tail...>, Value>::value;
};

// copied from https://stackoverflow.com/a/51073558/22035743
template<typename T>
struct IsTuple : std::false_type
{
};

template<typename... U>
struct IsTuple<std::tuple<U...>> : std::true_type
{
};

template<typename T>
constexpr bool isTuple()
{
return IsTuple<std::decay_t<T>>::value;
}

template<typename... T>
struct toTuple
{
using type = std::tuple<T...>;
};

template<typename... U>
struct toTuple<std::tuple<U...>>
{
using type = std::tuple<U...>;
};

} // namespace alpaka::meta
102 changes: 86 additions & 16 deletions test/unit/mem/src/Visibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,39 @@
using Dim = alpaka::DimInt<1>;
using Idx = std::size_t;

using ExpectedTagsMemVisibilities = std::tuple<
std::tuple<alpaka::TagCpuSerial, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuThreads, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuTbbBlocks, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuOmp2Blocks, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuOmp2Threads, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagGpuCudaRt, alpaka::MemVisibleGpuCudaRt>,
std::tuple<alpaka::TagGpuHipRt, alpaka::MemVisibleGpuHipRt>,
std::tuple<alpaka::TagCpuSycl, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagFpgaSyclIntel, alpaka::MemVisibleFpgaSyclIntel>,
std::tuple<alpaka::TagGpuSyclIntel, alpaka::MemVisibleGpuSyclIntel>>;
template<typename TTagMemView, typename = void>
struct AccIsEnabledMemVisibilities : std::false_type
{
};

template<typename TTagMemView>
struct AccIsEnabledMemVisibilities<
TTagMemView,
std::void_t<alpaka::TagToAcc<std::tuple_element_t<0, TTagMemView>, alpaka::DimInt<1>, int>>> : std::true_type
{
};

using ExpectedTagsMemVisibilities = alpaka::meta::Filter<
std::tuple<
std::tuple<alpaka::TagCpuSerial, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuThreads, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuTbbBlocks, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuOmp2Blocks, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagCpuOmp2Threads, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagGpuCudaRt, alpaka::MemVisibleGpuCudaRt>,
std::tuple<alpaka::TagGpuHipRt, alpaka::MemVisibleGpuHipRt>,
std::tuple<alpaka::TagCpuSycl, alpaka::MemVisibleCPU>,
std::tuple<alpaka::TagFpgaSyclIntel, alpaka::MemVisibleFpgaSyclIntel>,
std::tuple<alpaka::TagGpuSyclIntel, alpaka::MemVisibleGpuSyclIntel>>,
AccIsEnabledMemVisibilities>;

TEMPLATE_LIST_TEST_CASE("memoryVisibilityType", "[mem][visibility]", ExpectedTagsMemVisibilities)
{
using Tag = std::tuple_element_t<0, TestType>;
using ExpectedMemVisibility = std::tuple_element_t<1, TestType>;

if constexpr(alpaka::AccIsEnabled<Tag>::value)
{
using PltfType = alpaka::Platform<alpaka::TagToAcc<Tag, Dim, Idx>>;
STATIC_REQUIRE(std::is_same_v<typename alpaka::trait::MemVisibility<PltfType>::type, ExpectedMemVisibility>);
}
using PltfType = alpaka::Platform<alpaka::TagToAcc<Tag, Dim, Idx>>;
STATIC_REQUIRE(std::is_same_v<typename alpaka::trait::MemVisibility<PltfType>::type, ExpectedMemVisibility>);
}

using EnabledTagTagList = alpaka::meta::CartesianProduct<std::tuple, alpaka::EnabledAccTags, alpaka::EnabledAccTags>;
Expand Down Expand Up @@ -84,3 +95,62 @@ TEMPLATE_LIST_TEST_CASE("testHasSameMemView", "[mem][visibility]", EnabledTagTag
STATIC_REQUIRE_FALSE(alpaka::hasSameMemView<Acc2, BufAcc1>());
}
}

using EnabledTagTagMemVisibilityList
= alpaka::meta::CartesianProduct<std::tuple, ExpectedTagsMemVisibilities, ExpectedTagsMemVisibilities>;

TEMPLATE_LIST_TEST_CASE("testMemView", "[mem][visibility]", EnabledTagTagMemVisibilityList)
{
using Tag1 = std::tuple_element_t<0, std::tuple_element_t<0, TestType>>;
using ExpectedMemVisibilityForTag1 = std::tuple_element_t<1, std::tuple_element_t<0, TestType>>;
using Tag2 = std::tuple_element_t<0, std::tuple_element_t<1, TestType>>;
using ExpectedMemVisibilityForTag2 = std::tuple_element_t<1, std::tuple_element_t<1, TestType>>;

SUCCEED(
"Tag1: " << Tag1::get_name() << " + " << ExpectedMemVisibilityForTag1::get_name()
<< "\nTag2: " << Tag2::get_name() << " + " << ExpectedMemVisibilityForTag1::get_name());


constexpr Idx data_size = 10;

using Acc1 = alpaka::TagToAcc<Tag1, Dim, Idx>;
using Acc2 = alpaka::TagToAcc<Tag2, Dim, Idx>;

auto const plt1 = alpaka::Platform<Acc1>{};
auto const plt2 = alpaka::Platform<Acc2>{};

auto const dev1 = alpaka::getDevByIdx(plt1, 0);
auto const dev2 = alpaka::getDevByIdx(plt2, 0);

using Vec1D = alpaka::Vec<alpaka::DimInt<1>, Idx>;
Vec1D const extents(Vec1D::all(data_size));

std::array<int, data_size> data;

// STATIC_REQUIRE(std::is_same_v<typename alpaka::meta::toTuple<std::tuple<int, int>>::type, std::tuple<int,
// int>>); STATIC_REQUIRE(std::is_same_v<typename alpaka::meta::toTuple<int>::type, std::tuple<int>>);
// STATIC_REQUIRE(std::is_same_v<typename alpaka::meta::toTuple<int, float>::type, std::tuple<int, float>>);

auto data_view1 = alpaka::createView(dev1, data.data(), extents);
STATIC_REQUIRE(std::is_same_v<
typename alpaka::trait::MemVisibility<decltype(data_view1)>::type,
std::tuple<ExpectedMemVisibilityForTag1>>);
STATIC_REQUIRE(alpaka::hasSameMemView(plt1, data_view1));

auto data_view2 = alpaka::createView(dev2, data.data(), extents);
STATIC_REQUIRE(std::is_same_v<
typename alpaka::trait::MemVisibility<decltype(data_view2)>::type,
std::tuple<ExpectedMemVisibilityForTag2>>);
STATIC_REQUIRE(alpaka::hasSameMemView(plt2, data_view2));

if constexpr(std::is_same_v<ExpectedMemVisibilityForTag1, ExpectedMemVisibilityForTag2>)
{
STATIC_REQUIRE(alpaka::hasSameMemView(plt1, data_view2));
STATIC_REQUIRE(alpaka::hasSameMemView(plt2, data_view1));
}
else
{
STATIC_REQUIRE_FALSE(alpaka::hasSameMemView(plt1, data_view2));
STATIC_REQUIRE_FALSE(alpaka::hasSameMemView(plt2, data_view1));
}
}

0 comments on commit bdbd4bc

Please sign in to comment.