All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
system_memory_resource.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024-2025, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <rmm/cuda_device.hpp>
19 #include <rmm/cuda_stream_view.hpp>
20 #include <rmm/detail/error.hpp>
21 #include <rmm/detail/export.hpp>
22 #include <rmm/detail/format.hpp>
24 
25 #include <cstddef>
26 #include <string>
27 
28 namespace RMM_NAMESPACE {
29 namespace mr {
30 
31 namespace detail {
39 {
40  int pageableMemoryAccess;
41  RMM_CUDA_TRY(cudaDeviceGetAttribute(
42  &pageableMemoryAccess, cudaDevAttrPageableMemoryAccess, device_id.value()));
43  return pageableMemoryAccess == 1;
44 }
45 } // namespace detail
46 
75  public:
77  {
78  RMM_EXPECTS(rmm::mr::detail::is_system_memory_supported(rmm::get_current_cuda_device()),
79  "System memory allocator is not supported with this hardware/software version.");
80  }
81  ~system_memory_resource() override = default;
85  default;
87  default;
88 
89  private:
101  void* do_allocate(std::size_t bytes, [[maybe_unused]] cuda_stream_view stream) override
102  {
103  try {
104  return rmm::detail::aligned_host_allocate(
105  bytes, CUDA_ALLOCATION_ALIGNMENT, [](std::size_t size) { return ::operator new(size); });
106  } catch (std::bad_alloc const& e) {
107  auto const msg = std::string("Failed to allocate ") + rmm::detail::format_bytes(bytes) +
108  std::string("of memory: ") + e.what();
109  RMM_FAIL(msg.c_str(), rmm::out_of_memory);
110  }
111  }
112 
123  void do_deallocate(void* ptr,
124  [[maybe_unused]] std::size_t bytes,
125  cuda_stream_view stream) override
126  {
127  // With `cudaFree`, the CUDA runtime keeps track of dependent operations and does implicit
128  // synchronization. However, with SAM, since `free` is immediate, we need to wait for in-flight
129  // CUDA operations to finish before freeing the memory, to avoid potential use-after-free errors
130  // or race conditions.
131  stream.synchronize();
132 
133  rmm::detail::aligned_host_deallocate(
134  ptr, bytes, CUDA_ALLOCATION_ALIGNMENT, [](void* ptr) { ::operator delete(ptr); });
135  }
136 
147  [[nodiscard]] bool do_is_equal(device_memory_resource const& other) const noexcept override
148  {
149  return dynamic_cast<system_memory_resource const*>(&other) != nullptr;
150  }
156  friend void get_property(system_memory_resource const&, cuda::mr::device_accessible) noexcept {}
157 
163  friend void get_property(system_memory_resource const&, cuda::mr::host_accessible) noexcept {}
164 };
165 
166 // static property checks
167 static_assert(cuda::mr::async_resource_with<system_memory_resource, cuda::mr::device_accessible>);
168 static_assert(cuda::mr::async_resource_with<system_memory_resource, cuda::mr::host_accessible>); // end of group
170 } // namespace mr
171 } // namespace RMM_NAMESPACE
Strongly-typed non-owning wrapper for CUDA streams with default constructor.
Definition: cuda_stream_view.hpp:39
void synchronize() const
Synchronize the viewed CUDA stream.
Definition: cuda_stream_view.hpp:106
Base class for all librmm device memory allocation.
Definition: device_memory_resource.hpp:93
device_memory_resource derived class that uses malloc/free for allocation/deallocation.
Definition: system_memory_resource.hpp:74
system_memory_resource(system_memory_resource const &)=default
Default copy constructor.
system_memory_resource(system_memory_resource &&)=default
Default copy constructor.
system_memory_resource & operator=(system_memory_resource const &)=default
Default copy assignment operator.
friend void get_property(system_memory_resource const &, cuda::mr::device_accessible) noexcept
Enables the cuda::mr::device_accessible property.
Definition: system_memory_resource.hpp:156
friend void get_property(system_memory_resource const &, cuda::mr::host_accessible) noexcept
Enables the cuda::mr::host_accessible property.
Definition: system_memory_resource.hpp:163
system_memory_resource & operator=(system_memory_resource &&)=default
Default move assignment operator.
Exception thrown when RMM runs out of memory.
Definition: error.hpp:87
cuda_device_id get_current_cuda_device()
Returns a cuda_device_id for the current device.
Definition: cuda_device.hpp:99
static constexpr std::size_t CUDA_ALLOCATION_ALIGNMENT
Default alignment used for CUDA memory allocation.
Definition: aligned.hpp:43
Strong type for a CUDA device identifier.
Definition: cuda_device.hpp:41
constexpr value_type value() const noexcept
The wrapped integer value.
Definition: cuda_device.hpp:57
static bool is_system_memory_supported(cuda_device_id device_id)
Check if system allocated memory (SAM) is supported on the specified device.
Definition: system_memory_resource.hpp:38