Hardware Locality (hwloc)
v2.2-20200401.0300.gitd2f52ab
|
00001 /* 00002 * Copyright © 2012-2016 Inria. All rights reserved. 00003 * See COPYING in top-level directory. 00004 */ 00005 00013 #ifndef HWLOC_NVML_H 00014 #define HWLOC_NVML_H 00015 00016 #include "hwloc.h" 00017 #include "hwloc/autogen/config.h" 00018 #include "hwloc/helper.h" 00019 #ifdef HWLOC_LINUX_SYS 00020 #include "hwloc/linux.h" 00021 #endif 00022 00023 #include <nvml.h> 00024 00025 00026 #ifdef __cplusplus 00027 extern "C" { 00028 #endif 00029 00030 00055 static __hwloc_inline int 00056 hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, 00057 nvmlDevice_t device, hwloc_cpuset_t set) 00058 { 00059 #ifdef HWLOC_LINUX_SYS 00060 /* If we're on Linux, use the sysfs mechanism to get the local cpus */ 00061 #define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128 00062 char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX]; 00063 nvmlReturn_t nvres; 00064 nvmlPciInfo_t pci; 00065 00066 if (!hwloc_topology_is_thissystem(topology)) { 00067 errno = EINVAL; 00068 return -1; 00069 } 00070 00071 nvres = nvmlDeviceGetPciInfo(device, &pci); 00072 if (NVML_SUCCESS != nvres) { 00073 errno = EINVAL; 00074 return -1; 00075 } 00076 00077 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device); 00078 if (hwloc_linux_read_path_as_cpumask(path, set) < 0 00079 || hwloc_bitmap_iszero(set)) 00080 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00081 #else 00082 /* Non-Linux systems simply get a full cpuset */ 00083 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00084 #endif 00085 return 0; 00086 } 00087 00101 static __hwloc_inline hwloc_obj_t 00102 hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx) 00103 { 00104 hwloc_obj_t osdev = NULL; 00105 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 00106 if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type 00107 && osdev->name 00108 && !strncmp("nvml", osdev->name, 4) 00109 && atoi(osdev->name + 4) == (int) idx) 00110 return osdev; 00111 } 00112 return NULL; 00113 } 00114 00128 static __hwloc_inline hwloc_obj_t 00129 hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device) 00130 { 00131 hwloc_obj_t osdev; 00132 nvmlReturn_t nvres; 00133 nvmlPciInfo_t pci; 00134 char uuid[64]; 00135 00136 if (!hwloc_topology_is_thissystem(topology)) { 00137 errno = EINVAL; 00138 return NULL; 00139 } 00140 00141 nvres = nvmlDeviceGetPciInfo(device, &pci); 00142 if (NVML_SUCCESS != nvres) 00143 return NULL; 00144 00145 nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid)); 00146 if (NVML_SUCCESS != nvres) 00147 uuid[0] = '\0'; 00148 00149 osdev = NULL; 00150 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 00151 hwloc_obj_t pcidev = osdev->parent; 00152 const char *info; 00153 00154 if (strncmp(osdev->name, "nvml", 4)) 00155 continue; 00156 00157 if (pcidev 00158 && pcidev->type == HWLOC_OBJ_PCI_DEVICE 00159 && pcidev->attr->pcidev.domain == pci.domain 00160 && pcidev->attr->pcidev.bus == pci.bus 00161 && pcidev->attr->pcidev.dev == pci.device 00162 && pcidev->attr->pcidev.func == 0) 00163 return osdev; 00164 00165 info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID"); 00166 if (info && !strcmp(info, uuid)) 00167 return osdev; 00168 } 00169 00170 return NULL; 00171 } 00172 00176 #ifdef __cplusplus 00177 } /* extern "C" */ 00178 #endif 00179 00180 00181 #endif /* HWLOC_NVML_H */