00001
00002
00003
00004
00005
00006
00007
00016 #ifndef HWLOC_CUDA_H
00017 #define HWLOC_CUDA_H
00018
00019 #include <hwloc.h>
00020 #include <hwloc/autogen/config.h>
00021 #include <hwloc/helper.h>
00022 #ifdef HWLOC_LINUX_SYS
00023 #include <hwloc/linux.h>
00024 #endif
00025
00026 #include <cuda.h>
00027
00028
00029 #ifdef __cplusplus
00030 extern "C" {
00031 #endif
00032
00033
00046 static __hwloc_inline int
00047 hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
00048 CUdevice cudevice, int *domain, int *bus, int *dev)
00049 {
00050 CUresult cres;
00051
00052 #if CUDA_VERSION >= 4000
00053 cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);
00054 if (cres != CUDA_SUCCESS) {
00055 errno = ENOSYS;
00056 return -1;
00057 }
00058 #else
00059 *domain = 0;
00060 #endif
00061 cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice);
00062 if (cres != CUDA_SUCCESS) {
00063 errno = ENOSYS;
00064 return -1;
00065 }
00066 cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice);
00067 if (cres != CUDA_SUCCESS) {
00068 errno = ENOSYS;
00069 return -1;
00070 }
00071
00072 return 0;
00073 }
00074
00091 static __hwloc_inline int
00092 hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
00093 CUdevice cudevice, hwloc_cpuset_t set)
00094 {
00095 #ifdef HWLOC_LINUX_SYS
00096
00097 #define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128
00098 char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];
00099 FILE *sysfile = NULL;
00100 int domainid, busid, deviceid;
00101
00102 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))
00103 return -1;
00104
00105 if (!hwloc_topology_is_thissystem(topology)) {
00106 errno = EINVAL;
00107 return -1;
00108 }
00109
00110 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid);
00111 sysfile = fopen(path, "r");
00112 if (!sysfile)
00113 return -1;
00114
00115 hwloc_linux_parse_cpumap_file(sysfile, set);
00116 if (hwloc_bitmap_iszero(set))
00117 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
00118
00119 fclose(sysfile);
00120 #else
00121
00122 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
00123 #endif
00124 return 0;
00125 }
00126
00137 static __hwloc_inline hwloc_obj_t
00138 hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
00139 {
00140 int domain, bus, dev;
00141
00142 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
00143 return NULL;
00144
00145 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
00146 }
00147
00161 static __hwloc_inline hwloc_obj_t
00162 hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
00163 {
00164 hwloc_obj_t osdev = NULL;
00165 int domain, bus, dev;
00166
00167 if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
00168 return NULL;
00169
00170 osdev = NULL;
00171 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
00172 hwloc_obj_t pcidev = osdev->parent;
00173 if (strncmp(osdev->name, "cuda", 4))
00174 continue;
00175 if (pcidev
00176 && pcidev->type == HWLOC_OBJ_PCI_DEVICE
00177 && (int) pcidev->attr->pcidev.domain == domain
00178 && (int) pcidev->attr->pcidev.bus == bus
00179 && (int) pcidev->attr->pcidev.dev == dev
00180 && pcidev->attr->pcidev.func == 0)
00181 return osdev;
00182 }
00183
00184 return NULL;
00185 }
00186
00202 static __hwloc_inline hwloc_obj_t
00203 hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
00204 {
00205 hwloc_obj_t osdev = NULL;
00206 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
00207 if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
00208 && osdev->name
00209 && !strncmp("cuda", osdev->name, 4)
00210 && atoi(osdev->name + 4) == (int) idx)
00211 return osdev;
00212 }
00213 return NULL;
00214 }
00215
00219 #ifdef __cplusplus
00220 }
00221 #endif
00222
00223
00224 #endif