All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
logging_resource_adaptor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020-2024, 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_stream_view.hpp>
19 #include <rmm/detail/error.hpp>
20 #include <rmm/detail/export.hpp>
21 #include <rmm/detail/format.hpp>
23 #include <rmm/resource_ref.hpp>
24 
25 #include <spdlog/common.h>
26 #include <spdlog/sinks/basic_file_sink.h>
27 #include <spdlog/sinks/ostream_sink.h>
28 #include <spdlog/spdlog.h>
29 
30 #include <cstddef>
31 #include <cstdio>
32 #include <memory>
33 #include <sstream>
34 #include <string_view>
35 
36 namespace RMM_NAMESPACE {
37 namespace mr {
54 template <typename Upstream>
56  public:
78  logging_resource_adaptor(Upstream* upstream,
79  std::string const& filename = get_default_filename(),
80  bool auto_flush = false)
81  : logger_{make_logger(filename)}, upstream_{to_device_async_resource_ref_checked(upstream)}
82  {
83  init_logger(auto_flush);
84  }
85 
100  logging_resource_adaptor(Upstream* upstream, std::ostream& stream, bool auto_flush = false)
101  : logger_{make_logger(stream)}, upstream_{to_device_async_resource_ref_checked(upstream)}
102  {
103  init_logger(auto_flush);
104  }
105 
120  logging_resource_adaptor(Upstream* upstream,
121  spdlog::sinks_init_list sinks,
122  bool auto_flush = false)
123  : logger_{make_logger(sinks)}, upstream_{to_device_async_resource_ref_checked(upstream)}
124  {
125  init_logger(auto_flush);
126  }
127 
149  std::string const& filename = get_default_filename(),
150  bool auto_flush = false)
151  : logger_{make_logger(filename)}, upstream_{upstream}
152  {
153  init_logger(auto_flush);
154  }
155 
169  std::ostream& stream,
170  bool auto_flush = false)
171  : logger_{make_logger(stream)}, upstream_{upstream}
172  {
173  init_logger(auto_flush);
174  }
175 
189  spdlog::sinks_init_list sinks,
190  bool auto_flush = false)
191  : logger_{make_logger(sinks)}, upstream_{upstream}
192  {
193  init_logger(auto_flush);
194  }
195 
196  logging_resource_adaptor() = delete;
197  ~logging_resource_adaptor() override = default;
199  logging_resource_adaptor& operator=(logging_resource_adaptor const&) = delete;
201  default;
203  default;
204 
208  [[nodiscard]] rmm::device_async_resource_ref get_upstream_resource() const noexcept
209  {
210  return upstream_;
211  }
212 
216  void flush() { logger_->flush(); }
217 
223  [[nodiscard]] std::string header() const
224  {
225  return std::string{"Thread,Time,Action,Pointer,Size,Stream"};
226  }
227 
235  static std::string get_default_filename()
236  {
237  auto* filename = std::getenv("RMM_LOG_FILE");
238  RMM_EXPECTS(filename != nullptr,
239  "RMM logging requested without an explicit file name, but RMM_LOG_FILE is unset");
240  return std::string{filename};
241  }
242 
243  private:
244  static auto make_logger(std::ostream& stream)
245  {
246  return std::make_shared<spdlog::logger>(
247  "RMM", std::make_shared<spdlog::sinks::ostream_sink_mt>(stream));
248  }
249 
250  static auto make_logger(std::string const& filename)
251  {
252  return std::make_shared<spdlog::logger>(
253  "RMM", std::make_shared<spdlog::sinks::basic_file_sink_mt>(filename, true /*truncate file*/));
254  }
255 
256  static auto make_logger(spdlog::sinks_init_list sinks)
257  {
258  return std::make_shared<spdlog::logger>("RMM", sinks);
259  }
260 
264  void init_logger(bool auto_flush)
265  {
266  if (auto_flush) { logger_->flush_on(spdlog::level::info); }
267  logger_->set_pattern("%v");
268  logger_->info(header());
269  logger_->set_pattern("%t,%H:%M:%S.%f,%v");
270  }
271 
297  void* do_allocate(std::size_t bytes, cuda_stream_view stream) override
298  {
299  try {
300  auto const ptr = get_upstream_resource().allocate_async(bytes, stream);
301  logger_->info(rmm::detail::formatted_log(
302  "allocate,%p,%zu,%s", ptr, bytes, rmm::detail::format_stream(stream)));
303  return ptr;
304  } catch (...) {
305  logger_->info(rmm::detail::formatted_log(
306  "allocate failure,%p,%zu,%s", nullptr, bytes, rmm::detail::format_stream(stream)));
307  throw;
308  }
309  }
310 
325  void do_deallocate(void* ptr, std::size_t bytes, cuda_stream_view stream) override
326  {
327  logger_->info(
328  rmm::detail::formatted_log("free,%p,%zu,%s", ptr, bytes, rmm::detail::format_stream(stream)));
329  get_upstream_resource().deallocate_async(ptr, bytes, stream);
330  }
331 
339  [[nodiscard]] bool do_is_equal(device_memory_resource const& other) const noexcept override
340  {
341  if (this == &other) { return true; }
342  auto const* cast = dynamic_cast<logging_resource_adaptor<Upstream> const*>(&other);
343  if (cast == nullptr) { return false; }
344  return get_upstream_resource() == cast->get_upstream_resource();
345  }
346 
347  std::shared_ptr<spdlog::logger> logger_;
348 
349  device_async_resource_ref upstream_;
351 };
352 
365 template <typename Upstream>
366 [[deprecated(
367  "make_logging_adaptor is deprecated in RMM 24.10. Use the logging_resource_adaptor constructor "
368  "instead.")]]
370  Upstream* upstream,
371  std::string const& filename = logging_resource_adaptor<Upstream>::get_default_filename(),
372  bool auto_flush = false)
373 {
374  return logging_resource_adaptor<Upstream>{upstream, filename, auto_flush};
375 }
376 
388 template <typename Upstream>
389 [[deprecated(
390  "make_logging_adaptor is deprecated in RMM 24.10. Use the logging_resource_adaptor constructor "
391  "instead.")]]
393  std::ostream& stream,
394  bool auto_flush = false)
395 {
396  return logging_resource_adaptor<Upstream>{upstream, stream, auto_flush};
397 }
398  // end of group
400 } // namespace mr
401 } // namespace RMM_NAMESPACE
Base class for all libcudf device memory allocation.
Definition: device_memory_resource.hpp:94
Resource that uses Upstream to allocate memory and logs information about the requested allocation/de...
Definition: logging_resource_adaptor.hpp:55
std::string header() const
Return the CSV header string.
Definition: logging_resource_adaptor.hpp:223
logging_resource_adaptor(device_async_resource_ref upstream, std::string const &filename=get_default_filename(), bool auto_flush=false)
Construct a new logging resource adaptor using upstream to satisfy allocation requests and logging in...
Definition: logging_resource_adaptor.hpp:148
void flush()
Flush logger contents.
Definition: logging_resource_adaptor.hpp:216
logging_resource_adaptor(Upstream *upstream, std::string const &filename=get_default_filename(), bool auto_flush=false)
Construct a new logging resource adaptor using upstream to satisfy allocation requests and logging in...
Definition: logging_resource_adaptor.hpp:78
static std::string get_default_filename()
Return the value of the environment variable RMM_LOG_FILE.
Definition: logging_resource_adaptor.hpp:235
logging_resource_adaptor(logging_resource_adaptor &&) noexcept=default
Default move constructor.
logging_resource_adaptor(Upstream *upstream, std::ostream &stream, bool auto_flush=false)
Construct a new logging resource adaptor using upstream to satisfy allocation requests and logging in...
Definition: logging_resource_adaptor.hpp:100
logging_resource_adaptor(Upstream *upstream, spdlog::sinks_init_list sinks, bool auto_flush=false)
Construct a new logging resource adaptor using upstream to satisfy allocation requests and logging in...
Definition: logging_resource_adaptor.hpp:120
logging_resource_adaptor(device_async_resource_ref upstream, std::ostream &stream, bool auto_flush=false)
Construct a new logging resource adaptor using upstream to satisfy allocation requests and logging in...
Definition: logging_resource_adaptor.hpp:168
logging_resource_adaptor(device_async_resource_ref upstream, spdlog::sinks_init_list sinks, bool auto_flush=false)
Construct a new logging resource adaptor using upstream to satisfy allocation requests and logging in...
Definition: logging_resource_adaptor.hpp:188
logging_resource_adaptor< Upstream > make_logging_adaptor(Upstream *upstream, std::ostream &stream, bool auto_flush=false)
Convenience factory to return a logging_resource_adaptor around the upstream resource upstream.
Definition: logging_resource_adaptor.hpp:392
cuda::mr::async_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:41
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:79