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

Adding HPX backend #235

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
104 changes: 104 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Copyright (c) 2016 Thomas Heller
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR includes a .clang-format file. Are you suggesting this as a code formatting standard for the project?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't suggest using this formatting style. I guess I suggest using any .clang-format to simplify contributions. The file I used was simply taken from HPX (with minor changes). Do you have any coding guidelines for this project? I'd be happy to adapt everything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hkaiser An excellent idea! Ideally I would like the code to be formatted like the C++ Standard document. I don't think clang-format has a standard preset for that. I'll ask around for how to do this.

# Copyright (c) 2016-2022 Hartmut Kaiser

---
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BeforeLambdaBody: false
BeforeWhile: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: true
BreakBeforeTernaryOperators: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: ///
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth : 2
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
FixNamespaceComments: true
IncludeCategories:
- Regex: '^<hpx/config\.hpp>'
Priority: 1
- Regex: '^<hpx/config/.*\.hpp>'
Priority: 2
- Regex: '^<hpx/.*/config\.hpp>'
Priority: 3
- Regex: '^<hpx/.*/config/defines\.hpp>'
Priority: 4
- Regex: '^<hpx/.*\.hpp>'
Priority: 5
- Regex: '^<hpx/parallel/.*\.hpp>'
Priority: 6
- Regex: '^<.*'
Priority: 7
- Regex: '.*'
Priority: 8
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: false
SortIncludes: true
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 4
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never
...
34 changes: 34 additions & 0 deletions .github/workflows/linux_hpx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) 2022 Hartmut Kaiser

name: HPX Backend CI (Debug)

on: [pull_request]

jobs:
build:
runs-on: ubuntu-latest
container: stellargroup/hpx:dev

steps:
- uses: actions/checkout@v2
- name: Configure
shell: bash
run: |
cmake \
. \
-Bbuild \
-GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DLINALG_ENABLE_TESTS=On \
-DLINALG_ENABLE_HPX=On \
-DLINALG_ENABLE_HPX_DEFAULT=On \
-DHPX_DIR=/hpx/build/lib/cmake/HPX
- name: Build
shell: bash
run: |
make
- name: Test
shell: bash
run: |
cd build
ctest --output-on-failure
20 changes: 19 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ project(LinAlg
LANGUAGES CXX
)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

################################################################################

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
Expand Down Expand Up @@ -121,7 +123,7 @@ option(LINALG_ENABLE_BLAS
"Assume that we are linking with a BLAS library."
${BLAS_FOUND})

find_package(KokkosKernels)
find_package(KokkosKernels QUIET)
option(LINALG_ENABLE_KOKKOS
"Enable Kokkos-based implementation. Default: autodetect Kokkos installation."
${KokkosKernels_FOUND})
Expand Down Expand Up @@ -152,6 +154,22 @@ if(LINALG_ENABLE_KOKKOS)
)
endif()

if(LINALG_ENABLE_HPX)
find_package(HPX 1.8.1 REQUIRED)
target_link_libraries(linalg INTERFACE HPX::hpx)
target_include_directories(linalg INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/tpl-implementations/include>
)
if(MSVC)
target_compile_definitions(linalg INTERFACE NOMINMAX _CRT_SECURE_NO_WARNINGS)
endif()
message(STATUS "HPX version: " ${HPX_VERSION_STRING})
endif()

if(LINALG_ENABLE_KOKKOS_DEFAULT AND LINALG_ENABLE_HPX_DEFAULT)
message(FATAL_ERROR "Only one of the Kokkos and HPX backends can be marked as default. Please set either LINALG_ENABLE_KOKKOS_DEFAULT or LINALG_ENABLE_HPX_DEFAULT to OFF")
endif()

target_include_directories(linalg INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
Expand Down
6 changes: 5 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

function(linalg_add_example EXENAME)
add_executable(${EXENAME} ${EXENAME}.cpp)
target_link_libraries(${EXENAME} linalg)
target_link_libraries(${EXENAME} PRIVATE linalg)
set_target_properties(${EXENAME} PROPERTIES FOLDER "Examples")
endfunction(linalg_add_example)

linalg_add_example(01_scale)
Expand All @@ -11,3 +12,6 @@ linalg_add_example(03_matrix_vector_product_mixedprec)
if(LINALG_ENABLE_KOKKOS)
add_subdirectory(kokkos-based)
endif()
if(LINALG_ENABLE_HPX)
add_subdirectory(hpx-based)
endif()
19 changes: 19 additions & 0 deletions examples/hpx-based/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2022 Hartmut Kaiser

function(linalg_add_example_hpx EXENAME)
linalg_add_example(${EXENAME})
if(LINALG_ENABLE_HPX)
target_link_libraries(${EXENAME} PRIVATE HPX::wrap_main)
endif()
set_target_properties(${EXENAME} PROPERTIES FOLDER "Examples/HPX")
endfunction(linalg_add_example_hpx)

linalg_add_example_hpx(add_hpx)
#linalg_add_example_hpx(dot_hpx)
#linalg_add_example_hpx(dotc_hpx)
#linalg_add_example_hpx(idx_abs_max_hpx)
#linalg_add_example_hpx(vector_norm2_hpx)
#linalg_add_example_hpx(vector_abs_sum_hpx)
#linalg_add_example_hpx(vector_sum_of_squares_hpx)
linalg_add_example_hpx(scale_hpx)
#linalg_add_example_hpx(matrix_vector_product_hpx)
118 changes: 118 additions & 0 deletions examples/hpx-based/add_hpx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright (c) 2022 Hartmut Kaiser

#include <hpx/execution.hpp>
#include <hpx/hpx_main.hpp>

#include <experimental/linalg>
#include <experimental/mdspan>

#include <cstddef>
#include <execution>
#include <iostream>
#include <vector>

template <class T1, class ScalarType>
void print_elements(
const T1& v, const std::vector<ScalarType>& gold, char const* policy_str)
{
std::cout << "Using policy: " << policy_str << "\n";
for (std::size_t i = 0; i < v.size(); i++)
{
std::cout << "computed = " << v(i) << " , gold = " << gold[i] << "\n";
}
}

void reset(auto z)
{
for (std::size_t i = 0; i < z.extent(0); i++)
{
z(i) = 0;
}
}

int main(int argc, char* argv[])
{
std::cout << "add example: calling HPX-kernels" << std::endl;

std::size_t N = 50;

using value_type = double;

std::vector<value_type> x_data(N);
std::vector<value_type> y_data(N);
std::vector<value_type> z_data(N);

value_type* x_ptr = x_data.data();
value_type* y_ptr = y_data.data();
value_type* z_ptr = z_data.data();

using dyn_1d_ext_type = std::experimental::extents<std::size_t,
std::experimental::dynamic_extent>;
using mdspan_type = std::experimental::mdspan<value_type, dyn_1d_ext_type>;
mdspan_type x(x_ptr, N);
mdspan_type y(y_ptr, N);
mdspan_type z(z_ptr, N);

std::vector<value_type> gold(N);
for (std::size_t i = 0; i < x.extent(0); i++)
{
x(i) = static_cast<value_type>(i);
y(i) = i + static_cast<value_type>(10);
z(i) = 0;
gold[i] = x(i) + y(i);
}

namespace stdla = std::experimental::linalg;
const value_type init_value = 2.0;

// This goes to the base implementation
{
stdla::add(std::execution::seq, x, y, z);
print_elements(z, gold, "std::execution::seq");
}

// This also goes to the base implementation
{
reset(z); // reset z since it is modified above
stdla::add(hpx::execution::seq, x, y, z);
print_elements(z, gold, "hpx::execution::seq");
}

// This forwards to HPXKernels
{
reset(z); // reset z since it is modified above
stdla::add(HPXKernelsSTD::hpx_exec<>(), x, y, z);
print_elements(z, gold, "HPXKernelsSTD::hpx_exec<>()");
}

// This forwards to HPXKernels if LINALG_ENABLE_HPX_DEFAULT is ON
{
reset(z); // reset z since it is modified above
stdla::add(std::execution::par, x, y, z);
print_elements(z, gold, "std::execution::par");
}

// This forwards to HPXKernels
{
reset(z); // reset z since it is modified above
stdla::add(hpx::execution::par, x, y, z);
print_elements(z, gold, "hpx::execution::par");
}

#if defined(HPX_HAVE_DATAPAR)
// this invokes a explicitly vectorized HPX versions
{
reset(z); // reset z since it is modified above
stdla::add(hpx::execution::simd, x, y, z);
print_elements(z, gold, "hpx::execution::simd");
}

{
reset(z); // reset z since it is modified above
stdla::add(hpx::execution::par_simd, x, y, z);
print_elements(z, gold, "hpx::execution::par_simd");
}
#endif

return 0;
}
48 changes: 48 additions & 0 deletions examples/hpx-based/scale_hpx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2022 Hartmut Kaiser

#include <hpx/execution.hpp>
#include <hpx/hpx_main.hpp>

#include <experimental/linalg>
#include <experimental/mdspan>

#include <cstddef>
#include <iostream>

int main(int argc, char* argv[])
{
std::cout << "dot example: calling hpx-kernels" << std::endl;

std::size_t N = 40;
{
std::vector<double> data(N);
double* a_ptr = data.data();

// Requires CTAD working, GCC 11.1 works but some others are buggy
// std::experimental::mdspan a(a_ptr,N);
std::experimental::mdspan<double,
std::experimental::extents<std::size_t, std::experimental::dynamic_extent>>
a(a_ptr, N);
for (std::size_t i = 0; i < a.extent(0); i++)
a(i) = double(i);

// This forwards to HPXKernels
std::experimental::linalg::scale(HPXKernelsSTD::hpx_exec<>(), 2.0, a);
// This forwards to HPXKernels if LINALG_ENABLE_HPX_DEFAULT is ON
std::experimental::linalg::scale(std::execution::par, 2.0, a);
// This always forwards to HPXKernels
std::experimental::linalg::scale(hpx::execution::par, 2.0, a);
// This goes to the base implementation
std::experimental::linalg::scale(std::execution::seq, 2.0, a);
// This also goes to the base implementation
std::experimental::linalg::scale(hpx::execution::seq, 2.0, a);
#if defined(HPX_HAVE_DATAPAR)
// this invokes a explicitly vectorized version
std::experimental::linalg::scale(hpx::execution::simd, 2.0, a);
std::experimental::linalg::scale(hpx::execution::par_simd, 2.0, a);
#endif
for (std::size_t i = 0; i < a.extent(0); i++)
printf("%zi %lf\n", i, a(i));
}
return 0;
}
Loading