Skip to content

Commit

Permalink
Review issues + comparison
Browse files Browse the repository at this point in the history
* Fix typos.
* Move base interfaces to namespace detail.
* Add resource_view comparison.
* Add a view_resource with default property (is_kind).

Signed-off-by: Michał Zientkiewicz <[email protected]>
  • Loading branch information
mzient committed Jun 7, 2021
1 parent dde1c62 commit 319db3e
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
#include <memory>
#include <tuple>
#include <vector>
#include "resource_hierarchy.h"


class sync_resource : public cuda::memory_resource<cuda::memory_kind::pinned> {
public:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int main(int argc, char **argv) {
static_assert(cuda::detail::is_resource_pointer_convertible<derived2*,cuda::memory_resource<cuda::memory_kind::managed>*>::value,
"A pointer to a derived class should be convertible to a pointer of public a base class");

static_assert(cuda::detail::is_resource_pointer_convertible<derived2*, cuda::memory_resource_base*>::value,
static_assert(cuda::detail::is_resource_pointer_convertible<derived2*, cuda::detail::memory_resource_base*>::value,
"A pointer to a derived memory resource should be convertible to a pointer to the common base.");

static_assert(cuda::detail::is_resource_pointer_convertible<derived_async2*, derived_async1*>::value,
Expand All @@ -35,7 +35,7 @@ int main(int argc, char **argv) {
static_assert(cuda::detail::is_resource_pointer_convertible<derived_async2*, cuda::stream_ordered_memory_resource<cuda::memory_kind::managed>*>::value,
"A pointer to a derived class should be convertible to a pointer of public a base class");

static_assert(cuda::detail::is_resource_pointer_convertible<derived_async2*, cuda::stream_ordered_memory_resource_base*>::value,
static_assert(cuda::detail::is_resource_pointer_convertible<derived_async2*, cuda::detail::stream_ordered_memory_resource_base*>::value,
"A pointer to a derived memory resource should be convertible to a pointer to the common base.");


Expand All @@ -51,13 +51,13 @@ int main(int argc, char **argv) {
static_assert(!cuda::detail::is_resource_pointer_convertible<derived2*, cuda::stream_ordered_memory_resource<cuda::memory_kind::managed>*>::value,
"A pointer to a synchronous resource should not be convertible to a stream ordered one");

static_assert(!cuda::detail::is_resource_pointer_convertible<derived2*, cuda::stream_ordered_memory_resource_base*>::value,
static_assert(!cuda::detail::is_resource_pointer_convertible<derived2*, cuda::detail::stream_ordered_memory_resource_base*>::value,
"A pointer to a synchronous resource should not be convertible to a stream ordered one");

static_assert(!cuda::detail::is_resource_pointer_convertible<cuda::stream_ordered_memory_resource_base*, cuda::stream_ordered_memory_resource<cuda::memory_kind::managed>*>::value,
static_assert(!cuda::detail::is_resource_pointer_convertible<cuda::detail::stream_ordered_memory_resource_base*, cuda::stream_ordered_memory_resource<cuda::memory_kind::managed>*>::value,
"A pointer to a commnon base class should not be convertible to a pointer to a kind-qualified resource.");

static_assert(!cuda::detail::is_resource_pointer_convertible<cuda::memory_resource_base*, cuda::memory_resource<cuda::memory_kind::managed>*>::value,
static_assert(!cuda::detail::is_resource_pointer_convertible<cuda::detail::memory_resource_base*, cuda::memory_resource<cuda::memory_kind::managed>*>::value,
"A pointer to a commnon base class should not be convertible to a pointer to a kind-qualified resource.");

static_assert(!cuda::detail::is_resource_pointer_convertible<
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//===----------------------------------------------------------------------===//
//
// Part of libcu++, the C++ Standard Library for your entire system,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//


#include <cassert>
#include <cuda/memory_resource>
#include <cuda/std/cstddef>
#include <cuda/std/type_traits>
#include <memory>
#include <tuple>
#include <vector>


template <typename tag>
class resource : public cuda::memory_resource<cuda::memory_kind::pinned> {
public:
int value = 0;
private:
void *do_allocate(size_t, size_t) override {
return nullptr;
}

void do_deallocate(void *, size_t, size_t) {
}

#ifndef _LIBCUDACXX_NO_RTTI
bool do_is_equal(const cuda::memory_resource<cuda::memory_kind::pinned> &other) const noexcept override {
if (auto *other_ptr = dynamic_cast<const resource *>(&other)) {
return value == other_ptr->value;
} else {
return false;
}
}
#endif
};


struct tag1;
struct tag2;

int main(int argc, char **argv) {
#if !defined(__CUDA_ARCH__) && !defined(_LIBCUDACXX_NO_RTTI)
resource<tag1> r1, r2, r3;
resource<tag2> r4;
r1.value = 42;
r2.value = 42;
r3.value = 99;
r4.value = 42;

assert(view_resource(&r1) == view_resource(&r2));
assert(view_resource(&r1) != view_resource(&r3));
assert(view_resource(&r1) == view_resource(&r4));
#endif
return 0;
}
97 changes: 76 additions & 21 deletions include/cuda/memory_resource
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ namespace memory_location {
struct host;
}

namespace detail {

class memory_resource_base {
public:
Expand Down Expand Up @@ -167,8 +168,18 @@ public:
do_deallocate(__mem, __bytes, __alignment);
}

protected:
virtual void *do_allocate(size_t __bytes, size_t __alignment) = 0;
virtual void do_deallocate(void *__mem, size_t __bytes, size_t __alignment) = 0;

virtual bool is_equal_base(const memory_resource_base &other) const noexcept = 0;

bool is_equal(const memory_resource_base &other) const noexcept {
return is_equal_base(other);
}

template <typename _ResourcePointer, typename... _Properties>
friend class basic_resource_view;
};

class stream_ordered_memory_resource_base : public virtual memory_resource_base {
Expand Down Expand Up @@ -280,10 +291,17 @@ public:
void deallocate_async(void *__mem, size_t __bytes, size_t __alignment, stream_view __stream) {
do_deallocate_async(__mem, __bytes, __alignment, __stream);
}

protected:
virtual void *do_allocate_async(size_t __bytes, size_t __alignment, stream_view __stream) = 0;
virtual void do_deallocate_async(void *__mem, size_t __bytes, size_t __alignment, stream_view __stream) = 0;

template <typename _ResourcePointer, typename... _Properties>
friend class basic_resource_view;
};

} // namespace detail

/*!
* \brief Abstract interface for context specific memory allocation.
*
Expand All @@ -292,7 +310,7 @@ public:
* without synchronization
*/
template <typename _MemoryKind, typename _Context = any_context>
class memory_resource : private virtual memory_resource_base, private detail::__get_context_impl<_Context> {
class memory_resource : private virtual detail::memory_resource_base, private detail::__get_context_impl<_Context> {
public:
using memory_kind = _MemoryKind;
using context = _Context;
Expand Down Expand Up @@ -374,9 +392,21 @@ private:
std::size_t __alignment) = 0;

// Default to identity comparison
virtual bool do_is_equal(memory_resource const &__other) const noexcept{
virtual bool do_is_equal(memory_resource const &__other) const noexcept {
return this == &__other;
}

bool is_equal_base(const detail::memory_resource_base &__other) const noexcept final override {
#if _LIBCUDACXX_NO_RTTI
return this == &__other;
#else
if (auto *__other_res = dynamic_cast<const memory_resource *>(&__other))
return do_is_equal(__other_res);
else
return false;
#endif
}

};

#if _LIBCUDACXX_STD_VER > 14
Expand Down Expand Up @@ -465,7 +495,7 @@ private:
*/
template <typename _MemoryKind>
class stream_ordered_memory_resource : public virtual memory_resource<_MemoryKind>,
private virtual stream_ordered_memory_resource_base {
private virtual detail::stream_ordered_memory_resource_base {
public:
using memory_kind = _MemoryKind;
static constexpr _CUDA_VSTD::size_t default_alignment = memory_resource<_MemoryKind>::default_alignment;
Expand Down Expand Up @@ -687,15 +717,15 @@ struct is_resource_pointer_convertible : _CUDA_VSTD::is_convertible<_FromPointer
// Private inheritance from (stream_ordered_)memory_resource_base* requires explicit partial specializations as `is_convertible` will return false

template <typename _FromPointer>
struct is_resource_pointer_convertible<_FromPointer, memory_resource_base*>
struct is_resource_pointer_convertible<_FromPointer, detail::memory_resource_base*>
: _CUDA_VSTD::conjunction<_CUDA_VSTD::is_pointer<_FromPointer>,
_CUDA_VSTD::is_base_of<memory_resource_base,
_CUDA_VSTD::is_base_of<detail::memory_resource_base,
typename ::std::pointer_traits<_FromPointer>::element_type>> {};

template <typename _FromPointer>
struct is_resource_pointer_convertible<_FromPointer, stream_ordered_memory_resource_base*>
struct is_resource_pointer_convertible<_FromPointer, detail::stream_ordered_memory_resource_base*>
: _CUDA_VSTD::conjunction<_CUDA_VSTD::is_pointer<_FromPointer>,
_CUDA_VSTD::is_base_of<stream_ordered_memory_resource_base,
_CUDA_VSTD::is_base_of<detail::stream_ordered_memory_resource_base,
typename ::std::pointer_traits<_FromPointer>::element_type>> {};

} // namespace detail
Expand All @@ -719,16 +749,17 @@ struct is_view_convertible<
* Resource view is an object that acts as a memory resource pointer, but provides
* enhanced implicit conversions. The idea behind this type is that a user of
* a memory resource may be interested in many kinds of resources as long as they
* have certain properties - for example, a function may work with any resource
* that can provide host-accessible memory - be it plain host memory, pinned memory
* or managed memory or some future kind of memory, not yet defined.
* have certain properties. For example, a function may work with any resource
* that can provide host-accessible memory, regardless of whether it is plain host
* memory, pinned memory, managed memory, or some,yet-to-be-defined future kind
* of memory.
*
* A resource view can be created from a memory resource pointer or from another
* resource view, which defines a superset of the target properties.
* resource view that defines a superset of the target properties.
*
* The resource view exposes ther underlying resource's interface via `operator->`.
* The resource view exposes the underlying resource's interface via `operator->`.
*
* The `basic_resource_view` class can be parameterized with te resource pointer type,
* The `basic_resource_view` class can be parameterized with the resource pointer type,
* which can be either one of the base resource classes or a concrete resource type.
*
* \tparam _ResourcePointer a pointer-like object to the underlying memory resource
Expand All @@ -738,9 +769,9 @@ template <typename _ResourcePointer, typename... _Properties>
class basic_resource_view {
public:
static_assert(
_CUDA_VSTD::is_base_of<memory_resource_base, typename ::std::pointer_traits<_ResourcePointer>::element_type>::value ||
_CUDA_VSTD::is_base_of<stream_ordered_memory_resource_base, typename ::std::pointer_traits<_ResourcePointer>::element_type>::value,
"ResourcePointer must be a pointer to a memory_resource_base, stream_ordered_memory_resource_base or a derived class");
_CUDA_VSTD::is_base_of<detail::memory_resource_base, typename ::std::pointer_traits<_ResourcePointer>::element_type>::value ||
_CUDA_VSTD::is_base_of<detail::stream_ordered_memory_resource_base, typename ::std::pointer_traits<_ResourcePointer>::element_type>::value,
"ResourcePointer must be a pointer to a memory_resource_base, stream_ordered_memory_resource_base or a derived class");

basic_resource_view() = default;

Expand Down Expand Up @@ -781,7 +812,23 @@ public:
*
* \note This method should not be used to obtain the pointer to the memory resource.
*/
_ResourcePointer operator->() const { return __pointer; }
_ResourcePointer operator->() const noexcept { return __pointer; }


template <typename _Ptr2, typename... _Props2>
bool operator==(const cuda::basic_resource_view<_Ptr2, _Props2...> &__v2) const noexcept {
using __view1_t = basic_resource_view;
using __view2_t = basic_resource_view<_Ptr2, _Props2...>;
static_assert(cuda::is_view_convertible<__view1_t, __view2_t>::value || cuda::is_view_convertible<__view2_t, __view1_t>::value,
"The resource views are not compatible");
return static_cast<const detail::memory_resource_base*>(__pointer)->is_equal(__v2.pointer);
}

template <typename _Ptr2, typename... _Props2>
bool operator!=(const cuda::basic_resource_view<_Ptr2, _Props2...> &__v2) const noexcept {
return !(*this == __v2);
}


private:
template <typename, typename...>
Expand All @@ -790,16 +837,24 @@ private:
_ResourcePointer __pointer{};
};

template <typename... _Properties, typename _ResourcePointer>
basic_resource_view<_ResourcePointer, _Properties...> view_resource(_ResourcePointer __rsrc_ptr) {
template <typename _FirstProperty, typename... _Properties, typename _ResourcePointer>
basic_resource_view<_ResourcePointer, _FirstProperty, _Properties...>
view_resource(_ResourcePointer __rsrc_ptr) {
return __rsrc_ptr;
}


template <typename _ResourcePointer>
basic_resource_view<_ResourcePointer, is_kind<typename std::remove_pointer_t<_ResourcePointer>::memory_kind>>
view_resource(_ResourcePointer __rsrc_ptr) {
return __rsrc_ptr;
}

template <typename... _Properties>
using resource_view = basic_resource_view<memory_resource_base*, _Properties...>;
using resource_view = basic_resource_view<detail::memory_resource_base*, _Properties...>;

template <typename... _Properties>
using stream_ordered_resource_view = basic_resource_view<stream_ordered_memory_resource_base*, _Properties...>;
using stream_ordered_resource_view = basic_resource_view<detail::stream_ordered_memory_resource_base*, _Properties...>;


_LIBCUDACXX_END_NAMESPACE_CUDA
Expand Down

0 comments on commit 319db3e

Please sign in to comment.