From 8891fc865cb79595d1378342294f10be2766a325 Mon Sep 17 00:00:00 2001 From: Karthikeyan Natarajan Date: Thu, 26 May 2022 01:42:48 +0530 Subject: [PATCH 1/5] add missing docs to utilities/ headers --- cpp/include/cudf/utilities/bit.hpp | 18 +- cpp/include/cudf/utilities/error.hpp | 32 ++- cpp/include/cudf/utilities/span.hpp | 206 ++++++++++++++++-- cpp/include/cudf/utilities/traits.hpp | 21 ++ .../cudf/utilities/type_dispatcher.hpp | 22 +- 5 files changed, 272 insertions(+), 27 deletions(-) diff --git a/cpp/include/cudf/utilities/bit.hpp b/cpp/include/cudf/utilities/bit.hpp index f4a70463de3..d887ab747d0 100644 --- a/cpp/include/cudf/utilities/bit.hpp +++ b/cpp/include/cudf/utilities/bit.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. + * Copyright (c) 2019-2022, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ namespace cudf { namespace detail { +// @cond // Work around a bug in NVRTC that fails to compile assert() in constexpr // functions (fixed after CUDA 11.0) #if defined __GNUC__ @@ -40,7 +41,14 @@ namespace detail { #else #define constexpr_assert(CHECK) (LIKELY(CHECK) ? void(0) : [] { assert(!#CHECK); }()) #endif +// @endcond +/** + * @brief Returns the number of bits the given type can hold. + * + * @tparam T The type to query + * @return `sizeof(T)` in bits + */ template constexpr CUDF_HOST_DEVICE inline std::size_t size_in_bits() { @@ -57,6 +65,9 @@ constexpr CUDF_HOST_DEVICE inline std::size_t size_in_bits() /** * @brief Returns the index of the word containing the specified bit. + * + * @param bit_index The index of the bit to query + * @return The index of the word containing the specified bit */ constexpr CUDF_HOST_DEVICE inline size_type word_index(size_type bit_index) { @@ -65,6 +76,9 @@ constexpr CUDF_HOST_DEVICE inline size_type word_index(size_type bit_index) /** * @brief Returns the position within a word of the specified bit. + * + * @param bit_index The index of the bit to query + * @return The position within a word of the specified bit */ constexpr CUDF_HOST_DEVICE inline size_type intra_word_index(size_type bit_index) { @@ -79,6 +93,7 @@ constexpr CUDF_HOST_DEVICE inline size_type intra_word_index(size_type bit_index * * @param bitmask The bitmask containing the bit to set * @param bit_index Index of the bit to set + * @return void */ CUDF_HOST_DEVICE inline void set_bit_unsafe(bitmask_type* bitmask, size_type bit_index) { @@ -94,6 +109,7 @@ CUDF_HOST_DEVICE inline void set_bit_unsafe(bitmask_type* bitmask, size_type bit * * @param bitmask The bitmask containing the bit to clear * @param bit_index The index of the bit to clear + * @return void */ CUDF_HOST_DEVICE inline void clear_bit_unsafe(bitmask_type* bitmask, size_type bit_index) { diff --git a/cpp/include/cudf/utilities/error.hpp b/cpp/include/cudf/utilities/error.hpp index 8f6190bbaf7..b72e209d19a 100644 --- a/cpp/include/cudf/utilities/error.hpp +++ b/cpp/include/cudf/utilities/error.hpp @@ -35,8 +35,18 @@ namespace cudf { * CUDF_EXPECTS macro. */ struct logic_error : public std::logic_error { + /** + * @brief Constructs a logic_error with the error message. + * + * @param message Message to be associated with the exception + */ logic_error(char const* const message) : std::logic_error(message) {} + /** + * @brief Construct a new logic error object with error message + * + * @param message Message to be associated with the exception + */ logic_error(std::string const& message) : std::logic_error(message) {} // TODO Add an error code member? This would be useful for translating an @@ -46,27 +56,38 @@ struct logic_error : public std::logic_error { * @brief Exception thrown when a CUDA error is encountered. */ struct cuda_error : public std::runtime_error { + /** + * @brief Construct a new cuda error object with error message and code. + * + * @param message Error message + * @param error CUDA error code + */ cuda_error(std::string const& message, cudaError_t const& error) : std::runtime_error(message), _cudaError(error) { } public: + /** + * @brief Returns the CUDA error code associated with the exception. + * + * @return CUDA error code + */ cudaError_t error_code() const { return _cudaError; } protected: - cudaError_t _cudaError; + cudaError_t _cudaError; //!< CUDA error code }; struct fatal_cuda_error : public cuda_error { - using cuda_error::cuda_error; + using cuda_error::cuda_error; // Inherit constructors }; /** @} */ } // namespace cudf -#define STRINGIFY_DETAIL(x) #x -#define CUDF_STRINGIFY(x) STRINGIFY_DETAIL(x) +#define STRINGIFY_DETAIL(x) #x ///< Stringify a macro argument +#define CUDF_STRINGIFY(x) STRINGIFY_DETAIL(x) ///< Stringify a macro argument /** * @addtogroup utility_error @@ -111,7 +132,7 @@ struct fatal_cuda_error : public cuda_error { namespace cudf { namespace detail { - +// @cond inline void throw_cuda_error(cudaError_t error, const char* file, unsigned int line) { // Calls cudaGetLastError twice. It is nearly certain that a fatal error occurred if the second @@ -129,6 +150,7 @@ inline void throw_cuda_error(cudaError_t error, const char* file, unsigned int l throw cuda_error{msg, error}; } } +// @endcond } // namespace detail } // namespace cudf diff --git a/cpp/include/cudf/utilities/span.hpp b/cpp/include/cudf/utilities/span.hpp index f2686927cf7..f6c30b7a71a 100644 --- a/cpp/include/cudf/utilities/span.hpp +++ b/cpp/include/cudf/utilities/span.hpp @@ -31,6 +31,8 @@ namespace cudf { +/// A constant of type std::size_t that is used to differentiate std::span of static and dynamic +/// extent constexpr std::size_t dynamic_extent = std::numeric_limits::max(); namespace detail { @@ -43,43 +45,108 @@ class span_base { static_assert(Extent == dynamic_extent, "Only dynamic extent is supported"); public: - using element_type = T; - using value_type = std::remove_cv; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using pointer = T*; - using iterator = T*; - using const_pointer = T const*; - using reference = T&; - using const_reference = T const&; - - static constexpr std::size_t extent = Extent; + using element_type = T; ///< The type of the elements in the span + using value_type = std::remove_cv; ///< Stored value type + using size_type = std::size_t; ///< The type used for the size of the span + using difference_type = std::ptrdiff_t; ///< std::ptrdiff_t + using pointer = T*; ///< The type of the pointer returned by data() + using iterator = T*; ///< The type of the iterator returned by begin() + using const_pointer = T const*; ///< The type of the pointer returned by data() const + using reference = T&; ///< The type of the reference returned by operator[](size_type) + using const_reference = + T const&; ///< The type of the reference returned by operator[](size_type) const + + static constexpr std::size_t extent = Extent; ///< The extent of the span constexpr span_base() noexcept {} + /** + * @brief Constructs a span from a pointer and a size. + * + * @param data Pointer to the first element in the span. + * @param size The number of elements in the span. + */ constexpr span_base(pointer data, size_type size) : _data(data), _size(size) {} // constexpr span_base(pointer begin, pointer end) : _data(begin), _size(end - begin) {} - constexpr span_base(span_base const& other) noexcept = default; - constexpr span_base& operator=(span_base const& other) noexcept = default; + constexpr span_base(span_base const&) noexcept = default; ///< Copy constructor + /** + * @brief Copy assignment operator. + * + * @return Reference to this span. + */ + constexpr span_base& operator=(span_base const&) noexcept = default; // not noexcept due to undefined behavior when size = 0 + /** + * @brief Returns a reference to the first element in the span. + * Calling front on an empty span results in undefined behavior. + * + * @return Reference to the first element in the span + */ constexpr reference front() const { return _data[0]; } // not noexcept due to undefined behavior when size = 0 + /** + * @brief Returns a reference to the last element in the span. + * Calling last on an empty span results in undefined behavior. + * + * @return Reference to the last element in the span + */ constexpr reference back() const { return _data[_size - 1]; } // not noexcept due to undefined behavior when idx < 0 || idx >= size + /** + * @brief Returns a reference to the idx-th element of the sequence. + * The behavior is undefined if idx is out of range (i.e., if it is greater than or equal to + * size()). + * + * @param idx the index of the element to access + * @return A reference to the idx-th element of the sequence, i.e., `data()[idx]` + */ constexpr reference operator[](size_type idx) const { return _data[idx]; } + /** + * @brief Returns an iterator to the first element of the span. + * If the span is empty, the returned iterator will be equal to end(). + * + * @return An iterator to the first element of the span + */ constexpr iterator begin() const noexcept { return _data; } + /** + * @brief Returns an iterator to the element following the last element of the span. + * This element acts as a placeholder; attempting to access it results in undefined behavior. + * + * @return An iterator to the element following the last element of the span + */ constexpr iterator end() const noexcept { return _data + _size; } + /** + * @brief Returns a pointer to the beginning of the sequence. + * + * @return A pointer to the first element of the span + */ constexpr pointer data() const noexcept { return _data; } + /** + * @brief Returns the number of elements in the span. + * + * @return The number of elements in the span + */ [[nodiscard]] constexpr size_type size() const noexcept { return _size; } + /** + * @brief Returns the size of the sequence in bytes. + * + * @return The size of the sequence in bytes + */ [[nodiscard]] constexpr size_type size_bytes() const noexcept { return sizeof(T) * _size; } + /** + * @brief Checks if the span is empty. + * + * @return True if the span is empty, false otherwise + */ [[nodiscard]] constexpr bool empty() const noexcept { return _size == 0; } /** * @brief Obtains a subspan consisting of the first N elements of the sequence * * @param count Number of elements from the beginning of this span to put in the subspan. + * @return A subspan of the first N elements of the sequence */ constexpr Derived first(size_type count) const noexcept { return Derived(_data, count); } @@ -87,12 +154,20 @@ class span_base { * @brief Obtains a subspan consisting of the last N elements of the sequence * * @param count Number of elements from the end of this span to put in the subspan + * @return A subspan of the last N elements of the sequence */ constexpr Derived last(size_type count) const noexcept { return Derived(_data + _size - count, count); } + /** + * @brief Obtains a span that is a view over the `count` elements of this span starting at offset + * + * @param offset The offset of the first element in the subspan + * @param count The number of elements in the subspan + * @return A subspan of the sequence, of requested count and offset + */ constexpr Derived subspan(size_type offset, size_type count) const noexcept { return Derived(_data + offset, count); @@ -126,14 +201,18 @@ struct is_host_span_supported_container< // std::basic_string, Alloc>> : std::true_type { }; +/** + * @brief C++20 std::span with reduced feature set. + */ template struct host_span : public cudf::detail::span_base> { - using base = cudf::detail::span_base>; + using base = cudf::detail::span_base>; ///< Base type using base::base; constexpr host_span() noexcept : base() {} // required to compile on centos - // Constructor from container + /// Constructor from container + /// @param in The container to construct the span from template < typename C, // Only supported containers of types convertible to T @@ -145,7 +224,8 @@ struct host_span : public cudf::detail::span_base> : std::true_type { }; +/** + * @brief Device version of C++20 std::span with reduced feature set. + */ template struct device_span : public cudf::detail::span_base> { - using base = cudf::detail::span_base>; + using base = cudf::detail::span_base>; ///< Base type using base::base; constexpr device_span() noexcept : base() {} // required to compile on centos + /// Constructor from container + /// @param in The container to construct the span from template < typename C, // Only supported containers of types convertible to T @@ -208,6 +294,8 @@ struct device_span : public cudf::detail::span_base typename RowType> class base_2dspan { public: - using size_type = std::pair; + using size_type = + std::pair; ///< Type used to represent the dimension of the span constexpr base_2dspan() noexcept = default; + /** + * @brief Constructor a 2D span + * + * @param data Pointer to the data + * @param rows Number of rows + * @param columns Number of columns + */ constexpr base_2dspan(T* data, size_t rows, size_t columns) noexcept : _data{data}, _size{rows, columns} { } + /** + * @brief Constructor a 2D span + * + * @param data Pointer to the data + * @param size Size of the 2D span as pair + */ base_2dspan(T* data, size_type size) noexcept : _data{data}, _size{size} {} + /** + * @brief Returns a pointer to the beginning of the sequence. + * + * @return A pointer to the first element of the span + */ constexpr auto data() const noexcept { return _data; } + /** + * @brief Returns the size in the span as pair. + * + * @return pair representing rows and columns size of the span + */ constexpr auto size() const noexcept { return _size; } + /** + * @brief Returns the number of elements in the span. + * + * @return Number of elements in the span + */ constexpr auto count() const noexcept { return size().first * size().second; } + /** + * @brief Checks if the span is empty. + * + * @return True if the span is empty, false otherwise + */ [[nodiscard]] constexpr bool is_empty() const noexcept { return count() == 0; } + private: static constexpr size_t flatten_index(size_t row, size_t column, size_type size) noexcept { return row * size.second + column; } + public: + /** + * @brief Returns a reference to the row-th element of the sequence. + * The behavior is undefined if row is out of range (i.e., if it is greater than or equal to + * size()). + * + * @param row the index of the element to access + * @return A reference to the row-th element of the sequence, i.e., `data()[row]` + */ constexpr RowType operator[](size_t row) const { return {this->data() + flatten_index(row, 0, this->size()), this->size().second}; } + /** + * @brief Returns a reference to the first element in the span. + * Calling front on an empty span results in undefined behavior. + * + * @return Reference to the first element in the span + */ [[nodiscard]] constexpr RowType front() const { return (*this)[0]; } + /** + * @brief Returns a reference to the last element in the span. + * Calling last on an empty span results in undefined behavior. + * + * @return Reference to the last element in the span + */ [[nodiscard]] constexpr RowType back() const { return (*this)[size().first - 1]; } + /** + * @brief Obtains a 2D span that is a view over the `num_rows` rows of this span starting at + * `first_row` + * + * @param first_row The first row in the subspan + * @param num_rows The number of rows in the subspan + * @return A subspan of the sequence, of requested starting `first_row` and `num_rows` + */ constexpr base_2dspan subspan(size_t first_row, size_t num_rows) const noexcept { return base_2dspan( _data + flatten_index(first_row, 0, this->size()), num_rows, this->size().second); } + /** + * @brief Returns a flattened span of the 2D span. + * + * @return A flattened span of the 2D span + */ constexpr RowType flat_view() { return {this->data(), this->size().first * this->size().second}; } + /** + * @brief Construct a 2D span from another 2D span of convertible type + * + * @tparam OtherT Type of the other 2D span + * @tparam OtherRowType Type of the row of the other 2D span + * @param other The other 2D span + */ template typename OtherRowType, @@ -293,8 +459,8 @@ class base_2dspan { } protected: - T* _data = nullptr; - size_type _size{0, 0}; + T* _data = nullptr; ///< pointer to the first element + size_type _size{0, 0}; ///< rows, columns }; /** diff --git a/cpp/include/cudf/utilities/traits.hpp b/cpp/include/cudf/utilities/traits.hpp index d8fa7bff0b8..46baca48bee 100644 --- a/cpp/include/cudf/utilities/traits.hpp +++ b/cpp/include/cudf/utilities/traits.hpp @@ -31,6 +31,7 @@ namespace cudf { * @file */ +/// Utility metafunction that maps a sequence of any types to the type void. template using void_t = void; @@ -47,12 +48,15 @@ using void_t = void; */ #define CUDF_ENABLE_IF(...) std::enable_if_t<(__VA_ARGS__)>* = nullptr +/// Checks if two types are comparable using less operator (i.e. <). template using less_comparable = decltype(std::declval() < std::declval()); +/// Checks if two types are comparable using greater operator (i.e. >). template using greater_comparable = decltype(std::declval() > std::declval()); +/// Checks if two types are comparable using equality operator (i.e. ==). template using equality_comparable = decltype(std::declval() == std::declval()); @@ -86,12 +90,15 @@ struct has_common_type_impl>, Ts...> : std::tru }; } // namespace detail +/// Checks if types have a common type template using has_common_type = typename detail::has_common_type_impl::type; +/// Helper variable template for has_common_type<>::value template constexpr inline bool has_common_type_v = detail::has_common_type_impl::value; +/// Checks if a type is a timestamp type. template using is_timestamp_t = cuda::std::disjunction, std::is_same, @@ -99,6 +106,7 @@ using is_timestamp_t = cuda::std::disjunction std::is_same, std::is_same>; +/// Checks if a type is a duration type. template using is_duration_t = cuda::std::disjunction, std::is_same, @@ -129,6 +137,12 @@ namespace detail { * @brief Helper functor to check if a specified type `T` supports relational comparisons. */ struct unary_relationally_comparable_functor { + /** + * @brief Returns true if `T` supports relational comparisons. + * + * @tparam T Type to check + * @return true if `T` supports relational comparisons + */ template inline bool operator()() const { @@ -172,6 +186,12 @@ namespace detail { * @brief Helper functor to check if a specified type `T` supports equality comparisons. */ struct unary_equality_comparable_functor { + /** + * @brief Checks whether `T` supports equality comparisons. + * + * @tparam T Type to check + * @return true if `T` supports equality comparisons + */ template bool operator()() const { @@ -534,6 +554,7 @@ constexpr inline bool is_chrono(data_type type) * As further example, `duration_ns` is distinct from its concrete `int64_t` representation type, * but they are layout compatible. * + * @return true if `T` is layout compatible with its "representation" type */ template constexpr bool is_rep_layout_compatible() diff --git a/cpp/include/cudf/utilities/type_dispatcher.hpp b/cpp/include/cudf/utilities/type_dispatcher.hpp index 920c5222552..22d8b782e74 100644 --- a/cpp/include/cudf/utilities/type_dispatcher.hpp +++ b/cpp/include/cudf/utilities/type_dispatcher.hpp @@ -51,6 +51,7 @@ namespace cudf { * ``` * * @tparam T The type to map to a `cudf::type_id` + * @return The `cudf::type_id` corresponding to the specified type */ template inline constexpr type_id type_to_id() @@ -58,7 +59,16 @@ inline constexpr type_id type_to_id() return type_id::EMPTY; }; +/** + * @brief Maps a `cudf::type_id` types to it's corresponding C++ type name string + * + */ struct type_to_name { + /** + * @brief Maps a `cudf::type_id` types to it's corresponding C++ type name string + * + * @return The C++ type name as string + */ template inline std::string operator()() { @@ -124,6 +134,7 @@ constexpr bool type_id_matches_device_storage_type(type_id id) /** * @brief Checks if `id` is fixed_point (DECIMAL32/64/128) * + * @param id The `data_type::id` to check * @return `true` if `id` is `DECIMAL32`, `DECIMAL64` or `DECIMAL128` * @return `false` otherwise */ @@ -199,7 +210,7 @@ CUDF_TYPE_MAPPING(cudf::struct_view, type_id::STRUCT) */ template struct dispatch_storage_type { - using type = device_storage_type_t::type>; + using type = device_storage_type_t::type>; ///< The underlying type }; template @@ -334,6 +345,11 @@ MAP_DURATION_SCALAR(duration_ns) template using scalar_type_t = typename type_to_scalar_type_impl::ScalarType; +/** + * @brief Maps a C++ type to the scalar device type required to hold its value + * + * @tparam T The concrete C++ type to map + */ template using scalar_device_type_t = typename type_to_scalar_type_impl::ScalarDeviceType; @@ -534,6 +550,7 @@ CUDF_HOST_DEVICE __forceinline__ constexpr decltype(auto) type_dispatcher(cudf:: } } +// @cond namespace detail { template struct double_type_dispatcher_second_type { @@ -560,6 +577,7 @@ struct double_type_dispatcher_first_type { } }; } // namespace detail +// @endcond /** * @brief Dispatches two type template parameters to a callable. @@ -573,6 +591,8 @@ struct double_type_dispatcher_first_type { * parameter of the callable `F` * @param f The callable whose `operator()` template is invoked * @param args Parameter pack forwarded to the `operator()` invocation `F`. + * + * @return The result of invoking `f.template operator(args)` */ #pragma nv_exec_check_disable template