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

Update mdspan to account for changes to extents #751

Merged
merged 5 commits into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
367 changes: 209 additions & 158 deletions cpp/include/raft/core/mdarray.hpp

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions cpp/include/raft/detail/mdarray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,14 @@ using device_accessor = accessor_mixin<AccessorPolicy, false>;

namespace stdex = std::experimental;

using vector_extent = stdex::extents<dynamic_extent>;
using matrix_extent = stdex::extents<dynamic_extent, dynamic_extent>;
using scalar_extent = stdex::extents<1>;
template <typename IndexType>
using vector_extent = stdex::extents<IndexType, dynamic_extent>;

template <typename IndexType>
using matrix_extent = stdex::extents<IndexType, dynamic_extent, dynamic_extent>;

template <typename IndexType>
using scalar_extent = stdex::extents<IndexType, 1>;

template <typename T>
MDSPAN_INLINE_FUNCTION auto native_popc(T v) -> int32_t
Expand Down Expand Up @@ -301,8 +306,8 @@ MDSPAN_INLINE_FUNCTION constexpr auto arr_to_tup(T (&arr)[N])
// uint division optimization inspired by the CIndexer in cupy. Division operation is
// slow on both CPU and GPU, especially 64 bit integer. So here we first try to avoid 64
// bit when the index is smaller, then try to avoid division when it's exp of 2.
template <typename I, size_t... Extents>
MDSPAN_INLINE_FUNCTION auto unravel_index_impl(I idx, stdex::extents<Extents...> shape)
template <typename I, typename IndexType, size_t... Extents>
MDSPAN_INLINE_FUNCTION auto unravel_index_impl(I idx, stdex::extents<IndexType, Extents...> shape)
{
constexpr auto kRank = static_cast<int32_t>(shape.rank());
std::size_t index[shape.rank()]{0}; // NOLINT
Expand Down
34 changes: 17 additions & 17 deletions cpp/include/raft/distance/distance.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ template <raft::distance::DistanceType distanceType,
typename Index_ = int,
typename layout = raft::layout_c_contiguous>
void distance(raft::handle_t const& handle,
raft::device_matrix_view<InType, layout> const x,
raft::device_matrix_view<InType, layout> const y,
raft::device_matrix_view<OutType, layout> dist,
raft::device_matrix_view<InType, Index_, layout> const x,
raft::device_matrix_view<InType, Index_, layout> const y,
raft::device_matrix_view<OutType, Index_, layout> dist,
InType metric_arg = 2.0f)
{
RAFT_EXPECTS(x.extent(1) == y.extent(1), "Number of columns must be equal.");
Expand All @@ -255,14 +255,14 @@ void distance(raft::handle_t const& handle,
"Number of columns in output must be equal to "
"number of rows in Y");

RAFT_EXPECTS(x.is_contiguous(), "Input x must be contiguous.");
RAFT_EXPECTS(y.is_contiguous(), "Input y must be contiguous.");
RAFT_EXPECTS(x.is_exhaustive(), "Input x must be contiguous.");
RAFT_EXPECTS(y.is_exhaustive(), "Input y must be contiguous.");

constexpr auto is_rowmajor = std::is_same_v<layout, layout_c_contiguous>;

distance<distanceType, InType, AccType, OutType, Index_>(x.data(),
y.data(),
dist.data(),
distance<distanceType, InType, AccType, OutType, Index_>(x.data_handle(),
y.data_handle(),
dist.data_handle(),
x.extent(0),
y.extent(0),
x.extent(1),
Expand Down Expand Up @@ -415,9 +415,9 @@ void pairwise_distance(const raft::handle_t& handle,
*/
template <typename Type, typename Index_ = int, typename layout = layout_c_contiguous>
void pairwise_distance(raft::handle_t const& handle,
device_matrix_view<Type, layout> const x,
device_matrix_view<Type, layout> const y,
device_matrix_view<Type, layout> dist,
device_matrix_view<Type, Index_, layout> const x,
Copy link
Member

Choose a reason for hiding this comment

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

If we add the Index_ as a third type, we can default it to std::size_t and then we won't break any APIs downstream.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do, although it will be non-breaking if default is int as that is what it was before

device_matrix_view<Type, Index_, layout> const y,
device_matrix_view<Type, Index_, layout> dist,
raft::distance::DistanceType metric,
Type metric_arg = 2.0f)
{
Expand All @@ -429,18 +429,18 @@ void pairwise_distance(raft::handle_t const& handle,
"Number of columns in output must be equal to "
"number of rows in Y");

RAFT_EXPECTS(x.is_contiguous(), "Input x must be contiguous.");
RAFT_EXPECTS(y.is_contiguous(), "Input y must be contiguous.");
RAFT_EXPECTS(dist.is_contiguous(), "Output must be contiguous.");
RAFT_EXPECTS(x.is_exhaustive(), "Input x must be contiguous.");
RAFT_EXPECTS(y.is_exhaustive(), "Input y must be contiguous.");
RAFT_EXPECTS(dist.is_exhaustive(), "Output must be contiguous.");

constexpr auto rowmajor = std::is_same_v<layout, layout_c_contiguous>;

rmm::device_uvector<char> workspace(0, handle.get_stream());

pairwise_distance(handle,
x.data(),
y.data(),
dist.data(),
x.data_handle(),
y.data_handle(),
dist.data_handle(),
x.extent(0),
y.extent(0),
x.extent(1),
Expand Down
39 changes: 20 additions & 19 deletions cpp/include/raft/random/make_blobs.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -123,41 +123,42 @@ void make_blobs(DataT* out,
* @param[in] type RNG type
*/
template <typename DataT, typename IdxT, typename layout>
void make_blobs(raft::handle_t const& handle,
raft::device_matrix_view<DataT, layout> out,
raft::device_vector_view<IdxT> labels,
IdxT n_clusters = 5,
std::optional<raft::device_matrix_view<DataT, layout>> centers = std::nullopt,
std::optional<raft::device_vector_view<DataT>> const cluster_std = std::nullopt,
const DataT cluster_std_scalar = (DataT)1.0,
bool shuffle = true,
DataT center_box_min = (DataT)-10.0,
DataT center_box_max = (DataT)10.0,
uint64_t seed = 0ULL,
GeneratorType type = GenPhilox)
void make_blobs(
raft::handle_t const& handle,
raft::device_matrix_view<DataT, IdxT, layout> out,
raft::device_vector_view<IdxT, IdxT> labels,
IdxT n_clusters = 5,
std::optional<raft::device_matrix_view<DataT, IdxT, layout>> centers = std::nullopt,
std::optional<raft::device_vector_view<DataT, IdxT>> const cluster_std = std::nullopt,
const DataT cluster_std_scalar = (DataT)1.0,
bool shuffle = true,
DataT center_box_min = (DataT)-10.0,
DataT center_box_max = (DataT)10.0,
uint64_t seed = 0ULL,
GeneratorType type = GenPhilox)
{
if (centers.has_value()) {
RAFT_EXPECTS(centers.value().extent(0) == (std::size_t)n_clusters,
RAFT_EXPECTS(centers.value().extent(0) == (IdxT)n_clusters,
"n_centers must equal size of centers");
}

if (cluster_std.has_value()) {
RAFT_EXPECTS(cluster_std.value().extent(0) == (std::size_t)n_clusters,
RAFT_EXPECTS(cluster_std.value().extent(0) == (IdxT)n_clusters,
"n_centers must equal size of cluster_std");
}

RAFT_EXPECTS(out.extent(0) == labels.extent(0),
"Number of labels must equal the number of row in output matrix");

RAFT_EXPECTS(out.is_contiguous(), "Output must be contiguous.");
RAFT_EXPECTS(out.is_exhaustive(), "Output must be contiguous.");

bool row_major = std::is_same<layout, raft::layout_c_contiguous>::value;

auto prm_centers = centers.has_value() ? centers.value().data() : nullptr;
auto prm_cluster_std = cluster_std.has_value() ? cluster_std.value().data() : nullptr;
auto prm_centers = centers.has_value() ? centers.value().data_handle() : nullptr;
auto prm_cluster_std = cluster_std.has_value() ? cluster_std.value().data_handle() : nullptr;

detail::make_blobs_caller(out.data(),
labels.data(),
detail::make_blobs_caller(out.data_handle(),
labels.data_handle(),
(IdxT)out.extent(0),
(IdxT)out.extent(1),
n_clusters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
compiler_prefix: /usr/bin
- compiler_driver: icpx
compiler_prefix: /opt/intel/oneapi/compiler/latest/linux/bin
compiler_url: https://registrationcenter-download.intel.com/akdlm/irc_nas/18209/l_dpcpp-cpp-compiler_p_2021.4.0.3201_offline.sh
compiler_url: https://registrationcenter-download.intel.com/akdlm/irc_nas/18478/l_dpcpp-cpp-compiler_p_2022.0.2.84_offline.sh
name: ${{ matrix.compiler_driver }}
steps:

Expand All @@ -26,7 +26,7 @@ jobs:
uses: actions/cache@v2
with:
path: /opt/intel/oneapi
key: oneapi-${{ matrix.compile_url}}
key: oneapi-${{ matrix.compiler_url}}
- name: Install icpx
if: ${{ matrix.compiler_driver == 'icpx' && steps.cache-icpx.outputs.cache-hit != 'true' }}
run: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- run: sudo apt-get install python3
- run: ./make_single_header.py ./include/experimental/mdspan > /tmp/mdspan.hpp
- run: ./make_single_header.py ./include/experimental/mdarray > /tmp/mdspan.hpp
- uses: actions/checkout@v2
with:
ref: single-header
Expand Down
36 changes: 25 additions & 11 deletions cpp/include/raft/thirdparty/mdspan/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 3.14)

project(MDSpan
VERSION 0.2.0
VERSION 0.4.0
LANGUAGES CXX
)

include(GNUInstallDirs)

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

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
Expand All @@ -17,10 +19,11 @@ option(MDSPAN_ENABLE_BENCHMARKS "Enable benchmarks." Off)
option(MDSPAN_ENABLE_COMP_BENCH "Enable compilation benchmarks." Off)
option(MDSPAN_ENABLE_CUDA "Enable Cuda tests/benchmarks/examples if tests/benchmarks/examples are enabled." Off)
option(MDSPAN_ENABLE_OPENMP "Enable OpenMP benchmarks if benchmarks are enabled." On)
option(MDSPAN_USE_SYSTEM_GTEST "Use system-installed GoogleTest library for tests." Off)

# Option to override which C++ standard to use
set(MDSPAN_CXX_STANDARD DETECT CACHE STRING "Override the default CXX_STANDARD to compile with.")
set_property(CACHE MDSPAN_CXX_STANDARD PROPERTY STRINGS DETECT 14 17 20)
set_property(CACHE MDSPAN_CXX_STANDARD PROPERTY STRINGS DETECT 14 17 20 23)

option(MDSPAN_ENABLE_CONCEPTS "Try to enable concepts support by giving extra flags." On)

Expand Down Expand Up @@ -48,8 +51,18 @@ elseif(MDSPAN_CXX_STANDARD STREQUAL "20")
else()
message(FATAL_ERROR "Requested MDSPAN_CXX_STANDARD \"20\" not supported by provided C++ compiler")
endif()
elseif(MDSPAN_CXX_STANDARD STREQUAL "23")
if("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
message(STATUS "Using C++23 standard")
set(CMAKE_CXX_STANDARD 23)
else()
message(FATAL_ERROR "Requested MDSPAN_CXX_STANDARD \"23\" not supported by provided C++ compiler")
endif()
else()
if("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
if("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
set(CMAKE_CXX_STANDARD 23)
message(STATUS "Detected support for C++23 standard")
elseif("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
set(CMAKE_CXX_STANDARD 20)
message(STATUS "Detected support for C++20 standard")
elseif("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
Expand All @@ -66,7 +79,7 @@ endif()
################################################################################

if(MDSPAN_ENABLE_CONCEPTS)
if(CMAKE_CXX_STANDARD STREQUAL "20")
if(CMAKE_CXX_STANDARD GREATER_EQUAL 20)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-fconcepts" COMPILER_SUPPORTS_FCONCEPTS)
if(COMPILER_SUPPORTS_FCONCEPTS)
Expand Down Expand Up @@ -109,39 +122,40 @@ add_library(std::mdspan ALIAS mdspan)

target_include_directories(mdspan INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

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

install(TARGETS mdspan EXPORT mdspanTargets
INCLUDES DESTINATION include
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(EXPORT mdspanTargets
FILE mdspanTargets.cmake
NAMESPACE std::
DESTINATION lib/cmake/mdspan
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mdspan
)

export(TARGETS mdspan
NAMESPACE std::
FILE mdspanTargets.cmake
)

install(DIRECTORY include/experimental DESTINATION include)
install(DIRECTORY include/experimental DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

include(CMakePackageConfigHelpers)
configure_package_config_file(cmake/mdspanConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/mdspanConfig.cmake
INSTALL_DESTINATION lib/cmake/mdspan
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mdspan
)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/mdspanConfigVersion.cmake
COMPATIBILITY SameMajorVersion
ARCH_INDEPENDENT
)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mdspanConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/mdspanConfigVersion.cmake
DESTINATION lib/cmake/mdspan
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mdspan
)

################################################################################
Expand Down
25 changes: 22 additions & 3 deletions cpp/include/raft/thirdparty/mdspan/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ Reference `mdspan` implementation

The ISO-C++ proposal [P0009](https://wg21.link/p0009) will add support for non-owning multi-dimensional array references to the C++ standard library. This repository aims to provide a production-quality implementation of the proposal as written (with a few caveats, see below) in preparation for the addition of `mdspan` to the standard. Please feel free to use this, file bugs when it breaks, and let us know how it works for you :-)

[Try it out on Godbolt](https://godbolt.org/z/KMT3G9Ese){: .btn }
[Try it out on Godbolt](https://godbolt.org/z/Mxa7cej1a){: .btn }

During the final leg of the ISO C++ committee review process a number of breaking changes were proposed and accepted (issue #136). These are now merged into the stable branch.

Note: There is a tag mdspan-0.3.0 which reflects the status of P0009 before R17 - i.e. it does not have the integral type template parameter for `extents`.
Note: There is a tag mdspan-0.4.0 which reflects the status of P0009 before

* renaming `pointer`, `data`, `is_contiguous` and `is_always_contiguous`; and before
* renaming `size_type` to `index_type` and introducing a new `size_type = make_unsigned_t<index_type>` alias.

Using `mdspan`
--------------
Expand All @@ -25,7 +33,14 @@ This implementation is header-only, with compiler features detected using featur

### Running tests

TODO write this
#### Configurations

- clang-15 / cmake 3.23
- Warning free with `-Wall -Wextra -pedantic` for C++23/20. In C++17 pedantic will give a few warnings, in C++14 Wextra will also give some.
- `cmake -DMDSPAN_ENABLE_TESTS=ON -DMDSPAN_ENABLE_BENCHMARKS=ON -DCMAKE_CXX_FLAGS="-Werror -Wall -Wextra -pedantic" -DCMAKE_CXX_STANDARD=23 -DMDSPAN_CXX_STANDARD=23 -DCMAKE_CXX_COMPILER=clang++`
- gcc-11 / cmake 3.23
- Warning free with `-Wall -Wextra -pedantic` for C++23/20. In C++17 and C++14 pedantic will give a warning (note only with `CMAKE_CXX_EXTENSION=OFF`).
- `cmake -DMDSPAN_ENABLE_TESTS=ON -DMDSPAN_ENABLE_BENCHMARKS=ON -DCMAKE_CXX_FLAGS="-Werror -Wall -Wextra -pedantic" -DCMAKE_CXX_STANDARD=17 -DMDSPAN_CXX_STANDARD=17 -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_EXTENSIONS=OFF`

### Running benchmarks

Expand All @@ -34,19 +49,23 @@ TODO write this
Caveats
-------

This implementation is fully conforming with a few exceptions (most of which are extensions):
This implementation is fully conforming with revision 14 of P0009 with a few exceptions (most of which are extensions):

### C++20
- implements `operator()` not `operator[]`
- note you can control which operator is available with defining `MDSPAN_USE_BRACKET_OPERATOR=[0,1]` and `MDSPAN_USE_PAREN_OPERATOR=[0,1]` irrespective of whether multi dimensional subscript support is detected.

### C++17 and C++14
- mdspan has a default constructor even in cases where it shouldn't (i.e. all static extents, and default constructible mapping/accessor)
- the `layout_stride::mapping::strides` function returns `array` not `span`.
- the conditional explicit markup is missing, making certain constructors implicit
- most notably you can implicitly convert from dynamic extent to static extent, which you can't in C++20 mode

### C++14
- deduction guides don't exist



Acknowledgements
================

Expand Down
Loading