|
||||
File indexing completed on 2025-01-18 10:01:15
0001 /* 0002 * Copyright © 2010-2023 Inria. All rights reserved. 0003 * Copyright © 2010-2011 Université Bordeaux 0004 * Copyright © 2011 Cisco Systems, Inc. All rights reserved. 0005 * See COPYING in top-level directory. 0006 */ 0007 0008 /** \file 0009 * \brief Macros to help interaction between hwloc and the CUDA Runtime API. 0010 * 0011 * Applications that use both hwloc and the CUDA Runtime API may want to 0012 * include this file so as to get topology information for CUDA devices. 0013 * 0014 */ 0015 0016 #ifndef HWLOC_CUDART_H 0017 #define HWLOC_CUDART_H 0018 0019 #include "hwloc.h" 0020 #include "hwloc/autogen/config.h" 0021 #include "hwloc/helper.h" 0022 #ifdef HWLOC_LINUX_SYS 0023 #include "hwloc/linux.h" 0024 #endif 0025 0026 #include <cuda.h> /* for CUDA_VERSION */ 0027 #include <cuda_runtime_api.h> 0028 0029 0030 #ifdef __cplusplus 0031 extern "C" { 0032 #endif 0033 0034 0035 /** \defgroup hwlocality_cudart Interoperability with the CUDA Runtime API 0036 * 0037 * This interface offers ways to retrieve topology information about 0038 * CUDA devices when using the CUDA Runtime API. 0039 * 0040 * @{ 0041 */ 0042 0043 /** \brief Return the domain, bus and device IDs of the CUDA device whose index is \p idx. 0044 * 0045 * Device index \p idx must match the local machine. 0046 * 0047 * \return 0 on success. 0048 * \return -1 on error, for instance if device information could not be found. 0049 */ 0050 static __hwloc_inline int 0051 hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused, 0052 int idx, int *domain, int *bus, int *dev) 0053 { 0054 cudaError_t cerr; 0055 struct cudaDeviceProp prop; 0056 0057 cerr = cudaGetDeviceProperties(&prop, idx); 0058 if (cerr) { 0059 errno = ENOSYS; 0060 return -1; 0061 } 0062 0063 #if CUDA_VERSION >= 4000 0064 *domain = prop.pciDomainID; 0065 #else 0066 *domain = 0; 0067 #endif 0068 0069 *bus = prop.pciBusID; 0070 *dev = prop.pciDeviceID; 0071 0072 return 0; 0073 } 0074 0075 /** \brief Get the CPU set of processors that are physically 0076 * close to device \p idx. 0077 * 0078 * Store in \p set the CPU-set describing the locality of the CUDA device 0079 * whose index is \p idx. 0080 * 0081 * Topology \p topology and device \p idx must match the local machine. 0082 * I/O devices detection and the CUDA component are not needed in the topology. 0083 * 0084 * The function only returns the locality of the device. 0085 * If more information about the device is needed, OS objects should 0086 * be used instead, see hwloc_cudart_get_device_osdev_by_index(). 0087 * 0088 * This function is currently only implemented in a meaningful way for 0089 * Linux; other systems will simply get a full cpuset. 0090 * 0091 * \return 0 on success. 0092 * \return -1 on error, for instance if device information could not be found. 0093 */ 0094 static __hwloc_inline int 0095 hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, 0096 int idx, hwloc_cpuset_t set) 0097 { 0098 #ifdef HWLOC_LINUX_SYS 0099 /* If we're on Linux, use the sysfs mechanism to get the local cpus */ 0100 #define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128 0101 char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX]; 0102 int domain, bus, dev; 0103 0104 if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev)) 0105 return -1; 0106 0107 if (!hwloc_topology_is_thissystem(topology)) { 0108 errno = EINVAL; 0109 return -1; 0110 } 0111 0112 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", (unsigned) domain, (unsigned) bus, (unsigned) dev); 0113 if (hwloc_linux_read_path_as_cpumask(path, set) < 0 0114 || hwloc_bitmap_iszero(set)) 0115 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 0116 #else 0117 /* Non-Linux systems simply get a full cpuset */ 0118 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 0119 #endif 0120 return 0; 0121 } 0122 0123 /** \brief Get the hwloc PCI device object corresponding to the 0124 * CUDA device whose index is \p idx. 0125 * 0126 * \return The hwloc PCI device object describing the CUDA device whose index is \p idx. 0127 * \return \c NULL if none could be found. 0128 * 0129 * Topology \p topology and device \p idx must match the local machine. 0130 * I/O devices detection must be enabled in topology \p topology. 0131 * The CUDA component is not needed in the topology. 0132 */ 0133 static __hwloc_inline hwloc_obj_t 0134 hwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx) 0135 { 0136 int domain, bus, dev; 0137 0138 if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev)) 0139 return NULL; 0140 0141 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0); 0142 } 0143 0144 /** \brief Get the hwloc OS device object corresponding to the 0145 * CUDA device whose index is \p idx. 0146 * 0147 * \return The hwloc OS device object describing the CUDA device whose index is \p idx. 0148 * \return \c NULL if none could be found. 0149 * 0150 * The topology \p topology does not necessarily have to match the current 0151 * machine. For instance the topology may be an XML import of a remote host. 0152 * I/O devices detection and the CUDA component must be enabled in the topology. 0153 * If not, the locality of the object may still be found using 0154 * hwloc_cudart_get_device_cpuset(). 0155 * 0156 * \note The corresponding PCI device object can be obtained by looking 0157 * at the OS device parent object (unless PCI devices are filtered out). 0158 * 0159 * \note This function is identical to hwloc_cuda_get_device_osdev_by_index(). 0160 */ 0161 static __hwloc_inline hwloc_obj_t 0162 hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx) 0163 { 0164 hwloc_obj_t osdev = NULL; 0165 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 0166 if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type 0167 && osdev->name 0168 && !strncmp("cuda", osdev->name, 4) 0169 && atoi(osdev->name + 4) == (int) idx) 0170 return osdev; 0171 } 0172 return NULL; 0173 } 0174 0175 /** @} */ 0176 0177 0178 #ifdef __cplusplus 0179 } /* extern "C" */ 0180 #endif 0181 0182 0183 #endif /* HWLOC_CUDART_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |