root/opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-gl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hwloc_gl_discover
  2. hwloc_gl_component_instantiate
  3. hwloc_gl_component_init

   1 /*
   2  * Copyright © 2012-2013 Blue Brain Project, BBP/EPFL. All rights reserved.
   3  * Copyright © 2012-2017 Inria.  All rights reserved.
   4  * See COPYING in top-level directory.
   5  */
   6 
   7 #include <private/autogen/config.h>
   8 #include <hwloc.h>
   9 #include <hwloc/plugins.h>
  10 
  11 /* private headers allowed for convenience because this plugin is built within hwloc */
  12 #include <private/misc.h>
  13 #include <private/debug.h>
  14 
  15 #include <stdarg.h>
  16 #include <errno.h>
  17 #include <X11/Xlib.h>
  18 #include <NVCtrl/NVCtrl.h>
  19 #include <NVCtrl/NVCtrlLib.h>
  20 
  21 #define HWLOC_GL_SERVER_MAX 10
  22 #define HWLOC_GL_SCREEN_MAX 10
  23 
  24 static int
  25 hwloc_gl_discover(struct hwloc_backend *backend)
  26 {
  27   struct hwloc_topology *topology = backend->topology;
  28   enum hwloc_type_filter_e filter;
  29   unsigned i;
  30   int err;
  31 
  32   hwloc_topology_get_type_filter(topology, HWLOC_OBJ_OS_DEVICE, &filter);
  33   if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
  34     return 0;
  35 
  36   for (i = 0; i < HWLOC_GL_SERVER_MAX; ++i) {
  37     Display* display;
  38     char displayName[10];
  39     int opcode, event, error;
  40     unsigned j;
  41 
  42     /* open X server */
  43     snprintf(displayName, sizeof(displayName), ":%u", i);
  44     display = XOpenDisplay(displayName);
  45     if (!display)
  46       continue;
  47 
  48     /* Check for NV-CONTROL extension (it's per server) */
  49     if(!XQueryExtension(display, "NV-CONTROL", &opcode, &event, &error)) {
  50       XCloseDisplay(display);
  51       continue;
  52     }
  53 
  54     for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) {
  55       hwloc_obj_t osdev, parent;
  56       const int screen = (int)j;
  57       unsigned int *ptr_binary_data;
  58       int data_length;
  59       int gpu_number;
  60       int nv_ctrl_pci_bus;
  61       int nv_ctrl_pci_device;
  62       int nv_ctrl_pci_domain;
  63       int nv_ctrl_pci_func;
  64       char *productname;
  65       char name[64];
  66 
  67       /* the server supports NV-CONTROL but it may contain non-NVIDIA screen that don't support it */
  68       if (!XNVCTRLIsNvScreen(display, screen))
  69         continue;
  70 
  71       /* Gets the GPU number attached to the default screen. */
  72       /* For further details, see the <NVCtrl/NVCtrlLib.h> */
  73       err = XNVCTRLQueryTargetBinaryData (display, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 0,
  74                                           NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN,
  75                                           (unsigned char **) &ptr_binary_data, &data_length);
  76       if (!err)
  77         continue;
  78 
  79       gpu_number = (int)ptr_binary_data[1];
  80       free(ptr_binary_data);
  81 
  82 #ifdef NV_CTRL_PCI_DOMAIN
  83       /* Gets the ID's of the GPU defined by gpu_number
  84        * For further details, see the <NVCtrl/NVCtrlLib.h> */
  85       err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
  86                                         NV_CTRL_PCI_DOMAIN, &nv_ctrl_pci_domain);
  87       if (!err)
  88         continue;
  89 #else
  90       nv_ctrl_pci_domain = 0;
  91 #endif
  92 
  93       err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
  94                                         NV_CTRL_PCI_BUS, &nv_ctrl_pci_bus);
  95       if (!err)
  96         continue;
  97 
  98       err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
  99                                         NV_CTRL_PCI_DEVICE, &nv_ctrl_pci_device);
 100       if (!err)
 101         continue;
 102 
 103       err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
 104                                         NV_CTRL_PCI_FUNCTION, &nv_ctrl_pci_func);
 105       if (!err)
 106         continue;
 107 
 108       productname = NULL;
 109       err = XNVCTRLQueryTargetStringAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
 110                                               NV_CTRL_STRING_PRODUCT_NAME, &productname);
 111 
 112       snprintf(name, sizeof(name), ":%u.%u", i, j);
 113 
 114       osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, HWLOC_UNKNOWN_INDEX);
 115       osdev->name = strdup(name);
 116       osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
 117       hwloc_obj_add_info(osdev, "Backend", "GL");
 118       hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation");
 119       if (productname)
 120         hwloc_obj_add_info(osdev, "GPUModel", productname);
 121 
 122       parent = hwloc_pcidisc_find_by_busid(topology, (unsigned)nv_ctrl_pci_domain, (unsigned)nv_ctrl_pci_bus, (unsigned)nv_ctrl_pci_device, (unsigned)nv_ctrl_pci_func);
 123       if (!parent)
 124         parent = hwloc_pcidisc_find_busid_parent(topology, (unsigned)nv_ctrl_pci_domain, (unsigned)nv_ctrl_pci_bus, (unsigned)nv_ctrl_pci_device, (unsigned)nv_ctrl_pci_func);
 125       if (!parent)
 126         parent = hwloc_get_root_obj(topology);
 127 
 128       hwloc_insert_object_by_parent(topology, parent, osdev);
 129 
 130       hwloc_debug("GL device %s (product %s) on PCI %04x:%02x:%02x.%01x\n",
 131                   name, productname,
 132                   (unsigned) nv_ctrl_pci_domain, (unsigned) nv_ctrl_pci_bus, (unsigned) nv_ctrl_pci_device, (unsigned) nv_ctrl_pci_func);
 133     }
 134     XCloseDisplay(display);
 135   }
 136 
 137   return 0;
 138 }
 139 
 140 static struct hwloc_backend *
 141 hwloc_gl_component_instantiate(struct hwloc_disc_component *component,
 142                                const void *_data1 __hwloc_attribute_unused,
 143                                const void *_data2 __hwloc_attribute_unused,
 144                                const void *_data3 __hwloc_attribute_unused)
 145 {
 146   struct hwloc_backend *backend;
 147 
 148   backend = hwloc_backend_alloc(component);
 149   if (!backend)
 150     return NULL;
 151   backend->discover = hwloc_gl_discover;
 152   return backend;
 153 }
 154 
 155 static struct hwloc_disc_component hwloc_gl_disc_component = {
 156   HWLOC_DISC_COMPONENT_TYPE_MISC,
 157   "gl",
 158   HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
 159   hwloc_gl_component_instantiate,
 160   10, /* after pci */
 161   1,
 162   NULL
 163 };
 164 
 165 static int
 166 hwloc_gl_component_init(unsigned long flags)
 167 {
 168   if (flags)
 169     return -1;
 170   if (hwloc_plugin_check_namespace("gl", "hwloc_backend_alloc") < 0)
 171     return -1;
 172   return 0;
 173 }
 174 
 175 #ifdef HWLOC_INSIDE_PLUGIN
 176 HWLOC_DECLSPEC extern const struct hwloc_component hwloc_gl_component;
 177 #endif
 178 
 179 const struct hwloc_component hwloc_gl_component = {
 180   HWLOC_COMPONENT_ABI,
 181   hwloc_gl_component_init, NULL,
 182   HWLOC_COMPONENT_TYPE_DISC,
 183   0,
 184   &hwloc_gl_disc_component
 185 };

/* [<][>][^][v][top][bottom][index][help] */