All Classes Namespaces Functions Enumerations Enumerator Modules Pages
utils.hpp
1 /*
2  * Copyright (c) 2021-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 <chrono>
19 #include <cstring>
20 #include <future>
21 #include <optional>
22 #include <stdexcept>
23 #include <tuple>
24 #include <type_traits>
25 
26 #include <kvikio/error.hpp>
27 #include <kvikio/shim/cuda.hpp>
28 
29 namespace kvikio {
30 
31 // cuFile defines a page size to 4 KiB
32 inline constexpr std::size_t page_size = 4096;
33 
34 [[nodiscard]] off_t convert_size2off(std::size_t x);
35 
36 [[nodiscard]] ssize_t convert_size2ssize(std::size_t x);
37 
38 [[nodiscard]] CUdeviceptr convert_void2deviceptr(void const* devPtr);
39 
43 template <typename T, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
44 [[nodiscard]] std::int64_t convert_to_64bit(T value)
45 {
46  if constexpr (std::numeric_limits<T>::max() > std::numeric_limits<std::int64_t>::max()) {
47  KVIKIO_EXPECT(value <= std::numeric_limits<std::int64_t>::max(),
48  "convert_to_64bit(x): x too large to fit std::int64_t",
49  std::overflow_error);
50  }
51  return std::int64_t(value);
52 }
53 
58 [[nodiscard]] inline std::uint64_t convert_to_64bit(std::uint64_t value) { return value; }
59 
63 template <typename T, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
64 [[nodiscard]] double convert_to_64bit(T value)
65 {
66  return double(value);
67 }
68 
77 #ifdef KVIKIO_CUDA_FOUND
78 bool is_host_memory(void const* ptr);
79 #else
80 constexpr bool is_host_memory(void const* ptr) { return true; }
81 #endif
82 
89 [[nodiscard]] int get_device_ordinal_from_pointer(CUdeviceptr dev_ptr);
90 
99 [[nodiscard]] KVIKIO_EXPORT CUcontext get_primary_cuda_context(int ordinal);
100 
107 [[nodiscard]] std::optional<CUcontext> get_context_associated_pointer(CUdeviceptr dev_ptr);
108 
115 [[nodiscard]] bool current_context_can_access_pointer(CUdeviceptr dev_ptr);
116 
133 [[nodiscard]] CUcontext get_context_from_pointer(void const* devPtr);
134 
139  private:
140  CUcontext _ctx;
141 
142  public:
143  PushAndPopContext(CUcontext ctx);
144  PushAndPopContext(PushAndPopContext const&) = delete;
145  PushAndPopContext& operator=(PushAndPopContext const&) = delete;
147  PushAndPopContext&& operator=(PushAndPopContext&&) = delete;
149 };
150 
151 // Find the base and offset of the memory allocation `devPtr` is in
152 std::tuple<void*, std::size_t, std::size_t> get_alloc_info(void const* devPtr,
153  CUcontext* ctx = nullptr);
154 
166 template <typename T>
167 std::future<std::decay_t<T>> make_ready_future(T&& t)
168 {
169  std::promise<std::decay_t<T>> p;
170  auto fut = p.get_future();
171  p.set_value(std::forward<T>(t));
172  return fut;
173 }
174 
186 template <typename T>
187 bool is_future_done(T const& future)
188 {
189  KVIKIO_EXPECT(future.valid(),
190  "The future object does not refer to a valid shared state.",
191  std::invalid_argument);
192  return future.wait_for(std::chrono::seconds(0)) != std::future_status::timeout;
193 }
194 
195 } // namespace kvikio
Push CUDA context on creation and pop it on destruction.
Definition: utils.hpp:138
#define KVIKIO_EXPECT(...)
Macro for checking pre-conditions or conditions that throws an exception when a condition is violated...
Definition: error.hpp:216
KvikIO namespace.
Definition: batch.hpp:27
CUcontext get_context_from_pointer(void const *devPtr)
Return a CUDA context that can be used with the given device pointer.
constexpr bool is_host_memory(void const *ptr)
Check if ptr points to host memory (as opposed to device memory)
Definition: utils.hpp:80
std::int64_t convert_to_64bit(T value)
Help function to convert value to 64 bit signed integer.
Definition: utils.hpp:44
bool current_context_can_access_pointer(CUdeviceptr dev_ptr)
Check if the current CUDA context can access the given device pointer.
bool is_future_done(T const &future)
Check the status of the future object. True indicates that the result is available in the future's sh...
Definition: utils.hpp:187
KVIKIO_EXPORT CUcontext get_primary_cuda_context(int ordinal)
Given a device ordinal, return the primary context of the device.
std::future< std::decay_t< T > > make_ready_future(T &&t)
Create a shared state in a future object that is immediately ready.
Definition: utils.hpp:167
std::optional< CUcontext > get_context_associated_pointer(CUdeviceptr dev_ptr)
Return the CUDA context associated the given device pointer, if any.
int get_device_ordinal_from_pointer(CUdeviceptr dev_ptr)
Return the device owning the pointer.