Hardware Locality (hwloc)
v2.0-20191027.0400.gite37e7d8
|
00001 /* 00002 * Copyright © 2012-2018 Inria. All rights reserved. 00003 * Copyright © 2013, 2018 Université Bordeaux. All right reserved. 00004 * See COPYING in top-level directory. 00005 */ 00006 00014 #ifndef HWLOC_OPENCL_H 00015 #define HWLOC_OPENCL_H 00016 00017 #include <hwloc.h> 00018 #include <hwloc/autogen/config.h> 00019 #include <hwloc/helper.h> 00020 #ifdef HWLOC_LINUX_SYS 00021 #include <hwloc/linux.h> 00022 #endif 00023 00024 #ifdef __APPLE__ 00025 #include <OpenCL/cl.h> 00026 #include <OpenCL/cl_ext.h> 00027 #else 00028 #include <CL/cl.h> 00029 #include <CL/cl_ext.h> 00030 #endif 00031 00032 #include <stdio.h> 00033 00034 00035 #ifdef __cplusplus 00036 extern "C" { 00037 #endif 00038 00039 00068 static __hwloc_inline int 00069 hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, 00070 cl_device_id device __hwloc_attribute_unused, 00071 hwloc_cpuset_t set) 00072 { 00073 #if (defined HWLOC_LINUX_SYS) && (defined CL_DEVICE_TOPOLOGY_AMD) 00074 /* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */ 00075 #define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128 00076 char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX]; 00077 cl_device_topology_amd amdtopo; 00078 cl_int clret; 00079 00080 if (!hwloc_topology_is_thissystem(topology)) { 00081 errno = EINVAL; 00082 return -1; 00083 } 00084 00085 clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL); 00086 if (CL_SUCCESS != clret) { 00087 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00088 return 0; 00089 } 00090 if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) { 00091 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00092 return 0; 00093 } 00094 00095 sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus", 00096 (unsigned) amdtopo.pcie.bus, (unsigned) amdtopo.pcie.device, (unsigned) amdtopo.pcie.function); 00097 if (hwloc_linux_read_path_as_cpumask(path, set) < 0 00098 || hwloc_bitmap_iszero(set)) 00099 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00100 #else 00101 /* Non-Linux + AMD OpenCL systems simply get a full cpuset */ 00102 hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); 00103 #endif 00104 return 0; 00105 } 00106 00122 static __hwloc_inline hwloc_obj_t 00123 hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology, 00124 unsigned platform_index, unsigned device_index) 00125 { 00126 unsigned x = (unsigned) -1, y = (unsigned) -1; 00127 hwloc_obj_t osdev = NULL; 00128 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 00129 if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type 00130 && osdev->name 00131 && sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2 00132 && platform_index == x && device_index == y) 00133 return osdev; 00134 } 00135 return NULL; 00136 } 00137 00158 static __hwloc_inline hwloc_obj_t 00159 hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused, 00160 cl_device_id device __hwloc_attribute_unused) 00161 { 00162 #ifdef CL_DEVICE_TOPOLOGY_AMD 00163 hwloc_obj_t osdev; 00164 cl_device_topology_amd amdtopo; 00165 cl_int clret; 00166 00167 clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL); 00168 if (CL_SUCCESS != clret) { 00169 errno = EINVAL; 00170 return NULL; 00171 } 00172 if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) { 00173 errno = EINVAL; 00174 return NULL; 00175 } 00176 00177 osdev = NULL; 00178 while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { 00179 hwloc_obj_t pcidev = osdev->parent; 00180 if (strncmp(osdev->name, "opencl", 6)) 00181 continue; 00182 if (pcidev 00183 && pcidev->type == HWLOC_OBJ_PCI_DEVICE 00184 && pcidev->attr->pcidev.domain == 0 00185 && pcidev->attr->pcidev.bus == amdtopo.pcie.bus 00186 && pcidev->attr->pcidev.dev == amdtopo.pcie.device 00187 && pcidev->attr->pcidev.func == amdtopo.pcie.function) 00188 return osdev; 00189 /* if PCI are filtered out, we need a info attr to match on */ 00190 } 00191 00192 return NULL; 00193 #else 00194 return NULL; 00195 #endif 00196 } 00197 00201 #ifdef __cplusplus 00202 } /* extern "C" */ 00203 #endif 00204 00205 00206 #endif /* HWLOC_OPENCL_H */