Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@
/build*
/install*

.vscode
.vscode/
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ option(VIKUNJA_ENABLE_EXTRA_WARNINGS "Enable extra warnings" OFF)
option(BUILD_TESTING "Build the testing tree." OFF)
cmake_dependent_option(VIKUNJA_SYSTEM_CATCH2 "Use your local installation of Catch2" ON BUILD_TESTING OFF)
cmake_dependent_option(VIKUNJA_ENABLE_CXX_TEST "Builds test that checks if the C++ standard is set correctly" OFF BUILD_TESTING OFF)
cmake_dependent_option(VIKUNJA_ENABLE_BENCHMARKS "Enable benchmarks" OFF BUILD_TESTING OFF)
cmake_dependent_option(VIKUNJA_ENABLE_BENCHMARKS "Enable benchmarks" ON BUILD_TESTING OFF)
cmake_dependent_option(VIKUNJA_ENABLE_CUDA_THRUST_BENCHMARKS "Enable benchmarks using CUDA Thrust" OFF "VIKUNJA_ENABLE_BENCHMARKS;ALPAKA_ACC_GPU_CUDA_ENABLE" OFF)

# activate support for host/device lambdas in cuda
Expand Down
1 change: 1 addition & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cmake_minimum_required(VERSION 3.18)
add_subdirectory("constantIterator/")
add_subdirectory("reduce/")
add_subdirectory("transform/")
4 changes: 4 additions & 0 deletions example/constantIterator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.18)
set(_TARGET_NAME "example_constant_iterator")
alpaka_add_executable(${_TARGET_NAME} src/constantIterator-main.cpp)
target_link_libraries(${_TARGET_NAME} PUBLIC vikunja::internalvikunja)
81 changes: 81 additions & 0 deletions example/constantIterator/src/constantIterator-main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* Copyright 2021 Hauke Mewes, Simeon Ehrig, Victor
*
* This file is part of vikunja.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <vikunja/mem/iterator/ConstantIterator.hpp>
#include <vikunja/reduce/reduce.hpp>

#include <alpaka/alpaka.hpp>

#include <iostream>


int main()
{
// Define the accelerator here. Must be one of the enabled accelerators.
#ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
using TAcc = alpaka::AccGpuCudaRt<alpaka::DimInt<3u>, std::uint64_t>;
#else
using TAcc = alpaka::AccCpuSerial<alpaka::DimInt<3u>, std::uint64_t>;
#endif
// Type of the data that will be reduced
using TRed = uint64_t;

// Alpaka index type
using Idx = alpaka::Idx<TAcc>;
// Alpaka dimension type
using Dim = alpaka::Dim<TAcc>;
// number of elements to reduce
const Idx n = static_cast<Idx>(6400);

// define device, platform, and queue types.
using DevAcc = alpaka::Dev<TAcc>;
using PltfAcc = alpaka::Pltf<DevAcc>;
// using QueueAcc = alpaka::test::queue::DefaultQueue<alpaka::Dev<TAcc>>;
using PltfHost = alpaka::PltfCpu;
using DevHost = alpaka::Dev<PltfHost>;
using QueueAcc = alpaka::Queue<TAcc, alpaka::Blocking>;

// Get the host device.
DevHost devHost(alpaka::getDevByIdx<PltfHost>(0u));
// Select a device to execute on.
DevAcc devAcc(alpaka::getDevByIdx<PltfAcc>(0u));
// Get a queue on the accelerator device.
QueueAcc queueAcc(devAcc);

// Use Lambda function for reduction
auto sum = [] ALPAKA_FN_HOST_ACC(TRed const i, TRed const j) { return i + j; };
auto doubleNum = [] ALPAKA_FN_HOST_ACC(TRed const i) { return 2 * i; };
std::cout << "Testing accelerator: " << alpaka::getAccName<TAcc>() << " with size: " << n << "\n"
<< "Testing constant iterator with value: 10\n";

// Create the constant iterator
vikunja::iterator::ConstantIterator<TRed> constantIter(10);

// REDUCE CALL:
// Takes the arguments: accelerator device, host device, accelerator queue, size of data, pointer-like to memory,
// reduce lambda.
Idx reduceResult = vikunja::reduce::deviceReduce<TAcc>(devAcc, devHost, queueAcc, n, constantIter, sum);

// check reduce result
auto expectedResult = n * 10;
std::cout << "Expected reduce result: " << expectedResult << ", real result: " << reduceResult << "\n";

// TRANSFORM_REDUCE CALL:
// Takes the arguments: accelerator device, host device, accelerator queue, size of data, pointer-like to memory,
// transform lambda, reduce lambda.
Idx transformReduceResult
= vikunja::reduce::deviceTransformReduce<TAcc>(devAcc, devHost, queueAcc, n, constantIter, doubleNum, sum);

// check transform result
auto expectedTransformReduce = expectedResult * 2;
std::cout << "Expected transform_reduce result: " << expectedTransformReduce
<< ", real result: " << transformReduceResult << "\n";

return 0;
}
231 changes: 231 additions & 0 deletions include/vikunja/mem/iterator/ConstantIterator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/* Copyright 2021 Anton Reinhard
*
* This file is part of vikunja.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#include <alpaka/alpaka.hpp>

#include <iterator>

#if __has_include(<compare>)
# include <compare>
# if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_three_way_comparison)
# define USESPACESHIP
# endif
#endif

#if __has_cpp_attribute(nodiscard)
# define NODISCARD [[nodiscard]]
#else
# define NODISCARD
#endif

namespace vikunja::iterator
{
/**
* @brief A constant iterator, returning a value given initially at any index. As such it has no bounds,
* other than the bounds of the index type used.
* @tparam DataType The type of the data
* @tparam IdxType The type of the index
*/
template<typename DataType, typename IdxType = int64_t>
class ConstantIterator
{
public:
// Need all 5 of these types for iterator_traits
using difference_type = IdxType;
using value_type = DataType;
using pointer = DataType*;
using reference = DataType&;
using iterator_category = std::random_access_iterator_tag;

/**
* @brief Constructor for the ConstantIterator
* @param value The value to initialize the iterator with
* @param idx The index for the iterator, default 0
*/
ALPAKA_FN_HOST_ACC constexpr ConstantIterator(const DataType& value, const IdxType& idx = {})
: v(value)
, index(idx)
{
}

/**
* @brief Dereference operator to receive the stored value
*/
ALPAKA_FN_HOST_ACC NODISCARD constexpr ALPAKA_FN_INLINE const DataType& operator*() const
{
return v;
}

/**
* @brief Index operator to get stored value at some given offset from this iterator
*/
ALPAKA_FN_HOST_ACC NODISCARD constexpr ALPAKA_FN_INLINE const DataType& operator[](int) const
{
return v;
}

#pragma region arithmeticoperators
/**
* @brief Postfix increment operator
* @note Use prefix increment operator instead if possible to avoid copies
*/
ALPAKA_FN_HOST_ACC constexpr ALPAKA_FN_INLINE ConstantIterator operator++()
{
ConstantIterator cpy = *this;
++index;
return cpy;
}

/**
* @brief Prefix increment operator
*/
ALPAKA_FN_HOST_ACC constexpr ALPAKA_FN_INLINE ConstantIterator& operator++(int)
{
++index;
return *this;
}

/**
* @brief Postfix decrement operator
* @note Use prefix decrement operator instead if possible to avoid copies
*/
ALPAKA_FN_HOST_ACC constexpr ALPAKA_FN_INLINE ConstantIterator operator--()
{
ConstantIterator cpy = *this;
--index;
return cpy;
}

/**
* @brief Prefix decrement operator
*/
ALPAKA_FN_HOST_ACC constexpr ALPAKA_FN_INLINE ConstantIterator& operator--(int)
{
--index;
return *this;
}

/**
* @brief Add an index to this iterator
*/
ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE ConstantIterator
operator+(ConstantIterator it, IdxType idx)
{
return it += idx;
}

/**
* @brief Subtract an index from this iterator
*/
ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE ConstantIterator
operator-(ConstantIterator it, const IdxType idx)
{
return it -= idx;
}

/**
* @brief Subtract a second constant iterator of the same value from this one
*/
ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE IdxType
operator-(ConstantIterator it, const ConstantIterator& other)
{
assert(it.v == other.v && "Can't subtract constant iterators of different values!");
return it.index - other.index;
}

/**
* @brief Add an index to this iterator
*/
ALPAKA_FN_HOST_ACC constexpr friend ALPAKA_FN_INLINE ConstantIterator& operator+=(
ConstantIterator& it,
const IdxType idx)
{
it.index += idx;
return it;
}

/**
* @brief Subtract an index from this iterator
*/
ALPAKA_FN_HOST_ACC constexpr friend ALPAKA_FN_INLINE ConstantIterator& operator-=(
ConstantIterator& it,
const IdxType idx)
{
it.index -= idx;
return it;
}

#pragma endregion arithmeticoperators

#pragma region comparisonoperators
Comment thread
bernhardmgruber marked this conversation as resolved.

#ifdef USESPACESHIP

ALPAKA_FN_HOST_ACC NODISCARD constexpr ALPAKA_FN_INLINE auto operator<=>(
const ConstantIterator& other) const noexcept = default;

#else

ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator==(
const ConstantIterator& it,
const ConstantIterator& other) noexcept
{
return it.v == other.v && it.index == other.index;
}

ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator!=(
const ConstantIterator& it,
const ConstantIterator& other) noexcept
{
return !operator==(it, other);
}

ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator<(
const ConstantIterator& it,
const ConstantIterator& other) noexcept
{
if(it.v < other.v)
return true;
if(it.v > other.v)
return false;
return it.index < other.index;
}

ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator>(
const ConstantIterator& it,
const ConstantIterator& other) noexcept
{
return operator<(other, it);
}

ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator<=(
const ConstantIterator& it,
const ConstantIterator& other) noexcept
{
return operator<(it, other) || operator==(it, other);
}

ALPAKA_FN_HOST_ACC NODISCARD constexpr friend ALPAKA_FN_INLINE bool operator>=(
const ConstantIterator& it,
const ConstantIterator& other) noexcept
{
return operator<=(other, it);
}
#endif

#pragma endregion comparisonoperators

private:
DataType v;
IdxType index;
};

} // namespace vikunja::iterator
19 changes: 19 additions & 0 deletions test/benchmarks/reduce/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ add_test(NAME ${_TARGET_NAME_VIKUNJA_REDUCE} COMMAND ${_TARGET_NAME_VIKUNJA_REDU
set_tests_properties(${_TARGET_NAME_VIKUNJA_REDUCE} PROPERTIES RUN_SERIAL TRUE)


set(_TARGET_NAME_VIKUNJA_REDUCE "bench_vikunja_constiter_reduce")

alpaka_add_executable(
${_TARGET_NAME_VIKUNJA_REDUCE}
bench_vikunja_constiter_reduce.cpp
)

target_link_libraries(${_TARGET_NAME_VIKUNJA_REDUCE}
PRIVATE
vikunja::testSetup
vikunja::benchSetup
vikunja::internalvikunja
)

add_test(NAME ${_TARGET_NAME_VIKUNJA_REDUCE} COMMAND ${_TARGET_NAME_VIKUNJA_REDUCE} ${_VIKUNJA_TEST_OPTIONS})
# avoid running the benchmarks in parallel
set_tests_properties(${_TARGET_NAME_VIKUNJA_REDUCE} PROPERTIES RUN_SERIAL TRUE)


if(VIKUNJA_ENABLE_CUDA_THRUST_BENCHMARKS)
set(_TARGET_NAME_THRUST_REDUCE "bench_thrust_reduce")

Expand Down
Loading