Skip to content

Commit

Permalink
Merge pull request #39919 from fwyzard/alpaka_framework
Browse files Browse the repository at this point in the history
Improve the SoA accessors and optimisations
  • Loading branch information
cmsbuild authored Nov 16, 2022
2 parents 0c3e790 + 067becf commit d7777e0
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 71 deletions.
5 changes: 3 additions & 2 deletions DataFormats/SoATemplate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ Serialization of Eigen data is not yet supported.
The template shared by layouts and parameters are:
- Byte aligment (defaulting to the nVidia GPU cache line size (128 bytes))
- Alignment enforcement (`relaxed` or `enforced`). When enforced, the alignment will be checked at construction
time, and the accesses are done with compiler hinting (using the widely supported `__builtin_assume_aligned`
intrinsic).
time.~~, and the accesses are done with compiler hinting (using the widely supported `__builtin_assume_aligned`
intrinsic).~~ It turned out that hinting `nvcc` for alignement removed the benefit of more important `__restrict__`
hinting. The `__builtin_assume_aligned` is hence currently not use.

In addition, the views also provide access parameters:
- Restrict qualify: add restrict hints to read accesses, so that the compiler knows it can relax accesses to the
Expand Down
91 changes: 46 additions & 45 deletions DataFormats/SoATemplate/interface/SoACommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,19 +287,19 @@ namespace cms::soa {

SOA_HOST_DEVICE SOA_INLINE Ref operator()() {
// Ptr type will add the restrict qualifyer if needed
Ptr col = alignedCol();
Ptr col = col_;
return col[idx_];
}

SOA_HOST_DEVICE SOA_INLINE RefToConst operator()() const {
// PtrToConst type will add the restrict qualifyer if needed
PtrToConst col = alignedCol();
PtrToConst col = col_();
return col[idx_];
}

SOA_HOST_DEVICE SOA_INLINE Ptr operator&() { return &alignedCol()[idx_]; }
SOA_HOST_DEVICE SOA_INLINE Ptr operator&() { return &col_[idx_]; }

SOA_HOST_DEVICE SOA_INLINE PtrToConst operator&() const { return &alignedCol()[idx_]; }
SOA_HOST_DEVICE SOA_INLINE PtrToConst operator&() const { return &col_[idx_]; }

/* This was an attempt to implement the syntax
*
Expand All @@ -318,7 +318,7 @@ namespace cms::soa {
template <typename T2>
SOA_HOST_DEVICE SOA_INLINE Ref operator=(const T2& v) {
return alignedCol()[idx_] = v;
return col_[idx_] = v;
}
*/

Expand All @@ -327,13 +327,6 @@ namespace cms::soa {
static constexpr auto valueSize = sizeof(T);

private:
SOA_HOST_DEVICE SOA_INLINE Ptr alignedCol() const {
if constexpr (ALIGNMENT) {
return reinterpret_cast<Ptr>(__builtin_assume_aligned(col_, ALIGNMENT));
}
return reinterpret_cast<Ptr>(col_);
}

size_type idx_;
T* col_;
};
Expand Down Expand Up @@ -437,11 +430,11 @@ namespace cms::soa {

SOA_HOST_DEVICE SOA_INLINE RefToConst operator()() const {
// Ptr type will add the restrict qualifyer if needed
PtrToConst col = alignedCol();
PtrToConst col = col_;
return col[idx_];
}

SOA_HOST_DEVICE SOA_INLINE const T* operator&() const { return &alignedCol()[idx_]; }
SOA_HOST_DEVICE SOA_INLINE const T* operator&() const { return &col_[idx_]; }

/* This was an attempt to implement the syntax
*
Expand All @@ -461,13 +454,6 @@ namespace cms::soa {
static constexpr auto valueSize = sizeof(T);

private:
SOA_HOST_DEVICE SOA_INLINE PtrToConst alignedCol() const {
if constexpr (ALIGNMENT) {
return reinterpret_cast<PtrToConst>(__builtin_assume_aligned(col_, ALIGNMENT));
}
return reinterpret_cast<PtrToConst>(col_);
}

size_type idx_;
const T* col_;
};
Expand Down Expand Up @@ -584,47 +570,49 @@ namespace cms::soa {
/* Column accessors: templates implementing the global accesors (soa::x() and soa::x(index) */
enum class SoAAccessType : bool { mutableAccess, constAccess };

template <typename, SoAColumnType, SoAAccessType>
template <typename, SoAColumnType, SoAAccessType, byte_size_type, bool>
struct SoAColumnAccessorsImpl {};

// TODO from Eric Cano:
// - add alignment support
// - SFINAE-based const/non const variants

// Column
template <typename T>
struct SoAColumnAccessorsImpl<T, SoAColumnType::column, SoAAccessType::mutableAccess> {
//SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(T* baseAddress) : baseAddress_(baseAddress) {}
template <typename T, byte_size_type alignment, bool restrictQualify>
struct SoAColumnAccessorsImpl<T, SoAColumnType::column, SoAAccessType::mutableAccess, alignment, restrictQualify> {
SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(const SoAParametersImpl<SoAColumnType::column, T>& params)
: params_(params) {}
SOA_HOST_DEVICE SOA_INLINE T* operator()() { return params_.addr_; }
using NoParamReturnType = T*;
using ParamReturnType = T&;
SOA_HOST_DEVICE SOA_INLINE T& operator()(size_type index) { return params_.addr_[index]; }

private:
SoAParametersImpl<SoAColumnType::column, T> params_;
};

// Const column
template <typename T>
struct SoAColumnAccessorsImpl<T, SoAColumnType::column, SoAAccessType::constAccess> {
template <typename T, byte_size_type alignment, bool restrictQualify>
struct SoAColumnAccessorsImpl<T, SoAColumnType::column, SoAAccessType::constAccess, alignment, restrictQualify> {
SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(const SoAConstParametersImpl<SoAColumnType::column, T>& params)
: params_(params) {}
SOA_HOST_DEVICE SOA_INLINE const T* operator()() const { return params_.addr_; }
using NoParamReturnType = const T*;
SOA_HOST_DEVICE SOA_INLINE T operator()(size_type index) const { return params_.addr_[index]; }
using ParamReturnType = const T&;
SOA_HOST_DEVICE SOA_INLINE T const& operator()(size_type index) const { return params_.addr_[index]; }

private:
SoAConstParametersImpl<SoAColumnType::column, T> params_;
};

// Scalar
template <typename T>
struct SoAColumnAccessorsImpl<T, SoAColumnType::scalar, SoAAccessType::mutableAccess> {
template <typename T, byte_size_type alignment, bool restrictQualify>
struct SoAColumnAccessorsImpl<T, SoAColumnType::scalar, SoAAccessType::mutableAccess, alignment, restrictQualify> {
SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(const SoAParametersImpl<SoAColumnType::scalar, T>& params)
: params_(params) {}
SOA_HOST_DEVICE SOA_INLINE T& operator()() { return *params_.addr_; }
using NoParamReturnType = T&;
using ParamReturnType = void;
SOA_HOST_DEVICE SOA_INLINE void operator()(size_type index) const {
assert(false && "Indexed access impossible for SoA scalars.");
}
Expand All @@ -634,12 +622,13 @@ namespace cms::soa {
};

// Const scalar
template <typename T>
struct SoAColumnAccessorsImpl<T, SoAColumnType::scalar, SoAAccessType::constAccess> {
template <typename T, byte_size_type alignment, bool restrictQualify>
struct SoAColumnAccessorsImpl<T, SoAColumnType::scalar, SoAAccessType::constAccess, alignment, restrictQualify> {
SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(const SoAConstParametersImpl<SoAColumnType::scalar, T>& params)
: params_(params) {}
SOA_HOST_DEVICE SOA_INLINE T operator()() const { return *params_.addr_; }
using NoParamReturnType = T;
SOA_HOST_DEVICE SOA_INLINE T const& operator()() const { return *params_.addr_; }
using NoParamReturnType = T const&;
using ParamReturnType = void;
SOA_HOST_DEVICE SOA_INLINE void operator()(size_type index) const {
assert(false && "Indexed access impossible for SoA scalars.");
}
Expand All @@ -649,27 +638,32 @@ namespace cms::soa {
};

// Eigen-type
template <typename T>
struct SoAColumnAccessorsImpl<T, SoAColumnType::eigen, SoAAccessType::mutableAccess> {
//SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(T* baseAddress) : baseAddress_(baseAddress) {}
template <typename T, byte_size_type alignment, bool restrictQualify>
struct SoAColumnAccessorsImpl<T, SoAColumnType::eigen, SoAAccessType::mutableAccess, alignment, restrictQualify> {
SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(const SoAParametersImpl<SoAColumnType::eigen, T>& params)
: params_(params) {}
SOA_HOST_DEVICE SOA_INLINE typename T::Scalar* operator()() { return params_.addr_; }
using NoParamReturnType = typename T::Scalar*;
//SOA_HOST_DEVICE SOA_INLINE T& operator()(size_type index) { return params_.addr_[index]; }
using ParamReturnType = typename SoAValue<SoAColumnType::eigen, T, alignment, restrictQualify>::MapType;
SOA_HOST_DEVICE SOA_INLINE ParamReturnType operator()(size_type index) {
return SoAValue<SoAColumnType::eigen, T, alignment, restrictQualify>(index, params_)();
}

private:
SoAParametersImpl<SoAColumnType::eigen, T> params_;
};

// Const Eigen-type
template <typename T>
struct SoAColumnAccessorsImpl<T, SoAColumnType::eigen, SoAAccessType::constAccess> {
template <typename T, byte_size_type alignment, bool restrictQualify>
struct SoAColumnAccessorsImpl<T, SoAColumnType::eigen, SoAAccessType::constAccess, alignment, restrictQualify> {
SOA_HOST_DEVICE SOA_INLINE SoAColumnAccessorsImpl(const SoAConstParametersImpl<SoAColumnType::eigen, T>& params)
: params_(params) {}
SOA_HOST_DEVICE SOA_INLINE const typename T::Scalar* operator()() const { return params_.addr_; }
using NoParamReturnType = typename T::Scalar*;
//SOA_HOST_DEVICE SOA_INLINE T operator()(size_type index) const { return params_.addr_[index]; }
SOA_HOST_DEVICE SOA_INLINE typename T::Scalar const* operator()() const { return params_.addr_; }
using NoParamReturnType = typename T::Scalar const*;
using ParamReturnType = typename SoAValue<SoAColumnType::eigen, T, alignment, restrictQualify>::CMapType;
SOA_HOST_DEVICE SOA_INLINE ParamReturnType operator()(size_type index) const {
return SoAConstValue<SoAColumnType::eigen, T, alignment, restrictQualify>(index, params_)();
}

private:
SoAConstParametersImpl<SoAColumnType::eigen, T> params_;
Expand All @@ -681,8 +675,15 @@ namespace cms::soa {
template <auto columnType>
struct ColumnType {
template <auto accessType>
struct AccessType : public SoAColumnAccessorsImpl<T, columnType, accessType> {
using SoAColumnAccessorsImpl<T, columnType, accessType>::SoAColumnAccessorsImpl;
struct AccessType {
template <auto alignment>
struct Alignment {
template <auto restrictQualify>
struct RestrictQualifier
: public SoAColumnAccessorsImpl<T, columnType, accessType, alignment, restrictQualify> {
using SoAColumnAccessorsImpl<T, columnType, accessType, alignment, restrictQualify>::SoAColumnAccessorsImpl;
};
};
};
};
};
Expand Down
11 changes: 0 additions & 11 deletions DataFormats/SoATemplate/interface/SoALayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,17 +581,6 @@
throw std::runtime_error("In " #CLASS "::" #CLASS ": unexpected end pointer."); \
} \
\
/* Range checker conditional to the macro _DO_RANGECHECK */ \
SOA_HOST_DEVICE SOA_INLINE \
void rangeCheck(size_type index) const { \
if constexpr (_DO_RANGECHECK) { \
if (index >= elements_) { \
printf("In " #CLASS "::rangeCheck(): index out of range: %zu with elements: %zu\n", index, elements_); \
assert(false); \
} \
} \
} \
\
/* Data members */ \
std::byte* mem_; \
size_type elements_; \
Expand Down
Loading

0 comments on commit d7777e0

Please sign in to comment.