00001
00002
00003
00004
00005
00006
00007
00016 #ifndef HWLOC_CUDART_H
00017 #define HWLOC_CUDART_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 #include <cuda_runtime_api.h>
00028
00029
00030 #ifdef __cplusplus
00031 extern "C" {
00032 #endif
00033
00034
00047 static __hwloc_inline int
00048 hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
00049 int idx, int *domain, int *bus, int *dev)
00050 {
00051 cudaError_t cerr;
00052 struct cudaDeviceProp prop;
00053
00054 cerr = cudaGetDeviceProperties(&prop, idx);
00055 if (cerr) {
00056 errno = ENOSYS;
00057 return -1;
00058 }
00059
00060 #if CUDA_VERSION >= 4000
00061 *domain = prop.pciDomainID;
00062 #else
00063 *domain = 0;
00064 #endif
00065
00066 *bus = prop.pciBusID;
00067 *dev = prop.pciDeviceID;
00068
00069 return 0;
00070 }
00071
00088 static __hwloc_inline int
00089 hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
00090 int idx, hwloc_cpuset_t set)
00091 {
00092 #ifdef HWLOC_LINUX_SYS
00093
00094 #define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128
00095 char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX];
00096 FILE *sysfile = NULL;
00097 int domain, bus, dev;
00098
00099 if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
00100 return -1;
00101
00102 if (!hwloc_topology_is_thissystem(topology)) {
00103 errno = EINVAL;
00104 return -1;
00105 }
00106
00107 sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", (unsigned) domain, (unsigned) bus, (unsigned) dev);
00108 sysfile = fopen(path, "r");
00109 if (!sysfile)
00110 return -1;
00111
00112 if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0
00113 || hwloc_bitmap_iszero(set))
00114 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
00115
00116 fclose(sysfile);
00117 #else
00118
00119 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
00120 #endif
00121 return 0;
00122 }
00123
00134 static __hwloc_inline hwloc_obj_t
00135 hwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx)
00136 {
00137 int domain, bus, dev;
00138
00139 if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
00140 return NULL;
00141
00142 return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
00143 }
00144
00162 static __hwloc_inline hwloc_obj_t
00163 hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
00164 {
00165 hwloc_obj_t osdev = NULL;
00166 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
00167 if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
00168 && osdev->name
00169 && !strncmp("cuda", osdev->name, 4)
00170 && atoi(osdev->name + 4) == (int) idx)
00171 return osdev;
00172 }
00173 return NULL;
00174 }
00175
00179 #ifdef __cplusplus
00180 }
00181 #endif
00182
00183
00184 #endif