Ginkgo  Generated from pipelines/1330831941 branch based on master. Ginkgo version 1.8.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 
20 #include <ginkgo/config.hpp>
21 #include <ginkgo/core/base/exception.hpp>
22 #include <ginkgo/core/base/exception_helpers.hpp>
23 
24 
25 #if GKO_HAVE_HWLOC
26 
27 #include <hwloc.h>
28 
29 #else
30 
31 struct hwloc_obj_type_t {};
32 struct hwloc_obj_t {};
33 
34 #endif
35 
36 
37 struct hwloc_topology;
38 struct hwloc_bitmap_s;
39 
40 
41 namespace gko {
42 
43 
63  template <typename T>
64  using hwloc_manager = std::unique_ptr<T, std::function<void(T*)>>;
65 
69  struct normal_obj_info {
73  hwloc_obj_t obj;
74 
82  size_type logical_id;
83 
87  size_type os_id;
88 
92  size_type gp_id;
93 
97  int numa;
98 
102  size_type memory_size;
103  };
104 
105 
122  struct io_obj_info {
126  hwloc_obj_t obj;
127 
134  size_type logical_id;
135 
139  size_type os_id;
140 
144  size_type gp_id;
145 
149  int closest_numa;
150 
154  hwloc_obj_t non_io_ancestor;
155 
159  int ancestor_local_id;
160 
164  std::string ancestor_type;
165 
169  std::vector<int> closest_pu_ids;
170 
174  std::string pci_bus_id;
175  };
176 
177 public:
184  {
185  static machine_topology instance;
186  return &instance;
187  }
188 
201  void bind_to_cores(const std::vector<int>& ids,
202  const bool singlify = true) const
203  {
204  hwloc_binding_helper(this->cores_, ids, singlify);
205  }
206 
212  void bind_to_core(const int& id) const
213  {
214  machine_topology::get_instance()->bind_to_cores(std::vector<int>{id});
215  }
216 
229  void bind_to_pus(const std::vector<int>& ids,
230  const bool singlify = true) const
231  {
232  hwloc_binding_helper(this->pus_, ids, singlify);
233  }
234 
240  void bind_to_pu(const int& id) const
241  {
242  machine_topology::get_instance()->bind_to_pus(std::vector<int>{id});
243  }
244 
251  const normal_obj_info* get_pu(size_type id) const
252  {
253  GKO_ENSURE_IN_BOUNDS(id, this->pus_.size());
254  return &this->pus_[id];
255  }
256 
263  const normal_obj_info* get_core(size_type id) const
264  {
265  GKO_ENSURE_IN_BOUNDS(id, this->cores_.size());
266  return &this->cores_[id];
267  }
268 
275  const io_obj_info* get_pci_device(size_type id) const
276  {
277  GKO_ENSURE_IN_BOUNDS(id, this->pci_devices_.size());
278  return &this->pci_devices_[id];
279  }
280 
287  const io_obj_info* get_pci_device(const std::string& pci_bus_id) const;
288 
294  size_type get_num_pus() const { return this->pus_.size(); }
295 
301  size_type get_num_cores() const { return this->cores_.size(); }
302 
308  size_type get_num_pci_devices() const { return this->pci_devices_.size(); }
309 
315  size_type get_num_numas() const { return this->num_numas_; }
316 
323  void hwloc_binding_helper(
324  const std::vector<machine_topology::normal_obj_info>& obj,
325  const std::vector<int>& ids, const bool singlify = true) const;
326 
335  void load_objects(hwloc_obj_type_t type,
336  std::vector<normal_obj_info>& objects) const;
337 
346  void load_objects(hwloc_obj_type_t type,
347  std::vector<io_obj_info>& vector) const;
348 
355  int get_obj_id_by_os_index(const std::vector<normal_obj_info>& objects,
356  size_type os_index) const;
357 
364  int get_obj_id_by_gp_index(const std::vector<normal_obj_info>& objects,
365  size_type gp_index) const;
366 
367 private:
375  machine_topology& operator=(machine_topology&) = delete;
376  machine_topology& operator=(machine_topology&&) = delete;
377  ~machine_topology() = default;
378 
379  std::vector<normal_obj_info> pus_;
380  std::vector<normal_obj_info> cores_;
381  std::vector<normal_obj_info> packages_;
382  std::vector<normal_obj_info> numa_nodes_;
383  std::vector<io_obj_info> pci_devices_;
384  size_type num_numas_;
385 
386  hwloc_manager<hwloc_topology> topo_;
387 };
388 
389 
390 using MachineTopology GKO_DEPRECATED("please use machine_topology") =
391  machine_topology;
392 
393 
394 } // namespace gko
395 
396 
397 #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:251
gko::machine_topology::bind_to_core
void bind_to_core(const int &id) const
Bind to a single core.
Definition: machine_topology.hpp:212
hwloc_obj_t
Definition: machine_topology.hpp:32
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:315
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:108
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:275
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:308
gko::machine_topology::bind_to_pu
void bind_to_pu(const int &id) const
Bind to a Processing unit (PU)
Definition: machine_topology.hpp:240
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
hwloc_obj_type_t
Definition: machine_topology.hpp:31
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:301
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:201
gko::machine_topology
The machine topology class represents the hierarchical topology of a machine, including NUMA nodes,...
Definition: machine_topology.hpp:62
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:229
gko::machine_topology::get_instance
static machine_topology * get_instance()
Returns an instance of the machine_topology object.
Definition: machine_topology.hpp:183
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:263
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:294