openfabrics-verbs.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright © 2009 CNRS
  3. * Copyright © 2009-2023 Inria. All rights reserved.
  4. * Copyright © 2009-2010 Université Bordeaux
  5. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
  6. * See COPYING in top-level directory.
  7. */
  8. /** \file
  9. * \brief Macros to help interaction between hwloc and OpenFabrics
  10. * verbs.
  11. *
  12. * Applications that use both hwloc and OpenFabrics verbs may want to
  13. * include this file so as to get topology information for OpenFabrics
  14. * hardware (InfiniBand, etc).
  15. *
  16. */
  17. #ifndef HWLOC_OPENFABRICS_VERBS_H
  18. #define HWLOC_OPENFABRICS_VERBS_H
  19. #include "hwloc.h"
  20. #include "hwloc/autogen/config.h"
  21. #ifdef HWLOC_LINUX_SYS
  22. #include "hwloc/linux.h"
  23. #endif
  24. #include <infiniband/verbs.h>
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28. /** \defgroup hwlocality_openfabrics Interoperability with OpenFabrics
  29. *
  30. * This interface offers ways to retrieve topology information about
  31. * OpenFabrics devices (InfiniBand, Omni-Path, usNIC, etc).
  32. *
  33. * @{
  34. */
  35. /** \brief Get the CPU set of processors that are physically
  36. * close to device \p ibdev.
  37. *
  38. * Store in \p set the CPU-set describing the locality of the OpenFabrics
  39. * device \p ibdev (InfiniBand, etc).
  40. *
  41. * Topology \p topology and device \p ibdev must match the local machine.
  42. * I/O devices detection is not needed in the topology.
  43. *
  44. * The function only returns the locality of the device.
  45. * If more information about the device is needed, OS objects should
  46. * be used instead, see hwloc_ibv_get_device_osdev()
  47. * and hwloc_ibv_get_device_osdev_by_name().
  48. *
  49. * This function is currently only implemented in a meaningful way for
  50. * Linux; other systems will simply get a full cpuset.
  51. *
  52. * \return 0 on success.
  53. * \return -1 on error, for instance if device information could not be found.
  54. */
  55. static __hwloc_inline int
  56. hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
  57. struct ibv_device *ibdev, hwloc_cpuset_t set)
  58. {
  59. #ifdef HWLOC_LINUX_SYS
  60. /* If we're on Linux, use the verbs-provided sysfs mechanism to
  61. get the local cpus */
  62. #define HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX 128
  63. char path[HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX];
  64. if (!hwloc_topology_is_thissystem(topology)) {
  65. errno = EINVAL;
  66. return -1;
  67. }
  68. sprintf(path, "/sys/class/infiniband/%s/device/local_cpus",
  69. ibv_get_device_name(ibdev));
  70. if (hwloc_linux_read_path_as_cpumask(path, set) < 0
  71. || hwloc_bitmap_iszero(set))
  72. hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
  73. #else
  74. /* Non-Linux systems simply get a full cpuset */
  75. hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
  76. #endif
  77. return 0;
  78. }
  79. /** \brief Get the hwloc OS device object corresponding to the OpenFabrics
  80. * device named \p ibname.
  81. *
  82. * \return The hwloc OS device object describing the OpenFabrics device
  83. * (InfiniBand, Omni-Path, usNIC, etc) whose name is \p ibname
  84. * (mlx5_0, hfi1_0, usnic_0, qib0, etc).
  85. * \return \c NULL if none could be found.
  86. *
  87. * The name \p ibname is usually obtained from ibv_get_device_name().
  88. *
  89. * The topology \p topology does not necessarily have to match the current
  90. * machine. For instance the topology may be an XML import of a remote host.
  91. * I/O devices detection must be enabled in the topology.
  92. *
  93. * \note The corresponding PCI device object can be obtained by looking
  94. * at the OS device parent object.
  95. */
  96. static __hwloc_inline hwloc_obj_t
  97. hwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology,
  98. const char *ibname)
  99. {
  100. hwloc_obj_t osdev = NULL;
  101. while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
  102. if (HWLOC_OBJ_OSDEV_OPENFABRICS == osdev->attr->osdev.type
  103. && osdev->name && !strcmp(ibname, osdev->name))
  104. return osdev;
  105. }
  106. return NULL;
  107. }
  108. /** \brief Get the hwloc OS device object corresponding to the OpenFabrics
  109. * device \p ibdev.
  110. *
  111. * \return The hwloc OS device object describing the OpenFabrics
  112. * device \p ibdev (InfiniBand, etc).
  113. * \return \c NULL if none could be found.
  114. *
  115. * Topology \p topology and device \p ibdev must match the local machine.
  116. * I/O devices detection must be enabled in the topology.
  117. * If not, the locality of the object may still be found using
  118. * hwloc_ibv_get_device_cpuset().
  119. *
  120. * \note The corresponding PCI device object can be obtained by looking
  121. * at the OS device parent object.
  122. */
  123. static __hwloc_inline hwloc_obj_t
  124. hwloc_ibv_get_device_osdev(hwloc_topology_t topology,
  125. struct ibv_device *ibdev)
  126. {
  127. if (!hwloc_topology_is_thissystem(topology)) {
  128. errno = EINVAL;
  129. return NULL;
  130. }
  131. return hwloc_ibv_get_device_osdev_by_name(topology, ibv_get_device_name(ibdev));
  132. }
  133. /** @} */
  134. #ifdef __cplusplus
  135. } /* extern "C" */
  136. #endif
  137. #endif /* HWLOC_OPENFABRICS_VERBS_H */