static void init_device_info(struct monitor* mon) { gethostname(mon->hostname, 64); NVML_TRY(nvmlSystemGetDriverVersion(mon->driver_version, sizeof(mon->driver_version))); NVML_TRY(nvmlSystemGetNVMLVersion(mon->nvml_version, sizeof(mon->nvml_version))); NVML_TRY(nvmlDeviceGetCount(&mon->dev_count)); mon->devices = calloc(mon->dev_count, sizeof(struct device)); for(unsigned i = 0; i < mon->dev_count; ++i) { struct device dev; memset(&dev, 0, sizeof(struct device)); dev.index = i; NVML_TRY(nvmlDeviceGetHandleByIndex(i, &dev.handle)); NVML_TRY(nvmlDeviceGetName(dev.handle, dev.name, sizeof(dev.name))); NVML_TRY(nvmlDeviceGetSerial(dev.handle, dev.serial, sizeof(dev.serial))); NVML_TRY(nvmlDeviceGetUUID(dev.handle, dev.uuid, sizeof(dev.uuid))); NVML_TRY(nvmlDeviceGetPciInfo(dev.handle, &dev.pci)); NVML_TRY(nvmlDeviceGetMemoryInfo(dev.handle, &dev.memory)); unsigned long long event_types; NVML_TRY(nvmlEventSetCreate(&dev.event_set)); if(0 == NVML_TRY(nvmlDeviceGetSupportedEventTypes(dev.handle, &event_types))) { NVML_TRY(nvmlDeviceRegisterEvents(dev.handle, event_types, dev.event_set)); } else { dev.event_set = NULL; } for(nvmlClockType_t type = NVML_CLOCK_GRAPHICS; type < NVML_CLOCK_COUNT; ++type) { if(NVML_TRY(nvmlDeviceGetMaxClockInfo(dev.handle, type, &dev.max_clock[type]))) break; } get_device_features(&dev); mon->devices[i] = dev; } mon->last_update = time(NULL); }
void get_serial_number(unsigned int devIdx, char* serial) { #if (ENABLE_NVML==1) try { nvmlDevice_t devHandle; NVML_CHECK(nvmlDeviceGetHandleByIndex( devIdx, &devHandle )); unsigned int serialLength = NVML_DEVICE_SERIAL_BUFFER_SIZE; NVML_CHECK(nvmlDeviceGetSerial( devHandle, serial, serialLength )); } catch(const std::runtime_error& e) { std::strncpy( serial, "unknown (NVML runtime error)", NVML_DEVICE_SERIAL_BUFFER_SIZE); serial[NVML_DEVICE_SERIAL_BUFFER_SIZE-1] = '\0'; } #else (void)(devIdx); (void)(serial); #endif }
static int hwloc_nvml_discover(struct hwloc_backend *backend) { struct hwloc_topology *topology = backend->topology; nvmlReturn_t ret; unsigned nb, i; if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO))) return 0; if (!hwloc_topology_is_thissystem(topology)) { hwloc_debug("%s", "\nno NVML detection (not thissystem)\n"); return 0; } ret = nvmlInit(); if (NVML_SUCCESS != ret) return 0; ret = nvmlDeviceGetCount(&nb); if (NVML_SUCCESS != ret || !nb) { nvmlShutdown(); return 0; } for(i=0; i<nb; i++) { nvmlPciInfo_t pci; nvmlDevice_t device; hwloc_obj_t osdev, parent; char buffer[64]; ret = nvmlDeviceGetHandleByIndex(i, &device); assert(ret == NVML_SUCCESS); osdev = hwloc_alloc_setup_object(HWLOC_OBJ_OS_DEVICE, -1); snprintf(buffer, sizeof(buffer), "nvml%d", i); osdev->name = strdup(buffer); osdev->depth = (unsigned) HWLOC_TYPE_DEPTH_UNKNOWN; osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU; hwloc_obj_add_info(osdev, "Backend", "NVML"); hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation"); buffer[0] = '\0'; ret = nvmlDeviceGetName(device, buffer, sizeof(buffer)); hwloc_obj_add_info(osdev, "GPUModel", buffer); /* these may fail with NVML_ERROR_NOT_SUPPORTED on old devices */ buffer[0] = '\0'; ret = nvmlDeviceGetSerial(device, buffer, sizeof(buffer)); if (buffer[0] != '\0') hwloc_obj_add_info(osdev, "NVIDIASerial", buffer); buffer[0] = '\0'; ret = nvmlDeviceGetUUID(device, buffer, sizeof(buffer)); if (buffer[0] != '\0') hwloc_obj_add_info(osdev, "NVIDIAUUID", buffer); parent = NULL; if (NVML_SUCCESS == nvmlDeviceGetPciInfo(device, &pci)) { parent = hwloc_pci_belowroot_find_by_busid(topology, pci.domain, pci.bus, pci.device, 0); if (!parent) parent = hwloc_pci_find_busid_parent(topology, pci.domain, pci.bus, pci.device, 0); #if HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION if (parent && parent->type == HWLOC_OBJ_PCI_DEVICE) { unsigned maxwidth = 0, maxgen = 0; float lanespeed; nvmlDeviceGetMaxPcieLinkWidth(device, &maxwidth); nvmlDeviceGetMaxPcieLinkGeneration(device, &maxgen); /* PCIe Gen1 = 2.5GT/s signal-rate per lane with 8/10 encoding = 0.25GB/s data-rate per lane * PCIe Gen2 = 5 GT/s signal-rate per lane with 8/10 encoding = 0.5 GB/s data-rate per lane * PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane */ lanespeed = maxgen <= 2 ? 2.5 * maxgen * 0.8 : 8.0 * 128/130; /* Gbit/s per lane */ if (lanespeed * maxwidth) /* we found the max link speed, replace the current link speed found by pci (or none) */ parent->attr->pcidev.linkspeed = lanespeed * maxwidth / 8; /* GB/s */ } #endif } if (!parent) parent = hwloc_get_root_obj(topology); hwloc_insert_object_by_parent(topology, parent, osdev); } nvmlShutdown(); return nb; }