Ginkgo  Generated from pipelines/1478841010 branch based on develop. Ginkgo version 1.9.0
A numerical linear algebra library targeting many-core architectures
machine_topology.hpp
1 // SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_BASE_MACHINE_TOPOLOGY_HPP_
6 #define GKO_PUBLIC_CORE_BASE_MACHINE_TOPOLOGY_HPP_
7 
8 
9 #include <cassert>
10 #include <cstddef>
11 #include <functional>
12 #include <iostream>
13 #include <memory>
14 #include <mutex>
15 #include <string>
16 #include <type_traits>
17 #include <vector>
18 
19 #include <ginkgo/config.hpp>
20 #include <ginkgo/core/base/exception.hpp>
21 #include <ginkgo/core/base/exception_helpers.hpp>
22 
23 
24 #if GKO_HAVE_HWLOC
25 
26 #include <hwloc.h>
27 
28 #else
29 
30 struct hwloc_obj_type_t {};
31 struct hwloc_obj_t {};
32 
33 #endif
34 
35 
36 struct hwloc_topology;
37 struct hwloc_bitmap_s;
38 
39 
40 namespace gko {
41 
42 
62  template <typename T>
63  using hwloc_manager = std::unique_ptr<T, std::function<void(T*)>>;
64 
68  struct normal_obj_info {
72  hwloc_obj_t obj;
73 
81  size_type logical_id;
82 
86  size_type os_id;
87 
91  size_type gp_id;
92 
96  int numa;
97 
101  size_type memory_size;
102  };
103 
104 
121  struct io_obj_info {
125  hwloc_obj_t obj;
126 
133  size_type logical_id;
134 
138  size_type os_id;
139 
143  size_type gp_id;
144 
148  int closest_numa;
149 
153  hwloc_obj_t non_io_ancestor;
154 
158  int ancestor_local_id;
159 
163  std::string ancestor_type;
164 
168  std::vector<int> closest_pu_ids;
169 
173  std::string pci_bus_id;
174  };
175 
176 public:
183  {
184  static machine_topology instance;
185  return &instance;
186  }
187 
200  void bind_to_cores(const std::vector<int>& ids,
201  const bool singlify = true) const
202  {
203  hwloc_binding_helper(this->cores_, ids, singlify);
204  }
205 
211  void bind_to_core(const int& id) const
212  {
213  machine_topology::get_instance()->bind_to_cores(std::vector<int>{id});
214  }
215 
228  void bind_to_pus(const std::vector<int>& ids,
229  const bool singlify = true) const
230  {
231  hwloc_binding_helper(this->pus_, ids, singlify);
232  }
233 
239  void bind_to_pu(const int& id) const
240  {
241  machine_topology::get_instance()->bind_to_pus(std::vector<int>{id});
242  }
243 
250  const normal_obj_info* get_pu(size_type id) const
251  {
252  GKO_ENSURE_IN_BOUNDS(id, this->pus_.size());
253  return &this->pus_[id];
254  }
255 
262  const normal_obj_info* get_core(size_type id) const
263  {
264  GKO_ENSURE_IN_BOUNDS(id, this->cores_.size());
265  return &this->cores_[id];
266  }
267 
274  const io_obj_info* get_pci_device(size_type id) const
275  {
276  GKO_ENSURE_IN_BOUNDS(id, this->pci_devices_.size());
277  return &this->pci_devices_[id];
278  }
279 
286  const io_obj_info* get_pci_device(const std::string& pci_bus_id) const;
287 
293  size_type get_num_pus() const { return this->pus_.size(); }
294 
300  size_type get_num_cores() const { return this->cores_.size(); }
301 
307  size_type get_num_pci_devices() const { return this->pci_devices_.size(); }
308 
314  size_type get_num_numas() const { return this->num_numas_; }
315 
322  void hwloc_binding_helper(
323  const std::vector<machine_topology::normal_obj_info>& obj,
324  const std::vector<int>& ids, const bool singlify = true) const;
325 
334  void load_objects(hwloc_obj_type_t type,
335  std::vector<normal_obj_info>& objects) const;
336 
345  void load_objects(hwloc_obj_type_t type,
346  std::vector<io_obj_info>& vector) const;
347 
354  int get_obj_id_by_os_index(const std::vector<normal_obj_info>& objects,
355  size_type os_index) const;
356 
363  int get_obj_id_by_gp_index(const std::vector<normal_obj_info>& objects,
364  size_type gp_index) const;
365 
366 private:
374  machine_topology& operator=(machine_topology&) = delete;
375  machine_topology& operator=(machine_topology&&) = delete;
376  ~machine_topology() = default;
377 
378  std::vector<normal_obj_info> pus_;
379  std::vector<normal_obj_info> cores_;
380  std::vector<normal_obj_info> packages_;
381  std::vector<normal_obj_info> numa_nodes_;
382  std::vector<io_obj_info> pci_devices_;
383  size_type num_numas_;
384 
385  hwloc_manager<hwloc_topology> topo_;
386 };
387 
388 
389 using MachineTopology GKO_DEPRECATED("please use machine_topology") =
390  machine_topology;
391 
392 
393 } // namespace gko
394 
395 
396 #endif // GKO_PUBLIC_CORE_BASE_MACHINE_TOPOLOGY_HPP_
gko::machine_topology::get_pu
const normal_obj_info * get_pu(size_type id) const
Get the object of type PU associated with the id.
Definition: machine_topology.hpp:250
gko::machine_topology::bind_to_core
void bind_to_core(const int &id) const
Bind to a single core.
Definition: machine_topology.hpp:211
hwloc_obj_t
Definition: machine_topology.hpp:31
gko::machine_topology::get_num_numas
size_type get_num_numas() const
Get the number of NUMA objects stored in this Topology tree.
Definition: machine_topology.hpp:314
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:86
gko::machine_topology::get_pci_device
const io_obj_info * get_pci_device(size_type id) const
Get the object of type pci device associated with the id.
Definition: machine_topology.hpp:274
gko::machine_topology::get_num_pci_devices
size_type get_num_pci_devices() const
Get the number of PCI device objects stored in this Topology tree.
Definition: machine_topology.hpp:307
gko::machine_topology::bind_to_pu
void bind_to_pu(const int &id) const
Bind to a Processing unit (PU)
Definition: machine_topology.hpp:239
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
hwloc_obj_type_t
Definition: machine_topology.hpp:30
gko::machine_topology::get_num_cores
size_type get_num_cores() const
Get the number of core objects stored in this Topology tree.
Definition: machine_topology.hpp:300
gko::machine_topology::bind_to_cores
void bind_to_cores(const std::vector< int > &ids, const bool singlify=true) const
Bind the calling process to the CPU cores associated with the ids.
Definition: machine_topology.hpp:200
gko::machine_topology
The machine topology class represents the hierarchical topology of a machine, including NUMA nodes,...
Definition: machine_topology.hpp:61
gko::machine_topology::bind_to_pus
void bind_to_pus(const std::vector< int > &ids, const bool singlify=true) const
Bind the calling process to PUs associated with the ids.
Definition: machine_topology.hpp:228
gko::machine_topology::get_instance
static machine_topology * get_instance()
Returns an instance of the machine_topology object.
Definition: machine_topology.hpp:182
gko::machine_topology::get_core
const normal_obj_info * get_core(size_type id) const
Get the object of type core associated with the id.
Definition: machine_topology.hpp:262
gko::machine_topology::get_num_pus
size_type get_num_pus() const
Get the number of PU objects stored in this Topology tree.
Definition: machine_topology.hpp:293