binning_memory_resource.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2020-2025, NVIDIA CORPORATION.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #pragma once
6 
7 #include <rmm/aligned.hpp>
8 #include <rmm/detail/export.hpp>
11 #include <rmm/resource_ref.hpp>
12 
13 #include <cuda_runtime_api.h>
14 
15 #include <cassert>
16 #include <map>
17 #include <memory>
18 #include <optional>
19 #include <vector>
20 
21 namespace RMM_NAMESPACE {
22 namespace mr {
35 template <typename Upstream>
37  public:
47  : upstream_mr_{upstream_resource}
48  {
49  }
50 
61  explicit binning_memory_resource(Upstream* upstream_resource)
62  : upstream_mr_{to_device_async_resource_ref_checked(upstream_resource)}
63  {
64  }
65 
79  int8_t min_size_exponent, // NOLINT(bugprone-easily-swappable-parameters)
80  int8_t max_size_exponent)
81  : upstream_mr_{upstream_resource}
82  {
83  for (auto i = min_size_exponent; i <= max_size_exponent; i++) {
84  add_bin(1 << i);
85  }
86  }
87 
102  binning_memory_resource(Upstream* upstream_resource,
103  int8_t min_size_exponent, // NOLINT(bugprone-easily-swappable-parameters)
104  int8_t max_size_exponent)
105  : upstream_mr_{to_device_async_resource_ref_checked(upstream_resource)}
106  {
107  for (auto i = min_size_exponent; i <= max_size_exponent; i++) {
108  add_bin(1 << i);
109  }
110  }
111 
116  ~binning_memory_resource() override = default;
117 
118  binning_memory_resource() = delete;
121  binning_memory_resource& operator=(binning_memory_resource const&) = delete;
122  binning_memory_resource& operator=(binning_memory_resource&&) = delete;
123 
127  [[nodiscard]] device_async_resource_ref get_upstream_resource() const noexcept
128  {
129  return upstream_mr_;
130  }
131 
147  void add_bin(std::size_t allocation_size,
148  std::optional<device_async_resource_ref> bin_resource = std::nullopt)
149  {
150  allocation_size = align_up(allocation_size, CUDA_ALLOCATION_ALIGNMENT);
151 
152  if (bin_resource.has_value()) {
153  resource_bins_.insert({allocation_size, bin_resource.value()});
154  } else if (resource_bins_.count(allocation_size) == 0) { // do nothing if bin already exists
155  owned_bin_resources_.push_back(
156  std::make_unique<fixed_size_memory_resource<Upstream>>(upstream_mr_, allocation_size));
157  resource_bins_.insert({allocation_size, owned_bin_resources_.back().get()});
158  }
159  }
160 
161  private:
170  device_async_resource_ref get_resource_ref(std::size_t bytes)
171  {
172  auto iter = resource_bins_.lower_bound(bytes);
173  return (iter != resource_bins_.cend()) ? iter->second : get_upstream_resource();
174  }
175 
185  void* do_allocate(std::size_t bytes, cuda_stream_view stream) override
186  {
187  if (bytes <= 0) { return nullptr; }
188  return get_resource_ref(bytes).allocate(stream, bytes);
189  }
190 
199  void do_deallocate(void* ptr, std::size_t bytes, cuda_stream_view stream) noexcept override
200  {
201  get_resource_ref(bytes).deallocate(stream, ptr, bytes);
202  }
203 
205  upstream_mr_; // The upstream memory_resource from which to allocate blocks.
206 
207  std::vector<std::unique_ptr<fixed_size_memory_resource<Upstream>>> owned_bin_resources_;
208 
209  std::map<std::size_t, device_async_resource_ref> resource_bins_;
210 };
211  // end of group
213 } // namespace mr
214 } // namespace RMM_NAMESPACE
Strongly-typed non-owning wrapper for CUDA streams with default constructor.
Definition: cuda_stream_view.hpp:28
Allocates memory from upstream resources associated with bin sizes.
Definition: binning_memory_resource.hpp:36
binning_memory_resource(Upstream *upstream_resource)
Construct a new binning memory resource object.
Definition: binning_memory_resource.hpp:61
device_async_resource_ref get_upstream_resource() const noexcept
device_async_resource_ref to the upstream resource
Definition: binning_memory_resource.hpp:127
binning_memory_resource(device_async_resource_ref upstream_resource, int8_t min_size_exponent, int8_t max_size_exponent)
Construct a new binning memory resource object with a range of initial bins.
Definition: binning_memory_resource.hpp:78
~binning_memory_resource() override=default
Destroy the binning_memory_resource and free all memory allocated from the upstream resource.
binning_memory_resource(Upstream *upstream_resource, int8_t min_size_exponent, int8_t max_size_exponent)
Construct a new binning memory resource object with a range of initial bins.
Definition: binning_memory_resource.hpp:102
binning_memory_resource(device_async_resource_ref upstream_resource)
Construct a new binning memory resource object.
Definition: binning_memory_resource.hpp:46
void add_bin(std::size_t allocation_size, std::optional< device_async_resource_ref > bin_resource=std::nullopt)
Add a bin allocator to this resource.
Definition: binning_memory_resource.hpp:147
Base class for all librmm device memory allocation.
Definition: device_memory_resource.hpp:83
A device_memory_resource which allocates memory blocks of a single fixed size.
Definition: fixed_size_memory_resource.hpp:42
device_async_resource_ref to_device_async_resource_ref_checked(Resource *res)
Convert pointer to memory resource into device_async_resource_ref, checking for nullptr
Definition: resource_ref.hpp:72
detail::cccl_async_resource_ref< cuda::mr::resource_ref< cuda::mr::device_accessible > > device_async_resource_ref
Alias for a cuda::mr::async_resource_ref with the property cuda::mr::device_accessible.
Definition: resource_ref.hpp:32
static constexpr std::size_t CUDA_ALLOCATION_ALIGNMENT
Default alignment used for CUDA memory allocation.
Definition: aligned.hpp:31
std::size_t align_up(std::size_t value, std::size_t alignment) noexcept
Align up to nearest multiple of specified power of 2.