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

Allow to optionally use C++17 #1548

Closed
wants to merge 6 commits into from
Closed
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
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ include(cmake/build_type_helpers.cmake)
include(cmake/build_helpers.cmake)
include(cmake/install_helpers.cmake)

# Store the used CMAKE_CXX_STANDARD or fallback to the highest supported standard of (c++14, c++17)
ginkgo_set_cxx_standard()

if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
endif()
Expand Down
1 change: 1 addition & 0 deletions cmake/GinkgoConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ set(GINKGO_DEBUG_POSTFIX "@CMAKE_DEBUG_POSTFIX@")
# Compiler configuration
set(GINKGO_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
set(GINKGO_CXX_COMPILER_VERSION @CMAKE_CXX_COMPILER_VERSION@)
set(GINKGO_CXX_STANDARD "@GINKGO_CXX_STANDARD@")

set(GINKGO_CXX_FLAGS "@CMAKE_CXX_FLAGS@")
set(GINKGO_CXX_FLAGS_DEBUG "@CMAKE_CXX_FLAGS_DEBUG@")
Expand Down
50 changes: 49 additions & 1 deletion cmake/build_helpers.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,53 @@
set(GINKGO_LIBRARY_PATH "${PROJECT_BINARY_DIR}/lib")

function(ginkgo_check_std_available std)
if (std EQUAL 23)
set(__std_macro 202302L)
elseif (std EQUAL 20)
set(__std_macro 202002L)
elseif (std EQUAL 17)
set(__std_macro 201703L)
elseif (std EQUAL 14)
set(__std_macro 201402L)
else ()
message(FATAL_ERROR "Unsupported CXX standard: ${std}.")
endif ()
try_compile(GINKGO_HAVE_CXX${std}
${Ginkgo_BINARY_DIR}
${Ginkgo_SOURCE_DIR}/cmake/cxx_std_check.cpp
CMAKE_FLAGS -DCMAKE_CXX_STANDARD=${std}
COMPILE_DEFINITIONS -DCXX_STD=${__std_macro}
)
set(GINKGO_HAVE_CXX${std} PARENT_SCOPE)
endfunction()

macro(ginkgo_set_cxx_standard)
set(GINKGO_CXX_STANDARD ${CMAKE_CXX_STANDARD})
if(NOT GINKGO_CXX_STANDARD)
ginkgo_check_std_available(14)
if (GINKGO_HAVE_CXX14)
set(GINKGO_CXX_STANDARD 14)
endif ()
ginkgo_check_std_available(17)
if (GINKGO_HAVE_CXX17)
set(GINKGO_CXX_STANDARD 17)
endif ()
endif ()
set(__supported_cxx_std 14 17 20 23)
if(NOT GINKGO_CXX_STANDARD IN_LIST __supported_cxx_std)
message(FATAL_ERROR "Unsupported CXX standard: ${GINKGO_CXX_STANDARD}.")
endif ()
foreach (__std IN LISTS __supported_cxx_std)
if (GINKGO_CXX_STANDARD GREATER_EQUAL __std)
set(GINKGO_HAVE_CXX${__std} ON)
set(GINKGO_CXX_STANDARD_FEATURE cxx_std_${__std})
else ()
set(GINKGO_HAVE_CXX${__std} OFF)
endif ()
endforeach ()
unset(__supported_cxx_std)
endmacro()

function(ginkgo_default_includes name)
# set include path depending on used interface
target_include_directories("${name}"
Expand All @@ -18,7 +66,7 @@ function(ginkgo_default_includes name)
endfunction()

function(ginkgo_compile_features name)
target_compile_features("${name}" PUBLIC cxx_std_14)
target_compile_features("${name}" PUBLIC ${GINKGO_CXX_STANDARD_FEATURE})
# we set these properties regardless of the enabled backends,
# because unknown properties are ignored
set_target_properties("${name}" PROPERTIES HIP_STANDARD 14)
Expand Down
1 change: 0 additions & 1 deletion cmake/create_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ function(ginkgo_set_test_target_properties test_target_name test_library_suffix)
else()
target_link_libraries(${test_target_name} PRIVATE ginkgo_gtest_main${test_library_suffix})
endif()
target_compile_features(${test_target_name} PUBLIC cxx_std_14)
pratikvn marked this conversation as resolved.
Show resolved Hide resolved
# we set these properties regardless of the enabled backends,
# because unknown properties are ignored
set_target_properties(${test_target_name} PROPERTIES HIP_STANDARD 14)
Expand Down
5 changes: 5 additions & 0 deletions cmake/cxx_std_check.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
//
// SPDX-License-Identifier: BSD-3-Clause

int main() { static_assert(__cplusplus >= CXX_STD); }
Copy link
Member

Choose a reason for hiding this comment

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

static_assert should also have an error string (unless it's C++17+):

Suggested change
int main() { static_assert(__cplusplus >= CXX_STD); }
int main() { static_assert(__cplusplus >= CXX_STD, "Required C++ standard not supported."); }

2 changes: 1 addition & 1 deletion cmake/get_info.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ set(log_types "detailed_log;minimal_log")
foreach(log_type ${log_types})
ginkgo_print_module_footer(${${log_type}} "Ginkgo configuration:")
ginkgo_print_foreach_variable(${${log_type}}
"CMAKE_BUILD_TYPE;BUILD_SHARED_LIBS;CMAKE_INSTALL_PREFIX"
"GINKGO_CXX_STANDARD;CMAKE_BUILD_TYPE;BUILD_SHARED_LIBS;CMAKE_INSTALL_PREFIX"
"PROJECT_SOURCE_DIR;PROJECT_BINARY_DIR")
string(SUBSTRING
"
Expand Down
2 changes: 1 addition & 1 deletion cmake/information_helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ macro(ginkgo_pkg_information)
# Prepare recursively populated library list
list(APPEND GINKGO_INTERFACE_LIBS_FOUND "-lginkgo$<$<CONFIG:Debug>:${CMAKE_DEBUG_POSTFIX}>")
# Prepare recursively populated include directory list
list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "-I\\\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "-std=c++${GINKGO_CXX_STANDARD}" "-I\\\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")

# Call the recursive interface libraries macro
get_target_property(GINKGO_INTERFACE_LINK_LIBRARIES ginkgo INTERFACE_LINK_LIBRARIES)
Expand Down
2 changes: 1 addition & 1 deletion core/test/accessor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function(create_accessor_test test_name)
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}")
add_executable("${TEST_TARGET_NAME}" "${test_name}.cpp")
target_compile_features("${TEST_TARGET_NAME}" PUBLIC cxx_std_14)
target_compile_features("${TEST_TARGET_NAME}" PUBLIC ${GINKGO_CXX_STANDARD_FEATURE})
target_include_directories("${TEST_TARGET_NAME}"
PRIVATE
"${Ginkgo_SOURCE_DIR}"
Expand Down
8 changes: 7 additions & 1 deletion core/test/gtest/ginkgo_mpi_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,13 @@ int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);

MPI_Init(&argc, &argv);
int provided_thread_support;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE,
&provided_thread_support);
if (provided_thread_support != MPI_THREAD_MULTIPLE) {
throw std::runtime_error(
"This test requires an thread compliant MPI implementation.");
}
MPI_Comm comm(MPI_COMM_WORLD);
int rank;
int size;
Expand Down
1 change: 1 addition & 0 deletions core/test/mpi/distributed/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ginkgo_create_test(helpers MPI_SIZE 1)
ginkgo_create_test(matrix MPI_SIZE 1)
ginkgo_create_test(neighborhood_communicator MPI_SIZE 6)
ginkgo_create_test(row_gatherer MPI_SIZE 6)

add_subdirectory(preconditioner)
216 changes: 216 additions & 0 deletions core/test/mpi/distributed/row_gatherer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
//
// SPDX-License-Identifier: BSD-3-Clause

#include <gtest/gtest.h>


#include <ginkgo/core/distributed/neighborhood_communicator.hpp>
#include <ginkgo/core/distributed/row_gatherer.hpp>
#include <ginkgo/core/distributed/vector.hpp>


#include "core/test/utils.hpp"
#include "core/test/utils/assertions.hpp"


template <typename IndexType>
class RowGatherer : public ::testing::Test {
protected:
using index_type = IndexType;
using part_type =
gko::experimental::distributed::Partition<index_type, long>;
using map_type =
gko::experimental::distributed::index_map<index_type, long>;
using row_gatherer_type =
gko::experimental::distributed::RowGatherer<index_type>;

RowGatherer()
{
int rank = this->comm.rank();
auto part = gko::share(part_type::build_from_global_size_uniform(
this->ref, this->comm.size(), this->comm.size() * 3));
auto recv_connections =
this->template create_recv_connections<long>()[rank];
auto imap =
map_type{this->ref, part, this->comm.rank(), recv_connections};
auto coll_comm =
std::make_shared<gko::experimental::mpi::neighborhood_communicator>(
this->comm, imap);
rg = row_gatherer_type::create(ref, coll_comm, imap);
}

void SetUp() override { ASSERT_EQ(comm.size(), 6); }

template <typename T>
std::array<gko::array<T>, 6> create_recv_connections()
{
return {gko::array<T>{ref, {3, 5, 10, 11}},
gko::array<T>{ref, {0, 1, 7, 12, 13}},
gko::array<T>{ref, {3, 4, 17}},
gko::array<T>{ref, {1, 2, 12, 14}},
gko::array<T>{ref, {4, 5, 9, 10, 15, 16}},
gko::array<T>{ref, {8, 12, 13, 14}}};
}

std::shared_ptr<gko::Executor> ref = gko::ReferenceExecutor::create();
gko::experimental::mpi::communicator comm = MPI_COMM_WORLD;
std::shared_ptr<row_gatherer_type> rg;
};

TYPED_TEST_SUITE(RowGatherer, gko::test::IndexTypes, TypenameNameGenerator);

TYPED_TEST(RowGatherer, CanDefaultConstruct)
{
using RowGatherer = typename TestFixture::row_gatherer_type;

auto rg = RowGatherer::create(this->ref, this->comm);

GKO_ASSERT_EQUAL_DIMENSIONS(rg, gko::dim<2>());
}


TYPED_TEST(RowGatherer, CanConstructWithEmptCollectiveCommAndIndexMap)
{
using RowGatherer = typename TestFixture::row_gatherer_type;
using IndexMap = typename TestFixture::map_type;
auto coll_comm =
std::make_shared<gko::experimental::mpi::neighborhood_communicator>(
this->comm);
auto map = IndexMap{this->ref};

auto rg = RowGatherer::create(this->ref, coll_comm, map);

GKO_ASSERT_EQUAL_DIMENSIONS(rg, gko::dim<2>());
}


TYPED_TEST(RowGatherer, CanConstructFromCollectiveCommAndIndexMap)
{
using RowGatherer = typename TestFixture::row_gatherer_type;
using Part = typename TestFixture::part_type;
using IndexMap = typename TestFixture::map_type;
int rank = this->comm.rank();
auto part = gko::share(Part::build_from_global_size_uniform(
this->ref, this->comm.size(), this->comm.size() * 3));
auto recv_connections =
this->template create_recv_connections<long>()[rank];
auto imap = IndexMap{this->ref, part, this->comm.rank(), recv_connections};
auto coll_comm =
std::make_shared<gko::experimental::mpi::neighborhood_communicator>(
this->comm, imap);

auto rg = RowGatherer::create(this->ref, coll_comm, imap);

gko::dim<2> size{recv_connections.get_size(), 18};
GKO_ASSERT_EQUAL_DIMENSIONS(rg, size);
}


TYPED_TEST(RowGatherer, CanApply)
{
using Dense = gko::matrix::Dense<double>;
using Vector = gko::experimental::distributed::Vector<double>;
int rank = this->comm.rank();
auto offset = static_cast<double>(rank * 3);
auto b = Vector::create(
this->ref, this->comm, gko::dim<2>{18, 1},
gko::initialize<Dense>({offset, offset + 1, offset + 2}, this->ref));
auto x = Dense::create(this->ref, gko::dim<2>{this->rg->get_size()[0], 1});

this->rg->apply(b, x);

auto expected = this->template create_recv_connections<double>()[rank];
auto expected_vec = Dense::create(
this->ref, gko::dim<2>{expected.get_size(), 1}, expected, 1);
GKO_ASSERT_MTX_NEAR(x, expected_vec, 0.0);
}


TYPED_TEST(RowGatherer, CanApplyAsync)
{
using Dense = gko::matrix::Dense<double>;
using Vector = gko::experimental::distributed::Vector<double>;
int rank = this->comm.rank();
auto offset = static_cast<double>(rank * 3);
auto b = Vector::create(
this->ref, this->comm, gko::dim<2>{18, 1},
gko::initialize<Dense>({offset, offset + 1, offset + 2}, this->ref));
auto x = Dense::create(this->ref, gko::dim<2>{this->rg->get_size()[0], 1});

auto future = this->rg->apply_async(b, x);
future.wait();

auto expected = this->template create_recv_connections<double>()[rank];
auto expected_vec = Dense::create(
this->ref, gko::dim<2>{expected.get_size(), 1}, expected, 1);
GKO_ASSERT_MTX_NEAR(x, expected_vec, 0.0);
}


TYPED_TEST(RowGatherer, CanFinishFutureAfterReset)
{
using Dense = gko::matrix::Dense<double>;
using Vector = gko::experimental::distributed::Vector<double>;
int rank = this->comm.rank();
auto offset = static_cast<double>(rank * 3);
auto b = Vector::create(
this->ref, this->comm, gko::dim<2>{18, 1},
gko::initialize<Dense>({offset, offset + 1, offset + 2}, this->ref));
auto x = Dense::create(this->ref, gko::dim<2>{this->rg->get_size()[0], 1});

auto future = this->rg->apply_async(b, x);
this->rg.reset();
future.wait();

auto expected = this->template create_recv_connections<double>()[rank];
auto expected_vec = Dense::create(
this->ref, gko::dim<2>{expected.get_size(), 1}, expected, 1);
GKO_ASSERT_MTX_NEAR(x, expected_vec, 0.0);
}


TYPED_TEST(RowGatherer, CanApplyAsyncWithMultipleColumns)
{
using Dense = gko::matrix::Dense<double>;
using Vector = gko::experimental::distributed::Vector<double>;
int rank = this->comm.rank();
auto offset = static_cast<double>(rank * 3);
auto b = Vector::create(
this->ref, this->comm, gko::dim<2>{18, 2},
gko::initialize<Dense>({{offset, offset * offset},
{offset + 1, offset * offset + 1},
{offset + 2, offset * offset + 2}},
this->ref));
auto x = Dense::create(this->ref, gko::dim<2>{this->rg->get_size()[0], 2});

this->rg->apply_async(b, x).wait();

gko::array<double> expected[] = {
gko::array<double>{this->ref, {3, 9, 5, 11, 10, 82, 11, 83}},
gko::array<double>{this->ref, {0, 0, 1, 1, 7, 37, 12, 144, 13, 145}},
gko::array<double>{this->ref, {3, 9, 4, 10, 17, 227}},
gko::array<double>{this->ref, {1, 1, 2, 2, 12, 144, 14, 146}},
gko::array<double>{this->ref,
{4, 10, 5, 11, 9, 81, 10, 82, 15, 225, 16, 226}},
gko::array<double>{this->ref, {8, 38, 12, 144, 13, 145, 14, 146}}};
auto expected_vec =
Dense::create(this->ref, gko::dim<2>{expected[rank].get_size() / 2, 2},
expected[rank], 2);
GKO_ASSERT_MTX_NEAR(x, expected_vec, 0.0);
}


TYPED_TEST(RowGatherer, ThrowsOnAdvancedApply)
{
using RowGatherer = typename TestFixture::row_gatherer_type;
using Dense = gko::matrix::Dense<double>;
using Vector = gko::experimental::distributed::Vector<double>;
auto rg = RowGatherer::create(this->ref, this->comm);
auto b = Vector::create(this->ref, this->comm);
auto x = Dense::create(this->ref);
auto alpha = Dense::create(this->ref, gko::dim<2>{1, 1});
auto beta = Dense::create(this->ref, gko::dim<2>{1, 1});

ASSERT_THROW(rg->apply(alpha, b, beta, x), gko::NotImplemented);
}
2 changes: 1 addition & 1 deletion dpcpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ gko_add_sycl_to_target(TARGET ginkgo_dpcpp)
# Note: add MKL as PRIVATE not PUBLIC (MKL example shows) to avoid propagating
# find_package(MKL) everywhere when linking ginkgo (see the MKL example
# https://software.intel.com/content/www/us/en/develop/documentation/onemkl-windows-developer-guide/top/getting-started/cmake-config-for-onemkl.html)
target_compile_features(ginkgo_dpcpp PUBLIC cxx_std_17)
target_compile_features(ginkgo_dpcpp PRIVATE cxx_std_17 INTERFACE ${GINKGO_CXX_STANDARD_FEATURE})
target_link_options(ginkgo_dpcpp PRIVATE -fsycl-device-lib=all)
# When building ginkgo as a static library, we need to use dpcpp and per_kernel
# link option when the program uses a dpcpp related function.
Expand Down
6 changes: 6 additions & 0 deletions include/ginkgo/config.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,10 @@
// clang-format on


/* Do we support C++17? */
Copy link
Member

Choose a reason for hiding this comment

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

minor nit:

Suggested change
/* Do we support C++17? */
/* Does the CXX compiler support C++17? */

// clang-format off
#cmakedefine01 GINKGO_HAVE_CXX17
// clang-format on


#endif // GKO_INCLUDE_CONFIG_H
1 change: 0 additions & 1 deletion test/test_exportbuild/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ find_package(Ginkgo REQUIRED
# Here, we use test install without any data. We instantiate the
# interface only.
add_executable(test_exportbuild ../test_install/test_install.cpp)
target_compile_features(test_exportbuild PUBLIC cxx_std_14)
target_link_libraries(test_exportbuild PRIVATE Ginkgo::ginkgo)
1 change: 0 additions & 1 deletion test/test_install/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ if (GINKGO_BUILD_REFERENCE)
set(HAS_REFERENCE 1)
endif()
add_executable(test_install test_install.cpp)
target_compile_features(test_install PUBLIC cxx_std_14)
target_compile_definitions(test_install PRIVATE HAS_REFERENCE=${HAS_REFERENCE})
target_link_libraries(test_install PRIVATE Ginkgo::ginkgo)
if(GINKGO_BUILD_MPI)
Expand Down
Loading
Loading