From 2cc70998d1d4bff12c026ab40e2ed3260e41a281 Mon Sep 17 00:00:00 2001 From: kelvin Date: Tue, 5 May 2026 02:12:33 +0800 Subject: [PATCH] add init pxe cmd --- lib/sunhpc/sunhpc/commands/__init__.py | 103 +- .../sunhpc/commands/init/config/__init__.py | 177 +- .../sunhpc/commands/init/pxe/__init__.py | 264 + lib/sunhpc/sunhpc/configs.py | 18 +- lib/sunhpc/sunhpc/firewalld.py | 328 + lib/sunhpc/sunhpc/main.py | 10 +- lib/sunhpc/sunhpc/paths.py | 14 +- lib/sunhpc/sunhpc/utils/shells.py | 611 + var/pkgs/cuda/13.0/include/nvml.h | 13607 ++++++++++++++++ var/pkgs/cuda/13.0/lib64/stubs/libnvidia-ml.a | Bin 0 -> 557156 bytes .../cuda/13.0/nvml/doc/nvml_changelog.txt | 504 + .../nvml/doc/nvml_deprecation_and_removal.txt | 33 + var/pkgs/cuda/13.0/nvml/example/Makefile | 87 + var/pkgs/cuda/13.0/nvml/example/README.txt | 10 + var/pkgs/cuda/13.0/nvml/example/example.c | 180 + .../cuda/13.0/nvml/example/supportedVgpus.c | 160 + .../13.0/targets/x86_64-linux/include/nvml.h | 13607 ++++++++++++++++ .../x86_64-linux/lib/stubs/libnvidia-ml.a | Bin 0 -> 557156 bytes var/pkgs/ipxe/bootx64.efi | Bin 0 -> 959224 bytes var/pkgs/ipxe/ipxe.efi | Bin 0 -> 1163776 bytes var/pkgs/ipxe/undionly.kpxe | Bin 0 -> 71337 bytes var/pkgs/scripts/init.sh | 751 + var/pkgs/scripts/ipxe.sh | 21 + var/pkgs/scripts/rhel.ks | 77 + 24 files changed, 30461 insertions(+), 101 deletions(-) create mode 100644 lib/sunhpc/sunhpc/commands/init/pxe/__init__.py create mode 100644 lib/sunhpc/sunhpc/firewalld.py create mode 100644 lib/sunhpc/sunhpc/utils/shells.py create mode 100644 var/pkgs/cuda/13.0/include/nvml.h create mode 100644 var/pkgs/cuda/13.0/lib64/stubs/libnvidia-ml.a create mode 100644 var/pkgs/cuda/13.0/nvml/doc/nvml_changelog.txt create mode 100644 var/pkgs/cuda/13.0/nvml/doc/nvml_deprecation_and_removal.txt create mode 100644 var/pkgs/cuda/13.0/nvml/example/Makefile create mode 100644 var/pkgs/cuda/13.0/nvml/example/README.txt create mode 100644 var/pkgs/cuda/13.0/nvml/example/example.c create mode 100644 var/pkgs/cuda/13.0/nvml/example/supportedVgpus.c create mode 100644 var/pkgs/cuda/13.0/targets/x86_64-linux/include/nvml.h create mode 100644 var/pkgs/cuda/13.0/targets/x86_64-linux/lib/stubs/libnvidia-ml.a create mode 100644 var/pkgs/ipxe/bootx64.efi create mode 100644 var/pkgs/ipxe/ipxe.efi create mode 100644 var/pkgs/ipxe/undionly.kpxe create mode 100644 var/pkgs/scripts/init.sh create mode 100644 var/pkgs/scripts/ipxe.sh create mode 100644 var/pkgs/scripts/rhel.ks diff --git a/lib/sunhpc/sunhpc/commands/__init__.py b/lib/sunhpc/sunhpc/commands/__init__.py index f3d0897..3bffe67 100644 --- a/lib/sunhpc/sunhpc/commands/__init__.py +++ b/lib/sunhpc/sunhpc/commands/__init__.py @@ -8,10 +8,13 @@ import types import syslog import inspect import argparse +import subprocess import sunhpc.util +import sunhpc.utils from io import StringIO -from typing import Dict +from pathlib import Path +from typing import Dict, Optional, Tuple, List, Union from sunhpc.logs import Logs from sunhpc.disks import DiskInfo @@ -19,6 +22,9 @@ from sunhpc.configs import Config from sunhpc.network import Network from sunhpc.memory import MemoryInfo from sunhpc.output import Output +from sunhpc.firewalld import FWManager + +from sunhpc.utils.shells import ShellExecutor from xml.sax import saxutils from xml.sax import handler @@ -335,12 +341,15 @@ class Command: self.mem = MemoryInfo() self.disk = DiskInfo() self.fmt = Output() + self.sh = ShellExecutor() + self.fw = FWManager('sunhpc') self.os = os.uname()[0].lower() self.arch = os.uname()[4] self.user = pwd.getpwuid(os.getuid()).pw_name self.parser = argparse.ArgumentParser() + self.parserArgs = [] self.subcommand = 'Sub Command' self.subdesc = None self.epilog = None @@ -392,6 +401,77 @@ class Command: else: return 'no' + def rsync_copy( + self, + src: str, + dst: str, + options: str = '-ah --info=progress2' + ) -> bool: + """ + 简化版本的rsync拷贝、专注于进度显示 + + Args: + src: 源路径 + dst: 目标路径 + + Returns: + bool: 是否成功 + """ + options = options.split() + + cmd = ["rsync"] + cmd.extend(options) + + cmd.append(src) + cmd.append(dst) + + self.log.info(f"执行命令: {' '.join(cmd)}") + try: + # 使用Popen实时显示输出 + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1 + ) + + # 实时打印输出 + for line in process.stdout: + # 去除末尾换行符 + line = line.rstrip('\n\r') + + if line: + # 计算需要覆盖的长度(使用退格符或直接回车) + # 方法1:使用 \r 回车覆盖(推荐) + print(f'\r{line}', end='', flush=True) + last_line = line + else: + # 空行,换行 + print() + + # 输出完成后换行,避免下一行输出覆盖进度信息 + if last_line: + print() + + return_code = process.wait() + + if return_code == 0: + self.log.info("\n✓ 拷贝成功完成") + return True + else: + self.log.error(f"\n✗ 拷贝失败,返回码: {return_code}") + return False + + except Exception as e: + print(f"✗ 执行失败: {e}") + return False + + def is_remote_path(self, path: str) -> bool: + """判断是否为远程路径""" + return '@' in path and ':' in path and not path.startswith(':') + + def dtons(self, data: dict) -> types.SimpleNamespace: '''递归将字典转换为 SimpleNamespace''' if isinstance(data, dict): @@ -544,6 +624,13 @@ class Command: else: return ' '.join(plist) + def output_dict(self, data={}): + if not data: return + + max_key_len = max(len(str(key)) for key in data.keys()) + for key, value in data.items(): + print(f"{str(key):<{max_key_len}} : {value}") + def command(self, command, args=[]): '''Import and run a Sunhpc command. Returns and output string. @@ -599,13 +686,14 @@ class Command: rlist = [] for (key, default) in dlist: - if 'key' in params: + if key in params: rlist.append(params[key]) else: rlist.append(default) + return rlist - def fillPositionalArgs(self, names, params=None, args=None): + def fillPostArgs(self, names, params=None, args=None): ''' The helper function will allow named parameters to be used in lieu of positional arguments @@ -632,7 +720,7 @@ class Command: Returns: remaining args, Filled parameters Example:: - hostlist, iface, mac = self.fillPositionalArgs( + hostlist, iface, mac = self.fillPostArgs( ('iface','mac'), params, args) ''' @@ -690,9 +778,14 @@ class Command: plist = [] # arguments nparams = 0 - flagpattern = re.compile(r'^-[a-zA-Z0-9-_+]+=') + flagpattern = re.compile(r'^[a-zA-Z0-9-_+]+=') for arg in args: + # 检查 - 或 -- 开头 + if arg.startswith('--') or arg.startswith('-'): + self.parserArgs.append(arg) + continue + tokens = arg.split() if tokens[0] == 'select': plist.append(arg) diff --git a/lib/sunhpc/sunhpc/commands/init/config/__init__.py b/lib/sunhpc/sunhpc/commands/init/config/__init__.py index 10a8cff..78b8b3c 100644 --- a/lib/sunhpc/sunhpc/commands/init/config/__init__.py +++ b/lib/sunhpc/sunhpc/commands/init/config/__init__.py @@ -12,106 +12,107 @@ class Command(sunhpc.commands.init.command): 提供一个内网的接口、例如: eth1 - - 提供一个系统ISO文件、或者挂载路径、例如: /mnt/cdrom - - 提供一个内网的接口、例如: eth1 - - 提供一个系统ISO文件、或者挂载路径、例如: /mnt/cdrom - - - - -h --help 显示帮助信息 - -d --debug 开启调试模式 - -v --verbose 显示详细信息 - - - - 使用eth1网络接口、和 /mnt/cdrom 挂载路径 + + 使用eth1网络接口 - - 使用eth1网络接口、和 /mnt/cdrom 挂载路径 + + 使用eth1网络接口 """ def run(self, params, args): - self.parser_cmd_init() - self.parser.add_argument('-i', '--iface', action='store', help='Interface name') - self.parser.add_argument('-d', '--debug', action='store_true', help='Debug mode') - self.parser.add_argument('-f', '--file', action='store_true', help='Configuration file') + (args, iface) = self.fillPostArgs(('iface',)) - self.parser.add_argument( - 'iface', - help='Network interface (required, e.g., eth0, eth1)' - ) + if not iface: + self.abort('must supply an interface') - self.parser.add_argument( - 'mnt', - nargs='?', - default='/mnt/cdrom', - help='Mount point (optional, default: /mnt/cdrom)' - ) + self.net.setiface(iface) - parsed_params = self.parser_cmd_args(args) + ipaddr = self.net.getip() + if ipaddr is None: + self.abort('interface "%s" has no ip address' % iface) - self.log.info('File "/opt/sunhpc/lib/sunhpc/sunhpc/commands/init/config/__init__.py", line 63, in run File "/opt/sunhpc/lib/sunhpc/sunhpc/commands/init/config/__init__.py", line 63, in run') - #print (parsed_params) - iface = parsed_params.get('iface', 'eth0') - - - ''' - config = Config() - config.iface = 'eth1' - config.mnt = '/mnt/cdrom' - config.network = '1.1.1.1' - config.netmask = '255.255.255.0' - config.gateway = '1.1.1.1' - - config.dhcp = Config() - config.dhcp.enabled = True - config.dhcp.server = '1.1.1.1' - config.dhcp.options = ['domain-name', 'domain-name-servers'] - - config.http = Config() - config.http.enabled = True - config.http.server = '1.1.1.1' - - config.api = Config() - config.api.enabled = True - config.api.server = '1.1.1.1' - - config.save('/tmp/sunhpc.yaml') - - self.net.setiface('eth0') - print (f'Interface: {self.net.iface}') - print (f'IP : {self.net.getip()}') - print (f'Network: {self.net.getnetwork()}') - print (f'Netmask: {self.net.getnetmask()}') - print (f'Gateway: {self.net.getgateway()}') - print (f'MAC : {self.net.getmac()}') - print (f'CIDR : {self.net.getcidr()}') - print (f'IPv6 : {self.net.getipv6()}') - - rx, tx = self.net.get_transfer_human() - print (f'RX : {rx}') - print (f'TX : {tx}') - - #print (self.disk.get_disk_info('sda')) - #print (self.mem.get_memory_summary()) - #print (self.mem.get_memory_info()) - - #self.fmt.add_header(['Interface', 'IP', 'Network', 'Netmask', 'Gateway', 'MAC', 'CIDR', 'IPv6']) - - d1 = { - 'name', 'alice', - 'age', 18, - 'city', 'beijing', - 'occupation', 'student' + config_file = self.conf.getConfFile() + config_dict = { + 'iface': iface, + 'ipaddr': ipaddr, + 'netmask': self.net.getnetmask(), + 'network': self.net.getnetwork(), + 'mac': self.net.getmac(), + 'cidr': self.net.getcidr(), + 'dnsmasq': { + 'enabled': True, + 'config': '/etc/dnsmasq.d/sunhpc.conf', + 'server': self.net.getip(), + 'start_ip': '.'.join(ipaddr.split('.')[:-1]) + '.100', + 'end_ip': '.'.join(ipaddr.split('.')[:-1]) + '.200', + 'dns': '223.5.5.5', + 'systemd_name': 'dnsmasq', + }, + 'http': { + 'enabled': True, + 'wwwroot': '/var/www/html', + 'config': '/etc/httpd/conf.d/sunhpc.conf', + 'httpaddr': 'http://%s' % ipaddr, + 'systemd_name': 'httpd', + }, + 'tftp': { + 'enabled': False, + 'tftpboot': '/srv/pxelinux/tftpboot', + 'systemd_name': 'tftp-server', + }, + 'nfs': { + 'enabled': True, + 'paths': [ + { + 'path': '/home', + 'options': 'rw,sync' + }, + { + 'path': '/opt', + 'options': 'rw,sync,no_root_squash' + }, + ], + 'systemd_name': 'nfs-server', + }, + 'ssh': { + 'key_types': [ + 'ssh-rsa', + 'ssh-dss', + 'ssh-ed25519', + ] + }, + 'firewall': { + 'enabled': True, + 'backend': 'firewalld', + }, + 'osinfo': { + 'basename': 'sunhpc', + 'os': 'rocky', + 'version': '9.7', + }, + 'pxe':{ + 'bios': 'boot/undionly.kpxe', + 'uefi': 'boot/bootx64.efi', + 'ipxe': 'boot/ipxe.efi', + 'ksfile': 'scripts/rhel.ks', + 'ipxeboot': 'scripts/ipxe.sh', + 'repo': 'sunhpc/rockylinux/9.7', + 'initrd': 'images/pxeboot/initrd.img', + 'vmlinuz': 'images/pxeboot/vmlinuz', + }, + 'paths': { + 'bin': '/opt/sunhpc/bin', + 'etc': '/opt/sunhpc/etc', + 'lib': '/opt/sunhpc/lib', + 'var': '/opt/sunhpc/var', + 'pkgs': '/srv/repos/pkgs', + 'repo': '/srv/repos/rockylinux/9.7', + } } - self.fmt.dict_output(d1) - ''' \ No newline at end of file + self.conf.save(config_dict=config_dict) diff --git a/lib/sunhpc/sunhpc/commands/init/pxe/__init__.py b/lib/sunhpc/sunhpc/commands/init/pxe/__init__.py new file mode 100644 index 0000000..f253b11 --- /dev/null +++ b/lib/sunhpc/sunhpc/commands/init/pxe/__init__.py @@ -0,0 +1,264 @@ +import os +import re +import sys +import textwrap +import sunhpc.commands +from sunhpc.configs import Config +from sunhpc.paths import ipxe_path, scripts_path + +class Command(sunhpc.commands.init.command): + """ + 这个命令是初始化系统Pxe引导配置服务. + + 提供一个系统ISO挂载点、例如: /mnt/cdrom + 或者提供一个ISO文件路径、例如: /path/to/linux.iso + 或者提供一个ISO文件URL、例如: http://example.com/linux.iso + + + 初始化Pxe引导配置服务 + + """ + def run(self, params, args): + + (args, mnt_src) = self.fillPostArgs(('mntPath', )) + + if not mnt_src: + mnt_src = '/mnt/cdrom' + + if not os.path.exists(mnt_src): + self.log.error(f"挂载点不存在: {mnt_src}") + self.abort("请挂载一下受支持的Linux系统ISO文件.") + + # sunhpc + base_nm = self.conf.osinfo.basename + # /srv/repos/sunhpc + mnt_dst = os.path.join('/srv/repos', base_nm) + + iface = self.conf.iface + ipaddr = self.conf.ipaddr + + treeinfo = os.path.join(mnt_src, '.treeinfo') + if not os.path.exists(treeinfo): + self.log.error(f"不是一个有效或不受支持的Linux系统ISO挂载路径: {mnt_src}") + self.abort("重新挂载一下受支持的Linux系统ISO文件.") + + info = {} + with open(treeinfo, 'r') as f: + for i in f.readlines(): + tmp = i.strip().split('=', 1) + if len(tmp) == 2: + info[tmp[0].strip()] = tmp[1].strip() + + osname = info.get('family', 'unknown').split()[0].lower() + if osname not in ['rocky', 'rhel', 'centos']: + self.log.error(f"不支持的系统类型: {osname}") + self.abort("请提供一个受支持的Linux系统ISO文件. 只支持Rocky, RHEL, CentOS系统.") + + kernel = info.get('kernel', None) + if kernel is None: + self.log.error(f"没有找到内核文件: {kernel}") + self.abort("请提供一个支持 Pxe 的 vmlinuz 文件位置.") + + initrd = info.get('initrd', None) + if initrd is None: + self.log.error(f"没有找到初始化文件: {initrd}") + self.abort("请提供一个支持 Pxe 的 initrd 文件位置.") + + osvers = info.get('version', 'unknown') + http_head = self.conf.http.httpaddr + http_root = f"{http_head}/{base_nm}/{osname}/{osvers}" + http_ksfile = f"{http_root}/{base_nm}/{self.conf.pxe.ksfile}" + http_init = f"{http_root}/{base_nm}/{self.conf.pxe.initfile}" + lrepo_src = os.path.join(mnt_dst, osname, osvers) + if not os.path.exists(lrepo_src): + os.makedirs(lrepo_src) + + # 复制 ISO 文件到目标目录 + if not mnt_src.endswith('/'): + mnt_src = mnt_src + os.sep + + if not lrepo_src.endswith('/'): + lrepo_src = lrepo_src + os.sep + + self.rsync_copy(mnt_src, lrepo_src) + + # 拷贝scripts目录到目标目录. + scripts_dst = mnt_dst + os.sep + self.rsync_copy(scripts_path, scripts_dst) + + # 安装 httpd、dnsmasq 服务 + #result = self.sh.execute("dnf install -y httpd dnsmasq") + + wwwroot = self.conf.http.wwwroot + tftpboot = self.conf.tftp.tftpboot + vmlinuz = os.path.join(lrepo_src, kernel) + initrd = os.path.join(lrepo_src, initrd) + hostname = self.sh.execute("hostname", quiet=True).output().strip() + + # 创建软连接 + self.sh.execute(f"ln -s {mnt_dst} {wwwroot}", quiet=True) + + # 创建tftpboot目录 + pxe_boot_src = ipxe_path + os.sep + pxe_boot_dst = os.path.join(tftpboot, 'boot') + os.sep + self.sh.execute(f"mkdir -p {pxe_boot_dst}", quiet=True) + + # 拷贝pxe引导文件到tftpboot目录 + self.rsync_copy(pxe_boot_src, pxe_boot_dst) + + # 配置 httpd 服务 + httpd_conf = self.conf.http.config + self.create_httpd(hostname, base_nm, wwwroot, httpd_conf) + + # 配置 dnsmasq 服务 + start_ip = self.conf.dnsmasq.start_ip + end_ip = self.conf.dnsmasq.end_ip + addr_dns = self.conf.dnsmasq.dns + bios = self.conf.pxe.bios + ipxe = self.conf.pxe.ipxe + ipxe_sh = self.conf.pxe.ipxeboot + + ipxe_http = f"{http_head}/{base_nm}/{ipxe_sh}" + dnsmasq_conf = self.conf.dnsmasq.config + + self.create_dnsmasq(iface, + ipaddr, tftpboot, dnsmasq_conf, + start_ip, end_ip, addr_dns, bios, ipxe, ipxe_http) + + # kickstart + ksfile_src = self.conf.pxe.ksfile + ksfile_dst = os.path.join(scripts_dst, ksfile_src) + self.create_ksfile(hostname, osvers, http_root, http_init, ksfile_dst) + + # 配置 firewalld 服务 + self.fw.load() + self.fw.add_port('80', 'tcp') + self.fw.add_port('443', 'tcp') + self.fw.save() + + def create_ksfile(self, hostname, osvers, http_root, http_init, ksfile_dst): + ksfile_cnf = f""" + # Kickstart file for {hostname} + # Created by sunhpc + # Version: {osvers} + + graphical + timezone Asia/Shanghai --utc + keyboard --xlayouts="us" + lang en_US.UTF-8 + selinux --disabled + + url --url='{http_root}' + + network --bootproto=dhcp --device=link --ipv6=auto --activate + # autopart --type=lvm + # autopart --type=plain + # autopart --nohome + # autopart --noswap + + %include /tmp/diskinfo + + %packages + @^minimal-environment + @development + @standard + vim + wget + curl + autofs + nfs-utils + nfs4-acl-tools + sssd-nfs-idmap + %end + + rootpw --plaintext "admin_b101" + user --name=dell --plaintext --password="admin_b101" --gecos="dell" + reboot + + %pre --interpreter=/bin/bash + if [ -d /sys/firmware/efi ]; then + cat > /tmp/diskinfo < /tmp/diskinfo < + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + EnableSendfile on + + """ + with open(httpd_conf, 'w') as f: + f.write(textwrap.dedent(httpd_tmpl)) + + + + diff --git a/lib/sunhpc/sunhpc/configs.py b/lib/sunhpc/sunhpc/configs.py index caa3d25..3f01866 100644 --- a/lib/sunhpc/sunhpc/configs.py +++ b/lib/sunhpc/sunhpc/configs.py @@ -31,6 +31,9 @@ class Config: self._build_attributes() self._initialized = True + def getConfFile(self): + return self._config_path + def _build_attributes(self): """构建属性访问""" self._build_from_dict(self._data) @@ -98,17 +101,26 @@ class Config: # 如果属性不存在,返回 None(可选行为) return None - def save(self, path: Optional[str] = None): + def save(self, path: Optional[str] = None, config_dict: Optional[Dict] = None): """保存配置到文件""" save_path = path or self._config_path if not save_path: raise ValueError("未指定保存路径") - + + data = self.to_dict() + if config_dict: + data = config_dict + # 确保目录存在 Path(save_path).parent.mkdir(parents=True, exist_ok=True) with open(save_path, 'w', encoding='utf-8') as f: - yaml.dump(self.to_dict(), f, default_flow_style=False, indent=2, allow_unicode=True) + yaml.dump(data, f, + indent=4, + sort_keys=False, + allow_unicode=True, + default_flow_style=False, + ) print(f"配置已保存到: {save_path}") diff --git a/lib/sunhpc/sunhpc/firewalld.py b/lib/sunhpc/sunhpc/firewalld.py new file mode 100644 index 0000000..dd63f76 --- /dev/null +++ b/lib/sunhpc/sunhpc/firewalld.py @@ -0,0 +1,328 @@ +""" +Firewalld 自定义服务管理工具 +用于创建和修改 /etc/firewalld/services/ 目录下的自定义服务 XML 文件 +""" +import os +from pathlib import Path +from xml.dom import minidom +import xml.etree.ElementTree as ET +from sunhpc.logs import Logs + +slog = Logs(name="Firewd", show_time=True) + +class FWManager: + """Firewalld 服务文件管理器""" + + # firewalld 服务目录路径 + SYSTEM_SERVICES_DIR = Path('/usr/lib/firewalld/services') + CUSTOM_SERVICES_DIR = Path('/etc/firewalld/services') + + def __init__(self, service_name): + """ + 初始化服务管理器 + + Args: + service_name: 服务名称(不含 .xml 后缀) + """ + self.service_name = service_name + self.service_file = self.CUSTOM_SERVICES_DIR / f"{service_name}.xml" + self.xml_tree = None + self.root = None + + def _ensure_custom_dir(self): + """确保自定义服务目录存在""" + self.CUSTOM_SERVICES_DIR.mkdir(parents=True, exist_ok=True) + + def _create_xml_structure(self): + """创建基本的 XML 结构""" + # 创建根元素 + self.root = ET.Element('service') + + # 添加 short 元素 + short = ET.SubElement(self.root, 'short') + short.text = self.service_name.capitalize() + + # 添加 description 元素 + description = ET.SubElement(self.root, 'description') + description.text = f"Custom service: {self.service_name}" + + # 添加 port 元素(稍后添加) + # 添加 protocol 元素(稍后添加) + + self.xml_tree = ET.ElementTree(self.root) + + def _prettify_xml(self, elem): + """ + 格式化 XML 输出 + + Args: + elem: XML 元素 + + Returns: + str: 格式化后的 XML 字符串 + """ + rough_string = ET.tostring(elem, 'utf-8') + reparsed = minidom.parseString(rough_string) + return reparsed.toprettyxml(indent=' ') + + def _save_xml(self): + """保存 XML 文件到自定义服务目录""" + self._ensure_custom_dir() + + # 格式化 XML + xml_str = self._prettify_xml(self.root) + + # 写入文件 + with open(self.service_file, 'w', encoding='utf-8') as f: + # 移除多余的 XML 声明(firewalld 不需要) + if xml_str.startswith(' str: + """获取命令的标准输出""" + return self._stdout + + def error(self) -> str: + """获取命令的标准错误""" + return self._stderr + + def code(self) -> int: + """获取命令的返回码""" + return self._returncode + + def output_lines(self) -> List[str]: + """返回输出行列表,过滤空行""" + return [line for line in self._stdout.splitlines() if line] + + def error_lines(self) -> List[str]: + return [line for line in self._stderr.splitlines() if line] + + def get_metadata(self, key: str, default=None): + """获取元数据""" + return self._metadata.get(key, default) + + def set_metadata(self, key: str, value: Any): + """设置元数据""" + self._metadata[key] = value + + +class ShellExecutor: + """ + Shell命令执行器基类,提供通用的命令执行功能 + 子类可重写方法以实现特定命令的定制行为 + """ + + def __init__(self, + show_animation: bool = True, + animation_chars: str = '|/-\\', + show_last_line: bool = True, + max_display_lines: int = 1 + ): + """ + 初始化执行器 + + 参数: + show_animation : 是否显示动态动画 + animation_chars : 动画字符集 + show_last_line : 是否显示最后一行 + max_display_lines : 最大显示行数,超过则省略号显示 + """ + self.show_animation = show_animation + self.animation_chars = animation_chars + self.show_last_line = show_last_line + self.max_display_lines = max_display_lines + self._line_count = 0 + self._last_lines = deque(maxlen=max_display_lines) + + def pre_execute_hook(self, cmd: Union[str, List[str]]) -> Union[str, List[str]]: + """ + 执行前的钩子函数,可以修改命令或做预处理 + 子类可重写此方法 + """ + return cmd + + def post_execute_hook(self, result: ShellResult, cmd: Union[str, List[str]]) -> ShellResult: + """ + 执行后的钩子函数,可以处理结果、提取信息等 + 子类可重写此方法 + """ + return result + + def get_display_message(self, cmd: Union[str, List[str]]) -> str: + """ + 获取执行时显示的消息 + 子类可重写以显示不同的提示信息 + """ + return "Running..." + + def get_completion_message(self, cmd: Union[str, List[str]], result: ShellResult) -> str: + """ + 获取完成时显示的消息 + 子类可重写以显示不同的完成信息 + """ + if self._line_count > 0: + return f"Completed! (lines: {self._line_count})" + else: + return "Completed!" + + def get_realtime_info(self, line: str) -> str: + """ + 获取实时显示的信息(可被子类重写以显示不同的信息格式) + + 参数: + line: 最新读取的一行输出 + + 返回: + 要显示的附加信息字符串 + """ + # 默认显示最后一行内容(截断过长内容) + if self.show_last_line and line: + # 限制行长度,避免显示过长 + max_length = 80 + if len(line) > max_length: + line = line[:max_length-3] + "..." + return f" [{line}]" + return "" + + def update_realtime_output(self, line: str): + """ + 更新实时输出信息(可被子类重写以处理特殊输出) + + 参数: + line: 最新读取的一行输出 + """ + self._last_lines.append(line.rstrip('\n\r')) + + def parse_output_for_metadata(self, + result: ShellResult, + cmd: Union[str, List[str]]) -> Dict[str, Any]: + """ + 解析输出提取元数据 + 子类可重写此方法 + """ + return {} + + def _RRread_output_thread(self, process): + """读取输出的线程函数""" + for line in iter(process.stdout.readline, ''): + if line: + self._line_count += 1 + process.stdout.close() + + def _read_output_thread(self, process, is_stderr=False): + """读取输出的线程函数""" + if is_stderr: + # 错误输出只读取,不显示在动画中 + for line in iter(process.stderr.readline, ''): + if line: + pass # 可以在这里处理stderr + process.stderr.close() + else: + # 标准输出需要计数和显示 + for line in iter(process.stdout.readline, ''): + if line: + self._line_count += 1 + # 更新实时输出 + self.update_realtime_output(line) + # 可以添加一个回调,让子类实时处理每一行 + self.on_output_line(line) + process.stdout.close() + + def _display_animation(self, process): + """显示动画的函数""" + if not self.show_animation: + return + + idx = 0 + while process.poll() is None: + spin_char = self.animation_chars[idx % len(self.animation_chars)] + if self._line_count > 0: + display = f"\r{spin_char} {self.get_display_message(process.args)} (lines: {self._line_count})" + else: + display = f"\r{spin_char} {self.get_display_message(process.args)}" + sys.stdout.write(display) + sys.stdout.flush() + idx += 1 + time.sleep(0.1) + + # 清除当前行并显示完成信息 + completion_msg = self.get_completion_message(process.args, ShellResult(0, "", "")) + sys.stdout.write(f"\r✓ {completion_msg} \n") + sys.stdout.flush() + + def on_output_line(self, line: str): + """ + 当有新的输出行时的回调函数(可被子类重写) + + 参数: + line: 新输出的行 + """ + pass + + def execute(self, + cmd: Union[str, List[str]], + t_cmd: Optional[Union[str, List[str]]] = None, + quiet: bool = False, + timeout: Optional[int] = None, + show_animation: bool = True, + show_real_time: bool = True, + ) -> ShellResult: + """ + 执行shell命令 + + 参数: + cmd : 要执行的字符串或列表 + t_cmd : 可选,执行完成后的测试命令 + timeout : 超时时间(秒) + show_real_time : 是否显示实时输出(仅当show_animation为True时有效) + + 返回: + ShellResult 实例 + """ + # 执行预处理钩子 + processed_cmd = self.pre_execute_hook(cmd) + + # 转换命令为列表形式 + if isinstance(processed_cmd, str): + cmd_list = shlex.split(processed_cmd) + else: + cmd_list = processed_cmd + + # 重置计数器 + self._line_count = 0 + self._last_lines.clear() + + # 启动子进程 + process = subprocess.Popen( + cmd_list, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + bufsize=1 + ) + + # 用于存储输出 + stdout_lines = [] + stderr_lines = [] + + # 创建读取线程 + def collect_stdout(): + for line in iter(process.stdout.readline, ''): + if line: + stdout_lines.append(line) + self._line_count += 1 + self.update_realtime_output(line) + self.on_output_line(line) + process.stdout.close() + + def collect_stderr(): + for line in iter(process.stderr.readline, ''): + if line: + stderr_lines.append(line) + process.stderr.close() + + stdout_thread = threading.Thread(target=collect_stdout) + stderr_thread = threading.Thread(target=collect_stderr) + stdout_thread.daemon = True + stderr_thread.daemon = True + + stdout_thread.start() + stderr_thread.start() + + # 显示动画 + if self.show_animation: + idx = 0 + last_display = "" + while process.poll() is None: + spin_char = self.animation_chars[idx % len(self.animation_chars)] + + # 构建显示内容 + if self._line_count > 0: + base_display = f"{spin_char} {self.get_display_message(cmd_list)} (lines: {self._line_count})" + # 添加实时输出信息 + if show_real_time and self._last_lines: + # 显示最后一行内容 + last_line = list(self._last_lines)[-1] + realtime_info = self.get_realtime_info(last_line) + display = f"\r{base_display}{realtime_info}" + else: + display = f"\r{base_display}" + else: + display = f"\r{spin_char} {self.get_display_message(cmd_list)}" + + # 只在内容变化时更新,减少闪烁 + if display != last_display or self._line_count != last_line_count: + sys.stdout.write(f'\r{display}\033[K') + sys.stdout.flush() + last_display = display + last_line_count = self._line_count + + idx += 1 + time.sleep(0.1) + + # 等待线程结束 + stdout_thread.join(timeout=1) + stderr_thread.join(timeout=1) + + # 清除当前行 + self._clear_line() + + # 显示完成信息 + if not quiet: + completion_msg = self.get_completion_message(cmd_list, ShellResult(0, "", "")) + # 清除当前行并显示完成信息 + sys.stdout.write(f"\r✓ {completion_msg}\n") + sys.stdout.flush() + else: + # 不显示动画时,直接等待进程结束 + process.wait() + stdout_thread.join() + stderr_thread.join() + + # 合并输出 + stdout = ''.join(stdout_lines) + stderr = ''.join(stderr_lines) + + # 如果有测试命令,执行测试命令 + if t_cmd is not None: + if isinstance(t_cmd, str): + test_cmd_list = shlex.split(t_cmd) + else: + test_cmd_list = t_cmd + test_process = subprocess.run( + test_cmd_list, + input=stdout, + capture_output=True, + text=True + ) + final_returncode = 0 if test_process.returncode == 0 else 1 + final_stderr = stderr + test_process.stderr + else: + final_returncode = process.returncode + final_stderr = stderr + + # 创建结果对象 + result = ShellResult(final_returncode, stdout, final_stderr) + + # 解析元数据(如果子类需要) + metadata = self.parse_output_for_metadata(result, processed_cmd) + for key, value in metadata.items(): + result.set_metadata(key, value) + + # 执行后置钩子 + result = self.post_execute_hook(result, processed_cmd) + + return result + + def _clear_line(self): + """彻底清除当前行""" + # 先移动到行首,然后清除到行尾 + sys.stdout.write('\r\033[K') # \033[K 清除从光标到行尾的内容 + sys.stdout.flush() + +class DnfExecutor(ShellExecutor): + """针对dnf命令的专用执行器""" + + def get_display_message(self, cmd: Union[str, List[str]]) -> str: + """显示dnf特定消息""" + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + if 'install' in cmd_str: + return "Installing packages..." + elif 'remove' in cmd_str or 'erase' in cmd_str: + return "Removing packages..." + elif 'update' in cmd_str: + return "Updating packages..." + elif 'search' in cmd_str: + return "Searching packages..." + else: + return "DNF Running..." + + def parse_output_for_metadata(self, result: ShellResult, cmd: Union[str, List[str]]) -> Dict[str, Any]: + """从dnf输出中提取包信息""" + metadata = {} + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + + # 提取安装的包名 + if 'install' in cmd_str or 'remove' in cmd_str: + packages = [] + for line in result.output_lines(): + if 'Installing:' in line or 'Removing:' in line: + # 提取包名 + parts = line.split() + for part in parts: + if '.x86_64' in part or '.noarch' in part: + packages.append(part) + if packages: + metadata['packages'] = packages + metadata['package_count'] = len(packages) + + return metadata + + def post_execute_hook(self, result: ShellResult, cmd: Union[str, List[str]]) -> ShellResult: + """dnf执行后的额外处理""" + if result and 'install' in str(cmd): + # 如果安装成功,提取安装的包列表 + packages = result.get_metadata('packeds', []) + if packages: + result.set_metadata('installed_packages', packages) + return result + + +class RpmExecutor(ShellExecutor): + """针对rpm命令的专用执行器""" + + def __init__(self, query_format: Optional[str] = None, **kwargs): + """ + 初始化rpm执行器 + + 参数: + query_format: 查询格式,如 "%{NAME} %{VERSION}" + """ + super().__init__(**kwargs) + self.query_format = query_format + + def pre_execute_hook(self, cmd: Union[str, List[str]]) -> Union[str, List[str]]: + """预处理rpm命令""" + if isinstance(cmd, str): + cmd_parts = shlex.split(cmd) + else: + cmd_parts = cmd.copy() + + # 如果是查询命令且指定了格式,添加--qf参数 + if self.query_format and len(cmd_parts) > 1 and cmd_parts[0] == 'rpm': + if cmd_parts[1] in ['-q', '--query', '-qa', '--query', '-qi']: + # 插入格式参数 + if '--qf' not in cmd_parts and '--queryformat' not in cmd_parts: + cmd_parts.insert(2, '--qf') + cmd_parts.insert(3, self.query_format) + + return cmd_parts + + def get_display_message(self, cmd: Union[str, List[str]]) -> str: + """显示rpm特定消息""" + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + if '-i' in cmd_str and 'install' in cmd_str: + return "Installing RPM packages..." + elif '-e' in cmd_str: + return "Erasing RPM packages..." + elif '-q' in cmd_str: + return "Querying RPM database..." + elif '-U' in cmd_str or '-F' in cmd_str: + return "Upgrading RPM packages..." + else: + return "RPM Running..." + + def parse_output_for_metadata(self, result: ShellResult, cmd: Union[str, List[str]]) -> Dict[str, Any]: + """从rpm输出中提取包信息""" + metadata = {} + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + + # 提取查询结果的包名和版本 + if '-q' in cmd_str and result and result.output(): + packages = [] + for line in result.output_lines(): + if line.strip(): + parts = line.split() + if len(parts) >= 2: + packages.append({ + 'name': parts[0], + 'version': parts[1] if len(parts) > 1 else '' + }) + if packages: + metadata['packages'] = packages + metadata['package_count'] = len(packages) + + return metadata + + +class SystemdExecutor(ShellExecutor): + """针对systemctl命令的专用执行器""" + + def get_display_message(self, cmd: Union[str, List[str]]) -> str: + """显示systemctl特定消息""" + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + if 'start' in cmd_str: + return "Starting service..." + elif 'stop' in cmd_str: + return "Stopping service..." + elif 'restart' in cmd_str: + return "Restarting service..." + elif 'status' in cmd_str: + return "Checking service status..." + elif 'enable' in cmd_str: + return "Enabling service..." + elif 'disable' in cmd_str: + return "Disabling service..." + else: + return "Systemctl Running..." + + def parse_output_for_metadata(self, result: ShellResult, cmd: Union[str, List[str]]) -> Dict[str, Any]: + """从systemctl输出中提取服务状态""" + metadata = {} + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + + # 提取服务状态 + if 'status' in cmd_str and result: + for line in result.output_lines(): + if 'Active:' in line: + status = line.split('Active:')[1].strip() + metadata['service_status'] = status + if 'active' in status: + metadata['is_active'] = True + else: + metadata['is_active'] = False + + return metadata + + +# ========== 使用示例 ========== +if __name__ == "__main__": + + # 示例1:使用基础执行器 + print("=== 基础执行器 ===") + executor = ShellExecutor() + result = executor.execute("ls -la") + print(f"命令成功: {bool(result)}") + print(f"输出行数: {len(result.output_lines())}") + print(f"前3行输出:\n{chr(10).join(result.output_lines()[:3])}") + print("-" * 50) + + # 示例2:使用dnf执行器(如果有dnf命令) + print("=== DNF执行器 ===") + dnf = DnfExecutor() + # 搜索命令示例(不会实际修改系统) + result = dnf.execute("dnf search python3", show_animation=False) # 测试时关闭动画 + print(f"搜索完成: {bool(result)}") + if result.get_metadata('package_count', 0) > 0: + print(f"找到 {result.get_metadata('package_count')} 个包") + + # 示例3:使用rpm执行器 + print("=== RPM执行器 ===") + rpm = RpmExecutor(query_format="%{NAME} %{VERSION}") + # 查询已安装的包(前5个) + result = rpm.execute("rpm -qa | head -5", show_animation=False) + print(f"查询完成: {bool(result)}") + print("前5个包:") + for line in result.output_lines()[:5]: + print(f" {line}") + + # 示例4:使用systemd执行器 + print("=== Systemd执行器 ===") + systemd = SystemdExecutor() + result = systemd.execute("systemctl status sshd", show_animation=False) + print(f"服务状态: {result.get_metadata('service_status', 'unknown')}") + print(f"服务活跃: {result.get_metadata('is_active', False)}") + + # 示例5:带测试命令的示例 + print("=== 带测试命令 ===") + executor = ShellExecutor() + result = executor.execute("ls -la", t_cmd="grep README") + print(f"包含README文件: {bool(result)}") + if not result: + print(f"未找到README文件") + + # 示例6:如何扩展自己的专用执行器 + print("=== 自定义扩展示例 ===") + + class GitExecutor(ShellExecutor): + """Git命令专用执行器""" + + def get_display_message(self, cmd: Union[str, List[str]]) -> str: + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + if 'status' in cmd_str: + return "Checking git status..." + elif 'pull' in cmd_str: + return "Pulling from remote..." + elif 'push' in cmd_str: + return "Pushing to remote..." + elif 'commit' in cmd_str: + return "Committing changes..." + else: + return "Git Running..." + + def parse_output_for_metadata(self, result: ShellResult, cmd: Union[str, List[str]]) -> Dict[str, Any]: + """提取git信息""" + metadata = {} + cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd + + if 'status' in cmd_str: + # 统计未跟踪、修改、新增的文件 + untracked = 0 + modified = 0 + for line in result.output_lines(): + if 'Untracked files:' in line: + untracked = 1 + elif 'modified:' in line: + modified += 1 + metadata['untracked'] = untracked > 0 + metadata['modified_count'] = modified + + return metadata + + git = GitExecutor() + result = git.execute("git status", show_animation=False) + if result: + print(f"有未跟踪文件: {result.get_metadata('untracked', False)}") + print(f"修改文件数: {result.get_metadata('modified_count', 0)}") \ No newline at end of file diff --git a/var/pkgs/cuda/13.0/include/nvml.h b/var/pkgs/cuda/13.0/include/nvml.h new file mode 100644 index 0000000..5f6b9cf --- /dev/null +++ b/var/pkgs/cuda/13.0/include/nvml.h @@ -0,0 +1,13607 @@ +/* + * Copyright 1993-2025 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. Users and possessors of this source code + * are hereby granted a nonexclusive, royalty-free license to use this code + * in individual and commercial software. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + * + * Any use of this source code in individual and commercial software must + * include, in the user documentation and internal comments to the code, + * the above Disclaimer and U.S. Government End Users Notice. + */ + +/* +NVML API Reference + +The NVIDIA Management Library (NVML) is a C-based programmatic interface for monitoring and +managing various states within NVIDIA Tesla &tm; GPUs. It is intended to be a platform for building +3rd party applications, and is also the underlying library for the NVIDIA-supported nvidia-smi +tool. NVML is thread-safe so it is safe to make simultaneous NVML calls from multiple threads. + +API Documentation + +Supported platforms: +- Windows: Windows Server 2008 R2 64bit, Windows Server 2012 R2 64bit, Windows 7 64bit, Windows 8 64bit, Windows 10 64bit +- Linux: 32-bit and 64-bit +- Hypervisors: Windows Server 2008R2/2012 Hyper-V 64bit, Citrix XenServer 6.2 SP1+, VMware ESX 5.1/5.5 + +Supported products: +- Full Support + - All Tesla products, starting with the Fermi architecture + - All Quadro products, starting with the Fermi architecture + - All vGPU Software products, starting with the Kepler architecture + - Selected GeForce Titan products +- Limited Support + - All Geforce products, starting with the Fermi architecture + +The NVML library can be found at \%ProgramW6432\%\\"NVIDIA Corporation"\\NVSMI\\ on Windows. It is +not be added to the system path by default. To dynamically link to NVML, add this path to the PATH +environmental variable. To dynamically load NVML, call LoadLibrary with this path. + +On Linux the NVML library will be found on the standard library path. For 64 bit Linux, both the 32 bit +and 64 bit NVML libraries will be installed. + +Online documentation for this library is available at http://docs.nvidia.com/deploy/nvml-api/index.html +*/ + +#ifndef __nvml_nvml_h__ +#define __nvml_nvml_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * On Windows, set up methods for DLL export + * define NVML_STATIC_IMPORT when using nvml_loader library + */ +#if defined _WINDOWS + #if !defined NVML_STATIC_IMPORT + #if defined NVML_LIB_EXPORT + #define DECLDIR __declspec(dllexport) + #else + #define DECLDIR __declspec(dllimport) + #endif + #else + #define DECLDIR + #endif +#else + #define DECLDIR +#endif + +/* + * Deprecation definition. Starting CUDA 13.1 this will change to: + * #if defined _WINDOWS + * #define DEPRECATED(ver) __declspec(deprecated) + * #else + * #define DEPRECATED(ver) __attribute__((deprecated)) + * #endif + */ +#define DEPRECATED(ver) /* nop in CUDA 13.0, enabled in CUDA 13.1 */ + + #define NVML_MCDM_SUPPORT + +/** + * NVML API versioning support + */ +#define NVML_API_VERSION 13 +#define NVML_API_VERSION_STR "13" +/** + * Defining NVML_NO_UNVERSIONED_FUNC_DEFS will disable "auto upgrading" of APIs. + * e.g. the user will have to call nvmlInit_v2 instead of nvmlInit. Enable this + * guard if you need to support older versions of the API + */ +#ifndef NVML_NO_UNVERSIONED_FUNC_DEFS + #define nvmlInit nvmlInit_v2 + #define nvmlDeviceGetPciInfo nvmlDeviceGetPciInfo_v3 + #define nvmlDeviceGetCount nvmlDeviceGetCount_v2 + #define nvmlDeviceGetHandleByIndex nvmlDeviceGetHandleByIndex_v2 + #define nvmlDeviceGetHandleByPciBusId nvmlDeviceGetHandleByPciBusId_v2 + #define nvmlDeviceGetNvLinkRemotePciInfo nvmlDeviceGetNvLinkRemotePciInfo_v2 + #define nvmlDeviceRemoveGpu nvmlDeviceRemoveGpu_v2 + #define nvmlDeviceGetGridLicensableFeatures nvmlDeviceGetGridLicensableFeatures_v4 + #define nvmlEventSetWait nvmlEventSetWait_v2 + #define nvmlDeviceGetAttributes nvmlDeviceGetAttributes_v2 + #define nvmlComputeInstanceGetInfo nvmlComputeInstanceGetInfo_v2 + #define nvmlDeviceGetComputeRunningProcesses nvmlDeviceGetComputeRunningProcesses_v3 + #define nvmlDeviceGetGraphicsRunningProcesses nvmlDeviceGetGraphicsRunningProcesses_v3 + #define nvmlDeviceGetMPSComputeRunningProcesses nvmlDeviceGetMPSComputeRunningProcesses_v3 + #define nvmlBlacklistDeviceInfo_t nvmlExcludedDeviceInfo_t + #define nvmlGetBlacklistDeviceCount nvmlGetExcludedDeviceCount + #define nvmlGetBlacklistDeviceInfoByIndex nvmlGetExcludedDeviceInfoByIndex + #define nvmlDeviceGetGpuInstancePossiblePlacements nvmlDeviceGetGpuInstancePossiblePlacements_v2 + #define nvmlVgpuInstanceGetLicenseInfo nvmlVgpuInstanceGetLicenseInfo_v2 + #define nvmlDeviceGetDriverModel nvmlDeviceGetDriverModel_v2 +#endif // #ifndef NVML_NO_UNVERSIONED_FUNC_DEFS + +#define NVML_STRUCT_VERSION(data, ver) (unsigned int)(sizeof(nvml ## data ## _v ## ver ## _t) | \ + (ver << 24U)) + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceStructs Device Structs + * @{ + */ +/***************************************************************************************************/ + +/** + * Special constant that some fields take when they are not available. + * Used when only part of the struct is not available. + * + * Each structure explicitly states when to check for this value. + */ +#define NVML_VALUE_NOT_AVAILABLE (-1) + +typedef struct nvmlDevice_st* nvmlDevice_t; + +typedef struct nvmlGpuInstance_st* nvmlGpuInstance_t; + +/** + * Buffer size guaranteed to be large enough for pci bus id + */ +#define NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE 32 + +/** + * Buffer size guaranteed to be large enough for pci bus id for \p busIdLegacy + */ +#define NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE 16 + +/** + * PCI information about a GPU device. + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int domain; //!< The PCI domain on which the device's bus resides, 0 to 0xffffffff + unsigned int bus; //!< The bus on which the device resides, 0 to 0xff + unsigned int device; //!< The device's id on the bus, 0 to 31 + + unsigned int pciDeviceId; //!< The combined 16-bit device id and 16-bit vendor id + unsigned int pciSubSystemId; //!< The 32-bit Sub System Device ID + + unsigned int baseClass; //!< The 8-bit PCI base class code + unsigned int subClass; //!< The 8-bit PCI sub class code + + char busId[NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE]; //!< The tuple domain:bus:device.function PCI identifier (& NULL terminator) +} nvmlPciInfoExt_v1_t; +typedef nvmlPciInfoExt_v1_t nvmlPciInfoExt_t; +#define nvmlPciInfoExt_v1 NVML_STRUCT_VERSION(PciInfoExt, 1) + +/** + * PCI information about a GPU device. + */ +typedef struct nvmlPciInfo_st +{ + char busIdLegacy[NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE]; //!< The legacy tuple domain:bus:device.function PCI identifier (& NULL terminator) + unsigned int domain; //!< The PCI domain on which the device's bus resides, 0 to 0xffffffff + unsigned int bus; //!< The bus on which the device resides, 0 to 0xff + unsigned int device; //!< The device's id on the bus, 0 to 31 + unsigned int pciDeviceId; //!< The combined 16-bit device id and 16-bit vendor id + + // Added in NVML 2.285 API + unsigned int pciSubSystemId; //!< The 32-bit Sub System Device ID + + char busId[NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE]; //!< The tuple domain:bus:device.function PCI identifier (& NULL terminator) +} nvmlPciInfo_t; + +/** + * PCI format string for \p busIdLegacy + */ +#define NVML_DEVICE_PCI_BUS_ID_LEGACY_FMT "%04X:%02X:%02X.0" + +/** + * PCI format string for \p busId + */ +#define NVML_DEVICE_PCI_BUS_ID_FMT "%08X:%02X:%02X.0" + +/** + * Utility macro for filling the pci bus id format from a nvmlPciInfo_t + */ +#define NVML_DEVICE_PCI_BUS_ID_FMT_ARGS(pciInfo) (pciInfo)->domain, \ + (pciInfo)->bus, \ + (pciInfo)->device + +/** + * Detailed ECC error counts for a device. + * + * @deprecated Different GPU families can have different memory error counters + * See \ref nvmlDeviceGetMemoryErrorCounter + */ +typedef struct nvmlEccErrorCounts_st +{ + unsigned long long l1Cache; //!< L1 cache errors + unsigned long long l2Cache; //!< L2 cache errors + unsigned long long deviceMemory; //!< Device memory errors + unsigned long long registerFile; //!< Register file errors +} nvmlEccErrorCounts_t; + +/** + * Utilization information for a device. + * Each sample period may be between 1 second and 1/6 second, depending on the product being queried. + */ +typedef struct nvmlUtilization_st +{ + unsigned int gpu; //!< Percent of time over the past sample period during which one or more kernels was executing on the GPU + unsigned int memory; //!< Percent of time over the past sample period during which global (device) memory was being read or written +} nvmlUtilization_t; + +/** + * Memory allocation information for a device (v1). + * The total amount is equal to the sum of the amounts of free and used memory. + */ +typedef struct nvmlMemory_st +{ + unsigned long long total; //!< Total physical device memory (in bytes) + unsigned long long free; //!< Unallocated device memory (in bytes) + unsigned long long used; //!< Sum of Reserved and Allocated device memory (in bytes). + //!< Note that the driver/GPU always sets aside a small amount of memory for bookkeeping +} nvmlMemory_t; + +/** + * Memory allocation information for a device (v2). + * + * Version 2 adds versioning for the struct and the amount of system-reserved memory as an output. + */ +typedef struct nvmlMemory_v2_st +{ + unsigned int version; //!< Structure format version (must be 2) + unsigned long long total; //!< Total physical device memory (in bytes) + unsigned long long reserved; //!< Device memory (in bytes) reserved for system use (driver or firmware) + unsigned long long free; //!< Unallocated device memory (in bytes) + unsigned long long used; //!< Allocated device memory (in bytes). +} nvmlMemory_v2_t; + +#define nvmlMemory_v2 NVML_STRUCT_VERSION(Memory, 2) + +/** + * BAR1 Memory allocation Information for a device + */ +typedef struct nvmlBAR1Memory_st +{ + unsigned long long bar1Total; //!< Total BAR1 Memory (in bytes) + unsigned long long bar1Free; //!< Unallocated BAR1 Memory (in bytes) + unsigned long long bar1Used; //!< Allocated Used Memory (in bytes) +}nvmlBAR1Memory_t; + +/** + * Information about running compute processes on the GPU, legacy version + * for older versions of the API. + */ +typedef struct nvmlProcessInfo_v1_st +{ + unsigned int pid; //!< Process ID + unsigned long long usedGpuMemory; //!< Amount of used GPU memory in bytes. + //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported + //! because Windows KMD manages all the memory and not the NVIDIA driver +} nvmlProcessInfo_v1_t; + +/** + * Information about running compute processes on the GPU + */ +typedef struct nvmlProcessInfo_v2_st +{ + unsigned int pid; //!< Process ID + unsigned long long usedGpuMemory; //!< Amount of used GPU memory in bytes. + //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported + //! because Windows KMD manages all the memory and not the NVIDIA driver + unsigned int gpuInstanceId; //!< If MIG is enabled, stores a valid GPU instance ID. gpuInstanceId is set to + // 0xFFFFFFFF otherwise. + unsigned int computeInstanceId; //!< If MIG is enabled, stores a valid compute instance ID. computeInstanceId is set to + // 0xFFFFFFFF otherwise. +} nvmlProcessInfo_v2_t, nvmlProcessInfo_t; + +/** + * Information about running process on the GPU with protected memory + */ +typedef struct +{ + unsigned int pid; //!< Process ID + unsigned long long usedGpuMemory; //!< Amount of used GPU memory in bytes. + //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported + //! because Windows KMD manages all the memory and not the NVIDIA driver + unsigned int gpuInstanceId; //!< If MIG is enabled, stores a valid GPU instance ID. gpuInstanceId is + // set to 0xFFFFFFFF otherwise. + unsigned int computeInstanceId; //!< If MIG is enabled, stores a valid compute instance ID. computeInstanceId + // is set to 0xFFFFFFFF otherwise. + unsigned long long usedGpuCcProtectedMemory; //!< Amount of used GPU conf compute protected memory in bytes. +} nvmlProcessDetail_v1_t; + +/** + * Information about all running processes on the GPU for the given mode + */ +typedef struct +{ + unsigned int version; //!< Struct version, MUST be nvmlProcessDetailList_v1 + unsigned int mode; //!< Process mode(Compute/Graphics/MPSCompute) + unsigned int numProcArrayEntries; //!< Number of process entries in procArray + nvmlProcessDetail_v1_t *procArray; //!< Process array +} nvmlProcessDetailList_v1_t; + +typedef nvmlProcessDetailList_v1_t nvmlProcessDetailList_t; + +/** + * nvmlProcessDetailList version + */ +#define nvmlProcessDetailList_v1 NVML_STRUCT_VERSION(ProcessDetailList, 1) + +typedef struct nvmlDeviceAttributes_st +{ + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count + unsigned int gpuInstanceSliceCount; //!< GPU instance slice count + unsigned int computeInstanceSliceCount; //!< Compute instance slice count + unsigned long long memorySizeMB; //!< Device memory size (in MiB) +} nvmlDeviceAttributes_t; + +/** + * C2C Mode information for a device + */ +typedef struct +{ + unsigned int isC2cEnabled; +} nvmlC2cModeInfo_v1_t; + +#define nvmlC2cModeInfo_v1 NVML_STRUCT_VERSION(C2cModeInfo, 1) + +/** + * Enum to represent device addressing mode values + */ +typedef enum +{ + NVML_DEVICE_ADDRESSING_MODE_NONE = 0, //!< No active mode + NVML_DEVICE_ADDRESSING_MODE_HMM = 1, //!< Heterogeneous Memory Management mode + NVML_DEVICE_ADDRESSING_MODE_ATS = 2, //!< Address Translation Services mode +} nvmlDeviceAddressingModeType_t; + +/** + * Struct to represent device addressing mode information + */ +typedef struct +{ + unsigned int version; //!< API version + unsigned int value; //!< One of \ref nvmlDeviceAddressingModeType_t +} nvmlDeviceAddressingMode_v1_t; +typedef nvmlDeviceAddressingMode_v1_t nvmlDeviceAddressingMode_t; + +#define nvmlDeviceAddressingMode_v1 NVML_STRUCT_VERSION(DeviceAddressingMode, 1) + +/** + * Struct to represent the NVML repair status + */ +typedef struct +{ + unsigned int version; //!< API version number + unsigned int bChannelRepairPending; //!< Reference to \a unsigned int + unsigned int bTpcRepairPending; //!< Reference to \a unsigned int +} nvmlRepairStatus_v1_t; +typedef nvmlRepairStatus_v1_t nvmlRepairStatus_t; + +#define nvmlRepairStatus_v1 NVML_STRUCT_VERSION(RepairStatus, 1) + +/** + * Possible values that classify the remap availability for each bank. The max + * field will contain the number of banks that have maximum remap availability + * (all reserved rows are available). None means that there are no reserved + * rows available. + */ +typedef struct nvmlRowRemapperHistogramValues_st +{ + unsigned int max; + unsigned int high; + unsigned int partial; + unsigned int low; + unsigned int none; +} nvmlRowRemapperHistogramValues_t; + +/** + * Enum to represent type of bridge chip + */ +typedef enum nvmlBridgeChipType_enum +{ + NVML_BRIDGE_CHIP_PLX = 0, + NVML_BRIDGE_CHIP_BRO4 = 1 +}nvmlBridgeChipType_t; + +/** + * Maximum number of NvLink links supported + */ +#define NVML_NVLINK_MAX_LINKS 18 + +/** + * Enum to represent the NvLink utilization counter packet units + */ +typedef enum nvmlNvLinkUtilizationCountUnits_enum +{ + NVML_NVLINK_COUNTER_UNIT_CYCLES = 0, // count by cycles + NVML_NVLINK_COUNTER_UNIT_PACKETS = 1, // count by packets + NVML_NVLINK_COUNTER_UNIT_BYTES = 2, // count by bytes + NVML_NVLINK_COUNTER_UNIT_RESERVED = 3, // count reserved for internal use + // this must be last + NVML_NVLINK_COUNTER_UNIT_COUNT +} nvmlNvLinkUtilizationCountUnits_t; + +/** + * Enum to represent the NvLink utilization counter packet types to count + * ** this is ONLY applicable with the units as packets or bytes + * ** as specified in \a nvmlNvLinkUtilizationCountUnits_t + * ** all packet filter descriptions are target GPU centric + * ** these can be "OR'd" together + */ +typedef enum nvmlNvLinkUtilizationCountPktTypes_enum +{ + NVML_NVLINK_COUNTER_PKTFILTER_NOP = 0x1, // no operation packets + NVML_NVLINK_COUNTER_PKTFILTER_READ = 0x2, // read packets + NVML_NVLINK_COUNTER_PKTFILTER_WRITE = 0x4, // write packets + NVML_NVLINK_COUNTER_PKTFILTER_RATOM = 0x8, // reduction atomic requests + NVML_NVLINK_COUNTER_PKTFILTER_NRATOM = 0x10, // non-reduction atomic requests + NVML_NVLINK_COUNTER_PKTFILTER_FLUSH = 0x20, // flush requests + NVML_NVLINK_COUNTER_PKTFILTER_RESPDATA = 0x40, // responses with data + NVML_NVLINK_COUNTER_PKTFILTER_RESPNODATA = 0x80, // responses without data + NVML_NVLINK_COUNTER_PKTFILTER_ALL = 0xFF // all packets +} nvmlNvLinkUtilizationCountPktTypes_t; + +/** + * Struct to define the NVLINK counter controls + */ +typedef struct nvmlNvLinkUtilizationControl_st +{ + nvmlNvLinkUtilizationCountUnits_t units; + nvmlNvLinkUtilizationCountPktTypes_t pktfilter; +} nvmlNvLinkUtilizationControl_t; + +/** + * Enum to represent NvLink queryable capabilities + */ +typedef enum nvmlNvLinkCapability_enum +{ + NVML_NVLINK_CAP_P2P_SUPPORTED = 0, // P2P over NVLink is supported + NVML_NVLINK_CAP_SYSMEM_ACCESS = 1, // Access to system memory is supported + NVML_NVLINK_CAP_P2P_ATOMICS = 2, // P2P atomics are supported + NVML_NVLINK_CAP_SYSMEM_ATOMICS= 3, // System memory atomics are supported + NVML_NVLINK_CAP_SLI_BRIDGE = 4, // SLI is supported over this link + NVML_NVLINK_CAP_VALID = 5, // Link is supported on this device + // should be last + NVML_NVLINK_CAP_COUNT +} nvmlNvLinkCapability_t; + +/** + * Enum to represent NvLink queryable error counters + */ +typedef enum nvmlNvLinkErrorCounter_enum +{ + NVML_NVLINK_ERROR_DL_REPLAY = 0, // Data link transmit replay error counter + NVML_NVLINK_ERROR_DL_RECOVERY = 1, // Data link transmit recovery error counter + NVML_NVLINK_ERROR_DL_CRC_FLIT = 2, // Data link receive flow control digit CRC error counter + NVML_NVLINK_ERROR_DL_CRC_DATA = 3, // Data link receive data CRC error counter + NVML_NVLINK_ERROR_DL_ECC_DATA = 4, // Data link receive data ECC error counter + + // this must be last + NVML_NVLINK_ERROR_COUNT +} nvmlNvLinkErrorCounter_t; + +/** + * Enum to represent NvLink's remote device type + */ +typedef enum nvmlIntNvLinkDeviceType_enum +{ + NVML_NVLINK_DEVICE_TYPE_GPU = 0x00, + NVML_NVLINK_DEVICE_TYPE_IBMNPU = 0x01, + NVML_NVLINK_DEVICE_TYPE_SWITCH = 0x02, + NVML_NVLINK_DEVICE_TYPE_UNKNOWN = 0xFF +} nvmlIntNvLinkDeviceType_t; + +/** + * Represents level relationships within a system between two GPUs + * The enums are spaced to allow for future relationships + */ +typedef enum nvmlGpuLevel_enum +{ + NVML_TOPOLOGY_INTERNAL = 0, // e.g. Tesla K80 + NVML_TOPOLOGY_SINGLE = 10, // all devices that only need traverse a single PCIe switch + NVML_TOPOLOGY_MULTIPLE = 20, // all devices that need not traverse a host bridge + NVML_TOPOLOGY_HOSTBRIDGE = 30, // all devices that are connected to the same host bridge + NVML_TOPOLOGY_NODE = 40, // all devices that are connected to the same NUMA node but possibly multiple host bridges + NVML_TOPOLOGY_SYSTEM = 50 // all devices in the system + + // there is purposefully no COUNT here because of the need for spacing above +} nvmlGpuTopologyLevel_t; + +/* Compatibility for CPU->NODE renaming */ +#define NVML_TOPOLOGY_CPU NVML_TOPOLOGY_NODE + +/* P2P Capability Index Status*/ +typedef enum nvmlGpuP2PStatus_enum +{ + NVML_P2P_STATUS_OK = 0, + NVML_P2P_STATUS_CHIPSET_NOT_SUPPORED, + NVML_P2P_STATUS_CHIPSET_NOT_SUPPORTED = NVML_P2P_STATUS_CHIPSET_NOT_SUPPORED, + NVML_P2P_STATUS_GPU_NOT_SUPPORTED, + NVML_P2P_STATUS_IOH_TOPOLOGY_NOT_SUPPORTED, + NVML_P2P_STATUS_DISABLED_BY_REGKEY, + NVML_P2P_STATUS_NOT_SUPPORTED, + NVML_P2P_STATUS_UNKNOWN + +} nvmlGpuP2PStatus_t; + +/* P2P Capability Index*/ +typedef enum nvmlGpuP2PCapsIndex_enum +{ + NVML_P2P_CAPS_INDEX_READ = 0, + NVML_P2P_CAPS_INDEX_WRITE = 1, + NVML_P2P_CAPS_INDEX_NVLINK = 2, + NVML_P2P_CAPS_INDEX_ATOMICS = 3, + NVML_P2P_CAPS_INDEX_PCI = 4, + /* + * DO NOT USE! NVML_P2P_CAPS_INDEX_PROP is deprecated. + * Use NVML_P2P_CAPS_INDEX_PCI instead. + */ + NVML_P2P_CAPS_INDEX_PROP = NVML_P2P_CAPS_INDEX_PCI, + NVML_P2P_CAPS_INDEX_UNKNOWN = 5, +}nvmlGpuP2PCapsIndex_t; + +/** + * Maximum limit on Physical Bridges per Board + */ +#define NVML_MAX_PHYSICAL_BRIDGE (128) + +/** + * Information about the Bridge Chip Firmware + */ +typedef struct nvmlBridgeChipInfo_st +{ + nvmlBridgeChipType_t type; //!< Type of Bridge Chip + unsigned int fwVersion; //!< Firmware Version. 0=Version is unavailable +}nvmlBridgeChipInfo_t; + +/** + * This structure stores the complete Hierarchy of the Bridge Chip within the board. The immediate + * bridge is stored at index 0 of bridgeInfoList, parent to immediate bridge is at index 1 and so forth. + */ +typedef struct nvmlBridgeChipHierarchy_st +{ + unsigned char bridgeCount; //!< Number of Bridge Chips on the Board + nvmlBridgeChipInfo_t bridgeChipInfo[NVML_MAX_PHYSICAL_BRIDGE]; //!< Hierarchy of Bridge Chips on the board +}nvmlBridgeChipHierarchy_t; + +/** + * Represents Type of Sampling Event + */ +typedef enum nvmlSamplingType_enum +{ + NVML_TOTAL_POWER_SAMPLES = 0, //!< To represent total power drawn by GPU + NVML_GPU_UTILIZATION_SAMPLES = 1, //!< To represent percent of time during which one or more kernels was executing on the GPU + NVML_MEMORY_UTILIZATION_SAMPLES = 2, //!< To represent percent of time during which global (device) memory was being read or written + NVML_ENC_UTILIZATION_SAMPLES = 3, //!< To represent percent of time during which NVENC remains busy + NVML_DEC_UTILIZATION_SAMPLES = 4, //!< To represent percent of time during which NVDEC remains busy + NVML_PROCESSOR_CLK_SAMPLES = 5, //!< To represent processor clock samples + NVML_MEMORY_CLK_SAMPLES = 6, //!< To represent memory clock samples + NVML_MODULE_POWER_SAMPLES = 7, //!< To represent module power samples for total module starting Grace Hopper + NVML_JPG_UTILIZATION_SAMPLES = 8, //!< To represent percent of time during which NVJPG remains busy + NVML_OFA_UTILIZATION_SAMPLES = 9, //!< To represent percent of time during which NVOFA remains busy + + // Keep this last + NVML_SAMPLINGTYPE_COUNT +}nvmlSamplingType_t; + +/** + * Represents the queryable PCIe utilization counters + */ +typedef enum nvmlPcieUtilCounter_enum +{ + NVML_PCIE_UTIL_TX_BYTES = 0, // 1KB granularity + NVML_PCIE_UTIL_RX_BYTES = 1, // 1KB granularity + + // Keep this last + NVML_PCIE_UTIL_COUNT +} nvmlPcieUtilCounter_t; + +/** + * Represents the type for sample value returned + */ +typedef enum nvmlValueType_enum +{ + NVML_VALUE_TYPE_DOUBLE = 0, + NVML_VALUE_TYPE_UNSIGNED_INT = 1, + NVML_VALUE_TYPE_UNSIGNED_LONG = 2, + NVML_VALUE_TYPE_UNSIGNED_LONG_LONG = 3, + NVML_VALUE_TYPE_SIGNED_LONG_LONG = 4, + NVML_VALUE_TYPE_SIGNED_INT = 5, + NVML_VALUE_TYPE_UNSIGNED_SHORT = 6, + + // Keep this last + NVML_VALUE_TYPE_COUNT +}nvmlValueType_t; + +/** + * Union to represent different types of Value + */ +typedef union nvmlValue_st +{ + double dVal; //!< If the value is double + int siVal; //!< If the value is signed int + unsigned int uiVal; //!< If the value is unsigned int + unsigned long ulVal; //!< If the value is unsigned long + unsigned long long ullVal; //!< If the value is unsigned long long + signed long long sllVal; //!< If the value is signed long long + unsigned short usVal; //!< If the value is unsigned short +}nvmlValue_t; + +/** + * Information for Sample + */ +typedef struct nvmlSample_st +{ + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlValue_t sampleValue; //!< Sample Value +}nvmlSample_t; + +/** + * Represents type of perf policy for which violation times can be queried + */ +typedef enum nvmlPerfPolicyType_enum +{ + NVML_PERF_POLICY_POWER = 0, //!< How long did power violations cause the GPU to be below application clocks + NVML_PERF_POLICY_THERMAL = 1, //!< How long did thermal violations cause the GPU to be below application clocks + NVML_PERF_POLICY_SYNC_BOOST = 2, //!< How long did sync boost cause the GPU to be below application clocks + NVML_PERF_POLICY_BOARD_LIMIT = 3, //!< How long did the board limit cause the GPU to be below application clocks + NVML_PERF_POLICY_LOW_UTILIZATION = 4, //!< How long did low utilization cause the GPU to be below application clocks + NVML_PERF_POLICY_RELIABILITY = 5, //!< How long did the board reliability limit cause the GPU to be below application clocks + + NVML_PERF_POLICY_TOTAL_APP_CLOCKS = 10, //!< Total time the GPU was held below application clocks by any limiter (0 - 5 above) + NVML_PERF_POLICY_TOTAL_BASE_CLOCKS = 11, //!< Total time the GPU was held below base clocks + + // Keep this last + NVML_PERF_POLICY_COUNT +}nvmlPerfPolicyType_t; + +/** + * Struct to hold perf policy violation status data + */ +typedef struct nvmlViolationTime_st +{ + unsigned long long referenceTime; //!< referenceTime represents CPU timestamp in microseconds + unsigned long long violationTime; //!< violationTime in Nanoseconds +}nvmlViolationTime_t; + +#define NVML_MAX_THERMAL_SENSORS_PER_GPU 3 + +/** + * Represents the thermal sensor targets + */ +typedef enum +{ + NVML_THERMAL_TARGET_NONE = 0, + NVML_THERMAL_TARGET_GPU = 1, //!< GPU core temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_MEMORY = 2, //!< GPU memory temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_POWER_SUPPLY = 4, //!< GPU power supply temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_BOARD = 8, //!< GPU board ambient temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_VCD_BOARD = 9, //!< Visual Computing Device Board temperature requires NvVisualComputingDeviceHandle + NVML_THERMAL_TARGET_VCD_INLET = 10, //!< Visual Computing Device Inlet temperature requires NvVisualComputingDeviceHandle + NVML_THERMAL_TARGET_VCD_OUTLET = 11, //!< Visual Computing Device Outlet temperature requires NvVisualComputingDeviceHandle + + NVML_THERMAL_TARGET_ALL = 15, + NVML_THERMAL_TARGET_UNKNOWN = -1, +} nvmlThermalTarget_t; + +/** + * Represents the thermal sensor controllers + */ +typedef enum +{ + NVML_THERMAL_CONTROLLER_NONE = 0, + NVML_THERMAL_CONTROLLER_GPU_INTERNAL, + NVML_THERMAL_CONTROLLER_ADM1032, + NVML_THERMAL_CONTROLLER_ADT7461, + NVML_THERMAL_CONTROLLER_MAX6649, + NVML_THERMAL_CONTROLLER_MAX1617, + NVML_THERMAL_CONTROLLER_LM99, + NVML_THERMAL_CONTROLLER_LM89, + NVML_THERMAL_CONTROLLER_LM64, + NVML_THERMAL_CONTROLLER_G781, + NVML_THERMAL_CONTROLLER_ADT7473, + NVML_THERMAL_CONTROLLER_SBMAX6649, + NVML_THERMAL_CONTROLLER_VBIOSEVT, + NVML_THERMAL_CONTROLLER_OS, + NVML_THERMAL_CONTROLLER_NVSYSCON_CANOAS, + NVML_THERMAL_CONTROLLER_NVSYSCON_E551, + NVML_THERMAL_CONTROLLER_MAX6649R, + NVML_THERMAL_CONTROLLER_ADT7473S, + NVML_THERMAL_CONTROLLER_UNKNOWN = -1, +} nvmlThermalController_t; + +/** + * Struct to hold the thermal sensor settings + */ +typedef struct +{ + unsigned int count; + struct + { + nvmlThermalController_t controller; + int defaultMinTemp; + int defaultMaxTemp; + int currentTemp; + nvmlThermalTarget_t target; + } sensor[NVML_MAX_THERMAL_SENSORS_PER_GPU]; + +} nvmlGpuThermalSettings_t; + +/** + * Cooler control type + */ +typedef enum nvmlCoolerControl_enum +{ + NVML_THERMAL_COOLER_SIGNAL_NONE = 0, //!< This cooler has no control signal. + NVML_THERMAL_COOLER_SIGNAL_TOGGLE = 1, //!< This cooler can only be toggled either ON or OFF (eg a switch). + NVML_THERMAL_COOLER_SIGNAL_VARIABLE = 2, //!< This cooler's level can be adjusted from some minimum to some maximum (eg a knob). + + // Keep this last + NVML_THERMAL_COOLER_SIGNAL_COUNT +} nvmlCoolerControl_t; + +/** + * Cooler's target + */ +typedef enum nvmlCoolerTarget_enum +{ + NVML_THERMAL_COOLER_TARGET_NONE = 1 << 0, //!< This cooler cools nothing. + NVML_THERMAL_COOLER_TARGET_GPU = 1 << 1, //!< This cooler can cool the GPU. + NVML_THERMAL_COOLER_TARGET_MEMORY = 1 << 2, //!< This cooler can cool the memory. + NVML_THERMAL_COOLER_TARGET_POWER_SUPPLY = 1 << 3, //!< This cooler can cool the power supply. + NVML_THERMAL_COOLER_TARGET_GPU_RELATED = (NVML_THERMAL_COOLER_TARGET_GPU | NVML_THERMAL_COOLER_TARGET_MEMORY | NVML_THERMAL_COOLER_TARGET_POWER_SUPPLY) //!< This cooler cools all of the components related to its target gpu. GPU_RELATED = GPU | MEMORY | POWER_SUPPLY +} nvmlCoolerTarget_t; + +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int index; //!< the cooler index + nvmlCoolerControl_t signalType; //!< OUT: the cooler's control signal characteristics + nvmlCoolerTarget_t target; //!< OUT: the target that cooler cools +} nvmlCoolerInfo_v1_t; +typedef nvmlCoolerInfo_v1_t nvmlCoolerInfo_t; + +#define nvmlCoolerInfo_v1 NVML_STRUCT_VERSION(CoolerInfo, 1) + +/** + * UUID length in ASCII format + */ +#define NVML_DEVICE_UUID_ASCII_LEN 41 + +/** + * UUID length in binary format + */ +#define NVML_DEVICE_UUID_BINARY_LEN 16 + +/** + * Enum to represent different UUID types + */ +typedef enum +{ + NVML_UUID_TYPE_NONE = 0, //!< Undefined type + NVML_UUID_TYPE_ASCII = 1, //!< ASCII format type + NVML_UUID_TYPE_BINARY = 2, //!< Binary format type +} nvmlUUIDType_t; + +/** + * Union to represent different UUID values + */ +typedef union +{ + char str[NVML_DEVICE_UUID_ASCII_LEN]; //!< ASCII format value + unsigned char bytes[NVML_DEVICE_UUID_BINARY_LEN]; //!< Binary format value +} nvmlUUIDValue_t; + +/** + * Struct to represent NVML UUID information + */ +typedef struct +{ + unsigned int version; //!< API version number + unsigned int type; //!< One of \p nvmlUUIDType_t + nvmlUUIDValue_t value; //!< One of \p nvmlUUIDValue_t, to be set based on the UUID format +} nvmlUUID_v1_t; +typedef nvmlUUID_v1_t nvmlUUID_t; + +#define nvmlUUID_v1 NVML_STRUCT_VERSION(UUID, 1) + +/** + * Struct to represent the NVML PDI information + */ +typedef struct +{ + unsigned int version; //!< API version number + unsigned long long value; //!< 64-bit PDI value +} nvmlPdi_v1_t; +typedef nvmlPdi_v1_t nvmlPdi_t; + +#define nvmlPdi_v1 NVML_STRUCT_VERSION(Pdi, 1) + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceEnumvs Device Enums + * @{ + */ +/***************************************************************************************************/ + +/** + * Generic enable/disable enum. + */ +typedef enum nvmlEnableState_enum +{ + NVML_FEATURE_DISABLED = 0, //!< Feature disabled + NVML_FEATURE_ENABLED = 1 //!< Feature enabled +} nvmlEnableState_t; + +//! Generic flag used to specify the default behavior of some functions. See description of particular functions for details. +#define nvmlFlagDefault 0x00 +//! Generic flag used to force some behavior. See description of particular functions for details. +#define nvmlFlagForce 0x01 + +/** + * DRAM Encryption Info + */ +typedef struct +{ + unsigned int version; //!< IN - the API version number + nvmlEnableState_t encryptionState; //!< IN/OUT - DRAM Encryption state +} nvmlDramEncryptionInfo_v1_t; +typedef nvmlDramEncryptionInfo_v1_t nvmlDramEncryptionInfo_t; + +#define nvmlDramEncryptionInfo_v1 NVML_STRUCT_VERSION(DramEncryptionInfo, 1) + +/** + * * The Brand of the GPU + * */ +typedef enum nvmlBrandType_enum +{ + NVML_BRAND_UNKNOWN = 0, + NVML_BRAND_QUADRO = 1, + NVML_BRAND_TESLA = 2, + NVML_BRAND_NVS = 3, + NVML_BRAND_GRID = 4, // Deprecated from API reporting. Keeping definition for backward compatibility. + NVML_BRAND_GEFORCE = 5, + NVML_BRAND_TITAN = 6, + NVML_BRAND_NVIDIA_VAPPS = 7, // NVIDIA Virtual Applications + NVML_BRAND_NVIDIA_VPC = 8, // NVIDIA Virtual PC + NVML_BRAND_NVIDIA_VCS = 9, // NVIDIA Virtual Compute Server + NVML_BRAND_NVIDIA_VWS = 10, // NVIDIA RTX Virtual Workstation + NVML_BRAND_NVIDIA_CLOUD_GAMING = 11, // NVIDIA Cloud Gaming + NVML_BRAND_NVIDIA_VGAMING = NVML_BRAND_NVIDIA_CLOUD_GAMING, // Deprecated from API reporting. Keeping definition for backward compatibility. + NVML_BRAND_QUADRO_RTX = 12, + NVML_BRAND_NVIDIA_RTX = 13, + NVML_BRAND_NVIDIA = 14, + NVML_BRAND_GEFORCE_RTX = 15, // Unused + NVML_BRAND_TITAN_RTX = 16, // Unused + // Keep this last + NVML_BRAND_COUNT = 18, +} nvmlBrandType_t; + +/** + * Temperature thresholds. + */ +typedef enum nvmlTemperatureThresholds_enum +{ + NVML_TEMPERATURE_THRESHOLD_SHUTDOWN = 0, // Temperature at which the GPU will + // shut down for HW protection + NVML_TEMPERATURE_THRESHOLD_SLOWDOWN = 1, // Temperature at which the GPU will + // begin HW slowdown + NVML_TEMPERATURE_THRESHOLD_MEM_MAX = 2, // Memory Temperature at which the GPU will + // begin SW slowdown + NVML_TEMPERATURE_THRESHOLD_GPU_MAX = 3, // GPU Temperature at which the GPU + // can be throttled below base clock + NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MIN = 4, // Minimum GPU Temperature that can be + // set as acoustic threshold + NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_CURR = 5, // Current temperature that is set as + // acoustic threshold. + NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MAX = 6, // Maximum GPU temperature that can be + // set as acoustic threshold. + NVML_TEMPERATURE_THRESHOLD_GPS_CURR = 7, // Current temperature that is set as + // gps threshold. + // Keep this last + NVML_TEMPERATURE_THRESHOLD_COUNT +} nvmlTemperatureThresholds_t; + +/** + * Temperature sensors. + */ +typedef enum nvmlTemperatureSensors_enum +{ + NVML_TEMPERATURE_GPU = 0, //!< Temperature sensor for the GPU die + + // Keep this last + NVML_TEMPERATURE_COUNT +} nvmlTemperatureSensors_t; + +/** + * Margin temperature values + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + int marginTemperature; //!< The margin temperature value +} nvmlMarginTemperature_v1_t; + +typedef nvmlMarginTemperature_v1_t nvmlMarginTemperature_t; + +#define nvmlMarginTemperature_v1 NVML_STRUCT_VERSION(MarginTemperature, 1) + +/** + * Compute mode. + * + * NVML_COMPUTEMODE_EXCLUSIVE_PROCESS was added in CUDA 4.0. + * Earlier CUDA versions supported a single exclusive mode, + * which is equivalent to NVML_COMPUTEMODE_EXCLUSIVE_THREAD in CUDA 4.0 and beyond. + */ +typedef enum nvmlComputeMode_enum +{ + NVML_COMPUTEMODE_DEFAULT = 0, //!< Default compute mode -- multiple contexts per device + NVML_COMPUTEMODE_EXCLUSIVE_THREAD = 1, //!< Support Removed + NVML_COMPUTEMODE_PROHIBITED = 2, //!< Compute-prohibited mode -- no contexts per device + NVML_COMPUTEMODE_EXCLUSIVE_PROCESS = 3, //!< Compute-exclusive-process mode -- only one context per device, usable from multiple threads at a time + + // Keep this last + NVML_COMPUTEMODE_COUNT +} nvmlComputeMode_t; + +/** + * Max Clock Monitors available + */ +#define MAX_CLK_DOMAINS 32 + +/** + * Clock Monitor error types + */ +typedef struct nvmlClkMonFaultInfo_struct { + /** + * The Domain which faulted + */ + unsigned int clkApiDomain; + + /** + * Faults Information + */ + unsigned int clkDomainFaultMask; +} nvmlClkMonFaultInfo_t; + +/** + * Clock Monitor Status + */ +typedef struct nvmlClkMonStatus_status { + /** + * Fault status Indicator + */ + unsigned int bGlobalStatus; + + /** + * Total faulted domain numbers + */ + unsigned int clkMonListSize; + + /** + * The fault Information structure + */ + nvmlClkMonFaultInfo_t clkMonList[MAX_CLK_DOMAINS]; +} nvmlClkMonStatus_t; + +/** + * ECC bit types. + * + * @deprecated See \ref nvmlMemoryErrorType_t for a more flexible type + */ +#define nvmlEccBitType_t nvmlMemoryErrorType_t + +/** + * Single bit ECC errors + * + * @deprecated Mapped to \ref NVML_MEMORY_ERROR_TYPE_CORRECTED + */ +#define NVML_SINGLE_BIT_ECC NVML_MEMORY_ERROR_TYPE_CORRECTED + +/** + * Double bit ECC errors + * + * @deprecated Mapped to \ref NVML_MEMORY_ERROR_TYPE_UNCORRECTED + */ +#define NVML_DOUBLE_BIT_ECC NVML_MEMORY_ERROR_TYPE_UNCORRECTED + +/** + * Memory error types + */ +typedef enum nvmlMemoryErrorType_enum +{ + /** + * A memory error that was corrected + * + * For ECC errors, these are single bit errors + * For Texture memory, these are errors fixed by resend + */ + NVML_MEMORY_ERROR_TYPE_CORRECTED = 0, + /** + * A memory error that was not corrected + * + * For ECC errors, these are double bit errors + * For Texture memory, these are errors where the resend fails + */ + NVML_MEMORY_ERROR_TYPE_UNCORRECTED = 1, + + // Keep this last + NVML_MEMORY_ERROR_TYPE_COUNT //!< Count of memory error types + +} nvmlMemoryErrorType_t; + +/** + * Represents Nvlink Version + */ +typedef enum nvmlNvlinkVersion_enum +{ + NVML_NVLINK_VERSION_INVALID = 0, + NVML_NVLINK_VERSION_1_0 = 1, + NVML_NVLINK_VERSION_2_0 = 2, + NVML_NVLINK_VERSION_2_2 = 3, + NVML_NVLINK_VERSION_3_0 = 4, + NVML_NVLINK_VERSION_3_1 = 5, + NVML_NVLINK_VERSION_4_0 = 6, + NVML_NVLINK_VERSION_5_0 = 7, +}nvmlNvlinkVersion_t; + +/** + * ECC counter types. + * + * Note: Volatile counts are reset each time the driver loads. On Windows this is once per boot. On Linux this can be more frequent. + * On Linux the driver unloads when no active clients exist. If persistence mode is enabled or there is always a driver + * client active (e.g. X11), then Linux also sees per-boot behavior. If not, volatile counts are reset each time a compute app + * is run. + */ +typedef enum nvmlEccCounterType_enum +{ + NVML_VOLATILE_ECC = 0, //!< Volatile counts are reset each time the driver loads. + NVML_AGGREGATE_ECC = 1, //!< Aggregate counts persist across reboots (i.e. for the lifetime of the device) + + // Keep this last + NVML_ECC_COUNTER_TYPE_COUNT //!< Count of memory counter types +} nvmlEccCounterType_t; + +/** + * Clock types. + * + * All speeds are in Mhz. + */ +typedef enum nvmlClockType_enum +{ + NVML_CLOCK_GRAPHICS = 0, //!< Graphics clock domain + NVML_CLOCK_SM = 1, //!< SM clock domain + NVML_CLOCK_MEM = 2, //!< Memory clock domain + NVML_CLOCK_VIDEO = 3, //!< Video encoder/decoder clock domain + + // Keep this last + NVML_CLOCK_COUNT //!< Count of clock types +} nvmlClockType_t; + +/** + * Clock Ids. These are used in combination with nvmlClockType_t + * to specify a single clock value. + */ +typedef enum nvmlClockId_enum +{ + NVML_CLOCK_ID_CURRENT = 0, //!< Current actual clock value + NVML_CLOCK_ID_APP_CLOCK_TARGET = 1, //!< Target application clock. + //!< Deprecated, do not use. + NVML_CLOCK_ID_APP_CLOCK_DEFAULT = 2, //!< Default application clock target + //!< Deprecated, do not use. + NVML_CLOCK_ID_CUSTOMER_BOOST_MAX = 3, //!< OEM-defined maximum clock rate + + //Keep this last + NVML_CLOCK_ID_COUNT //!< Count of Clock Ids. +} nvmlClockId_t; + +/** + * Driver models. + * + * Windows only. + */ + +typedef enum nvmlDriverModel_enum +{ + NVML_DRIVER_WDDM = 0, //!< WDDM driver model -- GPU treated as a display device + NVML_DRIVER_WDM = 1, //!< WDM (TCC) model (deprecated) -- GPU treated as a generic compute device + NVML_DRIVER_MCDM = 2 //!< MCDM driver model -- GPU treated as a Microsoft compute device +} nvmlDriverModel_t; + +#define NVML_MAX_GPU_PERF_PSTATES 16 + +/** + * Allowed PStates. + */ +typedef enum nvmlPStates_enum +{ + NVML_PSTATE_0 = 0, //!< Performance state 0 -- Maximum Performance + NVML_PSTATE_1 = 1, //!< Performance state 1 + NVML_PSTATE_2 = 2, //!< Performance state 2 + NVML_PSTATE_3 = 3, //!< Performance state 3 + NVML_PSTATE_4 = 4, //!< Performance state 4 + NVML_PSTATE_5 = 5, //!< Performance state 5 + NVML_PSTATE_6 = 6, //!< Performance state 6 + NVML_PSTATE_7 = 7, //!< Performance state 7 + NVML_PSTATE_8 = 8, //!< Performance state 8 + NVML_PSTATE_9 = 9, //!< Performance state 9 + NVML_PSTATE_10 = 10, //!< Performance state 10 + NVML_PSTATE_11 = 11, //!< Performance state 11 + NVML_PSTATE_12 = 12, //!< Performance state 12 + NVML_PSTATE_13 = 13, //!< Performance state 13 + NVML_PSTATE_14 = 14, //!< Performance state 14 + NVML_PSTATE_15 = 15, //!< Performance state 15 -- Minimum Performance + NVML_PSTATE_UNKNOWN = 32 //!< Unknown performance state +} nvmlPstates_t; + +/** + * Clock offset info. + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + nvmlClockType_t type; + nvmlPstates_t pstate; + int clockOffsetMHz; + int minClockOffsetMHz; + int maxClockOffsetMHz; +} nvmlClockOffset_v1_t; + +typedef nvmlClockOffset_v1_t nvmlClockOffset_t; + +#define nvmlClockOffset_v1 NVML_STRUCT_VERSION(ClockOffset, 1) + +/** + * Fan speed info. + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int fan; //!< the fan index + unsigned int speed; //!< OUT: the fan speed in RPM +} nvmlFanSpeedInfo_v1_t; +typedef nvmlFanSpeedInfo_v1_t nvmlFanSpeedInfo_t; + +#define nvmlFanSpeedInfo_v1 NVML_STRUCT_VERSION(FanSpeedInfo, 1) + +#define NVML_PERF_MODES_BUFFER_SIZE 2048 + +/** + * Device performance modes string + */ +typedef struct +{ + unsigned int version; //!< the API version number + char str[NVML_PERF_MODES_BUFFER_SIZE]; //!< OUT: the performance modes string. +} nvmlDevicePerfModes_v1_t; +typedef nvmlDevicePerfModes_v1_t nvmlDevicePerfModes_t; + +#define nvmlDevicePerfModes_v1 NVML_STRUCT_VERSION(DevicePerfModes, 1) + +/** + * Device current clocks string + */ +typedef struct +{ + unsigned int version; //!< the API version number + char str[NVML_PERF_MODES_BUFFER_SIZE]; //!< OUT: the current clock frequency string. +} nvmlDeviceCurrentClockFreqs_v1_t; +typedef nvmlDeviceCurrentClockFreqs_v1_t nvmlDeviceCurrentClockFreqs_t; + +#define nvmlDeviceCurrentClockFreqs_v1 NVML_STRUCT_VERSION(DeviceCurrentClockFreqs, 1) + +/** + * Device powerMizer modes + */ +#define NVML_POWER_MIZER_MODE_ADAPTIVE 0 //!< adjust GPU clocks based on GPU utilization +#define NVML_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE 1 //!< raise GPU clocks to favor maximum performance, + //!< to the extent that thermal and other constraints allow +#define NVML_POWER_MIZER_MODE_AUTO 2 //!< PowerMizer mode is driver controlled. +#define NVML_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE 3 //!< lock to GPU base clocks + +typedef struct +{ + unsigned int currentMode; //!< OUT: the current powermizer mode + unsigned int mode; //!< IN: the powermizer mode to set + unsigned int supportedPowerMizerModes; //!< OUT: Bitmask of supported powermizer modes +} nvmlDevicePowerMizerModes_v1_t; + +/** + * GPU Operation Mode + * + * GOM allows to reduce power usage and optimize GPU throughput by disabling GPU features. + * + * Each GOM is designed to meet specific user needs. + */ +typedef enum nvmlGom_enum +{ + NVML_GOM_ALL_ON = 0, //!< Everything is enabled and running at full speed + + NVML_GOM_COMPUTE = 1, //!< Designed for running only compute tasks. Graphics operations + //!< are not allowed + + NVML_GOM_LOW_DP = 2 //!< Designed for running graphics applications that don't require + //!< high bandwidth double precision +} nvmlGpuOperationMode_t; + +/** + * Available infoROM objects. + */ +typedef enum nvmlInforomObject_enum +{ + NVML_INFOROM_OEM = 0, //!< An object defined by OEM + NVML_INFOROM_ECC = 1, //!< The ECC object determining the level of ECC support + NVML_INFOROM_POWER = 2, //!< The power management object + NVML_INFOROM_DEN = 3, //!< DRAM Encryption object + // Keep this last + NVML_INFOROM_COUNT //!< This counts the number of infoROM objects the driver knows about +} nvmlInforomObject_t; + +/** + * Return values for NVML API calls. + */ +typedef enum nvmlReturn_enum +{ + // cppcheck-suppress * + NVML_SUCCESS = 0, //!< The operation was successful + NVML_ERROR_UNINITIALIZED = 1, //!< NVML was not first initialized with nvmlInit() + NVML_ERROR_INVALID_ARGUMENT = 2, //!< A supplied argument is invalid + NVML_ERROR_NOT_SUPPORTED = 3, //!< The requested operation is not available on target device + NVML_ERROR_NO_PERMISSION = 4, //!< The current user does not have permission for operation + NVML_ERROR_ALREADY_INITIALIZED = 5, //!< Deprecated: Multiple initializations are now allowed through ref counting + NVML_ERROR_NOT_FOUND = 6, //!< A query to find an object was unsuccessful + NVML_ERROR_INSUFFICIENT_SIZE = 7, //!< An input argument is not large enough + NVML_ERROR_INSUFFICIENT_POWER = 8, //!< A device's external power cables are not properly attached + NVML_ERROR_DRIVER_NOT_LOADED = 9, //!< NVIDIA driver is not loaded + NVML_ERROR_TIMEOUT = 10, //!< User provided timeout passed + NVML_ERROR_IRQ_ISSUE = 11, //!< NVIDIA Kernel detected an interrupt issue with a GPU + NVML_ERROR_LIBRARY_NOT_FOUND = 12, //!< NVML Shared Library couldn't be found or loaded + NVML_ERROR_FUNCTION_NOT_FOUND = 13, //!< Local version of NVML doesn't implement this function + NVML_ERROR_CORRUPTED_INFOROM = 14, //!< infoROM is corrupted + NVML_ERROR_GPU_IS_LOST = 15, //!< The GPU has fallen off the bus or has otherwise become inaccessible + NVML_ERROR_RESET_REQUIRED = 16, //!< The GPU requires a reset before it can be used again + NVML_ERROR_OPERATING_SYSTEM = 17, //!< The GPU control device has been blocked by the operating system/cgroups + NVML_ERROR_LIB_RM_VERSION_MISMATCH = 18, //!< RM detects a driver/library version mismatch + NVML_ERROR_IN_USE = 19, //!< An operation cannot be performed because the GPU is currently in use + NVML_ERROR_MEMORY = 20, //!< Insufficient memory + NVML_ERROR_NO_DATA = 21, //!< No data + NVML_ERROR_VGPU_ECC_NOT_SUPPORTED = 22, //!< The requested vgpu operation is not available on target device, becasue ECC is enabled + NVML_ERROR_INSUFFICIENT_RESOURCES = 23, //!< Ran out of critical resources, other than memory + NVML_ERROR_FREQ_NOT_SUPPORTED = 24, //!< Ran out of critical resources, other than memory + NVML_ERROR_ARGUMENT_VERSION_MISMATCH = 25, //!< The provided version is invalid/unsupported + NVML_ERROR_DEPRECATED = 26, //!< The requested functionality has been deprecated + NVML_ERROR_NOT_READY = 27, //!< The system is not ready for the request + NVML_ERROR_GPU_NOT_FOUND = 28, //!< No GPUs were found + NVML_ERROR_INVALID_STATE = 29, //!< Resource not in correct state to perform requested operation + NVML_ERROR_RESET_TYPE_NOT_SUPPORTED = 30, //!< Reset not supported for given device/parameters + NVML_ERROR_UNKNOWN = 999 //!< An internal driver error occurred +} nvmlReturn_t; + +/** + * See \ref nvmlDeviceGetMemoryErrorCounter + */ +typedef enum nvmlMemoryLocation_enum +{ + NVML_MEMORY_LOCATION_L1_CACHE = 0, //!< GPU L1 Cache + NVML_MEMORY_LOCATION_L2_CACHE = 1, //!< GPU L2 Cache + NVML_MEMORY_LOCATION_DRAM = 2, //!< Turing+ DRAM + NVML_MEMORY_LOCATION_DEVICE_MEMORY = 2, //!< GPU Device Memory + NVML_MEMORY_LOCATION_REGISTER_FILE = 3, //!< GPU Register File + NVML_MEMORY_LOCATION_TEXTURE_MEMORY = 4, //!< GPU Texture Memory + NVML_MEMORY_LOCATION_TEXTURE_SHM = 5, //!< Shared memory + NVML_MEMORY_LOCATION_CBU = 6, //!< CBU + NVML_MEMORY_LOCATION_SRAM = 7, //!< Turing+ SRAM + // Keep this last + NVML_MEMORY_LOCATION_COUNT //!< This counts the number of memory locations the driver knows about +} nvmlMemoryLocation_t; + +/** + * Causes for page retirement + */ +typedef enum nvmlPageRetirementCause_enum +{ + NVML_PAGE_RETIREMENT_CAUSE_MULTIPLE_SINGLE_BIT_ECC_ERRORS = 0, //!< Page was retired due to multiple single bit ECC error + NVML_PAGE_RETIREMENT_CAUSE_DOUBLE_BIT_ECC_ERROR = 1, //!< Page was retired due to double bit ECC error + + // Keep this last + NVML_PAGE_RETIREMENT_CAUSE_COUNT +} nvmlPageRetirementCause_t; + +/** + * API types that allow changes to default permission restrictions + */ +typedef enum nvmlRestrictedAPI_enum +{ + NVML_RESTRICTED_API_SET_APPLICATION_CLOCKS = 0, //!< APIs that change application clocks, see nvmlDeviceSetApplicationsClocks + //!< and see nvmlDeviceResetApplicationsClocks. + //!< Deprecated, keeping definition for backward compatibility. + NVML_RESTRICTED_API_SET_AUTO_BOOSTED_CLOCKS = 1, //!< APIs that enable/disable Auto Boosted clocks + //!< see nvmlDeviceSetAutoBoostedClocksEnabled + // Keep this last + NVML_RESTRICTED_API_COUNT +} nvmlRestrictedAPI_t; + +/** + * Structure to store utilization value and process Id + */ +typedef struct nvmlProcessUtilizationSample_st +{ + unsigned int pid; //!< PID of process + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value +} nvmlProcessUtilizationSample_t; + +/** + * Structure to store utilization value and process Id -- version 1 + */ +typedef struct +{ + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + unsigned int pid; //!< PID of process + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value + unsigned int jpgUtil; //!< Jpeg Util Value + unsigned int ofaUtil; //!< Ofa Util Value +} nvmlProcessUtilizationInfo_v1_t; + +/** + * Structure to store utilization and process ID for each running process -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int processSamplesCount; //!< Caller-supplied array size, and returns number of processes running + unsigned long long lastSeenTimeStamp; //!< Return only samples with timestamp greater than lastSeenTimeStamp + nvmlProcessUtilizationInfo_v1_t *procUtilArray; //!< The array (allocated by caller) of the utilization of GPU SM, framebuffer, video encoder, video decoder, JPEG, and OFA +} nvmlProcessesUtilizationInfo_v1_t; +typedef nvmlProcessesUtilizationInfo_v1_t nvmlProcessesUtilizationInfo_t; +#define nvmlProcessesUtilizationInfo_v1 NVML_STRUCT_VERSION(ProcessesUtilizationInfo, 1) + +/** + * Structure to store SRAM uncorrectable error counters + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned long long aggregateUncParity; //!< aggregate uncorrectable parity error count + unsigned long long aggregateUncSecDed; //!< aggregate uncorrectable SEC-DED error count + unsigned long long aggregateCor; //!< aggregate correctable error count + unsigned long long volatileUncParity; //!< volatile uncorrectable parity error count + unsigned long long volatileUncSecDed; //!< volatile uncorrectable SEC-DED error count + unsigned long long volatileCor; //!< volatile correctable error count + unsigned long long aggregateUncBucketL2; //!< aggregate uncorrectable error count for L2 cache bucket + unsigned long long aggregateUncBucketSm; //!< aggregate uncorrectable error count for SM bucket + unsigned long long aggregateUncBucketPcie; //!< aggregate uncorrectable error count for PCIE bucket + unsigned long long aggregateUncBucketMcu; //!< aggregate uncorrectable error count for Microcontroller bucket + unsigned long long aggregateUncBucketOther; //!< aggregate uncorrectable error count for Other bucket + unsigned int bThresholdExceeded; //!< if the error threshold of field diag is exceeded +} nvmlEccSramErrorStatus_v1_t; + +typedef nvmlEccSramErrorStatus_v1_t nvmlEccSramErrorStatus_t; +#define nvmlEccSramErrorStatus_v1 NVML_STRUCT_VERSION(EccSramErrorStatus, 1) + +/** + * Structure to store platform information + * + * @deprecated The nvmlPlatformInfo_v1_t will be deprecated in the subsequent releases. + * Use nvmlPlatformInfo_v2_t + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned char ibGuid[16]; //!< Infiniband GUID reported by platform (for Blackwell, ibGuid is 8 bytes so indices 8-15 are zero) + unsigned char rackGuid[16]; //!< GUID of the rack containing this GPU (for Blackwell rackGuid is 13 bytes so indices 13-15 are zero) + unsigned char chassisPhysicalSlotNumber; //!< The slot number in the rack containing this GPU (includes switches) + unsigned char computeSlotIndex; //!< The index within the compute slots in the rack containing this GPU (does not include switches) + unsigned char nodeIndex; //!< Index of the node within the slot containing this GPU + unsigned char peerType; //!< Platform indicated NVLink-peer type (e.g. switch present or not) + unsigned char moduleId; //!< ID of this GPU within the node +} nvmlPlatformInfo_v1_t; +#define nvmlPlatformInfo_v1 NVML_STRUCT_VERSION(PlatformInfo, 1) + +/** + * Structure to store platform information (v2) + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned char ibGuid[16]; //!< Infiniband GUID reported by platform (for Blackwell, ibGuid is 8 bytes so indices 8-15 are zero) + unsigned char chassisSerialNumber[16]; //!< Serial number of the chassis containing this GPU (for Blackwell it is 13 bytes so indices 13-15 are zero) + unsigned char slotNumber; //!< The slot number in the chassis containing this GPU (includes switches) + unsigned char trayIndex; //!< The tray index within the compute slots in the chassis containing this GPU (does not include switches) + unsigned char hostId; //!< Index of the node within the slot containing this GPU + unsigned char peerType; //!< Platform indicated NVLink-peer type (e.g. switch present or not) + unsigned char moduleId; //!< ID of this GPU within the node +} nvmlPlatformInfo_v2_t; + +typedef nvmlPlatformInfo_v2_t nvmlPlatformInfo_t; +#define nvmlPlatformInfo_v2 NVML_STRUCT_VERSION(PlatformInfo, 2) + +/** + * Structure to store hostname information + */ +#define NVML_DEVICE_HOSTNAME_BUFFER_SIZE 64 + +typedef struct +{ + char value[NVML_DEVICE_HOSTNAME_BUFFER_SIZE]; //!< null-terminated hostname string +} nvmlHostname_v1_t; + +typedef struct +{ + unsigned int unit; //!< the SRAM unit index + unsigned int location; //!< the error location within the SRAM unit + unsigned int sublocation; //!< the error sublocation within the SRAM unit + unsigned int extlocation; //!< the error extlocation within the SRAM unit + unsigned int address; //!< the error address within the SRAM unit + unsigned int isParity; //!< if the SRAM error is parity or not + unsigned int count; //!< the error count at the same SRAM address +} nvmlEccSramUniqueUncorrectedErrorEntry_v1_t; + +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int entryCount; //!< the number of error count entries + nvmlEccSramUniqueUncorrectedErrorEntry_v1_t *entries; //!< pointer to caller-supplied buffer to return the SRAM unique uncorrected ECC error count entries +} nvmlEccSramUniqueUncorrectedErrorCounts_v1_t; + +typedef nvmlEccSramUniqueUncorrectedErrorCounts_v1_t nvmlEccSramUniqueUncorrectedErrorCounts_t; +#define nvmlEccSramUniqueUncorrectedErrorCounts_v1 NVML_STRUCT_VERSION(EccSramUniqueUncorrectedErrorCounts, 1) + +/** + * GSP firmware + */ +#define NVML_GSP_FIRMWARE_VERSION_BUF_SIZE 0x40 + +/** + * Simplified chip architecture + */ +#define NVML_DEVICE_ARCH_KEPLER 2 // Devices based on the NVIDIA Kepler architecture +#define NVML_DEVICE_ARCH_MAXWELL 3 // Devices based on the NVIDIA Maxwell architecture +#define NVML_DEVICE_ARCH_PASCAL 4 // Devices based on the NVIDIA Pascal architecture +#define NVML_DEVICE_ARCH_VOLTA 5 // Devices based on the NVIDIA Volta architecture +#define NVML_DEVICE_ARCH_TURING 6 // Devices based on the NVIDIA Turing architecture +#define NVML_DEVICE_ARCH_AMPERE 7 // Devices based on the NVIDIA Ampere architecture +#define NVML_DEVICE_ARCH_ADA 8 // Devices based on the NVIDIA Ada architecture +#define NVML_DEVICE_ARCH_HOPPER 9 // Devices based on the NVIDIA Hopper architecture + +#define NVML_DEVICE_ARCH_BLACKWELL 10 // Devices based on the NVIDIA Blackwell architecture + +#define NVML_DEVICE_ARCH_UNKNOWN 0xffffffff // Anything else, presumably something newer + +typedef unsigned int nvmlDeviceArchitecture_t; + +/** + * PCI bus types + */ +#define NVML_BUS_TYPE_UNKNOWN 0 +#define NVML_BUS_TYPE_PCI 1 +#define NVML_BUS_TYPE_PCIE 2 +#define NVML_BUS_TYPE_FPCI 3 +#define NVML_BUS_TYPE_AGP 4 + +typedef unsigned int nvmlBusType_t; + +/** + * Device Power Modes + */ + +/** + * Device Fan control policy + */ +#define NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW 0 +#define NVML_FAN_POLICY_MANUAL 1 + +typedef unsigned int nvmlFanControlPolicy_t; + +/** + * Device Power Source + */ +#define NVML_POWER_SOURCE_AC 0x00000000 +#define NVML_POWER_SOURCE_BATTERY 0x00000001 +#define NVML_POWER_SOURCE_UNDERSIZED 0x00000002 + +typedef unsigned int nvmlPowerSource_t; + +/** + * Device PCIE link Max Speed + */ +#define NVML_PCIE_LINK_MAX_SPEED_INVALID 0x00000000 +#define NVML_PCIE_LINK_MAX_SPEED_2500MBPS 0x00000001 +#define NVML_PCIE_LINK_MAX_SPEED_5000MBPS 0x00000002 +#define NVML_PCIE_LINK_MAX_SPEED_8000MBPS 0x00000003 +#define NVML_PCIE_LINK_MAX_SPEED_16000MBPS 0x00000004 +#define NVML_PCIE_LINK_MAX_SPEED_32000MBPS 0x00000005 +#define NVML_PCIE_LINK_MAX_SPEED_64000MBPS 0x00000006 + +/** + * Adaptive clocking status + */ +#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED 0x00000000 +#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED 0x00000001 + +#define NVML_MAX_GPU_UTILIZATIONS 8 + +/** + * Represents the GPU utilization domains + */ +typedef enum nvmlGpuUtilizationDomainId_t +{ + NVML_GPU_UTILIZATION_DOMAIN_GPU = 0, //!< Graphics engine domain + NVML_GPU_UTILIZATION_DOMAIN_FB = 1, //!< Frame buffer domain + NVML_GPU_UTILIZATION_DOMAIN_VID = 2, //!< Video engine domain + NVML_GPU_UTILIZATION_DOMAIN_BUS = 3, //!< Bus interface domain +} nvmlGpuUtilizationDomainId_t; + +typedef struct nvmlGpuDynamicPstatesInfo_st +{ + unsigned int flags; //!< Reserved for future use + struct + { + unsigned int bIsPresent; //!< Set if this utilization domain is present on this GPU + unsigned int percentage; //!< Percentage of time where the domain is considered busy in the last 1-second interval + unsigned int incThreshold; //!< Utilization threshold that can trigger a perf-increasing P-State change when crossed + unsigned int decThreshold; //!< Utilization threshold that can trigger a perf-decreasing P-State change when crossed + } utilization[NVML_MAX_GPU_UTILIZATIONS]; +} nvmlGpuDynamicPstatesInfo_t; + +/* + * PCIe outbound/inbound atomic operations capability + */ +#define NVML_PCIE_ATOMICS_CAP_FETCHADD32 0x01 +#define NVML_PCIE_ATOMICS_CAP_FETCHADD64 0x02 +#define NVML_PCIE_ATOMICS_CAP_SWAP32 0x04 +#define NVML_PCIE_ATOMICS_CAP_SWAP64 0x08 +#define NVML_PCIE_ATOMICS_CAP_CAS32 0x10 +#define NVML_PCIE_ATOMICS_CAP_CAS64 0x20 +#define NVML_PCIE_ATOMICS_CAP_CAS128 0x40 +#define NVML_PCIE_ATOMICS_OPS_MAX 7 + +/** + * Device Scope - This is useful to retrieve the telemetry at GPU and module (e.g. GPU + CPU) level + */ +#define NVML_POWER_SCOPE_GPU 0U //!< Targets only GPU +#define NVML_POWER_SCOPE_MODULE 1U //!< Targets the whole module +#define NVML_POWER_SCOPE_MEMORY 2U //!< Targets the GPU Memory + +typedef unsigned char nvmlPowerScopeType_t; + +/** + * Contains the power management limit + */ +typedef struct +{ + unsigned int version; //!< Structure format version (must be 1) + nvmlPowerScopeType_t powerScope; //!< [in] Device type: GPU or Total Module + unsigned int powerValueMw; //!< [out] Power value to retrieve or set in milliwatts +} nvmlPowerValue_v2_t; + +#define nvmlPowerValue_v2 NVML_STRUCT_VERSION(PowerValue, 2) + +/** @} */ + +/***************************************************************************************************/ +/** @addtogroup virtualGPU vGPU Enums, Constants, Structs + * @{ + */ +/***************************************************************************************************/ +/** @defgroup nvmlVirtualGpuEnums vGPU Enums + * @{ + */ +/***************************************************************************************************/ + +/*! + * GPU virtualization mode types. + */ +typedef enum nvmlGpuVirtualizationMode { + NVML_GPU_VIRTUALIZATION_MODE_NONE = 0, //!< Represents Bare Metal GPU + NVML_GPU_VIRTUALIZATION_MODE_PASSTHROUGH = 1, //!< Device is associated with GPU-Passthorugh + NVML_GPU_VIRTUALIZATION_MODE_VGPU = 2, //!< Device is associated with vGPU inside virtual machine. + NVML_GPU_VIRTUALIZATION_MODE_HOST_VGPU = 3, //!< Device is associated with VGX hypervisor in vGPU mode + NVML_GPU_VIRTUALIZATION_MODE_HOST_VSGA = 4 //!< Device is associated with VGX hypervisor in vSGA mode +} nvmlGpuVirtualizationMode_t; + +/** + * Host vGPU modes + */ +typedef enum nvmlHostVgpuMode_enum +{ + NVML_HOST_VGPU_MODE_NON_SRIOV = 0, //!< Non SR-IOV mode + NVML_HOST_VGPU_MODE_SRIOV = 1 //!< SR-IOV mode +} nvmlHostVgpuMode_t; + +/*! + * Types of VM identifiers + */ +typedef enum nvmlVgpuVmIdType { + NVML_VGPU_VM_ID_DOMAIN_ID = 0, //!< VM ID represents DOMAIN ID + NVML_VGPU_VM_ID_UUID = 1 //!< VM ID represents UUID +} nvmlVgpuVmIdType_t; + +/** + * vGPU GUEST info state + */ +typedef enum nvmlVgpuGuestInfoState_enum +{ + NVML_VGPU_INSTANCE_GUEST_INFO_STATE_UNINITIALIZED = 0, //!< Guest-dependent fields uninitialized + NVML_VGPU_INSTANCE_GUEST_INFO_STATE_INITIALIZED = 1 //!< Guest-dependent fields initialized +} nvmlVgpuGuestInfoState_t; + +/** + * vGPU software licensable features + */ +typedef enum { + NVML_GRID_LICENSE_FEATURE_CODE_UNKNOWN = 0, //!< Unknown + NVML_GRID_LICENSE_FEATURE_CODE_VGPU = 1, //!< Virtual GPU + NVML_GRID_LICENSE_FEATURE_CODE_NVIDIA_RTX = 2, //!< Nvidia RTX + NVML_GRID_LICENSE_FEATURE_CODE_VWORKSTATION = NVML_GRID_LICENSE_FEATURE_CODE_NVIDIA_RTX, //!< Deprecated, do not use. + NVML_GRID_LICENSE_FEATURE_CODE_GAMING = 3, //!< Gaming + NVML_GRID_LICENSE_FEATURE_CODE_COMPUTE = 4 //!< Compute +} nvmlGridLicenseFeatureCode_t; + +/** + * Status codes for license expiry + */ +#define NVML_GRID_LICENSE_EXPIRY_NOT_AVAILABLE 0 //!< Expiry information not available +#define NVML_GRID_LICENSE_EXPIRY_INVALID 1 //!< Invalid expiry or error fetching expiry +#define NVML_GRID_LICENSE_EXPIRY_VALID 2 //!< Valid expiry +#define NVML_GRID_LICENSE_EXPIRY_NOT_APPLICABLE 3 //!< Expiry not applicable +#define NVML_GRID_LICENSE_EXPIRY_PERMANENT 4 //!< Permanent expiry + +/** + * vGPU queryable capabilities + */ +typedef enum nvmlVgpuCapability_enum +{ + NVML_VGPU_CAP_NVLINK_P2P = 0, //!< P2P over NVLink is supported + NVML_VGPU_CAP_GPUDIRECT = 1, //!< GPUDirect capability is supported + NVML_VGPU_CAP_MULTI_VGPU_EXCLUSIVE = 2, //!< vGPU profile cannot be mixed with other vGPU profiles in same VM + NVML_VGPU_CAP_EXCLUSIVE_TYPE = 3, //!< vGPU profile cannot run on a GPU alongside other profiles of different type + NVML_VGPU_CAP_EXCLUSIVE_SIZE = 4, //!< vGPU profile cannot run on a GPU alongside other profiles of different size + // Keep this last + NVML_VGPU_CAP_COUNT +} nvmlVgpuCapability_t; + +/** +* vGPU driver queryable capabilities +*/ +typedef enum nvmlVgpuDriverCapability_enum +{ + NVML_VGPU_DRIVER_CAP_HETEROGENEOUS_MULTI_VGPU = 0, //!< Supports mixing of different vGPU profiles within one guest VM + NVML_VGPU_DRIVER_CAP_WARM_UPDATE = 1, //!< Supports FSR and warm update of vGPU host driver without terminating the running guest VM + // Keep this last + NVML_VGPU_DRIVER_CAP_COUNT +} nvmlVgpuDriverCapability_t; + +/** +* Device vGPU queryable capabilities +*/ +typedef enum nvmlDeviceVgpuCapability_enum +{ + NVML_DEVICE_VGPU_CAP_FRACTIONAL_MULTI_VGPU = 0, //!< Query whether the fractional vGPU profiles on this GPU can be used in multi-vGPU configurations + NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_PROFILES = 1, //!< Query whether the GPU support concurrent execution of timesliced vGPU profiles of differing types + NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_SIZES = 2, //!< Query whether the GPU support concurrent execution of timesliced vGPU profiles of differing framebuffer sizes + NVML_DEVICE_VGPU_CAP_READ_DEVICE_BUFFER_BW = 3, //!< Query the GPU's read_device_buffer expected bandwidth capacity in megabytes per second + NVML_DEVICE_VGPU_CAP_WRITE_DEVICE_BUFFER_BW = 4, //!< Query the GPU's write_device_buffer expected bandwidth capacity in megabytes per second + NVML_DEVICE_VGPU_CAP_DEVICE_STREAMING = 5, //!< Query whether the vGPU profiles on the GPU supports migration data streaming + NVML_DEVICE_VGPU_CAP_MINI_QUARTER_GPU = 6, //!< Set/Get support for mini-quarter vGPU profiles + NVML_DEVICE_VGPU_CAP_COMPUTE_MEDIA_ENGINE_GPU = 7, //!< Set/Get support for compute media engine vGPU profiles + NVML_DEVICE_VGPU_CAP_WARM_UPDATE = 8, //!< Query whether the GPU supports FSR and warm update + NVML_DEVICE_VGPU_CAP_HOMOGENEOUS_PLACEMENTS = 9, //!< Query whether the GPU supports reporting of placements of timesliced vGPU profiles with identical framebuffer sizes + NVML_DEVICE_VGPU_CAP_MIG_TIMESLICING_SUPPORTED = 10, //!< Query whether the GPU supports timesliced vGPU on MIG + NVML_DEVICE_VGPU_CAP_MIG_TIMESLICING_ENABLED = 11, //!< Set/Get MIG timesliced mode reporting, without impacting the underlying functionality + // Keep this last + NVML_DEVICE_VGPU_CAP_COUNT +} nvmlDeviceVgpuCapability_t; + +/** @} */ + +/***************************************************************************************************/ + +/** @defgroup nvmlVgpuConstants vGPU Constants + * @{ + */ +/***************************************************************************************************/ + +/** + * Buffer size guaranteed to be large enough for \ref nvmlVgpuTypeGetLicense + */ +#define NVML_GRID_LICENSE_BUFFER_SIZE 128 + +#define NVML_VGPU_NAME_BUFFER_SIZE 64 + +#define NVML_GRID_LICENSE_FEATURE_MAX_COUNT 3 + +#define INVALID_GPU_INSTANCE_PROFILE_ID 0xFFFFFFFF + +#define INVALID_GPU_INSTANCE_ID 0xFFFFFFFF + +#define NVML_INVALID_VGPU_PLACEMENT_ID 0xFFFF + +/*! + * Macros for vGPU instance's virtualization capabilities bitfield. + */ +#define NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION 0:0 +#define NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_NO 0x0 +#define NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_YES 0x1 + +/*! + * Macros for pGPU's virtualization capabilities bitfield. + */ +#define NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION 0:0 +#define NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_NO 0x0 +#define NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_YES 0x1 + +/** + * Macros to indicate the vGPU mode of the GPU. + */ +#define NVML_VGPU_PGPU_HETEROGENEOUS_MODE 0 +#define NVML_VGPU_PGPU_HOMOGENEOUS_MODE 1 + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVgpuStructs vGPU Structs + * @{ + */ +/***************************************************************************************************/ + +typedef unsigned int nvmlVgpuTypeId_t; + +typedef unsigned int nvmlVgpuInstance_t; + +/** + * Structure to store the vGPU heterogeneous mode of device -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int mode; //!< The vGPU heterogeneous mode +} nvmlVgpuHeterogeneousMode_v1_t; +typedef nvmlVgpuHeterogeneousMode_v1_t nvmlVgpuHeterogeneousMode_t; +#define nvmlVgpuHeterogeneousMode_v1 NVML_STRUCT_VERSION(VgpuHeterogeneousMode, 1) + +/** + * Structure to store the placement ID of vGPU instance -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int placementId; //!< Placement ID of the active vGPU instance +} nvmlVgpuPlacementId_v1_t; +typedef nvmlVgpuPlacementId_v1_t nvmlVgpuPlacementId_t; +#define nvmlVgpuPlacementId_v1 NVML_STRUCT_VERSION(VgpuPlacementId, 1) + +/** + * Structure to store the list of vGPU placements -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int placementSize; //!< The number of slots occupied by the vGPU type + unsigned int count; //!< Count of placement IDs fetched + unsigned int *placementIds; //!< Placement IDs for the vGPU type +} nvmlVgpuPlacementList_v1_t; +#define nvmlVgpuPlacementList_v1 NVML_STRUCT_VERSION(VgpuPlacementList, 1) + +/** + * Structure to store the list of vGPU placements -- version 2 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int placementSize; //!< OUT: The number of slots occupied by the vGPU type + unsigned int count; //!< IN/OUT: Count of the placement IDs + unsigned int *placementIds; //!< IN/OUT: Placement IDs for the vGPU type + unsigned int mode; //!< IN: The vGPU mode. Either NVML_VGPU_PGPU_HETEROGENEOUS_MODE or NVML_VGPU_PGPU_HOMOGENEOUS_MODE +} nvmlVgpuPlacementList_v2_t; +typedef nvmlVgpuPlacementList_v2_t nvmlVgpuPlacementList_t; +#define nvmlVgpuPlacementList_v2 NVML_STRUCT_VERSION(VgpuPlacementList, 2) + +/** + * Structure to store BAR1 size information of vGPU type -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned long long bar1Size; //!< BAR1 size in megabytes +} nvmlVgpuTypeBar1Info_v1_t; +typedef nvmlVgpuTypeBar1Info_v1_t nvmlVgpuTypeBar1Info_t; +#define nvmlVgpuTypeBar1Info_v1 NVML_STRUCT_VERSION(VgpuTypeBar1Info, 1) + +/** + * Structure to store Utilization Value and vgpuInstance + */ +typedef struct nvmlVgpuInstanceUtilizationSample_st +{ + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlValue_t smUtil; //!< SM (3D/Compute) Util Value + nvmlValue_t memUtil; //!< Frame Buffer Memory Util Value + nvmlValue_t encUtil; //!< Encoder Util Value + nvmlValue_t decUtil; //!< Decoder Util Value +} nvmlVgpuInstanceUtilizationSample_t; + +/** + * Structure to store Utilization Value and vgpuInstance Info -- Version 1 + */ +typedef struct +{ + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + nvmlValue_t smUtil; //!< SM (3D/Compute) Util Value + nvmlValue_t memUtil; //!< Frame Buffer Memory Util Value + nvmlValue_t encUtil; //!< Encoder Util Value + nvmlValue_t decUtil; //!< Decoder Util Value + nvmlValue_t jpgUtil; //!< Jpeg Util Value + nvmlValue_t ofaUtil; //!< Ofa Util Value +} nvmlVgpuInstanceUtilizationInfo_v1_t; + +/** + * Structure to store recent utilization for vGPU instances running on a device -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + nvmlValueType_t sampleValType; //!< Hold the type of returned sample values + unsigned int vgpuInstanceCount; //!< Hold the number of vGPU instances + unsigned long long lastSeenTimeStamp; //!< Return only samples with timestamp greater than lastSeenTimeStamp + nvmlVgpuInstanceUtilizationInfo_v1_t *vgpuUtilArray; //!< The array (allocated by caller) in which vGPU utilization are returned +} nvmlVgpuInstancesUtilizationInfo_v1_t; +typedef nvmlVgpuInstancesUtilizationInfo_v1_t nvmlVgpuInstancesUtilizationInfo_t; +#define nvmlVgpuInstancesUtilizationInfo_v1 NVML_STRUCT_VERSION(VgpuInstancesUtilizationInfo, 1) + +/** + * Structure to store Utilization Value, vgpuInstance and subprocess information + */ +typedef struct nvmlVgpuProcessUtilizationSample_st +{ + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + unsigned int pid; //!< PID of process running within the vGPU VM + char processName[NVML_VGPU_NAME_BUFFER_SIZE]; //!< Name of process running within the vGPU VM + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value +} nvmlVgpuProcessUtilizationSample_t; + +/** + * Structure to store Utilization Value, vgpuInstance and subprocess information for process running on vGPU instance -- version 1 + */ +typedef struct +{ + char processName[NVML_VGPU_NAME_BUFFER_SIZE]; //!< Name of process running within the vGPU VM + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + unsigned int pid; //!< PID of process running within the vGPU VM + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value + unsigned int jpgUtil; //!< Jpeg Util Value + unsigned int ofaUtil; //!< Ofa Util Value +} nvmlVgpuProcessUtilizationInfo_v1_t; + +/** + * Structure to store recent utilization, vgpuInstance and subprocess information for processes running on vGPU instances active on a device -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int vgpuProcessCount; //!< Hold the number of processes running on vGPU instances + unsigned long long lastSeenTimeStamp; //!< Return only samples with timestamp greater than lastSeenTimeStamp + nvmlVgpuProcessUtilizationInfo_v1_t *vgpuProcUtilArray; //!< The array (allocated by caller) in which utilization of processes running on vGPU instances are returned +} nvmlVgpuProcessesUtilizationInfo_v1_t; +typedef nvmlVgpuProcessesUtilizationInfo_v1_t nvmlVgpuProcessesUtilizationInfo_t; +#define nvmlVgpuProcessesUtilizationInfo_v1 NVML_STRUCT_VERSION(VgpuProcessesUtilizationInfo, 1) + +/** + * Structure to store the information of vGPU runtime state -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned long long size; //!< OUT: The runtime state size of the vGPU instance +} nvmlVgpuRuntimeState_v1_t; +typedef nvmlVgpuRuntimeState_v1_t nvmlVgpuRuntimeState_t; +#define nvmlVgpuRuntimeState_v1 NVML_STRUCT_VERSION(VgpuRuntimeState, 1) + +/** + * vGPU scheduler policies + */ +#define NVML_VGPU_SCHEDULER_POLICY_UNKNOWN 0 +#define NVML_VGPU_SCHEDULER_POLICY_BEST_EFFORT 1 +#define NVML_VGPU_SCHEDULER_POLICY_EQUAL_SHARE 2 +#define NVML_VGPU_SCHEDULER_POLICY_FIXED_SHARE 3 + +#define NVML_SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT 3 + +#define NVML_SCHEDULER_SW_MAX_LOG_ENTRIES 200 + +#define NVML_VGPU_SCHEDULER_ARR_DEFAULT 0 +#define NVML_VGPU_SCHEDULER_ARR_DISABLE 1 +#define NVML_VGPU_SCHEDULER_ARR_ENABLE 2 + +/** + * vGPU scheduler engine types + */ +#define NVML_VGPU_SCHEDULER_ENGINE_TYPE_GRAPHICS 1 + +/** + * Union to represent the vGPU Scheduler Parameters + */ +typedef union +{ + struct + { + unsigned int avgFactor; //!< Average factor in compensating the timeslice for Adaptive Round Robin mode + unsigned int timeslice; //!< The timeslice in ns for each software run list as configured, or the default value otherwise + } vgpuSchedDataWithARR; + + struct + { + unsigned int timeslice; //!< The timeslice in ns for each software run list as configured, or the default value otherwise + } vgpuSchedData; + +} nvmlVgpuSchedulerParams_t; + +/** + * Structure to store the state and logs of a software runlist + */ +typedef struct nvmlVgpuSchedulerLogEntries_st +{ + unsigned long long timestamp; //!< Timestamp in ns when this software runlist was preeempted + unsigned long long timeRunTotal; //!< Total time in ns this software runlist has run + unsigned long long timeRun; //!< Time in ns this software runlist ran before preemption + unsigned int swRunlistId; //!< Software runlist Id + unsigned long long targetTimeSlice; //!< The actual timeslice after deduction + unsigned long long cumulativePreemptionTime; //!< Preemption time in ns for this SW runlist +} nvmlVgpuSchedulerLogEntry_t; + +/** + * Structure to store a vGPU software scheduler log + */ +typedef struct nvmlVgpuSchedulerLog_st +{ + unsigned int engineId; //!< Engine whose software runlist log entries are fetched + unsigned int schedulerPolicy; //!< Scheduler policy + unsigned int arrMode; //!< Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; + unsigned int entriesCount; //!< Count of log entries fetched + nvmlVgpuSchedulerLogEntry_t logEntries[NVML_SCHEDULER_SW_MAX_LOG_ENTRIES]; +} nvmlVgpuSchedulerLog_t; + +/** + * Structure to store the vGPU scheduler state + */ +typedef struct nvmlVgpuSchedulerGetState_st +{ + unsigned int schedulerPolicy; //!< Scheduler policy + unsigned int arrMode; //!< Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; +} nvmlVgpuSchedulerGetState_t; + +/** + * Union to represent the vGPU Scheduler set Parameters + */ +typedef union +{ + struct + { + unsigned int avgFactor; //!< Average factor in compensating the timeslice for Adaptive Round Robin mode + unsigned int frequency; //!< Frequency for Adaptive Round Robin mode + } vgpuSchedDataWithARR; + + struct + { + unsigned int timeslice; //!< The timeslice in ns(Nanoseconds) for each software run list as configured, or the default value otherwise + } vgpuSchedData; + +} nvmlVgpuSchedulerSetParams_t; + +/** + * Structure to set the vGPU scheduler state + */ +typedef struct nvmlVgpuSchedulerSetState_st +{ + unsigned int schedulerPolicy; //!< Scheduler policy + unsigned int enableARRMode; //!< Adaptive Round Robin scheduler + nvmlVgpuSchedulerSetParams_t schedulerParams; +} nvmlVgpuSchedulerSetState_t; + +/** + * Structure to store the vGPU scheduler capabilities + */ +typedef struct nvmlVgpuSchedulerCapabilities_st +{ + unsigned int supportedSchedulers[NVML_SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT]; //!< List the supported vGPU schedulers on the device + unsigned int maxTimeslice; //!< Maximum timeslice value in ns + unsigned int minTimeslice; //!< Minimum timeslice value in ns + unsigned int isArrModeSupported; //!< Flag to check Adaptive Round Robin mode enabled/disabled. + unsigned int maxFrequencyForARR; //!< Maximum frequency for Adaptive Round Robin mode + unsigned int minFrequencyForARR; //!< Minimum frequency for Adaptive Round Robin mode + unsigned int maxAvgFactorForARR; //!< Maximum averaging factor for Adaptive Round Robin mode + unsigned int minAvgFactorForARR; //!< Minimum averaging factor for Adaptive Round Robin mode +} nvmlVgpuSchedulerCapabilities_t; + +/** + * Structure to store the vGPU license expiry details + */ +typedef struct nvmlVgpuLicenseExpiry_st +{ + unsigned int year; //!< Year of license expiry + unsigned short month; //!< Month of license expiry + unsigned short day; //!< Day of license expiry + unsigned short hour; //!< Hour of license expiry + unsigned short min; //!< Minutes of license expiry + unsigned short sec; //!< Seconds of license expiry + unsigned char status; //!< License expiry status +} nvmlVgpuLicenseExpiry_t; + +/** + * vGPU license state + */ +#define NVML_GRID_LICENSE_STATE_UNKNOWN 0 //!< Unknown state +#define NVML_GRID_LICENSE_STATE_UNINITIALIZED 1 //!< Uninitialized state +#define NVML_GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED 2 //!< Unlicensed unrestricted state +#define NVML_GRID_LICENSE_STATE_UNLICENSED_RESTRICTED 3 //!< Unlicensed restricted state +#define NVML_GRID_LICENSE_STATE_UNLICENSED 4 //!< Unlicensed state +#define NVML_GRID_LICENSE_STATE_LICENSED 5 //!< Licensed state + +typedef struct nvmlVgpuLicenseInfo_st +{ + unsigned char isLicensed; //!< License status + nvmlVgpuLicenseExpiry_t licenseExpiry; //!< License expiry information + unsigned int currentState; //!< Current license state +} nvmlVgpuLicenseInfo_t; + +/** + * Structure to store license expiry date and time values + */ +typedef struct nvmlGridLicenseExpiry_st +{ + unsigned int year; //!< Year value of license expiry + unsigned short month; //!< Month value of license expiry + unsigned short day; //!< Day value of license expiry + unsigned short hour; //!< Hour value of license expiry + unsigned short min; //!< Minutes value of license expiry + unsigned short sec; //!< Seconds value of license expiry + unsigned char status; //!< License expiry status +} nvmlGridLicenseExpiry_t; + +/** + * Structure containing vGPU software licensable feature information + */ +typedef struct nvmlGridLicensableFeature_st +{ + nvmlGridLicenseFeatureCode_t featureCode; //!< Licensed feature code + unsigned int featureState; //!< Non-zero if feature is currently licensed, otherwise zero + char licenseInfo[NVML_GRID_LICENSE_BUFFER_SIZE]; //!< Deprecated. + char productName[NVML_GRID_LICENSE_BUFFER_SIZE]; //!< Product name of feature + unsigned int featureEnabled; //!< Non-zero if feature is enabled, otherwise zero + nvmlGridLicenseExpiry_t licenseExpiry; //!< License expiry structure containing date and time +} nvmlGridLicensableFeature_t; + +/** + * Structure to store vGPU software licensable features + */ +typedef struct nvmlGridLicensableFeatures_st +{ + int isGridLicenseSupported; //!< Non-zero if vGPU Software Licensing is supported on the system, otherwise zero + unsigned int licensableFeaturesCount; //!< Entries returned in \a gridLicensableFeatures array + nvmlGridLicensableFeature_t gridLicensableFeatures[NVML_GRID_LICENSE_FEATURE_MAX_COUNT]; //!< Array of vGPU software licensable features. +} nvmlGridLicensableFeatures_t; + +/** + * Enum describing the GPU Recovery Action + */ +typedef enum nvmlDeviceGpuRecoveryAction_s { + NVML_GPU_RECOVERY_ACTION_NONE = 0, + NVML_GPU_RECOVERY_ACTION_GPU_RESET = 1, + NVML_GPU_RECOVERY_ACTION_NODE_REBOOT = 2, + NVML_GPU_RECOVERY_ACTION_DRAIN_P2P = 3, + NVML_GPU_RECOVERY_ACTION_DRAIN_AND_RESET = 4, +} nvmlDeviceGpuRecoveryAction_t; + +/** + * Structure to store the vGPU type IDs -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int vgpuCount; //!< IN/OUT: Number of vGPU types + nvmlVgpuTypeId_t *vgpuTypeIds; //!< OUT: List of vGPU type IDs +} nvmlVgpuTypeIdInfo_v1_t; +typedef nvmlVgpuTypeIdInfo_v1_t nvmlVgpuTypeIdInfo_t; +#define nvmlVgpuTypeIdInfo_v1 NVML_STRUCT_VERSION(VgpuTypeIdInfo, 1) + +/** + * Structure to store the maximum number of possible vGPU type IDs -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + nvmlVgpuTypeId_t vgpuTypeId; //!< IN: Handle to vGPU type + unsigned int maxInstancePerGI; //!< OUT: Maximum number of vGPU instances per GPU instance +} nvmlVgpuTypeMaxInstance_v1_t; +typedef nvmlVgpuTypeMaxInstance_v1_t nvmlVgpuTypeMaxInstance_t; +#define nvmlVgpuTypeMaxInstance_v1 NVML_STRUCT_VERSION(VgpuTypeMaxInstance, 1) + +/** + * Structure to store active vGPU instance information -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int vgpuCount; //!< IN/OUT: Count of the active vGPU instances + nvmlVgpuInstance_t *vgpuInstances; //!< IN/OUT: list of active vGPU instances +} nvmlActiveVgpuInstanceInfo_v1_t; +typedef nvmlActiveVgpuInstanceInfo_v1_t nvmlActiveVgpuInstanceInfo_t; +#define nvmlActiveVgpuInstanceInfo_v1 NVML_STRUCT_VERSION(ActiveVgpuInstanceInfo, 1) + +/** + * Structure to set vGPU scheduler state information -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int engineId; //!< IN: One of NVML_VGPU_SCHEDULER_ENGINE_TYPE_*. + unsigned int schedulerPolicy; //!< IN: Scheduler policy + unsigned int enableARRMode; //!< IN: Adaptive Round Robin scheduler + nvmlVgpuSchedulerSetParams_t schedulerParams; //!< IN: vGPU Scheduler Parameters +} nvmlVgpuSchedulerState_v1_t; +typedef nvmlVgpuSchedulerState_v1_t nvmlVgpuSchedulerState_t; +#define nvmlVgpuSchedulerState_v1 NVML_STRUCT_VERSION(VgpuSchedulerState, 1) + +/** + * Structure to store vGPU scheduler state information -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int engineId; //!< IN: Engine whose software scheduler state info is fetched. One of NVML_VGPU_SCHEDULER_ENGINE_TYPE_*. + unsigned int schedulerPolicy; //!< OUT: Scheduler policy + unsigned int arrMode; //!< OUT: Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; //!< OUT: vGPU Scheduler Parameters +} nvmlVgpuSchedulerStateInfo_v1_t; +typedef nvmlVgpuSchedulerStateInfo_v1_t nvmlVgpuSchedulerStateInfo_t; +#define nvmlVgpuSchedulerStateInfo_v1 NVML_STRUCT_VERSION(VgpuSchedulerStateInfo, 1) + +/** + * Structure to store vGPU scheduler log information -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int engineId; //!< IN: Engine whose software runlist log entries are fetched. One of One of NVML_VGPU_SCHEDULER_ENGINE_TYPE_*. + unsigned int schedulerPolicy; //!< OUT: Scheduler policy + unsigned int arrMode; //!< OUT: Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; //!< OUT: vGPU Scheduler Parameters + unsigned int entriesCount; //!< OUT: Count of log entries fetched + nvmlVgpuSchedulerLogEntry_t logEntries[NVML_SCHEDULER_SW_MAX_LOG_ENTRIES]; //!< OUT: Structure to store the state and logs of a software runlist +} nvmlVgpuSchedulerLogInfo_v1_t; +typedef nvmlVgpuSchedulerLogInfo_v1_t nvmlVgpuSchedulerLogInfo_t; +#define nvmlVgpuSchedulerLogInfo_v1 NVML_STRUCT_VERSION(VgpuSchedulerLogInfo, 1) + +/** + * Structure to store creatable vGPU placement information -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + nvmlVgpuTypeId_t vgpuTypeId; //!< IN: Handle to vGPU type + unsigned int count; //!< IN/OUT: Count of the placement IDs + unsigned int *placementIds; //!< IN/OUT: Placement IDs for the vGPU type + unsigned int placementSize; //!< OUT: The number of slots occupied by the vGPU type +} nvmlVgpuCreatablePlacementInfo_v1_t; +typedef nvmlVgpuCreatablePlacementInfo_v1_t nvmlVgpuCreatablePlacementInfo_t; +#define nvmlVgpuCreatablePlacementInfo_v1 NVML_STRUCT_VERSION(VgpuCreatablePlacementInfo, 1) + +/** @} */ +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFieldValueEnums Field Value Enums + * @{ + */ +/***************************************************************************************************/ + +/** + * Field Identifiers. + * + * All Identifiers pertain to a device. Each ID is only used once and is guaranteed never to change. + */ +#define NVML_FI_DEV_ECC_CURRENT 1 //!< Current ECC mode. 1=Active. 0=Inactive +#define NVML_FI_DEV_ECC_PENDING 2 //!< Pending ECC mode. 1=Active. 0=Inactive +/* ECC Count Totals */ +#define NVML_FI_DEV_ECC_SBE_VOL_TOTAL 3 //!< Total single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_TOTAL 4 //!< Total double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_TOTAL 5 //!< Total single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_TOTAL 6 //!< Total double bit aggregate (persistent) ECC errors +/* Individual ECC locations */ +#define NVML_FI_DEV_ECC_SBE_VOL_L1 7 //!< L1 cache single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_L1 8 //!< L1 cache double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_L2 9 //!< L2 cache single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_L2 10 //!< L2 cache double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_DEV 11 //!< Device memory single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_DEV 12 //!< Device memory double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_REG 13 //!< Register file single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_REG 14 //!< Register file double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_TEX 15 //!< Texture memory single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_TEX 16 //!< Texture memory double bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_CBU 17 //!< CBU double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_L1 18 //!< L1 cache single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_L1 19 //!< L1 cache double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_L2 20 //!< L2 cache single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_L2 21 //!< L2 cache double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_DEV 22 //!< Device memory single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_DEV 23 //!< Device memory double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_REG 24 //!< Register File single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_REG 25 //!< Register File double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_TEX 26 //!< Texture memory single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_TEX 27 //!< Texture memory double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_CBU 28 //!< CBU double bit aggregate ECC errors + +/* Page Retirement */ +#define NVML_FI_DEV_RETIRED_SBE 29 //!< Number of retired pages because of single bit errors +#define NVML_FI_DEV_RETIRED_DBE 30 //!< Number of retired pages because of double bit errors +#define NVML_FI_DEV_RETIRED_PENDING 31 //!< If any pages are pending retirement. 1=yes. 0=no. + +/** + * NVLink Flit Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L0 32 //!< NVLink flow control CRC Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L1 33 //!< NVLink flow control CRC Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L2 34 //!< NVLink flow control CRC Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L3 35 //!< NVLink flow control CRC Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L4 36 //!< NVLink flow control CRC Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L5 37 //!< NVLink flow control CRC Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL 38 //!< NVLink flow control CRC Error Counter total for all Lanes + +/** + * NVLink CRC Data Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L0 39 //!< NVLink data CRC Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L1 40 //!< NVLink data CRC Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L2 41 //!< NVLink data CRC Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L3 42 //!< NVLink data CRC Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L4 43 //!< NVLink data CRC Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L5 44 //!< NVLink data CRC Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_TOTAL 45 //!< NvLink data CRC Error Counter total for all Lanes + +/** + * NVLink Replay Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L0 46 //!< NVLink Replay Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L1 47 //!< NVLink Replay Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L2 48 //!< NVLink Replay Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L3 49 //!< NVLink Replay Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L4 50 //!< NVLink Replay Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L5 51 //!< NVLink Replay Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_TOTAL 52 //!< NVLink Replay Error Counter total for all Lanes + +/** + * NVLink Recovery Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L0 53 //!< NVLink Recovery Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L1 54 //!< NVLink Recovery Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L2 55 //!< NVLink Recovery Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L3 56 //!< NVLink Recovery Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L4 57 //!< NVLink Recovery Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L5 58 //!< NVLink Recovery Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_TOTAL 59 //!< NVLink Recovery Error Counter total for all Lanes + +/* NvLink Bandwidth Counters */ +/* + * NVML_FI_DEV_NVLINK_BANDWIDTH_* field values are now deprecated. + * Please use the following field values instead: + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX + */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L0 60 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 0 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L1 61 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 1 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L2 62 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 2 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L3 63 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 3 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L4 64 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 4 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L5 65 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 5 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_TOTAL 66 //!< NVLink Bandwidth Counter Total for Counter Set 0, All Lanes + +/* NvLink Bandwidth Counters */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L0 67 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 0 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L1 68 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 1 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L2 69 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 2 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L3 70 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 3 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L4 71 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 4 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L5 72 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 5 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_TOTAL 73 //!< NVLink Bandwidth Counter Total for Counter Set 1, All Lanes + +/* NVML Perf Policy Counters */ +#define NVML_FI_DEV_PERF_POLICY_POWER 74 //!< Perf Policy Counter for Power Policy +#define NVML_FI_DEV_PERF_POLICY_THERMAL 75 //!< Perf Policy Counter for Thermal Policy +#define NVML_FI_DEV_PERF_POLICY_SYNC_BOOST 76 //!< Perf Policy Counter for Sync boost Policy +#define NVML_FI_DEV_PERF_POLICY_BOARD_LIMIT 77 //!< Perf Policy Counter for Board Limit +#define NVML_FI_DEV_PERF_POLICY_LOW_UTILIZATION 78 //!< Perf Policy Counter for Low GPU Utilization Policy +#define NVML_FI_DEV_PERF_POLICY_RELIABILITY 79 //!< Perf Policy Counter for Reliability Policy +#define NVML_FI_DEV_PERF_POLICY_TOTAL_APP_CLOCKS 80 //!< Perf Policy Counter for Total App Clock Policy +#define NVML_FI_DEV_PERF_POLICY_TOTAL_BASE_CLOCKS 81 //!< Perf Policy Counter for Total Base Clocks Policy + +/* Memory temperatures */ +#define NVML_FI_DEV_MEMORY_TEMP 82 //!< Memory temperature for the device + +/* Energy Counter */ +#define NVML_FI_DEV_TOTAL_ENERGY_CONSUMPTION 83 //!< Total energy consumption for the GPU in mJ since the driver was last reloaded + +/** + * NVLink Speed + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L0 84 //!< NVLink Speed in MBps for Link 0 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L1 85 //!< NVLink Speed in MBps for Link 1 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L2 86 //!< NVLink Speed in MBps for Link 2 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L3 87 //!< NVLink Speed in MBps for Link 3 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L4 88 //!< NVLink Speed in MBps for Link 4 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L5 89 //!< NVLink Speed in MBps for Link 5 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_COMMON 90 //!< Common NVLink Speed in MBps for active links + +#define NVML_FI_DEV_NVLINK_LINK_COUNT 91 //!< Number of NVLinks present on the device + +#define NVML_FI_DEV_RETIRED_PENDING_SBE 92 //!< If any pages are pending retirement due to SBE. 1=yes. 0=no. +#define NVML_FI_DEV_RETIRED_PENDING_DBE 93 //!< If any pages are pending retirement due to DBE. 1=yes. 0=no. + +#define NVML_FI_DEV_PCIE_REPLAY_COUNTER 94 //!< PCIe replay counter +#define NVML_FI_DEV_PCIE_REPLAY_ROLLOVER_COUNTER 95 //!< PCIe replay rollover counter + +/** + * NVLink Flit Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L6 96 //!< NVLink flow control CRC Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L7 97 //!< NVLink flow control CRC Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L8 98 //!< NVLink flow control CRC Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L9 99 //!< NVLink flow control CRC Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L10 100 //!< NVLink flow control CRC Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L11 101 //!< NVLink flow control CRC Error Counter for Lane 11 + +/** + * NVLink CRC Data Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L6 102 //!< NVLink data CRC Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L7 103 //!< NVLink data CRC Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L8 104 //!< NVLink data CRC Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L9 105 //!< NVLink data CRC Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L10 106 //!< NVLink data CRC Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L11 107 //!< NVLink data CRC Error Counter for Lane 11 + +/** + * NVLink Replay Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L6 108 //!< NVLink Replay Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L7 109 //!< NVLink Replay Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L8 110 //!< NVLink Replay Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L9 111 //!< NVLink Replay Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L10 112 //!< NVLink Replay Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L11 113 //!< NVLink Replay Error Counter for Lane 11 + +/** + * NVLink Recovery Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L6 114 //!< NVLink Recovery Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L7 115 //!< NVLink Recovery Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L8 116 //!< NVLink Recovery Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L9 117 //!< NVLink Recovery Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L10 118 //!< NVLink Recovery Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L11 119 //!< NVLink Recovery Error Counter for Lane 11 + +/* NvLink Bandwidth Counters */ +/* + * NVML_FI_DEV_NVLINK_BANDWIDTH_* field values are now deprecated. + * Please use the following field values instead: + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX + */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L6 120 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 6 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L7 121 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 7 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L8 122 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 8 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L9 123 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 9 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L10 124 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 10 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L11 125 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 11 + +/* NvLink Bandwidth Counters */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L6 126 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 6 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L7 127 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 7 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L8 128 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 8 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L9 129 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 9 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L10 130 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 10 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L11 131 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 11 + +/** + * NVLink Speed + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L6 132 //!< NVLink Speed in MBps for Link 6 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L7 133 //!< NVLink Speed in MBps for Link 7 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L8 134 //!< NVLink Speed in MBps for Link 8 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L9 135 //!< NVLink Speed in MBps for Link 9 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L10 136 //!< NVLink Speed in MBps for Link 10 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L11 137 //!< NVLink Speed in MBps for Link 11 + +/** + * NVLink throughput counters field values + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + * A scopeId of UINT_MAX returns aggregate value summed up across all links + * for the specified counter type in fieldId. + */ +#define NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX 138 //!< NVLink TX Data throughput in KiB +#define NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX 139 //!< NVLink RX Data throughput in KiB +#define NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX 140 //!< NVLink TX Data + protocol overhead in KiB +#define NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX 141 //!< NVLink RX Data + protocol overhead in KiB + +/* Row Remapper */ +#define NVML_FI_DEV_REMAPPED_COR 142 //!< Number of remapped rows due to correctable errors +#define NVML_FI_DEV_REMAPPED_UNC 143 //!< Number of remapped rows due to uncorrectable errors +#define NVML_FI_DEV_REMAPPED_PENDING 144 //!< If any rows are pending remapping. 1=yes 0=no +#define NVML_FI_DEV_REMAPPED_FAILURE 145 //!< If any rows failed to be remapped 1=yes 0=no + +/** + * Remote device NVLink ID + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_REMOTE_NVLINK_ID 146 //!< Remote device NVLink ID + +/** + * NVSwitch: connected NVLink count + */ +#define NVML_FI_DEV_NVSWITCH_CONNECTED_LINK_COUNT 147 //!< Number of NVLinks connected to NVSwitch + +/* NvLink ECC Data Error Counters + * + * Lane ID needs to be specified in the scopeId field in nvmlFieldValue_t. + * + */ +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L0 148 //!< NVLink data ECC Error Counter for Link 0 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L1 149 //!< NVLink data ECC Error Counter for Link 1 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L2 150 //!< NVLink data ECC Error Counter for Link 2 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L3 151 //!< NVLink data ECC Error Counter for Link 3 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L4 152 //!< NVLink data ECC Error Counter for Link 4 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L5 153 //!< NVLink data ECC Error Counter for Link 5 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L6 154 //!< NVLink data ECC Error Counter for Link 6 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L7 155 //!< NVLink data ECC Error Counter for Link 7 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L8 156 //!< NVLink data ECC Error Counter for Link 8 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L9 157 //!< NVLink data ECC Error Counter for Link 9 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L10 158 //!< NVLink data ECC Error Counter for Link 10 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L11 159 //!< NVLink data ECC Error Counter for Link 11 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_TOTAL 160 //!< NVLink data ECC Error Counter total for all Links + +/** + * NVLink Error Replay + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_ERROR_DL_REPLAY 161 //!< NVLink Replay Error Counter + //!< This is unsupported for Blackwell+. + //!< Please use NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_* +/** + * NVLink Recovery Error Counter + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_ERROR_DL_RECOVERY 162 //!< NVLink Recovery Error Counter + //!< This is unsupported for Blackwell+ + //!< Please use NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_* + +/** + * NVLink Recovery Error CRC Counter + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_ERROR_DL_CRC 163 //!< NVLink CRC Error Counter + //!< This is unsupported for Blackwell+ + //!< Please use NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_* + +/** + * NVLink Speed, State and Version field id 164, 165, and 166 + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_GET_SPEED 164 //!< NVLink Speed in MBps +#define NVML_FI_DEV_NVLINK_GET_STATE 165 //!< NVLink State - Active,Inactive +#define NVML_FI_DEV_NVLINK_GET_VERSION 166 //!< NVLink Version + +#define NVML_FI_DEV_NVLINK_GET_POWER_STATE 167 //!< NVLink Power state. 0=HIGH_SPEED 1=LOW_SPEED +#define NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD 168 //!< NVLink length of idle period (units can be found from + //!< NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_UNITS) before + //!< transitioning links to sleep state + +#define NVML_FI_DEV_PCIE_L0_TO_RECOVERY_COUNTER 169 //!< Device PEX error recovery counter + +#define NVML_FI_DEV_C2C_LINK_COUNT 170 //!< Number of C2C Links present on the device +#define NVML_FI_DEV_C2C_LINK_GET_STATUS 171 //!< C2C Link Status 0=INACTIVE 1=ACTIVE +#define NVML_FI_DEV_C2C_LINK_GET_MAX_BW 172 //!< C2C Link Speed in MBps for active links + +#define NVML_FI_DEV_PCIE_COUNT_CORRECTABLE_ERRORS 173 //!< PCIe Correctable Errors Counter +#define NVML_FI_DEV_PCIE_COUNT_NAKS_RECEIVED 174 //!< PCIe NAK Receive Counter +#define NVML_FI_DEV_PCIE_COUNT_RECEIVER_ERROR 175 //!< PCIe Receiver Error Counter +#define NVML_FI_DEV_PCIE_COUNT_BAD_TLP 176 //!< PCIe Bad TLP Counter +#define NVML_FI_DEV_PCIE_COUNT_NAKS_SENT 177 //!< PCIe NAK Send Counter +#define NVML_FI_DEV_PCIE_COUNT_BAD_DLLP 178 //!< PCIe Bad DLLP Counter +#define NVML_FI_DEV_PCIE_COUNT_NON_FATAL_ERROR 179 //!< PCIe Non Fatal Error Counter +#define NVML_FI_DEV_PCIE_COUNT_FATAL_ERROR 180 //!< PCIe Fatal Error Counter +#define NVML_FI_DEV_PCIE_COUNT_UNSUPPORTED_REQ 181 //!< PCIe Unsupported Request Counter +#define NVML_FI_DEV_PCIE_COUNT_LCRC_ERROR 182 //!< PCIe LCRC Error Counter +#define NVML_FI_DEV_PCIE_COUNT_LANE_ERROR 183 //!< PCIe Per Lane Error Counter. + +#define NVML_FI_DEV_IS_RESETLESS_MIG_SUPPORTED 184 //!< Device's Restless MIG Capability + +/** + * Retrieves power usage for this GPU in milliwatts. + * It is only available if power management mode is supported. See \ref nvmlDeviceGetPowerManagementMode and + * \ref nvmlDeviceGetPowerUsage. + * + * scopeId needs to be specified. It signifies: + * 0 - GPU Only Scope - Metrics for GPU are retrieved + * 1 - Module scope - Metrics for the module (e.g. CPU + GPU) are retrieved. + * Note: CPU here refers to NVIDIA CPU (e.g. Grace). x86 or non-NVIDIA ARM is not supported + */ +#define NVML_FI_DEV_POWER_AVERAGE 185 //!< GPU power averaged over 1 sec interval, supported on Ampere (except GA100) or newer architectures. +#define NVML_FI_DEV_POWER_INSTANT 186 //!< Current GPU power, supported on all architectures. +#define NVML_FI_DEV_POWER_MIN_LIMIT 187 //!< Minimum power limit in milliwatts. +#define NVML_FI_DEV_POWER_MAX_LIMIT 188 //!< Maximum power limit in milliwatts. +#define NVML_FI_DEV_POWER_DEFAULT_LIMIT 189 //!< Default power limit in milliwatts (limit which device boots with). +#define NVML_FI_DEV_POWER_CURRENT_LIMIT 190 //!< Limit currently enforced in milliwatts (This includes other limits set elsewhere. E.g. Out-of-band). +#define NVML_FI_DEV_ENERGY 191 //!< Total energy consumption (in mJ) since the driver was last reloaded. Same as \ref NVML_FI_DEV_TOTAL_ENERGY_CONSUMPTION for the GPU. +#define NVML_FI_DEV_POWER_REQUESTED_LIMIT 192 //!< Power limit requested by NVML or any other userspace client. + +/** + * GPU T.Limit temperature thresholds in degree Celsius + * + * These fields are supported on Ada and later architectures and supersedes \ref nvmlDeviceGetTemperatureThreshold. + */ +#define NVML_FI_DEV_TEMPERATURE_SHUTDOWN_TLIMIT 193 //!< T.Limit temperature after which GPU may shut down for HW protection +#define NVML_FI_DEV_TEMPERATURE_SLOWDOWN_TLIMIT 194 //!< T.Limit temperature after which GPU may begin HW slowdown +#define NVML_FI_DEV_TEMPERATURE_MEM_MAX_TLIMIT 195 //!< T.Limit temperature after which GPU may begin SW slowdown due to memory temperature +#define NVML_FI_DEV_TEMPERATURE_GPU_MAX_TLIMIT 196 //!< T.Limit temperature after which GPU may be throttled below base clock + +#define NVML_FI_DEV_PCIE_COUNT_TX_BYTES 197 //!< PCIe transmit bytes. Value can be wrapped. +#define NVML_FI_DEV_PCIE_COUNT_RX_BYTES 198 //!< PCIe receive bytes. Value can be wrapped. + +#define NVML_FI_DEV_IS_MIG_MODE_INDEPENDENT_MIG_QUERY_CAPABLE 199 //!< MIG mode independent, MIG query capable device. 1=yes. 0=no. + +#define NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_MAX 200 //!< Max Nvlink Power Threshold. See NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD + +/** + * NVLink counter field id 201-225 + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_COUNT_XMIT_PACKETS 201 //!usedGpuMemory is not supported + + + unsigned long long time; //!< Amount of time in ms during which the compute context was active. The time is reported as 0 if + //!< the process is not terminated + + unsigned long long startTime; //!< CPU Timestamp in usec representing start time for the process + + unsigned int isRunning; //!< Flag to represent if the process is running (1 for running, 0 for terminated) + + unsigned int reserved[5]; //!< Reserved for future use +} nvmlAccountingStats_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlEncoderStructs Encoder Structs + * @{ + */ +/***************************************************************************************************/ + +/** + * Represents type of encoder for capacity can be queried + */ +typedef enum nvmlEncoderQueryType_enum +{ + NVML_ENCODER_QUERY_H264 = 0x00, //!< H264 encoder + NVML_ENCODER_QUERY_HEVC = 0x01, //!< HEVC encoder + NVML_ENCODER_QUERY_AV1 = 0x02, //!< AV1 encoder + NVML_ENCODER_QUERY_UNKNOWN = 0xFF //!< Unknown encoder +}nvmlEncoderType_t; + +/** + * Structure to hold encoder session data + */ +typedef struct nvmlEncoderSessionInfo_st +{ + unsigned int sessionId; //!< Unique session ID + unsigned int pid; //!< Owning process ID + nvmlVgpuInstance_t vgpuInstance; //!< Owning vGPU instance ID (only valid on vGPU hosts, otherwise zero) + nvmlEncoderType_t codecType; //!< Video encoder type + unsigned int hResolution; //!< Current encode horizontal resolution + unsigned int vResolution; //!< Current encode vertical resolution + unsigned int averageFps; //!< Moving average encode frames per second + unsigned int averageLatency; //!< Moving average encode latency in microseconds +}nvmlEncoderSessionInfo_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFBCStructs Frame Buffer Capture Structures +* @{ +*/ +/***************************************************************************************************/ + +/** + * Represents frame buffer capture session type + */ +typedef enum nvmlFBCSessionType_enum +{ + NVML_FBC_SESSION_TYPE_UNKNOWN = 0, //!< Unknown + NVML_FBC_SESSION_TYPE_TOSYS, //!< ToSys + NVML_FBC_SESSION_TYPE_CUDA, //!< Cuda + NVML_FBC_SESSION_TYPE_VID, //!< Vid + NVML_FBC_SESSION_TYPE_HWENC //!< HEnc +} nvmlFBCSessionType_t; + +/** + * Structure to hold frame buffer capture sessions stats + */ +typedef struct nvmlFBCStats_st +{ + unsigned int sessionsCount; //!< Total no of sessions + unsigned int averageFPS; //!< Moving average new frames captured per second + unsigned int averageLatency; //!< Moving average new frame capture latency in microseconds +} nvmlFBCStats_t; + +#define NVML_NVFBC_SESSION_FLAG_DIFFMAP_ENABLED 0x00000001 //!< Bit specifying differential map state. +#define NVML_NVFBC_SESSION_FLAG_CLASSIFICATIONMAP_ENABLED 0x00000002 //!< Bit specifying classification map state. +#define NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_NO_WAIT 0x00000004 //!< Bit specifying if capture was requested as non-blocking call. +#define NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_INFINITE 0x00000008 //!< Bit specifying if capture was requested as blocking call. +#define NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_TIMEOUT 0x00000010 //!< Bit specifying if capture was requested as blocking call with timeout period. + +/** + * Structure to hold FBC session data + */ +typedef struct nvmlFBCSessionInfo_st +{ + unsigned int sessionId; //!< Unique session ID + unsigned int pid; //!< Owning process ID + nvmlVgpuInstance_t vgpuInstance; //!< Owning vGPU instance ID (only valid on vGPU hosts, otherwise zero) + unsigned int displayOrdinal; //!< Display identifier + nvmlFBCSessionType_t sessionType; //!< Type of frame buffer capture session + unsigned int sessionFlags; //!< Session flags (one or more of NVML_NVFBC_SESSION_FLAG_XXX). + unsigned int hMaxResolution; //!< Max horizontal resolution supported by the capture session + unsigned int vMaxResolution; //!< Max vertical resolution supported by the capture session + unsigned int hResolution; //!< Horizontal resolution requested by caller in capture call + unsigned int vResolution; //!< Vertical resolution requested by caller in capture call + unsigned int averageFPS; //!< Moving average new frames captured per second + unsigned int averageLatency; //!< Moving average new frame capture latency in microseconds +} nvmlFBCSessionInfo_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDrainDefs Drain State definitions + * @{ + */ +/***************************************************************************************************/ + +/** + * Is the GPU device to be removed from the kernel by nvmlDeviceRemoveGpu() + */ +typedef enum nvmlDetachGpuState_enum +{ + NVML_DETACH_GPU_KEEP = 0, + NVML_DETACH_GPU_REMOVE +} nvmlDetachGpuState_t; + +/** + * Parent bridge PCIe link state requested by nvmlDeviceRemoveGpu() + */ +typedef enum nvmlPcieLinkState_enum +{ + NVML_PCIE_LINK_KEEP = 0, + NVML_PCIE_LINK_SHUT_DOWN +} nvmlPcieLinkState_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlConfidentialComputingDefs Confidential Computing definitions + * @{ + */ +/***************************************************************************************************/ +/** + * Confidential Compute CPU Capabilities values + */ +#define NVML_CC_SYSTEM_CPU_CAPS_NONE 0 +#define NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV 1 +#define NVML_CC_SYSTEM_CPU_CAPS_INTEL_TDX 2 +#define NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV_SNP 3 +#define NVML_CC_SYSTEM_CPU_CAPS_AMD_SNP_VTOM 4 + +/** + * Confidenial Compute GPU Capabilities values + */ +#define NVML_CC_SYSTEM_GPUS_CC_NOT_CAPABLE 0 +#define NVML_CC_SYSTEM_GPUS_CC_CAPABLE 1 + +typedef struct nvmlConfComputeSystemCaps_st { + unsigned int cpuCaps; + unsigned int gpusCaps; +} nvmlConfComputeSystemCaps_t; + +/** + * Confidential Compute DevTools Mode values + */ +#define NVML_CC_SYSTEM_DEVTOOLS_MODE_OFF 0 +#define NVML_CC_SYSTEM_DEVTOOLS_MODE_ON 1 + +/** + * Confidential Compute Environment values + */ +#define NVML_CC_SYSTEM_ENVIRONMENT_UNAVAILABLE 0 +#define NVML_CC_SYSTEM_ENVIRONMENT_SIM 1 +#define NVML_CC_SYSTEM_ENVIRONMENT_PROD 2 + +/** + * Confidential Compute Feature Status values + */ +#define NVML_CC_SYSTEM_FEATURE_DISABLED 0 +#define NVML_CC_SYSTEM_FEATURE_ENABLED 1 + +typedef struct nvmlConfComputeSystemState_st { + unsigned int environment; + unsigned int ccFeature; + unsigned int devToolsMode; +} nvmlConfComputeSystemState_t; + +/** + * Confidential Compute Multigpu mode values + */ +#define NVML_CC_SYSTEM_MULTIGPU_NONE 0 +#define NVML_CC_SYSTEM_MULTIGPU_PROTECTED_PCIE 1 +#define NVML_CC_SYSTEM_MULTIGPU_NVLE 2 + +/** + * Confidential Compute System settings + */ +typedef struct { + unsigned int version; + unsigned int environment; + unsigned int ccFeature; + unsigned int devToolsMode; + unsigned int multiGpuMode; +} nvmlSystemConfComputeSettings_v1_t; + +typedef nvmlSystemConfComputeSettings_v1_t nvmlSystemConfComputeSettings_t; +#define nvmlSystemConfComputeSettings_v1 NVML_STRUCT_VERSION(SystemConfComputeSettings, 1) + +/** + * Protected memory size + */ +typedef struct +nvmlConfComputeMemSizeInfo_st +{ + unsigned long long protectedMemSizeKib; + unsigned long long unprotectedMemSizeKib; +} nvmlConfComputeMemSizeInfo_t; + +/** + * Confidential Compute GPUs/System Ready State values + */ +#define NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE 0 +#define NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE 1 + +/** + * GPU Certificate Details + */ +#define NVML_GPU_CERT_CHAIN_SIZE 0x1000 +#define NVML_GPU_ATTESTATION_CERT_CHAIN_SIZE 0x1400 + +typedef struct nvmlConfComputeGpuCertificate_st { + unsigned int certChainSize; + unsigned int attestationCertChainSize; + unsigned char certChain[NVML_GPU_CERT_CHAIN_SIZE]; + unsigned char attestationCertChain[NVML_GPU_ATTESTATION_CERT_CHAIN_SIZE]; +} nvmlConfComputeGpuCertificate_t; + +/** + * GPU Attestation Report + */ +#define NVML_CC_GPU_CEC_NONCE_SIZE 0x20 +#define NVML_CC_GPU_ATTESTATION_REPORT_SIZE 0x2000 +#define NVML_CC_GPU_CEC_ATTESTATION_REPORT_SIZE 0x1000 +#define NVML_CC_CEC_ATTESTATION_REPORT_NOT_PRESENT 0 +#define NVML_CC_CEC_ATTESTATION_REPORT_PRESENT 1 +#define NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MIN 50 +#define NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MAX 65 + +typedef struct nvmlConfComputeGpuAttestationReport_st { + unsigned int isCecAttestationReportPresent; //!< output + unsigned int attestationReportSize; //!< output + unsigned int cecAttestationReportSize; //!< output + unsigned char nonce[NVML_CC_GPU_CEC_NONCE_SIZE]; //!< input: spdm supports 32 bytes on nonce + unsigned char attestationReport[NVML_CC_GPU_ATTESTATION_REPORT_SIZE]; //!< output + unsigned char cecAttestationReport[NVML_CC_GPU_CEC_ATTESTATION_REPORT_SIZE]; //!< output +} nvmlConfComputeGpuAttestationReport_t; + +typedef struct nvmlConfComputeSetKeyRotationThresholdInfo_st { + unsigned int version; + unsigned long long maxAttackerAdvantage; +} nvmlConfComputeSetKeyRotationThresholdInfo_v1_t; + +typedef nvmlConfComputeSetKeyRotationThresholdInfo_v1_t nvmlConfComputeSetKeyRotationThresholdInfo_t; +#define nvmlConfComputeSetKeyRotationThresholdInfo_v1 \ + NVML_STRUCT_VERSION(ConfComputeSetKeyRotationThresholdInfo, 1) + +typedef struct nvmlConfComputeGetKeyRotationThresholdInfo_st { + unsigned int version; + unsigned long long attackerAdvantage; +} nvmlConfComputeGetKeyRotationThresholdInfo_v1_t; + +typedef nvmlConfComputeGetKeyRotationThresholdInfo_v1_t nvmlConfComputeGetKeyRotationThresholdInfo_t; +#define nvmlConfComputeGetKeyRotationThresholdInfo_v1 \ + NVML_STRUCT_VERSION(ConfComputeGetKeyRotationThresholdInfo, 1) + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFabricDefs Fabric definitions + * @{ + */ +/***************************************************************************************************/ + +#define NVML_GPU_FABRIC_UUID_LEN 16 //!< Length of Fabric UUID + +/** + * Fabric Probe States + */ +#define NVML_GPU_FABRIC_STATE_NOT_SUPPORTED 0 //!< Fabric Probe State not supported +#define NVML_GPU_FABRIC_STATE_NOT_STARTED 1 //!< Fabric Probe has not started +#define NVML_GPU_FABRIC_STATE_IN_PROGRESS 2 //!< Fabric Probe in progress +#define NVML_GPU_FABRIC_STATE_COMPLETED 3 //!< Fabric Probe State completed + +/** + * Probe State of GPU registration process + */ +typedef unsigned char nvmlGpuFabricState_t; + +/** + * Contains the device fabric information + */ +typedef struct +{ + unsigned char clusterUuid[NVML_GPU_FABRIC_UUID_LEN]; //!< Uuid of the cluster to which this GPU belongs + nvmlReturn_t status; //!< Error status, if any. Must be checked only if state returns "complete". + unsigned int cliqueId; //!< ID of the fabric clique to which this GPU belongs + nvmlGpuFabricState_t state; //!< Current state of GPU registration process. See NVML_GPU_FABRIC_STATE_* +} nvmlGpuFabricInfo_t; + +/** + * Fabric Degraded BW + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_DEGRADED_BW_NOT_SUPPORTED 0 //!< Fabric Health Mask: Degraded Bandwidth not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_DEGRADED_BW_TRUE 1 //!< Fabric Health Mask: Bandwidth degraded +#define NVML_GPU_FABRIC_HEALTH_MASK_DEGRADED_BW_FALSE 2 //!< Fabric Health Mask: Bandwidth not degraded + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_DEGRADED_BW 0 //!< Fabric Health Mask Bit Shift for Degraded Bandwidth +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_DEGRADED_BW 0x3 //!< Fabric Health Mask Width for Degraded Bandwidth + +/** + * Fabric Route Recovery + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_NOT_SUPPORTED 0 //!< Fabric Health Mask: Route Recovery not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_TRUE 1 //!< Fabric Health Mask: Route Recovery in progress +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_FALSE 2 //!< Fabric Health Mask: Route Recovery not in progress + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_RECOVERY 2 //!< Fabric Health Mask Bit Shift for Route Recovery +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_RECOVERY 0x3 //!< Fabric Health Mask Width for Route Recovery + +/** + * Nvlink Fabric Route Unhealthy + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_NOT_SUPPORTED 0 //!< Fabric Health Mask: Route Unhealthy not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_TRUE 1 //!< Fabric Health Mask: Route is unhealthy +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_FALSE 2 //!< Fabric Health Mask: Route is healthy + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_UNHEALTHY 4 //!< Fabric Health Mask Bit Shift for Route Unhealthy +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_UNHEALTHY 0x3 //!< Fabric Health Mask Width for Route Unhealthy + +/** + * Fabric Access Timeout Recovery + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_NOT_SUPPORTED 0 //!< Fabric Health Mask: Access Timeout Recovery not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_TRUE 1 //!< Fabric Health Mask: Access Timeout Recovery in progress +#define NVML_GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_FALSE 2 //!< Fabric Health Mask: Access Timeout Recovery not in progress + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ACCESS_TIMEOUT_RECOVERY 6 //!< Fabric Health Mask Bit Shift for Access Timeout Recovery +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_ACCESS_TIMEOUT_RECOVERY 0x3 //!< Fabric Health Mask Width for Access Timeout Recovery + +/** + * Fabric Incorrect Configuration + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_NOT_SUPPORTED 0 //!< Fabric Health Mask: Incorrect Configuration not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_NONE 1 //!< Fabric Health Mask: Correct Configuration +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INCORRECT_SYSGUID 2 //!< Fabric Health Mask: Incorrect Configuration - SysGUID +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INCORRECT_CHASSIS_SN 3 //!< Fabric Health Mask: Incorrect Configuration - Chassis Serial Number +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_NO_PARTITION 4 //!< Fabric Health Mask: Incorrect Configuration - No Partition +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INSUFFICIENT_NVLINKS 5 //!< Fabric Health Mask: Incorrect Configuration - Insufficient Nvlinks +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INCOMPATIBLE_GPU_FW 6 //!< Fabric Health Mask: Incorrect Configuration - Incompatible GPU Firmware +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INVALID_LOCATION 7 //!< Fabric Health Mask: Incorrect Configuration - Invalid Location + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_INCORRECT_CONFIGURATION 8 //!< Fabric Health Mask Bit Shift for Incorrect Configuration +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_INCORRECT_CONFIGURATION 0xf //!< Fabric Health Mask Width for Incorrect Configuration + +/** + * Fabric Health + */ +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_NOT_SUPPORTED 0 //!< Fabric Health Summary: Not supported +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_HEALTHY 1 //!< Fabric Health Summary: Healthy +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_UNHEALTHY 2 //!< Fabric Health Summary: Unhealthy +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_LIMITED_CAPACITY 3 //!< Fabric Health Summary: Limited Capacity + +/** + * GPU Fabric Health Status Mask for various fields can be obtained + * using the below macro. + * Ex - NVML_GPU_FABRIC_HEALTH_GET(var, _DEGRADED_BW) + */ +#define NVML_GPU_FABRIC_HEALTH_GET(var, type) \ + (((var) >> NVML_GPU_FABRIC_HEALTH_MASK_SHIFT##type) & \ + (NVML_GPU_FABRIC_HEALTH_MASK_WIDTH##type)) + +/** + * GPU Fabric Health Status Mask for various fields can be tested + * using the below macro. + * Ex - NVML_GPU_FABRIC_HEALTH_TEST(var, _DEGRADED_BW, _TRUE) + */ +#define NVML_GPU_FABRIC_HEALTH_TEST(var, type, val) \ + (NVML_GPU_FABRIC_HEALTH_GET(var, type) == \ + NVML_GPU_FABRIC_HEALTH_MASK##type##val) + +/** +* GPU Fabric information (v2). +* +* @deprecated nvmlGpuFabricInfo_v2_t is deprecated and will be removed in a future release. +* Use nvmlGpuFabricInfo_v3_t instead +* +* Version 2 adds the \ref nvmlGpuFabricInfo_v2_t.version field +* to the start of the structure, and the \ref nvmlGpuFabricInfo_v2_t.healthMask +* field to the end. This structure is not backwards-compatible with +* \ref nvmlGpuFabricInfo_t. +*/ +typedef struct +{ + unsigned int version; //!< Structure version identifier (set to nvmlGpuFabricInfo_v2) + unsigned char clusterUuid[NVML_GPU_FABRIC_UUID_LEN]; //!< Uuid of the cluster to which this GPU belongs + nvmlReturn_t status; //!< Probe Error status, if any. Must be checked only if Probe state returns "complete". + unsigned int cliqueId; //!< ID of the fabric clique to which this GPU belongs + nvmlGpuFabricState_t state; //!< Current Probe State of GPU registration process. See NVML_GPU_FABRIC_STATE_* + unsigned int healthMask; //!< GPU Fabric health Status Mask. See NVML_GPU_FABRIC_HEALTH_MASK_* +} nvmlGpuFabricInfo_v2_t; + +/** +* Version identifier value for \ref nvmlGpuFabricInfo_v2_t.version. +*/ +#define nvmlGpuFabricInfo_v2 NVML_STRUCT_VERSION(GpuFabricInfo, 2) + +/** +* GPU Fabric information (v3). +*/ +typedef struct +{ + unsigned int version; //!< Structure version identifier (set to nvmlGpuFabricInfo_v2) + unsigned char clusterUuid[NVML_GPU_FABRIC_UUID_LEN]; //!< Uuid of the cluster to which this GPU belongs + nvmlReturn_t status; //!< Probe Error status, if any. Must be checked only if Probe state returns "complete". + unsigned int cliqueId; //!< ID of the fabric clique to which this GPU belongs + nvmlGpuFabricState_t state; //!< Current Probe State of GPU registration process. See NVML_GPU_FABRIC_STATE_* + unsigned int healthMask; //!< GPU Fabric health Status Mask. See NVML_GPU_FABRIC_HEALTH_MASK_* + unsigned char healthSummary; //!< GPU Fabric health summary. See NVML_GPU_FABRIC_HEALTH_SUMMARY_* +} nvmlGpuFabricInfo_v3_t; + +typedef nvmlGpuFabricInfo_v3_t nvmlGpuFabricInfoV_t; + +/** +* Version identifier value for \ref nvmlGpuFabricInfo_v3_t.version. +*/ +#define nvmlGpuFabricInfo_v3 NVML_STRUCT_VERSION(GpuFabricInfo, 3) + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlInitializationAndCleanup Initialization and Cleanup + * This chapter describes the methods that handle NVML initialization and cleanup. + * It is the user's responsibility to call \ref nvmlInit_v2() before calling any other methods, and + * nvmlShutdown() once NVML is no longer being used. + * @{ + */ +/***************************************************************************************************/ + +#define NVML_INIT_FLAG_NO_GPUS 1 //!< Don't fail nvmlInit() when no GPUs are found +#define NVML_INIT_FLAG_NO_ATTACH 2 //!< Don't attach GPUs + +/** + * Initialize NVML, but don't initialize any GPUs yet. + * + * \note nvmlInit_v3 introduces a "flags" argument, that allows passing boolean values + * modifying the behaviour of nvmlInit(). + * \note In NVML 5.319 new nvmlInit_v2 has replaced nvmlInit"_v1" (default in NVML 4.304 and older) that + * did initialize all GPU devices in the system. + * + * This allows NVML to communicate with a GPU + * when other GPUs in the system are unstable or in a bad state. When using this API, GPUs are + * discovered and initialized in nvmlDeviceGetHandleBy* functions instead. + * + * \note To contrast nvmlInit_v2 with nvmlInit"_v1", NVML 4.304 nvmlInit"_v1" will fail when any detected GPU is in + * a bad or unstable state. + * + * For all products. + * + * This method, should be called once before invoking any other methods in the library. + * A reference count of the number of initializations is maintained. Shutdown only occurs + * when the reference count reaches zero. + * + * @return + * - \ref NVML_SUCCESS if NVML has been properly initialized + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running + * - \ref NVML_ERROR_NO_PERMISSION if NVML does not have permission to talk to the driver + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlInit_v2(void); + +/** + * nvmlInitWithFlags is a variant of nvmlInit(), that allows passing a set of boolean values + * modifying the behaviour of nvmlInit(). + * Other than the "flags" parameter it is completely similar to \ref nvmlInit_v2. + * + * For all products. + * + * @param flags behaviour modifier flags + * + * @return + * - \ref NVML_SUCCESS if NVML has been properly initialized + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running + * - \ref NVML_ERROR_NO_PERMISSION if NVML does not have permission to talk to the driver + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlInitWithFlags(unsigned int flags); + +/** + * Shut down NVML by releasing all GPU resources previously allocated with \ref nvmlInit_v2(). + * + * For all products. + * + * This method should be called after NVML work is done, once for each call to \ref nvmlInit_v2() + * A reference count of the number of initializations is maintained. Shutdown only occurs + * when the reference count reaches zero. For backwards compatibility, no error is reported if + * nvmlShutdown() is called more times than nvmlInit(). + * + * @return + * - \ref NVML_SUCCESS if NVML has been properly shut down + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlShutdown(void); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlErrorReporting Error reporting + * This chapter describes helper functions for error reporting routines. + * @{ + */ +/***************************************************************************************************/ + +/** + * Helper method for converting NVML error codes into readable strings. + * + * For all products. + * + * @param result NVML error code to convert + * + * @return String representation of the error. + * + */ +const DECLDIR char* nvmlErrorString(nvmlReturn_t result); +/** @} */ + + +/***************************************************************************************************/ +/** @defgroup nvmlConstants Constants + * @{ + */ +/***************************************************************************************************/ + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetInforomVersion and \ref nvmlDeviceGetInforomImageVersion + */ +#define NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE 16 + +/** + * Buffer size guaranteed to be large enough for storing GPU identifiers. + */ +#define NVML_DEVICE_UUID_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetUUID + */ +#define NVML_DEVICE_UUID_V2_BUFFER_SIZE 96 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetBoardPartNumber + */ +#define NVML_DEVICE_PART_NUMBER_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlSystemGetDriverVersion + */ +#define NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlSystemGetNVMLVersion + */ +#define NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for storing GPU device names. + */ +#define NVML_DEVICE_NAME_BUFFER_SIZE 64 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetName + */ +#define NVML_DEVICE_NAME_V2_BUFFER_SIZE 96 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetSerial + */ +#define NVML_DEVICE_SERIAL_BUFFER_SIZE 30 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetVbiosVersion + */ +#define NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE 32 + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlSystemQueries System Queries + * This chapter describes the queries that NVML can perform against the local system. These queries + * are not device-specific. + * @{ + */ +/***************************************************************************************************/ + +/** + * Retrieves the version of the system's graphics driver. + * + * For all products. + * + * The version identifier is an alphanumeric string. It will not exceed 80 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE. + * + * @param version Reference in which to return the version identifier + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + */ +nvmlReturn_t DECLDIR nvmlSystemGetDriverVersion(char *version, unsigned int length); + +/** + * Retrieves the version of the NVML library. + * + * For all products. + * + * The version identifier is an alphanumeric string. It will not exceed 80 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE. + * + * @param version Reference in which to return the version identifier + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + */ +nvmlReturn_t DECLDIR nvmlSystemGetNVMLVersion(char *version, unsigned int length); + +/** + * Retrieves the version of the CUDA driver. + * + * For all products. + * + * The CUDA driver version returned will be retreived from the currently installed version of CUDA. + * If the cuda library is not found, this function will return a known supported version number. + * + * @param cudaDriverVersion Reference in which to return the version identifier + * + * @return + * - \ref NVML_SUCCESS if \a cudaDriverVersion has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a cudaDriverVersion is NULL + */ +nvmlReturn_t DECLDIR nvmlSystemGetCudaDriverVersion(int *cudaDriverVersion); + +/** + * Retrieves the version of the CUDA driver from the shared library. + * + * For all products. + * + * The returned CUDA driver version by calling cuDriverGetVersion() + * + * @param cudaDriverVersion Reference in which to return the version identifier + * + * @return + * - \ref NVML_SUCCESS if \a cudaDriverVersion has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a cudaDriverVersion is NULL + * - \ref NVML_ERROR_LIBRARY_NOT_FOUND if \a libcuda.so.1 or libcuda.dll is not found + * - \ref NVML_ERROR_FUNCTION_NOT_FOUND if \a cuDriverGetVersion() is not found in the shared library + */ +nvmlReturn_t DECLDIR nvmlSystemGetCudaDriverVersion_v2(int *cudaDriverVersion); + +/** + * Macros for converting the CUDA driver version number to Major and Minor version numbers. + */ +#define NVML_CUDA_DRIVER_VERSION_MAJOR(v) ((v)/1000) +#define NVML_CUDA_DRIVER_VERSION_MINOR(v) (((v)%1000)/10) + +/** + * Gets name of the process with provided process id + * + * For all products. + * + * Returned process name is cropped to provided length. + * name string is encoded in ANSI. + * + * @param pid The identifier of the process + * @param name Reference in which to return the process name + * @param length The maximum allowed length of the string returned in \a name + * + * @return + * - \ref NVML_SUCCESS if \a name has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a name is NULL or \a length is 0. + * - \ref NVML_ERROR_NOT_FOUND if process doesn't exists + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetProcessName(unsigned int pid, char *name, unsigned int length); + +/** + * Retrieves the IDs and firmware versions for any Host Interface Cards (HICs) in the system. + * + * For S-class products. + * + * The \a hwbcCount argument is expected to be set to the size of the input \a hwbcEntries array. + * The HIC must be connected to an S-class system for it to be reported by this function. + * + * @param hwbcCount Size of hwbcEntries array + * @param hwbcEntries Array holding information about hwbc + * + * @return + * - \ref NVML_SUCCESS if \a hwbcCount and \a hwbcEntries have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if either \a hwbcCount or \a hwbcEntries is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a hwbcCount indicates that the \a hwbcEntries array is too small + */ +nvmlReturn_t DECLDIR nvmlSystemGetHicVersion(unsigned int *hwbcCount, nvmlHwbcEntry_t *hwbcEntries); + +/** + * Retrieve the set of GPUs that have a CPU affinity with the given CPU number + * For all products. + * Supported on Linux only. + * + * @param cpuNumber The CPU number + * @param count When zero, is set to the number of matching GPUs such that \a deviceArray + * can be malloc'd. When non-zero, \a deviceArray will be filled with \a count + * number of device handles. + * @param deviceArray An array of device handles for GPUs found with affinity to \a cpuNumber + * + * @return + * - \ref NVML_SUCCESS if \a deviceArray or \a count (if initially zero) has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a cpuNumber, or \a count is invalid, or \a deviceArray is NULL with a non-zero \a count + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or OS does not support this feature + * - \ref NVML_ERROR_UNKNOWN an error has occurred in underlying topology discovery + */ +nvmlReturn_t DECLDIR nvmlSystemGetTopologyGpuSet(unsigned int cpuNumber, unsigned int *count, nvmlDevice_t *deviceArray); + +/** + * Structure to store Driver branch information + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + char branch[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< driver branch +} nvmlSystemDriverBranchInfo_v1_t; +typedef nvmlSystemDriverBranchInfo_v1_t nvmlSystemDriverBranchInfo_t; +#define nvmlSystemDriverBranchInfo_v1 NVML_STRUCT_VERSION(SystemDriverBranchInfo, 1) + +/** + * Retrieves the driver branch of the NVIDIA driver installed on the system. + * + * For all products. + * + * The branch identifier is an alphanumeric string. It will not exceed 80 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE. + * + * @param branchInfo Pointer to the driver branch information structure \a nvmlSystemDriverBranchInfo_t + * @param length The maximum allowed length of the driver branch string + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a branchInfo is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetDriverBranch(nvmlSystemDriverBranchInfo_t *branchInfo, unsigned int length); + + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlUnitQueries Unit Queries + * This chapter describes that queries that NVML can perform against each unit. For S-class systems only. + * In each case the device is identified with an nvmlUnit_t handle. This handle is obtained by + * calling \ref nvmlUnitGetHandleByIndex(). + * @{ + */ +/***************************************************************************************************/ + + /** + * Retrieves the number of units in the system. + * + * For S-class products. + * + * @param unitCount Reference in which to return the number of units + * + * @return + * - \ref NVML_SUCCESS if \a unitCount has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unitCount is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetCount(unsigned int *unitCount); + +/** + * Acquire the handle for a particular unit, based on its index. + * + * For S-class products. + * + * Valid indices are derived from the \a unitCount returned by \ref nvmlUnitGetCount(). + * For example, if \a unitCount is 2 the valid indices are 0 and 1, corresponding to UNIT 0 and UNIT 1. + * + * The order in which NVML enumerates units has no guarantees of consistency between reboots. + * + * @param index The index of the target unit, >= 0 and < \a unitCount + * @param unit Reference in which to return the unit handle + * + * @return + * - \ref NVML_SUCCESS if \a unit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a index is invalid or \a unit is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetHandleByIndex(unsigned int index, nvmlUnit_t *unit); + +/** + * Retrieves the static information associated with a unit. + * + * For S-class products. + * + * See \ref nvmlUnitInfo_t for details on available unit info. + * + * @param unit The identifier of the target unit + * @param info Reference in which to return the unit information + * + * @return + * - \ref NVML_SUCCESS if \a info has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a info is NULL + */ +nvmlReturn_t DECLDIR nvmlUnitGetUnitInfo(nvmlUnit_t unit, nvmlUnitInfo_t *info); + +/** + * Retrieves the LED state associated with this unit. + * + * For S-class products. + * + * See \ref nvmlLedState_t for details on allowed states. + * + * @param unit The identifier of the target unit + * @param state Reference in which to return the current LED state + * + * @return + * - \ref NVML_SUCCESS if \a state has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a state is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlUnitSetLedState() + */ +nvmlReturn_t DECLDIR nvmlUnitGetLedState(nvmlUnit_t unit, nvmlLedState_t *state); + +/** + * Retrieves the PSU stats for the unit. + * + * For S-class products. + * + * See \ref nvmlPSUInfo_t for details on available PSU info. + * + * @param unit The identifier of the target unit + * @param psu Reference in which to return the PSU information + * + * @return + * - \ref NVML_SUCCESS if \a psu has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a psu is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetPsuInfo(nvmlUnit_t unit, nvmlPSUInfo_t *psu); + +/** + * Retrieves the temperature readings for the unit, in degrees C. + * + * For S-class products. + * + * Depending on the product, readings may be available for intake (type=0), + * exhaust (type=1) and board (type=2). + * + * @param unit The identifier of the target unit + * @param type The type of reading to take + * @param temp Reference in which to return the intake temperature + * + * @return + * - \ref NVML_SUCCESS if \a temp has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit or \a type is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetTemperature(nvmlUnit_t unit, unsigned int type, unsigned int *temp); + +/** + * Retrieves the fan speed readings for the unit. + * + * For S-class products. + * + * See \ref nvmlUnitFanSpeeds_t for details on available fan speed info. + * + * @param unit The identifier of the target unit + * @param fanSpeeds Reference in which to return the fan speed information + * + * @return + * - \ref NVML_SUCCESS if \a fanSpeeds has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a fanSpeeds is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetFanSpeedInfo(nvmlUnit_t unit, nvmlUnitFanSpeeds_t *fanSpeeds); + +/** + * Retrieves the set of GPU devices that are attached to the specified unit. + * + * For S-class products. + * + * The \a deviceCount argument is expected to be set to the size of the input \a devices array. + * + * @param unit The identifier of the target unit + * @param deviceCount Reference in which to provide the \a devices array size, and + * to return the number of attached GPU devices + * @param devices Reference in which to return the references to the attached GPU devices + * + * @return + * - \ref NVML_SUCCESS if \a deviceCount and \a devices have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a deviceCount indicates that the \a devices array is too small + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid, either of \a deviceCount or \a devices is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetDevices(nvmlUnit_t unit, unsigned int *deviceCount, nvmlDevice_t *devices); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceQueries Device Queries + * This chapter describes that queries that NVML can perform against each device. + * In each case the device is identified with an nvmlDevice_t handle. This handle is obtained by + * calling one of \ref nvmlDeviceGetHandleByIndex_v2(), \ref nvmlDeviceGetHandleBySerial(), + * \ref nvmlDeviceGetHandleByPciBusId_v2(). or \ref nvmlDeviceGetHandleByUUID(). + * @{ + */ +/***************************************************************************************************/ + + /** + * Retrieves the number of compute devices in the system. A compute device is a single GPU. + * + * For all products. + * + * Note: New nvmlDeviceGetCount_v2 (default in NVML 5.319) returns count of all devices in the system + * even if nvmlDeviceGetHandleByIndex_v2 returns NVML_ERROR_NO_PERMISSION for such device. + * Update your code to handle this error, or use NVML 4.304 or older nvml header file. + * For backward binary compatibility reasons _v1 version of the API is still present in the shared + * library. + * Old _v1 version of nvmlDeviceGetCount doesn't count devices that NVML has no permission to talk to. + * + * @param deviceCount Reference in which to return the number of accessible devices + * + * @return + * - \ref NVML_SUCCESS if \a deviceCount has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a deviceCount is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCount_v2(unsigned int *deviceCount); + +/** + * Get attributes (engine counts etc.) for the given NVML device handle. + * + * @note This API currently only supports MIG device handles. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device NVML device handle + * @param attributes Device attributes + * + * @return + * - \ref NVML_SUCCESS if \a device attributes were successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device handle is invalid + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAttributes_v2(nvmlDevice_t device, nvmlDeviceAttributes_t *attributes); + +/** + * Acquire the handle for a particular device, based on its index. + * + * For all products. + * + * Valid indices are derived from the \a accessibleDevices count returned by + * \ref nvmlDeviceGetCount_v2(). For example, if \a accessibleDevices is 2 the valid indices + * are 0 and 1, corresponding to GPU 0 and GPU 1. + * + * The order in which NVML enumerates devices has no guarantees of consistency between reboots. For that reason it + * is recommended that devices be looked up by their PCI ids or UUID. See + * \ref nvmlDeviceGetHandleByUUID() and \ref nvmlDeviceGetHandleByPciBusId_v2(). + * + * Note: The NVML index may not correlate with other APIs, such as the CUDA device index. + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs if: + * - The target GPU is an SLI slave + * + * Note: New nvmlDeviceGetCount_v2 (default in NVML 5.319) returns count of all devices in the system + * even if nvmlDeviceGetHandleByIndex_v2 returns NVML_ERROR_NO_PERMISSION for such device. + * Update your code to handle this error, or use NVML 4.304 or older nvml header file. + * For backward binary compatibility reasons _v1 version of the API is still present in the shared + * library. + * Old _v1 version of nvmlDeviceGetCount doesn't count devices that NVML has no permission to talk to. + * + * This means that nvmlDeviceGetHandleByIndex_v2 and _v1 can return different devices for the same index. + * If you don't touch macros that map old (_v1) versions to _v2 versions at the top of the file you don't + * need to worry about that. + * + * @param index The index of the target GPU, >= 0 and < \a accessibleDevices + * @param device Reference in which to return the device handle + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a index is invalid or \a device is NULL + * - \ref NVML_ERROR_INSUFFICIENT_POWER if any attached devices have improperly attached external power cables + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to talk to this device + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetIndex + * @see nvmlDeviceGetCount + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByIndex_v2(unsigned int index, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its board serial number. + * + * For Fermi &tm; or newer fully supported devices. + * + * This number corresponds to the value printed directly on the board, and to the value returned by + * \ref nvmlDeviceGetSerial(). + * + * @deprecated Since more than one GPU can exist on a single board this function is deprecated in favor + * of \ref nvmlDeviceGetHandleByUUID. + * For dual GPU boards this function will return NVML_ERROR_INVALID_ARGUMENT. + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs as it searches for the target GPU + * + * @param serial The board serial number of the target GPU + * @param device Reference in which to return the device handle + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a serial is invalid, \a device is NULL or more than one + * device has the same serial (dual GPU boards) + * - \ref NVML_ERROR_NOT_FOUND if \a serial does not match a valid device on the system + * - \ref NVML_ERROR_INSUFFICIENT_POWER if any attached devices have improperly attached external power cables + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if any GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetSerial + * @see nvmlDeviceGetHandleByUUID + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetHandleBySerial(const char *serial, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its globally unique immutable UUID (in ASCII format) associated with each device. + * + * For all products. + * + * @param uuid The UUID of the target GPU or MIG instance + * @param device Reference in which to return the device handle or MIG device handle + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs as it searches for the target GPU + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a uuid is invalid or \a device is null + * - \ref NVML_ERROR_NOT_FOUND if \a uuid does not match a valid device on the system + * - \ref NVML_ERROR_INSUFFICIENT_POWER if any attached devices have improperly attached external power cables + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if any GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetUUID + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByUUID(const char *uuid, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its globally unique immutable UUID (in either ASCII or binary format) associated with each device. + * See \ref nvmlUUID_v1_t for more information on the UUID struct. The caller must set the appropriate version prior to calling this API. + * + * For all products. + * + * @param[in] uuid The UUID of the target GPU or MIG instance + * @param[out] device Reference in which to return the device handle or MIG device handle + * + * This API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs as it searches for the target GPU + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a uuid is invalid, \a device is null or \a uuid->type is invalid + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_FOUND if \a uuid does not match a valid device on the system + * - \ref NVML_ERROR_GPU_IS_LOST if any GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByUUIDV(const nvmlUUID_t *uuid, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its PCI bus id. + * + * For all products. + * + * This value corresponds to the nvmlPciInfo_t::busId returned by \ref nvmlDeviceGetPciInfo_v3(). + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs if: + * - The target GPU is an SLI slave + * + * \note NVML 4.304 and older version of nvmlDeviceGetHandleByPciBusId"_v1" returns NVML_ERROR_NOT_FOUND + * instead of NVML_ERROR_NO_PERMISSION. + * + * @param pciBusId The PCI bus id of the target GPU + * Accept the following formats (all numbers in hexadecimal): + * domain:bus:device.function in format %x:%x:%x.%x + * domain:bus:device in format %x:%x:%x + * bus:device.function in format %x:%x.%x + * + * @param device Reference in which to return the device handle + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a pciBusId is invalid or \a device is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a pciBusId does not match a valid device on the system + * - \ref NVML_ERROR_INSUFFICIENT_POWER if the attached device has improperly attached external power cables + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to talk to this device + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByPciBusId_v2(const char *pciBusId, nvmlDevice_t *device); + +/** + * Retrieves the name of this device. + * + * For all products. + * + * The name is an alphanumeric string that denotes a particular product, e.g. Tesla &tm; C2070. It will not + * exceed 96 characters in length (including the NULL terminator). See \ref + * nvmlConstants::NVML_DEVICE_NAME_V2_BUFFER_SIZE. + * + * When used with MIG device handles the API returns MIG device names which can be used to identify devices + * based on their attributes. + * + * @param device The identifier of the target device + * @param name Reference in which to return the product name + * @param length The maximum allowed length of the string returned in \a name + * + * @return + * - \ref NVML_SUCCESS if \a name has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetName(nvmlDevice_t device, char *name, unsigned int length); + +/** + * Retrieves the brand of this device. + * + * For all products. + * + * The type is a member of \ref nvmlBrandType_t defined above. + * + * @param device The identifier of the target device + * @param type Reference in which to return the product brand type + * + * @return + * - \ref NVML_SUCCESS if \a name has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a type is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t *type); + +/** + * Retrieves the NVML index of this device. + * + * For all products. + * + * Valid indices are derived from the \a accessibleDevices count returned by + * \ref nvmlDeviceGetCount_v2(). For example, if \a accessibleDevices is 2 the valid indices + * are 0 and 1, corresponding to GPU 0 and GPU 1. + * + * The order in which NVML enumerates devices has no guarantees of consistency between reboots. For that reason it + * is recommended that devices be looked up by their PCI ids or GPU UUID. See + * \ref nvmlDeviceGetHandleByPciBusId_v2() and \ref nvmlDeviceGetHandleByUUID(). + * + * When used with MIG device handles this API returns indices that can be + * passed to \ref nvmlDeviceGetMigDeviceHandleByIndex to retrieve an identical handle. + * MIG device indices are unique within a device. + * + * Note: The NVML index may not correlate with other APIs, such as the CUDA device index. + * + * @param device The identifier of the target device + * @param index Reference in which to return the NVML index of the device + * + * @return + * - \ref NVML_SUCCESS if \a index has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a index is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetHandleByIndex() + * @see nvmlDeviceGetCount() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetIndex(nvmlDevice_t device, unsigned int *index); + +/** + * Retrieves the globally unique board serial number associated with this device's board. + * + * For all products with an inforom. + * + * The serial number is an alphanumeric string that will not exceed 30 characters (including the NULL terminator). + * This number matches the serial number tag that is physically attached to the board. See \ref + * nvmlConstants::NVML_DEVICE_SERIAL_BUFFER_SIZE. + * + * @param device The identifier of the target device + * @param serial Reference in which to return the board/module serial number + * @param length The maximum allowed length of the string returned in \a serial + * + * @return + * - \ref NVML_SUCCESS if \a serial has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a serial is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSerial(nvmlDevice_t device, char *serial, unsigned int length); + +/** + * Get a unique identifier for the device module on the baseboard + * + * This API retrieves a unique identifier for each GPU module that exists on a given baseboard. + * For non-baseboard products, this ID would always be 0. + * + * @param device The identifier of the target device + * @param moduleId Unique identifier for the GPU module + * + * @return + * - \ref NVML_SUCCESS if \a moduleId has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a moduleId is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetModuleId(nvmlDevice_t device, unsigned int *moduleId); + +/** + * Retrieves the Device's C2C Mode information + * + * @param device The identifier of the target device + * @param c2cModeInfo Output struct containing the device's C2C Mode info + * + * @return + * - \ref NVML_SUCCESS if \a C2C Mode Infor query is successful + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a serial is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetC2cModeInfoV(nvmlDevice_t device, nvmlC2cModeInfo_v1_t *c2cModeInfo); + +/***************************************************************************************************/ + +/** @defgroup nvmlAffinity CPU and Memory Affinity + * This chapter describes NVML operations that are associated with CPU and memory + * affinity. + * @{ + */ +/***************************************************************************************************/ + +//! Scope of NUMA node for affinity queries +#define NVML_AFFINITY_SCOPE_NODE 0 +//! Scope of processor socket for affinity queries +#define NVML_AFFINITY_SCOPE_SOCKET 1 + +typedef unsigned int nvmlAffinityScope_t; + +/** + * Retrieves an array of unsigned ints (sized to nodeSetSize) of bitmasks with + * the ideal memory affinity within node or socket for the device. + * For example, if NUMA node 0, 1 are ideal within the socket for the device and nodeSetSize == 1, + * result[0] = 0x3 + * + * \note If requested scope is not applicable to the target topology, the API + * will fall back to reporting the memory affinity for the immediate non-I/O + * ancestor of the device. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param nodeSetSize The size of the nodeSet array that is safe to access + * @param nodeSet Array reference in which to return a bitmask of NODEs, 64 NODEs per + * unsigned long on 64-bit machines, 32 on 32-bit machines + * @param scope Scope that change the default behavior + * + * @return + * - \ref NVML_SUCCESS if \a NUMA node Affinity has been filled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, nodeSetSize == 0, nodeSet is NULL or scope is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryAffinity(nvmlDevice_t device, unsigned int nodeSetSize, unsigned long *nodeSet, nvmlAffinityScope_t scope); + +/** + * Retrieves an array of unsigned ints (sized to cpuSetSize) of bitmasks with the + * ideal CPU affinity within node or socket for the device. + * For example, if processors 0, 1, 32, and 33 are ideal for the device and cpuSetSize == 2, + * result[0] = 0x3, result[1] = 0x3 + * + * \note If requested scope is not applicable to the target topology, the API + * will fall back to reporting the CPU affinity for the immediate non-I/O + * ancestor of the device. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param cpuSetSize The size of the cpuSet array that is safe to access + * @param cpuSet Array reference in which to return a bitmask of CPUs, 64 CPUs per + * unsigned long on 64-bit machines, 32 on 32-bit machines + * @param scope Scope that change the default behavior + * + * @return + * - \ref NVML_SUCCESS if \a cpuAffinity has been filled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, cpuSetSize == 0, cpuSet is NULL or sope is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceGetCpuAffinityWithinScope(nvmlDevice_t device, unsigned int cpuSetSize, unsigned long *cpuSet, nvmlAffinityScope_t scope); + +/** + * Retrieves an array of unsigned ints (sized to cpuSetSize) of bitmasks with the ideal CPU affinity for the device + * For example, if processors 0, 1, 32, and 33 are ideal for the device and cpuSetSize == 2, + * result[0] = 0x3, result[1] = 0x3 + * This is equivalent to calling \ref nvmlDeviceGetCpuAffinityWithinScope with \ref NVML_AFFINITY_SCOPE_NODE. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param cpuSetSize The size of the cpuSet array that is safe to access + * @param cpuSet Array reference in which to return a bitmask of CPUs, 64 CPUs per + * unsigned long on 64-bit machines, 32 on 32-bit machines + * + * @return + * - \ref NVML_SUCCESS if \a cpuAffinity has been filled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, cpuSetSize == 0, or cpuSet is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCpuAffinity(nvmlDevice_t device, unsigned int cpuSetSize, unsigned long *cpuSet); + +/** + * Sets the ideal affinity for the calling thread and device using the guidelines + * given in nvmlDeviceGetCpuAffinity(). Note, this is a change as of version 8.0. + * Older versions set the affinity for a calling process and all children. + * Currently supports up to 1024 processors. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if the calling process has been successfully bound + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetCpuAffinity(nvmlDevice_t device); + +/** + * Clear all affinity bindings for the calling thread. Note, this is a change as of version + * 8.0 as older versions cleared the affinity for a calling process and all children. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if the calling process has been successfully unbound + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceClearCpuAffinity(nvmlDevice_t device); + +/** + * Get the NUMA node of the given GPU device. + * This only applies to platforms where the GPUs are NUMA nodes. + * + * @param[in] device The device handle + * @param[out] node NUMA node ID of the device + * + * @returns + * - \ref NVML_SUCCESS if the NUMA node is retrieved successfully + * - \ref NVML_ERROR_NOT_SUPPORTED if request is not supported on the current platform + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device \a node is invalid + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNumaNodeId(nvmlDevice_t device, unsigned int *node); + +/** + * Get the addressing mode for a given GPU. Addressing modes can be one of: + * 1. HMM: System allocated memory (malloc, mmap) is addressable from the device (GPU), + * via software-based mirroring of the CPU's page tables, on the GPU. + * 2. ATS: System allocated memory (malloc, mmap) is addressable from the device (GPU), + * via Address Translation Services. This means that there is (effectively) + * a single set of page tables, and the CPU and GPU both use them. + * 3. None: Neither HMM nor ATS is active. + * + * For Turing &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param[in] device The device handle + * @param[out] mode Pointer to addressing mode of the device + * + * @returns + * - \ref NVML_SUCCESS if \a mode is retrieved successfully + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED if request is not supported on the current platform + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device \a node is invalid + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAddressingMode(nvmlDevice_t device, nvmlDeviceAddressingMode_t *mode); + +/** + * Get the repair status for TPC/Channel repair + * + * For Ampere &tm; or newer fully supported devices. + * + * @param[in] device The identifier of the target device + * @param[out] repairStatus Reference to \a nvmlRepairStatus_t + * + * @return + * - \ref NVML_SUCCESS if the query was successful + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the provided version is invalid/unsupported + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRepairStatus(nvmlDevice_t device, nvmlRepairStatus_t *repairStatus); + +/** + * Retrieve the common ancestor for two devices + * For all products. + * Supported on Linux only. + * + * @param device1 The identifier of the first device + * @param device2 The identifier of the second device + * @param pathInfo A \ref nvmlGpuTopologyLevel_t that gives the path type + * + * @return + * - \ref NVML_SUCCESS if \a pathInfo has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device1, or \a device2 is invalid, or \a pathInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or OS does not support this feature + * - \ref NVML_ERROR_UNKNOWN an error has occurred in underlying topology discovery + */ + +/** @} */ +nvmlReturn_t DECLDIR nvmlDeviceGetTopologyCommonAncestor(nvmlDevice_t device1, nvmlDevice_t device2, nvmlGpuTopologyLevel_t *pathInfo); + +/** + * Retrieve the set of GPUs that are nearest to a given device at a specific interconnectivity level + * For all products. + * Supported on Linux only. + * + * @param device The identifier of the first device + * @param level The \ref nvmlGpuTopologyLevel_t level to search for other GPUs + * @param count When zero, is set to the number of matching GPUs such that \a deviceArray + * can be malloc'd. When non-zero, \a deviceArray will be filled with \a count + * number of device handles. + * @param deviceArray An array of device handles for GPUs found at \a level + * + * @return + * - \ref NVML_SUCCESS if \a deviceArray or \a count (if initially zero) has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a level, or \a count is invalid, or \a deviceArray is NULL with a non-zero \a count + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or OS does not support this feature + * - \ref NVML_ERROR_UNKNOWN an error has occurred in underlying topology discovery + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTopologyNearestGpus(nvmlDevice_t device, nvmlGpuTopologyLevel_t level, unsigned int *count, nvmlDevice_t *deviceArray); + +/** + * Retrieve the status for a given p2p capability index between a given pair of GPU + * + * @param device1 The first device + * @param device2 The second device + * @param p2pIndex p2p Capability Index being looked for between \a device1 and \a device2 + * @param p2pStatus Reference in which to return the status of the \a p2pIndex + * between \a device1 and \a device2 + * @return + * - \ref NVML_SUCCESS if \a p2pStatus has been populated + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device1 or \a device2 or \a p2pIndex is invalid or \a p2pStatus is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetP2PStatus(nvmlDevice_t device1, nvmlDevice_t device2, nvmlGpuP2PCapsIndex_t p2pIndex,nvmlGpuP2PStatus_t *p2pStatus); + +/** + * Retrieves the globally unique immutable UUID associated with this device, as a 5 part hexadecimal string, + * that augments the immutable, board serial identifier. + * + * For all products. + * + * The UUID is a globally unique identifier. It is the only available identifier for pre-Fermi-architecture products. + * It does NOT correspond to any identifier printed on the board. It will not exceed 96 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_DEVICE_UUID_V2_BUFFER_SIZE. + * + * When used with MIG device handles the API returns globally unique UUIDs which can be used to identify MIG + * devices across both GPU and MIG devices. UUIDs are immutable for the lifetime of a MIG device. + * + * @param device The identifier of the target device + * @param uuid Reference in which to return the GPU UUID + * @param length The maximum allowed length of the string returned in \a uuid + * + * @return + * - \ref NVML_SUCCESS if \a uuid has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a uuid is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetUUID(nvmlDevice_t device, char *uuid, unsigned int length); + +/** + * Retrieves minor number for the device. The minor number for the device is such that the Nvidia device node file for + * each GPU will have the form /dev/nvidia[minor number]. + * + * For all products. + * Supported only for Linux + * + * @param device The identifier of the target device + * @param minorNumber Reference in which to return the minor number for the device + * @return + * - \ref NVML_SUCCESS if the minor number is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minorNumber is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMinorNumber(nvmlDevice_t device, unsigned int *minorNumber); + +/** + * Retrieves the the device board part number which is programmed into the board's InfoROM + * + * For all products. + * + * @param device Identifier of the target device + * @param partNumber Reference to the buffer to return + * @param length Length of the buffer reference + * + * @return + * - \ref NVML_SUCCESS if \a partNumber has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED if the needed VBIOS fields have not been filled + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a serial is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBoardPartNumber(nvmlDevice_t device, char* partNumber, unsigned int length); + +/** + * Retrieves the version information for the device's infoROM object. + * + * For all products with an inforom. + * + * Fermi and higher parts have non-volatile on-board memory for persisting device info, such as aggregate + * ECC counts. The version of the data structures in this memory may change from time to time. It will not + * exceed 16 characters in length (including the NULL terminator). + * See \ref nvmlConstants::NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE. + * + * See \ref nvmlInforomObject_t for details on the available infoROM objects. + * + * @param device The identifier of the target device + * @param object The target infoROM object + * @param version Reference in which to return the infoROM version + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have an infoROM + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetInforomImageVersion + */ +nvmlReturn_t DECLDIR nvmlDeviceGetInforomVersion(nvmlDevice_t device, nvmlInforomObject_t object, char *version, unsigned int length); + +/** + * Retrieves the global infoROM image version + * + * For all products with an inforom. + * + * Image version just like VBIOS version uniquely describes the exact version of the infoROM flashed on the board + * in contrast to infoROM object version which is only an indicator of supported features. + * Version string will not exceed 16 characters in length (including the NULL terminator). + * See \ref nvmlConstants::NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE. + * + * @param device The identifier of the target device + * @param version Reference in which to return the infoROM image version + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have an infoROM + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetInforomVersion + */ +nvmlReturn_t DECLDIR nvmlDeviceGetInforomImageVersion(nvmlDevice_t device, char *version, unsigned int length); + +/** + * Retrieves the checksum of the configuration stored in the device's infoROM. + * + * For all products with an inforom. + * + * Can be used to make sure that two GPUs have the exact same configuration. + * Current checksum takes into account configuration stored in PWR and ECC infoROM objects. + * Checksum can change between driver releases or when user changes configuration (e.g. disable/enable ECC) + * + * @param device The identifier of the target device + * @param checksum Reference in which to return the infoROM configuration checksum + * + * @return + * - \ref NVML_SUCCESS if \a checksum has been set + * - \ref NVML_ERROR_CORRUPTED_INFOROM if the device's checksum couldn't be retrieved due to infoROM corruption + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a checksum is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetInforomConfigurationChecksum(nvmlDevice_t device, unsigned int *checksum); + +/** + * Reads the infoROM from the flash and verifies the checksums. + * + * For all products with an inforom. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if infoROM is not corrupted + * - \ref NVML_ERROR_CORRUPTED_INFOROM if the device's infoROM is corrupted + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceValidateInforom(nvmlDevice_t device); + +/** + * Retrieves the timestamp and the duration of the last flush of the BBX (blackbox) infoROM object during the current run. + * + * For all products with an inforom. + * + * @param device The identifier of the target device + * @param timestamp The start timestamp of the last BBX Flush + * @param durationUs The duration (us) of the last BBX Flush + * + * @return + * - \ref NVML_SUCCESS if \a timestamp and \a durationUs are successfully retrieved + * - \ref NVML_ERROR_NOT_READY if the BBX object has not been flushed yet + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have an infoROM + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetInforomVersion + */ +nvmlReturn_t DECLDIR nvmlDeviceGetLastBBXFlushTime(nvmlDevice_t device, unsigned long long *timestamp, + unsigned long *durationUs); + +/** + * Retrieves the display mode for the device. + * + * For all products. + * + * This method indicates whether a physical display (e.g. monitor) is currently connected to + * any of the device's connectors. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param display Reference in which to return the display mode + * + * @return + * - \ref NVML_SUCCESS if \a display has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a display is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDisplayMode(nvmlDevice_t device, nvmlEnableState_t *display); + +/** + * Retrieves the display active state for the device. + * + * For all products. + * + * This method indicates whether a display is initialized on the device. + * For example whether X Server is attached to this device and has allocated memory for the screen. + * + * Display can be active even when no monitor is physically attached. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param isActive Reference in which to return the display active state + * + * @return + * - \ref NVML_SUCCESS if \a isActive has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a isActive is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDisplayActive(nvmlDevice_t device, nvmlEnableState_t *isActive); + +/** + * Retrieves the persistence mode associated with this device. + * + * For all products. + * For Linux only. + * + * When driver persistence mode is enabled the driver software state is not torn down when the last + * client disconnects. By default this feature is disabled. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current driver persistence mode + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetPersistenceMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPersistenceMode(nvmlDevice_t device, nvmlEnableState_t *mode); + +/** + * Retrieves PCI attributes of this device. + * + * For all products. + * + * See \ref nvmlPciInfoExt_v1_t for details on the available PCI info. + * + * @param device The identifier of the target device + * @param pci Reference in which to return the PCI info + * + * @return + * - \ref NVML_SUCCESS if \a pci has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pci is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfoExt(nvmlDevice_t device, nvmlPciInfoExt_t *pci); + +/** + * Retrieves the PCI attributes of this device. + * + * For all products. + * + * See \ref nvmlPciInfo_t for details on the available PCI info. + * + * @param device The identifier of the target device + * @param pci Reference in which to return the PCI info + * + * @return + * - \ref NVML_SUCCESS if \a pci has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pci is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfo_v3(nvmlDevice_t device, nvmlPciInfo_t *pci); + +/** + * Retrieves the maximum PCIe link generation possible with this device and system + * + * I.E. for a generation 2 PCIe device attached to a generation 1 PCIe bus the max link generation this function will + * report is generation 1. + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param maxLinkGen Reference in which to return the max PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a maxLinkGen has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a maxLinkGen is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxPcieLinkGeneration(nvmlDevice_t device, unsigned int *maxLinkGen); + +/** + * Retrieves the maximum PCIe link generation supported by this device + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param maxLinkGenDevice Reference in which to return the max PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a maxLinkGenDevice has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a maxLinkGenDevice is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuMaxPcieLinkGeneration(nvmlDevice_t device, unsigned int *maxLinkGenDevice); + +/** + * Retrieves the maximum PCIe link width possible with this device and system + * + * I.E. for a device with a 16x PCIe bus width attached to a 8x PCIe system bus this function will report + * a max link width of 8. + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param maxLinkWidth Reference in which to return the max PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a maxLinkWidth has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a maxLinkWidth is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxPcieLinkWidth(nvmlDevice_t device, unsigned int *maxLinkWidth); + +/** + * Retrieves the current PCIe link generation + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param currLinkGen Reference in which to return the current PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a currLinkGen has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a currLinkGen is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrPcieLinkGeneration(nvmlDevice_t device, unsigned int *currLinkGen); + +/** + * Retrieves the current PCIe link width + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param currLinkWidth Reference in which to return the current PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a currLinkWidth has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a currLinkWidth is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrPcieLinkWidth(nvmlDevice_t device, unsigned int *currLinkWidth); + +/** + * Retrieve PCIe utilization information. + * This function is querying a byte counter over a 20ms interval and thus is the + * PCIe throughput over that interval. + * + * For Maxwell &tm; or newer fully supported devices. + * + * This method is not supported in virtual machines running virtual GPU (vGPU). + * + * @param device The identifier of the target device + * @param counter The specific counter that should be queried \ref nvmlPcieUtilCounter_t + * @param value Reference in which to return throughput in KB/s + * + * @return + * - \ref NVML_SUCCESS if \a value has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a counter is invalid, or \a value is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieThroughput(nvmlDevice_t device, nvmlPcieUtilCounter_t counter, unsigned int *value); + +/** + * Retrieve the PCIe replay counter. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param value Reference in which to return the counter's value + * + * @return + * - \ref NVML_SUCCESS if \a value has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a value is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieReplayCounter(nvmlDevice_t device, unsigned int *value); + +/** + * Retrieves the current clock speeds for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlClockType_t for details on available clock information. + * + * @param device The identifier of the target device + * @param type Identify which clock domain to query + * @param clock Reference in which to return the clock speed in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clock has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clock is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device cannot report the specified clock + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClockInfo(nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock); + +/** + * Retrieves the maximum clock speeds for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlClockType_t for details on available clock information. + * + * \note Current P0 clocks (reported by \ref nvmlDeviceGetClockInfo) can differ from max clocks + * by a few MHz. + * + * @param device The identifier of the target device + * @param type Identify which clock domain to query + * @param clock Reference in which to return the clock speed in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clock has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clock is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device cannot report the specified clock + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock); + +/** + * Retrieve the GPCCLK VF offset value + * @param[in] device The identifier of the target device + * @param[out] offset The retrieved GPCCLK VF offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpcClkVfOffset(nvmlDevice_t device, int *offset); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetApplicationsClock(nvmlDevice_t device, nvmlClockType_t clockType, unsigned int *clockMHz); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetDefaultApplicationsClock(nvmlDevice_t device, nvmlClockType_t clockType, unsigned int *clockMHz); + +/** + * Retrieves the clock speed for the clock specified by the clock type and clock ID. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param clockType Identify which clock domain to query + * @param clockId Identify which clock in the domain to query + * @param clockMHz Reference in which to return the clock in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clockMHz has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clockMHz is NULL or \a clockType is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClock(nvmlDevice_t device, nvmlClockType_t clockType, nvmlClockId_t clockId, unsigned int *clockMHz); + +/** + * Retrieves the customer defined maximum boost clock speed specified by the given clock type. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param clockType Identify which clock domain to query + * @param clockMHz Reference in which to return the clock in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clockMHz has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clockMHz is NULL or \a clockType is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or the \a clockType on this device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxCustomerBoostClock(nvmlDevice_t device, nvmlClockType_t clockType, unsigned int *clockMHz); + +/** + * Retrieves the list of possible memory clocks that can be used as an argument for \ref nvmlDeviceSetMemoryLockedClocks. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param count Reference in which to provide the \a clocksMHz array size, and + * to return the number of elements + * @param clocksMHz Reference in which to return the clock in MHz + * + * @return + * - \ref NVML_SUCCESS if \a count and \a clocksMHz have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a count is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small (\a count is set to the number of + * required elements) + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetMemoryLockedClocks + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedMemoryClocks(nvmlDevice_t device, unsigned int *count, unsigned int *clocksMHz); + +/** + * Retrieves the list of possible graphics clocks that can be used as an argument for \ref nvmlDeviceSetGpuLockedClocks. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param memoryClockMHz Memory clock for which to return possible graphics clocks + * @param count Reference in which to provide the \a clocksMHz array size, and + * to return the number of elements + * @param clocksMHz Reference in which to return the clocks in MHz + * + * @return + * - \ref NVML_SUCCESS if \a count and \a clocksMHz have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_FOUND if the specified \a memoryClockMHz is not a supported frequency + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clock is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetGpuLockedClocks + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedGraphicsClocks(nvmlDevice_t device, unsigned int memoryClockMHz, unsigned int *count, unsigned int *clocksMHz); + +/** + * Retrieve the current state of Auto Boosted clocks on a device and store it in \a isEnabled + * + * For Kepler &tm; or newer fully supported devices. + * + * Auto Boosted clocks are enabled by default on some hardware, allowing the GPU to run at higher clock rates + * to maximize performance as thermal limits allow. + * + * On Pascal and newer hardware, Auto Aoosted clocks are controlled through application clocks. + * Use \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks to control Auto Boost + * behavior. + * + * @param device The identifier of the target device + * @param isEnabled Where to store the current state of Auto Boosted clocks of the target device + * @param defaultIsEnabled Where to store the default Auto Boosted clocks behavior of the target device that the device will + * revert to when no applications are using the GPU + * + * @return + * - \ref NVML_SUCCESS If \a isEnabled has been been set with the Auto Boosted clocks state of \a device + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a isEnabled is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support Auto Boosted clocks + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAutoBoostedClocksEnabled(nvmlDevice_t device, nvmlEnableState_t *isEnabled, nvmlEnableState_t *defaultIsEnabled); + +/** + * Retrieves the intended operating speed of the device's fan. + * + * Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, the + * output will not match the actual fan speed. + * + * For all discrete products with dedicated fans. + * + * The fan speed is expressed as a percentage of the product's maximum noise tolerance fan speed. + * This value may exceed 100% in certain cases. + * + * @param device The identifier of the target device + * @param speed Reference in which to return the fan speed percentage + * + * @return + * - \ref NVML_SUCCESS if \a speed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a speed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanSpeed(nvmlDevice_t device, unsigned int *speed); + +/** + * Retrieves the intended operating speed of the device's specified fan. + * + * Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, the + * output will not match the actual fan speed. + * + * For all discrete products with dedicated fans. + * + * The fan speed is expressed as a percentage of the product's maximum noise tolerance fan speed. + * This value may exceed 100% in certain cases. + * + * @param device The identifier of the target device + * @param fan The index of the target fan, zero indexed. + * @param speed Reference in which to return the fan speed percentage + * + * @return + * - \ref NVML_SUCCESS if \a speed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a fan is not an acceptable index, or \a speed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan or is newer than Maxwell + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanSpeed_v2(nvmlDevice_t device, unsigned int fan, unsigned int * speed); + +/** + * Retrieves the intended operating speed in rotations per minute (RPM) of the device's specified fan. + * + * For Maxwell &tm; or newer fully supported devices. + * + * For all discrete products with dedicated fans. + * + * Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, the + * output will not match the actual fan speed. + * + * @param device The identifier of the target device + * @param fanSpeed Structure specifying the index of the target fan (input) and + * retrieved fan speed value (output) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, \a fan is not an acceptable + * index, or \a speed is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the \a device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanSpeedRPM(nvmlDevice_t device, nvmlFanSpeedInfo_t *fanSpeed); + +/** + * Retrieves the intended target speed of the device's specified fan. + * + * Normally, the driver dynamically adjusts the fan based on + * the needs of the GPU. But when user set fan speed using nvmlDeviceSetFanSpeed_v2, + * the driver will attempt to make the fan achieve the setting in + * nvmlDeviceSetFanSpeed_v2. The actual current speed of the fan + * is reported in nvmlDeviceGetFanSpeed_v2. + * + * For all discrete products with dedicated fans. + * + * The fan speed is expressed as a percentage of the product's maximum noise tolerance fan speed. + * This value may exceed 100% in certain cases. + * + * @param device The identifier of the target device + * @param fan The index of the target fan, zero indexed. + * @param targetSpeed Reference in which to return the fan speed percentage + * + * @return + * - \ref NVML_SUCCESS if \a speed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a fan is not an acceptable index, or \a speed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan or is newer than Maxwell + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTargetFanSpeed(nvmlDevice_t device, unsigned int fan, unsigned int *targetSpeed); + +/** + * Retrieves the min and max fan speed that user can set for the GPU fan. + * + * For all cuda-capable discrete products with fans + * + * @param device The identifier of the target device + * @param minSpeed The minimum speed allowed to set + * @param maxSpeed The maximum speed allowed to set + * + * return + * NVML_SUCCESS if speed has been adjusted + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if device is invalid + * NVML_ERROR_NOT_SUPPORTED if the device does not support this + * (doesn't have fans) + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMinMaxFanSpeed(nvmlDevice_t device, unsigned int * minSpeed, + unsigned int * maxSpeed); + +/** + * Gets current fan control policy. + * + * For Maxwell &tm; or newer fully supported devices. + * + * For all cuda-capable discrete products with fans + * + * device The identifier of the target \a device + * policy Reference in which to return the fan control \a policy + * + * return + * NVML_SUCCESS if \a policy has been populated + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a policy is null or the \a fan given doesn't reference + * a fan that exists. + * NVML_ERROR_NOT_SUPPORTED if the \a device is older than Maxwell + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanControlPolicy_v2(nvmlDevice_t device, unsigned int fan, + nvmlFanControlPolicy_t *policy); + +/** + * Retrieves the number of fans on the device. + * + * For all discrete products with dedicated fans. + * + * @param device The identifier of the target device + * @param numFans The number of fans + * + * @return + * - \ref NVML_SUCCESS if \a fan number query was successful + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a numFans is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNumFans(nvmlDevice_t device, unsigned int *numFans); + +/** + * @deprecated Use \ref nvmlDeviceGetTemperatureV instead + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetTemperature(nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp); + +/** + * Retrieves the cooler's information. + * Returns a cooler's control signal characteristics. The possible types are restricted, Variable and Toggle. + * See \ref nvmlCoolerControl_t for details on available signal types. + * Returns objects that cooler cools. Targets may be GPU, Memory, Power Supply or All of these. + * See \ref nvmlCoolerTarget_t for details on available targets. + * + * For Maxwell &tm; or newer fully supported devices. + * + * For all discrete products with dedicated fans. + * + * @param[in] device The identifier of the target device + * @param[out] coolerInfo Structure specifying the cooler's control signal characteristics (out) + * and the target that cooler cools (out) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, \a signalType or \a target is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the \a device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCoolerInfo(nvmlDevice_t device, nvmlCoolerInfo_t *coolerInfo); + +/** + * Structure used to encapsulate temperature info + */ +typedef struct +{ + unsigned int version; + nvmlTemperatureSensors_t sensorType; + int temperature; +} nvmlTemperature_v1_t; + +typedef nvmlTemperature_v1_t nvmlTemperature_t; + +#define nvmlTemperature_v1 NVML_STRUCT_VERSION(Temperature, 1) + +/** + * Retrieves the current temperature readings (in degrees C) for the given device. + * + * For all products. + * + * @param[in] device Target device identifier. + * @param[in,out] temperature Structure specifying the sensor type (input) and retrieved + * temperature value (output). + * + * @return + * - \ref NVML_SUCCESS if \a temp has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a sensorType is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have the specified sensor + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTemperatureV(nvmlDevice_t device, nvmlTemperature_t *temperature); + + +/** + * Retrieves the temperature threshold for the GPU with the specified threshold type in degrees C. + * + * For Kepler &tm; or newer fully supported devices. + * + * See \ref nvmlTemperatureThresholds_t for details on available temperature thresholds. + * + * Note: This API is no longer the preferred interface for retrieving the following temperature thresholds + * on Ada and later architectures: NVML_TEMPERATURE_THRESHOLD_SHUTDOWN, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN, + * NVML_TEMPERATURE_THRESHOLD_MEM_MAX and NVML_TEMPERATURE_THRESHOLD_GPU_MAX. + * + * Support for reading these temperature thresholds for Ada and later architectures would be removed from this + * API in future releases. Please use \ref nvmlDeviceGetFieldValues with NVML_FI_DEV_TEMPERATURE_* fields to retrieve + * temperature thresholds on these architectures. + * + * @param device The identifier of the target device + * @param thresholdType The type of threshold value queried + * @param temp Reference in which to return the temperature reading + * @return + * - \ref NVML_SUCCESS if \a temp has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a thresholdType is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a temperature sensor or is unsupported + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTemperatureThreshold(nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, unsigned int *temp); + +/** + * Retrieves the thermal margin temperature (distance to nearest slowdown threshold). + * + * @param[in] device The identifier of the target device + * @param[in,out] marginTempInfo Versioned structure in which to return the temperature reading + * + * @returns + * - \ref NVML_SUCCESS if the margin temperature was retrieved successfully + * - \ref NVML_ERROR_NOT_SUPPORTED if request is not supported on the current platform + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a temperature is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the right versioned structure is not used + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMarginTemperature(nvmlDevice_t device, nvmlMarginTemperature_t *marginTempInfo); + +/** + * Used to execute a list of thermal system instructions. + * + * @param device The identifier of the target device + * @param sensorIndex The index of the thermal sensor + * @param pThermalSettings Reference in which to return the thermal sensor information + * + * @return + * - \ref NVML_SUCCESS if \a pThermalSettings has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pThermalSettings is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetThermalSettings(nvmlDevice_t device, unsigned int sensorIndex, nvmlGpuThermalSettings_t *pThermalSettings); + +/** + * Retrieves the current performance state for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlPstates_t for details on allowed performance states. + * + * @param device The identifier of the target device + * @param pState Reference in which to return the performance state reading + * + * @return + * - \ref NVML_SUCCESS if \a pState has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pState is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPerformanceState(nvmlDevice_t device, nvmlPstates_t *pState); + +/** + * Retrieves current clocks event reasons. + * + * For all fully supported products. + * + * \note More than one bit can be enabled at the same time. Multiple reasons can be affecting clocks at once. + * + * @param device The identifier of the target device + * @param clocksEventReasons Reference in which to return bitmask of active clocks event + * reasons + * + * @return + * - \ref NVML_SUCCESS if \a clocksEventReasons has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clocksEventReasons is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlClocksEventReasons + * @see nvmlDeviceGetSupportedClocksEventReasons + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClocksEventReasons(nvmlDevice_t device, unsigned long long *clocksEventReasons); + +/** + * @deprecated Use \ref nvmlDeviceGetCurrentClocksEventReasons instead + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClocksThrottleReasons(nvmlDevice_t device, unsigned long long *clocksThrottleReasons); + +/** + * Retrieves bitmask of supported clocks event reasons that can be returned by + * \ref nvmlDeviceGetCurrentClocksEventReasons + * + * For all fully supported products. + * + * This method is not supported in virtual machines running virtual GPU (vGPU). + * + * @param device The identifier of the target device + * @param supportedClocksEventReasons Reference in which to return bitmask of supported + * clocks event reasons + * + * @return + * - \ref NVML_SUCCESS if \a supportedClocksEventReasons has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a supportedClocksEventReasons is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlClocksEventReasons + * @see nvmlDeviceGetCurrentClocksEventReasons + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedClocksEventReasons(nvmlDevice_t device, unsigned long long *supportedClocksEventReasons); + +/** + * @deprecated Use \ref nvmlDeviceGetSupportedClocksEventReasons instead + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetSupportedClocksThrottleReasons(nvmlDevice_t device, unsigned long long *supportedClocksThrottleReasons); + +/** + * @deprecated Use \ref nvmlDeviceGetPerformanceState. This function exposes an incorrect generalization. + * + * Retrieve the current performance state for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlPstates_t for details on allowed performance states. + * + * @param device The identifier of the target device + * @param pState Reference in which to return the performance state reading + * + * @return + * - \ref NVML_SUCCESS if \a pState has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pState is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetPowerState(nvmlDevice_t device, nvmlPstates_t *pState); + +/** + * Retrieve performance monitor samples from the associated subdevice. + * + * @param device + * @param pDynamicPstatesInfo + * + * @return + * - \ref NVML_SUCCESS if \a pDynamicPstatesInfo has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pDynamicPstatesInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDynamicPstatesInfo(nvmlDevice_t device, nvmlGpuDynamicPstatesInfo_t *pDynamicPstatesInfo); + +/** + * Retrieve the MemClk (Memory Clock) VF offset value. + * @param[in] device The identifier of the target device + * @param[out] offset The retrieved MemClk VF offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemClkVfOffset(nvmlDevice_t device, int *offset); + +/** + * Retrieve min and max clocks of some clock domain for a given PState + * + * @param device The identifier of the target device + * @param type Clock domain + * @param pstate PState to query + * @param minClockMHz Reference in which to return min clock frequency + * @param maxClockMHz Reference in which to return max clock frequency + * + * @return + * - \ref NVML_SUCCESS if everything worked + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a type or \a minClockMHz and \a maxClockMHz are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN if \a type or \a pstate are invalid or any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMinMaxClockOfPState(nvmlDevice_t device, nvmlClockType_t type, nvmlPstates_t pstate, + unsigned int * minClockMHz, unsigned int * maxClockMHz); + +/** + * Get all supported Performance States (P-States) for the device. + * + * The returned array would contain a contiguous list of valid P-States supported by + * the device. If the number of supported P-States is fewer than the size of the array + * supplied missing elements would contain \a NVML_PSTATE_UNKNOWN. + * + * The number of elements in the returned list will never exceed \a NVML_MAX_GPU_PERF_PSTATES. + * + * @param device The identifier of the target device + * @param pstates Container to return the list of performance states + * supported by device + * @param size Size of the supplied \a pstates array in bytes + * + * @return + * - \ref NVML_SUCCESS if \a pstates array has been retrieved + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if the the container supplied was not large enough to + * hold the resulting list + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a pstates is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support performance state readings + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedPerformanceStates(nvmlDevice_t device, + nvmlPstates_t *pstates, unsigned int size); + +/** + * Retrieve the GPCCLK min max VF offset value. + * @param[in] device The identifier of the target device + * @param[out] minOffset The retrieved GPCCLK VF min offset value + * @param[out] maxOffset The retrieved GPCCLK VF max offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpcClkMinMaxVfOffset(nvmlDevice_t device, + int *minOffset, int *maxOffset); + +/** + * Retrieve the MemClk (Memory Clock) min max VF offset value. + * @param[in] device The identifier of the target device + * @param[out] minOffset The retrieved MemClk VF min offset value + * @param[out] maxOffset The retrieved MemClk VF max offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemClkMinMaxVfOffset(nvmlDevice_t device, + int *minOffset, int *maxOffset); + +/** + * Retrieve min, max and current clock offset of some clock domain for a given PState + * + * For Maxwell &tm; or newer fully supported devices. + * + * Note: \ref nvmlDeviceGetGpcClkVfOffset, \ref nvmlDeviceGetMemClkVfOffset, \ref nvmlDeviceGetGpcClkMinMaxVfOffset and + * \ref nvmlDeviceGetMemClkMinMaxVfOffset will be deprecated in a future release. + Use \ref nvmlDeviceGetClockOffsets instead. + * + * @param device The identifier of the target device + * @param info Structure specifying the clock type (input) and the pstate (input) + * retrieved clock offset value (output), min clock offset (output) + * and max clock offset (output) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a type or \a pstate are invalid or both + * \a minClockOffsetMHz and \a maxClockOffsetMHz are NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClockOffsets(nvmlDevice_t device, nvmlClockOffset_t *info); + +/** + * Control current clock offset of some clock domain for a given PState + * + * For Maxwell &tm; or newer fully supported devices. + * + * Requires privileged user. + * + * @param device The identifier of the target device + * @param info Structure specifying the clock type (input), the pstate (input) + * and clock offset value (input) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_NO_PERMISSION If the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a type or \a pstate are invalid or both + * \a clockOffsetMHz is out of allowed range. + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceSetClockOffsets(nvmlDevice_t device, nvmlClockOffset_t *info); + +/** + * Retrieves a performance mode string with all the + * performance modes defined for this device along with their associated + * GPU Clock and Memory Clock values. + * Not all tokens will be reported on all GPUs, and additional tokens + * may be added in the future. + * For backwards compatibility we still provide nvclock and memclock; + * those are the same as nvclockmin and memclockmin. + * + * Note: These clock values take into account the offset + * set by clients through /ref nvmlDeviceSetClockOffsets. + * + * Maximum available Pstate (P15) shows the minimum performance level (0) and vice versa. + * + * Each performance modes are returned as a comma-separated list of + * "token=value" pairs. Each set of performance mode tokens are separated + * by a ";". Valid tokens: + * + * Token Value + * "perf" unsigned int - the Performance level + * "nvclock" unsigned int - the GPU clocks (in MHz) for the perf level + * "nvclockmin" unsigned int - the GPU clocks min (in MHz) for the perf level + * "nvclockmax" unsigned int - the GPU clocks max (in MHz) for the perf level + * "nvclockeditable" unsigned int - if the GPU clock domain is editable for the perf level + * "memclock" unsigned int - the memory clocks (in MHz) for the perf level + * "memclockmin" unsigned int - the memory clocks min (in MHz) for the perf level + * "memclockmax" unsigned int - the memory clocks max (in MHz) for the perf level + * "memclockeditable" unsigned int - if the memory clock domain is editable for the perf level + * "memtransferrate" unsigned int - the memory transfer rate (in MHz) for the perf level + * "memtransferratemin" unsigned int - the memory transfer rate min (in MHz) for the perf level + * "memtransferratemax" unsigned int - the memory transfer rate max (in MHz) for the perf level + * "memtransferrateeditable" unsigned int - if the memory transfer rate is editable for the perf level + * + * Example: + * + * perf=0, nvclock=324, nvclockmin=324, nvclockmax=324, nvclockeditable=0, + * memclock=324, memclockmin=324, memclockmax=324, memclockeditable=0, + * memtransferrate=648, memtransferratemin=648, memtransferratemax=648, + * memtransferrateeditable=0 ; + * perf=1, nvclock=324, nvclockmin=324, nvclockmax=640, nvclockeditable=0, + * memclock=810, memclockmin=810, memclockmax=810, memclockeditable=0, + * memtransferrate=1620, memtransferrate=1620, memtransferrate=1620, + * memtransferrateeditable=0 ; + * + * + * @param device The identifier of the target device + * @param perfModes Reference in which to return the performance level string + * + * @return + * - \ref NVML_SUCCESS if \a perfModes has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPerformanceModes(nvmlDevice_t device, nvmlDevicePerfModes_t *perfModes); + +/** + * Retrieves a string with the associated current GPU Clock and Memory Clock values. + * + * Not all tokens will be reported on all GPUs, and additional tokens + * may be added in the future. + * + * Note: These clock values take into account the offset + * set by clients through /ref nvmlDeviceSetClockOffsets. + * + * Clock values are returned as a comma-separated list of + * "token=value" pairs. + * Valid tokens: + * + * Token Value + * "perf" unsigned int - the Performance level + * "nvclock" unsigned int - the GPU clocks (in MHz) for the perf level + * "nvclockmin" unsigned int - the GPU clocks min (in MHz) for the perf level + * "nvclockmax" unsigned int - the GPU clocks max (in MHz) for the perf level + * "nvclockeditable" unsigned int - if the GPU clock domain is editable for the perf level + * "memclock" unsigned int - the memory clocks (in MHz) for the perf level + * "memclockmin" unsigned int - the memory clocks min (in MHz) for the perf level + * "memclockmax" unsigned int - the memory clocks max (in MHz) for the perf level + * "memclockeditable" unsigned int - if the memory clock domain is editable for the perf level + * "memtransferrate" unsigned int - the memory transfer rate (in MHz) for the perf level + * "memtransferratemin" unsigned int - the memory transfer rate min (in MHz) for the perf level + * "memtransferratemax" unsigned int - the memory transfer rate max (in MHz) for the perf level + * "memtransferrateeditable" unsigned int - if the memory transfer rate is editable for the perf level + * + * Example: + * + * nvclock=324, nvclockmin=324, nvclockmax=324, nvclockeditable=0, + * memclock=324, memclockmin=324, memclockmax=324, memclockeditable=0, + * memtransferrate=648, memtransferratemin=648, memtransferratemax=648, + * memtransferrateeditable=0 ; + * + * + * @param device The identifier of the target device + * @param currentClockFreqs Reference in which to return the performance level string + * + * @return + * - \ref NVML_SUCCESS if \a currentClockFreqs has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClockFreqs(nvmlDevice_t device, nvmlDeviceCurrentClockFreqs_t *currentClockFreqs); + +/** + * @deprecated This API has been deprecated. + * + * Retrieves the power management mode associated with this device. + * + * For products from the Fermi family. + * - Requires \a NVML_INFOROM_POWER version 3.0 or higher. + * + * For from the Kepler or newer families. + * - Does not require \a NVML_INFOROM_POWER object. + * + * This flag indicates whether any power management algorithm is currently active on the device. An + * enabled state does not necessarily mean the device is being actively throttled -- only that + * that the driver will do so if the appropriate conditions are met. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current power management mode + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementMode(nvmlDevice_t device, nvmlEnableState_t *mode); + +/** + * Retrieves the power management limit associated with this device. + * + * For Fermi &tm; or newer fully supported devices. + * + * The power limit defines the upper boundary for the card's power draw. If + * the card's total power draw reaches this limit the power management algorithm kicks in. + * + * This reading is only available if power management mode is supported. + * See \ref nvmlDeviceGetPowerManagementMode. + * + * @param device The identifier of the target device + * @param limit Reference in which to return the power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a limit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementLimit(nvmlDevice_t device, unsigned int *limit); + +/** + * Retrieves information about possible values of power management limits on this device. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param minLimit Reference in which to return the minimum power management limit in milliwatts + * @param maxLimit Reference in which to return the maximum power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a minLimit and \a maxLimit have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minLimit or \a maxLimit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetPowerManagementLimit + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementLimitConstraints(nvmlDevice_t device, unsigned int *minLimit, unsigned int *maxLimit); + +/** + * Retrieves default power management limit on this device, in milliwatts. + * Default power management limit is a power management limit that the device boots with. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param defaultLimit Reference in which to return the default power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a defaultLimit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a defaultLimit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementDefaultLimit(nvmlDevice_t device, unsigned int *defaultLimit); + +/** + * Retrieves power usage for this GPU in milliwatts and its associated circuitry (e.g. memory) + * + * For Fermi &tm; or newer fully supported devices. + * + * On Fermi and Kepler GPUs the reading is accurate to within +/- 5% of current power draw. On Ampere + * (except GA100) or newer GPUs, the API returns power averaged over 1 sec interval. On GA100 and + * older architectures, instantaneous power is returned. + * + * See \ref NVML_FI_DEV_POWER_AVERAGE and \ref NVML_FI_DEV_POWER_INSTANT to query specific power + * values. + * + * It is only available if power management mode is supported. See \ref nvmlDeviceGetPowerManagementMode. + * + * @param device The identifier of the target device + * @param power Reference in which to return the power usage information + * + * @return + * - \ref NVML_SUCCESS if \a power has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a power is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support power readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerUsage(nvmlDevice_t device, unsigned int *power); + +/** + * Retrieves current power mizer mode on this device. + * + * PowerMizerMode provides a hint to the driver as to how to manage the performance of the GPU. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param powerMizerMode Reference in which to return the power mizer mode + * @param supportedPowerMizerModes Reference in which to return the bitmask of supported power mizer modes on this device. + * The supported modes can be combined using the bitwise OR operator '|'. + * For example, if a device supports all PowerMizer modes, the bitmask would be: + * supportedPowerMizerModes = ((1 << NVML_POWER_MIZER_MODE_ADAPTIVE) | + * (1 << NVML_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE) | + * (1 << NVML_POWER_MIZER_MODE_AUTO) | + * (1 << NVML_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE)); + * This bitmask can be used to check which power mizer modes are available on the device by performing + * a bitwise AND operation with the specific mode you want to check. + * + * @return + * - \ref NVML_SUCCESS if \a powerMizerMode has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a powerMizerMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support powerMizerMode readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceGetPowerMizerMode_v1(nvmlDevice_t device, nvmlDevicePowerMizerModes_v1_t *powerMizerMode); + +/** + * Sets the new power mizer mode. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param powerMizerMode Reference in which to set the power mizer mode. + * + * @return + * - \ref NVML_SUCCESS if \a powerMizerMode has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a powerMizerMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support powerMizerMode readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceSetPowerMizerMode_v1(nvmlDevice_t device, nvmlDevicePowerMizerModes_v1_t *powerMizerMode); + + +/** + * Retrieves total energy consumption for this GPU in millijoules (mJ) since the driver was last reloaded + * + * For Volta &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param energy Reference in which to return the energy consumption information + * + * @return + * - \ref NVML_SUCCESS if \a energy has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a energy is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support energy readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTotalEnergyConsumption(nvmlDevice_t device, unsigned long long *energy); + +/** + * Get the effective power limit that the driver enforces after taking into account all limiters + * + * Note: This can be different from the \ref nvmlDeviceGetPowerManagementLimit if other limits are set elsewhere + * This includes the out of band power limit interface + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The device to communicate with + * @param limit Reference in which to return the power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a limit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEnforcedPowerLimit(nvmlDevice_t device, unsigned int *limit); + +/** + * Retrieves the current GOM and pending GOM (the one that GPU will switch to after reboot). + * + * For GK110 M-class and X-class Tesla &tm; products from the Kepler family. + * Modes \ref NVML_GOM_LOW_DP and \ref NVML_GOM_ALL_ON are supported on fully supported GeForce products. + * Not supported on Quadro ® and Tesla &tm; C-class products. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current GOM + * @param pending Reference in which to return the pending GOM + * + * @return + * - \ref NVML_SUCCESS if \a mode has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a current or \a pending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlGpuOperationMode_t + * @see nvmlDeviceSetGpuOperationMode + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuOperationMode(nvmlDevice_t device, nvmlGpuOperationMode_t *current, nvmlGpuOperationMode_t *pending); + +/** + * Retrieves the amount of used, free, reserved and total memory available on the device, in bytes. + * The reserved amount is supported on version 2 only. + * + * For all products. + * + * Enabling ECC reduces the amount of total available memory, due to the extra required parity bits. + * Under WDDM most device memory is allocated and managed on startup by Windows. + * + * Under Linux and Windows TCC, the reported amount of used memory is equal to the sum of memory allocated + * by all active channels on the device. + * + * See \ref nvmlMemory_v2_t for details on available memory info. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate + * information, only if the caller has appropriate privileges. Per-instance + * information can be queried by using specific MIG device handles. + * + * @note nvmlDeviceGetMemoryInfo_v2 adds additional memory information. + * + * @note On systems where GPUs are NUMA nodes, the accuracy of FB memory utilization + * provided by this API depends on the memory accounting of the operating system. + * This is because FB memory is managed by the operating system instead of the NVIDIA GPU driver. + * Typically, pages allocated from FB memory are not released even after + * the process terminates to enhance performance. In scenarios where + * the operating system is under memory pressure, it may resort to utilizing FB memory. + * Such actions can result in discrepancies in the accuracy of memory reporting. + * + * @note On certain SOC platforms, the integrated GPU (iGPU) does not use a dedicated framebuffer + * but instead shares memory with the system. As a result, \ref NVML_ERROR_NOT_SUPPORTED + * will be returned in this case. + * + * @param device The identifier of the target device + * @param memory Reference in which to return the memory information + * + * @return + * - \ref NVML_SUCCESS if \a memory has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if video memory is unsupported on the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo(nvmlDevice_t device, nvmlMemory_t *memory); + +/** + * nvmlDeviceGetMemoryInfo_v2 accounts separately for reserved memory and includes it in the used memory amount. + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo_v2(nvmlDevice_t device, nvmlMemory_v2_t *memory); + +/** + * Retrieves the current compute mode for the device. + * + * For all products. + * + * See \ref nvmlComputeMode_t for details on allowed compute modes. + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current compute mode + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetComputeMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetComputeMode(nvmlDevice_t device, nvmlComputeMode_t *mode); + +/** + * Retrieves the CUDA compute capability of the device. + * + * For all products. + * + * Returns the major and minor compute capability version numbers of the + * device. The major and minor versions are equivalent to the + * CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR and + * CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR attributes that would be + * returned by CUDA's cuDeviceGetAttribute(). + * + * @param device The identifier of the target device + * @param major Reference in which to return the major CUDA compute capability + * @param minor Reference in which to return the minor CUDA compute capability + * + * @return + * - \ref NVML_SUCCESS if \a major and \a minor have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a major or \a minor are NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCudaComputeCapability(nvmlDevice_t device, int *major, int *minor); + +/** + * Retrieves the current and pending DRAM Encryption modes for the device. + * + * For Blackwell &tm; or newer fully supported devices. + * Only applicable to devices that support DRAM Encryption + * Requires \a NVML_INFOROM_DEN version 1.0 or higher. + * + * Changing DRAM Encryption modes requires a reboot. The "pending" DRAM Encryption mode refers to the target mode following + * the next reboot. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current DRAM Encryption mode + * @param pending Reference in which to return the pending DRAM Encryption mode + * + * @return + * - \ref NVML_SUCCESS if \a current and \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or either \a current or \a pending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the argument version is not supported + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetDramEncryptionMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDramEncryptionMode(nvmlDevice_t device, nvmlDramEncryptionInfo_t *current, nvmlDramEncryptionInfo_t *pending); + +/** + * Set the DRAM Encryption mode for the device. + * + * For Kepler &tm; or newer fully supported devices. + * Only applicable to devices that support DRAM Encryption. + * Requires \a NVML_INFOROM_DEN version 1.0 or higher. + * Requires root/admin permissions. + * + * The DRAM Encryption mode determines whether the GPU enables its DRAM Encryption support. + * + * This operation takes effect after the next reboot. + * + * See \ref nvmlEnableState_t for details on available modes. + * + * @param device The identifier of the target device + * @param dramEncryption The target DRAM Encryption mode + * + * @return + * - \ref NVML_SUCCESS if the DRAM Encryption mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a DRAM Encryption is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the argument version is not supported + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetDramEncryptionMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDramEncryptionMode(nvmlDevice_t device, const nvmlDramEncryptionInfo_t *dramEncryption); + +/** + * Retrieves the current and pending ECC modes for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * + * Changing ECC modes requires a reboot. The "pending" ECC mode refers to the target mode following + * the next reboot. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current ECC mode + * @param pending Reference in which to return the pending ECC mode + * + * @return + * - \ref NVML_SUCCESS if \a current and \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or either \a current or \a pending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetEccMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEccMode(nvmlDevice_t device, nvmlEnableState_t *current, nvmlEnableState_t *pending); + +/** + * Retrieves the default ECC modes for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param defaultMode Reference in which to return the default ECC mode + * + * @return + * - \ref NVML_SUCCESS if \a current and \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a default is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetEccMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDefaultEccMode(nvmlDevice_t device, nvmlEnableState_t *defaultMode); + +/** + * Retrieves the device boardId from 0-N. + * Devices with the same boardId indicate GPUs connected to the same PLX. Use in conjunction with + * \ref nvmlDeviceGetMultiGpuBoard() to decide if they are on the same board as well. + * The boardId returned is a unique ID for the current configuration. Uniqueness and ordering across + * reboots and system configurations is not guaranteed (i.e. if a Tesla K40c returns 0x100 and + * the two GPUs on a Tesla K10 in the same system returns 0x200 it is not guaranteed they will + * always return those values but they will always be different from each other). + * + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param boardId Reference in which to return the device's board ID + * + * @return + * - \ref NVML_SUCCESS if \a boardId has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a boardId is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBoardId(nvmlDevice_t device, unsigned int *boardId); + +/** + * Retrieves whether the device is on a Multi-GPU Board + * Devices that are on multi-GPU boards will set \a multiGpuBool to a non-zero value. + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param multiGpuBool Reference in which to return a zero or non-zero value + * to indicate whether the device is on a multi GPU board + * + * @return + * - \ref NVML_SUCCESS if \a multiGpuBool has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a multiGpuBool is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMultiGpuBoard(nvmlDevice_t device, unsigned int *multiGpuBool); + +/** + * Retrieves the total ECC error counts for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * Requires ECC Mode to be enabled. + * + * The total error count is the sum of errors across each of the separate memory systems, i.e. the total set of + * errors across the entire device. + * + * See \ref nvmlMemoryErrorType_t for a description of available error types.\n + * See \ref nvmlEccCounterType_t for a description of available counter types. + * + * @param device The identifier of the target device + * @param errorType Flag that specifies the type of the errors. + * @param counterType Flag that specifies the counter-type of the errors. + * @param eccCounts Reference in which to return the specified ECC errors + * + * @return + * - \ref NVML_SUCCESS if \a eccCounts has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a errorType or \a counterType is invalid, or \a eccCounts is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceClearEccErrorCounts() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTotalEccErrors(nvmlDevice_t device, nvmlMemoryErrorType_t errorType, nvmlEccCounterType_t counterType, unsigned long long *eccCounts); + +/** + * Retrieves the detailed ECC error counts for the device. + * + * @deprecated This API supports only a fixed set of ECC error locations + * On different GPU architectures different locations are supported + * See \ref nvmlDeviceGetMemoryErrorCounter + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 2.0 or higher to report aggregate location-based ECC counts. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher to report all other ECC counts. + * Requires ECC Mode to be enabled. + * + * Detailed errors provide separate ECC counts for specific parts of the memory system. + * + * Reports zero for unsupported ECC error counters when a subset of ECC error counters are supported. + * + * See \ref nvmlMemoryErrorType_t for a description of available bit types.\n + * See \ref nvmlEccCounterType_t for a description of available counter types.\n + * See \ref nvmlEccErrorCounts_t for a description of provided detailed ECC counts. + * + * @param device The identifier of the target device + * @param errorType Flag that specifies the type of the errors. + * @param counterType Flag that specifies the counter-type of the errors. + * @param eccCounts Reference in which to return the specified ECC errors + * + * @return + * - \ref NVML_SUCCESS if \a eccCounts has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a errorType or \a counterType is invalid, or \a eccCounts is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceClearEccErrorCounts() + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetDetailedEccErrors(nvmlDevice_t device, nvmlMemoryErrorType_t errorType, nvmlEccCounterType_t counterType, nvmlEccErrorCounts_t *eccCounts); + +/** + * Retrieves the requested memory error counter for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Requires \a NVML_INFOROM_ECC version 2.0 or higher to report aggregate location-based memory error counts. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher to report all other memory error counts. + * + * Only applicable to devices with ECC. + * + * Requires ECC Mode to be enabled. + * + * @note On MIG-enabled GPUs, per instance information can be queried using specific + * MIG device handles. Per instance information is currently only supported for + * non-DRAM uncorrectable volatile errors. Querying volatile errors using device + * handles is currently not supported. + * + * See \ref nvmlMemoryErrorType_t for a description of available memory error types.\n + * See \ref nvmlEccCounterType_t for a description of available counter types.\n + * See \ref nvmlMemoryLocation_t for a description of available counter locations.\n + * + * @param device The identifier of the target device + * @param errorType Flag that specifies the type of error. + * @param counterType Flag that specifies the counter-type of the errors. + * @param locationType Specifies the location of the counter. + * @param count Reference in which to return the ECC counter + * + * @return + * - \ref NVML_SUCCESS if \a count has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a bitTyp,e \a counterType or \a locationType is + * invalid, or \a count is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support ECC error reporting in the specified memory + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryErrorCounter(nvmlDevice_t device, nvmlMemoryErrorType_t errorType, + nvmlEccCounterType_t counterType, + nvmlMemoryLocation_t locationType, unsigned long long *count); + +/** + * Retrieves the current utilization rates for the device's major subsystems. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlUtilization_t for details on available utilization rates. + * + * \note During driver initialization when ECC is enabled one can see high GPU and Memory Utilization readings. + * This is caused by ECC Memory Scrubbing mechanism that is performed during driver initialization. + * + * @note On MIG-enabled GPUs, querying device utilization rates is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference in which to return the utilization information + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a utilization is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetUtilizationRates(nvmlDevice_t device, nvmlUtilization_t *utilization); + +/** + * Retrieves the current utilization and sampling size in microseconds for the Encoder + * + * For Kepler &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying encoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for encoder utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** + * Retrieves the current capacity of the device's encoder, as a percentage of maximum encoder capacity with valid values in the range 0-100. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param encoderQueryType Type of encoder to query + * @param encoderCapacity Reference to an unsigned int for the encoder capacity + * + * @return + * - \ref NVML_SUCCESS if \a encoderCapacity is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a encoderCapacity is NULL, or \a device or \a encoderQueryType + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if device does not support the encoder specified in \a encodeQueryType + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderCapacity (nvmlDevice_t device, nvmlEncoderType_t encoderQueryType, unsigned int *encoderCapacity); + +/** + * Retrieves the current encoder statistics for a given device. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param sessionCount Reference to an unsigned int for count of active encoder sessions + * @param averageFps Reference to an unsigned int for trailing average FPS of all active sessions + * @param averageLatency Reference to an unsigned int for encode latency in microseconds + * + * @return + * - \ref NVML_SUCCESS if \a sessionCount, \a averageFps and \a averageLatency is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount, or \a device or \a averageFps, + * or \a averageLatency is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderStats (nvmlDevice_t device, unsigned int *sessionCount, + unsigned int *averageFps, unsigned int *averageLatency); + +/** + * Retrieves information about active encoder sessions on a target device. + * + * An array of active encoder sessions is returned in the caller-supplied buffer pointed at by \a sessionInfos. The + * array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions + * written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the active session array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlEncoderSessionInfo_t array required in \a sessionCount. + * To query the number of active encoder sessions, call this function with *sessionCount = 0. The code will return + * NVML_SUCCESS with number of active encoder sessions updated in *sessionCount. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param sessionCount Reference to caller supplied array size, and returns the number of sessions. + * @param sessionInfos Reference in which to return the session information + * + * @return + * - \ref NVML_SUCCESS if \a sessionInfos is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is returned in \a sessionCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount is NULL. + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderSessions(nvmlDevice_t device, unsigned int *sessionCount, nvmlEncoderSessionInfo_t *sessionInfos); + +/** + * Retrieves the current utilization and sampling size in microseconds for the Decoder + * + * For Kepler &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for decoder utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDecoderUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** + * Retrieves the current utilization and sampling size in microseconds for the JPG + * + * For Turing &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for jpg utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetJpgUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** + * Retrieves the current utilization and sampling size in microseconds for the OFA (Optical Flow Accelerator) + * + * For Turing &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for ofa utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetOfaUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** +* Retrieves the active frame buffer capture sessions statistics for a given device. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @param device The identifier of the target device +* @param fbcStats Reference to nvmlFBCStats_t structure containing NvFBC stats +* +* @return +* - \ref NVML_SUCCESS if \a fbcStats is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a fbcStats is NULL +* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetFBCStats(nvmlDevice_t device, nvmlFBCStats_t *fbcStats); + +/** +* Retrieves information about active frame buffer capture sessions on a target device. +* +* An array of active FBC sessions is returned in the caller-supplied buffer pointed at by \a sessionInfo. The +* array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions +* written to the buffer. +* +* If the supplied buffer is not large enough to accommodate the active session array, the function returns +* NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlFBCSessionInfo_t array required in \a sessionCount. +* To query the number of active FBC sessions, call this function with *sessionCount = 0. The code will return +* NVML_SUCCESS with number of active FBC sessions updated in *sessionCount. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @note hResolution, vResolution, averageFPS and averageLatency data for a FBC session returned in \a sessionInfo may +* be zero if there are no new frames captured since the session started. +* +* @param device The identifier of the target device +* @param sessionCount Reference to caller supplied array size, and returns the number of sessions. +* @param sessionInfo Reference in which to return the session information +* +* @return +* - \ref NVML_SUCCESS if \a sessionInfo is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is returned in \a sessionCount +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount is NULL. +* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetFBCSessions(nvmlDevice_t device, unsigned int *sessionCount, nvmlFBCSessionInfo_t *sessionInfo); + +/** + * Retrieves the current and pending driver model for the device. + * + * For Kepler &tm; or newer fully supported devices. + * For windows only. + * + * On Windows platforms the device driver can run in either WDDM, MCDM or WDM (TCC) modes. If a display is attached + * to the device it must run in WDDM mode. MCDM mode is preferred if a display is not attached. TCC mode is deprecated. + * + * See \ref nvmlDriverModel_t for details on available driver models. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current driver model + * @param pending Reference in which to return the pending driver model + * + * @return + * - \ref NVML_SUCCESS if either \a current and/or \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or both \a current and \a pending are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the platform is not windows + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetDriverModel_v2() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDriverModel_v2(nvmlDevice_t device, nvmlDriverModel_t *current, nvmlDriverModel_t *pending); + +/** + * Get VBIOS version of the device. + * + * For all products. + * + * The VBIOS version may change from time to time. It will not exceed 32 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE. + * + * @param device The identifier of the target device + * @param version Reference to which to return the VBIOS version + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVbiosVersion(nvmlDevice_t device, char *version, unsigned int length); + +/** + * Get Bridge Chip Information for all the bridge chips on the board. + * + * For all fully supported products. + * Only applicable to multi-GPU products. + * + * @param device The identifier of the target device + * @param bridgeHierarchy Reference to the returned bridge chip Hierarchy + * + * @return + * - \ref NVML_SUCCESS if bridge chip exists + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a bridgeInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if bridge chip not supported on the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBridgeChipInfo(nvmlDevice_t device, nvmlBridgeChipHierarchy_t *bridgeHierarchy); + +/** + * Get information about processes with a compute context on a device + * + * For Fermi &tm; or newer fully supported devices. + * + * This function returns information only about compute running processes (e.g. CUDA application which have + * active context). Any graphics applications (e.g. using OpenGL, DirectX) won't be listed by this function. + * + * To query the current number of running compute processes, call this function with *infoCount = 0. The + * return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if none are running. For this call + * \a infos is allowed to be NULL. + * + * The usedGpuMemory field returned is all of the memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a infos table in case new compute processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in vGPU Host virtualization mode. + * + * @param device The device handle or MIG device handle + * @param infoCount Reference in which to provide the \a infos array size, and + * to return the number of returned elements + * @param infos Reference in which to return the process information + * + * @return + * - \ref NVML_SUCCESS if \a infoCount and \a infos have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a infoCount indicates that the \a infos array is too small + * \a infoCount will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, either of \a infoCount or \a infos is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see \ref nvmlSystemGetProcessName + */ +nvmlReturn_t DECLDIR nvmlDeviceGetComputeRunningProcesses_v3(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_t *infos); + +/** + * Get information about processes with a graphics context on a device + * + * For Kepler &tm; or newer fully supported devices. + * + * This function returns information only about graphics based processes + * (eg. applications using OpenGL, DirectX) + * + * To query the current number of running graphics processes, call this function with *infoCount = 0. The + * return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if none are running. For this call + * \a infos is allowed to be NULL. + * + * The usedGpuMemory field returned is all of the memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a infos table in case new graphics processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in vGPU Host virtualization mode. + * + * @param device The device handle or MIG device handle + * @param infoCount Reference in which to provide the \a infos array size, and + * to return the number of returned elements + * @param infos Reference in which to return the process information + * + * @return + * - \ref NVML_SUCCESS if \a infoCount and \a infos have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a infoCount indicates that the \a infos array is too small + * \a infoCount will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, either of \a infoCount or \a infos is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see \ref nvmlSystemGetProcessName + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGraphicsRunningProcesses_v3(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_t *infos); + +/** + * Get information about processes with a Multi-Process Service (MPS) compute context on a device + * + * For Volta &tm; or newer fully supported devices. + * + * This function returns information only about compute running processes (e.g. CUDA application which have + * active context) utilizing MPS. Any graphics applications (e.g. using OpenGL, DirectX) won't be listed by + * this function. + * + * To query the current number of running compute processes, call this function with *infoCount = 0. The + * return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if none are running. For this call + * \a infos is allowed to be NULL. + * + * The usedGpuMemory field returned is all of the memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a infos table in case new compute processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in vGPU Host virtualization mode. + * + * @param device The device handle or MIG device handle + * @param infoCount Reference in which to provide the \a infos array size, and + * to return the number of returned elements + * @param infos Reference in which to return the process information + * + * @return + * - \ref NVML_SUCCESS if \a infoCount and \a infos have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a infoCount indicates that the \a infos array is too small + * \a infoCount will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, either of \a infoCount or \a infos is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see \ref nvmlSystemGetProcessName + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses_v3(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_t *infos); + +/** + * Get information about running processes on a device for input context + * + * For Hopper &tm; or newer fully supported devices. + * + * This function returns information only about running processes (e.g. CUDA application which have + * active context). + * + * To determine the size of the \a plist->procArray array to allocate, call the function with + * \a plist->numProcArrayEntries set to zero and \a plist->procArray set to NULL. The return + * code will be either NVML_ERROR_INSUFFICIENT_SIZE (if there are valid processes of type + * \a plist->mode to report on, in which case the \a plist->numProcArrayEntries field will + * indicate the required number of entries in the array) or NVML_SUCCESS (if no processes of type + * \a plist->mode exist). + * + * The usedGpuMemory field returned is all of the memory used by the application. + * The usedGpuCcProtectedMemory field returned is all of the protected memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a plist->procArray table in case new processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in + * vGPU Host virtualization mode. + * Protected memory usage is currently not available in MIG mode and in windows. + * + * @param device The device handle or MIG device handle + * @param plist Reference in which to process detail list + * \a plist->version The api version + * \a plist->mode The process mode + * \a plist->procArray Reference in which to return the process information + * \a plist->numProcArrayEntries Proc array size of returned entries + * + * @return + * - \ref NVML_SUCCESS if \a plist->numprocArrayEntries and \a plist->procArray have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a plist->numprocArrayEntries indicates that the \a plist->procArray is too small + * \a plist->numprocArrayEntries will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a plist is NULL, \a plist->version is invalid, + * \a plist->mode is invalid, + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRunningProcessDetailList(nvmlDevice_t device, nvmlProcessDetailList_t *plist); + +/** + * Check if the GPU devices are on the same physical board. + * + * For all fully supported products. + * + * @param device1 The first GPU device + * @param device2 The second GPU device + * @param onSameBoard Reference in which to return the status. + * Non-zero indicates that the GPUs are on the same board. + * + * @return + * - \ref NVML_SUCCESS if \a onSameBoard has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a dev1 or \a dev2 are invalid or \a onSameBoard is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this check is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the either GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceOnSameBoard(nvmlDevice_t device1, nvmlDevice_t device2, int *onSameBoard); + +/** + * Retrieves the root/admin permissions on the target API. See \a nvmlRestrictedAPI_t for the list of supported APIs. + * If an API is restricted only root users can call that API. See \a nvmlDeviceSetAPIRestriction to change current permissions. + * + * For all fully supported products. + * + * @param device The identifier of the target device + * @param apiType Target API type for this operation + * @param isRestricted Reference in which to return the current restriction + * NVML_FEATURE_ENABLED indicates that the API is root-only + * NVML_FEATURE_DISABLED indicates that the API is accessible to all users + * + * @return + * - \ref NVML_SUCCESS if \a isRestricted has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a apiType incorrect or \a isRestricted is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device or the device does not support + * the feature that is being queried (E.G. Enabling/disabling Auto Boosted clocks is + * not supported by the device) + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlRestrictedAPI_t + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAPIRestriction(nvmlDevice_t device, nvmlRestrictedAPI_t apiType, nvmlEnableState_t *isRestricted); + +/** + * Gets recent samples for the GPU. + * + * For Kepler &tm; or newer fully supported devices. + * + * Based on type, this method can be used to fetch the power, utilization or clock samples maintained in the buffer by + * the driver. + * + * Power, Utilization and Clock samples are returned as type "unsigned int" for the union nvmlValue_t. + * + * To get the size of samples that user needs to allocate, the method is invoked with samples set to NULL. + * The returned samplesCount will provide the number of samples that can be queried. The user needs to + * allocate the buffer with size as samplesCount * sizeof(nvmlSample_t). + * + * lastSeenTimeStamp represents CPU timestamp in microseconds. Set it to 0 to fetch all the samples maintained by the + * underlying buffer. Set lastSeenTimeStamp to one of the timeStamps retrieved from the date of the previous query + * to get more recent samples. + * + * This method fetches the number of entries which can be accommodated in the provided samples array, and the + * reference samplesCount is updated to indicate how many samples were actually retrieved. The advantage of using this + * method for samples in contrast to polling via existing methods is to get get higher frequency data at lower polling cost. + * + * @note On MIG-enabled GPUs, querying the following sample types, NVML_GPU_UTILIZATION_SAMPLES, NVML_MEMORY_UTILIZATION_SAMPLES + * NVML_ENC_UTILIZATION_SAMPLES and NVML_DEC_UTILIZATION_SAMPLES, is not currently supported. + * + * @param device The identifier for the target device + * @param type Type of sampling event + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + * @param sampleValType Output parameter to represent the type of sample value as described in nvmlSampleVal_t + * @param sampleCount Reference to provide the number of elements which can be queried in samples array + * @param samples Reference in which samples are returned + + * @return + * - \ref NVML_SUCCESS if samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a samplesCount is NULL or + * reference to \a sampleCount is 0 for non null \a samples + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSamples(nvmlDevice_t device, nvmlSamplingType_t type, unsigned long long lastSeenTimeStamp, + nvmlValueType_t *sampleValType, unsigned int *sampleCount, nvmlSample_t *samples); + +/** + * Gets Total, Available and Used size of BAR1 memory. + * + * BAR1 is used to map the FB (device memory) so that it can be directly accessed by the CPU or by 3rd party + * devices (peer-to-peer on the PCIE bus). + * + * @note In MIG mode, if device handle is provided, the API returns aggregate + * information, only if the caller has appropriate privileges. Per-instance + * information can be queried by using specific MIG device handles. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param bar1Memory Reference in which BAR1 memory + * information is returned. + * + * @return + * - \ref NVML_SUCCESS if BAR1 memory is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a bar1Memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBAR1MemoryInfo(nvmlDevice_t device, nvmlBAR1Memory_t *bar1Memory); + +/** + * @deprecated Use \ref nvmlDeviceGetFieldValues to query this data. + * This API will be removed in CUDA 14.0. + * + * Translations are as follows: + + * + * NVML_PERF_POLICY_POWER -> NVML_FI_DEV_CLOCKS_EVENT_REASON_SW_POWER_CAP + * NVML_PERF_POLICY_THERMAL -> NVML_FI_DEV_CLOCKS_EVENT_REASON_SW_THERM_SLOWDOWN + * NVML_PERF_POLICY_SYNC_BOOST -> NVML_FI_DEV_CLOCKS_EVENT_REASON_SYNC_BOOST + * NVML_PERF_POLICY_BOARD_LIMIT -> NVML_FI_DEV_PERF_POLICY_BOARD_LIMIT + * NVML_PERF_POLICY_LOW_UTILIZATION -> NVML_FI_DEV_PERF_POLICY_LOW_UTILIZATION + * NVML_PERF_POLICY_RELIABILITY -> NVML_FI_DEV_PERF_POLICY_RELIABILITY + * NVML_PERF_POLICY_TOTAL_APP_CLOCKS -> DEPRECATED, Do not use + * NVML_PERF_POLICY_TOTAL_BASE_CLOCKS -> NVML_FI_DEV_PERF_POLICY_TOTAL_BASE_CLOCKS + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetViolationStatus(nvmlDevice_t device, nvmlPerfPolicyType_t perfPolicyType, nvmlViolationTime_t *violTime); + +/** + * Gets the device's interrupt number + * + * @param device The identifier of the target device + * @param irqNum The interrupt number associated with the specified device + * + * @return + * - \ref NVML_SUCCESS if irq number is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a irqNum is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetIrqNum(nvmlDevice_t device, unsigned int *irqNum); + +/** + * Gets the device's core count + * + * @note On MIG-enabled GPUs, querying the device's core count is currently not supported using this API. + * Please use \ref nvmlDeviceGetGpuInstanceProfileInfo to fetch the MIG device's core count. + * + * @param device The identifier of the target device + * @param numCores The number of cores for the specified device + * + * @return + * - \ref NVML_SUCCESS if GPU core count is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a numCores is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device or a mig device. + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNumGpuCores(nvmlDevice_t device, unsigned int *numCores); + +/** + * Gets the devices power source + * + * @param device The identifier of the target device + * @param powerSource The power source of the device + * + * @return + * - \ref NVML_SUCCESS if the current power source was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a powerSource is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerSource(nvmlDevice_t device, nvmlPowerSource_t *powerSource); + +/** + * Gets the device's memory bus width + * + * @param device The identifier of the target device + * @param busWidth The devices's memory bus width + * + * @return + * - \ref NVML_SUCCESS if the memory bus width is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a busWidth is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryBusWidth(nvmlDevice_t device, unsigned int *busWidth); + +/** + * Gets the device's PCIE Max Link speed in MBPS + * + * @param device The identifier of the target device + * @param maxSpeed The devices's PCIE Max Link speed in MBPS + * + * @return + * - \ref NVML_SUCCESS if PCIe Max Link Speed is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a maxSpeed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieLinkMaxSpeed(nvmlDevice_t device, unsigned int *maxSpeed); + +/** + * Gets the device's PCIe Link speed in Mbps + * + * @param device The identifier of the target device + * @param pcieSpeed The devices's PCIe Max Link speed in Mbps + * + * @return + * - \ref NVML_SUCCESS if \a pcieSpeed has been retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pcieSpeed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support PCIe speed getting + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieSpeed(nvmlDevice_t device, unsigned int *pcieSpeed); + +/** + * Gets the device's Adaptive Clock status + * + * @param device The identifier of the target device + * @param adaptiveClockStatus The current adaptive clocking status, either + * NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED + * or NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED + * + * @return + * - \ref NVML_SUCCESS if the current adaptive clocking status is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a adaptiveClockStatus is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAdaptiveClockInfoStatus(nvmlDevice_t device, unsigned int *adaptiveClockStatus); + +/** + * Get the type of the GPU Bus (PCIe, PCI, ...) + * + * @param device The identifier of the target device + * @param type The PCI Bus type + * + * return + * - \ref NVML_SUCCESS if the bus \a type is successfully retreived + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a type is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBusType(nvmlDevice_t device, nvmlBusType_t *type); + + + /** + * @deprecated Will be deprecated in a future release. Use \ref nvmlDeviceGetGpuFabricInfoV instead + * + * Get fabric information associated with the device. + * + * For Hopper &tm; or newer fully supported devices. + * + * On Hopper + NVSwitch systems, GPU is registered with the NVIDIA Fabric Manager + * Upon successful registration, the GPU is added to the NVLink fabric to enable + * peer-to-peer communication. + * This API reports the current state of the GPU in the NVLink fabric + * along with other useful information. + * + * + * @param device The identifier of the target device + * @param gpuFabricInfo Information about GPU fabric state + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support gpu fabric + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetGpuFabricInfo(nvmlDevice_t device, nvmlGpuFabricInfo_t *gpuFabricInfo); + +/** +* Versioned wrapper around \ref nvmlDeviceGetGpuFabricInfo that accepts a versioned +* \ref nvmlGpuFabricInfo_v2_t or later output structure. +* +* @note The caller must set the \ref nvmlGpuFabricInfoV_t.version field to the +* appropriate version prior to calling this function. For example: +* \code +* nvmlGpuFabricInfoV_t fabricInfo = +* { .version = nvmlGpuFabricInfo_v2 }; +* nvmlReturn_t result = nvmlDeviceGetGpuFabricInfoV(device,&fabricInfo); +* \endcode +* +* For Hopper &tm; or newer fully supported devices. +* +* @param device The identifier of the target device +* @param gpuFabricInfo Information about GPU fabric state +* +* @return +* - \ref NVML_SUCCESS Upon success +* - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support gpu fabric +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuFabricInfoV(nvmlDevice_t device, + nvmlGpuFabricInfoV_t *gpuFabricInfo); + +/** + * Get Conf Computing System capabilities. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param capabilities System CC capabilities + * + * @return + * - \ref NVML_SUCCESS if \a capabilities were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a capabilities is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeCapabilities(nvmlConfComputeSystemCaps_t *capabilities); + +/** + * Get Conf Computing System State. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param state System CC State + * + * @return + * - \ref NVML_SUCCESS if \a state were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a state is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeState(nvmlConfComputeSystemState_t *state); + +/** + * Get Conf Computing Protected and Unprotected Memory Sizes. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device Device handle + * @param memInfo Protected/Unprotected Memory sizes + * + * @return + * - \ref NVML_SUCCESS if \a memInfo were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a memInfo or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeMemSizeInfo(nvmlDevice_t device, nvmlConfComputeMemSizeInfo_t *memInfo); + +/** + * Get Conf Computing GPUs ready state. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param isAcceptingWork Returns GPU current work accepting state, + * NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE or + * NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE + * + * return + * - \ref NVML_SUCCESS if \a current GPUs ready state were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a isAcceptingWork is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeGpusReadyState(unsigned int *isAcceptingWork); + +/** + * Get Conf Computing protected memory usage. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param memory Reference in which to return the memory information + * + * @return + * - \ref NVML_SUCCESS if \a memory has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeProtectedMemoryUsage(nvmlDevice_t device, nvmlMemory_t *memory); + +/** + * Get Conf Computing GPU certificate details. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param gpuCert Reference in which to return the gpu certificate information + * + * @return + * - \ref NVML_SUCCESS if \a gpu certificate info has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeGpuCertificate(nvmlDevice_t device, + nvmlConfComputeGpuCertificate_t *gpuCert); + +/** + * Get Conf Computing GPU attestation report. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param gpuAtstReport Reference in which to return the gpu attestation report + * + * @return + * - \ref NVML_SUCCESS if \a gpu attestation report has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeGpuAttestationReport(nvmlDevice_t device, + nvmlConfComputeGpuAttestationReport_t *gpuAtstReport); +/** + * Get Conf Computing key rotation threshold detail. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param pKeyRotationThrInfo Reference in which to return the key rotation threshold data + * + * @return + * - \ref NVML_SUCCESS if \a gpu key rotation threshold info has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeKeyRotationThresholdInfo( + nvmlConfComputeGetKeyRotationThresholdInfo_t *pKeyRotationThrInfo); + +/** + * Set Conf Computing Unprotected Memory Size. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device Device Handle + * @param sizeKiB Unprotected Memory size to be set in KiB + * + * @return + * - \ref NVML_SUCCESS if \a sizeKiB successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlDeviceSetConfComputeUnprotectedMemSize(nvmlDevice_t device, unsigned long long sizeKiB); + +/** + * Set Conf Computing GPUs ready state. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param isAcceptingWork GPU accepting new work, NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE or + * NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE + * + * return + * - \ref NVML_SUCCESS if \a current GPUs ready state is successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a isAcceptingWork is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemSetConfComputeGpusReadyState(unsigned int isAcceptingWork); + +/** + * Set Conf Computing key rotation threshold. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * This function is to set the confidential compute key rotation threshold parameters. + * \a pKeyRotationThrInfo->maxAttackerAdvantage should be in the range from + * NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MIN to NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MAX. + * Default value is 60. + * + * @param pKeyRotationThrInfo Reference to the key rotation threshold data + * + * @return + * - \ref NVML_SUCCESS if \a key rotation threashold max attacker advantage has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_INVALID_STATE if confidential compute GPU ready state is enabled + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemSetConfComputeKeyRotationThresholdInfo( + nvmlConfComputeSetKeyRotationThresholdInfo_t *pKeyRotationThrInfo); + +/** + * Get Conf Computing System Settings. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param settings System CC settings + * + * @return + * - \ref NVML_SUCCESS If the query is success + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a counters is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeSettings(nvmlSystemConfComputeSettings_t *settings); + +/** + * Retrieve GSP firmware version. + * + * The caller passes in buffer via \a version and corresponding GSP firmware numbered version + * is returned with the same parameter in string format. + * + * @param device Device handle + * @param version The retrieved GSP firmware version + * + * @return + * - \ref NVML_SUCCESS if GSP firmware version is sucessfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or GSP \a version pointer is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if GSP firmware is not enabled for GPU + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGspFirmwareVersion(nvmlDevice_t device, char *version); + +/** + * Retrieve GSP firmware mode. + * + * The caller passes in integer pointers. GSP firmware enablement and default mode information is returned with + * corresponding parameters. The return value in \a isEnabled and \a defaultMode should be treated as boolean. + * + * @param device Device handle + * @param isEnabled Pointer to specify if GSP firmware is enabled + * @param defaultMode Pointer to specify if GSP firmware is supported by default on \a device + * + * @return + * - \ref NVML_SUCCESS if GSP firmware mode is sucessfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or any of \a isEnabled or \a defaultMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if GSP firmware is not enabled for GPU + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGspFirmwareMode(nvmlDevice_t device, unsigned int *isEnabled, unsigned int *defaultMode); + +/** + * Get SRAM ECC error status of this device. + * + * For Ampere &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlEccSramErrorStatus_v1_t for more information on the struct. + * + * @param device The identifier of the target device + * @param status Returns SRAM ECC error status + * + * @return + * - \ref NVML_SUCCESS If \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a counters is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a nvmlEccSramErrorStatus_t is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSramEccErrorStatus(nvmlDevice_t device, + nvmlEccSramErrorStatus_t *status); + +/** + * Set new power limit of this device. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlDeviceGetPowerManagementLimitConstraints to check the allowed ranges of values. + * + * See \ref nvmlPowerValue_v2_t for more information on the struct. + * + * \note Limit is not persistent across reboots or driver unloads. + * Enable persistent mode to prevent driver from unloading when no application is using the device. + * + * This API replaces nvmlDeviceSetPowerManagementLimit. It can be used as a drop-in replacement for the older version. + * + * @param device The identifier of the target device + * @param powerValue Power management limit in milliwatts to set + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a powerValue is NULL or contains invalid values + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see NVML_FI_DEV_POWER_AVERAGE + * @see NVML_FI_DEV_POWER_INSTANT + * @see NVML_FI_DEV_POWER_MIN_LIMIT + * @see NVML_FI_DEV_POWER_MAX_LIMIT + * @see NVML_FI_DEV_POWER_CURRENT_LIMIT + */ +nvmlReturn_t DECLDIR nvmlDeviceSetPowerManagementLimit_v2(nvmlDevice_t device, nvmlPowerValue_v2_t *powerValue); + +/** + * @} // @defgroup nvmlDeviceQueries Device Queries + */ + +/** @addtogroup nvmlAccountingStats + * @{ + */ + +/** + * Queries the state of per process accounting mode. + * + * For Kepler &tm; or newer fully supported devices. + * + * See \ref nvmlDeviceGetAccountingStats for more details. + * See \ref nvmlDeviceSetAccountingMode + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current accounting mode + * + * @return + * - \ref NVML_SUCCESS if the mode has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingMode(nvmlDevice_t device, nvmlEnableState_t *mode); + +/** + * Queries process's accounting stats. + * + * For Kepler &tm; or newer fully supported devices. + * + * Accounting stats capture GPU utilization and other statistics across the lifetime of a process. + * Accounting stats can be queried during life time of the process and after its termination. + * The time field in \ref nvmlAccountingStats_t is reported as 0 during the lifetime of the process and + * updated to actual running time after its termination. + * Accounting stats are kept in a circular buffer, newly created processes overwrite information about old + * processes. + * + * See \ref nvmlAccountingStats_t for description of each returned metric. + * List of processes that can be queried can be retrieved from \ref nvmlDeviceGetAccountingPids. + * + * @note Accounting Mode needs to be on. See \ref nvmlDeviceGetAccountingMode. + * @note Only compute and graphics applications stats can be queried. Monitoring applications stats can't be + * queried since they don't contribute to GPU utilization. + * @note In case of pid collision stats of only the latest process (that terminated last) will be reported + * + * @warning On Kepler devices per process statistics are accurate only if there's one process running on a GPU. + * + * @param device The identifier of the target device + * @param pid Process Id of the target process to query stats for + * @param stats Reference in which to return the process's accounting stats + * + * @return + * - \ref NVML_SUCCESS if stats have been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a stats are NULL + * - \ref NVML_ERROR_NOT_FOUND if process stats were not found + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device doesn't support this feature or accounting mode is disabled + * or on vGPU host. + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetAccountingBufferSize + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingStats(nvmlDevice_t device, unsigned int pid, nvmlAccountingStats_t *stats); + +/** + * Queries list of processes that can be queried for accounting stats. The list of processes returned + * can be in running or terminated state. + * + * For Kepler &tm; or newer fully supported devices. + * + * To query the number of processes under Accounting Mode, call this function with *count = 0 and pids=NULL. + * The return code will be NVML_ERROR_INSUFFICIENT_SIZE with an updated count value indicating the number of processes. + * + * For more details see \ref nvmlDeviceGetAccountingStats. + * + * @note In case of PID collision some processes might not be accessible before the circular buffer is full. + * + * @param device The identifier of the target device + * @param count Reference in which to provide the \a pids array size, and + * to return the number of elements ready to be queried + * @param pids Reference in which to return list of process ids + * + * @return + * - \ref NVML_SUCCESS if pids were successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a count is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device doesn't support this feature or accounting mode is disabled + * or on vGPU host. + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small (\a count is set to + * expected value) + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetAccountingBufferSize + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingPids(nvmlDevice_t device, unsigned int *count, unsigned int *pids); + +/** + * Returns the number of processes that the circular buffer with accounting pids can hold. + * + * For Kepler &tm; or newer fully supported devices. + * + * This is the maximum number of processes that accounting information will be stored for before information + * about oldest processes will get overwritten by information about new processes. + * + * @param device The identifier of the target device + * @param bufferSize Reference in which to provide the size (in number of elements) + * of the circular buffer for accounting stats. + * + * @return + * - \ref NVML_SUCCESS if buffer size was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a bufferSize is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetAccountingStats + * @see nvmlDeviceGetAccountingPids + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingBufferSize(nvmlDevice_t device, unsigned int *bufferSize); + +/** @} */ + +/** @addtogroup nvmlDeviceQueries + * @{ + */ + +/** + * Returns the list of retired pages by source, including pages that are pending retirement + * The address information provided from this API is the hardware address of the page that was retired. Note + * that this does not match the virtual address used in CUDA, but will match the address information in Xid 63 + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param cause Filter page addresses by cause of retirement + * @param pageCount Reference in which to provide the \a addresses buffer size, and + * to return the number of retired pages that match \a cause + * Set to 0 to query the size without allocating an \a addresses buffer + * @param addresses Buffer to write the page addresses into + * + * @return + * - \ref NVML_SUCCESS if \a pageCount was populated and \a addresses was filled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a pageCount indicates the buffer is not large enough to store all the + * matching page addresses. \a pageCount is set to the needed size. + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a pageCount is NULL, \a cause is invalid, or + * \a addresses is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRetiredPages(nvmlDevice_t device, nvmlPageRetirementCause_t cause, + unsigned int *pageCount, unsigned long long *addresses); + +/** + * Returns the list of retired pages by source, including pages that are pending retirement + * The address information provided from this API is the hardware address of the page that was retired. Note + * that this does not match the virtual address used in CUDA, but will match the address information in Xid 63 + * + * \note nvmlDeviceGetRetiredPages_v2 adds an additional timestamps parameter to return the time of each page's + * retirement. This is supported for Pascal and newer architecture. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param cause Filter page addresses by cause of retirement + * @param pageCount Reference in which to provide the \a addresses buffer size, and + * to return the number of retired pages that match \a cause + * Set to 0 to query the size without allocating an \a addresses buffer + * @param addresses Buffer to write the page addresses into + * @param timestamps Buffer to write the timestamps of page retirement, additional for _v2 + * + * @return + * - \ref NVML_SUCCESS if \a pageCount was populated and \a addresses was filled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a pageCount indicates the buffer is not large enough to store all the + * matching page addresses. \a pageCount is set to the needed size. + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a pageCount is NULL, \a cause is invalid, or + * \a addresses is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRetiredPages_v2(nvmlDevice_t device, nvmlPageRetirementCause_t cause, + unsigned int *pageCount, unsigned long long *addresses, unsigned long long *timestamps); + +/** + * Check if any pages are pending retirement and need a reboot to fully retire. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param isPending Reference in which to return the pending status + * + * @return + * - \ref NVML_SUCCESS if \a isPending was populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a isPending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRetiredPagesPendingStatus(nvmlDevice_t device, nvmlEnableState_t *isPending); + +/** + * Get number of remapped rows. The number of rows reported will be based on + * the cause of the remapping. isPending indicates whether or not there are + * pending remappings. A reset will be required to actually remap the row. + * failureOccurred will be set if a row remapping ever failed in the past. A + * pending remapping won't affect future work on the GPU since + * error-containment and dynamic page blacklisting will take care of that. + * + * @note On MIG-enabled GPUs with active instances, querying the number of + * remapped rows is not supported + * + * For Ampere &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param corrRows Reference for number of rows remapped due to correctable errors + * @param uncRows Reference for number of rows remapped due to uncorrectable errors + * @param isPending Reference for whether or not remappings are pending + * @param failureOccurred Reference that is set when a remapping has failed in the past + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a corrRows, \a uncRows, \a isPending or \a failureOccurred is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN Unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRemappedRows(nvmlDevice_t device, unsigned int *corrRows, unsigned int *uncRows, + unsigned int *isPending, unsigned int *failureOccurred); + +/** + * Get the row remapper histogram. Returns the remap availability for each bank + * on the GPU. + * + * @param device Device handle + * @param values Histogram values + * + * @return + * - \ref NVML_SUCCESS On success + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRowRemapperHistogram(nvmlDevice_t device, nvmlRowRemapperHistogramValues_t *values); + +/** + * Get architecture for device + * + * @param device The identifier of the target device + * @param arch Reference where architecture is returned, if call successful. + * Set to NVML_DEVICE_ARCH_* upon success + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a arch (output refererence) are invalid + */ +nvmlReturn_t DECLDIR nvmlDeviceGetArchitecture(nvmlDevice_t device, nvmlDeviceArchitecture_t *arch); + +/** + * Retrieves the frequency monitor fault status for the device. + * + * For Ampere &tm; or newer fully supported devices. + * Requires root user. + * + * See \ref nvmlClkMonStatus_t for details on decoding the status output. + * + * @param device The identifier of the target device + * @param status Reference in which to return the clkmon fault status + * + * @return + * - \ref NVML_SUCCESS if \a status has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a status is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetClkMonStatus() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClkMonStatus(nvmlDevice_t device, nvmlClkMonStatus_t *status); + +/** + * Retrieves the current utilization and process ID + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder for processes running. + * Utilization values are returned as an array of utilization sample structures in the caller-supplied buffer pointed at + * by \a utilization. One utilization sample structure is returned per process running, that had some non-zero utilization + * during the last sample period. It includes the CPU timestamp at which the samples were recorded. Individual utilization values + * are returned as "unsigned int" values. If no valid sample entries are found since the lastSeenTimeStamp, NVML_ERROR_NOT_FOUND + * is returned. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a utilization set to NULL. The caller should allocate a buffer of size + * processSamplesCount * sizeof(nvmlProcessUtilizationSample_t). Invoke the function again with the allocated buffer passed + * in \a utilization, and \a processSamplesCount set to the number of entries the buffer is sized for. + * + * On successful return, the function updates \a processSamplesCount with the number of process utilization sample + * structures that were actually written. This may differ from a previously read value as instances are created or + * destroyed. + * + * lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @note On MIG-enabled GPUs, querying process utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Pointer to caller-supplied buffer in which guest process utilization samples are returned + * @param processSamplesCount Pointer to caller-supplied array size, and returns number of processes running + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetProcessUtilization(nvmlDevice_t device, nvmlProcessUtilizationSample_t *utilization, + unsigned int *processSamplesCount, unsigned long long lastSeenTimeStamp); + +/** + * Retrieves the recent utilization and process ID for all running processes + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder, jpeg decoder, OFA (Optical Flow Accelerator) + * for all running processes. Utilization values are returned as an array of utilization sample structures in the caller-supplied buffer pointed at + * by \a procesesUtilInfo->procUtilArray. One utilization sample structure is returned per process running, that had some non-zero utilization + * during the last sample period. It includes the CPU timestamp at which the samples were recorded. Individual utilization values + * are returned as "unsigned int" values. + * + * The caller should allocate a buffer of size processSamplesCount * sizeof(nvmlProcessUtilizationInfo_t). If the buffer is too small, the API will + * return \a NVML_ERROR_INSUFFICIENT_SIZE, with the recommended minimal buffer size at \a procesesUtilInfo->processSamplesCount. The caller should + * invoke the function again with the allocated buffer passed in \a procesesUtilInfo->procUtilArray, and \a procesesUtilInfo->processSamplesCount + * set to the number no less than the recommended value by the previous API return. + * + * On successful return, the function updates \a procesesUtilInfo->processSamplesCount with the number of process utilization info structures + * that were actually written. This may differ from a previously read value as instances are created or destroyed. + * + * \a procesesUtilInfo->lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set \a procesesUtilInfo->lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * \a procesesUtilInfo->version is the version number of the structure nvmlProcessesUtilizationInfo_t, the caller should set the correct version + * number to retrieve the specific version of processes utilization information. + * + * @note On MIG-enabled GPUs, querying process utilization is not currently supported. + * + * @param device The identifier of the target device + * @param procesesUtilInfo Pointer to the caller-provided structure of nvmlProcessesUtilizationInfo_t. + + * @return + * - \ref NVML_SUCCESS If \a procesesUtilInfo->procUtilArray has been populated + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, or \a procesesUtilInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_NOT_FOUND If sample entries are not found + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a procesesUtilInfo is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a procesesUtilInfo->procUtilArray is NULL, or the buffer size of procesesUtilInfo->procUtilArray is too small. + * The caller should check the minimul array size from the returned procesesUtilInfo->processSamplesCount, and call + * the function again with a buffer no smaller than procesesUtilInfo->processSamplesCount * sizeof(nvmlProcessUtilizationInfo_t) + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetProcessesUtilizationInfo(nvmlDevice_t device, nvmlProcessesUtilizationInfo_t *procesesUtilInfo); + +/** + * Get platform information of this device. + * + * For Blackwell &tm; or newer fully supported devices. + * + * See \ref nvmlPlatformInfo_v2_t for more information on the struct. + * + * @param device The identifier of the target device + * @param platformInfo Pointer to the caller-provided structure of nvmlPlatformInfo_t. + * + * @return + * - \ref NVML_SUCCESS If \a platformInfo has been retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a platformInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_MEMORY if system memory is insufficient + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a nvmlPlatformInfo_t is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPlatformInfo(nvmlDevice_t device, nvmlPlatformInfo_t *platformInfo); + +/** + * Retrieves the Per Device Identifier (PDI) associated with this device. + * + * For Pascal &tm; or newer fully supported devices. + * + * See \ref nvmlPdi_v1_t for more information on the struct. + * + * @param[in] device The identifier of the target device + * @param[out] pdi Reference to the caller-provided structure to return the GPU PDI + * + * @return + * - \ref NVML_SUCCESS if \a pdi has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a pdi is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPdi(nvmlDevice_t device, nvmlPdi_t *pdi); + +/** + * Set the hostname for the device. + * + * For Blackwell &tm; or newer fully supported devices. + * Requires root/admin permissions. + * Supported on Linux only. + * + * Sets a hostname string for the GPU device. This operation takes effect immediately. + * + * The hostname is not stored persistently across GPU resets or driver reloads. + * + * @param device The identifier of the target device + * @param hostname Reference to the caller-provided \ref nvmlHostname_v1_t struct containing the hostname + * + * @return + * - \ref NVML_SUCCESS if the hostname was set successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a hostname is NULL or contains invalid characters + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetHostname_v1() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetHostname_v1(nvmlDevice_t device, nvmlHostname_v1_t *hostname); + +/** + * Get the hostname for the device. + * + * For Blackwell &tm; or newer fully supported devices. + * Supported on Linux only. + * + * Retrieves the hostname string for the GPU device that was set using \ref nvmlDeviceSetHostname_v1(). + * + * @param device The identifier of the target device + * @param hostname Reference to the caller-provided \ref nvmlHostname_v1_t struct to return the hostname + * + * @return + * - \ref NVML_SUCCESS if the hostname was retrieved successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a hostname is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetHostname_v1() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHostname_v1(nvmlDevice_t device, nvmlHostname_v1_t *hostname); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlUnitCommands Unit Commands + * This chapter describes NVML operations that change the state of the unit. For S-class products. + * Each of these requires root/admin access. Non-admin users will see an NVML_ERROR_NO_PERMISSION + * error code when invoking any of these methods. + * @{ + */ +/***************************************************************************************************/ + +/** + * Set the LED state for the unit. The LED can be either green (0) or amber (1). + * + * For S-class products. + * Requires root/admin permissions. + * + * This operation takes effect immediately. + * + * + * Current S-Class products don't provide unique LEDs for each unit. As such, both front + * and back LEDs will be toggled in unison regardless of which unit is specified with this command. + * + * See \ref nvmlLedColor_t for available colors. + * + * @param unit The identifier of the target unit + * @param color The target LED color + * + * @return + * - \ref NVML_SUCCESS if the LED color has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit or \a color is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlUnitGetLedState() + */ +nvmlReturn_t DECLDIR nvmlUnitSetLedState(nvmlUnit_t unit, nvmlLedColor_t color); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceCommands Device Commands + * This chapter describes NVML operations that change the state of the device. + * Each of these requires root/admin access. Non-admin users will see an NVML_ERROR_NO_PERMISSION + * error code when invoking any of these methods. + * @{ + */ +/***************************************************************************************************/ + +/** + * Set the persistence mode for the device. + * + * For all products. + * For Linux only. + * Requires root/admin permissions. + * + * The persistence mode determines whether the GPU driver software is torn down after the last client + * exits. + * + * This operation takes effect immediately. It is not persistent across reboots. After each reboot the + * persistence mode is reset to "Disabled". + * + * See \ref nvmlEnableState_t for available modes. + * + * After calling this API with mode set to NVML_FEATURE_DISABLED on a device that has its own NUMA + * memory, the given device handle will no longer be valid, and to continue to interact with this + * device, a new handle should be obtained from one of the nvmlDeviceGetHandleBy*() APIs. This + * limitation is currently only applicable to devices that have a coherent NVLink connection to + * system memory. + * + * @param device The identifier of the target device + * @param mode The target persistence mode + * + * @return + * - \ref NVML_SUCCESS if the persistence mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetPersistenceMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetPersistenceMode(nvmlDevice_t device, nvmlEnableState_t mode); + +/** + * Set the compute mode for the device. + * + * For all products. + * Requires root/admin permissions. + * + * The compute mode determines whether a GPU can be used for compute operations and whether it can + * be shared across contexts. + * + * This operation takes effect immediately. Under Linux it is not persistent across reboots and + * always resets to "Default". Under windows it is persistent. + * + * Under windows compute mode may only be set to DEFAULT when running in WDDM + * + * @note On MIG-enabled GPUs, compute mode would be set to DEFAULT and changing it is not supported. + * + * See \ref nvmlComputeMode_t for details on available compute modes. + * + * @param device The identifier of the target device + * @param mode The target compute mode + * + * @return + * - \ref NVML_SUCCESS if the compute mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetComputeMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetComputeMode(nvmlDevice_t device, nvmlComputeMode_t mode); + +/** + * Set the ECC mode for the device. + * + * For Kepler &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * Requires root/admin permissions. + * + * The ECC mode determines whether the GPU enables its ECC support. + * + * This operation takes effect after the next reboot. + * + * See \ref nvmlEnableState_t for details on available modes. + * + * @param device The identifier of the target device + * @param ecc The target ECC mode + * + * @return + * - \ref NVML_SUCCESS if the ECC mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a ecc is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetEccMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetEccMode(nvmlDevice_t device, nvmlEnableState_t ecc); + +/** + * Clear the ECC error and other memory error counts for the device. + * + * For Kepler &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 2.0 or higher to clear aggregate location-based ECC counts. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher to clear all other ECC counts. + * Requires root/admin permissions. + * Requires ECC Mode to be enabled. + * + * Sets all of the specified ECC counters to 0, including both detailed and total counts. + * + * This operation takes effect immediately. + * + * See \ref nvmlMemoryErrorType_t for details on available counter types. + * + * @param device The identifier of the target device + * @param counterType Flag that indicates which type of errors should be cleared. + * + * @return + * - \ref NVML_SUCCESS if the error counts were cleared + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a counterType is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see + * - nvmlDeviceGetDetailedEccErrors() + * - nvmlDeviceGetTotalEccErrors() + */ +nvmlReturn_t DECLDIR nvmlDeviceClearEccErrorCounts(nvmlDevice_t device, nvmlEccCounterType_t counterType); + +/** + * Set the driver model for the device. + * + * For Fermi &tm; or newer fully supported devices. + * For windows only. + * Requires root/admin permissions. + * + * On Windows platforms the device driver can run in either WDDM or WDM (TCC) mode. If a display is attached + * to the device it must run in WDDM mode. + * + * It is possible to force the change to WDM (TCC) while the display is still attached with a force flag (nvmlFlagForce). + * This should only be done if the host is subsequently powered down and the display is detached from the device + * before the next reboot. + * + * This operation takes effect after the next reboot. + * + * Windows driver model may only be set to WDDM when running in DEFAULT compute mode. + * + * Change driver model to WDDM is not supported when GPU doesn't support graphics acceleration or + * will not support it after reboot. See \ref nvmlDeviceSetGpuOperationMode. + * + * See \ref nvmlDriverModel_t for details on available driver models. + * See \ref nvmlFlagDefault and \ref nvmlFlagForce + * + * @param device The identifier of the target device + * @param driverModel The target driver model + * @param flags Flags that change the default behavior + * + * @return + * - \ref NVML_SUCCESS if the driver model has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a driverModel is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the platform is not windows or the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetDriverModel() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDriverModel(nvmlDevice_t device, nvmlDriverModel_t driverModel, unsigned int flags); + +typedef enum nvmlClockLimitId_enum { + NVML_CLOCK_LIMIT_ID_RANGE_START = 0xffffff00, + NVML_CLOCK_LIMIT_ID_TDP, + NVML_CLOCK_LIMIT_ID_UNLIMITED +} nvmlClockLimitId_t; + +/** + * Set clocks that device will lock to. + * + * Sets the clocks that the device will be running at to the value in the range of minGpuClockMHz to maxGpuClockMHz. + * + * Can be used as a setting to request constant performance. + * + * This can be called with a pair of integer clock frequencies in MHz, or a pair of /ref nvmlClockLimitId_t values. + * See the table below for valid combinations of these values. + * + * minGpuClock | maxGpuClock | Effect + * ------------+-------------+-------------------------------------------------- + * tdp | tdp | Lock clock to TDP + * unlimited | tdp | Upper bound is TDP but clock may drift below this + * tdp | unlimited | Lower bound is TDP but clock may boost above this + * unlimited | unlimited | Unlocked (== nvmlDeviceResetGpuLockedClocks) + * + * If one arg takes one of these values, the other must be one of these values as + * well. Mixed numeric and symbolic calls return NVML_ERROR_INVALID_ARGUMENT. + * + * Requires root/admin permissions. + * + * After system reboot or driver reload GPU clocks go back to their default value. + * See \ref nvmlDeviceResetGpuLockedClocks. + * + * For Volta &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param minGpuClockMHz Requested minimum gpu clock in MHz + * @param maxGpuClockMHz Requested maximum gpu clock in MHz + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minGpuClockMHz and \a maxGpuClockMHz + * is not a valid clock combination + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetGpuLockedClocks(nvmlDevice_t device, unsigned int minGpuClockMHz, unsigned int maxGpuClockMHz); + +/** + * Resets the gpu clock to the default value + * + * This is the gpu clock that will be used after system reboot or driver reload. + * Default values are idle clocks. + * + * @see nvmlDeviceSetGpuLockedClocks + * + * For Volta &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceResetGpuLockedClocks(nvmlDevice_t device); + +/** + * Set memory clocks that device will lock to. + * + * Sets the device's memory clocks to the value in the range of minMemClockMHz to maxMemClockMHz. + * + * Can be used as a setting to request constant performance. + * + * Requires root/admin permissions. + * + * After system reboot or driver reload memory clocks go back to their default value. + * See \ref nvmlDeviceResetMemoryLockedClocks. + * + * For Ampere &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param minMemClockMHz Requested minimum memory clock in MHz + * @param maxMemClockMHz Requested maximum memory clock in MHz + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minGpuClockMHz and \a maxGpuClockMHz + * is not a valid clock combination + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetMemoryLockedClocks(nvmlDevice_t device, unsigned int minMemClockMHz, unsigned int maxMemClockMHz); + +/** + * Resets the memory clock to the default value + * + * This is the memory clock that will be used after system reboot or driver reload. + * Default values are idle clocks. + * + * @see nvmlDeviceSetMemoryLockedClocks + * + * For Ampere &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceResetMemoryLockedClocks(nvmlDevice_t device); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + * + * Please use \ref nvmlDeviceSetMemoryLockedClocks for Memory Clocks and + * \ref nvmlDeviceSetGpuLockedClocks for Graphics Clocks. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetApplicationsClocks(nvmlDevice_t device, unsigned int memClockMHz, unsigned int graphicsClockMHz); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + * + * Please use \ref nvmlDeviceResetMemoryLockedClocks for Memory Clocks and + * \ref nvmlDeviceResetGpuLockedClocks for Graphics Clocks. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceResetApplicationsClocks(nvmlDevice_t device); + +/** + * Try to set the current state of Auto Boosted clocks on a device. + * + * For Kepler &tm; or newer fully supported devices. + * + * Auto Boosted clocks are enabled by default on some hardware, allowing the GPU to run at higher clock rates + * to maximize performance as thermal limits allow. Auto Boosted clocks should be disabled if fixed clock + * rates are desired. + * + * Non-root users may use this API by default but can be restricted by root from using this API by calling + * \ref nvmlDeviceSetAPIRestriction with apiType=NVML_RESTRICTED_API_SET_AUTO_BOOSTED_CLOCKS. + * Note: Persistence Mode is required to modify current Auto Boost settings, therefore, it must be enabled. + * + * On Pascal and newer hardware, Auto Boosted clocks are controlled through application clocks. + * Use \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks to control Auto Boost + * behavior. + * + * @param device The identifier of the target device + * @param enabled What state to try to set Auto Boosted clocks of the target device to + * + * @return + * - \ref NVML_SUCCESS If the Auto Boosted clocks were successfully set to the state specified by \a enabled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support Auto Boosted clocks + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceSetAutoBoostedClocksEnabled(nvmlDevice_t device, nvmlEnableState_t enabled); + +/** + * Try to set the default state of Auto Boosted clocks on a device. This is the default state that Auto Boosted clocks will + * return to when no compute running processes (e.g. CUDA application which have an active context) are running + * + * For Kepler &tm; or newer non-GeForce fully supported devices and Maxwell or newer GeForce devices. + * Requires root/admin permissions. + * + * Auto Boosted clocks are enabled by default on some hardware, allowing the GPU to run at higher clock rates + * to maximize performance as thermal limits allow. Auto Boosted clocks should be disabled if fixed clock + * rates are desired. + * + * On Pascal and newer hardware, Auto Boosted clocks are controlled through application clocks. + * Use \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks to control Auto Boost + * behavior. + * + * @param device The identifier of the target device + * @param enabled What state to try to set default Auto Boosted clocks of the target device to + * @param flags Flags that change the default behavior. Currently Unused. + * + * @return + * - \ref NVML_SUCCESS If the Auto Boosted clock's default state was successfully set to the state specified by \a enabled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NO_PERMISSION If the calling user does not have permission to change Auto Boosted clock's default state. + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support Auto Boosted clocks + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDefaultAutoBoostedClocksEnabled(nvmlDevice_t device, nvmlEnableState_t enabled, unsigned int flags); + +/** + * Sets the speed of the fan control policy to default. + * + * For all cuda-capable discrete products with fans + * + * @param device The identifier of the target device + * @param fan The index of the fan, starting at zero + * + * return + * NVML_SUCCESS if speed has been adjusted + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if device is invalid + * NVML_ERROR_NOT_SUPPORTED if the device does not support this + * (doesn't have fans) + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDefaultFanSpeed_v2(nvmlDevice_t device, unsigned int fan); + +/** + * Sets current fan control policy. + * + * For Maxwell &tm; or newer fully supported devices. + * + * Requires privileged user. + * + * For all cuda-capable discrete products with fans + * + * device The identifier of the target \a device + * policy The fan control \a policy to set + * + * return + * NVML_SUCCESS if \a policy has been set + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a policy is null or the \a fan given doesn't reference + * a fan that exists. + * NVML_ERROR_NOT_SUPPORTED if the \a device is older than Maxwell + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetFanControlPolicy(nvmlDevice_t device, unsigned int fan, + nvmlFanControlPolicy_t policy); + +/** + * Sets the temperature threshold for the GPU with the specified threshold type in degrees C. + * + * For Maxwell &tm; or newer fully supported devices. + * + * See \ref nvmlTemperatureThresholds_t for details on available temperature thresholds. + * + * @param device The identifier of the target device + * @param thresholdType The type of threshold value to be set + * @param temp Reference which hold the value to be set + * @return + * - \ref NVML_SUCCESS if \a temp has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a thresholdType is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a temperature sensor or is unsupported + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetTemperatureThreshold(nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, int *temp); + +/** + * Set new power limit of this device. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlDeviceGetPowerManagementLimitConstraints to check the allowed ranges of values. + * + * \note Limit is not persistent across reboots or driver unloads. + * Enable persistent mode to prevent driver from unloading when no application is using the device. + * + * @param device The identifier of the target device + * @param limit Power management limit in milliwatts to set + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a defaultLimit is out of range + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetPowerManagementLimitConstraints + * @see nvmlDeviceGetPowerManagementDefaultLimit + */ +nvmlReturn_t DECLDIR nvmlDeviceSetPowerManagementLimit(nvmlDevice_t device, unsigned int limit); + +/** + * Sets new GOM. See \a nvmlGpuOperationMode_t for details. + * + * For GK110 M-class and X-class Tesla &tm; products from the Kepler family. + * Modes \ref NVML_GOM_LOW_DP and \ref NVML_GOM_ALL_ON are supported on fully supported GeForce products. + * Not supported on Quadro ® and Tesla &tm; C-class products. + * Requires root/admin permissions. + * + * Changing GOMs requires a reboot. + * The reboot requirement might be removed in the future. + * + * Compute only GOMs don't support graphics acceleration. Under windows switching to these GOMs when + * pending driver model is WDDM is not supported. See \ref nvmlDeviceSetDriverModel. + * + * @param device The identifier of the target device + * @param mode Target GOM + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode incorrect + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support GOM or specific mode + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlGpuOperationMode_t + * @see nvmlDeviceGetGpuOperationMode + */ +nvmlReturn_t DECLDIR nvmlDeviceSetGpuOperationMode(nvmlDevice_t device, nvmlGpuOperationMode_t mode); + +/** + * Changes the root/admin restructions on certain APIs. See \a nvmlRestrictedAPI_t for the list of supported APIs. + * This method can be used by a root/admin user to give non-root/admin access to certain otherwise-restricted APIs. + * The new setting lasts for the lifetime of the NVIDIA driver; it is not persistent. See \a nvmlDeviceGetAPIRestriction + * to query the current restriction settings. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * @param device The identifier of the target device + * @param apiType Target API type for this operation + * @param isRestricted The target restriction + * + * @return + * - \ref NVML_SUCCESS if \a isRestricted has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a apiType incorrect + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support changing API restrictions or the device does not support + * the feature that api restrictions are being set for (E.G. Enabling/disabling auto + * boosted clocks is not supported by the device) + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlRestrictedAPI_t + */ +nvmlReturn_t DECLDIR nvmlDeviceSetAPIRestriction(nvmlDevice_t device, nvmlRestrictedAPI_t apiType, nvmlEnableState_t isRestricted); + +/** + * Sets the speed of a specified fan. + * + * WARNING: This function changes the fan control policy to manual. It means that YOU have to monitor + * the temperature and adjust the fan speed accordingly. + * If you set the fan speed too low you can burn your GPU! + * Use nvmlDeviceSetDefaultFanSpeed_v2 to restore default control policy. + * + * For all cuda-capable discrete products with fans that are Maxwell or Newer. + * + * device The identifier of the target device + * fan The index of the fan, starting at zero + * speed The target speed of the fan [0-100] in % of max speed + * + * return + * NVML_SUCCESS if the fan speed has been set + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if the device is not valid, or the speed is outside acceptable ranges, + * or if the fan index doesn't reference an actual fan. + * NVML_ERROR_NOT_SUPPORTED if the device is older than Maxwell. + * NVML_ERROR_UNKNOWN if there was an unexpected error. + */ +nvmlReturn_t DECLDIR nvmlDeviceSetFanSpeed_v2(nvmlDevice_t device, unsigned int fan, unsigned int speed); + +/** + * @deprecated Will be deprecated in a future release. Use \ref nvmlDeviceSetClockOffsets instead. It works + * on Maxwell onwards GPU architectures. + * + * Set the GPCCLK VF offset value + * @param[in] device The identifier of the target device + * @param[in] offset The GPCCLK VF offset value to set + * + * @return + * - \ref NVML_SUCCESS if \a offset has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetGpcClkVfOffset(nvmlDevice_t device, int offset); + +/** + * @deprecated Will be deprecated in a future release. Use \ref nvmlDeviceSetClockOffsets instead. It works + * on Maxwell onwards GPU architectures. + * + * Set the MemClk (Memory Clock) VF offset value. It requires elevated privileges. + * @param[in] device The identifier of the target device + * @param[in] offset The MemClk VF offset value to set + * + * @return + * - \ref NVML_SUCCESS if \a offset has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetMemClkVfOffset(nvmlDevice_t device, int offset); + +/** + * @} + */ + +/** @addtogroup nvmlAccountingStats + * @{ + */ + +/** + * Enables or disables per process accounting. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * @note This setting is not persistent and will default to disabled after driver unloads. + * Enable persistence mode to be sure the setting doesn't switch off to disabled. + * + * @note Enabling accounting mode has no negative impact on the GPU performance. + * + * @note Disabling accounting clears all accounting pids information. + * + * @note On MIG-enabled GPUs, accounting mode would be set to DISABLED and changing it is not supported. + * + * See \ref nvmlDeviceGetAccountingMode + * See \ref nvmlDeviceGetAccountingStats + * See \ref nvmlDeviceClearAccountingPids + * + * @param device The identifier of the target device + * @param mode The target accounting mode + * + * @return + * - \ref NVML_SUCCESS if the new mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a mode are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetAccountingMode(nvmlDevice_t device, nvmlEnableState_t mode); + +/** + * Clears accounting information about all processes that have already terminated. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlDeviceGetAccountingMode + * See \ref nvmlDeviceGetAccountingStats + * See \ref nvmlDeviceSetAccountingMode + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if accounting information has been cleared + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceClearAccountingPids(nvmlDevice_t device); + +/** @} */ // @addtogroup nvmlAccountingStats + +/***************************************************************************************************/ +/** @defgroup NvLink NvLink Methods + * This chapter describes methods that NVML can perform on NVLINK enabled devices. + * @{ + */ +/***************************************************************************************************/ + +#define NVML_NVLINK_BER_MANTISSA_SHIFT 8 +#define NVML_NVLINK_BER_MANTISSA_WIDTH 0xf + +#define NVML_NVLINK_BER_EXP_SHIFT 0 +#define NVML_NVLINK_BER_EXP_WIDTH 0xff + +/** + * Nvlink Error counter BER can be obtained using the below macros + * Ex - NVML_NVLINK_ERROR_COUNTER_BER_GET(var, BER_MANTISSA) + */ +#define NVML_NVLINK_ERROR_COUNTER_BER_GET(var, type) \ + (((var) >> NVML_NVLINK_##type##_SHIFT) & \ + (NVML_NVLINK_##type##_WIDTH)) \ + +/* + * NVML_FI_DEV_NVLINK_GET_STATE state enums + */ +#define NVML_NVLINK_STATE_INACTIVE 0x0 +#define NVML_NVLINK_STATE_ACTIVE 0x1 +#define NVML_NVLINK_STATE_SLEEP 0x2 + +#define NVML_NVLINK_TOTAL_SUPPORTED_BW_MODES 23 + +typedef struct +{ + unsigned int version; + unsigned char bwModes[NVML_NVLINK_TOTAL_SUPPORTED_BW_MODES]; + unsigned char totalBwModes; +} nvmlNvlinkSupportedBwModes_v1_t; +typedef nvmlNvlinkSupportedBwModes_v1_t nvmlNvlinkSupportedBwModes_t; +#define nvmlNvlinkSupportedBwModes_v1 NVML_STRUCT_VERSION(NvlinkSupportedBwModes, 1) + +typedef struct +{ + unsigned int version; + unsigned int bIsBest; + unsigned char bwMode; +} nvmlNvlinkGetBwMode_v1_t; +typedef nvmlNvlinkGetBwMode_v1_t nvmlNvlinkGetBwMode_t; +#define nvmlNvlinkGetBwMode_v1 NVML_STRUCT_VERSION(NvlinkGetBwMode, 1) + +typedef struct +{ + unsigned int version; + unsigned int bSetBest; + unsigned char bwMode; +} nvmlNvlinkSetBwMode_v1_t; +typedef nvmlNvlinkSetBwMode_v1_t nvmlNvlinkSetBwMode_t; +#define nvmlNvlinkSetBwMode_v1 NVML_STRUCT_VERSION(NvlinkSetBwMode, 1) + +/** + * Struct to represent per device NVLINK information v1 + */ +typedef struct +{ + unsigned int version; //!< IN - the API version number + unsigned int isNvleEnabled; //!< OUT - NVLINK encryption enablement +} nvmlNvLinkInfo_v1_t; +#define nvmlNvLinkInfo_v1 NVML_STRUCT_VERSION(NvLinkInfo, 1) + +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_MSE 0x1 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR 0x2 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR_UPHY 0x3 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR_CLN 0x4 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR_DLN 0x5 +#define NVML_NVLINK_FIRMWARE_VERSION_LENGTH 100 + +/** + * Struct to represent NVLINK firmware Semantic versioning and ucode type + */ +typedef struct +{ + unsigned char ucodeType; + unsigned int major; + unsigned int minor; + unsigned int subMinor; +} nvmlNvlinkFirmwareVersion_t; + +/** + * Struct to represent NVLINK firmware information + */ +typedef struct +{ + nvmlNvlinkFirmwareVersion_t firmwareVersion[NVML_NVLINK_FIRMWARE_VERSION_LENGTH]; //!< OUT - NVLINK firmware version + unsigned int numValidEntries; //!< OUT - Number of valid firmware entries +} nvmlNvlinkFirmwareInfo_t; + +/** + * Struct to represent per device NVLINK information v2 + */ +typedef struct +{ + unsigned int version; //!< IN - the API version number + unsigned int isNvleEnabled; //!< OUT - NVLINK encryption enablement + nvmlNvlinkFirmwareInfo_t firmwareInfo; //!< OUT - NVLINK Firmware info +} nvmlNvLinkInfo_v2_t; +typedef nvmlNvLinkInfo_v2_t nvmlNvLinkInfo_t; +#define nvmlNvLinkInfo_v2 NVML_STRUCT_VERSION(NvLinkInfo, 2) + +/** + * Retrieves the state of the device's NvLink for the link specified + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param isActive \a nvmlEnableState_t where NVML_FEATURE_ENABLED indicates that + * the link is active and NVML_FEATURE_DISABLED indicates it + * is inactive + * + * @return + * - \ref NVML_SUCCESS if \a isActive has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid or \a isActive is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkState(nvmlDevice_t device, unsigned int link, nvmlEnableState_t *isActive); + +/** + * Retrieves the version of the device's NvLink for the link specified + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param version Requested NvLink version from nvmlNvlinkVersion_t + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid or \a version is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkVersion(nvmlDevice_t device, unsigned int link, unsigned int *version); + +/** + * Retrieves the requested capability from the device's NvLink for the link specified + * Please refer to the \a nvmlNvLinkCapability_t structure for the specific caps that can be queried + * The return value should be treated as a boolean. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param capability Specifies the \a nvmlNvLinkCapability_t to be queried + * @param capResult A boolean for the queried capability indicating that feature is available + * + * @return + * - \ref NVML_SUCCESS if \a capResult has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, or \a capability is invalid or \a capResult is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkCapability(nvmlDevice_t device, unsigned int link, + nvmlNvLinkCapability_t capability, unsigned int *capResult); + +/** + * Retrieves the PCI information for the remote node on a NvLink link + * Note: pciSubSystemId is not filled in this function and is indeterminate + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param pci \a nvmlPciInfo_t of the remote node for the specified link + * + * @return + * - \ref NVML_SUCCESS if \a pci has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid or \a pci is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkRemotePciInfo_v2(nvmlDevice_t device, unsigned int link, nvmlPciInfo_t *pci); + +/** + * Retrieves the specified error counter value + * Please refer to \a nvmlNvLinkErrorCounter_t for error counters that are available + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param counter Specifies the NvLink counter to be queried + * @param counterValue Returned counter value + * + * @return + * - \ref NVML_SUCCESS if \a counter has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, or \a counter is invalid or \a counterValue is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkErrorCounter(nvmlDevice_t device, unsigned int link, + nvmlNvLinkErrorCounter_t counter, unsigned long long *counterValue); + +/** + * Resets all error counters to zero + * Please refer to \a nvmlNvLinkErrorCounter_t for the list of error counters that are reset + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * + * @return + * - \ref NVML_SUCCESS if the reset is successful + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceResetNvLinkErrorCounters(nvmlDevice_t device, unsigned int link); + +/** + * @deprecated Setting utilization counter control is no longer supported. + * + * Set the NVLINK utilization counter control information for the specified counter, 0 or 1. + * Please refer to \a nvmlNvLinkUtilizationControl_t for the structure definition. Performs a reset + * of the counters if the reset parameter is non-zero. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param counter Specifies the counter that should be set (0 or 1). + * @param link Specifies the NvLink link to be queried + * @param control A reference to the \a nvmlNvLinkUtilizationControl_t to set + * @param reset Resets the counters on set if non-zero + * + * @return + * - \ref NVML_SUCCESS if the control has been set successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a counter, \a link, or \a control is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetNvLinkUtilizationControl(nvmlDevice_t device, unsigned int link, unsigned int counter, + nvmlNvLinkUtilizationControl_t *control, unsigned int reset); + +/** + * @deprecated Getting utilization counter control is no longer supported. + * + * Get the NVLINK utilization counter control information for the specified counter, 0 or 1. + * Please refer to \a nvmlNvLinkUtilizationControl_t for the structure definition + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param counter Specifies the counter that should be set (0 or 1). + * @param link Specifies the NvLink link to be queried + * @param control A reference to the \a nvmlNvLinkUtilizationControl_t to place information + * + * @return + * - \ref NVML_SUCCESS if the control has been set successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a counter, \a link, or \a control is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkUtilizationControl(nvmlDevice_t device, unsigned int link, unsigned int counter, + nvmlNvLinkUtilizationControl_t *control); + + +/** + * @deprecated Use \ref nvmlDeviceGetFieldValues with NVML_FI_DEV_NVLINK_THROUGHPUT_* as field values instead. + * + * Retrieve the NVLINK utilization counter based on the current control for a specified counter. + * In general it is good practice to use \a nvmlDeviceSetNvLinkUtilizationControl + * before reading the utilization counters as they have no default state + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param counter Specifies the counter that should be read (0 or 1). + * @param rxcounter Receive counter return value + * @param txcounter Transmit counter return value + * + * @return + * - \ref NVML_SUCCESS if \a rxcounter and \a txcounter have been successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a counter, or \a link is invalid or \a rxcounter or \a txcounter are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkUtilizationCounter(nvmlDevice_t device, unsigned int link, unsigned int counter, + unsigned long long *rxcounter, unsigned long long *txcounter); + +/** + * @deprecated Freezing NVLINK utilization counters is no longer supported. + * + * Freeze the NVLINK utilization counters + * Both the receive and transmit counters are operated on by this function + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param counter Specifies the counter that should be frozen (0 or 1). + * @param freeze NVML_FEATURE_ENABLED = freeze the receive and transmit counters + * NVML_FEATURE_DISABLED = unfreeze the receive and transmit counters + * + * @return + * - \ref NVML_SUCCESS if counters were successfully frozen or unfrozen + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, \a counter, or \a freeze is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceFreezeNvLinkUtilizationCounter (nvmlDevice_t device, unsigned int link, + unsigned int counter, nvmlEnableState_t freeze); + +/** + * @deprecated Resetting NVLINK utilization counters is no longer supported. + * + * Reset the NVLINK utilization counters + * Both the receive and transmit counters are operated on by this function + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be reset + * @param counter Specifies the counter that should be reset (0 or 1) + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, or \a counter is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceResetNvLinkUtilizationCounter (nvmlDevice_t device, unsigned int link, unsigned int counter); + +/** +* Get the NVLink device type of the remote device connected over the given link. +* +* @param device The device handle of the target GPU +* @param link The NVLink link index on the target GPU +* @param pNvLinkDeviceType Pointer in which the output remote device type is returned +* +* @return +* - \ref NVML_SUCCESS if \a pNvLinkDeviceType has been set +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_NOT_SUPPORTED if NVLink is not supported +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid, or +* \a pNvLinkDeviceType is NULL +* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is +* otherwise inaccessible +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkRemoteDeviceType(nvmlDevice_t device, unsigned int link, nvmlIntNvLinkDeviceType_t *pNvLinkDeviceType); + +/** + * Set NvLink Low Power Threshold for device. + * + * For Hopper &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param info Reference to \a nvmlNvLinkPowerThres_t struct + * input parameters + * + * @return + * - \ref NVML_SUCCESS if the \a Threshold is successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a Threshold is not within range + * - \ref NVML_ERROR_NOT_READY if an internal driver setting prevents the threshold from being used + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * + **/ +nvmlReturn_t DECLDIR nvmlDeviceSetNvLinkDeviceLowPowerThreshold(nvmlDevice_t device, nvmlNvLinkPowerThres_t *info); + +/** + * Set the global nvlink bandwith mode + * + * @param nvlinkBwMode nvlink bandwidth mode + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid argument is provided + * - \ref NVML_ERROR_IN_USE if P2P object exists + * - \ref NVML_ERROR_NOT_SUPPORTED if GPU is not Hopper or newer architecture. + * - \ref NVML_ERROR_NO_PERMISSION if not root user + */ +nvmlReturn_t DECLDIR nvmlSystemSetNvlinkBwMode(unsigned int nvlinkBwMode); + +/** + * Get the global nvlink bandwith mode + * + * @param nvlinkBwMode reference of nvlink bandwidth mode + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid pointer is provided + * - \ref NVML_ERROR_NOT_SUPPORTED if GPU is not Hopper or newer architecture. + * - \ref NVML_ERROR_NO_PERMISSION if not root user + */ +nvmlReturn_t DECLDIR nvmlSystemGetNvlinkBwMode(unsigned int *nvlinkBwMode); + +/** + * Get the supported NvLink Reduced Bandwidth Modes of the device + * + * For Blackwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param supportedBwMode Reference to \a nvmlNvlinkSupportedBwModes_t + * + * @return + * - \ref NVML_SUCCESS if the query was successful + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or supportedBwMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified is not supported + **/ +nvmlReturn_t DECLDIR nvmlDeviceGetNvlinkSupportedBwModes(nvmlDevice_t device, + nvmlNvlinkSupportedBwModes_t *supportedBwMode); + +/** + * Get the NvLink Reduced Bandwidth Mode for the device + * + * For Blackwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param getBwMode Reference to \a nvmlNvlinkGetBwMode_t + * + * @return + * - \ref NVML_SUCCESS if the query was successful + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or getBwMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified is not supported + **/ +nvmlReturn_t DECLDIR nvmlDeviceGetNvlinkBwMode(nvmlDevice_t device, + nvmlNvlinkGetBwMode_t *getBwMode); + +/** + * Set the NvLink Reduced Bandwidth Mode for the device + * + * For Blackwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param setBwMode Reference to \a nvmlNvlinkSetBwMode_t + * + * @return + * - \ref NVML_SUCCESS if the Bandwidth mode was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or setBwMode is NULL + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change Bandwidth mode + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified is not supported + **/ +nvmlReturn_t DECLDIR nvmlDeviceSetNvlinkBwMode(nvmlDevice_t device, + nvmlNvlinkSetBwMode_t *setBwMode); + +/** + * Query NVLINK information associated with this device. + * + * @param[in] device The identifier of the target device + * @param[out] info Reference to \a nvmlNvLinkInfo_t + * + * @return + * - \ref NVML_SUCCESS if query is success + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a info is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkInfo(nvmlDevice_t device, nvmlNvLinkInfo_t *info); + +/** @} */ // @defgroup NvLink NvLink Methods + +/***************************************************************************************************/ +/** @defgroup nvmlEvents Event Handling Methods + * This chapter describes methods that NVML can perform against each device to register and wait for + * some event to occur. + * @{ + */ +/***************************************************************************************************/ + +/** + * Create an empty set of events. + * Event set should be freed by \ref nvmlEventSetFree + * + * For Fermi &tm; or newer fully supported devices. + * @param set Reference in which to return the event handle + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a set is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventSetFree + */ +nvmlReturn_t DECLDIR nvmlEventSetCreate(nvmlEventSet_t *set); + +/** + * Starts recording of events on a specified devices and add the events to specified \ref nvmlEventSet_t + * + * For Fermi &tm; or newer fully supported devices. + * ECC events are available only on ECC-enabled devices (see \ref nvmlDeviceGetTotalEccErrors) + * Power capping events are available only on Power Management enabled devices (see \ref nvmlDeviceGetPowerManagementMode) + * + * For Linux only. + * + * This call starts recording of events on specific device. + * All events that occurred before this call are not recorded. + * Checking if some event occurred can be done with \ref nvmlEventSetWait_v2 + * + * If function reports NVML_ERROR_UNKNOWN, event set is in undefined state and should be freed. + * If function reports NVML_ERROR_NOT_SUPPORTED, event set can still be used. None of the requested eventTypes + * are registered in that case. + * + * @param device The identifier of the target device + * @param eventTypes Bitmask of \ref nvmlEventType to record + * @param set Set to which add new event types + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a eventTypes is invalid or \a set is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the platform does not support this feature or some of requested event types + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventType + * @see nvmlDeviceGetSupportedEventTypes + * @see nvmlEventSetWait + * @see nvmlEventSetFree + */ +nvmlReturn_t DECLDIR nvmlDeviceRegisterEvents(nvmlDevice_t device, unsigned long long eventTypes, nvmlEventSet_t set); + +/** + * Returns information about events supported on device + * + * For Fermi &tm; or newer fully supported devices. + * + * Events are not supported on Windows. So this function returns an empty mask in \a eventTypes on Windows. + * + * @param device The identifier of the target device + * @param eventTypes Reference in which to return bitmask of supported events + * + * @return + * - \ref NVML_SUCCESS if the eventTypes has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a eventType is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventType + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedEventTypes(nvmlDevice_t device, unsigned long long *eventTypes); + +/** + * Waits on events and delivers events + * + * For Fermi &tm; or newer fully supported devices. + * + * If some events are ready to be delivered at the time of the call, function returns immediately. + * If there are no events ready to be delivered, function sleeps till event arrives + * but not longer than specified timeout. This function in certain conditions can return before + * specified timeout passes (e.g. when interrupt arrives) + * + * On Windows, in case of Xid error, the function returns the most recent Xid error type seen by the system. + * If there are multiple Xid errors generated before nvmlEventSetWait is invoked then the last seen Xid error + * type is returned for all Xid error events. + * + * On Linux, every Xid error event would return the associated event data and other information if applicable. + * + * In MIG mode, if device handle is provided, the API reports all the events for the available instances, + * only if the caller has appropriate privileges. In absence of required privileges, only the events which + * affect all the instances (i.e. whole device) are reported. + * + * This API does not currently support per-instance event reporting using MIG device handles. + * + * @param set Reference to set of events to wait on + * @param data Reference in which to return event data + * @param timeoutms Maximum amount of wait time in milliseconds for registered event + * + * @return + * - \ref NVML_SUCCESS if the data has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a data is NULL + * - \ref NVML_ERROR_TIMEOUT if no event arrived in specified timeout or interrupt arrived + * - \ref NVML_ERROR_GPU_IS_LOST if a GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventType + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlEventSetWait_v2(nvmlEventSet_t set, nvmlEventData_t * data, unsigned int timeoutms); + +/** + * Releases events in the set + * + * For Fermi &tm; or newer fully supported devices. + * + * @param set Reference to events to be released + * + * @return + * - \ref NVML_SUCCESS if the event has been successfully released + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlEventSetFree(nvmlEventSet_t set); + +/** + * Create an empty set of system events. + * Event set should be freed by \ref nvmlSystemEventSetFree + * + * For Fermi &tm; or newer fully supported devices. + * @param request Reference to nvmlSystemEventSetCreateRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlSystemEventSetFree + */ +nvmlReturn_t DECLDIR nvmlSystemEventSetCreate(nvmlSystemEventSetCreateRequest_t *request); + +/** + * Releases system event set + * + * For Fermi &tm; or newer fully supported devices. + * + * @param request Reference to nvmlSystemEventSetFreeRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlSystemEventSetFree(nvmlSystemEventSetFreeRequest_t *request); + +/** + * Starts recording of events on system and add the events to specified \ref nvmlSystemEventSet_t + * + * For Linux only. + * + * This call starts recording of events on specific device. + * All events that occurred before this call are not recorded. + * Checking if some event occurred can be done with \ref nvmlSystemEventSetWait + * + * If function reports NVML_ERROR_UNKNOWN, event set is in undefined state and should be freed. + * If function reports NVML_ERROR_NOT_SUPPORTED, event set can still be used. None of the requested eventTypes + * are registered in that case. + * + * @param request Reference to the struct nvmlSystemRegisterEventRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlSystemEventType + * @see nvmlSystemEventSetWait + * @see nvmlEventSetFree + */ +nvmlReturn_t DECLDIR nvmlSystemRegisterEvents(nvmlSystemRegisterEventRequest_t *request); + +/** + * Waits on system events and delivers events + * + * For Fermi &tm; or newer fully supported devices. + * + * If some events are ready to be delivered at the time of the call, function returns immediately. + * If there are no events ready to be delivered, function sleeps till event arrives + * but not longer than specified timeout. This function in certain conditions can return before + * specified timeout passes (e.g. when interrupt arrives) + * + * if the return request->numEvent equals to request->dataSize, there might be outstanding + * event, it is recommended to call nvmlSystemEventSetWait again to query all the events. + * + * @param request Reference in which to nvmlSystemEventSetWaitRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_TIMEOUT if no event notification after timeoutms + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlSystemEventType + * @see nvmlSystemRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlSystemEventSetWait(nvmlSystemEventSetWaitRequest_t *request); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlZPI Drain states + * This chapter describes methods that NVML can perform against each device to control their drain state + * and recognition by NVML and NVIDIA kernel driver. These methods can be used with out-of-band tools to + * power on/off GPUs, enable robust reset scenarios, etc. + * @{ + */ +/***************************************************************************************************/ + +/** + * Modify the drain state of a GPU. This method forces a GPU to no longer accept new incoming requests. + * Any new NVML process will no longer see this GPU. Persistence mode for this GPU must be turned off before + * this call is made. + * Must be called as administrator. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI address of the GPU drain state to be modified + * @param newState The drain state that should be entered, see \ref nvmlEnableState_t + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a nvmlIndex or \a newState is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the calling process has insufficient permissions to perform operation + * - \ref NVML_ERROR_IN_USE if the device has persistence mode turned on + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceModifyDrainState (nvmlPciInfo_t *pciInfo, nvmlEnableState_t newState); + +/** + * Query the drain state of a GPU. This method is used to check if a GPU is in a currently draining + * state. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI address of the GPU drain state to be queried + * @param currentState The current drain state for this GPU, see \ref nvmlEnableState_t + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a nvmlIndex or \a currentState is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceQueryDrainState (nvmlPciInfo_t *pciInfo, nvmlEnableState_t *currentState); + +/** + * This method will remove the specified GPU from the view of both NVML and the NVIDIA kernel driver + * as long as no other processes are attached. If other processes are attached, this call will return + * NVML_ERROR_IN_USE and the GPU will be returned to its original "draining" state. Note: the + * only situation where a process can still be attached after nvmlDeviceModifyDrainState() is called + * to initiate the draining state is if that process was using, and is still using, a GPU before the + * call was made. Also note, persistence mode counts as an attachment to the GPU thus it must be disabled + * prior to this call. + * + * For long-running NVML processes please note that this will change the enumeration of current GPUs. + * For example, if there are four GPUs present and GPU1 is removed, the new enumeration will be 0-2. + * Also, device handles after the removed GPU will not be valid and must be re-established. + * Must be run as administrator. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI address of the GPU to be removed + * @param gpuState Whether the GPU is to be removed, from the OS + * see \ref nvmlDetachGpuState_t + * @param linkState Requested upstream PCIe link state, see \ref nvmlPcieLinkState_t + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a nvmlIndex is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_IN_USE if the device is still in use and cannot be removed + */ +nvmlReturn_t DECLDIR nvmlDeviceRemoveGpu_v2(nvmlPciInfo_t *pciInfo, nvmlDetachGpuState_t gpuState, nvmlPcieLinkState_t linkState); + +/** + * Request the OS and the NVIDIA kernel driver to rediscover a portion of the PCI subsystem looking for GPUs that + * were previously removed. The portion of the PCI tree can be narrowed by specifying a domain, bus, and device. + * If all are zeroes then the entire PCI tree will be searched. Please note that for long-running NVML processes + * the enumeration will change based on how many GPUs are discovered and where they are inserted in bus order. + * + * In addition, all newly discovered GPUs will be initialized and their ECC scrubbed which may take several seconds + * per GPU. Also, all device handles are no longer guaranteed to be valid post discovery. + * + * Must be run as administrator. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI tree to be searched. Only the domain, bus, and device + * fields are used in this call. + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a pciInfo is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the operating system does not support this feature + * - \ref NVML_ERROR_OPERATING_SYSTEM if the operating system is denying this feature + * - \ref NVML_ERROR_NO_PERMISSION if the calling process has insufficient permissions to perform operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceDiscoverGpus (nvmlPciInfo_t *pciInfo); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFieldValueQueries Field Value Queries + * This chapter describes NVML operations that are associated with retrieving Field Values from NVML + * @{ + */ +/***************************************************************************************************/ + +/** + * Request values for a list of fields for a device. This API allows multiple fields to be queried at once. + * If any of the underlying fieldIds are populated by the same driver call, the results for those field IDs + * will be populated from a single call rather than making a driver call for each fieldId. + * + * @param device The device handle of the GPU to request field values for + * @param valuesCount Number of entries in values that should be retrieved + * @param values Array of \a valuesCount structures to hold field values. + * Each value's fieldId must be populated prior to this call + * + * @return + * - \ref NVML_SUCCESS if any values in \a values were populated. Note that you must + * check the nvmlReturn field of each value for each individual + * status + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a values is NULL + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFieldValues(nvmlDevice_t device, int valuesCount, nvmlFieldValue_t *values); + +/** + * Clear values for a list of fields for a device. This API allows multiple fields to be cleared at once. + * + * @param device The device handle of the GPU to request field values for + * @param valuesCount Number of entries in values that should be cleared + * @param values Array of \a valuesCount structures to hold field values. + * Each value's fieldId must be populated prior to this call + * + * @return + * - \ref NVML_SUCCESS if any values in \a values were cleared. Note that you must + * check the nvmlReturn field of each value for each individual + * status + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a values is NULL + */ +nvmlReturn_t DECLDIR nvmlDeviceClearFieldValues(nvmlDevice_t device, int valuesCount, nvmlFieldValue_t *values); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVirtualGpuQueries vGPU APIs + * This chapter describes operations that are associated with NVIDIA vGPU Software products. + * @{ + */ +/***************************************************************************************************/ + +/** + * This method is used to get the virtualization mode corresponding to the GPU. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device Identifier of the target device + * @param pVirtualMode Reference to virtualization mode. One of NVML_GPU_VIRTUALIZATION_? + * + * @return + * - \ref NVML_SUCCESS if \a pVirtualMode is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pVirtualMode is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVirtualizationMode(nvmlDevice_t device, nvmlGpuVirtualizationMode_t *pVirtualMode); + +/** + * Queries if SR-IOV host operation is supported on a vGPU supported device. + * + * Checks whether SR-IOV host capability is supported by the device and the + * driver, and indicates device is in SR-IOV mode if both of these conditions + * are true. + * + * @param device The identifier of the target device + * @param pHostVgpuMode Reference in which to return the current vGPU mode + * + * @return + * - \ref NVML_SUCCESS if device's vGPU mode has been successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device handle is 0 or \a pVgpuMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device doesn't support this feature. + * - \ref NVML_ERROR_UNKNOWN if any unexpected error occurred + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHostVgpuMode(nvmlDevice_t device, nvmlHostVgpuMode_t *pHostVgpuMode); + +/** + * This method is used to set the virtualization mode corresponding to the GPU. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device Identifier of the target device + * @param virtualMode virtualization mode. One of NVML_GPU_VIRTUALIZATION_? + * + * @return + * - \ref NVML_SUCCESS if \a virtualMode is set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a virtualMode is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if setting of virtualization mode is not supported. + * - \ref NVML_ERROR_NO_PERMISSION if setting of virtualization mode is not allowed for this client. + */ +nvmlReturn_t DECLDIR nvmlDeviceSetVirtualizationMode(nvmlDevice_t device, nvmlGpuVirtualizationMode_t virtualMode); + +/** + * Get the vGPU heterogeneous mode for the device. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * On successful return, the function returns \a pHeterogeneousMode->mode with the current vGPU heterogeneous mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to retrieve the vGPU heterogeneous mode. + * \a pHeterogeneousMode->mode can either be \ref NVML_FEATURE_ENABLED or \ref NVML_FEATURE_DISABLED. + * + * @param device The identifier of the target device + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a pHeterogeneousMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device doesn't support this feature + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuHeterogeneousMode(nvmlDevice_t device, nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** + * Enable or disable vGPU heterogeneous mode for the device. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * API would return an appropriate error code upon unsuccessful activation. For example, the heterogeneous mode + * set will fail with error \ref NVML_ERROR_IN_USE if any vGPU instance is active on the device. The caller of this API + * is expected to shutdown the vGPU VMs and retry setting the \a mode. + * On KVM platform, setting heterogeneous mode is allowed, if no MDEV device is created on the device, else will fail + * with same error \ref NVML_ERROR_IN_USE. + * On successful return, the function updates the vGPU heterogeneous mode with the user provided \a pHeterogeneousMode->mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to set the vGPU heterogeneous mode. + * + * @param device Identifier of the target device + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a pHeterogeneousMode is NULL or \a pHeterogeneousMode->mode is invalid + * - \ref NVML_ERROR_IN_USE If the \a device is in use + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device doesn't support this feature + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetVgpuHeterogeneousMode(nvmlDevice_t device, const nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** + * Query the placement ID of active vGPU instance. + * + * When in vGPU heterogeneous mode, this function returns a valid placement ID as \a pPlacement->placementId + * else NVML_INVALID_VGPU_PLACEMENT_ID is returned. + * \a pPlacement->version is the version number of the structure nvmlVgpuPlacementId_t, the caller should + * set the correct version number to get placement id of the vGPU instance \a vgpuInstance. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param pPlacement Pointer to vGPU placement ID structure \a nvmlVgpuPlacementId_t + * + * @return + * - \ref NVML_SUCCESS If information is successfully retrieved + * - \ref NVML_ERROR_NOT_FOUND If \a vgpuInstance does not match a valid active vGPU instance + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuInstance is invalid or \a pPlacement is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pPlacement is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetPlacementId(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuPlacementId_t *pPlacement); + +/** + * Query the supported vGPU placement ID of the vGPU type. + * + * The function returns an array of supported vGPU placement IDs for the specified vGPU type ID in the buffer provided + * by the caller at \a pPlacementList->placementIds. The required memory for the placementIds array must be allocated + * based on the maximum number of vGPU type instances, which is retrievable through \ref nvmlVgpuTypeGetMaxInstances(). + * If the provided count by the caller is insufficient, the function will return NVML_ERROR_INSUFFICIENT_SIZE along with + * the number of required entries in \a pPlacementList->count. The caller should then reallocate a buffer with the size + * of pPlacementList->count * sizeof(pPlacementList->placementIds) and invoke the function again. + * + * To obtain a list of homogeneous placement IDs, the caller needs to set \a pPlacementList->mode to NVML_VGPU_PGPU_HOMOGENEOUS_MODE. + * For heterogeneous placement IDs, \a pPlacementList->mode should be set to NVML_VGPU_PGPU_HETEROGENEOUS_MODE. + * By default, a list of heterogeneous placement IDs is returned. + * + * @param device Identifier of the target device + * @param vgpuTypeId Handle to vGPU type. The vGPU type ID + * @param pPlacementList Pointer to the vGPU placement structure \a nvmlVgpuPlacementList_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a vgpuTypeId is invalid or \a pPlacementList is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device or \a vgpuTypeId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pPlacementList is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If the buffer is small, element count is returned in \a pPlacementList->count + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuTypeSupportedPlacements(nvmlDevice_t device, nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuPlacementList_t *pPlacementList); + +/** + * Query the creatable vGPU placement ID of the vGPU type. + * + * An array of creatable vGPU placement IDs for the vGPU type ID indicated by \a vgpuTypeId is returned in the + * caller-supplied buffer of \a pPlacementList->placementIds. Memory needed for the placementIds array should be + * allocated based on maximum instances of a vGPU type which can be queried via \ref nvmlVgpuTypeGetMaxInstances(). + * If the provided count by the caller is insufficient, the function will return NVML_ERROR_INSUFFICIENT_SIZE along with + * the number of required entries in \a pPlacementList->count. The caller should then reallocate a buffer with the size + * of pPlacementList->count * sizeof(pPlacementList->placementIds) and invoke the function again. + * + * The creatable vGPU placement IDs may differ over time, as there may be restrictions on what type of vGPU the + * vGPU instance is running. + * + * @param device The identifier of the target device + * @param vgpuTypeId Handle to vGPU type. The vGPU type ID + * @param pPlacementList Pointer to the list of vGPU placement structure \a nvmlVgpuPlacementList_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a vgpuTypeId is invalid or \a pPlacementList is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device or \a vgpuTypeId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pPlacementList is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuTypeCreatablePlacements(nvmlDevice_t device, nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuPlacementList_t *pPlacementList); + +/** + * Retrieve the static GSP heap size of the vGPU type in bytes + * + * @param vgpuTypeId Handle to vGPU type + * @param gspHeapSize Reference to return the GSP heap size value + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuTypeId is invalid, or \a gspHeapSize is NULL + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetGspHeapSize(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *gspHeapSize); + +/** + * Retrieve the static framebuffer reservation of the vGPU type in bytes + * + * @param vgpuTypeId Handle to vGPU type + * @param fbReservation Reference to return the framebuffer reservation + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuTypeId is invalid, or \a fbReservation is NULL + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetFbReservation(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *fbReservation); + +/** + * Retrieve the currently used runtime state size of the vGPU instance + * + * This size represents the maximum in-memory data size utilized by a vGPU instance during standard operation. + * This measurement is exclusive of frame buffer (FB) data size assigned to the vGPU instance. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param pState Pointer to the vGPU runtime state's structure \a nvmlVgpuRuntimeState_t + * + * @return + * - \ref NVML_SUCCESS If information is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuInstance is invalid, or \a pState is NULL + * - \ref NVML_ERROR_NOT_FOUND If \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pState is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetRuntimeStateSize(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuRuntimeState_t *pState); + +/** + * Set the desirable vGPU capability of a device + * + * Refer to the \a nvmlDeviceVgpuCapability_t structure for the specific capabilities that can be set. + * See \ref nvmlEnableState_t for available state. + * + * @param device The identifier of the target device + * @param capability Specifies the \a nvmlDeviceVgpuCapability_t to be set + * @param state The target capability mode + * + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, or \a capability is invalid, or \a state is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported in current state, or \a device not in vGPU mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceSetVgpuCapabilities(nvmlDevice_t device, nvmlDeviceVgpuCapability_t capability, nvmlEnableState_t state); + +/** + * Retrieve the vGPU Software licensable features. + * + * Identifies whether the system supports vGPU Software Licensing. If it does, return the list of licensable feature(s) + * and their current license status. + * + * @param device Identifier of the target device + * @param pGridLicensableFeatures Pointer to structure in which vGPU software licensable features are returned + * + * @return + * - \ref NVML_SUCCESS if licensable features are successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a pGridLicensableFeatures is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures_v4(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVgpu vGPU Management + * @{ + * + * This chapter describes APIs supporting NVIDIA vGPU. + */ +/***************************************************************************************************/ + +/** + * Retrieve the requested vGPU driver capability. + * + * Refer to the \a nvmlVgpuDriverCapability_t structure for the specific capabilities that can be queried. + * The return value in \a capResult should be treated as a boolean, with a non-zero value indicating that the capability + * is supported. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param capability Specifies the \a nvmlVgpuDriverCapability_t to be queried + * @param capResult A boolean for the queried capability indicating that feature is supported + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a capability is invalid, or \a capResult is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED the API is not supported in current state or \a devices not in vGPU mode + * - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlGetVgpuDriverCapabilities(nvmlVgpuDriverCapability_t capability, unsigned int *capResult); + +/** + * Retrieve the requested vGPU capability for GPU. + * + * Refer to the \a nvmlDeviceVgpuCapability_t structure for the specific capabilities that can be queried. + * The return value in \a capResult reports a non-zero value indicating that the capability + * is supported, and also reports the capability's data based on the queried capability. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param capability Specifies the \a nvmlDeviceVgpuCapability_t to be queried + * @param capResult Specifies that the queried capability is supported, and also returns capability's data + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a capability is invalid, or \a capResult is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED the API is not supported in current state or \a device not in vGPU mode + * - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuCapabilities(nvmlDevice_t device, nvmlDeviceVgpuCapability_t capability, unsigned int *capResult); + +/** + * Retrieve the supported vGPU types on a physical GPU (device). + * + * An array of supported vGPU types for the physical GPU indicated by \a device is returned in the caller-supplied buffer + * pointed at by \a vgpuTypeIds. The element count of nvmlVgpuTypeId_t array is passed in \a vgpuCount, and \a vgpuCount + * is used to return the number of vGPU types written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the vGPU type array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlVgpuTypeId_t array required in \a vgpuCount. + * To query the number of vGPU types supported for the GPU, call this function with *vgpuCount = 0. + * The code will return NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if no vGPU types are supported. + * + * @param device The identifier of the target device + * @param vgpuCount Pointer to caller-supplied array size, and returns number of vGPU types + * @param vgpuTypeIds Pointer to caller-supplied array in which to return list of vGPU types + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a vgpuTypeIds buffer is too small, array element count is returned in \a vgpuCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuCount is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedVgpus(nvmlDevice_t device, unsigned int *vgpuCount, nvmlVgpuTypeId_t *vgpuTypeIds); + +/** + * Retrieve the currently creatable vGPU types on a physical GPU (device). + * + * An array of creatable vGPU types for the physical GPU indicated by \a device is returned in the caller-supplied buffer + * pointed at by \a vgpuTypeIds. The element count of nvmlVgpuTypeId_t array is passed in \a vgpuCount, and \a vgpuCount + * is used to return the number of vGPU types written to the buffer. + * + * The creatable vGPU types for a device may differ over time, as there may be restrictions on what type of vGPU types + * can concurrently run on a device. For example, if only one vGPU type is allowed at a time on a device, then the creatable + * list will be restricted to whatever vGPU type is already running on the device. + * + * If the supplied buffer is not large enough to accommodate the vGPU type array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlVgpuTypeId_t array required in \a vgpuCount. + * To query the number of vGPU types that can be created for the GPU, call this function with *vgpuCount = 0. + * The code will return NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if no vGPU types are creatable. + * + * @param device The identifier of the target device + * @param vgpuCount Pointer to caller-supplied array size, and returns number of vGPU types + * @param vgpuTypeIds Pointer to caller-supplied array in which to return list of vGPU types + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a vgpuTypeIds buffer is too small, array element count is returned in \a vgpuCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuCount is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCreatableVgpus(nvmlDevice_t device, unsigned int *vgpuCount, nvmlVgpuTypeId_t *vgpuTypeIds); + +/** + * Retrieve the class of a vGPU type. It will not exceed 64 characters in length (including the NUL terminator). + * See \ref nvmlConstants::NVML_DEVICE_NAME_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuTypeClass Pointer to string array to return class in + * @param size Size of string + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a vgpuTypeClass is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetClass(nvmlVgpuTypeId_t vgpuTypeId, char *vgpuTypeClass, unsigned int *size); + +/** + * Retrieve the vGPU type name. + * + * The name is an alphanumeric string that denotes a particular vGPU, e.g. GRID M60-2Q. It will not + * exceed 64 characters in length (including the NUL terminator). See \ref + * nvmlConstants::NVML_DEVICE_NAME_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuTypeName Pointer to buffer to return name + * @param size Size of buffer + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetName(nvmlVgpuTypeId_t vgpuTypeId, char *vgpuTypeName, unsigned int *size); + +/** + * Retrieve the GPU Instance Profile ID for the given vGPU type ID. + * The API will return a valid GPU Instance Profile ID for the MIG capable vGPU types, else INVALID_GPU_INSTANCE_PROFILE_ID is + * returned. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param gpuInstanceProfileId GPU Instance Profile ID + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device is not in vGPU Host virtualization mode + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a gpuInstanceProfileId is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetGpuInstanceProfileId(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *gpuInstanceProfileId); + +/** + * Retrieve the device ID of a vGPU type. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param deviceID Device ID and vendor ID of the device contained in single 32 bit value + * @param subsystemID Subsystem ID and subsystem vendor ID of the device contained in single 32 bit value + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a deviceId or \a subsystemID are NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetDeviceID(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *deviceID, unsigned long long *subsystemID); + +/** + * Retrieve the vGPU framebuffer size in bytes. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param fbSize Pointer to framebuffer size in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a fbSize is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetFramebufferSize(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *fbSize); + +/** + * Retrieve count of vGPU's supported display heads. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param numDisplayHeads Pointer to number of display heads + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a numDisplayHeads is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetNumDisplayHeads(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *numDisplayHeads); + +/** + * Retrieve vGPU display head's maximum supported resolution. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param displayIndex Zero-based index of display head + * @param xdim Pointer to maximum number of pixels in X dimension + * @param ydim Pointer to maximum number of pixels in Y dimension + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a xdim or \a ydim are NULL, or \a displayIndex + * is out of range. + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetResolution(nvmlVgpuTypeId_t vgpuTypeId, unsigned int displayIndex, unsigned int *xdim, unsigned int *ydim); + +/** + * Retrieve license requirements for a vGPU type + * + * The license type and version required to run the specified vGPU type is returned as an alphanumeric string, in the form + * ",", for example "GRID-Virtual-PC,2.0". If a vGPU is runnable with* more than one type of license, + * the licenses are delimited by a semicolon, for example "GRID-Virtual-PC,2.0;GRID-Virtual-WS,2.0;GRID-Virtual-WS-Ext,2.0". + * + * The total length of the returned string will not exceed 128 characters, including the NUL terminator. + * See \ref nvmlVgpuConstants::NVML_GRID_LICENSE_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuTypeLicenseString Pointer to buffer to return license info + * @param size Size of \a vgpuTypeLicenseString buffer + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a vgpuTypeLicenseString is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetLicense(nvmlVgpuTypeId_t vgpuTypeId, char *vgpuTypeLicenseString, unsigned int size); + +/** + * Retrieve the static frame rate limit value of the vGPU type + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param frameRateLimit Reference to return the frame rate limit value + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_NOT_SUPPORTED if frame rate limiter is turned off for the vGPU type + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a frameRateLimit is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetFrameRateLimit(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *frameRateLimit); + +/** + * Retrieve the maximum number of vGPU instances creatable on a device for given vGPU type + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param vgpuTypeId Handle to vGPU type + * @param vgpuInstanceCount Pointer to get the max number of vGPU instances + * that can be created on a deicve for given vgpuTypeId + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid or is not supported on target device, + * or \a vgpuInstanceCount is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetMaxInstances(nvmlDevice_t device, nvmlVgpuTypeId_t vgpuTypeId, unsigned int *vgpuInstanceCount); + +/** + * Retrieve the maximum number of vGPU instances supported per VM for given vGPU type + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuInstanceCountPerVm Pointer to get the max number of vGPU instances supported per VM for given \a vgpuTypeId + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a vgpuInstanceCountPerVm is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetMaxInstancesPerVm(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *vgpuInstanceCountPerVm); + +/** + * Retrieve the BAR1 info for given vGPU type. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param bar1Info Pointer to the vGPU type BAR1 information structure \a nvmlVgpuTypeBar1Info_t + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a bar1Info is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetBAR1Info(nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuTypeBar1Info_t *bar1Info); + +/** + * Retrieve the active vGPU instances on a device. + * + * An array of active vGPU instances is returned in the caller-supplied buffer pointed at by \a vgpuInstances. The + * array element count is passed in \a vgpuCount, and \a vgpuCount is used to return the number of vGPU instances + * written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the vGPU instance array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlVgpuInstance_t array required in \a vgpuCount. + * To query the number of active vGPU instances, call this function with *vgpuCount = 0. The code will return + * NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if no vGPU Types are supported. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param vgpuCount Pointer which passes in the array size as well as get + * back the number of types + * @param vgpuInstances Pointer to array in which to return list of vGPU instances + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a vgpuCount is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetActiveVgpus(nvmlDevice_t device, unsigned int *vgpuCount, nvmlVgpuInstance_t *vgpuInstances); + +/** + * Retrieve the VM ID associated with a vGPU instance. + * + * The VM ID is returned as a string, not exceeding 80 characters in length (including the NUL terminator). + * See \ref nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE. + * + * The format of the VM ID varies by platform, and is indicated by the type identifier returned in \a vmIdType. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param vmId Pointer to caller-supplied buffer to hold VM ID + * @param size Size of buffer in bytes + * @param vmIdType Pointer to hold VM ID type + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vmId or \a vmIdType is NULL, or \a vgpuInstance is 0 + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetVmID(nvmlVgpuInstance_t vgpuInstance, char *vmId, unsigned int size, nvmlVgpuVmIdType_t *vmIdType); + +/** + * Retrieve the UUID of a vGPU instance. + * + * The UUID is a globally unique identifier associated with the vGPU, and is returned as a 5-part hexadecimal string, + * not exceeding 80 characters in length (including the NULL terminator). + * See \ref nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param uuid Pointer to caller-supplied buffer to hold vGPU UUID + * @param size Size of buffer in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a uuid is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetUUID(nvmlVgpuInstance_t vgpuInstance, char *uuid, unsigned int size); + +/** + * Retrieve the NVIDIA driver version installed in the VM associated with a vGPU. + * + * The version is returned as an alphanumeric string in the caller-supplied buffer \a version. The length of the version + * string will not exceed 80 characters in length (including the NUL terminator). + * See \ref nvmlConstants::NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE. + * + * nvmlVgpuInstanceGetVmDriverVersion() may be called at any time for a vGPU instance. The guest VM driver version is + * returned as "Not Available" if no NVIDIA driver is installed in the VM, or the VM has not yet booted to the point where the + * NVIDIA driver is loaded and initialized. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param version Caller-supplied buffer to return driver version string + * @param length Size of \a version buffer + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0 + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetVmDriverVersion(nvmlVgpuInstance_t vgpuInstance, char* version, unsigned int length); + +/** + * Retrieve the framebuffer usage in bytes. + * + * Framebuffer usage is the amont of vGPU framebuffer memory that is currently in use by the VM. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance The identifier of the target instance + * @param fbUsage Pointer to framebuffer usage in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a fbUsage is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFbUsage(nvmlVgpuInstance_t vgpuInstance, unsigned long long *fbUsage); + +/** + * @deprecated Use \ref nvmlVgpuInstanceGetLicenseInfo_v2. + * + * Retrieve the current licensing state of the vGPU instance. + * + * If the vGPU is currently licensed, \a licensed is set to 1, otherwise it is set to 0. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param licensed Reference to return the licensing status + * + * @return + * - \ref NVML_SUCCESS if \a licensed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a licensed is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseStatus(nvmlVgpuInstance_t vgpuInstance, unsigned int *licensed); + +/** + * Retrieve the vGPU type of a vGPU instance. + * + * Returns the vGPU type ID of vgpu assigned to the vGPU instance. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param vgpuTypeId Reference to return the vgpuTypeId + * + * @return + * - \ref NVML_SUCCESS if \a vgpuTypeId has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a vgpuTypeId is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetType(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuTypeId_t *vgpuTypeId); + +/** + * Retrieve the frame rate limit set for the vGPU instance. + * + * Returns the value of the frame rate limit set for the vGPU instance + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param frameRateLimit Reference to return the frame rate limit + * + * @return + * - \ref NVML_SUCCESS if \a frameRateLimit has been set + * - \ref NVML_ERROR_NOT_SUPPORTED if frame rate limiter is turned off for the vGPU type + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a frameRateLimit is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFrameRateLimit(nvmlVgpuInstance_t vgpuInstance, unsigned int *frameRateLimit); + +/** + * Retrieve the current ECC mode of vGPU instance. + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param eccMode Reference in which to return the current ECC mode + * + * @return + * - \ref NVML_SUCCESS if the vgpuInstance's ECC mode has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a mode is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEccMode(nvmlVgpuInstance_t vgpuInstance, nvmlEnableState_t *eccMode); + +/** + * Retrieve the encoder capacity of a vGPU instance, as a percentage of maximum encoder capacity with valid values in the range 0-100. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param encoderCapacity Reference to an unsigned int for the encoder capacity + * + * @return + * - \ref NVML_SUCCESS if \a encoderCapacity has been retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a encoderQueryType is invalid + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEncoderCapacity(nvmlVgpuInstance_t vgpuInstance, unsigned int *encoderCapacity); + +/** + * Set the encoder capacity of a vGPU instance, as a percentage of maximum encoder capacity with valid values in the range 0-100. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param encoderCapacity Unsigned int for the encoder capacity value + * + * @return + * - \ref NVML_SUCCESS if \a encoderCapacity has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a encoderCapacity is out of range of 0-100. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceSetEncoderCapacity(nvmlVgpuInstance_t vgpuInstance, unsigned int encoderCapacity); + +/** + * Retrieves the current encoder statistics of a vGPU Instance + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param sessionCount Reference to an unsigned int for count of active encoder sessions + * @param averageFps Reference to an unsigned int for trailing average FPS of all active sessions + * @param averageLatency Reference to an unsigned int for encode latency in microseconds + * + * @return + * - \ref NVML_SUCCESS if \a sessionCount, \a averageFps and \a averageLatency is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount , or \a averageFps or \a averageLatency is NULL + * or \a vgpuInstance is 0. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEncoderStats(nvmlVgpuInstance_t vgpuInstance, unsigned int *sessionCount, + unsigned int *averageFps, unsigned int *averageLatency); + +/** + * Retrieves information about all active encoder sessions on a vGPU Instance. + * + * An array of active encoder sessions is returned in the caller-supplied buffer pointed at by \a sessionInfo. The + * array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions + * written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the active session array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlEncoderSessionInfo_t array required in \a sessionCount. + * To query the number of active encoder sessions, call this function with *sessionCount = 0. The code will return + * NVML_SUCCESS with number of active encoder sessions updated in *sessionCount. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param sessionCount Reference to caller supplied array size, and returns + * the number of sessions. + * @param sessionInfo Reference to caller supplied array in which the list + * of session information us returned. + * + * @return + * - \ref NVML_SUCCESS if \a sessionInfo is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is + returned in \a sessionCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount is NULL, or \a vgpuInstance is 0. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEncoderSessions(nvmlVgpuInstance_t vgpuInstance, unsigned int *sessionCount, nvmlEncoderSessionInfo_t *sessionInfo); + +/** +* Retrieves the active frame buffer capture sessions statistics of a vGPU Instance +* +* For Maxwell &tm; or newer fully supported devices. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param fbcStats Reference to nvmlFBCStats_t structure containing NvFBC stats +* +* @return +* - \ref NVML_SUCCESS if \a fbcStats is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a fbcStats is NULL +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFBCStats(nvmlVgpuInstance_t vgpuInstance, nvmlFBCStats_t *fbcStats); + +/** +* Retrieves information about active frame buffer capture sessions on a vGPU Instance. +* +* An array of active FBC sessions is returned in the caller-supplied buffer pointed at by \a sessionInfo. The +* array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions +* written to the buffer. +* +* If the supplied buffer is not large enough to accommodate the active session array, the function returns +* NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlFBCSessionInfo_t array required in \a sessionCount. +* To query the number of active FBC sessions, call this function with *sessionCount = 0. The code will return +* NVML_SUCCESS with number of active FBC sessions updated in *sessionCount. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @note hResolution, vResolution, averageFPS and averageLatency data for a FBC session returned in \a sessionInfo may +* be zero if there are no new frames captured since the session started. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param sessionCount Reference to caller supplied array size, and returns the number of sessions. +* @param sessionInfo Reference in which to return the session information +* +* @return +* - \ref NVML_SUCCESS if \a sessionInfo is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a sessionCount is NULL. +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is returned in \a sessionCount +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFBCSessions(nvmlVgpuInstance_t vgpuInstance, unsigned int *sessionCount, nvmlFBCSessionInfo_t *sessionInfo); + +/** +* Retrieve the GPU Instance ID for the given vGPU Instance. +* The API will return a valid GPU Instance ID for MIG backed vGPU Instance, else INVALID_GPU_INSTANCE_ID is returned. +* +* For Kepler &tm; or newer fully supported devices. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param gpuInstanceId GPU Instance ID +* +* @return +* - \ref NVML_SUCCESS successful completion +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a gpuInstanceId is NULL. +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetGpuInstanceId(nvmlVgpuInstance_t vgpuInstance, unsigned int *gpuInstanceId); + +/** +* Retrieves the PCI Id of the given vGPU Instance i.e. the PCI Id of the GPU as seen inside the VM. +* +* The vGPU PCI id is returned as "00000000:00:00.0" if NVIDIA driver is not installed on the vGPU instance. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param vgpuPciId Caller-supplied buffer to return vGPU PCI Id string +* @param length Size of the vgpuPciId buffer +* +* @return +* - \ref NVML_SUCCESS if vGPU PCI Id is sucessfully retrieved +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a vgpuPciId is NULL +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running on the vGPU instance +* - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small, \a length is set to required length +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetGpuPciId(nvmlVgpuInstance_t vgpuInstance, char *vgpuPciId, unsigned int *length); + +/** +* Retrieve the requested capability for a given vGPU type. Refer to the \a nvmlVgpuCapability_t structure +* for the specific capabilities that can be queried. The return value in \a capResult should be treated as +* a boolean, with a non-zero value indicating that the capability is supported. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @param vgpuTypeId Handle to vGPU type +* @param capability Specifies the \a nvmlVgpuCapability_t to be queried +* @param capResult A boolean for the queried capability indicating that feature is supported +* +* @return +* - \ref NVML_SUCCESS successful completion +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a capability is invalid, or \a capResult is NULL +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetCapabilities(nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuCapability_t capability, unsigned int *capResult); + +/** + * Retrieve the MDEV UUID of a vGPU instance. + * + * The MDEV UUID is a globally unique identifier of the mdev device assigned to the VM, and is returned as a 5-part hexadecimal string, + * not exceeding 80 characters in length (including the NULL terminator). + * MDEV UUID is displayed only on KVM platform. + * See \ref nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param mdevUuid Pointer to caller-supplied buffer to hold MDEV UUID + * @param size Size of buffer in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED on any hypervisor other than KVM + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a mdevUuid is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetMdevUUID(nvmlVgpuInstance_t vgpuInstance, char *mdevUuid, unsigned int size); + +/** + * Query the currently creatable vGPU types on a specific GPU Instance. + * + * The function returns an array of vGPU types that can be created for a specified GPU instance. This array is stored + * in a caller-supplied buffer, with the buffer's element count passed through \a pVgpus->vgpuCount. The number of + * vGPU types written to the buffer is indicated by \a pVgpus->vgpuCount. If the buffer is too small to hold the vGPU + * type array, the function returns NVML_ERROR_INSUFFICIENT_SIZE and updates \a pVgpus->vgpuCount with the required + * element count. + * + * To determine the creatable vGPUs for a GPU Instance, invoke this function with \a pVgpus->vgpuCount set to 0 and + * \a pVgpus->vgpuTypeIds as NULL. This will result in NVML_ERROR_INSUFFICIENT_SIZE being returned, along with the + * count value in \a pVgpus->vgpuCount. + * + * The creatable vGPU types may differ over time, as there may be restrictions on what type of vGPUs can concurrently + * run on the device. + * + * @param gpuInstance The GPU instance handle + * @param pVgpus Pointer to the caller-provided structure of nvmlVgpuTypeIdInfo_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pVgpus is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a pVgpus->vgpuTypeIds buffer is small + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pVgpus is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetCreatableVgpus(nvmlGpuInstance_t gpuInstance, nvmlVgpuTypeIdInfo_t *pVgpus); + +/** + * Retrieve the maximum number of vGPU instances per GPU instance for given vGPU type + * + * @param pMaxInstance Pointer to the caller-provided structure of nvmlVgpuTypeMaxInstance_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pMaxInstance is NULL or \a pMaxInstance->vgpuTypeId is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or non-MIG vGPU type + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pMaxInstance is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetMaxInstancesPerGpuInstance(nvmlVgpuTypeMaxInstance_t *pMaxInstance); + +/** + * Retrieve the active vGPU instances within a GPU instance. + * + * An array of active vGPU instances is returned in the caller-supplied buffer pointed + * at by \a pVgpuInstanceInfo->vgpuInstances. The array element count is passed in + * \a pVgpuInstanceInfo->vgpuCount, and \a pVgpuInstanceInfo->vgpuCount is used to return + * the number of vGPU instances written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the vGPU instance array, + * the function returns NVML_ERROR_INSUFFICIENT_SIZE, with the element count of + * nvmlVgpuInstance_t array required in \a pVgpuInstanceInfo->vgpuCount. To query the + * number of active vGPU instances, call this function with pVgpuInstanceInfo->vgpuCount = 0 + * and pVgpuInstanceInfo->vgpuTypeIds = NULL. The code will return NVML_ERROR_INSUFFICIENT_SIZE, + * or NVML_SUCCESS if no vGPU Types are active. + * + * @param gpuInstance The GPU instance handle + * @param pVgpuInstanceInfo Pointer to the vGPU instance information structure \a nvmlActiveVgpuInstanceInfo_t + * + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pVgpuInstanceInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a pVgpuInstanceInfo->vgpuTypeIds buffer is too small, + * array element count is returned in \a pVgpuInstanceInfo->vgpuCount + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pVgpuInstanceInfo is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetActiveVgpus(nvmlGpuInstance_t gpuInstance, nvmlActiveVgpuInstanceInfo_t *pVgpuInstanceInfo); + +/** + * Set vGPU scheduler state for the given GPU instance + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * Scheduler state and params will be allowed to set only when no VM is running within the GPU instance. + * In \a nvmlVgpuSchedulerState_t, IFF enableARRMode is enabled then provide the avgFactor and frequency + * as input. If enableARRMode is disabled then provide timeslice as input. + * + * The scheduler state change won't persist across module load/unload and GPU Instance creation/deletion. + * + * @param gpuInstance The GPU instance handle + * @param pScheduler Pointer to the caller-provided structure of nvmlVgpuSchedulerState_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pScheduler is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_RESET_REQUIRED If setting the state failed with fatal error, reboot is required + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or if any vGPU instance exists + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pScheduler is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceSetVgpuSchedulerState(nvmlGpuInstance_t gpuInstance, nvmlVgpuSchedulerState_t *pScheduler); + +/** + * Returns the vGPU scheduler state for the given GPU instance. + * The information returned in \a nvmlVgpuSchedulerStateInfo_t is not relevant if the BEST EFFORT policy is set. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * @param gpuInstance The GPU instance handle + * @param pSchedulerStateInfo Reference in which \a pSchedulerStateInfo is returned + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler state is successfully obtained + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pSchedulerStateInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pSchedulerStateInfo is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuSchedulerState(nvmlGpuInstance_t gpuInstance, nvmlVgpuSchedulerStateInfo_t *pSchedulerStateInfo); + +/** + * Returns the vGPU scheduler logs for the given GPU instance. + * \a pSchedulerLogInfo points to a caller-allocated structure to contain the logs. The number of elements returned will + * never exceed \a NVML_SCHEDULER_SW_MAX_LOG_ENTRIES. + * + * To get the entire logs, call the function atleast 5 times a second. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * @param gpuInstance The GPU instance handle + * @param pSchedulerLogInfo Reference in which \a pSchedulerLogInfo is written + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler logs are successfully obtained + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pSchedulerLogInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pSchedulerLogInfo is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuSchedulerLog(nvmlGpuInstance_t gpuInstance, nvmlVgpuSchedulerLogInfo_t *pSchedulerLogInfo); + +/** + * Query the creatable vGPU placement ID of the vGPU type within a GPU instance. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * An array of creatable vGPU placement IDs for the vGPU type ID indicated by \a pCreatablePlacementInfo->vgpuTypeId + * is returned in the caller-supplied buffer of \a pCreatablePlacementInfo->placementIds. Memory needed for the + * placementIds array should be allocated based on maximum instances of a vGPU type per GPU instance which can be + * queried via \ref nvmlVgpuTypeGetMaxInstancesPerGpuInstance(). + * If the provided count by the caller is insufficient, the function will return NVML_ERROR_INSUFFICIENT_SIZE along with + * the number of required entries in \a pCreatablePlacementInfo->count. The caller should then reallocate a buffer with the size + * of pCreatablePlacementInfo->count * sizeof(pCreatablePlacementInfo->placementIds) and invoke the function again. + * The creatable vGPU placement IDs may differ over time, as there may be restrictions on what type of vGPU the + * vGPU instance is running. + * + * @param gpuInstance The GPU instance handle + * @param pCreatablePlacementInfo Pointer to the list of vGPU creatable placement structure \a nvmlVgpuCreatablePlacementInfo_t + * + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pCreatablePlacementInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If the buffer is small, element count is returned in \a pCreatablePlacementInfo->count + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pCreatablePlacementInfo is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or vGPU heterogeneous mode is not enabled + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuTypeCreatablePlacements(nvmlGpuInstance_t gpuInstance, nvmlVgpuCreatablePlacementInfo_t *pCreatablePlacementInfo); + +/** + * Get the vGPU heterogeneous mode for the GPU instance. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * On successful return, the function returns \a pHeterogeneousMode->mode with the current vGPU heterogeneous mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to retrieve the vGPU heterogeneous mode. + * \a pHeterogeneousMode->mode can either be \ref NVML_FEATURE_ENABLED or \ref NVML_FEATURE_DISABLED. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * @param gpuInstance The GPU instance handle + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pHeterogeneousMode is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or not in MIG mode + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuHeterogeneousMode(nvmlGpuInstance_t gpuInstance, nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** + * Enable or disable vGPU heterogeneous mode for the GPU instance. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * API would return an appropriate error code upon unsuccessful activation. For example, the heterogeneous mode + * set will fail with error \ref NVML_ERROR_IN_USE if any vGPU instance is active within the GPU instance. + * The caller of this API is expected to shutdown the vGPU VMs and retry setting the \a mode. + * On successful return, the function updates the vGPU heterogeneous mode with the user provided \a pHeterogeneousMode->mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to set the vGPU heterogeneous mode. + * + * @param gpuInstance The GPU instance handle + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, + * or \a pHeterogeneousMode is NULL or \a pHeterogeneousMode->mode is invalid + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_IN_USE If the \a gpuInstance is in use + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceSetVgpuHeterogeneousMode(nvmlGpuInstance_t gpuInstance, const nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVgpuMigration vGPU Migration + * This chapter describes operations that are associated with vGPU Migration. + * @{ + */ +/***************************************************************************************************/ + +/** + * Structure representing range of vGPU versions. + */ +typedef struct nvmlVgpuVersion_st +{ + unsigned int minVersion; //!< Minimum vGPU version. + unsigned int maxVersion; //!< Maximum vGPU version. +} nvmlVgpuVersion_t; + +/** + * vGPU metadata structure. + */ +typedef struct nvmlVgpuMetadata_st +{ + unsigned int version; //!< Current version of the structure + unsigned int revision; //!< Current revision of the structure + nvmlVgpuGuestInfoState_t guestInfoState; //!< Current state of Guest-dependent fields + char guestDriverVersion[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< Version of driver installed in guest + char hostDriverVersion[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< Version of driver installed in host + unsigned int reserved[6]; //!< Reserved for internal use + unsigned int vgpuVirtualizationCaps; //!< vGPU virtualization capabilities bitfield + unsigned int guestVgpuVersion; //!< vGPU version of guest driver + unsigned int opaqueDataSize; //!< Size of opaque data field in bytes + char opaqueData[4]; //!< Opaque data +} nvmlVgpuMetadata_t; + +/** + * Physical GPU metadata structure + */ +typedef struct nvmlVgpuPgpuMetadata_st +{ + unsigned int version; //!< Current version of the structure + unsigned int revision; //!< Current revision of the structure + char hostDriverVersion[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< Host driver version + unsigned int pgpuVirtualizationCaps; //!< Pgpu virtualization capabilities bitfield + unsigned int reserved[5]; //!< Reserved for internal use + nvmlVgpuVersion_t hostSupportedVgpuRange; //!< vGPU version range supported by host driver + unsigned int opaqueDataSize; //!< Size of opaque data field in bytes + char opaqueData[4]; //!< Opaque data +} nvmlVgpuPgpuMetadata_t; + +/** + * vGPU VM compatibility codes + */ +typedef enum nvmlVgpuVmCompatibility_enum +{ + NVML_VGPU_VM_COMPATIBILITY_NONE = 0x0, //!< vGPU is not runnable + NVML_VGPU_VM_COMPATIBILITY_COLD = 0x1, //!< vGPU is runnable from a cold / powered-off state (ACPI S5) + NVML_VGPU_VM_COMPATIBILITY_HIBERNATE = 0x2, //!< vGPU is runnable from a hibernated state (ACPI S4) + NVML_VGPU_VM_COMPATIBILITY_SLEEP = 0x4, //!< vGPU is runnable from a sleeped state (ACPI S3) + NVML_VGPU_VM_COMPATIBILITY_LIVE = 0x8 //!< vGPU is runnable from a live/paused (ACPI S0) +} nvmlVgpuVmCompatibility_t; + +/** + * vGPU-pGPU compatibility limit codes + */ +typedef enum nvmlVgpuPgpuCompatibilityLimitCode_enum +{ + NVML_VGPU_COMPATIBILITY_LIMIT_NONE = 0x0, //!< Compatibility is not limited. + NVML_VGPU_COMPATIBILITY_LIMIT_HOST_DRIVER = 0x1, //!< ompatibility is limited by host driver version. + NVML_VGPU_COMPATIBILITY_LIMIT_GUEST_DRIVER = 0x2, //!< Compatibility is limited by guest driver version. + NVML_VGPU_COMPATIBILITY_LIMIT_GPU = 0x4, //!< Compatibility is limited by GPU hardware. + NVML_VGPU_COMPATIBILITY_LIMIT_OTHER = 0x80000000 //!< Compatibility is limited by an undefined factor. +} nvmlVgpuPgpuCompatibilityLimitCode_t; + +/** + * vGPU-pGPU compatibility structure + */ +typedef struct nvmlVgpuPgpuCompatibility_st +{ + nvmlVgpuVmCompatibility_t vgpuVmCompatibility; //!< Compatibility of vGPU VM. See \ref nvmlVgpuVmCompatibility_t + nvmlVgpuPgpuCompatibilityLimitCode_t compatibilityLimitCode; //!< Limiting factor for vGPU-pGPU compatibility. See \ref nvmlVgpuPgpuCompatibilityLimitCode_t +} nvmlVgpuPgpuCompatibility_t; + +/** + * Returns vGPU metadata structure for a running vGPU. The structure contains information about the vGPU and its associated VM + * such as the currently installed NVIDIA guest driver version, together with host driver version and an opaque data section + * containing internal state. + * + * nvmlVgpuInstanceGetMetadata() may be called at any time for a vGPU instance. Some fields in the returned structure are + * dependent on information obtained from the guest VM, which may not yet have reached a state where that information + * is available. The current state of these dependent fields is reflected in the info structure's \ref nvmlVgpuGuestInfoState_t field. + * + * The VMM may choose to read and save the vGPU's VM info as persistent metadata associated with the VM, and provide + * it to Virtual GPU Manager when creating a vGPU for subsequent instances of the VM. + * + * The caller passes in a buffer via \a vgpuMetadata, with the size of the buffer in \a bufferSize. If the vGPU Metadata structure + * is too large to fit in the supplied buffer, the function returns NVML_ERROR_INSUFFICIENT_SIZE with the size needed + * in \a bufferSize. + * + * @param vgpuInstance vGPU instance handle + * @param vgpuMetadata Pointer to caller-supplied buffer into which vGPU metadata is written + * @param bufferSize Size of vgpuMetadata buffer + * + * @return + * - \ref NVML_SUCCESS vGPU metadata structure was successfully returned + * - \ref NVML_ERROR_INSUFFICIENT_SIZE vgpuMetadata buffer is too small, required size is returned in \a bufferSize + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a bufferSize is NULL or \a vgpuInstance is 0; if \a vgpuMetadata is NULL and the value of \a bufferSize is not 0. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetMetadata(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuMetadata_t *vgpuMetadata, unsigned int *bufferSize); + +/** + * Returns a vGPU metadata structure for the physical GPU indicated by \a device. The structure contains information about + * the GPU and the currently installed NVIDIA host driver version that's controlling it, together with an opaque data section + * containing internal state. + * + * The caller passes in a buffer via \a pgpuMetadata, with the size of the buffer in \a bufferSize. If the \a pgpuMetadata + * structure is too large to fit in the supplied buffer, the function returns NVML_ERROR_INSUFFICIENT_SIZE with the size needed + * in \a bufferSize. + * + * @param device The identifier of the target device + * @param pgpuMetadata Pointer to caller-supplied buffer into which \a pgpuMetadata is written + * @param bufferSize Pointer to size of \a pgpuMetadata buffer + * + * @return + * - \ref NVML_SUCCESS GPU metadata structure was successfully returned + * - \ref NVML_ERROR_INSUFFICIENT_SIZE pgpuMetadata buffer is too small, required size is returned in \a bufferSize + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a bufferSize is NULL or \a device is invalid; if \a pgpuMetadata is NULL and the value of \a bufferSize is not 0. + * - \ref NVML_ERROR_NOT_SUPPORTED vGPU is not supported by the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuMetadata(nvmlDevice_t device, nvmlVgpuPgpuMetadata_t *pgpuMetadata, unsigned int *bufferSize); + +/** + * Takes a vGPU instance metadata structure read from \ref nvmlVgpuInstanceGetMetadata(), and a vGPU metadata structure for a + * physical GPU read from \ref nvmlDeviceGetVgpuMetadata(), and returns compatibility information of the vGPU instance and the + * physical GPU. + * + * The caller passes in a buffer via \a compatibilityInfo, into which a compatibility information structure is written. The + * structure defines the states in which the vGPU / VM may be booted on the physical GPU. If the vGPU / VM compatibility + * with the physical GPU is limited, a limit code indicates the factor limiting compatability. + * (see \ref nvmlVgpuPgpuCompatibilityLimitCode_t for details). + * + * Note: vGPU compatibility does not take into account dynamic capacity conditions that may limit a system's ability to + * boot a given vGPU or associated VM. + * + * @param vgpuMetadata Pointer to caller-supplied vGPU metadata structure + * @param pgpuMetadata Pointer to caller-supplied GPU metadata structure + * @param compatibilityInfo Pointer to caller-supplied buffer to hold compatibility info + * + * @return + * - \ref NVML_SUCCESS vGPU metadata structure was successfully returned + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuMetadata or \a pgpuMetadata or \a bufferSize are NULL + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGetVgpuCompatibility(nvmlVgpuMetadata_t *vgpuMetadata, nvmlVgpuPgpuMetadata_t *pgpuMetadata, nvmlVgpuPgpuCompatibility_t *compatibilityInfo); + +/** + * Returns the properties of the physical GPU indicated by the device in an ascii-encoded string format. + * + * The caller passes in a buffer via \a pgpuMetadata, with the size of the buffer in \a bufferSize. If the + * string is too large to fit in the supplied buffer, the function returns NVML_ERROR_INSUFFICIENT_SIZE with the size needed + * in \a bufferSize. + * + * @param device The identifier of the target device + * @param pgpuMetadata Pointer to caller-supplied buffer into which \a pgpuMetadata is written + * @param bufferSize Pointer to size of \a pgpuMetadata buffer + * + * @return + * - \ref NVML_SUCCESS GPU metadata structure was successfully returned + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a pgpuMetadata buffer is too small, required size is returned in \a bufferSize + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a bufferSize is NULL or \a device is invalid; if \a pgpuMetadata is NULL and the value of \a bufferSize is not 0. + * - \ref NVML_ERROR_NOT_SUPPORTED If vGPU is not supported by the system + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPgpuMetadataString(nvmlDevice_t device, char *pgpuMetadata, unsigned int *bufferSize); + +/** + * Returns the vGPU Software scheduler logs. + * \a pSchedulerLog points to a caller-allocated structure to contain the logs. The number of elements returned will + * never exceed \a NVML_SCHEDULER_SW_MAX_LOG_ENTRIES. + * + * To get the entire logs, call the function atleast 5 times a second. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target \a device + * @param pSchedulerLog Reference in which \a pSchedulerLog is written + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler logs were successfully obtained + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pSchedulerLog is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device not in vGPU host mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerLog(nvmlDevice_t device, nvmlVgpuSchedulerLog_t *pSchedulerLog); + +/** + * Returns the vGPU scheduler state. + * The information returned in \a nvmlVgpuSchedulerGetState_t is not relevant if the BEST EFFORT policy is set. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target \a device + * @param pSchedulerState Reference in which \a pSchedulerState is returned + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler state is successfully obtained + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pSchedulerState is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device not in vGPU host mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerState(nvmlDevice_t device, nvmlVgpuSchedulerGetState_t *pSchedulerState); + +/** + * Returns the vGPU scheduler capabilities. + * The list of supported vGPU schedulers returned in \a nvmlVgpuSchedulerCapabilities_t is from + * the NVML_VGPU_SCHEDULER_POLICY_*. This list enumerates the supported scheduler policies + * if the engine is Graphics type. + * The other values in \a nvmlVgpuSchedulerCapabilities_t are also applicable if the engine is + * Graphics type. For other engine types, it is BEST EFFORT policy. + * If ARR is supported and enabled, scheduling frequency and averaging factor are applicable + * else timeSlice is applicable. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target \a device + * @param pCapabilities Reference in which \a pCapabilities is written + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler capabilities were successfully obtained + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pCapabilities is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported in current state or \a device not in vGPU host mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerCapabilities(nvmlDevice_t device, nvmlVgpuSchedulerCapabilities_t *pCapabilities); + +/** + * Sets the vGPU scheduler state. + * + * For Pascal &tm; or newer fully supported devices. + * + * The scheduler state change won't persist across module load/unload. + * Scheduler state and params will be allowed to set only when no VM is running. + * In \a nvmlVgpuSchedulerSetState_t, IFF enableARRMode is enabled then + * provide avgFactorForARR and frequency as input. If enableARRMode is disabled + * then provide timeslice as input. + * + * @param device The identifier of the target \a device + * @param pSchedulerState vGPU \a pSchedulerState to set + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler state has been successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pSchedulerState is NULL or \a device is invalid + * - \ref NVML_ERROR_RESET_REQUIRED If setting \a pSchedulerState failed with fatal error, + * reboot is required to overcome from this error. + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device not in vGPU host mode + * or if any vGPU instance currently exists on the \a device + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetVgpuSchedulerState(nvmlDevice_t device, nvmlVgpuSchedulerSetState_t *pSchedulerState); + +/* + * Virtual GPU (vGPU) version + * + * The NVIDIA vGPU Manager and the guest drivers are tagged with a range of supported vGPU versions. This determines the range of NVIDIA guest driver versions that + * are compatible for vGPU feature support with a given NVIDIA vGPU Manager. For vGPU feature support, the range of supported versions for the NVIDIA vGPU Manager + * and the guest driver must overlap. Otherwise, the guest driver fails to load in the VM. + * + * When the NVIDIA guest driver loads, either when the VM is booted or when the driver is installed or upgraded, a negotiation occurs between the guest driver + * and the NVIDIA vGPU Manager to select the highest mutually compatible vGPU version. The negotiated vGPU version stays the same across VM migration. + */ + +/** + * Query the ranges of supported vGPU versions. + * + * This function gets the linear range of supported vGPU versions that is preset for the NVIDIA vGPU Manager and the range set by an administrator. + * If the preset range has not been overridden by \ref nvmlSetVgpuVersion, both ranges are the same. + * + * The caller passes pointers to the following \ref nvmlVgpuVersion_t structures, into which the NVIDIA vGPU Manager writes the ranges: + * 1. \a supported structure that represents the preset range of vGPU versions supported by the NVIDIA vGPU Manager. + * 2. \a current structure that represents the range of supported vGPU versions set by an administrator. By default, this range is the same as the preset range. + * + * @param supported Pointer to the structure in which the preset range of vGPU versions supported by the NVIDIA vGPU Manager is written + * @param current Pointer to the structure in which the range of supported vGPU versions set by an administrator is written + * + * @return + * - \ref NVML_SUCCESS The vGPU version range structures were successfully obtained. + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported. + * - \ref NVML_ERROR_INVALID_ARGUMENT The \a supported parameter or the \a current parameter is NULL. + * - \ref NVML_ERROR_UNKNOWN An error occurred while the data was being fetched. + */ +nvmlReturn_t DECLDIR nvmlGetVgpuVersion(nvmlVgpuVersion_t *supported, nvmlVgpuVersion_t *current); + +/** + * Override the preset range of vGPU versions supported by the NVIDIA vGPU Manager with a range set by an administrator. + * + * This function configures the NVIDIA vGPU Manager with a range of supported vGPU versions set by an administrator. This range must be a subset of the + * preset range that the NVIDIA vGPU Manager supports. The custom range set by an administrator takes precedence over the preset range and is advertised to + * the guest VM for negotiating the vGPU version. See \ref nvmlGetVgpuVersion for details of how to query the preset range of versions supported. + * + * This function takes a pointer to vGPU version range structure \ref nvmlVgpuVersion_t as input to override the preset vGPU version range that the NVIDIA vGPU Manager supports. + * + * After host system reboot or driver reload, the range of supported versions reverts to the range that is preset for the NVIDIA vGPU Manager. + * + * @note 1. The range set by the administrator must be a subset of the preset range that the NVIDIA vGPU Manager supports. Otherwise, an error is returned. + * 2. If the range of supported guest driver versions does not overlap the range set by the administrator, the guest driver fails to load. + * 3. If the range of supported guest driver versions overlaps the range set by the administrator, the guest driver will load with a negotiated + * vGPU version that is the maximum value in the overlapping range. + * 4. No VMs must be running on the host when this function is called. If a VM is running on the host, the call to this function fails. + * + * @param vgpuVersion Pointer to a caller-supplied range of supported vGPU versions. + * + * @return + * - \ref NVML_SUCCESS The preset range of supported vGPU versions was successfully overridden. + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported. + * - \ref NVML_ERROR_IN_USE The range was not overridden because a VM is running on the host. + * - \ref NVML_ERROR_INVALID_ARGUMENT The \a vgpuVersion parameter specifies a range that is outside the range supported by the NVIDIA vGPU Manager or if \a vgpuVersion is NULL. + */ +nvmlReturn_t DECLDIR nvmlSetVgpuVersion(nvmlVgpuVersion_t *vgpuVersion); + +/** @} */ // @defgroup nvmlVgpuMigration vGPU Migration + +/***************************************************************************************************/ +/** @defgroup nvmlUtil vGPU Utilization and Accounting + * This chapter describes operations that are associated with vGPU Utilization and Accounting. + * @{ + */ +/***************************************************************************************************/ + +/** + * Retrieves current utilization for vGPUs on a physical GPU (device). + * + * For Kepler &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder for vGPU instances running + * on a device. Utilization values are returned as an array of utilization sample structures in the caller-supplied buffer + * pointed at by \a utilizationSamples. One utilization sample structure is returned per vGPU instance, and includes the + * CPU timestamp at which the samples were recorded. Individual utilization values are returned as "unsigned int" values + * in nvmlValue_t unions. The function sets the caller-supplied \a sampleValType to NVML_VALUE_TYPE_UNSIGNED_INT to + * indicate the returned value type. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a utilizationSamples set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current vGPU instance + * count in \a vgpuInstanceSamplesCount, or NVML_SUCCESS if the current vGPU instance count is zero. The caller should allocate + * a buffer of size vgpuInstanceSamplesCount * sizeof(nvmlVgpuInstanceUtilizationSample_t). Invoke the function again with + * the allocated buffer passed in \a utilizationSamples, and \a vgpuInstanceSamplesCount set to the number of entries the + * buffer is sized for. + * + * On successful return, the function updates \a vgpuInstanceSampleCount with the number of vGPU utilization sample + * structures that were actually written. This may differ from a previously read value as vGPU instances are created or + * destroyed. + * + * lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + * @param sampleValType Pointer to caller-supplied buffer to hold the type of returned sample values + * @param vgpuInstanceSamplesCount Pointer to caller-supplied array size, and returns number of vGPU instances + * @param utilizationSamples Pointer to caller-supplied buffer in which vGPU utilization samples are returned + + * @return + * - \ref NVML_SUCCESS if utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a vgpuInstanceSamplesCount or \a sampleValType is + * NULL, or a sample count of 0 is passed with a non-NULL \a utilizationSamples + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if supplied \a vgpuInstanceSamplesCount is too small to return samples for all + * vGPU instances currently executing on the device + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuUtilization(nvmlDevice_t device, unsigned long long lastSeenTimeStamp, + nvmlValueType_t *sampleValType, unsigned int *vgpuInstanceSamplesCount, + nvmlVgpuInstanceUtilizationSample_t *utilizationSamples); + +/** + * Retrieves recent utilization for vGPU instances running on a physical GPU (device). + * + * For Kepler &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, video decoder, jpeg decoder, and OFA for vGPU + * instances running on a device. Utilization values are returned as an array of utilization sample structures in the caller-supplied + * buffer pointed at by \a vgpuUtilInfo->vgpuUtilArray. One utilization sample structure is returned per vGPU instance, and includes the + * CPU timestamp at which the samples were recorded. Individual utilization values are returned as "unsigned int" values + * in nvmlValue_t unions. The function sets the caller-supplied \a vgpuUtilInfo->sampleValType to NVML_VALUE_TYPE_UNSIGNED_INT to + * indicate the returned value type. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a vgpuUtilInfo->vgpuUtilArray set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current vGPU instance + * count in \a vgpuUtilInfo->vgpuInstanceCount, or NVML_SUCCESS if the current vGPU instance count is zero. The caller should allocate + * a buffer of size vgpuUtilInfo->vgpuInstanceCount * sizeof(nvmlVgpuInstanceUtilizationInfo_t). Invoke the function again with + * the allocated buffer passed in \a vgpuUtilInfo->vgpuUtilArray, and \a vgpuUtilInfo->vgpuInstanceCount set to the number of entries the + * buffer is sized for. + * + * On successful return, the function updates \a vgpuUtilInfo->vgpuInstanceCount with the number of vGPU utilization sample + * structures that were actually written. This may differ from a previously read value as vGPU instances are created or + * destroyed. + * + * \a vgpuUtilInfo->lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set \a vgpuUtilInfo->lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param vgpuUtilInfo Pointer to the caller-provided structure of nvmlVgpuInstancesUtilizationInfo_t + + * @return + * - \ref NVML_SUCCESS If utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, \a vgpuUtilInfo is NULL, or \a vgpuUtilInfo->vgpuInstanceCount is 0 + * - \ref NVML_ERROR_NOT_SUPPORTED If vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a vgpuUtilInfo is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a vgpuUtilInfo->vgpuUtilArray is NULL, or the buffer size of vgpuUtilInfo->vgpuInstanceCount is too small. + * The caller should check the current vGPU instance count from the returned vgpuUtilInfo->vgpuInstanceCount, and call + * the function again with a buffer of size vgpuUtilInfo->vgpuInstanceCount * sizeof(nvmlVgpuInstanceUtilizationInfo_t) + * - \ref NVML_ERROR_NOT_FOUND If sample entries are not found + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuInstancesUtilizationInfo(nvmlDevice_t device, + nvmlVgpuInstancesUtilizationInfo_t *vgpuUtilInfo); + +/** + * Retrieves current utilization for processes running on vGPUs on a physical GPU (device). + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder for processes running on + * vGPU instances active on a device. Utilization values are returned as an array of utilization sample structures in the + * caller-supplied buffer pointed at by \a utilizationSamples. One utilization sample structure is returned per process running + * on vGPU instances, that had some non-zero utilization during the last sample period. It includes the CPU timestamp at which + * the samples were recorded. Individual utilization values are returned as "unsigned int" values. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a utilizationSamples set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current vGPU instance + * count in \a vgpuProcessSamplesCount. The caller should allocate a buffer of size + * vgpuProcessSamplesCount * sizeof(nvmlVgpuProcessUtilizationSample_t). Invoke the function again with + * the allocated buffer passed in \a utilizationSamples, and \a vgpuProcessSamplesCount set to the number of entries the + * buffer is sized for. + * + * On successful return, the function updates \a vgpuSubProcessSampleCount with the number of vGPU sub process utilization sample + * structures that were actually written. This may differ from a previously read value depending on the number of processes that are active + * in any given sample period. + * + * lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + * @param vgpuProcessSamplesCount Pointer to caller-supplied array size, and returns number of processes running on vGPU instances + * @param utilizationSamples Pointer to caller-supplied buffer in which vGPU sub process utilization samples are returned + + * @return + * - \ref NVML_SUCCESS if utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a vgpuProcessSamplesCount or a sample count of 0 is + * passed with a non-NULL \a utilizationSamples + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if supplied \a vgpuProcessSamplesCount is too small to return samples for all + * vGPU instances currently executing on the device + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuProcessUtilization(nvmlDevice_t device, unsigned long long lastSeenTimeStamp, + unsigned int *vgpuProcessSamplesCount, + nvmlVgpuProcessUtilizationSample_t *utilizationSamples); + +/** + * Retrieves recent utilization for processes running on vGPU instances on a physical GPU (device). + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, video decoder, jpeg decoder, and OFA for processes running + * on vGPU instances active on a device. Utilization values are returned as an array of utilization sample structures in the caller-supplied + * buffer pointed at by \a vgpuProcUtilInfo->vgpuProcUtilArray. One utilization sample structure is returned per process running + * on vGPU instances, that had some non-zero utilization during the last sample period. It includes the CPU timestamp at which + * the samples were recorded. Individual utilization values are returned as "unsigned int" values. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a vgpuProcUtilInfo->vgpuProcUtilArray set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current processes' count + * running on vGPU instances in \a vgpuProcUtilInfo->vgpuProcessCount. The caller should allocate a buffer of size + * vgpuProcUtilInfo->vgpuProcessCount * sizeof(nvmlVgpuProcessUtilizationSample_t). Invoke the function again with the allocated buffer passed + * in \a vgpuProcUtilInfo->vgpuProcUtilArray, and \a vgpuProcUtilInfo->vgpuProcessCount set to the number of entries the buffer is sized for. + * + * On successful return, the function updates \a vgpuProcUtilInfo->vgpuProcessCount with the number of vGPU sub process utilization sample + * structures that were actually written. This may differ from a previously read value depending on the number of processes that are active + * in any given sample period. + * + * vgpuProcUtilInfo->lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set vgpuProcUtilInfo->lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param vgpuProcUtilInfo Pointer to the caller-provided structure of nvmlVgpuProcessesUtilizationInfo_t + + * @return + * - \ref NVML_SUCCESS If utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, or \a vgpuProcUtilInfo is null + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a vgpuProcUtilInfo is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a vgpuProcUtilInfo->vgpuProcUtilArray is null, or supplied \a vgpuProcUtilInfo->vgpuProcessCount + * is too small to return samples for all processes on vGPU instances currently executing on the device. + * The caller should check the current processes count from the returned \a vgpuProcUtilInfo->vgpuProcessCount, + * and call the function again with a buffer of size + * vgpuProcUtilInfo->vgpuProcessCount * sizeof(nvmlVgpuProcessUtilizationSample_t) + * - \ref NVML_ERROR_NOT_SUPPORTED If vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND If sample entries are not found + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuProcessesUtilizationInfo(nvmlDevice_t device, nvmlVgpuProcessesUtilizationInfo_t *vgpuProcUtilInfo); + +/** + * Queries the state of per process accounting mode on vGPU. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param mode Reference in which to return the current accounting mode + * + * @return + * - \ref NVML_SUCCESS if the mode has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a mode is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running on the vGPU instance + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetAccountingMode(nvmlVgpuInstance_t vgpuInstance, nvmlEnableState_t *mode); + +/** + * Queries list of processes running on vGPU that can be queried for accounting stats. The list of processes + * returned can be in running or terminated state. + * + * For Maxwell &tm; or newer fully supported devices. + * + * To just query the maximum number of processes that can be queried, call this function with *count = 0 and + * pids=NULL. The return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if list is empty. + * + * For more details see \ref nvmlVgpuInstanceGetAccountingStats. + * + * @note In case of PID collision some processes might not be accessible before the circular buffer is full. + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param count Reference in which to provide the \a pids array size, and + * to return the number of elements ready to be queried + * @param pids Reference in which to return list of process ids + * + * @return + * - \ref NVML_SUCCESS if pids were successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a count is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small (\a count is set to expected value) + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlVgpuInstanceGetAccountingPids + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetAccountingPids(nvmlVgpuInstance_t vgpuInstance, unsigned int *count, unsigned int *pids); + +/** + * Queries process's accounting stats. + * + * For Maxwell &tm; or newer fully supported devices. + * + * Accounting stats capture GPU utilization and other statistics across the lifetime of a process, and + * can be queried during life time of the process or after its termination. + * The time field in \ref nvmlAccountingStats_t is reported as 0 during the lifetime of the process and + * updated to actual running time after its termination. + * Accounting stats are kept in a circular buffer, newly created processes overwrite information about old + * processes. + * + * See \ref nvmlAccountingStats_t for description of each returned metric. + * List of processes that can be queried can be retrieved from \ref nvmlVgpuInstanceGetAccountingPids. + * + * @note Accounting Mode needs to be on. See \ref nvmlVgpuInstanceGetAccountingMode. + * @note Only compute and graphics applications stats can be queried. Monitoring applications stats can't be + * queried since they don't contribute to GPU utilization. + * @note In case of pid collision stats of only the latest process (that terminated last) will be reported + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param pid Process Id of the target process to query stats for + * @param stats Reference in which to return the process's accounting stats + * + * @return + * - \ref NVML_SUCCESS if stats have been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a stats is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * or \a stats is not found + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetAccountingStats(nvmlVgpuInstance_t vgpuInstance, unsigned int pid, nvmlAccountingStats_t *stats); + +/** + * Clears accounting information of the vGPU instance that have already terminated. + * + * For Maxwell &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * @note Accounting Mode needs to be on. See \ref nvmlVgpuInstanceGetAccountingMode. + * @note Only compute and graphics applications stats are reported and can be cleared since monitoring applications + * stats don't contribute to GPU utilization. + * + * @param vgpuInstance The identifier of the target vGPU instance + * + * @return + * - \ref NVML_SUCCESS if accounting information has been cleared + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is invalid + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceClearAccountingPids(nvmlVgpuInstance_t vgpuInstance); + +/** + * Query the license information of the vGPU instance. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param licenseInfo Pointer to vGPU license information structure + * + * @return + * - \ref NVML_SUCCESS if information is successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a licenseInfo is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running on the vGPU instance + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseInfo_v2(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuLicenseInfo_t *licenseInfo); +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlExcludedGpuQueries Excluded GPU Queries + * This chapter describes NVML operations that are associated with excluded GPUs. + * @{ + */ +/***************************************************************************************************/ + +/** + * Excluded GPU device information + **/ +typedef struct nvmlExcludedDeviceInfo_st +{ + nvmlPciInfo_t pciInfo; //!< The PCI information for the excluded GPU + char uuid[NVML_DEVICE_UUID_BUFFER_SIZE]; //!< The ASCII string UUID for the excluded GPU +} nvmlExcludedDeviceInfo_t; + + /** + * Retrieves the number of excluded GPU devices in the system. + * + * For all products. + * + * @param deviceCount Reference in which to return the number of excluded devices + * + * @return + * - \ref NVML_SUCCESS if \a deviceCount has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a deviceCount is NULL + */ +nvmlReturn_t DECLDIR nvmlGetExcludedDeviceCount(unsigned int *deviceCount); + +/** + * Acquire the device information for an excluded GPU device, based on its index. + * + * For all products. + * + * Valid indices are derived from the \a deviceCount returned by + * \ref nvmlGetExcludedDeviceCount(). For example, if \a deviceCount is 2 the valid indices + * are 0 and 1, corresponding to GPU 0 and GPU 1. + * + * @param index The index of the target GPU, >= 0 and < \a deviceCount + * @param info Reference in which to return the device information + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a index is invalid or \a info is NULL + * + * @see nvmlGetExcludedDeviceCount + */ +nvmlReturn_t DECLDIR nvmlGetExcludedDeviceInfoByIndex(unsigned int index, nvmlExcludedDeviceInfo_t *info); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlGPUPRMAccess PRM Access + * This chapter describes NVML operations that are associated with PRM register reads + * @{ + */ +/***************************************************************************************************/ + +#define NVML_PRM_DATA_MAX_SIZE 496 +/** + * Main PRM input structure + */ +typedef struct +{ + /* I/O parameters */ + unsigned dataSize; //!< Size of the input TLV data. + unsigned status; //!< OUT: status of the PRM command + union { + /* Input data in TLV format */ + unsigned char inData[NVML_PRM_DATA_MAX_SIZE]; //!< IN: Input data in TLV format + /* Output data in TLV format */ + unsigned char outData[NVML_PRM_DATA_MAX_SIZE]; //!< OUT: Output PRM data in TLV format + }; +} nvmlPRMTLV_v1_t; + +/** + * Read or write a GPU PRM register. The input is assumed to be in TLV format in + * network byte order. + * + * For Blackwell &tm; or newer fully supported devices. + * + * Supported on Linux only. + * + * @param device Identifer of target GPU device + * @param buffer Structure holding the input data in TLV format as well as + * the PRM register contents in TLV format (in the case of a successful + * read operation). + * Note: the input data and any returned data shall be in network byte order. + * + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if \p device or \p buffer are invalid + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified in \p buffer is not supported + */ +nvmlReturn_t DECLDIR nvmlDeviceReadWritePRM_v1(nvmlDevice_t device, nvmlPRMTLV_v1_t *buffer); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlMultiInstanceGPU Multi Instance GPU Management + * This chapter describes NVML operations that are associated with Multi Instance GPU management. + * @{ + */ +/***************************************************************************************************/ + +/** + * Disable Multi Instance GPU mode. + */ +#define NVML_DEVICE_MIG_DISABLE 0x0 + +/** + * Enable Multi Instance GPU mode. + */ +#define NVML_DEVICE_MIG_ENABLE 0x1 + +/** + * GPU instance profiles. + * + * These macros should be passed to \ref nvmlDeviceGetGpuInstanceProfileInfo to retrieve the + * detailed information about a GPU instance such as profile ID, engine counts. + */ +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE 0x0 +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE 0x1 +#define NVML_GPU_INSTANCE_PROFILE_3_SLICE 0x2 +#define NVML_GPU_INSTANCE_PROFILE_4_SLICE 0x3 +#define NVML_GPU_INSTANCE_PROFILE_7_SLICE 0x4 +#define NVML_GPU_INSTANCE_PROFILE_8_SLICE 0x5 +#define NVML_GPU_INSTANCE_PROFILE_6_SLICE 0x6 +// 1_SLICE profile with at least one (if supported at all) of Decoder, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV1 0x7 +// 2_SLICE profile with at least one (if supported at all) of Decoder, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_REV1 0x8 +// 1_SLICE profile with twice the amount of memory resources. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV2 0x9 +// 1_SLICE gfx capable profile +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_GFX 0x0A +// 2_SLICE gfx capable profile +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_GFX 0x0B +// 4_SLICE gfx capable profile +#define NVML_GPU_INSTANCE_PROFILE_4_SLICE_GFX 0x0C +// 1_SLICE profile with none of Decode, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_NO_ME 0x0D +// 2_SLICE profile with none of Decode, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_NO_ME 0x0E +// 1_SLICE profile with all of GPU Decode, Encoder, JPEG, OFA engines. +// Allocation of instance of this profile prevents allocation of +// all but _NO_ME profiles. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_ALL_ME 0x0F +// 2_SLICE profile with all of GPU Decode, Encoder, JPEG, OFA engines. +// Allocation of instance of this profile prevents allocation of +// all but _NO_ME profiles. +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_ALL_ME 0x10 +#define NVML_GPU_INSTANCE_PROFILE_COUNT 0x11 + +/** + * MIG GPU instance profile capability. + * + * Bit field values representing MIG profile capabilities + * \ref nvmlGpuInstanceProfileInfo_v3_t.capabilities + */ +#define NVML_GPU_INSTANCE_PROFILE_CAPS_P2P 0x1 +#define NVML_GPU_INTSTANCE_PROFILE_CAPS_P2P 0x1 //!< Deprecated, do not use +#define NVML_GPU_INSTANCE_PROFILE_CAPS_GFX 0x2 + +/** + * MIG compute instance profile capability. + * + * Bit field values representing MIG profile capabilities + * \ref nvmlComputeInstanceProfileInfo_v3_t.capabilities + */ +#define NVML_COMPUTE_INSTANCE_PROFILE_CAPS_GFX 0x1 + +typedef struct nvmlGpuInstancePlacement_st +{ + unsigned int start; //!< Index of first occupied memory slice + unsigned int size; //!< Number of memory slices occupied +} nvmlGpuInstancePlacement_t; + +/** + * GPU instance profile information. + */ +typedef struct nvmlGpuInstanceProfileInfo_st +{ + unsigned int id; //!< Unique profile ID within the device + unsigned int isP2pSupported; //!< Peer-to-Peer support + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< GPU instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int copyEngineCount; //!< Copy Engine count + unsigned int decoderCount; //!< Decoder Engine count + unsigned int encoderCount; //!< Encoder Engine count + unsigned int jpegCount; //!< JPEG Engine count + unsigned int ofaCount; //!< OFA Engine count + unsigned long long memorySizeMB; //!< Memory size in MBytes +} nvmlGpuInstanceProfileInfo_t; + +/** + * GPU instance profile information (v2). + * + * Version 2 adds the \ref nvmlGpuInstanceProfileInfo_v2_t.version field + * to the start of the structure, and the \ref nvmlGpuInstanceProfileInfo_v2_t.name + * field to the end. This structure is not backwards-compatible with + * \ref nvmlGpuInstanceProfileInfo_t. + */ +typedef struct nvmlGpuInstanceProfileInfo_v2_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlGpuInstanceProfileInfo_v2) + unsigned int id; //!< Unique profile ID within the device + unsigned int isP2pSupported; //!< Peer-to-Peer support + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< GPU instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int copyEngineCount; //!< Copy Engine count + unsigned int decoderCount; //!< Decoder Engine count + unsigned int encoderCount; //!< Encoder Engine count + unsigned int jpegCount; //!< JPEG Engine count + unsigned int ofaCount; //!< OFA Engine count + unsigned long long memorySizeMB; //!< Memory size in MBytes + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name +} nvmlGpuInstanceProfileInfo_v2_t; + +/** + * Version identifier value for \ref nvmlGpuInstanceProfileInfo_v2_t.version. + */ +#define nvmlGpuInstanceProfileInfo_v2 NVML_STRUCT_VERSION(GpuInstanceProfileInfo, 2) + +/** + * GPU instance profile information (v3). + * + * Version 3 removes isP2pSupported field and adds the \ref nvmlGpuInstanceProfileInfo_v3_t.capabilities + * field \ref nvmlGpuInstanceProfileInfo_t. + */ +typedef struct nvmlGpuInstanceProfileInfo_v3_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlGpuInstanceProfileInfo_v3) + unsigned int id; //!< Unique profile ID within the device + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< GPU instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int copyEngineCount; //!< Copy Engine count + unsigned int decoderCount; //!< Decoder Engine count + unsigned int encoderCount; //!< Encoder Engine count + unsigned int jpegCount; //!< JPEG Engine count + unsigned int ofaCount; //!< OFA Engine count + unsigned long long memorySizeMB; //!< Memory size in MBytes + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name + unsigned int capabilities; //!< Additional capabilities +} nvmlGpuInstanceProfileInfo_v3_t; + +/** + * Version identifier value for \ref nvmlGpuInstanceProfileInfo_v3_t.version. + */ +#define nvmlGpuInstanceProfileInfo_v3 NVML_STRUCT_VERSION(GpuInstanceProfileInfo, 3) + +typedef struct nvmlGpuInstanceInfo_st +{ + nvmlDevice_t device; //!< Parent device + unsigned int id; //!< Unique instance ID within the device + unsigned int profileId; //!< Unique profile ID within the device + nvmlGpuInstancePlacement_t placement; //!< Placement for this instance +} nvmlGpuInstanceInfo_t; + +/** + * Compute instance profiles. + * + * These macros should be passed to \ref nvmlGpuInstanceGetComputeInstanceProfileInfo to retrieve the + * detailed information about a compute instance such as profile ID, engine counts + */ +#define NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE 0x0 +#define NVML_COMPUTE_INSTANCE_PROFILE_2_SLICE 0x1 +#define NVML_COMPUTE_INSTANCE_PROFILE_3_SLICE 0x2 +#define NVML_COMPUTE_INSTANCE_PROFILE_4_SLICE 0x3 +#define NVML_COMPUTE_INSTANCE_PROFILE_7_SLICE 0x4 +#define NVML_COMPUTE_INSTANCE_PROFILE_8_SLICE 0x5 +#define NVML_COMPUTE_INSTANCE_PROFILE_6_SLICE 0x6 +#define NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE_REV1 0x7 +#define NVML_COMPUTE_INSTANCE_PROFILE_COUNT 0x8 + +#define NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED 0x0 //!< All the engines except multiprocessors would be shared +#define NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT 0x1 + +typedef struct nvmlComputeInstancePlacement_st +{ + unsigned int start; //!< Index of first occupied compute slice + unsigned int size; //!< Number of compute slices occupied +} nvmlComputeInstancePlacement_t; + +/** + * Compute instance profile information. + */ +typedef struct nvmlComputeInstanceProfileInfo_st +{ + unsigned int id; //!< Unique profile ID within the GPU instance + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< Compute instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count +} nvmlComputeInstanceProfileInfo_t; + +/** + * Compute instance profile information (v2). + * + * Version 2 adds the \ref nvmlComputeInstanceProfileInfo_v2_t.version field + * to the start of the structure, and the \ref nvmlComputeInstanceProfileInfo_v2_t.name + * field to the end. This structure is not backwards-compatible with + * \ref nvmlComputeInstanceProfileInfo_t. + */ +typedef struct nvmlComputeInstanceProfileInfo_v2_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlComputeInstanceProfileInfo_v2) + unsigned int id; //!< Unique profile ID within the GPU instance + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< Compute instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name +} nvmlComputeInstanceProfileInfo_v2_t; + +/** + * Version identifier value for \ref nvmlComputeInstanceProfileInfo_v2_t.version. + */ +#define nvmlComputeInstanceProfileInfo_v2 NVML_STRUCT_VERSION(ComputeInstanceProfileInfo, 2) + +/** + * Compute instance profile information (v3). + * + * Version 3 adds the \ref nvmlComputeInstanceProfileInfo_v3_t.capabilities field + * \ref nvmlComputeInstanceProfileInfo_t. + */ +typedef struct nvmlComputeInstanceProfileInfo_v3_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlComputeInstanceProfileInfo_v3) + unsigned int id; //!< Unique profile ID within the GPU instance + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< Compute instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name + unsigned int capabilities; //!< Additional capabilities +} nvmlComputeInstanceProfileInfo_v3_t; + +/** + * Version identifier value for \ref nvmlComputeInstanceProfileInfo_v3_t.version. + */ +#define nvmlComputeInstanceProfileInfo_v3 NVML_STRUCT_VERSION(ComputeInstanceProfileInfo, 3) + +typedef struct nvmlComputeInstanceInfo_st +{ + nvmlDevice_t device; //!< Parent device + nvmlGpuInstance_t gpuInstance; //!< Parent GPU instance + unsigned int id; //!< Unique instance ID within the GPU instance + unsigned int profileId; //!< Unique profile ID within the GPU instance + nvmlComputeInstancePlacement_t placement; //!< Placement for this instance within the GPU instance's compute slice range {0, sliceCount} +} nvmlComputeInstanceInfo_t; + +typedef struct nvmlComputeInstance_st* nvmlComputeInstance_t; + +/** + * Set MIG mode for the device. + * + * For Ampere &tm; or newer fully supported devices. + * Requires root user. + * + * This mode determines whether a GPU instance can be created. + * + * This API may unbind or reset the device to activate the requested mode. Thus, the attributes associated with the + * device, such as minor number, might change. The caller of this API is expected to query such attributes again. + * + * On certain platforms like pass-through virtualization, where reset functionality may not be exposed directly, VM + * reboot is required. \a activationStatus would return \ref NVML_ERROR_RESET_REQUIRED for such cases. + * + * \a activationStatus would return the appropriate error code upon unsuccessful activation. For example, if device + * unbind fails because the device isn't idle, \ref NVML_ERROR_IN_USE would be returned. The caller of this API + * is expected to idle the device and retry setting the \a mode. + * + * @note On Windows, only disabling MIG mode is supported. \a activationStatus would return \ref + * NVML_ERROR_NOT_SUPPORTED as GPU reset is not supported on Windows through this API. + * + * @param device The identifier of the target device + * @param mode The mode to be set, \ref NVML_DEVICE_MIG_DISABLE or + * \ref NVML_DEVICE_MIG_ENABLE + * @param activationStatus The activationStatus status + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device,\a mode or \a activationStatus are invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG mode + */ +nvmlReturn_t DECLDIR nvmlDeviceSetMigMode(nvmlDevice_t device, unsigned int mode, nvmlReturn_t *activationStatus); + +/** + * Get MIG mode for the device. + * + * For Ampere &tm; or newer fully supported devices. + * + * Changing MIG modes may require device unbind or reset. The "pending" MIG mode refers to the target mode following the + * next activation trigger. + * + * @param device The identifier of the target device + * @param currentMode Returns the current mode, \ref NVML_DEVICE_MIG_DISABLE or + * \ref NVML_DEVICE_MIG_ENABLE + * @param pendingMode Returns the pending mode, \ref NVML_DEVICE_MIG_DISABLE or + * \ref NVML_DEVICE_MIG_ENABLE + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a currentMode or \a pendingMode are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG mode + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMigMode(nvmlDevice_t device, unsigned int *currentMode, unsigned int *pendingMode); + +/** + * Get GPU instance profile information + * + * Information provided by this API is immutable throughout the lifetime of a MIG mode. + * + * @note This API can be used to enumerate all MIG profiles supported by NVML in a forward compatible + * way by invoking it on \a profile values starting from 0, until the API returns \ref NVML_ERROR_INVALID_ARGUMENT. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param profile One of the NVML_GPU_INSTANCE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile or \a info are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG or \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceProfileInfo(nvmlDevice_t device, unsigned int profile, + nvmlGpuInstanceProfileInfo_t *info); + +/** + * Versioned wrapper around \ref nvmlDeviceGetGpuInstanceProfileInfo that accepts a versioned + * \ref nvmlGpuInstanceProfileInfo_v2_t or later output structure. + * + * @note The caller must set the \ref nvmlGpuInstanceProfileInfo_v2_t.version field to the + * appropriate version prior to calling this function. For example: + * \code + * nvmlGpuInstanceProfileInfo_v2_t profileInfo = + * { .version = nvmlGpuInstanceProfileInfo_v2 }; + * nvmlReturn_t result = nvmlDeviceGetGpuInstanceProfileInfoV(device, + * profile, + * &profileInfo); + * \endcode + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param profile One of the NVML_GPU_INSTANCE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile, \a info, or \a info->version are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceProfileInfoV(nvmlDevice_t device, unsigned int profile, + nvmlGpuInstanceProfileInfo_v2_t *info); + +/** + * GPU instance profile query function that accepts profile ID, instead of profile name. + * It accepts a versioned \ref nvmlGpuInstanceProfileInfo_v2_t or later output structure. + * + * @note The caller must set the \ref nvmlGpuInstanceProfileInfo_v2_t.version field to the + * appropriate version prior to calling this function. For example: + * \code + * nvmlGpuInstanceProfileInfo_v2_t profileInfo = + * { .version = nvmlGpuInstanceProfileInfo_v2 }; + * nvmlReturn_t result = nvmlDeviceGetGpuInstanceProfileInfoV(device, + * profile, + * &profileInfo); + * \endcode + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param profileId One of the profile IDs. + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId, \a info, or \a info->version are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceProfileInfoByIdV(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstanceProfileInfo_v2_t *info); + +/** + * Get GPU instance placements. + * + * A placement represents the location of a GPU instance within a device. This API only returns all the possible + * placements for the given profile regardless of whether MIG is enabled or not. + * A created GPU instance occupies memory slices described by its placement. Creation of new GPU instance will + * fail if there is overlap with the already occupied memory slices. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param placements Returns placements allowed for the profile. Can be NULL to discover number + * of allowed placements for this profile. If non-NULL must be large enough + * to accommodate the placements supported by the profile. + * @param count Returns number of allowed placemenets for the profile. + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG or \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstancePossiblePlacements_v2(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstancePlacement_t *placements, + unsigned int *count); + +/** + * Get GPU instance profile capacity. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param count Returns remaining instance count for the profile ID + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceRemainingCapacity(nvmlDevice_t device, unsigned int profileId, + unsigned int *count); + +/** + * Create GPU instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the GPU instance is destroyed explicitly, the GPU instance handle would + * become invalid. The GPU instance must be recreated to acquire a valid handle. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param gpuInstance Returns the GPU instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile, \a profileId or \a gpuInstance are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or in vGPU guest + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested GPU instance could not be created + */ +nvmlReturn_t DECLDIR nvmlDeviceCreateGpuInstance(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstance_t *gpuInstance); + +/** + * Create GPU instance with the specified placement. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the GPU instance is destroyed explicitly, the GPU instance handle would + * become invalid. The GPU instance must be recreated to acquire a valid handle. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param placement The requested placement. See \ref nvmlDeviceGetGpuInstancePossiblePlacements_v2 + * @param gpuInstance Returns the GPU instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile, \a profileId, \a placement or \a gpuInstance + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or in vGPU guest + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested GPU instance could not be created + */ +nvmlReturn_t DECLDIR nvmlDeviceCreateGpuInstanceWithPlacement(nvmlDevice_t device, unsigned int profileId, + const nvmlGpuInstancePlacement_t *placement, + nvmlGpuInstance_t *gpuInstance); +/** + * Destroy GPU instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The GPU instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or in vGPU guest + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_IN_USE If the GPU instance is in use. This error would be returned if processes + * (e.g. CUDA application) or compute instances are active on the + * GPU instance. + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceDestroy(nvmlGpuInstance_t gpuInstance); + +/** + * Get GPU instances for given profile ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param gpuInstances Returns pre-exiting GPU instances, the buffer must be large enough to + * accommodate the instances supported by the profile. + * See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param count The count of returned GPU instances + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId, \a gpuInstances or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstances(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstance_t *gpuInstances, unsigned int *count); + +/** + * Get GPU instances for given instance ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param id The GPU instance ID + * @param gpuInstance Returns GPU instance + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a id or \a gpuInstance are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_FOUND If the GPU instance is not found. + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceById(nvmlDevice_t device, unsigned int id, nvmlGpuInstance_t *gpuInstance); + +/** + * Get GPU instance information. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param gpuInstance The GPU instance handle + * @param info Return GPU instance information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance or \a info are invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetInfo(nvmlGpuInstance_t gpuInstance, nvmlGpuInstanceInfo_t *info); + +/** + * Get compute instance profile information. + * + * Information provided by this API is immutable throughout the lifetime of a MIG mode. + * + * @note This API can be used to enumerate all MIG profiles supported by NVML in a forward compatible + * way by invoking it on \a profile values starting from 0, until the API returns \ref NVML_ERROR_INVALID_ARGUMENT. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profile One of the NVML_COMPUTE_INSTANCE_PROFILE_* + * @param engProfile One of the NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a engProfile or \a info are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceProfileInfo(nvmlGpuInstance_t gpuInstance, unsigned int profile, + unsigned int engProfile, + nvmlComputeInstanceProfileInfo_t *info); + +/** + * Versioned wrapper around \ref nvmlGpuInstanceGetComputeInstanceProfileInfo that accepts a versioned + * \ref nvmlComputeInstanceProfileInfo_v2_t or later output structure. + * + * @note The caller must set the \ref nvmlGpuInstanceProfileInfo_v2_t.version field to the + * appropriate version prior to calling this function. For example: + * \code + * nvmlComputeInstanceProfileInfo_v2_t profileInfo = + * { .version = nvmlComputeInstanceProfileInfo_v2 }; + * nvmlReturn_t result = nvmlGpuInstanceGetComputeInstanceProfileInfoV(gpuInstance, + * profile, + * engProfile, + * &profileInfo); + * \endcode + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profile One of the NVML_COMPUTE_INSTANCE_PROFILE_* + * @param engProfile One of the NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a engProfile, \a info, or \a info->version are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceProfileInfoV(nvmlGpuInstance_t gpuInstance, unsigned int profile, + unsigned int engProfile, + nvmlComputeInstanceProfileInfo_v2_t *info); + +/** + * Get compute instance profile capacity. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param count Returns remaining instance count for the profile ID + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profileId or \a availableCount are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceRemainingCapacity(nvmlGpuInstance_t gpuInstance, + unsigned int profileId, unsigned int *count); + +/** + * Get compute instance placements. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * A placement represents the location of a compute instance within a GPU instance. This API only returns all the possible + * placements for the given profile. + * A created compute instance occupies compute slices described by its placement. Creation of new compute instance will + * fail if there is overlap with the already occupied compute slices. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param placements Returns placements allowed for the profile. Can be NULL to discover number + * of allowed placements for this profile. If non-NULL must be large enough + * to accommodate the placements supported by the profile. + * @param count Returns number of allowed placemenets for the profile. + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profileId or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstancePossiblePlacements(nvmlGpuInstance_t gpuInstance, + unsigned int profileId, + nvmlComputeInstancePlacement_t *placements, + unsigned int *count); + +/** + * Create compute instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the parent GPU instance is destroyed or the compute instance is destroyed + * explicitly, the compute instance handle would become invalid. The compute instance must be recreated to acquire + * a valid handle. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param computeInstance Returns the compute instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a profileId or \a computeInstance + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested compute instance could not be created + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceCreateComputeInstance(nvmlGpuInstance_t gpuInstance, unsigned int profileId, + nvmlComputeInstance_t *computeInstance); + +/** + * Create compute instance with the specified placement. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the parent GPU instance is destroyed or the compute instance is destroyed + * explicitly, the compute instance handle would become invalid. The compute instance must be recreated to acquire + * a valid handle. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param placement The requested placement. See \ref nvmlGpuInstanceGetComputeInstancePossiblePlacements + * @param computeInstance Returns the compute instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a profileId or \a computeInstance + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested compute instance could not be created + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceCreateComputeInstanceWithPlacement(nvmlGpuInstance_t gpuInstance, unsigned int profileId, + const nvmlComputeInstancePlacement_t *placement, + nvmlComputeInstance_t *computeInstance); + +/** + * Destroy compute instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param computeInstance The compute instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a computeInstance is invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_IN_USE If the compute instance is in use. This error would be returned if + * processes (e.g. CUDA application) are active on the compute instance. + */ +nvmlReturn_t DECLDIR nvmlComputeInstanceDestroy(nvmlComputeInstance_t computeInstance); + +/** + * Get compute instances for given profile ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param computeInstances Returns pre-exiting compute instances, the buffer must be large enough to + * accommodate the instances supported by the profile. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param count The count of returned compute instances + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profileId, \a computeInstances or \a count + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstances(nvmlGpuInstance_t gpuInstance, unsigned int profileId, + nvmlComputeInstance_t *computeInstances, unsigned int *count); + +/** + * Get compute instance for given instance ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The identifier of the target GPU instance + * @param id The compute instance ID + * @param computeInstance Returns compute instance + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a ID or \a computeInstance are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_FOUND If the compute instance is not found. + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceById(nvmlGpuInstance_t gpuInstance, unsigned int id, + nvmlComputeInstance_t *computeInstance); + +/** + * Get compute instance information. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param computeInstance The compute instance handle + * @param info Return compute instance information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a computeInstance or \a info are invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlComputeInstanceGetInfo_v2(nvmlComputeInstance_t computeInstance, nvmlComputeInstanceInfo_t *info); + +/** + * Test if the given handle refers to a MIG device. + * + * A MIG device handle is an NVML abstraction which maps to a MIG compute instance. + * These overloaded references can be used (with some restrictions) interchangeably + * with a GPU device handle to execute queries at a per-compute instance granularity. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device NVML handle to test + * @param isMigDevice True when handle refers to a MIG device + * + * @return + * - \ref NVML_SUCCESS if \a device status was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device handle or \a isMigDevice reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this check is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceIsMigDeviceHandle(nvmlDevice_t device, unsigned int *isMigDevice); + +/** + * Get GPU instance ID for the given MIG device handle. + * + * GPU instance IDs are unique per device and remain valid until the GPU instance is destroyed. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Target MIG device handle + * @param id GPU instance ID + * + * @return + * - \ref NVML_SUCCESS if instance ID was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a id reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceId(nvmlDevice_t device, unsigned int *id); + +/** + * Get compute instance ID for the given MIG device handle. + * + * Compute instance IDs are unique per GPU instance and remain valid until the compute instance + * is destroyed. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Target MIG device handle + * @param id Compute instance ID + * + * @return + * - \ref NVML_SUCCESS if instance ID was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a id reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetComputeInstanceId(nvmlDevice_t device, unsigned int *id); + +/** + * Get the maximum number of MIG devices that can exist under a given parent NVML device. + * + * Returns zero if MIG is not supported or enabled. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Target device handle + * @param count Count of MIG devices + * + * @return + * - \ref NVML_SUCCESS if \a count was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a count reference is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxMigDeviceCount(nvmlDevice_t device, unsigned int *count); + +/** + * Get MIG device handle for the given index under its parent NVML device. + * + * If the compute instance is destroyed either explicitly or by destroying, + * resetting or unbinding the parent GPU instance or the GPU device itself + * the MIG device handle would remain invalid and must be requested again + * using this API. Handles may be reused and their properties can change in + * the process. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Reference to the parent GPU device handle + * @param index Index of the MIG device + * @param migDevice Reference to the MIG device handle + * + * @return + * - \ref NVML_SUCCESS if \a migDevice handle was successfully created + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a index or \a migDevice reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_NOT_FOUND if no valid MIG device was found at \a index + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMigDeviceHandleByIndex(nvmlDevice_t device, unsigned int index, + nvmlDevice_t *migDevice); + +/** + * Get parent device handle from a MIG device handle. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param migDevice MIG device handle + * @param device Device handle + * + * @return + * - \ref NVML_SUCCESS if \a device handle was successfully created + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a migDevice or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDeviceHandleFromMigDeviceHandle(nvmlDevice_t migDevice, nvmlDevice_t *device); + +/** @} */ // @defgroup nvmlMultiInstanceGPU + + +/***************************************************************************************************/ +/** @defgroup GPM NVML GPM + * @note For NVIDIA vGPU Software products + * @note (A) GPM is supported only on MIG-backed vGPU profiles that are allocated all of the instance's frame buffer + * @note (B) No GPM support on Windows + * @{ + */ +/***************************************************************************************************/ +/** @defgroup nvmlGpmEnums GPM Enums + * @{ + */ +/***************************************************************************************************/ + +/** + * GPM Metric Identifiers + */ +typedef enum +{ + NVML_GPM_METRIC_GRAPHICS_UTIL = 1, //!< Percentage of time any compute/graphics app was active on the GPU. 0.0 - 100.0 + NVML_GPM_METRIC_SM_UTIL = 2, //!< Percentage of SMs that were busy. 0.0 - 100.0 + NVML_GPM_METRIC_SM_OCCUPANCY = 3, //!< Percentage of warps that were active vs theoretical maximum. 0.0 - 100.0 + NVML_GPM_METRIC_INTEGER_UTIL = 4, //!< Percentage of time the GPU's SMs were doing integer operations. 0.0 - 100.0 + NVML_GPM_METRIC_ANY_TENSOR_UTIL = 5, //!< Percentage of time the GPU's SMs were doing ANY tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_DFMA_TENSOR_UTIL = 6, //!< Percentage of time the GPU's SMs were doing DFMA tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_HMMA_TENSOR_UTIL = 7, //!< Percentage of time the GPU's SMs were doing HMMA tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_IMMA_TENSOR_UTIL = 9, //!< Percentage of time the GPU's SMs were doing IMMA tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_DRAM_BW_UTIL = 10, //!< Percentage of DRAM bw used vs theoretical maximum. 0.0 - 100.0 */ + NVML_GPM_METRIC_FP64_UTIL = 11, //!< Percentage of time the GPU's SMs were doing non-tensor FP64 math. 0.0 - 100.0 + NVML_GPM_METRIC_FP32_UTIL = 12, //!< Percentage of time the GPU's SMs were doing non-tensor FP32 math. 0.0 - 100.0 + NVML_GPM_METRIC_FP16_UTIL = 13, //!< Percentage of time the GPU's SMs were doing non-tensor FP16 math. 0.0 - 100.0 + NVML_GPM_METRIC_PCIE_TX_PER_SEC = 20, //!< PCIe traffic from this GPU in MiB/sec + NVML_GPM_METRIC_PCIE_RX_PER_SEC = 21, //!< PCIe traffic to this GPU in MiB/sec + NVML_GPM_METRIC_NVDEC_0_UTIL = 30, //!< Percent utilization of NVDEC 0. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_1_UTIL = 31, //!< Percent utilization of NVDEC 1. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_2_UTIL = 32, //!< Percent utilization of NVDEC 2. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_3_UTIL = 33, //!< Percent utilization of NVDEC 3. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_4_UTIL = 34, //!< Percent utilization of NVDEC 4. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_5_UTIL = 35, //!< Percent utilization of NVDEC 5. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_6_UTIL = 36, //!< Percent utilization of NVDEC 6. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_7_UTIL = 37, //!< Percent utilization of NVDEC 7. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_0_UTIL = 40, //!< Percent utilization of NVJPG 0. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_1_UTIL = 41, //!< Percent utilization of NVJPG 1. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_2_UTIL = 42, //!< Percent utilization of NVJPG 2. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_3_UTIL = 43, //!< Percent utilization of NVJPG 3. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_4_UTIL = 44, //!< Percent utilization of NVJPG 4. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_5_UTIL = 45, //!< Percent utilization of NVJPG 5. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_6_UTIL = 46, //!< Percent utilization of NVJPG 6. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_7_UTIL = 47, //!< Percent utilization of NVJPG 7. 0.0 - 100.0 + NVML_GPM_METRIC_NVOFA_0_UTIL = 50, //!< Percent utilization of NVOFA 0. 0.0 - 100.0 + NVML_GPM_METRIC_NVOFA_1_UTIL = 51, //!< Percent utilization of NVOFA 1. 0.0 - 100.0 + NVML_GPM_METRIC_NVLINK_TOTAL_RX_PER_SEC = 60, //!< NvLink read bandwidth for all links in MiB/sec + NVML_GPM_METRIC_NVLINK_TOTAL_TX_PER_SEC = 61, //!< NvLink write bandwidth for all links in MiB/sec + NVML_GPM_METRIC_NVLINK_L0_RX_PER_SEC = 62, //!< NvLink read bandwidth for link 0 in MiB/sec + NVML_GPM_METRIC_NVLINK_L0_TX_PER_SEC = 63, //!< NvLink write bandwidth for link 0 in MiB/sec + NVML_GPM_METRIC_NVLINK_L1_RX_PER_SEC = 64, //!< NvLink read bandwidth for link 1 in MiB/sec + NVML_GPM_METRIC_NVLINK_L1_TX_PER_SEC = 65, //!< NvLink write bandwidth for link 1 in MiB/sec + NVML_GPM_METRIC_NVLINK_L2_RX_PER_SEC = 66, //!< NvLink read bandwidth for link 2 in MiB/sec + NVML_GPM_METRIC_NVLINK_L2_TX_PER_SEC = 67, //!< NvLink write bandwidth for link 2 in MiB/sec + NVML_GPM_METRIC_NVLINK_L3_RX_PER_SEC = 68, //!< NvLink read bandwidth for link 3 in MiB/sec + NVML_GPM_METRIC_NVLINK_L3_TX_PER_SEC = 69, //!< NvLink write bandwidth for link 3 in MiB/sec + NVML_GPM_METRIC_NVLINK_L4_RX_PER_SEC = 70, //!< NvLink read bandwidth for link 4 in MiB/sec + NVML_GPM_METRIC_NVLINK_L4_TX_PER_SEC = 71, //!< NvLink write bandwidth for link 4 in MiB/sec + NVML_GPM_METRIC_NVLINK_L5_RX_PER_SEC = 72, //!< NvLink read bandwidth for link 5 in MiB/sec + NVML_GPM_METRIC_NVLINK_L5_TX_PER_SEC = 73, //!< NvLink write bandwidth for link 5 in MiB/sec + NVML_GPM_METRIC_NVLINK_L6_RX_PER_SEC = 74, //!< NvLink read bandwidth for link 6 in MiB/sec + NVML_GPM_METRIC_NVLINK_L6_TX_PER_SEC = 75, //!< NvLink write bandwidth for link 6 in MiB/sec + NVML_GPM_METRIC_NVLINK_L7_RX_PER_SEC = 76, //!< NvLink read bandwidth for link 7 in MiB/sec + NVML_GPM_METRIC_NVLINK_L7_TX_PER_SEC = 77, //!< NvLink write bandwidth for link 7 in MiB/sec + NVML_GPM_METRIC_NVLINK_L8_RX_PER_SEC = 78, //!< NvLink read bandwidth for link 8 in MiB/sec + NVML_GPM_METRIC_NVLINK_L8_TX_PER_SEC = 79, //!< NvLink write bandwidth for link 8 in MiB/sec + NVML_GPM_METRIC_NVLINK_L9_RX_PER_SEC = 80, //!< NvLink read bandwidth for link 9 in MiB/sec + NVML_GPM_METRIC_NVLINK_L9_TX_PER_SEC = 81, //!< NvLink write bandwidth for link 9 in MiB/sec + NVML_GPM_METRIC_NVLINK_L10_RX_PER_SEC = 82, //!< NvLink read bandwidth for link 10 in MiB/sec + NVML_GPM_METRIC_NVLINK_L10_TX_PER_SEC = 83, //!< NvLink write bandwidth for link 10 in MiB/sec + NVML_GPM_METRIC_NVLINK_L11_RX_PER_SEC = 84, //!< NvLink read bandwidth for link 11 in MiB/sec + NVML_GPM_METRIC_NVLINK_L11_TX_PER_SEC = 85, //!< NvLink write bandwidth for link 11 in MiB/sec + NVML_GPM_METRIC_NVLINK_L12_RX_PER_SEC = 86, //!< NvLink read bandwidth for link 12 in MiB/sec + NVML_GPM_METRIC_NVLINK_L12_TX_PER_SEC = 87, //!< NvLink write bandwidth for link 12 in MiB/sec + NVML_GPM_METRIC_NVLINK_L13_RX_PER_SEC = 88, //!< NvLink read bandwidth for link 13 in MiB/sec + NVML_GPM_METRIC_NVLINK_L13_TX_PER_SEC = 89, //!< NvLink write bandwidth for link 13 in MiB/sec + NVML_GPM_METRIC_NVLINK_L14_RX_PER_SEC = 90, //!< NvLink read bandwidth for link 14 in MiB/sec + NVML_GPM_METRIC_NVLINK_L14_TX_PER_SEC = 91, //!< NvLink write bandwidth for link 14 in MiB/sec + NVML_GPM_METRIC_NVLINK_L15_RX_PER_SEC = 92, //!< NvLink read bandwidth for link 15 in MiB/sec + NVML_GPM_METRIC_NVLINK_L15_TX_PER_SEC = 93, //!< NvLink write bandwidth for link 15 in MiB/sec + NVML_GPM_METRIC_NVLINK_L16_RX_PER_SEC = 94, //!< NvLink read bandwidth for link 16 in MiB/sec + NVML_GPM_METRIC_NVLINK_L16_TX_PER_SEC = 95, //!< NvLink write bandwidth for link 16 in MiB/sec + NVML_GPM_METRIC_NVLINK_L17_RX_PER_SEC = 96, //!< NvLink read bandwidth for link 17 in MiB/sec + NVML_GPM_METRIC_NVLINK_L17_TX_PER_SEC = 97, //!< NvLink write bandwidth for link 17 in MiB/sec + //Put new metrics for BLACKWELL here... + NVML_GPM_METRIC_C2C_TOTAL_TX_PER_SEC = 100, + NVML_GPM_METRIC_C2C_TOTAL_RX_PER_SEC = 101, + NVML_GPM_METRIC_C2C_DATA_TX_PER_SEC = 102, + NVML_GPM_METRIC_C2C_DATA_RX_PER_SEC = 103, + NVML_GPM_METRIC_C2C_LINK0_TOTAL_TX_PER_SEC = 104, + NVML_GPM_METRIC_C2C_LINK0_TOTAL_RX_PER_SEC = 105, + NVML_GPM_METRIC_C2C_LINK0_DATA_TX_PER_SEC = 106, + NVML_GPM_METRIC_C2C_LINK0_DATA_RX_PER_SEC = 107, + NVML_GPM_METRIC_C2C_LINK1_TOTAL_TX_PER_SEC = 108, + NVML_GPM_METRIC_C2C_LINK1_TOTAL_RX_PER_SEC = 109, + NVML_GPM_METRIC_C2C_LINK1_DATA_TX_PER_SEC = 110, + NVML_GPM_METRIC_C2C_LINK1_DATA_RX_PER_SEC = 111, + NVML_GPM_METRIC_C2C_LINK2_TOTAL_TX_PER_SEC = 112, + NVML_GPM_METRIC_C2C_LINK2_TOTAL_RX_PER_SEC = 113, + NVML_GPM_METRIC_C2C_LINK2_DATA_TX_PER_SEC = 114, + NVML_GPM_METRIC_C2C_LINK2_DATA_RX_PER_SEC = 115, + NVML_GPM_METRIC_C2C_LINK3_TOTAL_TX_PER_SEC = 116, + NVML_GPM_METRIC_C2C_LINK3_TOTAL_RX_PER_SEC = 117, + NVML_GPM_METRIC_C2C_LINK3_DATA_TX_PER_SEC = 118, + NVML_GPM_METRIC_C2C_LINK3_DATA_RX_PER_SEC = 119, + NVML_GPM_METRIC_C2C_LINK4_TOTAL_TX_PER_SEC = 120, + NVML_GPM_METRIC_C2C_LINK4_TOTAL_RX_PER_SEC = 121, + NVML_GPM_METRIC_C2C_LINK4_DATA_TX_PER_SEC = 122, + NVML_GPM_METRIC_C2C_LINK4_DATA_RX_PER_SEC = 123, + NVML_GPM_METRIC_C2C_LINK5_TOTAL_TX_PER_SEC = 124, + NVML_GPM_METRIC_C2C_LINK5_TOTAL_RX_PER_SEC = 125, + NVML_GPM_METRIC_C2C_LINK5_DATA_TX_PER_SEC = 126, + NVML_GPM_METRIC_C2C_LINK5_DATA_RX_PER_SEC = 127, + NVML_GPM_METRIC_C2C_LINK6_TOTAL_TX_PER_SEC = 128, + NVML_GPM_METRIC_C2C_LINK6_TOTAL_RX_PER_SEC = 129, + NVML_GPM_METRIC_C2C_LINK6_DATA_TX_PER_SEC = 130, + NVML_GPM_METRIC_C2C_LINK6_DATA_RX_PER_SEC = 131, + NVML_GPM_METRIC_C2C_LINK7_TOTAL_TX_PER_SEC = 132, + NVML_GPM_METRIC_C2C_LINK7_TOTAL_RX_PER_SEC = 133, + NVML_GPM_METRIC_C2C_LINK7_DATA_TX_PER_SEC = 134, + NVML_GPM_METRIC_C2C_LINK7_DATA_RX_PER_SEC = 135, + NVML_GPM_METRIC_C2C_LINK8_TOTAL_TX_PER_SEC = 136, + NVML_GPM_METRIC_C2C_LINK8_TOTAL_RX_PER_SEC = 137, + NVML_GPM_METRIC_C2C_LINK8_DATA_TX_PER_SEC = 138, + NVML_GPM_METRIC_C2C_LINK8_DATA_RX_PER_SEC = 139, + NVML_GPM_METRIC_C2C_LINK9_TOTAL_TX_PER_SEC = 140, + NVML_GPM_METRIC_C2C_LINK9_TOTAL_RX_PER_SEC = 141, + NVML_GPM_METRIC_C2C_LINK9_DATA_TX_PER_SEC = 142, + NVML_GPM_METRIC_C2C_LINK9_DATA_RX_PER_SEC = 143, + NVML_GPM_METRIC_C2C_LINK10_TOTAL_TX_PER_SEC = 144, + NVML_GPM_METRIC_C2C_LINK10_TOTAL_RX_PER_SEC = 145, + NVML_GPM_METRIC_C2C_LINK10_DATA_TX_PER_SEC = 146, + NVML_GPM_METRIC_C2C_LINK10_DATA_RX_PER_SEC = 147, + NVML_GPM_METRIC_C2C_LINK11_TOTAL_TX_PER_SEC = 148, + NVML_GPM_METRIC_C2C_LINK11_TOTAL_RX_PER_SEC = 149, + NVML_GPM_METRIC_C2C_LINK11_DATA_TX_PER_SEC = 150, + NVML_GPM_METRIC_C2C_LINK11_DATA_RX_PER_SEC = 151, + NVML_GPM_METRIC_C2C_LINK12_TOTAL_TX_PER_SEC = 152, + NVML_GPM_METRIC_C2C_LINK12_TOTAL_RX_PER_SEC = 153, + NVML_GPM_METRIC_C2C_LINK12_DATA_TX_PER_SEC = 154, + NVML_GPM_METRIC_C2C_LINK12_DATA_RX_PER_SEC = 155, + NVML_GPM_METRIC_C2C_LINK13_TOTAL_TX_PER_SEC = 156, + NVML_GPM_METRIC_C2C_LINK13_TOTAL_RX_PER_SEC = 157, + NVML_GPM_METRIC_C2C_LINK13_DATA_TX_PER_SEC = 158, + NVML_GPM_METRIC_C2C_LINK13_DATA_RX_PER_SEC = 159, + NVML_GPM_METRIC_HOSTMEM_CACHE_HIT = 160, + NVML_GPM_METRIC_HOSTMEM_CACHE_MISS = 161, + NVML_GPM_METRIC_PEERMEM_CACHE_HIT = 162, + NVML_GPM_METRIC_PEERMEM_CACHE_MISS = 163, + NVML_GPM_METRIC_DRAM_CACHE_HIT = 164, + NVML_GPM_METRIC_DRAM_CACHE_MISS = 165, + NVML_GPM_METRIC_NVENC_0_UTIL = 166, + NVML_GPM_METRIC_NVENC_1_UTIL = 167, + NVML_GPM_METRIC_NVENC_2_UTIL = 168, + NVML_GPM_METRIC_NVENC_3_UTIL = 169, + NVML_GPM_METRIC_GR0_CTXSW_CYCLES_ELAPSED = 170, + NVML_GPM_METRIC_GR0_CTXSW_CYCLES_ACTIVE = 171, + NVML_GPM_METRIC_GR0_CTXSW_REQUESTS = 172, + NVML_GPM_METRIC_GR0_CTXSW_CYCLES_PER_REQ = 173, + NVML_GPM_METRIC_GR0_CTXSW_ACTIVE_PCT = 174, + NVML_GPM_METRIC_GR1_CTXSW_CYCLES_ELAPSED = 175, + NVML_GPM_METRIC_GR1_CTXSW_CYCLES_ACTIVE = 176, + NVML_GPM_METRIC_GR1_CTXSW_REQUESTS = 177, + NVML_GPM_METRIC_GR1_CTXSW_CYCLES_PER_REQ = 178, + NVML_GPM_METRIC_GR1_CTXSW_ACTIVE_PCT = 179, + NVML_GPM_METRIC_GR2_CTXSW_CYCLES_ELAPSED = 180, + NVML_GPM_METRIC_GR2_CTXSW_CYCLES_ACTIVE = 181, + NVML_GPM_METRIC_GR2_CTXSW_REQUESTS = 182, + NVML_GPM_METRIC_GR2_CTXSW_CYCLES_PER_REQ = 183, + NVML_GPM_METRIC_GR2_CTXSW_ACTIVE_PCT = 184, + NVML_GPM_METRIC_GR3_CTXSW_CYCLES_ELAPSED = 185, + NVML_GPM_METRIC_GR3_CTXSW_CYCLES_ACTIVE = 186, + NVML_GPM_METRIC_GR3_CTXSW_REQUESTS = 187, + NVML_GPM_METRIC_GR3_CTXSW_CYCLES_PER_REQ = 188, + NVML_GPM_METRIC_GR3_CTXSW_ACTIVE_PCT = 189, + NVML_GPM_METRIC_GR4_CTXSW_CYCLES_ELAPSED = 190, + NVML_GPM_METRIC_GR4_CTXSW_CYCLES_ACTIVE = 191, + NVML_GPM_METRIC_GR4_CTXSW_REQUESTS = 192, + NVML_GPM_METRIC_GR4_CTXSW_CYCLES_PER_REQ = 193, + NVML_GPM_METRIC_GR4_CTXSW_ACTIVE_PCT = 194, + NVML_GPM_METRIC_GR5_CTXSW_CYCLES_ELAPSED = 195, + NVML_GPM_METRIC_GR5_CTXSW_CYCLES_ACTIVE = 196, + NVML_GPM_METRIC_GR5_CTXSW_REQUESTS = 197, + NVML_GPM_METRIC_GR5_CTXSW_CYCLES_PER_REQ = 198, + NVML_GPM_METRIC_GR5_CTXSW_ACTIVE_PCT = 199, + NVML_GPM_METRIC_GR6_CTXSW_CYCLES_ELAPSED = 200, + NVML_GPM_METRIC_GR6_CTXSW_CYCLES_ACTIVE = 201, + NVML_GPM_METRIC_GR6_CTXSW_REQUESTS = 202, + NVML_GPM_METRIC_GR6_CTXSW_CYCLES_PER_REQ = 203, + NVML_GPM_METRIC_GR6_CTXSW_ACTIVE_PCT = 204, + NVML_GPM_METRIC_GR7_CTXSW_CYCLES_ELAPSED = 205, + NVML_GPM_METRIC_GR7_CTXSW_CYCLES_ACTIVE = 206, + NVML_GPM_METRIC_GR7_CTXSW_REQUESTS = 207, + NVML_GPM_METRIC_GR7_CTXSW_CYCLES_PER_REQ = 208, + NVML_GPM_METRIC_GR7_CTXSW_ACTIVE_PCT = 209, + NVML_GPM_METRIC_MAX = 210, //!< Maximum value above +1. Note that changing this should also change NVML_GPM_METRICS_GET_VERSION due to struct size change +} nvmlGpmMetricId_t; + +/** @} */ // @defgroup nvmlGpmEnums + + +/***************************************************************************************************/ +/** @defgroup nvmlGpmStructs GPM Structs + * @{ + */ +/***************************************************************************************************/ + +/** + * Handle to an allocated GPM sample allocated with nvmlGpmSampleAlloc(). Free this with nvmlGpmSampleFree(). + */ +typedef struct nvmlGpmSample_st* nvmlGpmSample_t; + +/** + * GPM metric information. + */ +typedef struct +{ + unsigned int metricId; //!< IN: NVML_GPM_METRIC_? define of which metric to retrieve + nvmlReturn_t nvmlReturn; //!< OUT: Status of this metric. If this is nonzero, then value is not valid + double value; //!< OUT: Value of this metric. Is only valid if nvmlReturn is 0 (NVML_SUCCESS) + struct + { + char *shortName; + char *longName; + char *unit; + } metricInfo; //!< OUT: Metric name and unit. Those can be NULL if not defined +} nvmlGpmMetric_t; + +/** + * GPM buffer information. + */ +typedef struct +{ + unsigned int version; //!< IN: Set to NVML_GPM_METRICS_GET_VERSION + unsigned int numMetrics; //!< IN: How many metrics to retrieve in metrics[] + nvmlGpmSample_t sample1; //!< IN: Sample buffer + nvmlGpmSample_t sample2; //!< IN: Sample buffer + nvmlGpmMetric_t metrics[NVML_GPM_METRIC_MAX]; //!< IN/OUT: Array of metrics. Set metricId on call. See nvmlReturn and value on return +} nvmlGpmMetricsGet_t; + +#define NVML_GPM_METRICS_GET_VERSION 1 + +/** + * GPM device information. + */ +typedef struct +{ + unsigned int version; //!< IN: Set to NVML_GPM_SUPPORT_VERSION + unsigned int isSupportedDevice; //!< OUT: Indicates device support +} nvmlGpmSupport_t; + +#define NVML_GPM_SUPPORT_VERSION 1 + +/** @} */ // @defgroup nvmlGPMStructs + +/***************************************************************************************************/ +/** @defgroup nvmlGpmFunctions GPM Functions + * @{ + */ +/***************************************************************************************************/ + +/** + * Calculate GPM metrics from two samples. + * + * For Hopper &tm; or newer fully supported devices. + * + * To retrieve metrics, the user must first allocate the two sample buffers at \a metricsGet->sample1 + * and \a metricsGet->sample2 by calling \a nvmlGpmSampleAlloc(). Next, the user should fill in the ID of each metric + * in \a metricsGet->metrics[i].metricId and specify the total number of metrics to retrieve in \a metricsGet->numMetrics, + * The version should be set to NVML_GPM_METRICS_GET_VERSION in \a metricsGet->version. The user then calls the + * \a nvmlGpmSampleGet() API twice to obtain 2 samples of counters. + * + * @note The interval between these two \a nvmlGpmSampleGet() calls should be greater than 100ms due to the + * internal sample refresh rate. Finally, the user calls \a nvmlGpmMetricsGet to retrieve the metrics, which will + * be stored at \a metricsGet->metrics + * + * + * @param metricsGet IN/OUT: populated \a nvmlGpmMetricsGet_t struct + * + * @return + * - \ref NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum on error + */ +nvmlReturn_t DECLDIR nvmlGpmMetricsGet(nvmlGpmMetricsGet_t *metricsGet); + + +/** + * Free an allocated sample buffer that was allocated with \ref nvmlGpmSampleAlloc() + * + * For Hopper &tm; or newer fully supported devices. + * + * @param gpmSample Sample to free + * + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid pointer is provided + */ +nvmlReturn_t DECLDIR nvmlGpmSampleFree(nvmlGpmSample_t gpmSample); + + +/** + * Allocate a sample buffer to be used with NVML GPM . You will need to allocate + * at least two of these buffers to use with the NVML GPM feature + * + * For Hopper &tm; or newer fully supported devices. + * + * @param gpmSample Where the allocated sample will be stored + * + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid pointer is provided + * - \ref NVML_ERROR_MEMORY if system memory is insufficient + */ +nvmlReturn_t DECLDIR nvmlGpmSampleAlloc(nvmlGpmSample_t *gpmSample); + +/** + * Read a sample of GPM metrics into the provided \a gpmSample buffer. After + * two samples are gathered, you can call nvmlGpmMetricGet on those samples to + * retrive metrics + * + * For Hopper &tm; or newer fully supported devices. + * + * @note The interval between two \a nvmlGpmSampleGet() calls should be greater than 100ms due to + * the internal sample refresh rate. + * + * @param device Device to get samples for + * @param gpmSample Buffer to read samples into + * + * @return + * - \ref NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum on error + */ +nvmlReturn_t DECLDIR nvmlGpmSampleGet(nvmlDevice_t device, nvmlGpmSample_t gpmSample); + +/** + * Read a sample of GPM metrics into the provided \a gpmSample buffer for a MIG GPU Instance. + * + * After two samples are gathered, you can call nvmlGpmMetricGet on those + * samples to retrive metrics + * + * For Hopper &tm; or newer fully supported devices. + * + * @note The interval between two \a nvmlGpmMigSampleGet() calls should be greater than 100ms due to + * the internal sample refresh rate. + * + * @param device Device to get samples for + * @param gpuInstanceId MIG GPU Instance ID + * @param gpmSample Buffer to read samples into + * + * @return + * - \ref NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum on error + */ +nvmlReturn_t DECLDIR nvmlGpmMigSampleGet(nvmlDevice_t device, unsigned int gpuInstanceId, nvmlGpmSample_t gpmSample); + +/** + * Indicate whether the supplied device supports GPM + * + * For Hopper &tm; or newer fully supported devices. + * + * @param device NVML device to query for + * @param gpmSupport Structure to indicate GPM support \a nvmlGpmSupport_t. Indicates + * GPM support per system for the supplied device + * + * @return + * - NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum if there is an error in processing the query + */ +nvmlReturn_t DECLDIR nvmlGpmQueryDeviceSupport(nvmlDevice_t device, nvmlGpmSupport_t *gpmSupport); + +/* GPM Stream State */ +/** + * Get GPM stream state. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param state Returns GPM stream state + * NVML_FEATURE_DISABLED or NVML_FEATURE_ENABLED + * + * @return + * - \ref NVML_SUCCESS if \a current GPM stream state were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a state is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlGpmQueryIfStreamingEnabled(nvmlDevice_t device, unsigned int *state); + +/** + * Set GPM stream state. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param state GPM stream state, + * NVML_FEATURE_DISABLED or NVML_FEATURE_ENABLED + * + * @return + * - \ref NVML_SUCCESS if \a current GPM stream state is successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlGpmSetStreamingEnabled(nvmlDevice_t device, unsigned int state); + +/** @} */ // @defgroup nvmlGpmFunctions +/** @} */ // @defgroup GPM + +#define NVML_DEV_CAP_EGM (1 << 0) // Extended GPU memory +/** + * Device capabilities + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int capMask; //!< OUT: Bit mask of capabilities. +} nvmlDeviceCapabilities_v1_t; +typedef nvmlDeviceCapabilities_v1_t nvmlDeviceCapabilities_t; +#define nvmlDeviceCapabilities_v1 NVML_STRUCT_VERSION(DeviceCapabilities, 1) + +/** + * Get device capabilities + * + * See \ref nvmlDeviceCapabilities_v1_t for more information on the struct. + * + * @param device The identifier of the target device + * @param caps Returns GPU's capabilities + * + * @return + * - \ref NVML_SUCCESS If the query is success + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a counters is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCapabilities(nvmlDevice_t device, + nvmlDeviceCapabilities_t *caps); + + +/* + * Generic bitmask to hold 255 bits, represented by 8 elements of 32 bits + */ +#define NVML_255_MASK_BITS_PER_ELEM 32 +#define NVML_255_MASK_NUM_ELEMS 8 +#define NVML_255_MASK_BIT_SET(index, nvmlMask) \ + nvmlMask.mask[index / NVML_255_MASK_BITS_PER_ELEM] |= (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +#define NVML_255_MASK_BIT_GET(index, nvmlMask) \ + nvmlMask.mask[index / NVML_255_MASK_BITS_PER_ELEM] & (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +#define NVML_255_MASK_BIT_SET_PTR(index, nvmlMask) \ + nvmlMask->mask[index / NVML_255_MASK_BITS_PER_ELEM] |= (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +#define NVML_255_MASK_BIT_GET_PTR(index, nvmlMask) \ + nvmlMask->mask[index / NVML_255_MASK_BITS_PER_ELEM] & (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +typedef struct +{ + unsigned int mask[NVML_255_MASK_NUM_ELEMS]; //profileId is used and + * the rest of the structure is ignored. + * + * @return + * - \ref NVML_SUCCESS if the Desired Profile was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or structure was NULL + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change the profile number + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * + **/ +nvmlReturn_t DECLDIR nvmlDevicePowerSmoothingActivatePresetProfile(nvmlDevice_t device, + nvmlPowerSmoothingProfile_t *profile); + +/** + * Update the value of a specific profile parameter contained within \ref nvmlPowerSmoothingProfile_v1_t. + * Requires root/admin permissions. + * + * For Blackwell &tm; or newer fully supported devices. + * + * NVML_POWER_SMOOTHING_PROFILE_PARAM_PERCENT_TMP_FLOOR expects a value as a percentage from 00.00-100.00% + * NVML_POWER_SMOOTHING_PROFILE_PARAM_RAMP_UP_RATE expects a value in W/s + * NVML_POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_RATE expects a value in W/s + * NVML_POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_HYSTERESIS expects a value in ms + * + * @param device The identifier of the target device + * @param profile Reference to \ref nvmlPowerSmoothingProfile_v1_t struct + * + * @return + * - \ref NVML_SUCCESS if the Active Profile was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or profile parameter/value was invalid + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change any profile parameters + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the structure version is not supported + * + **/ +nvmlReturn_t DECLDIR nvmlDevicePowerSmoothingUpdatePresetProfileParam(nvmlDevice_t device, + nvmlPowerSmoothingProfile_t *profile); +/** + * Enable or disable the Power Smoothing Feature. + * Requires root/admin permissions. + * + * For Blackwell &tm; or newer fully supported devices. + * + * See \ref nvmlEnableState_t for details on allowed states + * + * @param device The identifier of the target device + * @param state Reference to \ref nvmlPowerSmoothingState_v1_t + * + * @return + * - \ref NVML_SUCCESS if the feature state was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or state is NULL + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change feature state + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * + **/ +nvmlReturn_t DECLDIR nvmlDevicePowerSmoothingSetState(nvmlDevice_t device, + nvmlPowerSmoothingState_t *state); +/** @} */ // @defgroup + +/** + * Retrieves the counts of SRAM unique uncorrected ECC errors + * + * For Blackwell &tm; or newer fully supported devices. + * + * Reads SRAM unique uncorrected ECC error counts. The total number of unique errors is returned by + * \a errorCounts->entryCount. Error counts are returned as an array of in the caller-supplied buffer pointed at by + * \a errorCounts->entries. Each error count entry holds the location/address of the unique error, the error count and + * whether the error is parity or not. + * + * To read SRAM unique uncorrected ECC error counts, first determine the size of buffer required to hold the error + * counts by invoking the function with \a errorCounts->entries set to NULL. The required array size is returned in + * \a errorCounts->entryCount. The caller should allocate a buffer of size "errorCounts->entryCount * + * sizeof(nvmlEccSramUniqueUncorrectedErrorCounts_t)". Invoke the function again with the allocated buffer passed in + * \a errorCounts->entries. This time \a errorCounts->entryCount will be taken as the entry array size that caller + * allocates for \a errorCounts->entries. + * + * On successful return of the second query, the function updates \a errorCounts->entries with all unique errors. This + * may fail if \a errorCounts->entryCount is smaller than the actual number of unique errors. This can happen in cases + * like new errors occur since the previous query of \a errorCounts->entryCount. No matter the query succeeds or not, + * the latest number of unique errors will be returned in \a errorCounts->entryCount. + * + * @note The query is only supported when ECC mode is enabled. + * + * @param device The identifier of the target device + * @param errorCounts Pointer to caller-supplied array which returns the unique error count entries + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a errorCounts->entryCount is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature or ECC mods is not enabled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if the allocated error entry array is not big enough + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSramUniqueUncorrectedEccErrorCounts(nvmlDevice_t device, + nvmlEccSramUniqueUncorrectedErrorCounts_t *errorCounts); + +/** + * NVML API versioning support + */ + +#ifdef NVML_NO_UNVERSIONED_FUNC_DEFS +nvmlReturn_t DECLDIR nvmlInit(void); +nvmlReturn_t DECLDIR nvmlDeviceGetCount(unsigned int *deviceCount); +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByIndex(unsigned int index, nvmlDevice_t *device); +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByPciBusId(const char *pciBusId, nvmlDevice_t *device); +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfo(nvmlDevice_t device, nvmlPciInfo_t *pci); +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfo_v2(nvmlDevice_t device, nvmlPciInfo_t *pci); +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkRemotePciInfo(nvmlDevice_t device, unsigned int link, nvmlPciInfo_t *pci); +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures_v2(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures_v3(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); +nvmlReturn_t DECLDIR nvmlDeviceRemoveGpu(nvmlPciInfo_t *pciInfo); +nvmlReturn_t DECLDIR nvmlEventSetWait(nvmlEventSet_t set, nvmlEventData_t * data, unsigned int timeoutms); +nvmlReturn_t DECLDIR nvmlDeviceGetAttributes(nvmlDevice_t device, nvmlDeviceAttributes_t *attributes); +nvmlReturn_t DECLDIR nvmlComputeInstanceGetInfo(nvmlComputeInstance_t computeInstance, nvmlComputeInstanceInfo_t *info); +nvmlReturn_t DECLDIR nvmlDeviceGetComputeRunningProcesses(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v1_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetComputeRunningProcesses_v2(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v2_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetGraphicsRunningProcesses(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v1_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetGraphicsRunningProcesses_v2(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v2_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v1_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses_v2(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v2_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstancePossiblePlacements(nvmlDevice_t device, unsigned int profileId, nvmlGpuInstancePlacement_t *placements, unsigned int *count); +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseInfo(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuLicenseInfo_t *licenseInfo); +nvmlReturn_t DECLDIR nvmlDeviceGetDriverModel(nvmlDevice_t device, nvmlDriverModel_t *current, nvmlDriverModel_t *pending); +#endif // #ifdef NVML_NO_UNVERSIONED_FUNC_DEFS + +#if defined(NVML_NO_UNVERSIONED_FUNC_DEFS) +// We don't define APIs to run new versions if this guard is present so there is +// no need to undef +#elif defined(__NVML_API_VERSION_INTERNAL) +#undef nvmlDeviceGetGraphicsRunningProcesses +#undef nvmlDeviceGetComputeRunningProcesses +#undef nvmlDeviceGetMPSComputeRunningProcesses +#undef nvmlDeviceGetAttributes +#undef nvmlComputeInstanceGetInfo +#undef nvmlEventSetWait +#undef nvmlDeviceGetGridLicensableFeatures +#undef nvmlDeviceRemoveGpu +#undef nvmlDeviceGetNvLinkRemotePciInfo +#undef nvmlDeviceGetPciInfo +#undef nvmlDeviceGetCount +#undef nvmlDeviceGetHandleByIndex +#undef nvmlDeviceGetHandleByPciBusId +#undef nvmlInit +#undef nvmlBlacklistDeviceInfo_t +#undef nvmlGetBlacklistDeviceCount +#undef nvmlGetBlacklistDeviceInfoByIndex +#undef nvmlDeviceGetGpuInstancePossiblePlacements +#undef nvmlVgpuInstanceGetLicenseInfo +#undef nvmlDeviceGetDriverModel +#undef nvmlDeviceSetPowerManagementLimit + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/var/pkgs/cuda/13.0/lib64/stubs/libnvidia-ml.a b/var/pkgs/cuda/13.0/lib64/stubs/libnvidia-ml.a new file mode 100644 index 0000000000000000000000000000000000000000..2bbacd8fd8f49767e01c9adbd66d2a32416a4a4f GIT binary patch literal 557156 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

>=Uw>jTk=~I4@dzkZgi(g?ppXWSi-Q;9E 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 Pk&=I}CI9=srTPB{Z_=_5 literal 0 HcmV?d00001 diff --git a/var/pkgs/cuda/13.0/nvml/doc/nvml_changelog.txt b/var/pkgs/cuda/13.0/nvml/doc/nvml_changelog.txt new file mode 100644 index 0000000..c6ec756 --- /dev/null +++ b/var/pkgs/cuda/13.0/nvml/doc/nvml_changelog.txt @@ -0,0 +1,504 @@ +/*! @page KnownIssues Known issues in the current version of NVML library + * + * This is a list of known NVML issues in the current driver: + * - NVML Field Values from #251 - #273 (Power Smoothing, Clock Event Reason, and Sync Power Balancing related field values) have changed between 13.0 and 13.0U1/v580TRD2. + * - Any application that is using these field IDs must be recompiled using the NVML header file from CUDA 13.0 Update 1 in order to continue working correctly with NVIDIA drivers v580 TRD2 and beyond. + * - On systems where GPUs are NUMA nodes, the accuracy of FB memory utilization provided by NVML depends on the memory accounting of the operating system. + * This is because FB memory is managed by the operating system instead of the NVIDIA GPU driver. + * Typically, pages allocated from FB memory are not released even after the process terminates to enhance performance. In scenarios where + * the operating system is under memory pressure, it may resort to utilizing FB memory. Such actions can result in discrepancies in the accuracy of memory reporting. + * - On Linux GPU Reset can't be triggered when there is pending GPU Operation Mode (GOM) change + * - On Linux GPU Reset may not successfully change pending ECC mode. A full reboot may be required to enable the mode change. + * - \ref nvmlAccountingStats supports only one process per GPU at a time (CUDA proxy server counts as one process). + * - \ref nvmlAccountingStats_t.time reports time and utilization values starting from cuInit till process termination. Next driver versions might change this behavior slightly and account process only from cuCtxCreate till cuCtxDestroy. + * - On GPUs from Fermi family current P0 clocks (reported by \ref nvmlDeviceGetClockInfo) can differ from max clocks by few MHz. + */ +/*! @page Changelog Change log of NVML library + * This chapter list changes in API and bug fixes that were introduced to the library + * \section changelog32 Changes between NVML v575 and v580 === + * - Fixed bug with NVML_FI_PWR_SMOOTHING_* Field Value numbering, which was different than the v570 values. + * - Adjusted NVML_FI_DEV_CLOCKS_EVENT_REASON_* and NVML_FI_DEV_POWER_SYNC_BALANCING_* field value numbering to resolve overlap with NVML_FI_PWR_SMOOTHING_* field values. + * + * - Added \ref nvmlDeviceGetSramUniqueUncorrectedEccErrorCounts to get the counts of SRAM unique uncorrected ECC errors. + * - Deprecated Applications Clocks APIs, which will be removed in CUDA 14.0: + * - \ref nvmlDeviceSetApplicationsClocks + * - \ref nvmlDeviceGetApplicationsClock + * - \ref nvmlDeviceGetDefaultApplicationsClock + * - \ref nvmlDeviceResetApplicationsClocks + * - Deprecated \ref nvmlDeviceGetViolationStatus, which will be removed in CUDA 14.0 + * - Added \ref nvmlDeviceGetNvLinkInfo to query device NVLINK info. + * - Added \ref nvmlDeviceGetPdi to retrieve the device GPU PDI. + * - Added Multi-GPU mode NVLINK Encryption \ref NVML_CC_SYSTEM_MULTIGPU_NVLE + * - Added V2 struct to \ref nvmlDeviceGetNvLinkInfo to query NVLINK Firmware info. + * - Added \ref nvmlDeviceReadWritePRM_v1 to retrieve GPU PRM register contents + * - Added \ref nvmlDeviceGetAddressingMode to retrieve the addressing mode for the device. + * - Added \ref nvmlDeviceGetRepairStatus to get ECC status info. + * - Added \ref nvmlDeviceGetGpuInstanceProfileInfoByIdV which allows for MIG GPU instance profile info to be queried with profileId instead of profile name. + * - Updated nvmlGpuFabricInfoV_t to v3 to include a new Health Summary field, and new Incorrect Configuration statuses. + - nvmlGpuFabricInfo_v2_t is deprecated and will be removed in a future release + * - Added \ref nvmlDeviceGetPowerMizerMode_v1 to query the current and supported power mizer modes on Maxwell and newer gpus. Power mizer mode provides a hint to the driver as to how to manage the performance of the GPU. + * - Added \ref nvmlDeviceSetPowerMizerMode_v1 to set the power mizer mode on Maxwell and newer gpus. + * - Added new Incorrect Configuration Statuses to nvmlGpuFabricInfoV_t + * - NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INCOMPATIBLE_GPU_FW + * - NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INVALID_LOCATION + * - Added \ref nvmlDeviceSetHostname_v1 and \ref nvmlDeviceGetHostname_v1 to allow custom GPU hostname configuration. + * \section changelog31 Changes between NVML v570 and v575 === + * + * - Added \ref nvmlSystemEventSetCreate to create a system event set. + * - Added \ref nvmlSystemEventSetFree to free a system event set. + * - Added \ref nvmlSystemRegisterEvents to register system events on a system event set. + * - Added \ref nvmlSystemEventSetWait to wait for system event notification and obtain system event data. + * - Added \ref nvmlGpuInstanceGetCreatableVgpus to query the currently creatable vGPU types on the user provided GPU Instance + * - Added \ref nvmlVgpuTypeGetMaxInstancesPerGpuInstance to query the maximum number of vGPU instances per GPU Instance for the given vGPU type + * - Added \ref nvmlGpuInstanceSetVgpuSchedulerState to set the vGPU scheduler state for the given GPU Instance + * - Added \ref nvmlGpuInstanceGetActiveVgpus to query the currently active vGPU instances on the user provided GPU Instance + * - Added \ref nvmlGpuInstanceGetVgpuSchedulerState to query the vGPU software scheduler state for the given GPU Instance. + * - Added \ref nvmlGpuInstanceGetVgpuSchedulerLog to query the vGPU software scheduler logs for the given GPU Instance. + * - Added \ref nvmlGpuInstanceGetVgpuTypeCreatablePlacements to query the creatable vGPU placement IDs of the vGPU type within a GPU instance + * - Added \ref nvmlGpuInstanceSetVgpuHeterogeneousMode to enable or disable vGPU heterogenous mode for the GPU Instance. + * - Added \ref nvmlGpuInstanceGetVgpuHeterogeneousMode to query the vGPU heterogenous mode for the GPU Instance. + * - Updated \ref nvmlDeviceGetVgpuCapabilities to report whether GPU supports timesliced vGPU on MIG and whether MIG timesliced mode is enabled or not vGPU capabilities. + * - Updated \ref nvmlDeviceSetVgpuCapabilities to set the MIG timesliced mode vGPU capability of a device. + * - Updated \ref nvmlDeviceSetVgpuHeterogeneousMode to return \ref NVML_ERROR_NOT_SUPPORTED when in MIG mode. + * - Updated \ref nvmlDeviceGetVgpuHeterogeneousMode to return \ref NVML_ERROR_NOT_SUPPORTED when in MIG mode. + * - Updated \ref nvmlDeviceGetVgpuTypeCreatablePlacements to return \ref NVML_ERROR_NOT_SUPPORTED when in MIG mode. + * - Updated \ref nvmlDeviceGetVgpuSchedulerLog to return \ref NVML_ERROR_NOT_SUPPORTED when in MIG mode. + * - Updated \ref nvmlDeviceSetVgpuSchedulerState to return \ref NVML_ERROR_NOT_SUPPORTED when in MIG mode. + * - Updated \ref nvmlDeviceGetVgpuSchedulerState to return \ref NVML_ERROR_NOT_SUPPORTED when in MIG mode. + * - Added 3 new NVML_FI_DEV_C2C_LINK_ERROR fieldIds + * - \ref NVML_FI_DEV_C2C_LINK_ERROR_INTR + * - \ref NVML_FI_DEV_C2C_LINK_ERROR_REPLAY + * - \ref NVML_FI_DEV_C2C_LINK_ERROR_REPLAY_B2B + * - Added new NVML_FI_DEV_C2C_LINK_POWER_STATE fieldId + * - Added new CTXSW GPM Metrics + * - Added \ref nvmlDeviceGetHandleByUUIDV that supports both the ASCII and binary format UUID to retrieve the device handle. + * - Added 2 new NVML_FI_DEV_POWER_SYNC_BALANCING fieldIds + * - \ref NVML_FI_DEV_POWER_SYNC_BALANCING_FREQ + * - \ref NVML_FI_DEV_POWER_SYNC_BALANCING_AF + * - Added 5 new Clock Event Reason Counters fieldIds + * - \ref NVML_FI_DEV_CLOCKS_EVENT_REASON_SW_POWER_CAP + * - \ref NVML_FI_DEV_CLOCKS_EVENT_REASON_SYNC_BOOST + * - \ref NVML_FI_DEV_CLOCKS_EVENT_REASON_SW_THERM_SLOWDOWN + * - \ref NVML_FI_DEV_CLOCKS_EVENT_REASON_HW_THERM_SLOWDOWN + * - \ref NVML_FI_DEV_CLOCKS_EVENT_REASON_HW_POWER_BRAKE_SLOWDOWN + * - Updated \ref nvmlDeviceGetMemoryErrorCounter to better account for transient vs. permanent errors + * - Added MIG profiles that can allocate all or none of Decoder, Encoder, JPEG and OFA engines. + * + * \section changelog30 Changes between NVML v565 Update and v570 === + * - Revert the fix for the issue where PCIe throughput (reported via \ref nvmlDeviceGetPcieThroughput and nvidia-smi -q) is 1000 times bigger than its actual value + * - Added field values for data related to Power Smoothing + * - Added \ref nvmlDevicePowerSmoothingActivatePresetProfile to activate a specific Preset Profile for Power Smoothing + * - Added \ref nvmlDevicePowerSmoothingSetState to enable/disable the Power Smoothing feature + * - Added \ref nvmlDevicePowerSmoothingUpdatePresetProfileParam to update parameters to preset profiles for Power Smoothing + * - Added new enums for fieldId NVML_FI_DEV_NVLINK_GET_STATE to expose INACTIVE, ACTIVE, and SLEEP state for a link + * - Added \ref nvmlDeviceGetMarginTemperature to retrieve the thermal margin temperature (distance to nearest slowdown threshold). + * - Added \ref nvmlDeviceGetNvlinkSupportedBwModes to get all supported Nvlink Bandwidth modes + * - Added \ref nvmlDeviceGetNvlinkBwMode to get the current Nvlink Bandwidth mode + * - Added \ref nvmlDeviceSetNvlinkBwMode to set the Nvlink Bandwidth mode + * - Added MIG profiles with support for graphics. + * - Added support for new recovery action - NVML_GPU_RECOVERY_ACTION_DRAIN_AND_RESET + * - Deprecated nvml fieldIds NVML_FI_DEV_RESET_STATUS and NVML_FI_DEV_DRAIN_AND_RESET_STATUS. Usee NVML_FI_DEV_GET_GPU_RECOVERY_ACTION instead + * - Added \ref nvmlDeviceGetDramEncryptionMode and \ref nvmlDeviceSetDramEncryptionMode to query and configure DRAM Encryption Mode + * - Added 3 new flags to GPU Fabric Health Mask + * - NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_RECOVERY + * - NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_UNHEALTHY + * - NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ACCESS_TIMEOUT_RECOVERY + * - Added 4 new GPM metrics + * - NVML_GPM_METRIC_NVENC_0_UTIL + * - NVML_GPM_METRIC_NVENC_1_UTIL + * - NVML_GPM_METRIC_NVENC_2_UTIL + * - NVML_GPM_METRIC_NVENC_3_UTIL + * - Added new counters for Nvlink5 + * - \ref NVML_FI_DEV_NVLINK_COUNT_EFFECTIVE_ERRORS to get sum of the number of errors in each Nvlink packet + * - \ref NVML_FI_DEV_NVLINK_COUNT_EFFECTIVE_BER to get Effective BER for effective errors + * - \ref NVML_FI_DEV_NVLINK_COUNT_FEC_HISTORY_0 to 15 to get count of symbol errors that are corrected + * - Swapped the values of field IDs \ref NVML_FI_DEV_IS_MIG_MODE_INDEPENDENT_MIG_QUERY_CAPABLE and \ref NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_MAX to fix backwards compatibility with v550. + * - New revision of nvmlPlatformInfo_t -- nvmlPlatformInfo_v2 has been added. In this version the following fields from v1 have been renamed + * - rackGuid to chassisSerialNumber + * - chassisPhysicalSlotNumber to slotNumber + * - computeSlotIndex to trayIndex + * - nodeIndex to hostId + * - nvmlPlatformInfo_v1 is deprecated and will be removed in subsequent releases + * + * \section changelog29 Changes between NVML v560 Update and v565 === + * - Fixed the ECC error count mismatch between nvidia-smi query output and NVML APIs, \ref nvmlDeviceGetMemoryErrorCounter and \ref nvmlDeviceGetFieldValues. + * - Added new value NVML_CC_SYSTEM_CPU_CAPS_AMD_SNP_VTOM for CC CPU capability reporting + * - Added \ref nvmlDeviceGetCoolerInfo to retrieve a cooler's control signal characteristics and target that cooler cools. + * - Added new value NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV_SNP for CC CPU capability reporting + * - Added \ref nvmlDeviceGetFanSpeedRPM to report the intended operating speed in rotations per minute (RPM) of the device's specified fan. + * - Added \ref nvmlDeviceGetPerformanceModes to retrieve a performance modes string with all the performance modes defined for this device along with their associated GPU Clock and Memory Clock values. + * - Added \ref nvmlDeviceGetCurrentClockFreqs to retrieve a string with the associated GPU Clock and Memory Clock values for the current pstate. + * - Added \ref nvmlNvlinkVersion_t enum to define NvLink Version + * - Added \ref nvmlDeviceGetPlatformInfo to retrieve the platform information of a device + * - Added new event type nvmlEventTypeGpuUnavailableError + * - Removed support for \p nvmlDeviceGetNvLinkCrcLaneErrorCounter \p nvmlDeviceGetNvLinkEccLaneErrorCounter \p nvmlDeviceGetNvLinkErrorCounter on Blackwell + * - Removed support for fieldIds \ref NVML_FI_DEV_NVLINK_ERROR_DL_REPLAY \ref NVML_FI_DEV_NVLINK_ERROR_DL_RECOVERY \ref NVML_FI_DEV_NVLINK_ERROR_DL_CRC on Blackwell + * - Added \ref nvmlVgpuInstanceGetRuntimeStateSize to get the vGPU runtime state size + * - Updated nvmlDeviceGetVgpuTypeSupportedPlacements function to report both Heterogeneous and Homogeneous vGPU placements. + * - Updated nvmlDeviceGetVgpuCapabilities to report the Homogeneous vGPU capability. + * - Added \ref nvmlDeviceWorkloadPowerProfileGetProfilesInfo to retrieve Workload Power Profile Info + * - Added \ref nvmlDeviceWorkloadPowerProfileGetCurrentProfiles to retrieve current Requested and Enforced Workload Power Profiles + * - Added \ref nvmlDeviceWorkloadPowerProfileSetRequestedProfiles to set Requested Workload Power Profiles + * - Added \ref nvmlDeviceWorkloadPowerProfileClearRequestedProfiles to clear Requested Performance Profiles + * - Added new event type nvmlEventTypeGpuRecoveryAction + * - Added new fieldId to query gpu recovery action NVML_FI_DEV_GET_GPU_RECOVERY_ACTION + * - Deprecated fieldIds + * - \ref NVML_FI_DEV_NVLINK_COUNT_VL15_DROPPED to get Number of VL15 MADs dropped on a link in NVLink5 + * - \ref NVML_FI_DEV_NVLINK_COUNT_RAW_BER_LANE0 to get BER per lane for lane 0 + * - \ref NVML_FI_DEV_NVLINK_COUNT_RAW_BER_LANE1 to get BER per lane for lane 1 + * - \ref NVML_FI_DEV_NVLINK_COUNT_RAW_BER to get BER per link. Sum of all the raw errors per lane/Bits received per link + * - \ref NVML_FI_DEV_NVLINK_COUNT_EFFECTIVE_ERRORS to get Sum of the number of errors in each Nvlink packet + * - \ref NVML_FI_DEV_NVLINK_COUNT_EFFECTIVE_BER to get Effective BER for effective errors + * + * \section changelog28 Changes between NVML v555 Update and v560 === + * + * - Added field values NVML_FI_DEV_PCIE_OUTBOUND_ATOMICS_MASK and NVML_FI_DEV_PCIE_INBOUND_ATOMICS_MASK for nvmlDeviceGetFieldValues. + * - Added field ids NVML_FI_DEV_RESET_STATUS and NVML_FI_DEV_DRAIN_AND_RESET_STATUS which correspond to the nvidia-smi output. + * - Added NVML_DEVICE_ARCH_T23X architecture type. + * - Added \ref nvmlVgpuTypeGetBAR1Info to query the BAR1 information of a vGPU type. + * - Added new event types, nvmlEventTypeSingleBitEccErrorStorm, nvmlEventTypeDramRetirementEvent, nvmlEventTypeDramRetirementFailure, nvmlEventTypeNonFatalPoisonError and nvmlEventTypeFatalPoisonError. + * - Added \ref nvmlSystemGetDriverBranch to query the driver branch information. + * + * \section changelog27 Changes between NVML v550 Update and v555 === + * + * - Added \ref nvmlDeviceGetClockOffsets to query min, max and current clock offset value on a Maxwell and later GPU for a specified clock. + * - Added \ref nvmlDeviceSetClockOffsets to control clock offset value on a Maxwell and later GPU for a specified clock. + * - Added new fieldIds for Nvlink5 telemetry on Blackwell + * - \ref NVML_FI_DEV_NVLINK_COUNT_XMIT_PACKETS to get Total Tx packets on the link in NVLink5 + * - \ref NVML_FI_DEV_NVLINK_COUNT_XMIT_BYTES to get Total Tx bytes on the link in NVLink5 + * - \ref NVML_FI_DEV_NVLINK_COUNT_RCV_PACKETS to get Total Rx packets on the link in NVLink5 + * - \ref NVML_FI_DEV_NVLINK_COUNT_RCV_BYTES to get Total Rx bytes on the link in NVLink5 + * - \ref NVML_FI_DEV_NVLINK_COUNT_VL15_DROPPED to get Number of VL15 MADs dropped on a link in NVLink5 + * - \ref NVML_FI_DEV_NVLINK_COUNT_MALFORMED_PACKET_ERRORS to get Number of packets Rx on a link where packets are malformed + * - \ref NVML_FI_DEV_NVLINK_COUNT_BUFFER_OVERRUN_ERRORS to get Number of packets that were discarded on Rx due to buffer overrun + * - \ref NVML_FI_DEV_NVLINK_COUNT_RCV_ERRORS to get Total number of packets with errors Rx on a link + * - \ref NVML_FI_DEV_NVLINK_COUNT_RCV_REMOTE_ERRORS to get Total number of packets Rx - stomp/EBP marker + * - \ref NVML_FI_DEV_NVLINK_COUNT_RCV_GENERAL_ERRORS to get Total number of packets Rx with header mismatch + * - \ref NVML_FI_DEV_NVLINK_COUNT_LOCAL_LINK_INTEGRITY_ERRORS to get Total number of times that the count of local errors exceeded a threshold + * - \ref NVML_FI_DEV_NVLINK_COUNT_XMIT_DISCARDS to get Total number of tx error packets that were discarded + * - \ref NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_SUCCESSFUL_EVENTS to get Number of times link went from Up to recovery, succeeded and link came back up + * - \ref NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_FAILED_EVENTS to get Number of times link went from Up to recovery, failed and link was declared down + * - \ref NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_EVENTS to get Number of times link went from Up to recovery, irrespective of the result + * - \ref NVML_FI_DEV_NVLINK_COUNT_RAW_BER_LANE0 to get BER per lane for lane 0 + * - \ref NVML_FI_DEV_NVLINK_COUNT_RAW_BER_LANE1 to get BER per lane for lane 1 + * - \ref NVML_FI_DEV_NVLINK_COUNT_RAW_BER to get BER per link. Sum of all the raw errors per lane/Bits received per link + * - \ref NVML_FI_DEV_NVLINK_COUNT_EFFECTIVE_ERRORS to get Sum of the number of errors in each Nvlink packet + * - \ref NVML_FI_DEV_NVLINK_COUNT_EFFECTIVE_BER to get Effective BER for effective errors + * - \ref NVML_FI_DEV_NVLINK_COUNT_SYMBOL_ERRORS to get Number of errors in rx symbols + * - \ref NVML_FI_DEV_NVLINK_COUNT_SYMBOL_BER to get BER for symbol errors + * - Added two new field ids NVML_FI_DEV_PCIE_COUNT_TX_BYTES and NVML_FI_DEV_PCIE_COUNT_RX_BYTES for nvmlDeviceGetFieldValues. + * - Added new API nvmlDeviceGetCapabilities with the first capability bit NVML_DEV_CAP_EGM for Extended GPU Memory (EGM) capability. + * - Added multiGpuMode display on CC enabled system via new API nvmlSystemGetConfComputeSettings or "nvidia-smi conf-compute --get-multigpu-mode" or "nvidia-smi conf-compute -mgm". + * - Added new field ID \ref NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_MAX to get the Max Nvlink Power Threshold for a device. + * - Deprecated \ref nvmlDeviceGetTemperature and replaced with a new API \ref nvmlDeviceGetTemperatureV to retrieve device temperature. + * - Added new field ID \ref NVML_VGPU_DRIVER_CAP_WARM_UPDATE and NVML_DEVICE_VGPU_CAP_WARM_UPDATE to query whether the driver and the device supports FSR and warm update of vGPU host driver without terminating the running guest VM respectively. + * - Added new field ID \ref NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_MIN to get the Min Nvlink Power Threshold for a device. + * - Added new field ID \ref NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_UNITS to get the Units of the Nvlink Power Threshold for a device. + * - Added new field ID \ref NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_SUPPORTED to get if Nvlink Power Threshold is supported for a device. + * + * + * \section changelog26 Changes between NVML v545 Update and v550 === + * + * - Added \ref nvmlDeviceGetNumaNodeId to query the NUMA node of a GPU. + * - Fix the issue where PCIe throughput (reported via nvmlDeviceGetPcieThroughput and nvidia-smi -q) is 1000 times bigger than its actual value. + * - Added new GPM metric Id NVML_GPM_METRIC_NVOFA_1_UTIL to \ref nvmlGpmMetricId_t. + * - Added new field ID \ref NVML_FI_DEV_IS_MIG_MODE_INDEPENDENT_MIG_QUERY_CAPABLE, to check MIG query capable device irrespective of MIG mode. + * - Deprecated NVML_P2P_CAPS_INDEX_PROP and added NVML_P2P_CAPS_INDEX_PCI to reflect the same P2P capability. + * - Added \ref nvmlDeviceGetProcessesUtilizationInfo to retrieve the recent utilization and process ID for all running processes. + * - Added new struct \ref nvmlProcessesUtilizationInfo_v1_t, which includes the new utilization of NVJPG and NVOFA. + * - Added \ref nvmlDeviceGetVgpuInstancesUtilizationInfo to retrieve the recent utilization for vGPU instances running on a physical GPU. + * - Added \ref nvmlDeviceGetVgpuProcessesUtilizationInfo to retrieve the recent utilization for processes running on vGPU instances on a physical GPU. + * - Added \ref nvmlDeviceSetVgpuHeterogeneousMode to enable or disable vGPU heterogenous mode for the device. + * - Added \ref nvmlDeviceGetVgpuHeterogeneousMode to query the vGPU heterogenous mode for the device. + * - Added \ref nvmlVgpuInstanceGetPlacementId to query placement ID of the active vGPU instance. + * - Added \ref nvmlDeviceGetVgpuTypeSupportedPlacements to query the supported vGPU placement IDs of a vGPU type. + * - Added \ref nvmlDeviceGetVgpuTypeCreatablePlacements to query the creatable vGPU placement IDs of a vGPU type. + * - Added support to display confidential compute protected memory along with fb & bar1 in nvidia-smi pmon & dmon commands. + * - Added \ref nvmlDeviceGetGpuFabricInfoV to query Gpu Fabric Probe Info for the device. + * - Deprecated \ref nvmlDeviceGetGpuFabricInfo. This function should not be used, and will be removed in a future release. Use \ref nvmlDeviceGetGpuFabricInfoV instead. + * - Modified \ref nvmlDeviceGetGpuInstanceProfileInfo and \ref nvmlDeviceGetGpuInstancePossiblePlacements_v2 to no longer require MIG being enabled + * - Added \ref nvmlSystemSetConfComputeKeyRotationThresholdInfo to set confidential compute key rotation threshold. + * - Added \ref nvmlSystemGetConfComputeKeyRotationThresholdInfo to query confidential compute key rotation threshold detail. + * - Added \ref nvmlDeviceSetVgpuCapabilities to set the desirable vGPU capability of a device. + * + * + * \section changelog25 Changes between NVML v535 Update and v545 === + * + * - Added a new error code \ref NVML_ERROR_GPU_NOT_FOUND to be returned if no supported GPUS are found during initialization. + * - In \ref nvmlGpuFabricInfo_t \p partitionId has been renamed to \p cliqueId. + * - Added new versioned structs \ref nvmlGpuInstanceProfileInfo_v3_t and \ref nvmlComputeInstanceProfileInfo_v3_t. + * - Added \ref nvmlDeviceGetLastBBXFlushTime for retrieving the timestamp and duration of the latest flush of the BBX object to the inforom storage. + * - Added \ref NVML_POWER_SCOPE_MEMORY to report out power usage for GPU Memory. + * - Added \ref nvmlDeviceGetPciInfoExt which expands \ref nvmlDeviceGetPciInfo_v3 to also report PCI base and sub classcodes. + * - Added new struct \ref nvmlPciInfoExt_v1_t, which is used in \ref nvmlDeviceGetPciInfoExt. + * - Added \ref nvmlDeviceGetRunningProcessDetailList api to get information about Compute, Graphics or MPS-Compute processes running on a GPU with protected memory usage info. + * + * + * \section changelog24 Changes between NVML v530 Update and v535 === + * + * - Fixed \ref nvmlDeviceGetMemoryErrorCounter and \ref nvmlDeviceGetFieldValues to return correct SRAM volatile total error counts. + * - Added \ref nvmlDeviceGetSramEccErrorStatus to query SRAM ECC error status for the device. + * - Added \ref nvmlDeviceGetModuleId for getting device module id + * - Updated \ref nvmlDeviceGetPowerSource API to report undersized power source. + * - Added \ref nvmlDeviceGetJpgUtilization and \ref nvmlDeviceGetOfaUtilization APIs + * - Added \ref nvmlSystemGetNvlinkBwMode and \ref nvmlSystemSetNvlinkBwMode APIs + * - Added \ref nvmlDeviceSetVgpuSchedulerState to set the vGPU scheduler state. + * - Added new field ID \ref NVML_FI_DEV_IS_RESETLESS_MIG_SUPPORTED for device's resetless MIG capability + * - Added \ref nvmlDeviceGetComputeRunningProcesses_v3 to get information about Compute processes running on a GPU. + * - Added \ref nvmlDeviceGetGraphicsRunningProcesses_v3 to get information about Graphics processes running on a GPU. + * - Added \ref nvmlDeviceGetMPSComputeRunningProcesses_v3 to get information about MPS-Compute processes running on a GPU. + * - Added \ref nvmlDeviceGetRunningProcessDetailList to get information about Compute, Graphics or MPS-Compute processes running on a GPU with protected memory usage info. Currently returns NVML_ERROR_NOT_SUPPORTED. Functionality will be implemented in next release. + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_CORRECTABLE_ERRORS for PCIe correctable errors counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_NAKS_RECEIVED for PCIe NAK Receive counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_RECEIVER_ERROR for PCIe receiver error counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_BAD_TLP for PCIe bad TLP counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_NAKS_SENT for NAK Send counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_BAD_DLLP for PCIe bad DLLP counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_NON_FATAL_ERROR for PCIe non fatal error counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_FATAL_ERROR for PCIe fatal error counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_UNSUPPORTED_REQ for PCIe unsupported request counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_LCRC_ERROR for PCIe LCRC error counter + * - Added new field ID \ref NVML_FI_DEV_PCIE_COUNT_LANE_ERROR for per lane error counter with scope as PCIe lane number. + * - Added \ref nvmlDeviceGetPowerUsage to retrieve current power usage + * - Added \ref nvmlDeviceGetTotalEnergyConsumption to get current energy consumption + * - Added \ref nvmlDeviceSetPowerManagementLimit_v2 to set the power limit + * - Renamed nvmlDeviceCcuGetStreamState to nvmlGpmQueryIfStreamingEnabled and nvmlDeviceCcuSetStreamState to nvmlGpmSetStreamingEnabled. + * + * + * \section changelog23 Changes between NVML v525 Update and v530 === + * + * - Fixed a typo in nvmlGpuP2PStatus_t: added a new enum entry for NVML_P2P_STATUS_CHIPSET_NOT_SUPPORTED with the same numeric value as the existing erroneous entry ("NVML_P2P_STATUS_CHIPSET_NOT_SUPPORED") + * - Added \ref nvmlDeviceGetVgpuSchedulerLog to fetch the vGPU software scheduler logs. + * - Added \ref nvmlDeviceGetVgpuSchedulerState to fetch the vGPU software scheduler state. + * - Added \ref nvmlDeviceGetVgpuSchedulerCapabilities to fetch the vGPU software scheduler capabilities. + * + * + * \section changelog22 Changes between NVML v520 Update and v525 === + * + * - Added \ref nvmlDeviceSetNvLinkDeviceLowPowerThreshold to set the NvLink low power threshold. + * - Added \p nvmlDeviceGetPcieAtomicCaps to report PCIe atomic capabilities. + * - Added \p nvmlDeviceCcuGetStreamState API to report the counter collection unit stream state. + * - Added \p nvmlDeviceCcuSetStreamState API to set the counter collection unit stream state. + * - Removed support for NVML_FI_DEV_LINK_SPEED_MBPS_L{0..} field Ids in Hopper. Replaced with NVML_FI_DEV_NVLINK_GET_SPEED with scope as link Id. + * - Removed support for NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT{0..} field Ids in Hopper. Replaced with NVML_FI_DEV_NVLINK_ERROR_DL_CRC with scope as link Id. + * - Removed support for NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L{0..} field Ids in Hopper. Replaced with NVML_FI_DEV_NVLINK_ERROR_DL_REPLAY with scope as link Id. + * - Removed support for NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_{0..} field Ids in Hopper. Replaced with NVML_FI_DEV_NVLINK_ERROR_DL_RECOVERY with scope as link Id. + * - Added new field ID \ref NVML_FI_DEV_NVLINK_GET_STATE to get nvlink state + * - Added new field ID \ref NVML_FI_DEV_NVLINK_GET_VERSION to get nvlink version + * - Added new field ID \ref NVML_FI_DEV_C2C_LINK_COUNT to get C2C link count + * - Added new field ID \ref NVML_FI_DEV_C2C_LINK_GET_STATUS to get C2C link status + * - Added new field ID \ref NVML_FI_DEV_C2C_LINK_GET_MAX_BW to get C2C link bandwidth + * + * + * \section changelog21 Changes between NVML v515 Update and v520 === + * + * - Added \ref nvmlDeviceGetMemClkVfOffset API to report the MemClk VF offset value. + * - Added \ref nvmlDeviceGetMemClkMinMaxVfOffset API to report the Memory clock min and max VF offset that user can set for a specified GPU. + * - Added \ref nvmlDeviceGetGpcClkMinMaxVfOffset API to report the Graphics clock min and max VF offset that user can set for a specified GPU. + * - Added \ref nvmlGpmMetricsGet to calculate GPM metrics from two GPM samples + * - Added \ref nvmlGpmSampleFree to free allocated GPM sample + * - Added \ref nvmlGpmSampleAlloc to allocate a GPM sample + * - Added \ref nvmlGpmSampleGet to retrieve a GPM snapshot + * - Added \ref nvmlGpmQueryDeviceSupport to query whether a device supports GPM + * - Added \ref nvmlDeviceGetFanControlPolicy_v2 API to report the control policy for a specified GPU fan. + * - Added \ref nvmlDeviceSetFanControlPolicy API to set the control policy for a specified GPU fan. + * + * + * \section changelog20 Changes between NVML v510 Update and v515 === + * + * - Added \ref nvmlDeviceGetMinMaxClockOfPState API to report the min and max clocks of some clock domain for a given PState. + * - Added \ref nvmlDeviceGetSupportedPerformanceStates API to get all supported Performance States (P-States) for the GPU. + * - Added \ref nvmlDeviceGetGpcClkVfOffset API to report the GPCCLK VF offset value. + * - Added \ref nvmlDeviceGetMinMaxFanSpeed API to report the min and max fan speed that user can set for a specified GPU fan. + * + * + * \section changelog19 Changes between NVML v495 Update and v510 === + * + * - Added \ref nvmlDeviceGetGpuInstanceProfileInfoV and \ref nvmlGpuInstanceGetComputeInstanceProfileInfoV APIs to include the profile name in their output. + * - Added \ref nvmlDeviceGetMemoryBusWidth API to report the GPU's Memory Bus Width. + * - Added \ref nvmlDeviceGetPcieLinkMaxSpeed API to report the GPU's PCIe Max Speed. + * - Added \ref nvmlDeviceGetPowerSource API to report the GPU's power source as AC or battery. + * - Added \ref nvmlDeviceGetNumFans API to report the GPU's number of fans. + * - Added \ref nvmlDeviceGetNumGpuCores API to report the GPU's number of cores. + * - Added \ref nvmlDeviceGetMemoryInfo_v2. The new version accounts separately for system-reserved memory, and includes it in the used memory amount. The previous version of the API reduced the total memory amount by the amount of system-reserved memory. + * - Added \ref nvmlDeviceGetAdaptiveClockInfoStatus API to report the status of adaptive clocking for the GPU. + * + * + * \section changelog18 Changes between NVML v465 Update and v470 === + * + * - Added new MIG GPU instance profile NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV1. + * - Added \ref nvmlDeviceGetGpuInstancePossiblePlacements_v2. The previous version of the API will not support the profiles with possible placements greater than its total capacity, such as NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV1. + * + * + * \section changelog17 Changes between NVML v460 Update and v465 === + * + * - Added new NVML_BRAND_* enumeration values for NVIDIA, NVIDIA_RTX, GEFORCE_RTX, QUADRO_RTX and TITAN_RTX + * - Updated \ref nvmlDeviceGetHandleByUUID to make it MIG-aware. + * - Updated \ref nvmlDeviceGetUUID to return MIG UUIDs in the canonical format, 'MIG-UUID'. + * - Updated \ref nvmlDeviceGetHandleByUUID to accept both UUID formats, 'MIG-UUID' and 'MIG-GPU UUID/GID/CID'. + * - The \ref nvmlDeviceSetAPIRestriction and \ref nvmlDeviceGetAPIRestriction APIs would no longer support the ability to toggle root-only requirement for \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks. + * + * + * \section changelog16 Changes between NVML v450 Update and v460 === + * + * - Added \ref nvmlDeviceCreateGpuInstanceWithPlacement to allow placement specification when creating a new MIG GPU instance. + * + * + * \section changelog15 Changes between NVML v445 Update and v450 === + * + * - Updated \ref nvmlDeviceGetFanSpeed and \ref nvmlDeviceGetFanSpeed_v2 for allowing fan speeds greater than 100% to be reported. + * - Added \ref nvmlDeviceGetCpuAffinityWithinScope to determine the closest processor(s) within a NUMA node or socket. + * - Added \ref nvmlDeviceGetMemoryAffinity to determine the closest NUMA node(s) within a NUMA node or socket. + * - Added support to query and disable MIG mode on Windows. + * + * + * \section changelog14 Changes between NVML v418 Update and v445 === + * + * - Added support for NVIDIA Ampere architecture. + * - Added support for Multi Instance GPU management. Refer "Multi Instance GPU Management" section for details. + * + * + * \section changelog13 Changes between NVML v361 Update and v418 + * + * - Support for Volta and Turing architectures, bug fixes, performance improvements, and new features + * + * + * \section changelog12 Changes between NVML v349 Update and v361 + * + * - Added \ref nvmlDeviceGetBoardPartNumber to return GPU part numbers + * - Removed support for exclusive thread compute mode (Deprecated in 7.5) + * - Added NVML_CLOCK_VIDEO (encoder/decoder) clock type as a supported clock type for \ref nvmlDeviceGetClockInfo and \ref nvmlDeviceGetMaxClockInfo. + * + * + * \section changelog11 Changes between NVML v346 Update and v349 + * + * The following new functionality is exposed on NVIDIA display drivers version 349 Production or later + * - Updated \ref nvmlDeviceGetMemoryInfo to report Used/Free memory under Windows WDDM mode + * - Added \ref nvmlDeviceGetTopologyCommonAncestor to find the common path between two devices + * - Added \ref nvmlDeviceGetTopologyNearestGpus to get a set of GPUs given a path level + * - Added \ref nvmlSystemGetTopologyGpuSet to retrieve a set of GPUs with a given CPU affinity + * - Updated \ref nvmlDeviceGetAccountingPids, \ref nvmlDeviceGetAccountingBufferSize and \ref nvmlDeviceGetAccountingStats to report accounting information for both active and terminated processes. The execution time field in \ref nvmlAccountingStats_t structure is populated only when the process is terminated. + * + * + * \section changelog10 Changes between NVML v340 Update and v346 + * + * The following new functionality is exposed on NVIDIA display drivers version 346 Production or later + * - added the public APIs nvmlDeviceGetPcieReplayCounter and nvmlDeviceGetPcieThroughput + * - Discontinued Perl bindings support + * - Added \p nvmlDeviceGetGraphicsRunningProcesses_v2 to get information about Graphics processes running on a GPU. + * + * + * \section changelog9 Changes between NVML v331 Update and v340 + * + * The following new functionality is exposed on NVIDIA display drivers version 340 Production or later + * - Added \ref nvmlDeviceGetSamples to get recent power, utilization and clock samples for the GPU. + * - Added \ref nvmlDeviceGetTemperatureThreshold to retrieve temperature threshold information. + * - Added \ref nvmlDeviceGetBrand to retrieve brand information (e.g. Tesla, Quadro, etc.) + * - Added support for K40d and K80 + * - Added nvmlDeviceGetTopology internal API to retrieve path info between PCI devices (remove this for DITA) + * - Added \ref nvmlDeviceGetViolationStatus to get the duration of time during which the device was throttled (lower than requested clocks) due to thermal or power constraints. + * - Added \ref nvmlDeviceGetEncoderUtilization and \ref nvmlDeviceGetDecoderUtilization APIs + * - Added \ref nvmlDeviceGetCpuAffinity to determine the closest processor(s) affinity to a specific GPU + * - Added \ref nvmlDeviceSetCpuAffinity to bind a specific GPU to the closest processor + * - Added \ref nvmlDeviceClearCpuAffinity to unbind a specific GPU + * - Added \ref nvmlDeviceGetBoardId to get a unique boardId for the running system + * - Added \ref nvmlDeviceGetMultiGpuBoard to get whether the device is on a multiGPU board + * - Added \ref nvmlDeviceGetAutoBoostedClocksEnabled and nvmlDeviceSetAutoBoostedClocksEnabled for querying and setting the state of auto boosted clocks on supporting hardware. + * - Added \ref nvmlDeviceSetDefaultAutoBoostedClocksEnabled for setting the default state of auto boosted clocks on supporting hardware. + * + * + * \section changelog8 Changes between NVML v5.319 Update and v331 + * + * The following new functionality is exposed on NVIDIA display drivers version 331 Production or later + * - Added \ref nvmlDeviceGetMinorNumber to get the minor number for the device. + * - Added \ref nvmlDeviceGetBAR1MemoryInfo to get BAR1 total, available and used memory size. + * - Added \ref nvmlDeviceGetBridgeChipInfo to get the information related to bridge chip firmware. + * - Added enforced power limit query API \ref nvmlDeviceGetEnforcedPowerLimit + * - Updated \ref nvmlEventSetWait_v2 to return xid event data in case of xid error event. + * - Added support for K8 + * + * \section changelog7 Changes between NVML v5.319 RC and v5.319 Update + * + * The following new functionality is exposed on NVIDIA display drivers version 319 Update or later + * + * - Added \ref nvmlDeviceSetAPIRestriction and \ref nvmlDeviceGetAPIRestriction, with initial ability to toggle root-only requirement for \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks. + * + * \section changelog6 Changes between NVML v4.304 and v5.319 RC + * + * The following new functionality is exposed on NVIDIA display drivers version 319 Production or later + * + * - IMPORTANT: Added _v2 versions of \ref nvmlDeviceGetHandleByIndex_v2 and \ref nvmlDeviceGetCount_v2 that also count devices not accessible by current user + * - IMPORTANT: nvmlDeviceGetHandleByIndex_v2 (default) can also return NVML_ERROR_NO_PERMISSION + * - Added nvmlInit_v2 and nvmlDeviceGetHandleByIndex_v2 that is safer and thus recommended function for initializing the library + * - nvmlInit_v2 lazily initializes only requested devices (queried with nvmlDeviceGetHandle*) + * - nvml.h defines nvmlInit_v2 and nvmlDeviceGetHandleByIndex_v2 as default functions + * - Added \ref nvmlDeviceGetIndex + * - Added \ref NVML_ERROR_GPU_IS_LOST to report GPUs that have fallen off the bus. + * - Note: All NVML device APIs can return this error code, as a GPU can fall off the bus at any time. + * - Added new class of APIs for gathering process statistics (\ref nvmlAccountingStats) + * - Application Clocks are no longer supported on GPU's from Quadro product line + * - Added APIs to support dynamic page retirement. See \ref nvmlDeviceGetRetiredPages and + * \ref nvmlDeviceGetRetiredPagesPendingStatus + * - Renamed nvmlClocksThrottleReasonUserDefinedClocks to nvmlClocksThrottleReasonApplicationsClocksSetting. Old name is deprecated and can be removed in one of the next major releases. + * - Added \ref nvmlDeviceGetDisplayActive and updated documentation to clarify how it differs from \ref nvmlDeviceGetDisplayMode + * + * \section changelog5 Changes between NVML v4.304 RC and v4.304 Production + * + * The following new functionality is exposed on NVIDIA display drivers version 304 Production or later + * + * - Added \ref nvmlDeviceGetGpuOperationMode and \ref nvmlDeviceSetGpuOperationMode + * + * \section changelog4 Changes between NVML v3.295 and v4.304 RC + * + * The following new functionality is exposed on NVIDIA display drivers version 304 RC or later + * + * - Added \ref nvmlDeviceGetInforomConfigurationChecksum and \ref nvmlDeviceValidateInforom + * - Added new error return value for initialization failure due to kernel module not receiving interrupts + * - Added \ref nvmlDeviceSetApplicationsClocks, \ref nvmlDeviceGetApplicationsClock, \ref nvmlDeviceResetApplicationsClocks + * - Added \ref nvmlDeviceGetSupportedMemoryClocks and \ref nvmlDeviceGetSupportedGraphicsClocks + * - Added \ref nvmlDeviceGetPowerManagementLimitConstraints, \ref nvmlDeviceGetPowerManagementDefaultLimit and \ref nvmlDeviceSetPowerManagementLimit + * - Added \ref nvmlDeviceGetInforomImageVersion + * - Expanded \ref nvmlDeviceGetUUID to support all CUDA capable GPUs + * - Deprecated \ref nvmlDeviceGetDetailedEccErrors in favor of \ref nvmlDeviceGetMemoryErrorCounter + * - Added \ref NVML_MEMORY_LOCATION_TEXTURE_MEMORY to support reporting of texture memory error counters + * - Added \ref nvmlDeviceGetCurrentClocksThrottleReasons and \ref nvmlDeviceGetSupportedClocksThrottleReasons + * - \ref NVML_CLOCK_SM is now also reported on supported Kepler devices. + * - Dropped support for GT200 based Tesla brand GPUs: C1060, M1060, S1070 + * + * \section changelog3 Changes between NVML v2.285 and v3.295 + * + * The following new functionality is exposed on NVIDIA display drivers version 295 or later + * + * - deprecated \ref nvmlDeviceGetHandleBySerial in favor of newly added \ref nvmlDeviceGetHandleByUUID + * - Marked the input parameters of \ref nvmlDeviceGetHandleBySerial, \ref nvmlDeviceGetHandleByUUID and \ref nvmlDeviceGetHandleByPciBusId_v2 as const + * - Added \ref nvmlDeviceOnSameBoard + * - Added \ref nvmlConstants defines + * - Added \ref nvmlDeviceGetMaxPcieLinkGeneration, \ref nvmlDeviceGetMaxPcieLinkWidth, \ref nvmlDeviceGetCurrPcieLinkGeneration,\ref nvmlDeviceGetCurrPcieLinkWidth + * - Format change of \ref nvmlDeviceGetUUID output to match the UUID standard. This function will return a different value. + * - \ref nvmlDeviceGetDetailedEccErrors will report zero for unsupported ECC error counters when a subset of ECC error counters are supported + * \section changelog1 Changes between NVML v1.0 and v2.285 + * + * The following new functionality is exposed on NVIDIA display drivers version 285 or later + * + * - Added possibility to query separately current and pending driver model with \p nvmlDeviceGetDriverModel + * - Added API \ref nvmlDeviceGetVbiosVersion function to report VBIOS version. + * - Added pciSubSystemId to \ref nvmlPciInfo_t struct + * - Added API \ref nvmlErrorString function to convert error code to string + * - Updated docs to indicate we support M2075 and C2075 + * - Added API \ref nvmlSystemGetHicVersion function to report HIC firmware version + * - Added NVML versioning support + * - Functions that changed API and/or size of structs have appended versioning suffix + * (e.g. nvmlDeviceGetPciInfo_v2). Appropriate C defines have been + * added that map old function names to the newer version of the function + * - Added support for concurrent library usage by multiple libraries + * - Added API \ref nvmlDeviceGetMaxClockInfo function for reporting device's clock limits + * - Added new error code NVML_ERROR_DRIVER_NOT_LOADED used by \ref nvmlInit_v2 + * - Extended \ref nvmlPciInfo_t struct with new field: sub system id + * - Added NVML support on Windows guest account + * - Changed format of pciBusId string (to XXXX:XX:XX.X) of \ref nvmlPciInfo_t + * - Parsing of busId in \ref nvmlDeviceGetHandleByPciBusId_v2 is less restrictive. You can pass 0:2:0.0 or 0000:02:00 and other variations + * - Added API for events waiting for GPU events (Linux only) see docs of \ref nvmlEvents + * - Added API \p nvmlDeviceGetComputeRunningProcesses_v2 and \ref nvmlSystemGetProcessName functions for looking up currently running compute applications + * - Deprecated \ref nvmlDeviceGetPowerState in favor of \ref nvmlDeviceGetPerformanceState. + * - Added \ref NVML_FI_DEV_POWER_REQUESTED_LIMIT to report out the power limit requested by the client. + */ diff --git a/var/pkgs/cuda/13.0/nvml/doc/nvml_deprecation_and_removal.txt b/var/pkgs/cuda/13.0/nvml/doc/nvml_deprecation_and_removal.txt new file mode 100644 index 0000000..23c1303 --- /dev/null +++ b/var/pkgs/cuda/13.0/nvml/doc/nvml_deprecation_and_removal.txt @@ -0,0 +1,33 @@ +/*! @page DeprecationNotices Deprecation and/or removal notices for the NVML library + * This chap†er lists the NVML functions marked for deprecation and/or removal. Starting from CUDA 13.1 deprecated functions will generate a compiler warning. Removed functions will return the NVML error code NVML_ERROR_DEPRECATED. + * + * \section depNotice1 CUDA 13.0 === + * The following functions are deprecated starting CUDA 13.0; they will be removed in CUDA 14.0. + * + * - nvmlDeviceSetApplicationsClocks + * - nvmlDeviceGetApplicationsClock + * - nvmlDeviceGetDefaultApplicationsClock + * - nvmlDeviceResetApplicationsClocks + * - nvmlDeviceGetViolationStatus + * - nvmlVgpuInstanceGetLicenseStatus + * - nvmlDeviceResetNvLinkUtilizationCounter + * - nvmlDeviceFreezeNvLinkUtilizationCounter + * - nvmlDeviceGetNvLinkUtilizationCounter + * - nvmlDeviceGetNvLinkUtilizationControl + * - nvmlDeviceSetNvLinkUtilizationControl + * - nvmlDeviceSetMemClkVfOffset + * - nvmlDeviceSetGpcClkVfOffset + * - nvmlDeviceGetGpuFabricInfo + * - nvmlDeviceGetDetailedEccErrors + * - nvmlDeviceGetPowerManagementMode + * - nvmlDeviceGetPowerState + * - nvmlDeviceGetSupportedClocksThrottleReasons + * - nvmlDeviceGetCurrentClocksThrottleReasons + * - nvmlDeviceGetTemperature + * - nvmlDeviceGetHandleBySerial + * + * The following data structures are deprecated starting CUDA 13.0 + * + * - nvmlGpuFabricInfo_v2_t + * + */ diff --git a/var/pkgs/cuda/13.0/nvml/example/Makefile b/var/pkgs/cuda/13.0/nvml/example/Makefile new file mode 100644 index 0000000..459db52 --- /dev/null +++ b/var/pkgs/cuda/13.0/nvml/example/Makefile @@ -0,0 +1,87 @@ +ARCH := $(shell getconf LONG_BIT) +OS := $(shell cat /etc/issue) + +ifneq (,$(wildcard /etc/redhat-release)) + RHEL_OS := $(shell cat /etc/redhat-release) +endif + +# Gets Driver Branch +DRIVER_BRANCH := $(shell nvidia-smi | grep Driver | cut -f 3 -d' ' | cut -f 1 -d '.') + +# Location of the CUDA Toolkit +CUDA_PATH ?= "/usr/local/cuda-8.0" + +ifeq (${ARCH},$(filter ${ARCH},32 64)) + # If correct architecture and libnvidia-ml library is not found + # within the environment, build using the stub library + + ifneq (,$(findstring Ubuntu,$(OS))) + DEB := $(shell dpkg -l | grep cuda) + ifneq (,$(findstring cuda, $(DEB))) + NVML_LIB := /usr/lib/nvidia-$(DRIVER_BRANCH) + else + NVML_LIB := /lib${ARCH} + endif + endif + + ifneq (,$(findstring SUSE,$(OS))) + RPM := $(shell rpm -qa cuda*) + ifneq (,$(findstring cuda, $(RPM))) + NVML_LIB := /usr/lib${ARCH} + else + NVML_LIB := /lib${ARCH} + endif + endif + + ifneq (,$(findstring CentOS,$(RHEL_OS))) + RPM := $(shell rpm -qa cuda*) + ifneq (,$(findstring cuda, $(RPM))) + NVML_LIB := /usr/lib${ARCH}/nvidia + else + NVML_LIB := /lib${ARCH} + endif + endif + + ifneq (,$(findstring Red Hat,$(RHEL_OS))) + RPM := $(shell rpm -qa cuda*) + ifneq (,$(findstring cuda, $(RPM))) + NVML_LIB := /usr/lib${ARCH}/nvidia + else + NVML_LIB := /lib${ARCH} + endif + endif + + ifneq (,$(findstring Fedora,$(RHEL_OS))) + RPM := $(shell rpm -qa cuda*) + ifneq (,$(findstring cuda, $(RPM))) + NVML_LIB := /usr/lib${ARCH}/nvidia + else + NVML_LIB := /lib${ARCH} + endif + endif + +else + NVML_LIB := ../../lib${ARCH}/stubs/ + $(info "libnvidia-ml.so.1" not found, using stub library.) +endif + +ifneq (${ARCH},$(filter ${ARCH},32 64)) + $(error Unknown architecture!) +endif + +NVML_LIB += ../lib/ +NVML_LIB_L := $(addprefix -L , $(NVML_LIB)) + +CFLAGS := -I ../../include -I ../include +LDFLAGS := -lnvidia-ml $(NVML_LIB_L) + +all: example supportedVgpus +example: example.o + $(CC) $< $(CFLAGS) $(LDFLAGS) -o $@ +supportedVgpus: supportedVgpus.o + $(CC) $< $(CFLAGS) $(LDFLAGS) -o $@ +clean: + -@rm -f example.o + -@rm -f example + -@rm -f supportedVgpus.o + -@rm -f supportedVgpus diff --git a/var/pkgs/cuda/13.0/nvml/example/README.txt b/var/pkgs/cuda/13.0/nvml/example/README.txt new file mode 100644 index 0000000..20fceb9 --- /dev/null +++ b/var/pkgs/cuda/13.0/nvml/example/README.txt @@ -0,0 +1,10 @@ +The NVIDIA GDK provides a simple example program that shows how to build an +NVML client. When running an NVML client while the GDK is installed, be +sure your library path first includes the actual NVML library (installed +with the driver), not the stub library that exists solely for +compilation on systems without an NVIDIA driver available. + +If you have installed this example code via your packaging system, +you should first copy it to a user directory before compilation. +The packaging system uninstall feature will not remove this directory if it +contains new files beyond what were installed as part of the GDK. diff --git a/var/pkgs/cuda/13.0/nvml/example/example.c b/var/pkgs/cuda/13.0/nvml/example/example.c new file mode 100644 index 0000000..9b7967a --- /dev/null +++ b/var/pkgs/cuda/13.0/nvml/example/example.c @@ -0,0 +1,180 @@ + /***************************************************************************\ +|* *| +|* Copyright 2010-2016 NVIDIA Corporation. All rights reserved. *| +|* *| +|* NOTICE TO USER: *| +|* *| +|* This source code is subject to NVIDIA ownership rights under U.S. *| +|* and international Copyright laws. Users and possessors of this *| +|* source code are hereby granted a nonexclusive, royalty-free *| +|* license to use this code in individual and commercial software. *| +|* *| +|* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE *| +|* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR *| +|* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH *| +|* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF *| +|* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR *| +|* PURPOSE. IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, *| +|* INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES *| +|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN *| +|* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *| +|* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE *| +|* CODE. *| +|* *| +|* U.S. Government End Users. This source code is a "commercial item" *| +|* as that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting *| +|* of "commercial computer software" and "commercial computer software *| +|* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) *| +|* and is provided to the U.S. Government only as a commercial end item. *| +|* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through *| +|* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the *| +|* source code with only those rights set forth herein. *| +|* *| +|* Any use of this source code in individual and commercial software must *| +|* include, in the user documentation and internal comments to the code, *| +|* the above Disclaimer and U.S. Government End Users Notice. *| +|* *| +|* *| + \***************************************************************************/ + +#include +#include + +static const char * convertToComputeModeString(nvmlComputeMode_t mode) +{ + switch (mode) + { + case NVML_COMPUTEMODE_DEFAULT: + return "Default"; + case NVML_COMPUTEMODE_EXCLUSIVE_THREAD: + return "Exclusive_Thread"; + case NVML_COMPUTEMODE_PROHIBITED: + return "Prohibited"; + case NVML_COMPUTEMODE_EXCLUSIVE_PROCESS: + return "Exclusive Process"; + default: + return "Unknown"; + } +} + +int main(void) +{ + nvmlReturn_t result; + unsigned int device_count, i; + + // First initialize NVML library + result = nvmlInit(); + if (NVML_SUCCESS != result) + { + printf("Failed to initialize NVML: %s\n", nvmlErrorString(result)); + + printf("Press ENTER to continue...\n"); + getchar(); + return 1; + } + + result = nvmlDeviceGetCount(&device_count); + if (NVML_SUCCESS != result) + { + printf("Failed to query device count: %s\n", nvmlErrorString(result)); + goto Error; + } + printf("Found %u device%s\n\n", device_count, device_count != 1 ? "s" : ""); + + printf("Listing devices:\n"); + for (i = 0; i < device_count; i++) + { + nvmlDevice_t device; + char name[NVML_DEVICE_NAME_BUFFER_SIZE]; + nvmlPciInfo_t pci; + nvmlComputeMode_t compute_mode; + + // Query for device handle to perform operations on a device + // You can also query device handle by other features like: + // nvmlDeviceGetHandleBySerial + // nvmlDeviceGetHandleByPciBusId + result = nvmlDeviceGetHandleByIndex(i, &device); + if (NVML_SUCCESS != result) + { + printf("Failed to get handle for device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + + result = nvmlDeviceGetName(device, name, NVML_DEVICE_NAME_BUFFER_SIZE); + if (NVML_SUCCESS != result) + { + printf("Failed to get name of device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + + // pci.busId is very useful to know which device physically you're talking to + // Using PCI identifier you can also match nvmlDevice handle to CUDA device. + result = nvmlDeviceGetPciInfo(device, &pci); + if (NVML_SUCCESS != result) + { + printf("Failed to get pci info for device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + + printf("%u. %s [%s]\n", i, name, pci.busId); + + // This is a simple example on how you can modify GPU's state + result = nvmlDeviceGetComputeMode(device, &compute_mode); + if (NVML_ERROR_NOT_SUPPORTED == result) + printf("\t This is not CUDA capable device\n"); + else if (NVML_SUCCESS != result) + { + printf("Failed to get compute mode for device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + else + { + // try to change compute mode + printf("\t Changing device's compute mode from '%s' to '%s'\n", + convertToComputeModeString(compute_mode), + convertToComputeModeString(NVML_COMPUTEMODE_PROHIBITED)); + + result = nvmlDeviceSetComputeMode(device, NVML_COMPUTEMODE_PROHIBITED); + if (NVML_ERROR_NO_PERMISSION == result) + printf("\t\t Need root privileges to do that: %s\n", nvmlErrorString(result)); + else if (NVML_ERROR_NOT_SUPPORTED == result) + printf("\t\t Compute mode prohibited not supported. You might be running on\n" + "\t\t windows in WDDM driver model or on non-CUDA capable GPU\n"); + else if (NVML_SUCCESS != result) + { + printf("\t\t Failed to set compute mode for device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + else + { + printf("\t Restoring device's compute mode back to '%s'\n", + convertToComputeModeString(compute_mode)); + result = nvmlDeviceSetComputeMode(device, compute_mode); + if (NVML_SUCCESS != result) + { + printf("\t\t Failed to restore compute mode for device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + } + } + } + + result = nvmlShutdown(); + if (NVML_SUCCESS != result) + printf("Failed to shutdown NVML: %s\n", nvmlErrorString(result)); + + printf("All done.\n"); + + printf("Press ENTER to continue...\n"); + getchar(); + return 0; + +Error: + result = nvmlShutdown(); + if (NVML_SUCCESS != result) + printf("Failed to shutdown NVML: %s\n", nvmlErrorString(result)); + + printf("Press ENTER to continue...\n"); + getchar(); + return 1; +} diff --git a/var/pkgs/cuda/13.0/nvml/example/supportedVgpus.c b/var/pkgs/cuda/13.0/nvml/example/supportedVgpus.c new file mode 100644 index 0000000..fe9a094 --- /dev/null +++ b/var/pkgs/cuda/13.0/nvml/example/supportedVgpus.c @@ -0,0 +1,160 @@ + /***************************************************************************\ +|* *| +|* Copyright 2010-2016 NVIDIA Corporation. All rights reserved. *| +|* *| +|* NOTICE TO USER: *| +|* *| +|* This source code is subject to NVIDIA ownership rights under U.S. *| +|* and international Copyright laws. Users and possessors of this *| +|* source code are hereby granted a nonexclusive, royalty-free *| +|* license to use this code in individual and commercial software. *| +|* *| +|* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE *| +|* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR *| +|* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH *| +|* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF *| +|* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR *| +|* PURPOSE. IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, *| +|* INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES *| +|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN *| +|* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *| +|* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE *| +|* CODE. *| +|* *| +|* U.S. Government End Users. This source code is a "commercial item" *| +|* as that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting *| +|* of "commercial computer software" and "commercial computer software *| +|* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) *| +|* and is provided to the U.S. Government only as a commercial end item. *| +|* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through *| +|* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the *| +|* source code with only those rights set forth herein. *| +|* *| +|* Any use of this source code in individual and commercial software must *| +|* include, in the user documentation and internal comments to the code, *| +|* the above Disclaimer and U.S. Government End Users Notice. *| +|* *| +|* *| + \***************************************************************************/ + +#include +#include +#include + +int main(void) +{ + nvmlReturn_t result; + unsigned int device_count, i; + + // First initialize NVML library + result = nvmlInit(); + if (NVML_SUCCESS != result) + { + printf("Failed to initialize NVML: %s\n", nvmlErrorString(result)); + return 1; + } + + result = nvmlDeviceGetCount(&device_count); + if (NVML_SUCCESS != result) + { + printf("Failed to query device count: %s\n", nvmlErrorString(result)); + goto Error; + } + + printf("Found %u device%s\n", device_count, device_count != 1 ? "s" : ""); + printf("Listing devices:\n"); + + for (i = 0; i < device_count; i++) + { + nvmlDevice_t device; + char name[NVML_DEVICE_NAME_BUFFER_SIZE]; + nvmlPciInfo_t pci; + + // Query for device handle to perform operations on a device + // You can also query device handle by other features like: + // nvmlDeviceGetHandleBySerial + // nvmlDeviceGetHandleByPciBusId + result = nvmlDeviceGetHandleByIndex(i, &device); + if (NVML_SUCCESS != result) + { + printf("Failed to get handle for device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + + result = nvmlDeviceGetName(device, name, NVML_DEVICE_NAME_BUFFER_SIZE); + if (NVML_SUCCESS != result) + { + printf("Failed to get name of device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + + // pci.busId is very useful to know which device physically you're talking to + // Using PCI identifier you can also match nvmlDevice handle to CUDA device. + result = nvmlDeviceGetPciInfo(device, &pci); + if (NVML_SUCCESS != result) + { + printf("Failed to get pci info for device %u: %s\n", i, nvmlErrorString(result)); + goto Error; + } + + printf("%u. %s [%s]\n", i, name, pci.busId); + + // This is an example to get the supported vGPUs type names + unsigned int vgpuCount = 0; + nvmlVgpuTypeId_t *vgpuTypeIds = NULL; + unsigned int j; + + result = nvmlDeviceGetSupportedVgpus(device, &vgpuCount, NULL); + if (NVML_ERROR_INSUFFICIENT_SIZE != result) + goto Error; + + if (vgpuCount != 0) + { + vgpuTypeIds = malloc(sizeof(nvmlVgpuTypeId_t) * vgpuCount); + if (!vgpuTypeIds) + { + printf("Memory allocation of %d bytes failed \n", (int)(sizeof(*vgpuTypeIds)*vgpuCount)); + goto Error; + } + + result = nvmlDeviceGetSupportedVgpus(device, &vgpuCount, vgpuTypeIds); + if (NVML_SUCCESS != result) + { + printf("Failed to get the supported vGPUs with status %d \n", (int)result); + goto Error; + } + + printf(" Displaying vGPU type names: \n"); + for (j = 0; j < vgpuCount; j++) + { + char vgpuTypeName[NVML_DEVICE_NAME_BUFFER_SIZE]; + unsigned int bufferSize = NVML_DEVICE_NAME_BUFFER_SIZE; + + if (NVML_SUCCESS == (result = nvmlVgpuTypeGetName(vgpuTypeIds[j], vgpuTypeName, &bufferSize))) + { + printf(" %s\n",vgpuTypeName); + } + else + { + printf("Failed to query the vGPU type name with status %d \n", (int)result); + } + } + } + if (vgpuTypeIds) + free(vgpuTypeIds); + } + + result = nvmlShutdown(); + if (NVML_SUCCESS != result) + printf("Failed to shutdown NVML: %s\n", nvmlErrorString(result)); + + printf("All done.\n"); + return 0; + +Error: + result = nvmlShutdown(); + if (NVML_SUCCESS != result) + printf("Failed to shutdown NVML: %s\n", nvmlErrorString(result)); + + return 1; +} diff --git a/var/pkgs/cuda/13.0/targets/x86_64-linux/include/nvml.h b/var/pkgs/cuda/13.0/targets/x86_64-linux/include/nvml.h new file mode 100644 index 0000000..5f6b9cf --- /dev/null +++ b/var/pkgs/cuda/13.0/targets/x86_64-linux/include/nvml.h @@ -0,0 +1,13607 @@ +/* + * Copyright 1993-2025 NVIDIA Corporation. All rights reserved. + * + * NOTICE TO USER: + * + * This source code is subject to NVIDIA ownership rights under U.S. and + * international Copyright laws. Users and possessors of this source code + * are hereby granted a nonexclusive, royalty-free license to use this code + * in individual and commercial software. + * + * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE + * CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR + * IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. + * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOURCE CODE. + * + * U.S. Government End Users. This source code is a "commercial item" as + * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of + * "commercial computer software" and "commercial computer software + * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) + * and is provided to the U.S. Government only as a commercial end item. + * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through + * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the + * source code with only those rights set forth herein. + * + * Any use of this source code in individual and commercial software must + * include, in the user documentation and internal comments to the code, + * the above Disclaimer and U.S. Government End Users Notice. + */ + +/* +NVML API Reference + +The NVIDIA Management Library (NVML) is a C-based programmatic interface for monitoring and +managing various states within NVIDIA Tesla &tm; GPUs. It is intended to be a platform for building +3rd party applications, and is also the underlying library for the NVIDIA-supported nvidia-smi +tool. NVML is thread-safe so it is safe to make simultaneous NVML calls from multiple threads. + +API Documentation + +Supported platforms: +- Windows: Windows Server 2008 R2 64bit, Windows Server 2012 R2 64bit, Windows 7 64bit, Windows 8 64bit, Windows 10 64bit +- Linux: 32-bit and 64-bit +- Hypervisors: Windows Server 2008R2/2012 Hyper-V 64bit, Citrix XenServer 6.2 SP1+, VMware ESX 5.1/5.5 + +Supported products: +- Full Support + - All Tesla products, starting with the Fermi architecture + - All Quadro products, starting with the Fermi architecture + - All vGPU Software products, starting with the Kepler architecture + - Selected GeForce Titan products +- Limited Support + - All Geforce products, starting with the Fermi architecture + +The NVML library can be found at \%ProgramW6432\%\\"NVIDIA Corporation"\\NVSMI\\ on Windows. It is +not be added to the system path by default. To dynamically link to NVML, add this path to the PATH +environmental variable. To dynamically load NVML, call LoadLibrary with this path. + +On Linux the NVML library will be found on the standard library path. For 64 bit Linux, both the 32 bit +and 64 bit NVML libraries will be installed. + +Online documentation for this library is available at http://docs.nvidia.com/deploy/nvml-api/index.html +*/ + +#ifndef __nvml_nvml_h__ +#define __nvml_nvml_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * On Windows, set up methods for DLL export + * define NVML_STATIC_IMPORT when using nvml_loader library + */ +#if defined _WINDOWS + #if !defined NVML_STATIC_IMPORT + #if defined NVML_LIB_EXPORT + #define DECLDIR __declspec(dllexport) + #else + #define DECLDIR __declspec(dllimport) + #endif + #else + #define DECLDIR + #endif +#else + #define DECLDIR +#endif + +/* + * Deprecation definition. Starting CUDA 13.1 this will change to: + * #if defined _WINDOWS + * #define DEPRECATED(ver) __declspec(deprecated) + * #else + * #define DEPRECATED(ver) __attribute__((deprecated)) + * #endif + */ +#define DEPRECATED(ver) /* nop in CUDA 13.0, enabled in CUDA 13.1 */ + + #define NVML_MCDM_SUPPORT + +/** + * NVML API versioning support + */ +#define NVML_API_VERSION 13 +#define NVML_API_VERSION_STR "13" +/** + * Defining NVML_NO_UNVERSIONED_FUNC_DEFS will disable "auto upgrading" of APIs. + * e.g. the user will have to call nvmlInit_v2 instead of nvmlInit. Enable this + * guard if you need to support older versions of the API + */ +#ifndef NVML_NO_UNVERSIONED_FUNC_DEFS + #define nvmlInit nvmlInit_v2 + #define nvmlDeviceGetPciInfo nvmlDeviceGetPciInfo_v3 + #define nvmlDeviceGetCount nvmlDeviceGetCount_v2 + #define nvmlDeviceGetHandleByIndex nvmlDeviceGetHandleByIndex_v2 + #define nvmlDeviceGetHandleByPciBusId nvmlDeviceGetHandleByPciBusId_v2 + #define nvmlDeviceGetNvLinkRemotePciInfo nvmlDeviceGetNvLinkRemotePciInfo_v2 + #define nvmlDeviceRemoveGpu nvmlDeviceRemoveGpu_v2 + #define nvmlDeviceGetGridLicensableFeatures nvmlDeviceGetGridLicensableFeatures_v4 + #define nvmlEventSetWait nvmlEventSetWait_v2 + #define nvmlDeviceGetAttributes nvmlDeviceGetAttributes_v2 + #define nvmlComputeInstanceGetInfo nvmlComputeInstanceGetInfo_v2 + #define nvmlDeviceGetComputeRunningProcesses nvmlDeviceGetComputeRunningProcesses_v3 + #define nvmlDeviceGetGraphicsRunningProcesses nvmlDeviceGetGraphicsRunningProcesses_v3 + #define nvmlDeviceGetMPSComputeRunningProcesses nvmlDeviceGetMPSComputeRunningProcesses_v3 + #define nvmlBlacklistDeviceInfo_t nvmlExcludedDeviceInfo_t + #define nvmlGetBlacklistDeviceCount nvmlGetExcludedDeviceCount + #define nvmlGetBlacklistDeviceInfoByIndex nvmlGetExcludedDeviceInfoByIndex + #define nvmlDeviceGetGpuInstancePossiblePlacements nvmlDeviceGetGpuInstancePossiblePlacements_v2 + #define nvmlVgpuInstanceGetLicenseInfo nvmlVgpuInstanceGetLicenseInfo_v2 + #define nvmlDeviceGetDriverModel nvmlDeviceGetDriverModel_v2 +#endif // #ifndef NVML_NO_UNVERSIONED_FUNC_DEFS + +#define NVML_STRUCT_VERSION(data, ver) (unsigned int)(sizeof(nvml ## data ## _v ## ver ## _t) | \ + (ver << 24U)) + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceStructs Device Structs + * @{ + */ +/***************************************************************************************************/ + +/** + * Special constant that some fields take when they are not available. + * Used when only part of the struct is not available. + * + * Each structure explicitly states when to check for this value. + */ +#define NVML_VALUE_NOT_AVAILABLE (-1) + +typedef struct nvmlDevice_st* nvmlDevice_t; + +typedef struct nvmlGpuInstance_st* nvmlGpuInstance_t; + +/** + * Buffer size guaranteed to be large enough for pci bus id + */ +#define NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE 32 + +/** + * Buffer size guaranteed to be large enough for pci bus id for \p busIdLegacy + */ +#define NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE 16 + +/** + * PCI information about a GPU device. + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int domain; //!< The PCI domain on which the device's bus resides, 0 to 0xffffffff + unsigned int bus; //!< The bus on which the device resides, 0 to 0xff + unsigned int device; //!< The device's id on the bus, 0 to 31 + + unsigned int pciDeviceId; //!< The combined 16-bit device id and 16-bit vendor id + unsigned int pciSubSystemId; //!< The 32-bit Sub System Device ID + + unsigned int baseClass; //!< The 8-bit PCI base class code + unsigned int subClass; //!< The 8-bit PCI sub class code + + char busId[NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE]; //!< The tuple domain:bus:device.function PCI identifier (& NULL terminator) +} nvmlPciInfoExt_v1_t; +typedef nvmlPciInfoExt_v1_t nvmlPciInfoExt_t; +#define nvmlPciInfoExt_v1 NVML_STRUCT_VERSION(PciInfoExt, 1) + +/** + * PCI information about a GPU device. + */ +typedef struct nvmlPciInfo_st +{ + char busIdLegacy[NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE]; //!< The legacy tuple domain:bus:device.function PCI identifier (& NULL terminator) + unsigned int domain; //!< The PCI domain on which the device's bus resides, 0 to 0xffffffff + unsigned int bus; //!< The bus on which the device resides, 0 to 0xff + unsigned int device; //!< The device's id on the bus, 0 to 31 + unsigned int pciDeviceId; //!< The combined 16-bit device id and 16-bit vendor id + + // Added in NVML 2.285 API + unsigned int pciSubSystemId; //!< The 32-bit Sub System Device ID + + char busId[NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE]; //!< The tuple domain:bus:device.function PCI identifier (& NULL terminator) +} nvmlPciInfo_t; + +/** + * PCI format string for \p busIdLegacy + */ +#define NVML_DEVICE_PCI_BUS_ID_LEGACY_FMT "%04X:%02X:%02X.0" + +/** + * PCI format string for \p busId + */ +#define NVML_DEVICE_PCI_BUS_ID_FMT "%08X:%02X:%02X.0" + +/** + * Utility macro for filling the pci bus id format from a nvmlPciInfo_t + */ +#define NVML_DEVICE_PCI_BUS_ID_FMT_ARGS(pciInfo) (pciInfo)->domain, \ + (pciInfo)->bus, \ + (pciInfo)->device + +/** + * Detailed ECC error counts for a device. + * + * @deprecated Different GPU families can have different memory error counters + * See \ref nvmlDeviceGetMemoryErrorCounter + */ +typedef struct nvmlEccErrorCounts_st +{ + unsigned long long l1Cache; //!< L1 cache errors + unsigned long long l2Cache; //!< L2 cache errors + unsigned long long deviceMemory; //!< Device memory errors + unsigned long long registerFile; //!< Register file errors +} nvmlEccErrorCounts_t; + +/** + * Utilization information for a device. + * Each sample period may be between 1 second and 1/6 second, depending on the product being queried. + */ +typedef struct nvmlUtilization_st +{ + unsigned int gpu; //!< Percent of time over the past sample period during which one or more kernels was executing on the GPU + unsigned int memory; //!< Percent of time over the past sample period during which global (device) memory was being read or written +} nvmlUtilization_t; + +/** + * Memory allocation information for a device (v1). + * The total amount is equal to the sum of the amounts of free and used memory. + */ +typedef struct nvmlMemory_st +{ + unsigned long long total; //!< Total physical device memory (in bytes) + unsigned long long free; //!< Unallocated device memory (in bytes) + unsigned long long used; //!< Sum of Reserved and Allocated device memory (in bytes). + //!< Note that the driver/GPU always sets aside a small amount of memory for bookkeeping +} nvmlMemory_t; + +/** + * Memory allocation information for a device (v2). + * + * Version 2 adds versioning for the struct and the amount of system-reserved memory as an output. + */ +typedef struct nvmlMemory_v2_st +{ + unsigned int version; //!< Structure format version (must be 2) + unsigned long long total; //!< Total physical device memory (in bytes) + unsigned long long reserved; //!< Device memory (in bytes) reserved for system use (driver or firmware) + unsigned long long free; //!< Unallocated device memory (in bytes) + unsigned long long used; //!< Allocated device memory (in bytes). +} nvmlMemory_v2_t; + +#define nvmlMemory_v2 NVML_STRUCT_VERSION(Memory, 2) + +/** + * BAR1 Memory allocation Information for a device + */ +typedef struct nvmlBAR1Memory_st +{ + unsigned long long bar1Total; //!< Total BAR1 Memory (in bytes) + unsigned long long bar1Free; //!< Unallocated BAR1 Memory (in bytes) + unsigned long long bar1Used; //!< Allocated Used Memory (in bytes) +}nvmlBAR1Memory_t; + +/** + * Information about running compute processes on the GPU, legacy version + * for older versions of the API. + */ +typedef struct nvmlProcessInfo_v1_st +{ + unsigned int pid; //!< Process ID + unsigned long long usedGpuMemory; //!< Amount of used GPU memory in bytes. + //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported + //! because Windows KMD manages all the memory and not the NVIDIA driver +} nvmlProcessInfo_v1_t; + +/** + * Information about running compute processes on the GPU + */ +typedef struct nvmlProcessInfo_v2_st +{ + unsigned int pid; //!< Process ID + unsigned long long usedGpuMemory; //!< Amount of used GPU memory in bytes. + //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported + //! because Windows KMD manages all the memory and not the NVIDIA driver + unsigned int gpuInstanceId; //!< If MIG is enabled, stores a valid GPU instance ID. gpuInstanceId is set to + // 0xFFFFFFFF otherwise. + unsigned int computeInstanceId; //!< If MIG is enabled, stores a valid compute instance ID. computeInstanceId is set to + // 0xFFFFFFFF otherwise. +} nvmlProcessInfo_v2_t, nvmlProcessInfo_t; + +/** + * Information about running process on the GPU with protected memory + */ +typedef struct +{ + unsigned int pid; //!< Process ID + unsigned long long usedGpuMemory; //!< Amount of used GPU memory in bytes. + //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported + //! because Windows KMD manages all the memory and not the NVIDIA driver + unsigned int gpuInstanceId; //!< If MIG is enabled, stores a valid GPU instance ID. gpuInstanceId is + // set to 0xFFFFFFFF otherwise. + unsigned int computeInstanceId; //!< If MIG is enabled, stores a valid compute instance ID. computeInstanceId + // is set to 0xFFFFFFFF otherwise. + unsigned long long usedGpuCcProtectedMemory; //!< Amount of used GPU conf compute protected memory in bytes. +} nvmlProcessDetail_v1_t; + +/** + * Information about all running processes on the GPU for the given mode + */ +typedef struct +{ + unsigned int version; //!< Struct version, MUST be nvmlProcessDetailList_v1 + unsigned int mode; //!< Process mode(Compute/Graphics/MPSCompute) + unsigned int numProcArrayEntries; //!< Number of process entries in procArray + nvmlProcessDetail_v1_t *procArray; //!< Process array +} nvmlProcessDetailList_v1_t; + +typedef nvmlProcessDetailList_v1_t nvmlProcessDetailList_t; + +/** + * nvmlProcessDetailList version + */ +#define nvmlProcessDetailList_v1 NVML_STRUCT_VERSION(ProcessDetailList, 1) + +typedef struct nvmlDeviceAttributes_st +{ + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count + unsigned int gpuInstanceSliceCount; //!< GPU instance slice count + unsigned int computeInstanceSliceCount; //!< Compute instance slice count + unsigned long long memorySizeMB; //!< Device memory size (in MiB) +} nvmlDeviceAttributes_t; + +/** + * C2C Mode information for a device + */ +typedef struct +{ + unsigned int isC2cEnabled; +} nvmlC2cModeInfo_v1_t; + +#define nvmlC2cModeInfo_v1 NVML_STRUCT_VERSION(C2cModeInfo, 1) + +/** + * Enum to represent device addressing mode values + */ +typedef enum +{ + NVML_DEVICE_ADDRESSING_MODE_NONE = 0, //!< No active mode + NVML_DEVICE_ADDRESSING_MODE_HMM = 1, //!< Heterogeneous Memory Management mode + NVML_DEVICE_ADDRESSING_MODE_ATS = 2, //!< Address Translation Services mode +} nvmlDeviceAddressingModeType_t; + +/** + * Struct to represent device addressing mode information + */ +typedef struct +{ + unsigned int version; //!< API version + unsigned int value; //!< One of \ref nvmlDeviceAddressingModeType_t +} nvmlDeviceAddressingMode_v1_t; +typedef nvmlDeviceAddressingMode_v1_t nvmlDeviceAddressingMode_t; + +#define nvmlDeviceAddressingMode_v1 NVML_STRUCT_VERSION(DeviceAddressingMode, 1) + +/** + * Struct to represent the NVML repair status + */ +typedef struct +{ + unsigned int version; //!< API version number + unsigned int bChannelRepairPending; //!< Reference to \a unsigned int + unsigned int bTpcRepairPending; //!< Reference to \a unsigned int +} nvmlRepairStatus_v1_t; +typedef nvmlRepairStatus_v1_t nvmlRepairStatus_t; + +#define nvmlRepairStatus_v1 NVML_STRUCT_VERSION(RepairStatus, 1) + +/** + * Possible values that classify the remap availability for each bank. The max + * field will contain the number of banks that have maximum remap availability + * (all reserved rows are available). None means that there are no reserved + * rows available. + */ +typedef struct nvmlRowRemapperHistogramValues_st +{ + unsigned int max; + unsigned int high; + unsigned int partial; + unsigned int low; + unsigned int none; +} nvmlRowRemapperHistogramValues_t; + +/** + * Enum to represent type of bridge chip + */ +typedef enum nvmlBridgeChipType_enum +{ + NVML_BRIDGE_CHIP_PLX = 0, + NVML_BRIDGE_CHIP_BRO4 = 1 +}nvmlBridgeChipType_t; + +/** + * Maximum number of NvLink links supported + */ +#define NVML_NVLINK_MAX_LINKS 18 + +/** + * Enum to represent the NvLink utilization counter packet units + */ +typedef enum nvmlNvLinkUtilizationCountUnits_enum +{ + NVML_NVLINK_COUNTER_UNIT_CYCLES = 0, // count by cycles + NVML_NVLINK_COUNTER_UNIT_PACKETS = 1, // count by packets + NVML_NVLINK_COUNTER_UNIT_BYTES = 2, // count by bytes + NVML_NVLINK_COUNTER_UNIT_RESERVED = 3, // count reserved for internal use + // this must be last + NVML_NVLINK_COUNTER_UNIT_COUNT +} nvmlNvLinkUtilizationCountUnits_t; + +/** + * Enum to represent the NvLink utilization counter packet types to count + * ** this is ONLY applicable with the units as packets or bytes + * ** as specified in \a nvmlNvLinkUtilizationCountUnits_t + * ** all packet filter descriptions are target GPU centric + * ** these can be "OR'd" together + */ +typedef enum nvmlNvLinkUtilizationCountPktTypes_enum +{ + NVML_NVLINK_COUNTER_PKTFILTER_NOP = 0x1, // no operation packets + NVML_NVLINK_COUNTER_PKTFILTER_READ = 0x2, // read packets + NVML_NVLINK_COUNTER_PKTFILTER_WRITE = 0x4, // write packets + NVML_NVLINK_COUNTER_PKTFILTER_RATOM = 0x8, // reduction atomic requests + NVML_NVLINK_COUNTER_PKTFILTER_NRATOM = 0x10, // non-reduction atomic requests + NVML_NVLINK_COUNTER_PKTFILTER_FLUSH = 0x20, // flush requests + NVML_NVLINK_COUNTER_PKTFILTER_RESPDATA = 0x40, // responses with data + NVML_NVLINK_COUNTER_PKTFILTER_RESPNODATA = 0x80, // responses without data + NVML_NVLINK_COUNTER_PKTFILTER_ALL = 0xFF // all packets +} nvmlNvLinkUtilizationCountPktTypes_t; + +/** + * Struct to define the NVLINK counter controls + */ +typedef struct nvmlNvLinkUtilizationControl_st +{ + nvmlNvLinkUtilizationCountUnits_t units; + nvmlNvLinkUtilizationCountPktTypes_t pktfilter; +} nvmlNvLinkUtilizationControl_t; + +/** + * Enum to represent NvLink queryable capabilities + */ +typedef enum nvmlNvLinkCapability_enum +{ + NVML_NVLINK_CAP_P2P_SUPPORTED = 0, // P2P over NVLink is supported + NVML_NVLINK_CAP_SYSMEM_ACCESS = 1, // Access to system memory is supported + NVML_NVLINK_CAP_P2P_ATOMICS = 2, // P2P atomics are supported + NVML_NVLINK_CAP_SYSMEM_ATOMICS= 3, // System memory atomics are supported + NVML_NVLINK_CAP_SLI_BRIDGE = 4, // SLI is supported over this link + NVML_NVLINK_CAP_VALID = 5, // Link is supported on this device + // should be last + NVML_NVLINK_CAP_COUNT +} nvmlNvLinkCapability_t; + +/** + * Enum to represent NvLink queryable error counters + */ +typedef enum nvmlNvLinkErrorCounter_enum +{ + NVML_NVLINK_ERROR_DL_REPLAY = 0, // Data link transmit replay error counter + NVML_NVLINK_ERROR_DL_RECOVERY = 1, // Data link transmit recovery error counter + NVML_NVLINK_ERROR_DL_CRC_FLIT = 2, // Data link receive flow control digit CRC error counter + NVML_NVLINK_ERROR_DL_CRC_DATA = 3, // Data link receive data CRC error counter + NVML_NVLINK_ERROR_DL_ECC_DATA = 4, // Data link receive data ECC error counter + + // this must be last + NVML_NVLINK_ERROR_COUNT +} nvmlNvLinkErrorCounter_t; + +/** + * Enum to represent NvLink's remote device type + */ +typedef enum nvmlIntNvLinkDeviceType_enum +{ + NVML_NVLINK_DEVICE_TYPE_GPU = 0x00, + NVML_NVLINK_DEVICE_TYPE_IBMNPU = 0x01, + NVML_NVLINK_DEVICE_TYPE_SWITCH = 0x02, + NVML_NVLINK_DEVICE_TYPE_UNKNOWN = 0xFF +} nvmlIntNvLinkDeviceType_t; + +/** + * Represents level relationships within a system between two GPUs + * The enums are spaced to allow for future relationships + */ +typedef enum nvmlGpuLevel_enum +{ + NVML_TOPOLOGY_INTERNAL = 0, // e.g. Tesla K80 + NVML_TOPOLOGY_SINGLE = 10, // all devices that only need traverse a single PCIe switch + NVML_TOPOLOGY_MULTIPLE = 20, // all devices that need not traverse a host bridge + NVML_TOPOLOGY_HOSTBRIDGE = 30, // all devices that are connected to the same host bridge + NVML_TOPOLOGY_NODE = 40, // all devices that are connected to the same NUMA node but possibly multiple host bridges + NVML_TOPOLOGY_SYSTEM = 50 // all devices in the system + + // there is purposefully no COUNT here because of the need for spacing above +} nvmlGpuTopologyLevel_t; + +/* Compatibility for CPU->NODE renaming */ +#define NVML_TOPOLOGY_CPU NVML_TOPOLOGY_NODE + +/* P2P Capability Index Status*/ +typedef enum nvmlGpuP2PStatus_enum +{ + NVML_P2P_STATUS_OK = 0, + NVML_P2P_STATUS_CHIPSET_NOT_SUPPORED, + NVML_P2P_STATUS_CHIPSET_NOT_SUPPORTED = NVML_P2P_STATUS_CHIPSET_NOT_SUPPORED, + NVML_P2P_STATUS_GPU_NOT_SUPPORTED, + NVML_P2P_STATUS_IOH_TOPOLOGY_NOT_SUPPORTED, + NVML_P2P_STATUS_DISABLED_BY_REGKEY, + NVML_P2P_STATUS_NOT_SUPPORTED, + NVML_P2P_STATUS_UNKNOWN + +} nvmlGpuP2PStatus_t; + +/* P2P Capability Index*/ +typedef enum nvmlGpuP2PCapsIndex_enum +{ + NVML_P2P_CAPS_INDEX_READ = 0, + NVML_P2P_CAPS_INDEX_WRITE = 1, + NVML_P2P_CAPS_INDEX_NVLINK = 2, + NVML_P2P_CAPS_INDEX_ATOMICS = 3, + NVML_P2P_CAPS_INDEX_PCI = 4, + /* + * DO NOT USE! NVML_P2P_CAPS_INDEX_PROP is deprecated. + * Use NVML_P2P_CAPS_INDEX_PCI instead. + */ + NVML_P2P_CAPS_INDEX_PROP = NVML_P2P_CAPS_INDEX_PCI, + NVML_P2P_CAPS_INDEX_UNKNOWN = 5, +}nvmlGpuP2PCapsIndex_t; + +/** + * Maximum limit on Physical Bridges per Board + */ +#define NVML_MAX_PHYSICAL_BRIDGE (128) + +/** + * Information about the Bridge Chip Firmware + */ +typedef struct nvmlBridgeChipInfo_st +{ + nvmlBridgeChipType_t type; //!< Type of Bridge Chip + unsigned int fwVersion; //!< Firmware Version. 0=Version is unavailable +}nvmlBridgeChipInfo_t; + +/** + * This structure stores the complete Hierarchy of the Bridge Chip within the board. The immediate + * bridge is stored at index 0 of bridgeInfoList, parent to immediate bridge is at index 1 and so forth. + */ +typedef struct nvmlBridgeChipHierarchy_st +{ + unsigned char bridgeCount; //!< Number of Bridge Chips on the Board + nvmlBridgeChipInfo_t bridgeChipInfo[NVML_MAX_PHYSICAL_BRIDGE]; //!< Hierarchy of Bridge Chips on the board +}nvmlBridgeChipHierarchy_t; + +/** + * Represents Type of Sampling Event + */ +typedef enum nvmlSamplingType_enum +{ + NVML_TOTAL_POWER_SAMPLES = 0, //!< To represent total power drawn by GPU + NVML_GPU_UTILIZATION_SAMPLES = 1, //!< To represent percent of time during which one or more kernels was executing on the GPU + NVML_MEMORY_UTILIZATION_SAMPLES = 2, //!< To represent percent of time during which global (device) memory was being read or written + NVML_ENC_UTILIZATION_SAMPLES = 3, //!< To represent percent of time during which NVENC remains busy + NVML_DEC_UTILIZATION_SAMPLES = 4, //!< To represent percent of time during which NVDEC remains busy + NVML_PROCESSOR_CLK_SAMPLES = 5, //!< To represent processor clock samples + NVML_MEMORY_CLK_SAMPLES = 6, //!< To represent memory clock samples + NVML_MODULE_POWER_SAMPLES = 7, //!< To represent module power samples for total module starting Grace Hopper + NVML_JPG_UTILIZATION_SAMPLES = 8, //!< To represent percent of time during which NVJPG remains busy + NVML_OFA_UTILIZATION_SAMPLES = 9, //!< To represent percent of time during which NVOFA remains busy + + // Keep this last + NVML_SAMPLINGTYPE_COUNT +}nvmlSamplingType_t; + +/** + * Represents the queryable PCIe utilization counters + */ +typedef enum nvmlPcieUtilCounter_enum +{ + NVML_PCIE_UTIL_TX_BYTES = 0, // 1KB granularity + NVML_PCIE_UTIL_RX_BYTES = 1, // 1KB granularity + + // Keep this last + NVML_PCIE_UTIL_COUNT +} nvmlPcieUtilCounter_t; + +/** + * Represents the type for sample value returned + */ +typedef enum nvmlValueType_enum +{ + NVML_VALUE_TYPE_DOUBLE = 0, + NVML_VALUE_TYPE_UNSIGNED_INT = 1, + NVML_VALUE_TYPE_UNSIGNED_LONG = 2, + NVML_VALUE_TYPE_UNSIGNED_LONG_LONG = 3, + NVML_VALUE_TYPE_SIGNED_LONG_LONG = 4, + NVML_VALUE_TYPE_SIGNED_INT = 5, + NVML_VALUE_TYPE_UNSIGNED_SHORT = 6, + + // Keep this last + NVML_VALUE_TYPE_COUNT +}nvmlValueType_t; + +/** + * Union to represent different types of Value + */ +typedef union nvmlValue_st +{ + double dVal; //!< If the value is double + int siVal; //!< If the value is signed int + unsigned int uiVal; //!< If the value is unsigned int + unsigned long ulVal; //!< If the value is unsigned long + unsigned long long ullVal; //!< If the value is unsigned long long + signed long long sllVal; //!< If the value is signed long long + unsigned short usVal; //!< If the value is unsigned short +}nvmlValue_t; + +/** + * Information for Sample + */ +typedef struct nvmlSample_st +{ + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlValue_t sampleValue; //!< Sample Value +}nvmlSample_t; + +/** + * Represents type of perf policy for which violation times can be queried + */ +typedef enum nvmlPerfPolicyType_enum +{ + NVML_PERF_POLICY_POWER = 0, //!< How long did power violations cause the GPU to be below application clocks + NVML_PERF_POLICY_THERMAL = 1, //!< How long did thermal violations cause the GPU to be below application clocks + NVML_PERF_POLICY_SYNC_BOOST = 2, //!< How long did sync boost cause the GPU to be below application clocks + NVML_PERF_POLICY_BOARD_LIMIT = 3, //!< How long did the board limit cause the GPU to be below application clocks + NVML_PERF_POLICY_LOW_UTILIZATION = 4, //!< How long did low utilization cause the GPU to be below application clocks + NVML_PERF_POLICY_RELIABILITY = 5, //!< How long did the board reliability limit cause the GPU to be below application clocks + + NVML_PERF_POLICY_TOTAL_APP_CLOCKS = 10, //!< Total time the GPU was held below application clocks by any limiter (0 - 5 above) + NVML_PERF_POLICY_TOTAL_BASE_CLOCKS = 11, //!< Total time the GPU was held below base clocks + + // Keep this last + NVML_PERF_POLICY_COUNT +}nvmlPerfPolicyType_t; + +/** + * Struct to hold perf policy violation status data + */ +typedef struct nvmlViolationTime_st +{ + unsigned long long referenceTime; //!< referenceTime represents CPU timestamp in microseconds + unsigned long long violationTime; //!< violationTime in Nanoseconds +}nvmlViolationTime_t; + +#define NVML_MAX_THERMAL_SENSORS_PER_GPU 3 + +/** + * Represents the thermal sensor targets + */ +typedef enum +{ + NVML_THERMAL_TARGET_NONE = 0, + NVML_THERMAL_TARGET_GPU = 1, //!< GPU core temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_MEMORY = 2, //!< GPU memory temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_POWER_SUPPLY = 4, //!< GPU power supply temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_BOARD = 8, //!< GPU board ambient temperature requires NvPhysicalGpuHandle + NVML_THERMAL_TARGET_VCD_BOARD = 9, //!< Visual Computing Device Board temperature requires NvVisualComputingDeviceHandle + NVML_THERMAL_TARGET_VCD_INLET = 10, //!< Visual Computing Device Inlet temperature requires NvVisualComputingDeviceHandle + NVML_THERMAL_TARGET_VCD_OUTLET = 11, //!< Visual Computing Device Outlet temperature requires NvVisualComputingDeviceHandle + + NVML_THERMAL_TARGET_ALL = 15, + NVML_THERMAL_TARGET_UNKNOWN = -1, +} nvmlThermalTarget_t; + +/** + * Represents the thermal sensor controllers + */ +typedef enum +{ + NVML_THERMAL_CONTROLLER_NONE = 0, + NVML_THERMAL_CONTROLLER_GPU_INTERNAL, + NVML_THERMAL_CONTROLLER_ADM1032, + NVML_THERMAL_CONTROLLER_ADT7461, + NVML_THERMAL_CONTROLLER_MAX6649, + NVML_THERMAL_CONTROLLER_MAX1617, + NVML_THERMAL_CONTROLLER_LM99, + NVML_THERMAL_CONTROLLER_LM89, + NVML_THERMAL_CONTROLLER_LM64, + NVML_THERMAL_CONTROLLER_G781, + NVML_THERMAL_CONTROLLER_ADT7473, + NVML_THERMAL_CONTROLLER_SBMAX6649, + NVML_THERMAL_CONTROLLER_VBIOSEVT, + NVML_THERMAL_CONTROLLER_OS, + NVML_THERMAL_CONTROLLER_NVSYSCON_CANOAS, + NVML_THERMAL_CONTROLLER_NVSYSCON_E551, + NVML_THERMAL_CONTROLLER_MAX6649R, + NVML_THERMAL_CONTROLLER_ADT7473S, + NVML_THERMAL_CONTROLLER_UNKNOWN = -1, +} nvmlThermalController_t; + +/** + * Struct to hold the thermal sensor settings + */ +typedef struct +{ + unsigned int count; + struct + { + nvmlThermalController_t controller; + int defaultMinTemp; + int defaultMaxTemp; + int currentTemp; + nvmlThermalTarget_t target; + } sensor[NVML_MAX_THERMAL_SENSORS_PER_GPU]; + +} nvmlGpuThermalSettings_t; + +/** + * Cooler control type + */ +typedef enum nvmlCoolerControl_enum +{ + NVML_THERMAL_COOLER_SIGNAL_NONE = 0, //!< This cooler has no control signal. + NVML_THERMAL_COOLER_SIGNAL_TOGGLE = 1, //!< This cooler can only be toggled either ON or OFF (eg a switch). + NVML_THERMAL_COOLER_SIGNAL_VARIABLE = 2, //!< This cooler's level can be adjusted from some minimum to some maximum (eg a knob). + + // Keep this last + NVML_THERMAL_COOLER_SIGNAL_COUNT +} nvmlCoolerControl_t; + +/** + * Cooler's target + */ +typedef enum nvmlCoolerTarget_enum +{ + NVML_THERMAL_COOLER_TARGET_NONE = 1 << 0, //!< This cooler cools nothing. + NVML_THERMAL_COOLER_TARGET_GPU = 1 << 1, //!< This cooler can cool the GPU. + NVML_THERMAL_COOLER_TARGET_MEMORY = 1 << 2, //!< This cooler can cool the memory. + NVML_THERMAL_COOLER_TARGET_POWER_SUPPLY = 1 << 3, //!< This cooler can cool the power supply. + NVML_THERMAL_COOLER_TARGET_GPU_RELATED = (NVML_THERMAL_COOLER_TARGET_GPU | NVML_THERMAL_COOLER_TARGET_MEMORY | NVML_THERMAL_COOLER_TARGET_POWER_SUPPLY) //!< This cooler cools all of the components related to its target gpu. GPU_RELATED = GPU | MEMORY | POWER_SUPPLY +} nvmlCoolerTarget_t; + +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int index; //!< the cooler index + nvmlCoolerControl_t signalType; //!< OUT: the cooler's control signal characteristics + nvmlCoolerTarget_t target; //!< OUT: the target that cooler cools +} nvmlCoolerInfo_v1_t; +typedef nvmlCoolerInfo_v1_t nvmlCoolerInfo_t; + +#define nvmlCoolerInfo_v1 NVML_STRUCT_VERSION(CoolerInfo, 1) + +/** + * UUID length in ASCII format + */ +#define NVML_DEVICE_UUID_ASCII_LEN 41 + +/** + * UUID length in binary format + */ +#define NVML_DEVICE_UUID_BINARY_LEN 16 + +/** + * Enum to represent different UUID types + */ +typedef enum +{ + NVML_UUID_TYPE_NONE = 0, //!< Undefined type + NVML_UUID_TYPE_ASCII = 1, //!< ASCII format type + NVML_UUID_TYPE_BINARY = 2, //!< Binary format type +} nvmlUUIDType_t; + +/** + * Union to represent different UUID values + */ +typedef union +{ + char str[NVML_DEVICE_UUID_ASCII_LEN]; //!< ASCII format value + unsigned char bytes[NVML_DEVICE_UUID_BINARY_LEN]; //!< Binary format value +} nvmlUUIDValue_t; + +/** + * Struct to represent NVML UUID information + */ +typedef struct +{ + unsigned int version; //!< API version number + unsigned int type; //!< One of \p nvmlUUIDType_t + nvmlUUIDValue_t value; //!< One of \p nvmlUUIDValue_t, to be set based on the UUID format +} nvmlUUID_v1_t; +typedef nvmlUUID_v1_t nvmlUUID_t; + +#define nvmlUUID_v1 NVML_STRUCT_VERSION(UUID, 1) + +/** + * Struct to represent the NVML PDI information + */ +typedef struct +{ + unsigned int version; //!< API version number + unsigned long long value; //!< 64-bit PDI value +} nvmlPdi_v1_t; +typedef nvmlPdi_v1_t nvmlPdi_t; + +#define nvmlPdi_v1 NVML_STRUCT_VERSION(Pdi, 1) + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceEnumvs Device Enums + * @{ + */ +/***************************************************************************************************/ + +/** + * Generic enable/disable enum. + */ +typedef enum nvmlEnableState_enum +{ + NVML_FEATURE_DISABLED = 0, //!< Feature disabled + NVML_FEATURE_ENABLED = 1 //!< Feature enabled +} nvmlEnableState_t; + +//! Generic flag used to specify the default behavior of some functions. See description of particular functions for details. +#define nvmlFlagDefault 0x00 +//! Generic flag used to force some behavior. See description of particular functions for details. +#define nvmlFlagForce 0x01 + +/** + * DRAM Encryption Info + */ +typedef struct +{ + unsigned int version; //!< IN - the API version number + nvmlEnableState_t encryptionState; //!< IN/OUT - DRAM Encryption state +} nvmlDramEncryptionInfo_v1_t; +typedef nvmlDramEncryptionInfo_v1_t nvmlDramEncryptionInfo_t; + +#define nvmlDramEncryptionInfo_v1 NVML_STRUCT_VERSION(DramEncryptionInfo, 1) + +/** + * * The Brand of the GPU + * */ +typedef enum nvmlBrandType_enum +{ + NVML_BRAND_UNKNOWN = 0, + NVML_BRAND_QUADRO = 1, + NVML_BRAND_TESLA = 2, + NVML_BRAND_NVS = 3, + NVML_BRAND_GRID = 4, // Deprecated from API reporting. Keeping definition for backward compatibility. + NVML_BRAND_GEFORCE = 5, + NVML_BRAND_TITAN = 6, + NVML_BRAND_NVIDIA_VAPPS = 7, // NVIDIA Virtual Applications + NVML_BRAND_NVIDIA_VPC = 8, // NVIDIA Virtual PC + NVML_BRAND_NVIDIA_VCS = 9, // NVIDIA Virtual Compute Server + NVML_BRAND_NVIDIA_VWS = 10, // NVIDIA RTX Virtual Workstation + NVML_BRAND_NVIDIA_CLOUD_GAMING = 11, // NVIDIA Cloud Gaming + NVML_BRAND_NVIDIA_VGAMING = NVML_BRAND_NVIDIA_CLOUD_GAMING, // Deprecated from API reporting. Keeping definition for backward compatibility. + NVML_BRAND_QUADRO_RTX = 12, + NVML_BRAND_NVIDIA_RTX = 13, + NVML_BRAND_NVIDIA = 14, + NVML_BRAND_GEFORCE_RTX = 15, // Unused + NVML_BRAND_TITAN_RTX = 16, // Unused + // Keep this last + NVML_BRAND_COUNT = 18, +} nvmlBrandType_t; + +/** + * Temperature thresholds. + */ +typedef enum nvmlTemperatureThresholds_enum +{ + NVML_TEMPERATURE_THRESHOLD_SHUTDOWN = 0, // Temperature at which the GPU will + // shut down for HW protection + NVML_TEMPERATURE_THRESHOLD_SLOWDOWN = 1, // Temperature at which the GPU will + // begin HW slowdown + NVML_TEMPERATURE_THRESHOLD_MEM_MAX = 2, // Memory Temperature at which the GPU will + // begin SW slowdown + NVML_TEMPERATURE_THRESHOLD_GPU_MAX = 3, // GPU Temperature at which the GPU + // can be throttled below base clock + NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MIN = 4, // Minimum GPU Temperature that can be + // set as acoustic threshold + NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_CURR = 5, // Current temperature that is set as + // acoustic threshold. + NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_MAX = 6, // Maximum GPU temperature that can be + // set as acoustic threshold. + NVML_TEMPERATURE_THRESHOLD_GPS_CURR = 7, // Current temperature that is set as + // gps threshold. + // Keep this last + NVML_TEMPERATURE_THRESHOLD_COUNT +} nvmlTemperatureThresholds_t; + +/** + * Temperature sensors. + */ +typedef enum nvmlTemperatureSensors_enum +{ + NVML_TEMPERATURE_GPU = 0, //!< Temperature sensor for the GPU die + + // Keep this last + NVML_TEMPERATURE_COUNT +} nvmlTemperatureSensors_t; + +/** + * Margin temperature values + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + int marginTemperature; //!< The margin temperature value +} nvmlMarginTemperature_v1_t; + +typedef nvmlMarginTemperature_v1_t nvmlMarginTemperature_t; + +#define nvmlMarginTemperature_v1 NVML_STRUCT_VERSION(MarginTemperature, 1) + +/** + * Compute mode. + * + * NVML_COMPUTEMODE_EXCLUSIVE_PROCESS was added in CUDA 4.0. + * Earlier CUDA versions supported a single exclusive mode, + * which is equivalent to NVML_COMPUTEMODE_EXCLUSIVE_THREAD in CUDA 4.0 and beyond. + */ +typedef enum nvmlComputeMode_enum +{ + NVML_COMPUTEMODE_DEFAULT = 0, //!< Default compute mode -- multiple contexts per device + NVML_COMPUTEMODE_EXCLUSIVE_THREAD = 1, //!< Support Removed + NVML_COMPUTEMODE_PROHIBITED = 2, //!< Compute-prohibited mode -- no contexts per device + NVML_COMPUTEMODE_EXCLUSIVE_PROCESS = 3, //!< Compute-exclusive-process mode -- only one context per device, usable from multiple threads at a time + + // Keep this last + NVML_COMPUTEMODE_COUNT +} nvmlComputeMode_t; + +/** + * Max Clock Monitors available + */ +#define MAX_CLK_DOMAINS 32 + +/** + * Clock Monitor error types + */ +typedef struct nvmlClkMonFaultInfo_struct { + /** + * The Domain which faulted + */ + unsigned int clkApiDomain; + + /** + * Faults Information + */ + unsigned int clkDomainFaultMask; +} nvmlClkMonFaultInfo_t; + +/** + * Clock Monitor Status + */ +typedef struct nvmlClkMonStatus_status { + /** + * Fault status Indicator + */ + unsigned int bGlobalStatus; + + /** + * Total faulted domain numbers + */ + unsigned int clkMonListSize; + + /** + * The fault Information structure + */ + nvmlClkMonFaultInfo_t clkMonList[MAX_CLK_DOMAINS]; +} nvmlClkMonStatus_t; + +/** + * ECC bit types. + * + * @deprecated See \ref nvmlMemoryErrorType_t for a more flexible type + */ +#define nvmlEccBitType_t nvmlMemoryErrorType_t + +/** + * Single bit ECC errors + * + * @deprecated Mapped to \ref NVML_MEMORY_ERROR_TYPE_CORRECTED + */ +#define NVML_SINGLE_BIT_ECC NVML_MEMORY_ERROR_TYPE_CORRECTED + +/** + * Double bit ECC errors + * + * @deprecated Mapped to \ref NVML_MEMORY_ERROR_TYPE_UNCORRECTED + */ +#define NVML_DOUBLE_BIT_ECC NVML_MEMORY_ERROR_TYPE_UNCORRECTED + +/** + * Memory error types + */ +typedef enum nvmlMemoryErrorType_enum +{ + /** + * A memory error that was corrected + * + * For ECC errors, these are single bit errors + * For Texture memory, these are errors fixed by resend + */ + NVML_MEMORY_ERROR_TYPE_CORRECTED = 0, + /** + * A memory error that was not corrected + * + * For ECC errors, these are double bit errors + * For Texture memory, these are errors where the resend fails + */ + NVML_MEMORY_ERROR_TYPE_UNCORRECTED = 1, + + // Keep this last + NVML_MEMORY_ERROR_TYPE_COUNT //!< Count of memory error types + +} nvmlMemoryErrorType_t; + +/** + * Represents Nvlink Version + */ +typedef enum nvmlNvlinkVersion_enum +{ + NVML_NVLINK_VERSION_INVALID = 0, + NVML_NVLINK_VERSION_1_0 = 1, + NVML_NVLINK_VERSION_2_0 = 2, + NVML_NVLINK_VERSION_2_2 = 3, + NVML_NVLINK_VERSION_3_0 = 4, + NVML_NVLINK_VERSION_3_1 = 5, + NVML_NVLINK_VERSION_4_0 = 6, + NVML_NVLINK_VERSION_5_0 = 7, +}nvmlNvlinkVersion_t; + +/** + * ECC counter types. + * + * Note: Volatile counts are reset each time the driver loads. On Windows this is once per boot. On Linux this can be more frequent. + * On Linux the driver unloads when no active clients exist. If persistence mode is enabled or there is always a driver + * client active (e.g. X11), then Linux also sees per-boot behavior. If not, volatile counts are reset each time a compute app + * is run. + */ +typedef enum nvmlEccCounterType_enum +{ + NVML_VOLATILE_ECC = 0, //!< Volatile counts are reset each time the driver loads. + NVML_AGGREGATE_ECC = 1, //!< Aggregate counts persist across reboots (i.e. for the lifetime of the device) + + // Keep this last + NVML_ECC_COUNTER_TYPE_COUNT //!< Count of memory counter types +} nvmlEccCounterType_t; + +/** + * Clock types. + * + * All speeds are in Mhz. + */ +typedef enum nvmlClockType_enum +{ + NVML_CLOCK_GRAPHICS = 0, //!< Graphics clock domain + NVML_CLOCK_SM = 1, //!< SM clock domain + NVML_CLOCK_MEM = 2, //!< Memory clock domain + NVML_CLOCK_VIDEO = 3, //!< Video encoder/decoder clock domain + + // Keep this last + NVML_CLOCK_COUNT //!< Count of clock types +} nvmlClockType_t; + +/** + * Clock Ids. These are used in combination with nvmlClockType_t + * to specify a single clock value. + */ +typedef enum nvmlClockId_enum +{ + NVML_CLOCK_ID_CURRENT = 0, //!< Current actual clock value + NVML_CLOCK_ID_APP_CLOCK_TARGET = 1, //!< Target application clock. + //!< Deprecated, do not use. + NVML_CLOCK_ID_APP_CLOCK_DEFAULT = 2, //!< Default application clock target + //!< Deprecated, do not use. + NVML_CLOCK_ID_CUSTOMER_BOOST_MAX = 3, //!< OEM-defined maximum clock rate + + //Keep this last + NVML_CLOCK_ID_COUNT //!< Count of Clock Ids. +} nvmlClockId_t; + +/** + * Driver models. + * + * Windows only. + */ + +typedef enum nvmlDriverModel_enum +{ + NVML_DRIVER_WDDM = 0, //!< WDDM driver model -- GPU treated as a display device + NVML_DRIVER_WDM = 1, //!< WDM (TCC) model (deprecated) -- GPU treated as a generic compute device + NVML_DRIVER_MCDM = 2 //!< MCDM driver model -- GPU treated as a Microsoft compute device +} nvmlDriverModel_t; + +#define NVML_MAX_GPU_PERF_PSTATES 16 + +/** + * Allowed PStates. + */ +typedef enum nvmlPStates_enum +{ + NVML_PSTATE_0 = 0, //!< Performance state 0 -- Maximum Performance + NVML_PSTATE_1 = 1, //!< Performance state 1 + NVML_PSTATE_2 = 2, //!< Performance state 2 + NVML_PSTATE_3 = 3, //!< Performance state 3 + NVML_PSTATE_4 = 4, //!< Performance state 4 + NVML_PSTATE_5 = 5, //!< Performance state 5 + NVML_PSTATE_6 = 6, //!< Performance state 6 + NVML_PSTATE_7 = 7, //!< Performance state 7 + NVML_PSTATE_8 = 8, //!< Performance state 8 + NVML_PSTATE_9 = 9, //!< Performance state 9 + NVML_PSTATE_10 = 10, //!< Performance state 10 + NVML_PSTATE_11 = 11, //!< Performance state 11 + NVML_PSTATE_12 = 12, //!< Performance state 12 + NVML_PSTATE_13 = 13, //!< Performance state 13 + NVML_PSTATE_14 = 14, //!< Performance state 14 + NVML_PSTATE_15 = 15, //!< Performance state 15 -- Minimum Performance + NVML_PSTATE_UNKNOWN = 32 //!< Unknown performance state +} nvmlPstates_t; + +/** + * Clock offset info. + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + nvmlClockType_t type; + nvmlPstates_t pstate; + int clockOffsetMHz; + int minClockOffsetMHz; + int maxClockOffsetMHz; +} nvmlClockOffset_v1_t; + +typedef nvmlClockOffset_v1_t nvmlClockOffset_t; + +#define nvmlClockOffset_v1 NVML_STRUCT_VERSION(ClockOffset, 1) + +/** + * Fan speed info. + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int fan; //!< the fan index + unsigned int speed; //!< OUT: the fan speed in RPM +} nvmlFanSpeedInfo_v1_t; +typedef nvmlFanSpeedInfo_v1_t nvmlFanSpeedInfo_t; + +#define nvmlFanSpeedInfo_v1 NVML_STRUCT_VERSION(FanSpeedInfo, 1) + +#define NVML_PERF_MODES_BUFFER_SIZE 2048 + +/** + * Device performance modes string + */ +typedef struct +{ + unsigned int version; //!< the API version number + char str[NVML_PERF_MODES_BUFFER_SIZE]; //!< OUT: the performance modes string. +} nvmlDevicePerfModes_v1_t; +typedef nvmlDevicePerfModes_v1_t nvmlDevicePerfModes_t; + +#define nvmlDevicePerfModes_v1 NVML_STRUCT_VERSION(DevicePerfModes, 1) + +/** + * Device current clocks string + */ +typedef struct +{ + unsigned int version; //!< the API version number + char str[NVML_PERF_MODES_BUFFER_SIZE]; //!< OUT: the current clock frequency string. +} nvmlDeviceCurrentClockFreqs_v1_t; +typedef nvmlDeviceCurrentClockFreqs_v1_t nvmlDeviceCurrentClockFreqs_t; + +#define nvmlDeviceCurrentClockFreqs_v1 NVML_STRUCT_VERSION(DeviceCurrentClockFreqs, 1) + +/** + * Device powerMizer modes + */ +#define NVML_POWER_MIZER_MODE_ADAPTIVE 0 //!< adjust GPU clocks based on GPU utilization +#define NVML_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE 1 //!< raise GPU clocks to favor maximum performance, + //!< to the extent that thermal and other constraints allow +#define NVML_POWER_MIZER_MODE_AUTO 2 //!< PowerMizer mode is driver controlled. +#define NVML_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE 3 //!< lock to GPU base clocks + +typedef struct +{ + unsigned int currentMode; //!< OUT: the current powermizer mode + unsigned int mode; //!< IN: the powermizer mode to set + unsigned int supportedPowerMizerModes; //!< OUT: Bitmask of supported powermizer modes +} nvmlDevicePowerMizerModes_v1_t; + +/** + * GPU Operation Mode + * + * GOM allows to reduce power usage and optimize GPU throughput by disabling GPU features. + * + * Each GOM is designed to meet specific user needs. + */ +typedef enum nvmlGom_enum +{ + NVML_GOM_ALL_ON = 0, //!< Everything is enabled and running at full speed + + NVML_GOM_COMPUTE = 1, //!< Designed for running only compute tasks. Graphics operations + //!< are not allowed + + NVML_GOM_LOW_DP = 2 //!< Designed for running graphics applications that don't require + //!< high bandwidth double precision +} nvmlGpuOperationMode_t; + +/** + * Available infoROM objects. + */ +typedef enum nvmlInforomObject_enum +{ + NVML_INFOROM_OEM = 0, //!< An object defined by OEM + NVML_INFOROM_ECC = 1, //!< The ECC object determining the level of ECC support + NVML_INFOROM_POWER = 2, //!< The power management object + NVML_INFOROM_DEN = 3, //!< DRAM Encryption object + // Keep this last + NVML_INFOROM_COUNT //!< This counts the number of infoROM objects the driver knows about +} nvmlInforomObject_t; + +/** + * Return values for NVML API calls. + */ +typedef enum nvmlReturn_enum +{ + // cppcheck-suppress * + NVML_SUCCESS = 0, //!< The operation was successful + NVML_ERROR_UNINITIALIZED = 1, //!< NVML was not first initialized with nvmlInit() + NVML_ERROR_INVALID_ARGUMENT = 2, //!< A supplied argument is invalid + NVML_ERROR_NOT_SUPPORTED = 3, //!< The requested operation is not available on target device + NVML_ERROR_NO_PERMISSION = 4, //!< The current user does not have permission for operation + NVML_ERROR_ALREADY_INITIALIZED = 5, //!< Deprecated: Multiple initializations are now allowed through ref counting + NVML_ERROR_NOT_FOUND = 6, //!< A query to find an object was unsuccessful + NVML_ERROR_INSUFFICIENT_SIZE = 7, //!< An input argument is not large enough + NVML_ERROR_INSUFFICIENT_POWER = 8, //!< A device's external power cables are not properly attached + NVML_ERROR_DRIVER_NOT_LOADED = 9, //!< NVIDIA driver is not loaded + NVML_ERROR_TIMEOUT = 10, //!< User provided timeout passed + NVML_ERROR_IRQ_ISSUE = 11, //!< NVIDIA Kernel detected an interrupt issue with a GPU + NVML_ERROR_LIBRARY_NOT_FOUND = 12, //!< NVML Shared Library couldn't be found or loaded + NVML_ERROR_FUNCTION_NOT_FOUND = 13, //!< Local version of NVML doesn't implement this function + NVML_ERROR_CORRUPTED_INFOROM = 14, //!< infoROM is corrupted + NVML_ERROR_GPU_IS_LOST = 15, //!< The GPU has fallen off the bus or has otherwise become inaccessible + NVML_ERROR_RESET_REQUIRED = 16, //!< The GPU requires a reset before it can be used again + NVML_ERROR_OPERATING_SYSTEM = 17, //!< The GPU control device has been blocked by the operating system/cgroups + NVML_ERROR_LIB_RM_VERSION_MISMATCH = 18, //!< RM detects a driver/library version mismatch + NVML_ERROR_IN_USE = 19, //!< An operation cannot be performed because the GPU is currently in use + NVML_ERROR_MEMORY = 20, //!< Insufficient memory + NVML_ERROR_NO_DATA = 21, //!< No data + NVML_ERROR_VGPU_ECC_NOT_SUPPORTED = 22, //!< The requested vgpu operation is not available on target device, becasue ECC is enabled + NVML_ERROR_INSUFFICIENT_RESOURCES = 23, //!< Ran out of critical resources, other than memory + NVML_ERROR_FREQ_NOT_SUPPORTED = 24, //!< Ran out of critical resources, other than memory + NVML_ERROR_ARGUMENT_VERSION_MISMATCH = 25, //!< The provided version is invalid/unsupported + NVML_ERROR_DEPRECATED = 26, //!< The requested functionality has been deprecated + NVML_ERROR_NOT_READY = 27, //!< The system is not ready for the request + NVML_ERROR_GPU_NOT_FOUND = 28, //!< No GPUs were found + NVML_ERROR_INVALID_STATE = 29, //!< Resource not in correct state to perform requested operation + NVML_ERROR_RESET_TYPE_NOT_SUPPORTED = 30, //!< Reset not supported for given device/parameters + NVML_ERROR_UNKNOWN = 999 //!< An internal driver error occurred +} nvmlReturn_t; + +/** + * See \ref nvmlDeviceGetMemoryErrorCounter + */ +typedef enum nvmlMemoryLocation_enum +{ + NVML_MEMORY_LOCATION_L1_CACHE = 0, //!< GPU L1 Cache + NVML_MEMORY_LOCATION_L2_CACHE = 1, //!< GPU L2 Cache + NVML_MEMORY_LOCATION_DRAM = 2, //!< Turing+ DRAM + NVML_MEMORY_LOCATION_DEVICE_MEMORY = 2, //!< GPU Device Memory + NVML_MEMORY_LOCATION_REGISTER_FILE = 3, //!< GPU Register File + NVML_MEMORY_LOCATION_TEXTURE_MEMORY = 4, //!< GPU Texture Memory + NVML_MEMORY_LOCATION_TEXTURE_SHM = 5, //!< Shared memory + NVML_MEMORY_LOCATION_CBU = 6, //!< CBU + NVML_MEMORY_LOCATION_SRAM = 7, //!< Turing+ SRAM + // Keep this last + NVML_MEMORY_LOCATION_COUNT //!< This counts the number of memory locations the driver knows about +} nvmlMemoryLocation_t; + +/** + * Causes for page retirement + */ +typedef enum nvmlPageRetirementCause_enum +{ + NVML_PAGE_RETIREMENT_CAUSE_MULTIPLE_SINGLE_BIT_ECC_ERRORS = 0, //!< Page was retired due to multiple single bit ECC error + NVML_PAGE_RETIREMENT_CAUSE_DOUBLE_BIT_ECC_ERROR = 1, //!< Page was retired due to double bit ECC error + + // Keep this last + NVML_PAGE_RETIREMENT_CAUSE_COUNT +} nvmlPageRetirementCause_t; + +/** + * API types that allow changes to default permission restrictions + */ +typedef enum nvmlRestrictedAPI_enum +{ + NVML_RESTRICTED_API_SET_APPLICATION_CLOCKS = 0, //!< APIs that change application clocks, see nvmlDeviceSetApplicationsClocks + //!< and see nvmlDeviceResetApplicationsClocks. + //!< Deprecated, keeping definition for backward compatibility. + NVML_RESTRICTED_API_SET_AUTO_BOOSTED_CLOCKS = 1, //!< APIs that enable/disable Auto Boosted clocks + //!< see nvmlDeviceSetAutoBoostedClocksEnabled + // Keep this last + NVML_RESTRICTED_API_COUNT +} nvmlRestrictedAPI_t; + +/** + * Structure to store utilization value and process Id + */ +typedef struct nvmlProcessUtilizationSample_st +{ + unsigned int pid; //!< PID of process + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value +} nvmlProcessUtilizationSample_t; + +/** + * Structure to store utilization value and process Id -- version 1 + */ +typedef struct +{ + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + unsigned int pid; //!< PID of process + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value + unsigned int jpgUtil; //!< Jpeg Util Value + unsigned int ofaUtil; //!< Ofa Util Value +} nvmlProcessUtilizationInfo_v1_t; + +/** + * Structure to store utilization and process ID for each running process -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int processSamplesCount; //!< Caller-supplied array size, and returns number of processes running + unsigned long long lastSeenTimeStamp; //!< Return only samples with timestamp greater than lastSeenTimeStamp + nvmlProcessUtilizationInfo_v1_t *procUtilArray; //!< The array (allocated by caller) of the utilization of GPU SM, framebuffer, video encoder, video decoder, JPEG, and OFA +} nvmlProcessesUtilizationInfo_v1_t; +typedef nvmlProcessesUtilizationInfo_v1_t nvmlProcessesUtilizationInfo_t; +#define nvmlProcessesUtilizationInfo_v1 NVML_STRUCT_VERSION(ProcessesUtilizationInfo, 1) + +/** + * Structure to store SRAM uncorrectable error counters + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned long long aggregateUncParity; //!< aggregate uncorrectable parity error count + unsigned long long aggregateUncSecDed; //!< aggregate uncorrectable SEC-DED error count + unsigned long long aggregateCor; //!< aggregate correctable error count + unsigned long long volatileUncParity; //!< volatile uncorrectable parity error count + unsigned long long volatileUncSecDed; //!< volatile uncorrectable SEC-DED error count + unsigned long long volatileCor; //!< volatile correctable error count + unsigned long long aggregateUncBucketL2; //!< aggregate uncorrectable error count for L2 cache bucket + unsigned long long aggregateUncBucketSm; //!< aggregate uncorrectable error count for SM bucket + unsigned long long aggregateUncBucketPcie; //!< aggregate uncorrectable error count for PCIE bucket + unsigned long long aggregateUncBucketMcu; //!< aggregate uncorrectable error count for Microcontroller bucket + unsigned long long aggregateUncBucketOther; //!< aggregate uncorrectable error count for Other bucket + unsigned int bThresholdExceeded; //!< if the error threshold of field diag is exceeded +} nvmlEccSramErrorStatus_v1_t; + +typedef nvmlEccSramErrorStatus_v1_t nvmlEccSramErrorStatus_t; +#define nvmlEccSramErrorStatus_v1 NVML_STRUCT_VERSION(EccSramErrorStatus, 1) + +/** + * Structure to store platform information + * + * @deprecated The nvmlPlatformInfo_v1_t will be deprecated in the subsequent releases. + * Use nvmlPlatformInfo_v2_t + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned char ibGuid[16]; //!< Infiniband GUID reported by platform (for Blackwell, ibGuid is 8 bytes so indices 8-15 are zero) + unsigned char rackGuid[16]; //!< GUID of the rack containing this GPU (for Blackwell rackGuid is 13 bytes so indices 13-15 are zero) + unsigned char chassisPhysicalSlotNumber; //!< The slot number in the rack containing this GPU (includes switches) + unsigned char computeSlotIndex; //!< The index within the compute slots in the rack containing this GPU (does not include switches) + unsigned char nodeIndex; //!< Index of the node within the slot containing this GPU + unsigned char peerType; //!< Platform indicated NVLink-peer type (e.g. switch present or not) + unsigned char moduleId; //!< ID of this GPU within the node +} nvmlPlatformInfo_v1_t; +#define nvmlPlatformInfo_v1 NVML_STRUCT_VERSION(PlatformInfo, 1) + +/** + * Structure to store platform information (v2) + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned char ibGuid[16]; //!< Infiniband GUID reported by platform (for Blackwell, ibGuid is 8 bytes so indices 8-15 are zero) + unsigned char chassisSerialNumber[16]; //!< Serial number of the chassis containing this GPU (for Blackwell it is 13 bytes so indices 13-15 are zero) + unsigned char slotNumber; //!< The slot number in the chassis containing this GPU (includes switches) + unsigned char trayIndex; //!< The tray index within the compute slots in the chassis containing this GPU (does not include switches) + unsigned char hostId; //!< Index of the node within the slot containing this GPU + unsigned char peerType; //!< Platform indicated NVLink-peer type (e.g. switch present or not) + unsigned char moduleId; //!< ID of this GPU within the node +} nvmlPlatformInfo_v2_t; + +typedef nvmlPlatformInfo_v2_t nvmlPlatformInfo_t; +#define nvmlPlatformInfo_v2 NVML_STRUCT_VERSION(PlatformInfo, 2) + +/** + * Structure to store hostname information + */ +#define NVML_DEVICE_HOSTNAME_BUFFER_SIZE 64 + +typedef struct +{ + char value[NVML_DEVICE_HOSTNAME_BUFFER_SIZE]; //!< null-terminated hostname string +} nvmlHostname_v1_t; + +typedef struct +{ + unsigned int unit; //!< the SRAM unit index + unsigned int location; //!< the error location within the SRAM unit + unsigned int sublocation; //!< the error sublocation within the SRAM unit + unsigned int extlocation; //!< the error extlocation within the SRAM unit + unsigned int address; //!< the error address within the SRAM unit + unsigned int isParity; //!< if the SRAM error is parity or not + unsigned int count; //!< the error count at the same SRAM address +} nvmlEccSramUniqueUncorrectedErrorEntry_v1_t; + +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int entryCount; //!< the number of error count entries + nvmlEccSramUniqueUncorrectedErrorEntry_v1_t *entries; //!< pointer to caller-supplied buffer to return the SRAM unique uncorrected ECC error count entries +} nvmlEccSramUniqueUncorrectedErrorCounts_v1_t; + +typedef nvmlEccSramUniqueUncorrectedErrorCounts_v1_t nvmlEccSramUniqueUncorrectedErrorCounts_t; +#define nvmlEccSramUniqueUncorrectedErrorCounts_v1 NVML_STRUCT_VERSION(EccSramUniqueUncorrectedErrorCounts, 1) + +/** + * GSP firmware + */ +#define NVML_GSP_FIRMWARE_VERSION_BUF_SIZE 0x40 + +/** + * Simplified chip architecture + */ +#define NVML_DEVICE_ARCH_KEPLER 2 // Devices based on the NVIDIA Kepler architecture +#define NVML_DEVICE_ARCH_MAXWELL 3 // Devices based on the NVIDIA Maxwell architecture +#define NVML_DEVICE_ARCH_PASCAL 4 // Devices based on the NVIDIA Pascal architecture +#define NVML_DEVICE_ARCH_VOLTA 5 // Devices based on the NVIDIA Volta architecture +#define NVML_DEVICE_ARCH_TURING 6 // Devices based on the NVIDIA Turing architecture +#define NVML_DEVICE_ARCH_AMPERE 7 // Devices based on the NVIDIA Ampere architecture +#define NVML_DEVICE_ARCH_ADA 8 // Devices based on the NVIDIA Ada architecture +#define NVML_DEVICE_ARCH_HOPPER 9 // Devices based on the NVIDIA Hopper architecture + +#define NVML_DEVICE_ARCH_BLACKWELL 10 // Devices based on the NVIDIA Blackwell architecture + +#define NVML_DEVICE_ARCH_UNKNOWN 0xffffffff // Anything else, presumably something newer + +typedef unsigned int nvmlDeviceArchitecture_t; + +/** + * PCI bus types + */ +#define NVML_BUS_TYPE_UNKNOWN 0 +#define NVML_BUS_TYPE_PCI 1 +#define NVML_BUS_TYPE_PCIE 2 +#define NVML_BUS_TYPE_FPCI 3 +#define NVML_BUS_TYPE_AGP 4 + +typedef unsigned int nvmlBusType_t; + +/** + * Device Power Modes + */ + +/** + * Device Fan control policy + */ +#define NVML_FAN_POLICY_TEMPERATURE_CONTINOUS_SW 0 +#define NVML_FAN_POLICY_MANUAL 1 + +typedef unsigned int nvmlFanControlPolicy_t; + +/** + * Device Power Source + */ +#define NVML_POWER_SOURCE_AC 0x00000000 +#define NVML_POWER_SOURCE_BATTERY 0x00000001 +#define NVML_POWER_SOURCE_UNDERSIZED 0x00000002 + +typedef unsigned int nvmlPowerSource_t; + +/** + * Device PCIE link Max Speed + */ +#define NVML_PCIE_LINK_MAX_SPEED_INVALID 0x00000000 +#define NVML_PCIE_LINK_MAX_SPEED_2500MBPS 0x00000001 +#define NVML_PCIE_LINK_MAX_SPEED_5000MBPS 0x00000002 +#define NVML_PCIE_LINK_MAX_SPEED_8000MBPS 0x00000003 +#define NVML_PCIE_LINK_MAX_SPEED_16000MBPS 0x00000004 +#define NVML_PCIE_LINK_MAX_SPEED_32000MBPS 0x00000005 +#define NVML_PCIE_LINK_MAX_SPEED_64000MBPS 0x00000006 + +/** + * Adaptive clocking status + */ +#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED 0x00000000 +#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED 0x00000001 + +#define NVML_MAX_GPU_UTILIZATIONS 8 + +/** + * Represents the GPU utilization domains + */ +typedef enum nvmlGpuUtilizationDomainId_t +{ + NVML_GPU_UTILIZATION_DOMAIN_GPU = 0, //!< Graphics engine domain + NVML_GPU_UTILIZATION_DOMAIN_FB = 1, //!< Frame buffer domain + NVML_GPU_UTILIZATION_DOMAIN_VID = 2, //!< Video engine domain + NVML_GPU_UTILIZATION_DOMAIN_BUS = 3, //!< Bus interface domain +} nvmlGpuUtilizationDomainId_t; + +typedef struct nvmlGpuDynamicPstatesInfo_st +{ + unsigned int flags; //!< Reserved for future use + struct + { + unsigned int bIsPresent; //!< Set if this utilization domain is present on this GPU + unsigned int percentage; //!< Percentage of time where the domain is considered busy in the last 1-second interval + unsigned int incThreshold; //!< Utilization threshold that can trigger a perf-increasing P-State change when crossed + unsigned int decThreshold; //!< Utilization threshold that can trigger a perf-decreasing P-State change when crossed + } utilization[NVML_MAX_GPU_UTILIZATIONS]; +} nvmlGpuDynamicPstatesInfo_t; + +/* + * PCIe outbound/inbound atomic operations capability + */ +#define NVML_PCIE_ATOMICS_CAP_FETCHADD32 0x01 +#define NVML_PCIE_ATOMICS_CAP_FETCHADD64 0x02 +#define NVML_PCIE_ATOMICS_CAP_SWAP32 0x04 +#define NVML_PCIE_ATOMICS_CAP_SWAP64 0x08 +#define NVML_PCIE_ATOMICS_CAP_CAS32 0x10 +#define NVML_PCIE_ATOMICS_CAP_CAS64 0x20 +#define NVML_PCIE_ATOMICS_CAP_CAS128 0x40 +#define NVML_PCIE_ATOMICS_OPS_MAX 7 + +/** + * Device Scope - This is useful to retrieve the telemetry at GPU and module (e.g. GPU + CPU) level + */ +#define NVML_POWER_SCOPE_GPU 0U //!< Targets only GPU +#define NVML_POWER_SCOPE_MODULE 1U //!< Targets the whole module +#define NVML_POWER_SCOPE_MEMORY 2U //!< Targets the GPU Memory + +typedef unsigned char nvmlPowerScopeType_t; + +/** + * Contains the power management limit + */ +typedef struct +{ + unsigned int version; //!< Structure format version (must be 1) + nvmlPowerScopeType_t powerScope; //!< [in] Device type: GPU or Total Module + unsigned int powerValueMw; //!< [out] Power value to retrieve or set in milliwatts +} nvmlPowerValue_v2_t; + +#define nvmlPowerValue_v2 NVML_STRUCT_VERSION(PowerValue, 2) + +/** @} */ + +/***************************************************************************************************/ +/** @addtogroup virtualGPU vGPU Enums, Constants, Structs + * @{ + */ +/***************************************************************************************************/ +/** @defgroup nvmlVirtualGpuEnums vGPU Enums + * @{ + */ +/***************************************************************************************************/ + +/*! + * GPU virtualization mode types. + */ +typedef enum nvmlGpuVirtualizationMode { + NVML_GPU_VIRTUALIZATION_MODE_NONE = 0, //!< Represents Bare Metal GPU + NVML_GPU_VIRTUALIZATION_MODE_PASSTHROUGH = 1, //!< Device is associated with GPU-Passthorugh + NVML_GPU_VIRTUALIZATION_MODE_VGPU = 2, //!< Device is associated with vGPU inside virtual machine. + NVML_GPU_VIRTUALIZATION_MODE_HOST_VGPU = 3, //!< Device is associated with VGX hypervisor in vGPU mode + NVML_GPU_VIRTUALIZATION_MODE_HOST_VSGA = 4 //!< Device is associated with VGX hypervisor in vSGA mode +} nvmlGpuVirtualizationMode_t; + +/** + * Host vGPU modes + */ +typedef enum nvmlHostVgpuMode_enum +{ + NVML_HOST_VGPU_MODE_NON_SRIOV = 0, //!< Non SR-IOV mode + NVML_HOST_VGPU_MODE_SRIOV = 1 //!< SR-IOV mode +} nvmlHostVgpuMode_t; + +/*! + * Types of VM identifiers + */ +typedef enum nvmlVgpuVmIdType { + NVML_VGPU_VM_ID_DOMAIN_ID = 0, //!< VM ID represents DOMAIN ID + NVML_VGPU_VM_ID_UUID = 1 //!< VM ID represents UUID +} nvmlVgpuVmIdType_t; + +/** + * vGPU GUEST info state + */ +typedef enum nvmlVgpuGuestInfoState_enum +{ + NVML_VGPU_INSTANCE_GUEST_INFO_STATE_UNINITIALIZED = 0, //!< Guest-dependent fields uninitialized + NVML_VGPU_INSTANCE_GUEST_INFO_STATE_INITIALIZED = 1 //!< Guest-dependent fields initialized +} nvmlVgpuGuestInfoState_t; + +/** + * vGPU software licensable features + */ +typedef enum { + NVML_GRID_LICENSE_FEATURE_CODE_UNKNOWN = 0, //!< Unknown + NVML_GRID_LICENSE_FEATURE_CODE_VGPU = 1, //!< Virtual GPU + NVML_GRID_LICENSE_FEATURE_CODE_NVIDIA_RTX = 2, //!< Nvidia RTX + NVML_GRID_LICENSE_FEATURE_CODE_VWORKSTATION = NVML_GRID_LICENSE_FEATURE_CODE_NVIDIA_RTX, //!< Deprecated, do not use. + NVML_GRID_LICENSE_FEATURE_CODE_GAMING = 3, //!< Gaming + NVML_GRID_LICENSE_FEATURE_CODE_COMPUTE = 4 //!< Compute +} nvmlGridLicenseFeatureCode_t; + +/** + * Status codes for license expiry + */ +#define NVML_GRID_LICENSE_EXPIRY_NOT_AVAILABLE 0 //!< Expiry information not available +#define NVML_GRID_LICENSE_EXPIRY_INVALID 1 //!< Invalid expiry or error fetching expiry +#define NVML_GRID_LICENSE_EXPIRY_VALID 2 //!< Valid expiry +#define NVML_GRID_LICENSE_EXPIRY_NOT_APPLICABLE 3 //!< Expiry not applicable +#define NVML_GRID_LICENSE_EXPIRY_PERMANENT 4 //!< Permanent expiry + +/** + * vGPU queryable capabilities + */ +typedef enum nvmlVgpuCapability_enum +{ + NVML_VGPU_CAP_NVLINK_P2P = 0, //!< P2P over NVLink is supported + NVML_VGPU_CAP_GPUDIRECT = 1, //!< GPUDirect capability is supported + NVML_VGPU_CAP_MULTI_VGPU_EXCLUSIVE = 2, //!< vGPU profile cannot be mixed with other vGPU profiles in same VM + NVML_VGPU_CAP_EXCLUSIVE_TYPE = 3, //!< vGPU profile cannot run on a GPU alongside other profiles of different type + NVML_VGPU_CAP_EXCLUSIVE_SIZE = 4, //!< vGPU profile cannot run on a GPU alongside other profiles of different size + // Keep this last + NVML_VGPU_CAP_COUNT +} nvmlVgpuCapability_t; + +/** +* vGPU driver queryable capabilities +*/ +typedef enum nvmlVgpuDriverCapability_enum +{ + NVML_VGPU_DRIVER_CAP_HETEROGENEOUS_MULTI_VGPU = 0, //!< Supports mixing of different vGPU profiles within one guest VM + NVML_VGPU_DRIVER_CAP_WARM_UPDATE = 1, //!< Supports FSR and warm update of vGPU host driver without terminating the running guest VM + // Keep this last + NVML_VGPU_DRIVER_CAP_COUNT +} nvmlVgpuDriverCapability_t; + +/** +* Device vGPU queryable capabilities +*/ +typedef enum nvmlDeviceVgpuCapability_enum +{ + NVML_DEVICE_VGPU_CAP_FRACTIONAL_MULTI_VGPU = 0, //!< Query whether the fractional vGPU profiles on this GPU can be used in multi-vGPU configurations + NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_PROFILES = 1, //!< Query whether the GPU support concurrent execution of timesliced vGPU profiles of differing types + NVML_DEVICE_VGPU_CAP_HETEROGENEOUS_TIMESLICE_SIZES = 2, //!< Query whether the GPU support concurrent execution of timesliced vGPU profiles of differing framebuffer sizes + NVML_DEVICE_VGPU_CAP_READ_DEVICE_BUFFER_BW = 3, //!< Query the GPU's read_device_buffer expected bandwidth capacity in megabytes per second + NVML_DEVICE_VGPU_CAP_WRITE_DEVICE_BUFFER_BW = 4, //!< Query the GPU's write_device_buffer expected bandwidth capacity in megabytes per second + NVML_DEVICE_VGPU_CAP_DEVICE_STREAMING = 5, //!< Query whether the vGPU profiles on the GPU supports migration data streaming + NVML_DEVICE_VGPU_CAP_MINI_QUARTER_GPU = 6, //!< Set/Get support for mini-quarter vGPU profiles + NVML_DEVICE_VGPU_CAP_COMPUTE_MEDIA_ENGINE_GPU = 7, //!< Set/Get support for compute media engine vGPU profiles + NVML_DEVICE_VGPU_CAP_WARM_UPDATE = 8, //!< Query whether the GPU supports FSR and warm update + NVML_DEVICE_VGPU_CAP_HOMOGENEOUS_PLACEMENTS = 9, //!< Query whether the GPU supports reporting of placements of timesliced vGPU profiles with identical framebuffer sizes + NVML_DEVICE_VGPU_CAP_MIG_TIMESLICING_SUPPORTED = 10, //!< Query whether the GPU supports timesliced vGPU on MIG + NVML_DEVICE_VGPU_CAP_MIG_TIMESLICING_ENABLED = 11, //!< Set/Get MIG timesliced mode reporting, without impacting the underlying functionality + // Keep this last + NVML_DEVICE_VGPU_CAP_COUNT +} nvmlDeviceVgpuCapability_t; + +/** @} */ + +/***************************************************************************************************/ + +/** @defgroup nvmlVgpuConstants vGPU Constants + * @{ + */ +/***************************************************************************************************/ + +/** + * Buffer size guaranteed to be large enough for \ref nvmlVgpuTypeGetLicense + */ +#define NVML_GRID_LICENSE_BUFFER_SIZE 128 + +#define NVML_VGPU_NAME_BUFFER_SIZE 64 + +#define NVML_GRID_LICENSE_FEATURE_MAX_COUNT 3 + +#define INVALID_GPU_INSTANCE_PROFILE_ID 0xFFFFFFFF + +#define INVALID_GPU_INSTANCE_ID 0xFFFFFFFF + +#define NVML_INVALID_VGPU_PLACEMENT_ID 0xFFFF + +/*! + * Macros for vGPU instance's virtualization capabilities bitfield. + */ +#define NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION 0:0 +#define NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_NO 0x0 +#define NVML_VGPU_VIRTUALIZATION_CAP_MIGRATION_YES 0x1 + +/*! + * Macros for pGPU's virtualization capabilities bitfield. + */ +#define NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION 0:0 +#define NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_NO 0x0 +#define NVML_VGPU_PGPU_VIRTUALIZATION_CAP_MIGRATION_YES 0x1 + +/** + * Macros to indicate the vGPU mode of the GPU. + */ +#define NVML_VGPU_PGPU_HETEROGENEOUS_MODE 0 +#define NVML_VGPU_PGPU_HOMOGENEOUS_MODE 1 + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVgpuStructs vGPU Structs + * @{ + */ +/***************************************************************************************************/ + +typedef unsigned int nvmlVgpuTypeId_t; + +typedef unsigned int nvmlVgpuInstance_t; + +/** + * Structure to store the vGPU heterogeneous mode of device -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int mode; //!< The vGPU heterogeneous mode +} nvmlVgpuHeterogeneousMode_v1_t; +typedef nvmlVgpuHeterogeneousMode_v1_t nvmlVgpuHeterogeneousMode_t; +#define nvmlVgpuHeterogeneousMode_v1 NVML_STRUCT_VERSION(VgpuHeterogeneousMode, 1) + +/** + * Structure to store the placement ID of vGPU instance -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int placementId; //!< Placement ID of the active vGPU instance +} nvmlVgpuPlacementId_v1_t; +typedef nvmlVgpuPlacementId_v1_t nvmlVgpuPlacementId_t; +#define nvmlVgpuPlacementId_v1 NVML_STRUCT_VERSION(VgpuPlacementId, 1) + +/** + * Structure to store the list of vGPU placements -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int placementSize; //!< The number of slots occupied by the vGPU type + unsigned int count; //!< Count of placement IDs fetched + unsigned int *placementIds; //!< Placement IDs for the vGPU type +} nvmlVgpuPlacementList_v1_t; +#define nvmlVgpuPlacementList_v1 NVML_STRUCT_VERSION(VgpuPlacementList, 1) + +/** + * Structure to store the list of vGPU placements -- version 2 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int placementSize; //!< OUT: The number of slots occupied by the vGPU type + unsigned int count; //!< IN/OUT: Count of the placement IDs + unsigned int *placementIds; //!< IN/OUT: Placement IDs for the vGPU type + unsigned int mode; //!< IN: The vGPU mode. Either NVML_VGPU_PGPU_HETEROGENEOUS_MODE or NVML_VGPU_PGPU_HOMOGENEOUS_MODE +} nvmlVgpuPlacementList_v2_t; +typedef nvmlVgpuPlacementList_v2_t nvmlVgpuPlacementList_t; +#define nvmlVgpuPlacementList_v2 NVML_STRUCT_VERSION(VgpuPlacementList, 2) + +/** + * Structure to store BAR1 size information of vGPU type -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned long long bar1Size; //!< BAR1 size in megabytes +} nvmlVgpuTypeBar1Info_v1_t; +typedef nvmlVgpuTypeBar1Info_v1_t nvmlVgpuTypeBar1Info_t; +#define nvmlVgpuTypeBar1Info_v1 NVML_STRUCT_VERSION(VgpuTypeBar1Info, 1) + +/** + * Structure to store Utilization Value and vgpuInstance + */ +typedef struct nvmlVgpuInstanceUtilizationSample_st +{ + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlValue_t smUtil; //!< SM (3D/Compute) Util Value + nvmlValue_t memUtil; //!< Frame Buffer Memory Util Value + nvmlValue_t encUtil; //!< Encoder Util Value + nvmlValue_t decUtil; //!< Decoder Util Value +} nvmlVgpuInstanceUtilizationSample_t; + +/** + * Structure to store Utilization Value and vgpuInstance Info -- Version 1 + */ +typedef struct +{ + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + nvmlValue_t smUtil; //!< SM (3D/Compute) Util Value + nvmlValue_t memUtil; //!< Frame Buffer Memory Util Value + nvmlValue_t encUtil; //!< Encoder Util Value + nvmlValue_t decUtil; //!< Decoder Util Value + nvmlValue_t jpgUtil; //!< Jpeg Util Value + nvmlValue_t ofaUtil; //!< Ofa Util Value +} nvmlVgpuInstanceUtilizationInfo_v1_t; + +/** + * Structure to store recent utilization for vGPU instances running on a device -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + nvmlValueType_t sampleValType; //!< Hold the type of returned sample values + unsigned int vgpuInstanceCount; //!< Hold the number of vGPU instances + unsigned long long lastSeenTimeStamp; //!< Return only samples with timestamp greater than lastSeenTimeStamp + nvmlVgpuInstanceUtilizationInfo_v1_t *vgpuUtilArray; //!< The array (allocated by caller) in which vGPU utilization are returned +} nvmlVgpuInstancesUtilizationInfo_v1_t; +typedef nvmlVgpuInstancesUtilizationInfo_v1_t nvmlVgpuInstancesUtilizationInfo_t; +#define nvmlVgpuInstancesUtilizationInfo_v1 NVML_STRUCT_VERSION(VgpuInstancesUtilizationInfo, 1) + +/** + * Structure to store Utilization Value, vgpuInstance and subprocess information + */ +typedef struct nvmlVgpuProcessUtilizationSample_st +{ + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + unsigned int pid; //!< PID of process running within the vGPU VM + char processName[NVML_VGPU_NAME_BUFFER_SIZE]; //!< Name of process running within the vGPU VM + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value +} nvmlVgpuProcessUtilizationSample_t; + +/** + * Structure to store Utilization Value, vgpuInstance and subprocess information for process running on vGPU instance -- version 1 + */ +typedef struct +{ + char processName[NVML_VGPU_NAME_BUFFER_SIZE]; //!< Name of process running within the vGPU VM + unsigned long long timeStamp; //!< CPU Timestamp in microseconds + nvmlVgpuInstance_t vgpuInstance; //!< vGPU Instance + unsigned int pid; //!< PID of process running within the vGPU VM + unsigned int smUtil; //!< SM (3D/Compute) Util Value + unsigned int memUtil; //!< Frame Buffer Memory Util Value + unsigned int encUtil; //!< Encoder Util Value + unsigned int decUtil; //!< Decoder Util Value + unsigned int jpgUtil; //!< Jpeg Util Value + unsigned int ofaUtil; //!< Ofa Util Value +} nvmlVgpuProcessUtilizationInfo_v1_t; + +/** + * Structure to store recent utilization, vgpuInstance and subprocess information for processes running on vGPU instances active on a device -- version 1 + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + unsigned int vgpuProcessCount; //!< Hold the number of processes running on vGPU instances + unsigned long long lastSeenTimeStamp; //!< Return only samples with timestamp greater than lastSeenTimeStamp + nvmlVgpuProcessUtilizationInfo_v1_t *vgpuProcUtilArray; //!< The array (allocated by caller) in which utilization of processes running on vGPU instances are returned +} nvmlVgpuProcessesUtilizationInfo_v1_t; +typedef nvmlVgpuProcessesUtilizationInfo_v1_t nvmlVgpuProcessesUtilizationInfo_t; +#define nvmlVgpuProcessesUtilizationInfo_v1 NVML_STRUCT_VERSION(VgpuProcessesUtilizationInfo, 1) + +/** + * Structure to store the information of vGPU runtime state -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned long long size; //!< OUT: The runtime state size of the vGPU instance +} nvmlVgpuRuntimeState_v1_t; +typedef nvmlVgpuRuntimeState_v1_t nvmlVgpuRuntimeState_t; +#define nvmlVgpuRuntimeState_v1 NVML_STRUCT_VERSION(VgpuRuntimeState, 1) + +/** + * vGPU scheduler policies + */ +#define NVML_VGPU_SCHEDULER_POLICY_UNKNOWN 0 +#define NVML_VGPU_SCHEDULER_POLICY_BEST_EFFORT 1 +#define NVML_VGPU_SCHEDULER_POLICY_EQUAL_SHARE 2 +#define NVML_VGPU_SCHEDULER_POLICY_FIXED_SHARE 3 + +#define NVML_SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT 3 + +#define NVML_SCHEDULER_SW_MAX_LOG_ENTRIES 200 + +#define NVML_VGPU_SCHEDULER_ARR_DEFAULT 0 +#define NVML_VGPU_SCHEDULER_ARR_DISABLE 1 +#define NVML_VGPU_SCHEDULER_ARR_ENABLE 2 + +/** + * vGPU scheduler engine types + */ +#define NVML_VGPU_SCHEDULER_ENGINE_TYPE_GRAPHICS 1 + +/** + * Union to represent the vGPU Scheduler Parameters + */ +typedef union +{ + struct + { + unsigned int avgFactor; //!< Average factor in compensating the timeslice for Adaptive Round Robin mode + unsigned int timeslice; //!< The timeslice in ns for each software run list as configured, or the default value otherwise + } vgpuSchedDataWithARR; + + struct + { + unsigned int timeslice; //!< The timeslice in ns for each software run list as configured, or the default value otherwise + } vgpuSchedData; + +} nvmlVgpuSchedulerParams_t; + +/** + * Structure to store the state and logs of a software runlist + */ +typedef struct nvmlVgpuSchedulerLogEntries_st +{ + unsigned long long timestamp; //!< Timestamp in ns when this software runlist was preeempted + unsigned long long timeRunTotal; //!< Total time in ns this software runlist has run + unsigned long long timeRun; //!< Time in ns this software runlist ran before preemption + unsigned int swRunlistId; //!< Software runlist Id + unsigned long long targetTimeSlice; //!< The actual timeslice after deduction + unsigned long long cumulativePreemptionTime; //!< Preemption time in ns for this SW runlist +} nvmlVgpuSchedulerLogEntry_t; + +/** + * Structure to store a vGPU software scheduler log + */ +typedef struct nvmlVgpuSchedulerLog_st +{ + unsigned int engineId; //!< Engine whose software runlist log entries are fetched + unsigned int schedulerPolicy; //!< Scheduler policy + unsigned int arrMode; //!< Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; + unsigned int entriesCount; //!< Count of log entries fetched + nvmlVgpuSchedulerLogEntry_t logEntries[NVML_SCHEDULER_SW_MAX_LOG_ENTRIES]; +} nvmlVgpuSchedulerLog_t; + +/** + * Structure to store the vGPU scheduler state + */ +typedef struct nvmlVgpuSchedulerGetState_st +{ + unsigned int schedulerPolicy; //!< Scheduler policy + unsigned int arrMode; //!< Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; +} nvmlVgpuSchedulerGetState_t; + +/** + * Union to represent the vGPU Scheduler set Parameters + */ +typedef union +{ + struct + { + unsigned int avgFactor; //!< Average factor in compensating the timeslice for Adaptive Round Robin mode + unsigned int frequency; //!< Frequency for Adaptive Round Robin mode + } vgpuSchedDataWithARR; + + struct + { + unsigned int timeslice; //!< The timeslice in ns(Nanoseconds) for each software run list as configured, or the default value otherwise + } vgpuSchedData; + +} nvmlVgpuSchedulerSetParams_t; + +/** + * Structure to set the vGPU scheduler state + */ +typedef struct nvmlVgpuSchedulerSetState_st +{ + unsigned int schedulerPolicy; //!< Scheduler policy + unsigned int enableARRMode; //!< Adaptive Round Robin scheduler + nvmlVgpuSchedulerSetParams_t schedulerParams; +} nvmlVgpuSchedulerSetState_t; + +/** + * Structure to store the vGPU scheduler capabilities + */ +typedef struct nvmlVgpuSchedulerCapabilities_st +{ + unsigned int supportedSchedulers[NVML_SUPPORTED_VGPU_SCHEDULER_POLICY_COUNT]; //!< List the supported vGPU schedulers on the device + unsigned int maxTimeslice; //!< Maximum timeslice value in ns + unsigned int minTimeslice; //!< Minimum timeslice value in ns + unsigned int isArrModeSupported; //!< Flag to check Adaptive Round Robin mode enabled/disabled. + unsigned int maxFrequencyForARR; //!< Maximum frequency for Adaptive Round Robin mode + unsigned int minFrequencyForARR; //!< Minimum frequency for Adaptive Round Robin mode + unsigned int maxAvgFactorForARR; //!< Maximum averaging factor for Adaptive Round Robin mode + unsigned int minAvgFactorForARR; //!< Minimum averaging factor for Adaptive Round Robin mode +} nvmlVgpuSchedulerCapabilities_t; + +/** + * Structure to store the vGPU license expiry details + */ +typedef struct nvmlVgpuLicenseExpiry_st +{ + unsigned int year; //!< Year of license expiry + unsigned short month; //!< Month of license expiry + unsigned short day; //!< Day of license expiry + unsigned short hour; //!< Hour of license expiry + unsigned short min; //!< Minutes of license expiry + unsigned short sec; //!< Seconds of license expiry + unsigned char status; //!< License expiry status +} nvmlVgpuLicenseExpiry_t; + +/** + * vGPU license state + */ +#define NVML_GRID_LICENSE_STATE_UNKNOWN 0 //!< Unknown state +#define NVML_GRID_LICENSE_STATE_UNINITIALIZED 1 //!< Uninitialized state +#define NVML_GRID_LICENSE_STATE_UNLICENSED_UNRESTRICTED 2 //!< Unlicensed unrestricted state +#define NVML_GRID_LICENSE_STATE_UNLICENSED_RESTRICTED 3 //!< Unlicensed restricted state +#define NVML_GRID_LICENSE_STATE_UNLICENSED 4 //!< Unlicensed state +#define NVML_GRID_LICENSE_STATE_LICENSED 5 //!< Licensed state + +typedef struct nvmlVgpuLicenseInfo_st +{ + unsigned char isLicensed; //!< License status + nvmlVgpuLicenseExpiry_t licenseExpiry; //!< License expiry information + unsigned int currentState; //!< Current license state +} nvmlVgpuLicenseInfo_t; + +/** + * Structure to store license expiry date and time values + */ +typedef struct nvmlGridLicenseExpiry_st +{ + unsigned int year; //!< Year value of license expiry + unsigned short month; //!< Month value of license expiry + unsigned short day; //!< Day value of license expiry + unsigned short hour; //!< Hour value of license expiry + unsigned short min; //!< Minutes value of license expiry + unsigned short sec; //!< Seconds value of license expiry + unsigned char status; //!< License expiry status +} nvmlGridLicenseExpiry_t; + +/** + * Structure containing vGPU software licensable feature information + */ +typedef struct nvmlGridLicensableFeature_st +{ + nvmlGridLicenseFeatureCode_t featureCode; //!< Licensed feature code + unsigned int featureState; //!< Non-zero if feature is currently licensed, otherwise zero + char licenseInfo[NVML_GRID_LICENSE_BUFFER_SIZE]; //!< Deprecated. + char productName[NVML_GRID_LICENSE_BUFFER_SIZE]; //!< Product name of feature + unsigned int featureEnabled; //!< Non-zero if feature is enabled, otherwise zero + nvmlGridLicenseExpiry_t licenseExpiry; //!< License expiry structure containing date and time +} nvmlGridLicensableFeature_t; + +/** + * Structure to store vGPU software licensable features + */ +typedef struct nvmlGridLicensableFeatures_st +{ + int isGridLicenseSupported; //!< Non-zero if vGPU Software Licensing is supported on the system, otherwise zero + unsigned int licensableFeaturesCount; //!< Entries returned in \a gridLicensableFeatures array + nvmlGridLicensableFeature_t gridLicensableFeatures[NVML_GRID_LICENSE_FEATURE_MAX_COUNT]; //!< Array of vGPU software licensable features. +} nvmlGridLicensableFeatures_t; + +/** + * Enum describing the GPU Recovery Action + */ +typedef enum nvmlDeviceGpuRecoveryAction_s { + NVML_GPU_RECOVERY_ACTION_NONE = 0, + NVML_GPU_RECOVERY_ACTION_GPU_RESET = 1, + NVML_GPU_RECOVERY_ACTION_NODE_REBOOT = 2, + NVML_GPU_RECOVERY_ACTION_DRAIN_P2P = 3, + NVML_GPU_RECOVERY_ACTION_DRAIN_AND_RESET = 4, +} nvmlDeviceGpuRecoveryAction_t; + +/** + * Structure to store the vGPU type IDs -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int vgpuCount; //!< IN/OUT: Number of vGPU types + nvmlVgpuTypeId_t *vgpuTypeIds; //!< OUT: List of vGPU type IDs +} nvmlVgpuTypeIdInfo_v1_t; +typedef nvmlVgpuTypeIdInfo_v1_t nvmlVgpuTypeIdInfo_t; +#define nvmlVgpuTypeIdInfo_v1 NVML_STRUCT_VERSION(VgpuTypeIdInfo, 1) + +/** + * Structure to store the maximum number of possible vGPU type IDs -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + nvmlVgpuTypeId_t vgpuTypeId; //!< IN: Handle to vGPU type + unsigned int maxInstancePerGI; //!< OUT: Maximum number of vGPU instances per GPU instance +} nvmlVgpuTypeMaxInstance_v1_t; +typedef nvmlVgpuTypeMaxInstance_v1_t nvmlVgpuTypeMaxInstance_t; +#define nvmlVgpuTypeMaxInstance_v1 NVML_STRUCT_VERSION(VgpuTypeMaxInstance, 1) + +/** + * Structure to store active vGPU instance information -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int vgpuCount; //!< IN/OUT: Count of the active vGPU instances + nvmlVgpuInstance_t *vgpuInstances; //!< IN/OUT: list of active vGPU instances +} nvmlActiveVgpuInstanceInfo_v1_t; +typedef nvmlActiveVgpuInstanceInfo_v1_t nvmlActiveVgpuInstanceInfo_t; +#define nvmlActiveVgpuInstanceInfo_v1 NVML_STRUCT_VERSION(ActiveVgpuInstanceInfo, 1) + +/** + * Structure to set vGPU scheduler state information -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int engineId; //!< IN: One of NVML_VGPU_SCHEDULER_ENGINE_TYPE_*. + unsigned int schedulerPolicy; //!< IN: Scheduler policy + unsigned int enableARRMode; //!< IN: Adaptive Round Robin scheduler + nvmlVgpuSchedulerSetParams_t schedulerParams; //!< IN: vGPU Scheduler Parameters +} nvmlVgpuSchedulerState_v1_t; +typedef nvmlVgpuSchedulerState_v1_t nvmlVgpuSchedulerState_t; +#define nvmlVgpuSchedulerState_v1 NVML_STRUCT_VERSION(VgpuSchedulerState, 1) + +/** + * Structure to store vGPU scheduler state information -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int engineId; //!< IN: Engine whose software scheduler state info is fetched. One of NVML_VGPU_SCHEDULER_ENGINE_TYPE_*. + unsigned int schedulerPolicy; //!< OUT: Scheduler policy + unsigned int arrMode; //!< OUT: Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; //!< OUT: vGPU Scheduler Parameters +} nvmlVgpuSchedulerStateInfo_v1_t; +typedef nvmlVgpuSchedulerStateInfo_v1_t nvmlVgpuSchedulerStateInfo_t; +#define nvmlVgpuSchedulerStateInfo_v1 NVML_STRUCT_VERSION(VgpuSchedulerStateInfo, 1) + +/** + * Structure to store vGPU scheduler log information -- Version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + unsigned int engineId; //!< IN: Engine whose software runlist log entries are fetched. One of One of NVML_VGPU_SCHEDULER_ENGINE_TYPE_*. + unsigned int schedulerPolicy; //!< OUT: Scheduler policy + unsigned int arrMode; //!< OUT: Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*. + nvmlVgpuSchedulerParams_t schedulerParams; //!< OUT: vGPU Scheduler Parameters + unsigned int entriesCount; //!< OUT: Count of log entries fetched + nvmlVgpuSchedulerLogEntry_t logEntries[NVML_SCHEDULER_SW_MAX_LOG_ENTRIES]; //!< OUT: Structure to store the state and logs of a software runlist +} nvmlVgpuSchedulerLogInfo_v1_t; +typedef nvmlVgpuSchedulerLogInfo_v1_t nvmlVgpuSchedulerLogInfo_t; +#define nvmlVgpuSchedulerLogInfo_v1 NVML_STRUCT_VERSION(VgpuSchedulerLogInfo, 1) + +/** + * Structure to store creatable vGPU placement information -- version 1 + */ +typedef struct +{ + unsigned int version; //!< IN: The version number of this struct + nvmlVgpuTypeId_t vgpuTypeId; //!< IN: Handle to vGPU type + unsigned int count; //!< IN/OUT: Count of the placement IDs + unsigned int *placementIds; //!< IN/OUT: Placement IDs for the vGPU type + unsigned int placementSize; //!< OUT: The number of slots occupied by the vGPU type +} nvmlVgpuCreatablePlacementInfo_v1_t; +typedef nvmlVgpuCreatablePlacementInfo_v1_t nvmlVgpuCreatablePlacementInfo_t; +#define nvmlVgpuCreatablePlacementInfo_v1 NVML_STRUCT_VERSION(VgpuCreatablePlacementInfo, 1) + +/** @} */ +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFieldValueEnums Field Value Enums + * @{ + */ +/***************************************************************************************************/ + +/** + * Field Identifiers. + * + * All Identifiers pertain to a device. Each ID is only used once and is guaranteed never to change. + */ +#define NVML_FI_DEV_ECC_CURRENT 1 //!< Current ECC mode. 1=Active. 0=Inactive +#define NVML_FI_DEV_ECC_PENDING 2 //!< Pending ECC mode. 1=Active. 0=Inactive +/* ECC Count Totals */ +#define NVML_FI_DEV_ECC_SBE_VOL_TOTAL 3 //!< Total single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_TOTAL 4 //!< Total double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_TOTAL 5 //!< Total single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_TOTAL 6 //!< Total double bit aggregate (persistent) ECC errors +/* Individual ECC locations */ +#define NVML_FI_DEV_ECC_SBE_VOL_L1 7 //!< L1 cache single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_L1 8 //!< L1 cache double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_L2 9 //!< L2 cache single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_L2 10 //!< L2 cache double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_DEV 11 //!< Device memory single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_DEV 12 //!< Device memory double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_REG 13 //!< Register file single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_REG 14 //!< Register file double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_VOL_TEX 15 //!< Texture memory single bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_TEX 16 //!< Texture memory double bit volatile ECC errors +#define NVML_FI_DEV_ECC_DBE_VOL_CBU 17 //!< CBU double bit volatile ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_L1 18 //!< L1 cache single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_L1 19 //!< L1 cache double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_L2 20 //!< L2 cache single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_L2 21 //!< L2 cache double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_DEV 22 //!< Device memory single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_DEV 23 //!< Device memory double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_REG 24 //!< Register File single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_REG 25 //!< Register File double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_SBE_AGG_TEX 26 //!< Texture memory single bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_TEX 27 //!< Texture memory double bit aggregate (persistent) ECC errors +#define NVML_FI_DEV_ECC_DBE_AGG_CBU 28 //!< CBU double bit aggregate ECC errors + +/* Page Retirement */ +#define NVML_FI_DEV_RETIRED_SBE 29 //!< Number of retired pages because of single bit errors +#define NVML_FI_DEV_RETIRED_DBE 30 //!< Number of retired pages because of double bit errors +#define NVML_FI_DEV_RETIRED_PENDING 31 //!< If any pages are pending retirement. 1=yes. 0=no. + +/** + * NVLink Flit Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L0 32 //!< NVLink flow control CRC Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L1 33 //!< NVLink flow control CRC Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L2 34 //!< NVLink flow control CRC Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L3 35 //!< NVLink flow control CRC Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L4 36 //!< NVLink flow control CRC Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L5 37 //!< NVLink flow control CRC Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_TOTAL 38 //!< NVLink flow control CRC Error Counter total for all Lanes + +/** + * NVLink CRC Data Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L0 39 //!< NVLink data CRC Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L1 40 //!< NVLink data CRC Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L2 41 //!< NVLink data CRC Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L3 42 //!< NVLink data CRC Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L4 43 //!< NVLink data CRC Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L5 44 //!< NVLink data CRC Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_TOTAL 45 //!< NvLink data CRC Error Counter total for all Lanes + +/** + * NVLink Replay Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L0 46 //!< NVLink Replay Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L1 47 //!< NVLink Replay Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L2 48 //!< NVLink Replay Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L3 49 //!< NVLink Replay Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L4 50 //!< NVLink Replay Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L5 51 //!< NVLink Replay Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_TOTAL 52 //!< NVLink Replay Error Counter total for all Lanes + +/** + * NVLink Recovery Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L0 53 //!< NVLink Recovery Error Counter for Lane 0 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L1 54 //!< NVLink Recovery Error Counter for Lane 1 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L2 55 //!< NVLink Recovery Error Counter for Lane 2 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L3 56 //!< NVLink Recovery Error Counter for Lane 3 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L4 57 //!< NVLink Recovery Error Counter for Lane 4 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L5 58 //!< NVLink Recovery Error Counter for Lane 5 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_TOTAL 59 //!< NVLink Recovery Error Counter total for all Lanes + +/* NvLink Bandwidth Counters */ +/* + * NVML_FI_DEV_NVLINK_BANDWIDTH_* field values are now deprecated. + * Please use the following field values instead: + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX + */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L0 60 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 0 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L1 61 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 1 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L2 62 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 2 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L3 63 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 3 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L4 64 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 4 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L5 65 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 5 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_TOTAL 66 //!< NVLink Bandwidth Counter Total for Counter Set 0, All Lanes + +/* NvLink Bandwidth Counters */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L0 67 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 0 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L1 68 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 1 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L2 69 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 2 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L3 70 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 3 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L4 71 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 4 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L5 72 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 5 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_TOTAL 73 //!< NVLink Bandwidth Counter Total for Counter Set 1, All Lanes + +/* NVML Perf Policy Counters */ +#define NVML_FI_DEV_PERF_POLICY_POWER 74 //!< Perf Policy Counter for Power Policy +#define NVML_FI_DEV_PERF_POLICY_THERMAL 75 //!< Perf Policy Counter for Thermal Policy +#define NVML_FI_DEV_PERF_POLICY_SYNC_BOOST 76 //!< Perf Policy Counter for Sync boost Policy +#define NVML_FI_DEV_PERF_POLICY_BOARD_LIMIT 77 //!< Perf Policy Counter for Board Limit +#define NVML_FI_DEV_PERF_POLICY_LOW_UTILIZATION 78 //!< Perf Policy Counter for Low GPU Utilization Policy +#define NVML_FI_DEV_PERF_POLICY_RELIABILITY 79 //!< Perf Policy Counter for Reliability Policy +#define NVML_FI_DEV_PERF_POLICY_TOTAL_APP_CLOCKS 80 //!< Perf Policy Counter for Total App Clock Policy +#define NVML_FI_DEV_PERF_POLICY_TOTAL_BASE_CLOCKS 81 //!< Perf Policy Counter for Total Base Clocks Policy + +/* Memory temperatures */ +#define NVML_FI_DEV_MEMORY_TEMP 82 //!< Memory temperature for the device + +/* Energy Counter */ +#define NVML_FI_DEV_TOTAL_ENERGY_CONSUMPTION 83 //!< Total energy consumption for the GPU in mJ since the driver was last reloaded + +/** + * NVLink Speed + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L0 84 //!< NVLink Speed in MBps for Link 0 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L1 85 //!< NVLink Speed in MBps for Link 1 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L2 86 //!< NVLink Speed in MBps for Link 2 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L3 87 //!< NVLink Speed in MBps for Link 3 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L4 88 //!< NVLink Speed in MBps for Link 4 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L5 89 //!< NVLink Speed in MBps for Link 5 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_COMMON 90 //!< Common NVLink Speed in MBps for active links + +#define NVML_FI_DEV_NVLINK_LINK_COUNT 91 //!< Number of NVLinks present on the device + +#define NVML_FI_DEV_RETIRED_PENDING_SBE 92 //!< If any pages are pending retirement due to SBE. 1=yes. 0=no. +#define NVML_FI_DEV_RETIRED_PENDING_DBE 93 //!< If any pages are pending retirement due to DBE. 1=yes. 0=no. + +#define NVML_FI_DEV_PCIE_REPLAY_COUNTER 94 //!< PCIe replay counter +#define NVML_FI_DEV_PCIE_REPLAY_ROLLOVER_COUNTER 95 //!< PCIe replay rollover counter + +/** + * NVLink Flit Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L6 96 //!< NVLink flow control CRC Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L7 97 //!< NVLink flow control CRC Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L8 98 //!< NVLink flow control CRC Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L9 99 //!< NVLink flow control CRC Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L10 100 //!< NVLink flow control CRC Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_CRC_FLIT_ERROR_COUNT_L11 101 //!< NVLink flow control CRC Error Counter for Lane 11 + +/** + * NVLink CRC Data Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L6 102 //!< NVLink data CRC Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L7 103 //!< NVLink data CRC Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L8 104 //!< NVLink data CRC Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L9 105 //!< NVLink data CRC Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L10 106 //!< NVLink data CRC Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_CRC_DATA_ERROR_COUNT_L11 107 //!< NVLink data CRC Error Counter for Lane 11 + +/** + * NVLink Replay Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L6 108 //!< NVLink Replay Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L7 109 //!< NVLink Replay Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L8 110 //!< NVLink Replay Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L9 111 //!< NVLink Replay Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L10 112 //!< NVLink Replay Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_REPLAY_ERROR_COUNT_L11 113 //!< NVLink Replay Error Counter for Lane 11 + +/** + * NVLink Recovery Error Counters + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L6 114 //!< NVLink Recovery Error Counter for Lane 6 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L7 115 //!< NVLink Recovery Error Counter for Lane 7 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L8 116 //!< NVLink Recovery Error Counter for Lane 8 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L9 117 //!< NVLink Recovery Error Counter for Lane 9 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L10 118 //!< NVLink Recovery Error Counter for Lane 10 +#define NVML_FI_DEV_NVLINK_RECOVERY_ERROR_COUNT_L11 119 //!< NVLink Recovery Error Counter for Lane 11 + +/* NvLink Bandwidth Counters */ +/* + * NVML_FI_DEV_NVLINK_BANDWIDTH_* field values are now deprecated. + * Please use the following field values instead: + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX + * NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX + */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L6 120 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 6 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L7 121 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 7 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L8 122 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 8 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L9 123 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 9 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L10 124 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 10 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C0_L11 125 //!< NVLink Bandwidth Counter for Counter Set 0, Lane 11 + +/* NvLink Bandwidth Counters */ +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L6 126 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 6 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L7 127 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 7 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L8 128 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 8 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L9 129 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 9 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L10 130 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 10 +#define NVML_FI_DEV_NVLINK_BANDWIDTH_C1_L11 131 //!< NVLink Bandwidth Counter for Counter Set 1, Lane 11 + +/** + * NVLink Speed + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L6 132 //!< NVLink Speed in MBps for Link 6 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L7 133 //!< NVLink Speed in MBps for Link 7 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L8 134 //!< NVLink Speed in MBps for Link 8 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L9 135 //!< NVLink Speed in MBps for Link 9 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L10 136 //!< NVLink Speed in MBps for Link 10 +#define NVML_FI_DEV_NVLINK_SPEED_MBPS_L11 137 //!< NVLink Speed in MBps for Link 11 + +/** + * NVLink throughput counters field values + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + * A scopeId of UINT_MAX returns aggregate value summed up across all links + * for the specified counter type in fieldId. + */ +#define NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_TX 138 //!< NVLink TX Data throughput in KiB +#define NVML_FI_DEV_NVLINK_THROUGHPUT_DATA_RX 139 //!< NVLink RX Data throughput in KiB +#define NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_TX 140 //!< NVLink TX Data + protocol overhead in KiB +#define NVML_FI_DEV_NVLINK_THROUGHPUT_RAW_RX 141 //!< NVLink RX Data + protocol overhead in KiB + +/* Row Remapper */ +#define NVML_FI_DEV_REMAPPED_COR 142 //!< Number of remapped rows due to correctable errors +#define NVML_FI_DEV_REMAPPED_UNC 143 //!< Number of remapped rows due to uncorrectable errors +#define NVML_FI_DEV_REMAPPED_PENDING 144 //!< If any rows are pending remapping. 1=yes 0=no +#define NVML_FI_DEV_REMAPPED_FAILURE 145 //!< If any rows failed to be remapped 1=yes 0=no + +/** + * Remote device NVLink ID + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_REMOTE_NVLINK_ID 146 //!< Remote device NVLink ID + +/** + * NVSwitch: connected NVLink count + */ +#define NVML_FI_DEV_NVSWITCH_CONNECTED_LINK_COUNT 147 //!< Number of NVLinks connected to NVSwitch + +/* NvLink ECC Data Error Counters + * + * Lane ID needs to be specified in the scopeId field in nvmlFieldValue_t. + * + */ +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L0 148 //!< NVLink data ECC Error Counter for Link 0 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L1 149 //!< NVLink data ECC Error Counter for Link 1 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L2 150 //!< NVLink data ECC Error Counter for Link 2 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L3 151 //!< NVLink data ECC Error Counter for Link 3 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L4 152 //!< NVLink data ECC Error Counter for Link 4 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L5 153 //!< NVLink data ECC Error Counter for Link 5 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L6 154 //!< NVLink data ECC Error Counter for Link 6 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L7 155 //!< NVLink data ECC Error Counter for Link 7 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L8 156 //!< NVLink data ECC Error Counter for Link 8 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L9 157 //!< NVLink data ECC Error Counter for Link 9 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L10 158 //!< NVLink data ECC Error Counter for Link 10 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_L11 159 //!< NVLink data ECC Error Counter for Link 11 +#define NVML_FI_DEV_NVLINK_ECC_DATA_ERROR_COUNT_TOTAL 160 //!< NVLink data ECC Error Counter total for all Links + +/** + * NVLink Error Replay + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_ERROR_DL_REPLAY 161 //!< NVLink Replay Error Counter + //!< This is unsupported for Blackwell+. + //!< Please use NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_* +/** + * NVLink Recovery Error Counter + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_ERROR_DL_RECOVERY 162 //!< NVLink Recovery Error Counter + //!< This is unsupported for Blackwell+ + //!< Please use NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_* + +/** + * NVLink Recovery Error CRC Counter + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_ERROR_DL_CRC 163 //!< NVLink CRC Error Counter + //!< This is unsupported for Blackwell+ + //!< Please use NVML_FI_DEV_NVLINK_COUNT_LINK_RECOVERY_* + +/** + * NVLink Speed, State and Version field id 164, 165, and 166 + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_GET_SPEED 164 //!< NVLink Speed in MBps +#define NVML_FI_DEV_NVLINK_GET_STATE 165 //!< NVLink State - Active,Inactive +#define NVML_FI_DEV_NVLINK_GET_VERSION 166 //!< NVLink Version + +#define NVML_FI_DEV_NVLINK_GET_POWER_STATE 167 //!< NVLink Power state. 0=HIGH_SPEED 1=LOW_SPEED +#define NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD 168 //!< NVLink length of idle period (units can be found from + //!< NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_UNITS) before + //!< transitioning links to sleep state + +#define NVML_FI_DEV_PCIE_L0_TO_RECOVERY_COUNTER 169 //!< Device PEX error recovery counter + +#define NVML_FI_DEV_C2C_LINK_COUNT 170 //!< Number of C2C Links present on the device +#define NVML_FI_DEV_C2C_LINK_GET_STATUS 171 //!< C2C Link Status 0=INACTIVE 1=ACTIVE +#define NVML_FI_DEV_C2C_LINK_GET_MAX_BW 172 //!< C2C Link Speed in MBps for active links + +#define NVML_FI_DEV_PCIE_COUNT_CORRECTABLE_ERRORS 173 //!< PCIe Correctable Errors Counter +#define NVML_FI_DEV_PCIE_COUNT_NAKS_RECEIVED 174 //!< PCIe NAK Receive Counter +#define NVML_FI_DEV_PCIE_COUNT_RECEIVER_ERROR 175 //!< PCIe Receiver Error Counter +#define NVML_FI_DEV_PCIE_COUNT_BAD_TLP 176 //!< PCIe Bad TLP Counter +#define NVML_FI_DEV_PCIE_COUNT_NAKS_SENT 177 //!< PCIe NAK Send Counter +#define NVML_FI_DEV_PCIE_COUNT_BAD_DLLP 178 //!< PCIe Bad DLLP Counter +#define NVML_FI_DEV_PCIE_COUNT_NON_FATAL_ERROR 179 //!< PCIe Non Fatal Error Counter +#define NVML_FI_DEV_PCIE_COUNT_FATAL_ERROR 180 //!< PCIe Fatal Error Counter +#define NVML_FI_DEV_PCIE_COUNT_UNSUPPORTED_REQ 181 //!< PCIe Unsupported Request Counter +#define NVML_FI_DEV_PCIE_COUNT_LCRC_ERROR 182 //!< PCIe LCRC Error Counter +#define NVML_FI_DEV_PCIE_COUNT_LANE_ERROR 183 //!< PCIe Per Lane Error Counter. + +#define NVML_FI_DEV_IS_RESETLESS_MIG_SUPPORTED 184 //!< Device's Restless MIG Capability + +/** + * Retrieves power usage for this GPU in milliwatts. + * It is only available if power management mode is supported. See \ref nvmlDeviceGetPowerManagementMode and + * \ref nvmlDeviceGetPowerUsage. + * + * scopeId needs to be specified. It signifies: + * 0 - GPU Only Scope - Metrics for GPU are retrieved + * 1 - Module scope - Metrics for the module (e.g. CPU + GPU) are retrieved. + * Note: CPU here refers to NVIDIA CPU (e.g. Grace). x86 or non-NVIDIA ARM is not supported + */ +#define NVML_FI_DEV_POWER_AVERAGE 185 //!< GPU power averaged over 1 sec interval, supported on Ampere (except GA100) or newer architectures. +#define NVML_FI_DEV_POWER_INSTANT 186 //!< Current GPU power, supported on all architectures. +#define NVML_FI_DEV_POWER_MIN_LIMIT 187 //!< Minimum power limit in milliwatts. +#define NVML_FI_DEV_POWER_MAX_LIMIT 188 //!< Maximum power limit in milliwatts. +#define NVML_FI_DEV_POWER_DEFAULT_LIMIT 189 //!< Default power limit in milliwatts (limit which device boots with). +#define NVML_FI_DEV_POWER_CURRENT_LIMIT 190 //!< Limit currently enforced in milliwatts (This includes other limits set elsewhere. E.g. Out-of-band). +#define NVML_FI_DEV_ENERGY 191 //!< Total energy consumption (in mJ) since the driver was last reloaded. Same as \ref NVML_FI_DEV_TOTAL_ENERGY_CONSUMPTION for the GPU. +#define NVML_FI_DEV_POWER_REQUESTED_LIMIT 192 //!< Power limit requested by NVML or any other userspace client. + +/** + * GPU T.Limit temperature thresholds in degree Celsius + * + * These fields are supported on Ada and later architectures and supersedes \ref nvmlDeviceGetTemperatureThreshold. + */ +#define NVML_FI_DEV_TEMPERATURE_SHUTDOWN_TLIMIT 193 //!< T.Limit temperature after which GPU may shut down for HW protection +#define NVML_FI_DEV_TEMPERATURE_SLOWDOWN_TLIMIT 194 //!< T.Limit temperature after which GPU may begin HW slowdown +#define NVML_FI_DEV_TEMPERATURE_MEM_MAX_TLIMIT 195 //!< T.Limit temperature after which GPU may begin SW slowdown due to memory temperature +#define NVML_FI_DEV_TEMPERATURE_GPU_MAX_TLIMIT 196 //!< T.Limit temperature after which GPU may be throttled below base clock + +#define NVML_FI_DEV_PCIE_COUNT_TX_BYTES 197 //!< PCIe transmit bytes. Value can be wrapped. +#define NVML_FI_DEV_PCIE_COUNT_RX_BYTES 198 //!< PCIe receive bytes. Value can be wrapped. + +#define NVML_FI_DEV_IS_MIG_MODE_INDEPENDENT_MIG_QUERY_CAPABLE 199 //!< MIG mode independent, MIG query capable device. 1=yes. 0=no. + +#define NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD_MAX 200 //!< Max Nvlink Power Threshold. See NVML_FI_DEV_NVLINK_GET_POWER_THRESHOLD + +/** + * NVLink counter field id 201-225 + * + * Link ID needs to be specified in the scopeId field in nvmlFieldValue_t. + */ +#define NVML_FI_DEV_NVLINK_COUNT_XMIT_PACKETS 201 //!usedGpuMemory is not supported + + + unsigned long long time; //!< Amount of time in ms during which the compute context was active. The time is reported as 0 if + //!< the process is not terminated + + unsigned long long startTime; //!< CPU Timestamp in usec representing start time for the process + + unsigned int isRunning; //!< Flag to represent if the process is running (1 for running, 0 for terminated) + + unsigned int reserved[5]; //!< Reserved for future use +} nvmlAccountingStats_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlEncoderStructs Encoder Structs + * @{ + */ +/***************************************************************************************************/ + +/** + * Represents type of encoder for capacity can be queried + */ +typedef enum nvmlEncoderQueryType_enum +{ + NVML_ENCODER_QUERY_H264 = 0x00, //!< H264 encoder + NVML_ENCODER_QUERY_HEVC = 0x01, //!< HEVC encoder + NVML_ENCODER_QUERY_AV1 = 0x02, //!< AV1 encoder + NVML_ENCODER_QUERY_UNKNOWN = 0xFF //!< Unknown encoder +}nvmlEncoderType_t; + +/** + * Structure to hold encoder session data + */ +typedef struct nvmlEncoderSessionInfo_st +{ + unsigned int sessionId; //!< Unique session ID + unsigned int pid; //!< Owning process ID + nvmlVgpuInstance_t vgpuInstance; //!< Owning vGPU instance ID (only valid on vGPU hosts, otherwise zero) + nvmlEncoderType_t codecType; //!< Video encoder type + unsigned int hResolution; //!< Current encode horizontal resolution + unsigned int vResolution; //!< Current encode vertical resolution + unsigned int averageFps; //!< Moving average encode frames per second + unsigned int averageLatency; //!< Moving average encode latency in microseconds +}nvmlEncoderSessionInfo_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFBCStructs Frame Buffer Capture Structures +* @{ +*/ +/***************************************************************************************************/ + +/** + * Represents frame buffer capture session type + */ +typedef enum nvmlFBCSessionType_enum +{ + NVML_FBC_SESSION_TYPE_UNKNOWN = 0, //!< Unknown + NVML_FBC_SESSION_TYPE_TOSYS, //!< ToSys + NVML_FBC_SESSION_TYPE_CUDA, //!< Cuda + NVML_FBC_SESSION_TYPE_VID, //!< Vid + NVML_FBC_SESSION_TYPE_HWENC //!< HEnc +} nvmlFBCSessionType_t; + +/** + * Structure to hold frame buffer capture sessions stats + */ +typedef struct nvmlFBCStats_st +{ + unsigned int sessionsCount; //!< Total no of sessions + unsigned int averageFPS; //!< Moving average new frames captured per second + unsigned int averageLatency; //!< Moving average new frame capture latency in microseconds +} nvmlFBCStats_t; + +#define NVML_NVFBC_SESSION_FLAG_DIFFMAP_ENABLED 0x00000001 //!< Bit specifying differential map state. +#define NVML_NVFBC_SESSION_FLAG_CLASSIFICATIONMAP_ENABLED 0x00000002 //!< Bit specifying classification map state. +#define NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_NO_WAIT 0x00000004 //!< Bit specifying if capture was requested as non-blocking call. +#define NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_INFINITE 0x00000008 //!< Bit specifying if capture was requested as blocking call. +#define NVML_NVFBC_SESSION_FLAG_CAPTURE_WITH_WAIT_TIMEOUT 0x00000010 //!< Bit specifying if capture was requested as blocking call with timeout period. + +/** + * Structure to hold FBC session data + */ +typedef struct nvmlFBCSessionInfo_st +{ + unsigned int sessionId; //!< Unique session ID + unsigned int pid; //!< Owning process ID + nvmlVgpuInstance_t vgpuInstance; //!< Owning vGPU instance ID (only valid on vGPU hosts, otherwise zero) + unsigned int displayOrdinal; //!< Display identifier + nvmlFBCSessionType_t sessionType; //!< Type of frame buffer capture session + unsigned int sessionFlags; //!< Session flags (one or more of NVML_NVFBC_SESSION_FLAG_XXX). + unsigned int hMaxResolution; //!< Max horizontal resolution supported by the capture session + unsigned int vMaxResolution; //!< Max vertical resolution supported by the capture session + unsigned int hResolution; //!< Horizontal resolution requested by caller in capture call + unsigned int vResolution; //!< Vertical resolution requested by caller in capture call + unsigned int averageFPS; //!< Moving average new frames captured per second + unsigned int averageLatency; //!< Moving average new frame capture latency in microseconds +} nvmlFBCSessionInfo_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDrainDefs Drain State definitions + * @{ + */ +/***************************************************************************************************/ + +/** + * Is the GPU device to be removed from the kernel by nvmlDeviceRemoveGpu() + */ +typedef enum nvmlDetachGpuState_enum +{ + NVML_DETACH_GPU_KEEP = 0, + NVML_DETACH_GPU_REMOVE +} nvmlDetachGpuState_t; + +/** + * Parent bridge PCIe link state requested by nvmlDeviceRemoveGpu() + */ +typedef enum nvmlPcieLinkState_enum +{ + NVML_PCIE_LINK_KEEP = 0, + NVML_PCIE_LINK_SHUT_DOWN +} nvmlPcieLinkState_t; + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlConfidentialComputingDefs Confidential Computing definitions + * @{ + */ +/***************************************************************************************************/ +/** + * Confidential Compute CPU Capabilities values + */ +#define NVML_CC_SYSTEM_CPU_CAPS_NONE 0 +#define NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV 1 +#define NVML_CC_SYSTEM_CPU_CAPS_INTEL_TDX 2 +#define NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV_SNP 3 +#define NVML_CC_SYSTEM_CPU_CAPS_AMD_SNP_VTOM 4 + +/** + * Confidenial Compute GPU Capabilities values + */ +#define NVML_CC_SYSTEM_GPUS_CC_NOT_CAPABLE 0 +#define NVML_CC_SYSTEM_GPUS_CC_CAPABLE 1 + +typedef struct nvmlConfComputeSystemCaps_st { + unsigned int cpuCaps; + unsigned int gpusCaps; +} nvmlConfComputeSystemCaps_t; + +/** + * Confidential Compute DevTools Mode values + */ +#define NVML_CC_SYSTEM_DEVTOOLS_MODE_OFF 0 +#define NVML_CC_SYSTEM_DEVTOOLS_MODE_ON 1 + +/** + * Confidential Compute Environment values + */ +#define NVML_CC_SYSTEM_ENVIRONMENT_UNAVAILABLE 0 +#define NVML_CC_SYSTEM_ENVIRONMENT_SIM 1 +#define NVML_CC_SYSTEM_ENVIRONMENT_PROD 2 + +/** + * Confidential Compute Feature Status values + */ +#define NVML_CC_SYSTEM_FEATURE_DISABLED 0 +#define NVML_CC_SYSTEM_FEATURE_ENABLED 1 + +typedef struct nvmlConfComputeSystemState_st { + unsigned int environment; + unsigned int ccFeature; + unsigned int devToolsMode; +} nvmlConfComputeSystemState_t; + +/** + * Confidential Compute Multigpu mode values + */ +#define NVML_CC_SYSTEM_MULTIGPU_NONE 0 +#define NVML_CC_SYSTEM_MULTIGPU_PROTECTED_PCIE 1 +#define NVML_CC_SYSTEM_MULTIGPU_NVLE 2 + +/** + * Confidential Compute System settings + */ +typedef struct { + unsigned int version; + unsigned int environment; + unsigned int ccFeature; + unsigned int devToolsMode; + unsigned int multiGpuMode; +} nvmlSystemConfComputeSettings_v1_t; + +typedef nvmlSystemConfComputeSettings_v1_t nvmlSystemConfComputeSettings_t; +#define nvmlSystemConfComputeSettings_v1 NVML_STRUCT_VERSION(SystemConfComputeSettings, 1) + +/** + * Protected memory size + */ +typedef struct +nvmlConfComputeMemSizeInfo_st +{ + unsigned long long protectedMemSizeKib; + unsigned long long unprotectedMemSizeKib; +} nvmlConfComputeMemSizeInfo_t; + +/** + * Confidential Compute GPUs/System Ready State values + */ +#define NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE 0 +#define NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE 1 + +/** + * GPU Certificate Details + */ +#define NVML_GPU_CERT_CHAIN_SIZE 0x1000 +#define NVML_GPU_ATTESTATION_CERT_CHAIN_SIZE 0x1400 + +typedef struct nvmlConfComputeGpuCertificate_st { + unsigned int certChainSize; + unsigned int attestationCertChainSize; + unsigned char certChain[NVML_GPU_CERT_CHAIN_SIZE]; + unsigned char attestationCertChain[NVML_GPU_ATTESTATION_CERT_CHAIN_SIZE]; +} nvmlConfComputeGpuCertificate_t; + +/** + * GPU Attestation Report + */ +#define NVML_CC_GPU_CEC_NONCE_SIZE 0x20 +#define NVML_CC_GPU_ATTESTATION_REPORT_SIZE 0x2000 +#define NVML_CC_GPU_CEC_ATTESTATION_REPORT_SIZE 0x1000 +#define NVML_CC_CEC_ATTESTATION_REPORT_NOT_PRESENT 0 +#define NVML_CC_CEC_ATTESTATION_REPORT_PRESENT 1 +#define NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MIN 50 +#define NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MAX 65 + +typedef struct nvmlConfComputeGpuAttestationReport_st { + unsigned int isCecAttestationReportPresent; //!< output + unsigned int attestationReportSize; //!< output + unsigned int cecAttestationReportSize; //!< output + unsigned char nonce[NVML_CC_GPU_CEC_NONCE_SIZE]; //!< input: spdm supports 32 bytes on nonce + unsigned char attestationReport[NVML_CC_GPU_ATTESTATION_REPORT_SIZE]; //!< output + unsigned char cecAttestationReport[NVML_CC_GPU_CEC_ATTESTATION_REPORT_SIZE]; //!< output +} nvmlConfComputeGpuAttestationReport_t; + +typedef struct nvmlConfComputeSetKeyRotationThresholdInfo_st { + unsigned int version; + unsigned long long maxAttackerAdvantage; +} nvmlConfComputeSetKeyRotationThresholdInfo_v1_t; + +typedef nvmlConfComputeSetKeyRotationThresholdInfo_v1_t nvmlConfComputeSetKeyRotationThresholdInfo_t; +#define nvmlConfComputeSetKeyRotationThresholdInfo_v1 \ + NVML_STRUCT_VERSION(ConfComputeSetKeyRotationThresholdInfo, 1) + +typedef struct nvmlConfComputeGetKeyRotationThresholdInfo_st { + unsigned int version; + unsigned long long attackerAdvantage; +} nvmlConfComputeGetKeyRotationThresholdInfo_v1_t; + +typedef nvmlConfComputeGetKeyRotationThresholdInfo_v1_t nvmlConfComputeGetKeyRotationThresholdInfo_t; +#define nvmlConfComputeGetKeyRotationThresholdInfo_v1 \ + NVML_STRUCT_VERSION(ConfComputeGetKeyRotationThresholdInfo, 1) + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFabricDefs Fabric definitions + * @{ + */ +/***************************************************************************************************/ + +#define NVML_GPU_FABRIC_UUID_LEN 16 //!< Length of Fabric UUID + +/** + * Fabric Probe States + */ +#define NVML_GPU_FABRIC_STATE_NOT_SUPPORTED 0 //!< Fabric Probe State not supported +#define NVML_GPU_FABRIC_STATE_NOT_STARTED 1 //!< Fabric Probe has not started +#define NVML_GPU_FABRIC_STATE_IN_PROGRESS 2 //!< Fabric Probe in progress +#define NVML_GPU_FABRIC_STATE_COMPLETED 3 //!< Fabric Probe State completed + +/** + * Probe State of GPU registration process + */ +typedef unsigned char nvmlGpuFabricState_t; + +/** + * Contains the device fabric information + */ +typedef struct +{ + unsigned char clusterUuid[NVML_GPU_FABRIC_UUID_LEN]; //!< Uuid of the cluster to which this GPU belongs + nvmlReturn_t status; //!< Error status, if any. Must be checked only if state returns "complete". + unsigned int cliqueId; //!< ID of the fabric clique to which this GPU belongs + nvmlGpuFabricState_t state; //!< Current state of GPU registration process. See NVML_GPU_FABRIC_STATE_* +} nvmlGpuFabricInfo_t; + +/** + * Fabric Degraded BW + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_DEGRADED_BW_NOT_SUPPORTED 0 //!< Fabric Health Mask: Degraded Bandwidth not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_DEGRADED_BW_TRUE 1 //!< Fabric Health Mask: Bandwidth degraded +#define NVML_GPU_FABRIC_HEALTH_MASK_DEGRADED_BW_FALSE 2 //!< Fabric Health Mask: Bandwidth not degraded + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_DEGRADED_BW 0 //!< Fabric Health Mask Bit Shift for Degraded Bandwidth +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_DEGRADED_BW 0x3 //!< Fabric Health Mask Width for Degraded Bandwidth + +/** + * Fabric Route Recovery + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_NOT_SUPPORTED 0 //!< Fabric Health Mask: Route Recovery not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_TRUE 1 //!< Fabric Health Mask: Route Recovery in progress +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_RECOVERY_FALSE 2 //!< Fabric Health Mask: Route Recovery not in progress + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_RECOVERY 2 //!< Fabric Health Mask Bit Shift for Route Recovery +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_RECOVERY 0x3 //!< Fabric Health Mask Width for Route Recovery + +/** + * Nvlink Fabric Route Unhealthy + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_NOT_SUPPORTED 0 //!< Fabric Health Mask: Route Unhealthy not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_TRUE 1 //!< Fabric Health Mask: Route is unhealthy +#define NVML_GPU_FABRIC_HEALTH_MASK_ROUTE_UNHEALTHY_FALSE 2 //!< Fabric Health Mask: Route is healthy + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ROUTE_UNHEALTHY 4 //!< Fabric Health Mask Bit Shift for Route Unhealthy +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_ROUTE_UNHEALTHY 0x3 //!< Fabric Health Mask Width for Route Unhealthy + +/** + * Fabric Access Timeout Recovery + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_NOT_SUPPORTED 0 //!< Fabric Health Mask: Access Timeout Recovery not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_TRUE 1 //!< Fabric Health Mask: Access Timeout Recovery in progress +#define NVML_GPU_FABRIC_HEALTH_MASK_ACCESS_TIMEOUT_RECOVERY_FALSE 2 //!< Fabric Health Mask: Access Timeout Recovery not in progress + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_ACCESS_TIMEOUT_RECOVERY 6 //!< Fabric Health Mask Bit Shift for Access Timeout Recovery +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_ACCESS_TIMEOUT_RECOVERY 0x3 //!< Fabric Health Mask Width for Access Timeout Recovery + +/** + * Fabric Incorrect Configuration + */ +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_NOT_SUPPORTED 0 //!< Fabric Health Mask: Incorrect Configuration not supported +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_NONE 1 //!< Fabric Health Mask: Correct Configuration +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INCORRECT_SYSGUID 2 //!< Fabric Health Mask: Incorrect Configuration - SysGUID +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INCORRECT_CHASSIS_SN 3 //!< Fabric Health Mask: Incorrect Configuration - Chassis Serial Number +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_NO_PARTITION 4 //!< Fabric Health Mask: Incorrect Configuration - No Partition +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INSUFFICIENT_NVLINKS 5 //!< Fabric Health Mask: Incorrect Configuration - Insufficient Nvlinks +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INCOMPATIBLE_GPU_FW 6 //!< Fabric Health Mask: Incorrect Configuration - Incompatible GPU Firmware +#define NVML_GPU_FABRIC_HEALTH_MASK_INCORRECT_CONFIGURATION_INVALID_LOCATION 7 //!< Fabric Health Mask: Incorrect Configuration - Invalid Location + +#define NVML_GPU_FABRIC_HEALTH_MASK_SHIFT_INCORRECT_CONFIGURATION 8 //!< Fabric Health Mask Bit Shift for Incorrect Configuration +#define NVML_GPU_FABRIC_HEALTH_MASK_WIDTH_INCORRECT_CONFIGURATION 0xf //!< Fabric Health Mask Width for Incorrect Configuration + +/** + * Fabric Health + */ +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_NOT_SUPPORTED 0 //!< Fabric Health Summary: Not supported +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_HEALTHY 1 //!< Fabric Health Summary: Healthy +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_UNHEALTHY 2 //!< Fabric Health Summary: Unhealthy +#define NVML_GPU_FABRIC_HEALTH_SUMMARY_LIMITED_CAPACITY 3 //!< Fabric Health Summary: Limited Capacity + +/** + * GPU Fabric Health Status Mask for various fields can be obtained + * using the below macro. + * Ex - NVML_GPU_FABRIC_HEALTH_GET(var, _DEGRADED_BW) + */ +#define NVML_GPU_FABRIC_HEALTH_GET(var, type) \ + (((var) >> NVML_GPU_FABRIC_HEALTH_MASK_SHIFT##type) & \ + (NVML_GPU_FABRIC_HEALTH_MASK_WIDTH##type)) + +/** + * GPU Fabric Health Status Mask for various fields can be tested + * using the below macro. + * Ex - NVML_GPU_FABRIC_HEALTH_TEST(var, _DEGRADED_BW, _TRUE) + */ +#define NVML_GPU_FABRIC_HEALTH_TEST(var, type, val) \ + (NVML_GPU_FABRIC_HEALTH_GET(var, type) == \ + NVML_GPU_FABRIC_HEALTH_MASK##type##val) + +/** +* GPU Fabric information (v2). +* +* @deprecated nvmlGpuFabricInfo_v2_t is deprecated and will be removed in a future release. +* Use nvmlGpuFabricInfo_v3_t instead +* +* Version 2 adds the \ref nvmlGpuFabricInfo_v2_t.version field +* to the start of the structure, and the \ref nvmlGpuFabricInfo_v2_t.healthMask +* field to the end. This structure is not backwards-compatible with +* \ref nvmlGpuFabricInfo_t. +*/ +typedef struct +{ + unsigned int version; //!< Structure version identifier (set to nvmlGpuFabricInfo_v2) + unsigned char clusterUuid[NVML_GPU_FABRIC_UUID_LEN]; //!< Uuid of the cluster to which this GPU belongs + nvmlReturn_t status; //!< Probe Error status, if any. Must be checked only if Probe state returns "complete". + unsigned int cliqueId; //!< ID of the fabric clique to which this GPU belongs + nvmlGpuFabricState_t state; //!< Current Probe State of GPU registration process. See NVML_GPU_FABRIC_STATE_* + unsigned int healthMask; //!< GPU Fabric health Status Mask. See NVML_GPU_FABRIC_HEALTH_MASK_* +} nvmlGpuFabricInfo_v2_t; + +/** +* Version identifier value for \ref nvmlGpuFabricInfo_v2_t.version. +*/ +#define nvmlGpuFabricInfo_v2 NVML_STRUCT_VERSION(GpuFabricInfo, 2) + +/** +* GPU Fabric information (v3). +*/ +typedef struct +{ + unsigned int version; //!< Structure version identifier (set to nvmlGpuFabricInfo_v2) + unsigned char clusterUuid[NVML_GPU_FABRIC_UUID_LEN]; //!< Uuid of the cluster to which this GPU belongs + nvmlReturn_t status; //!< Probe Error status, if any. Must be checked only if Probe state returns "complete". + unsigned int cliqueId; //!< ID of the fabric clique to which this GPU belongs + nvmlGpuFabricState_t state; //!< Current Probe State of GPU registration process. See NVML_GPU_FABRIC_STATE_* + unsigned int healthMask; //!< GPU Fabric health Status Mask. See NVML_GPU_FABRIC_HEALTH_MASK_* + unsigned char healthSummary; //!< GPU Fabric health summary. See NVML_GPU_FABRIC_HEALTH_SUMMARY_* +} nvmlGpuFabricInfo_v3_t; + +typedef nvmlGpuFabricInfo_v3_t nvmlGpuFabricInfoV_t; + +/** +* Version identifier value for \ref nvmlGpuFabricInfo_v3_t.version. +*/ +#define nvmlGpuFabricInfo_v3 NVML_STRUCT_VERSION(GpuFabricInfo, 3) + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlInitializationAndCleanup Initialization and Cleanup + * This chapter describes the methods that handle NVML initialization and cleanup. + * It is the user's responsibility to call \ref nvmlInit_v2() before calling any other methods, and + * nvmlShutdown() once NVML is no longer being used. + * @{ + */ +/***************************************************************************************************/ + +#define NVML_INIT_FLAG_NO_GPUS 1 //!< Don't fail nvmlInit() when no GPUs are found +#define NVML_INIT_FLAG_NO_ATTACH 2 //!< Don't attach GPUs + +/** + * Initialize NVML, but don't initialize any GPUs yet. + * + * \note nvmlInit_v3 introduces a "flags" argument, that allows passing boolean values + * modifying the behaviour of nvmlInit(). + * \note In NVML 5.319 new nvmlInit_v2 has replaced nvmlInit"_v1" (default in NVML 4.304 and older) that + * did initialize all GPU devices in the system. + * + * This allows NVML to communicate with a GPU + * when other GPUs in the system are unstable or in a bad state. When using this API, GPUs are + * discovered and initialized in nvmlDeviceGetHandleBy* functions instead. + * + * \note To contrast nvmlInit_v2 with nvmlInit"_v1", NVML 4.304 nvmlInit"_v1" will fail when any detected GPU is in + * a bad or unstable state. + * + * For all products. + * + * This method, should be called once before invoking any other methods in the library. + * A reference count of the number of initializations is maintained. Shutdown only occurs + * when the reference count reaches zero. + * + * @return + * - \ref NVML_SUCCESS if NVML has been properly initialized + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running + * - \ref NVML_ERROR_NO_PERMISSION if NVML does not have permission to talk to the driver + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlInit_v2(void); + +/** + * nvmlInitWithFlags is a variant of nvmlInit(), that allows passing a set of boolean values + * modifying the behaviour of nvmlInit(). + * Other than the "flags" parameter it is completely similar to \ref nvmlInit_v2. + * + * For all products. + * + * @param flags behaviour modifier flags + * + * @return + * - \ref NVML_SUCCESS if NVML has been properly initialized + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running + * - \ref NVML_ERROR_NO_PERMISSION if NVML does not have permission to talk to the driver + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlInitWithFlags(unsigned int flags); + +/** + * Shut down NVML by releasing all GPU resources previously allocated with \ref nvmlInit_v2(). + * + * For all products. + * + * This method should be called after NVML work is done, once for each call to \ref nvmlInit_v2() + * A reference count of the number of initializations is maintained. Shutdown only occurs + * when the reference count reaches zero. For backwards compatibility, no error is reported if + * nvmlShutdown() is called more times than nvmlInit(). + * + * @return + * - \ref NVML_SUCCESS if NVML has been properly shut down + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlShutdown(void); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlErrorReporting Error reporting + * This chapter describes helper functions for error reporting routines. + * @{ + */ +/***************************************************************************************************/ + +/** + * Helper method for converting NVML error codes into readable strings. + * + * For all products. + * + * @param result NVML error code to convert + * + * @return String representation of the error. + * + */ +const DECLDIR char* nvmlErrorString(nvmlReturn_t result); +/** @} */ + + +/***************************************************************************************************/ +/** @defgroup nvmlConstants Constants + * @{ + */ +/***************************************************************************************************/ + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetInforomVersion and \ref nvmlDeviceGetInforomImageVersion + */ +#define NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE 16 + +/** + * Buffer size guaranteed to be large enough for storing GPU identifiers. + */ +#define NVML_DEVICE_UUID_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetUUID + */ +#define NVML_DEVICE_UUID_V2_BUFFER_SIZE 96 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetBoardPartNumber + */ +#define NVML_DEVICE_PART_NUMBER_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlSystemGetDriverVersion + */ +#define NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlSystemGetNVMLVersion + */ +#define NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE 80 + +/** + * Buffer size guaranteed to be large enough for storing GPU device names. + */ +#define NVML_DEVICE_NAME_BUFFER_SIZE 64 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetName + */ +#define NVML_DEVICE_NAME_V2_BUFFER_SIZE 96 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetSerial + */ +#define NVML_DEVICE_SERIAL_BUFFER_SIZE 30 + +/** + * Buffer size guaranteed to be large enough for \ref nvmlDeviceGetVbiosVersion + */ +#define NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE 32 + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlSystemQueries System Queries + * This chapter describes the queries that NVML can perform against the local system. These queries + * are not device-specific. + * @{ + */ +/***************************************************************************************************/ + +/** + * Retrieves the version of the system's graphics driver. + * + * For all products. + * + * The version identifier is an alphanumeric string. It will not exceed 80 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE. + * + * @param version Reference in which to return the version identifier + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + */ +nvmlReturn_t DECLDIR nvmlSystemGetDriverVersion(char *version, unsigned int length); + +/** + * Retrieves the version of the NVML library. + * + * For all products. + * + * The version identifier is an alphanumeric string. It will not exceed 80 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE. + * + * @param version Reference in which to return the version identifier + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + */ +nvmlReturn_t DECLDIR nvmlSystemGetNVMLVersion(char *version, unsigned int length); + +/** + * Retrieves the version of the CUDA driver. + * + * For all products. + * + * The CUDA driver version returned will be retreived from the currently installed version of CUDA. + * If the cuda library is not found, this function will return a known supported version number. + * + * @param cudaDriverVersion Reference in which to return the version identifier + * + * @return + * - \ref NVML_SUCCESS if \a cudaDriverVersion has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a cudaDriverVersion is NULL + */ +nvmlReturn_t DECLDIR nvmlSystemGetCudaDriverVersion(int *cudaDriverVersion); + +/** + * Retrieves the version of the CUDA driver from the shared library. + * + * For all products. + * + * The returned CUDA driver version by calling cuDriverGetVersion() + * + * @param cudaDriverVersion Reference in which to return the version identifier + * + * @return + * - \ref NVML_SUCCESS if \a cudaDriverVersion has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a cudaDriverVersion is NULL + * - \ref NVML_ERROR_LIBRARY_NOT_FOUND if \a libcuda.so.1 or libcuda.dll is not found + * - \ref NVML_ERROR_FUNCTION_NOT_FOUND if \a cuDriverGetVersion() is not found in the shared library + */ +nvmlReturn_t DECLDIR nvmlSystemGetCudaDriverVersion_v2(int *cudaDriverVersion); + +/** + * Macros for converting the CUDA driver version number to Major and Minor version numbers. + */ +#define NVML_CUDA_DRIVER_VERSION_MAJOR(v) ((v)/1000) +#define NVML_CUDA_DRIVER_VERSION_MINOR(v) (((v)%1000)/10) + +/** + * Gets name of the process with provided process id + * + * For all products. + * + * Returned process name is cropped to provided length. + * name string is encoded in ANSI. + * + * @param pid The identifier of the process + * @param name Reference in which to return the process name + * @param length The maximum allowed length of the string returned in \a name + * + * @return + * - \ref NVML_SUCCESS if \a name has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a name is NULL or \a length is 0. + * - \ref NVML_ERROR_NOT_FOUND if process doesn't exists + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetProcessName(unsigned int pid, char *name, unsigned int length); + +/** + * Retrieves the IDs and firmware versions for any Host Interface Cards (HICs) in the system. + * + * For S-class products. + * + * The \a hwbcCount argument is expected to be set to the size of the input \a hwbcEntries array. + * The HIC must be connected to an S-class system for it to be reported by this function. + * + * @param hwbcCount Size of hwbcEntries array + * @param hwbcEntries Array holding information about hwbc + * + * @return + * - \ref NVML_SUCCESS if \a hwbcCount and \a hwbcEntries have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if either \a hwbcCount or \a hwbcEntries is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a hwbcCount indicates that the \a hwbcEntries array is too small + */ +nvmlReturn_t DECLDIR nvmlSystemGetHicVersion(unsigned int *hwbcCount, nvmlHwbcEntry_t *hwbcEntries); + +/** + * Retrieve the set of GPUs that have a CPU affinity with the given CPU number + * For all products. + * Supported on Linux only. + * + * @param cpuNumber The CPU number + * @param count When zero, is set to the number of matching GPUs such that \a deviceArray + * can be malloc'd. When non-zero, \a deviceArray will be filled with \a count + * number of device handles. + * @param deviceArray An array of device handles for GPUs found with affinity to \a cpuNumber + * + * @return + * - \ref NVML_SUCCESS if \a deviceArray or \a count (if initially zero) has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a cpuNumber, or \a count is invalid, or \a deviceArray is NULL with a non-zero \a count + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or OS does not support this feature + * - \ref NVML_ERROR_UNKNOWN an error has occurred in underlying topology discovery + */ +nvmlReturn_t DECLDIR nvmlSystemGetTopologyGpuSet(unsigned int cpuNumber, unsigned int *count, nvmlDevice_t *deviceArray); + +/** + * Structure to store Driver branch information + */ +typedef struct +{ + unsigned int version; //!< The version number of this struct + char branch[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< driver branch +} nvmlSystemDriverBranchInfo_v1_t; +typedef nvmlSystemDriverBranchInfo_v1_t nvmlSystemDriverBranchInfo_t; +#define nvmlSystemDriverBranchInfo_v1 NVML_STRUCT_VERSION(SystemDriverBranchInfo, 1) + +/** + * Retrieves the driver branch of the NVIDIA driver installed on the system. + * + * For all products. + * + * The branch identifier is an alphanumeric string. It will not exceed 80 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE. + * + * @param branchInfo Pointer to the driver branch information structure \a nvmlSystemDriverBranchInfo_t + * @param length The maximum allowed length of the driver branch string + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a branchInfo is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetDriverBranch(nvmlSystemDriverBranchInfo_t *branchInfo, unsigned int length); + + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlUnitQueries Unit Queries + * This chapter describes that queries that NVML can perform against each unit. For S-class systems only. + * In each case the device is identified with an nvmlUnit_t handle. This handle is obtained by + * calling \ref nvmlUnitGetHandleByIndex(). + * @{ + */ +/***************************************************************************************************/ + + /** + * Retrieves the number of units in the system. + * + * For S-class products. + * + * @param unitCount Reference in which to return the number of units + * + * @return + * - \ref NVML_SUCCESS if \a unitCount has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unitCount is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetCount(unsigned int *unitCount); + +/** + * Acquire the handle for a particular unit, based on its index. + * + * For S-class products. + * + * Valid indices are derived from the \a unitCount returned by \ref nvmlUnitGetCount(). + * For example, if \a unitCount is 2 the valid indices are 0 and 1, corresponding to UNIT 0 and UNIT 1. + * + * The order in which NVML enumerates units has no guarantees of consistency between reboots. + * + * @param index The index of the target unit, >= 0 and < \a unitCount + * @param unit Reference in which to return the unit handle + * + * @return + * - \ref NVML_SUCCESS if \a unit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a index is invalid or \a unit is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetHandleByIndex(unsigned int index, nvmlUnit_t *unit); + +/** + * Retrieves the static information associated with a unit. + * + * For S-class products. + * + * See \ref nvmlUnitInfo_t for details on available unit info. + * + * @param unit The identifier of the target unit + * @param info Reference in which to return the unit information + * + * @return + * - \ref NVML_SUCCESS if \a info has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a info is NULL + */ +nvmlReturn_t DECLDIR nvmlUnitGetUnitInfo(nvmlUnit_t unit, nvmlUnitInfo_t *info); + +/** + * Retrieves the LED state associated with this unit. + * + * For S-class products. + * + * See \ref nvmlLedState_t for details on allowed states. + * + * @param unit The identifier of the target unit + * @param state Reference in which to return the current LED state + * + * @return + * - \ref NVML_SUCCESS if \a state has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a state is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlUnitSetLedState() + */ +nvmlReturn_t DECLDIR nvmlUnitGetLedState(nvmlUnit_t unit, nvmlLedState_t *state); + +/** + * Retrieves the PSU stats for the unit. + * + * For S-class products. + * + * See \ref nvmlPSUInfo_t for details on available PSU info. + * + * @param unit The identifier of the target unit + * @param psu Reference in which to return the PSU information + * + * @return + * - \ref NVML_SUCCESS if \a psu has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a psu is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetPsuInfo(nvmlUnit_t unit, nvmlPSUInfo_t *psu); + +/** + * Retrieves the temperature readings for the unit, in degrees C. + * + * For S-class products. + * + * Depending on the product, readings may be available for intake (type=0), + * exhaust (type=1) and board (type=2). + * + * @param unit The identifier of the target unit + * @param type The type of reading to take + * @param temp Reference in which to return the intake temperature + * + * @return + * - \ref NVML_SUCCESS if \a temp has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit or \a type is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetTemperature(nvmlUnit_t unit, unsigned int type, unsigned int *temp); + +/** + * Retrieves the fan speed readings for the unit. + * + * For S-class products. + * + * See \ref nvmlUnitFanSpeeds_t for details on available fan speed info. + * + * @param unit The identifier of the target unit + * @param fanSpeeds Reference in which to return the fan speed information + * + * @return + * - \ref NVML_SUCCESS if \a fanSpeeds has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid or \a fanSpeeds is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetFanSpeedInfo(nvmlUnit_t unit, nvmlUnitFanSpeeds_t *fanSpeeds); + +/** + * Retrieves the set of GPU devices that are attached to the specified unit. + * + * For S-class products. + * + * The \a deviceCount argument is expected to be set to the size of the input \a devices array. + * + * @param unit The identifier of the target unit + * @param deviceCount Reference in which to provide the \a devices array size, and + * to return the number of attached GPU devices + * @param devices Reference in which to return the references to the attached GPU devices + * + * @return + * - \ref NVML_SUCCESS if \a deviceCount and \a devices have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a deviceCount indicates that the \a devices array is too small + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit is invalid, either of \a deviceCount or \a devices is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlUnitGetDevices(nvmlUnit_t unit, unsigned int *deviceCount, nvmlDevice_t *devices); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceQueries Device Queries + * This chapter describes that queries that NVML can perform against each device. + * In each case the device is identified with an nvmlDevice_t handle. This handle is obtained by + * calling one of \ref nvmlDeviceGetHandleByIndex_v2(), \ref nvmlDeviceGetHandleBySerial(), + * \ref nvmlDeviceGetHandleByPciBusId_v2(). or \ref nvmlDeviceGetHandleByUUID(). + * @{ + */ +/***************************************************************************************************/ + + /** + * Retrieves the number of compute devices in the system. A compute device is a single GPU. + * + * For all products. + * + * Note: New nvmlDeviceGetCount_v2 (default in NVML 5.319) returns count of all devices in the system + * even if nvmlDeviceGetHandleByIndex_v2 returns NVML_ERROR_NO_PERMISSION for such device. + * Update your code to handle this error, or use NVML 4.304 or older nvml header file. + * For backward binary compatibility reasons _v1 version of the API is still present in the shared + * library. + * Old _v1 version of nvmlDeviceGetCount doesn't count devices that NVML has no permission to talk to. + * + * @param deviceCount Reference in which to return the number of accessible devices + * + * @return + * - \ref NVML_SUCCESS if \a deviceCount has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a deviceCount is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCount_v2(unsigned int *deviceCount); + +/** + * Get attributes (engine counts etc.) for the given NVML device handle. + * + * @note This API currently only supports MIG device handles. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device NVML device handle + * @param attributes Device attributes + * + * @return + * - \ref NVML_SUCCESS if \a device attributes were successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device handle is invalid + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAttributes_v2(nvmlDevice_t device, nvmlDeviceAttributes_t *attributes); + +/** + * Acquire the handle for a particular device, based on its index. + * + * For all products. + * + * Valid indices are derived from the \a accessibleDevices count returned by + * \ref nvmlDeviceGetCount_v2(). For example, if \a accessibleDevices is 2 the valid indices + * are 0 and 1, corresponding to GPU 0 and GPU 1. + * + * The order in which NVML enumerates devices has no guarantees of consistency between reboots. For that reason it + * is recommended that devices be looked up by their PCI ids or UUID. See + * \ref nvmlDeviceGetHandleByUUID() and \ref nvmlDeviceGetHandleByPciBusId_v2(). + * + * Note: The NVML index may not correlate with other APIs, such as the CUDA device index. + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs if: + * - The target GPU is an SLI slave + * + * Note: New nvmlDeviceGetCount_v2 (default in NVML 5.319) returns count of all devices in the system + * even if nvmlDeviceGetHandleByIndex_v2 returns NVML_ERROR_NO_PERMISSION for such device. + * Update your code to handle this error, or use NVML 4.304 or older nvml header file. + * For backward binary compatibility reasons _v1 version of the API is still present in the shared + * library. + * Old _v1 version of nvmlDeviceGetCount doesn't count devices that NVML has no permission to talk to. + * + * This means that nvmlDeviceGetHandleByIndex_v2 and _v1 can return different devices for the same index. + * If you don't touch macros that map old (_v1) versions to _v2 versions at the top of the file you don't + * need to worry about that. + * + * @param index The index of the target GPU, >= 0 and < \a accessibleDevices + * @param device Reference in which to return the device handle + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a index is invalid or \a device is NULL + * - \ref NVML_ERROR_INSUFFICIENT_POWER if any attached devices have improperly attached external power cables + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to talk to this device + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetIndex + * @see nvmlDeviceGetCount + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByIndex_v2(unsigned int index, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its board serial number. + * + * For Fermi &tm; or newer fully supported devices. + * + * This number corresponds to the value printed directly on the board, and to the value returned by + * \ref nvmlDeviceGetSerial(). + * + * @deprecated Since more than one GPU can exist on a single board this function is deprecated in favor + * of \ref nvmlDeviceGetHandleByUUID. + * For dual GPU boards this function will return NVML_ERROR_INVALID_ARGUMENT. + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs as it searches for the target GPU + * + * @param serial The board serial number of the target GPU + * @param device Reference in which to return the device handle + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a serial is invalid, \a device is NULL or more than one + * device has the same serial (dual GPU boards) + * - \ref NVML_ERROR_NOT_FOUND if \a serial does not match a valid device on the system + * - \ref NVML_ERROR_INSUFFICIENT_POWER if any attached devices have improperly attached external power cables + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if any GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetSerial + * @see nvmlDeviceGetHandleByUUID + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetHandleBySerial(const char *serial, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its globally unique immutable UUID (in ASCII format) associated with each device. + * + * For all products. + * + * @param uuid The UUID of the target GPU or MIG instance + * @param device Reference in which to return the device handle or MIG device handle + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs as it searches for the target GPU + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a uuid is invalid or \a device is null + * - \ref NVML_ERROR_NOT_FOUND if \a uuid does not match a valid device on the system + * - \ref NVML_ERROR_INSUFFICIENT_POWER if any attached devices have improperly attached external power cables + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if any GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetUUID + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByUUID(const char *uuid, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its globally unique immutable UUID (in either ASCII or binary format) associated with each device. + * See \ref nvmlUUID_v1_t for more information on the UUID struct. The caller must set the appropriate version prior to calling this API. + * + * For all products. + * + * @param[in] uuid The UUID of the target GPU or MIG instance + * @param[out] device Reference in which to return the device handle or MIG device handle + * + * This API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs as it searches for the target GPU + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a uuid is invalid, \a device is null or \a uuid->type is invalid + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_FOUND if \a uuid does not match a valid device on the system + * - \ref NVML_ERROR_GPU_IS_LOST if any GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByUUIDV(const nvmlUUID_t *uuid, nvmlDevice_t *device); + +/** + * Acquire the handle for a particular device, based on its PCI bus id. + * + * For all products. + * + * This value corresponds to the nvmlPciInfo_t::busId returned by \ref nvmlDeviceGetPciInfo_v3(). + * + * Starting from NVML 5, this API causes NVML to initialize the target GPU + * NVML may initialize additional GPUs if: + * - The target GPU is an SLI slave + * + * \note NVML 4.304 and older version of nvmlDeviceGetHandleByPciBusId"_v1" returns NVML_ERROR_NOT_FOUND + * instead of NVML_ERROR_NO_PERMISSION. + * + * @param pciBusId The PCI bus id of the target GPU + * Accept the following formats (all numbers in hexadecimal): + * domain:bus:device.function in format %x:%x:%x.%x + * domain:bus:device in format %x:%x:%x + * bus:device.function in format %x:%x.%x + * + * @param device Reference in which to return the device handle + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a pciBusId is invalid or \a device is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a pciBusId does not match a valid device on the system + * - \ref NVML_ERROR_INSUFFICIENT_POWER if the attached device has improperly attached external power cables + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to talk to this device + * - \ref NVML_ERROR_IRQ_ISSUE if NVIDIA kernel detected an interrupt issue with the attached GPUs + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByPciBusId_v2(const char *pciBusId, nvmlDevice_t *device); + +/** + * Retrieves the name of this device. + * + * For all products. + * + * The name is an alphanumeric string that denotes a particular product, e.g. Tesla &tm; C2070. It will not + * exceed 96 characters in length (including the NULL terminator). See \ref + * nvmlConstants::NVML_DEVICE_NAME_V2_BUFFER_SIZE. + * + * When used with MIG device handles the API returns MIG device names which can be used to identify devices + * based on their attributes. + * + * @param device The identifier of the target device + * @param name Reference in which to return the product name + * @param length The maximum allowed length of the string returned in \a name + * + * @return + * - \ref NVML_SUCCESS if \a name has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetName(nvmlDevice_t device, char *name, unsigned int length); + +/** + * Retrieves the brand of this device. + * + * For all products. + * + * The type is a member of \ref nvmlBrandType_t defined above. + * + * @param device The identifier of the target device + * @param type Reference in which to return the product brand type + * + * @return + * - \ref NVML_SUCCESS if \a name has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a type is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t *type); + +/** + * Retrieves the NVML index of this device. + * + * For all products. + * + * Valid indices are derived from the \a accessibleDevices count returned by + * \ref nvmlDeviceGetCount_v2(). For example, if \a accessibleDevices is 2 the valid indices + * are 0 and 1, corresponding to GPU 0 and GPU 1. + * + * The order in which NVML enumerates devices has no guarantees of consistency between reboots. For that reason it + * is recommended that devices be looked up by their PCI ids or GPU UUID. See + * \ref nvmlDeviceGetHandleByPciBusId_v2() and \ref nvmlDeviceGetHandleByUUID(). + * + * When used with MIG device handles this API returns indices that can be + * passed to \ref nvmlDeviceGetMigDeviceHandleByIndex to retrieve an identical handle. + * MIG device indices are unique within a device. + * + * Note: The NVML index may not correlate with other APIs, such as the CUDA device index. + * + * @param device The identifier of the target device + * @param index Reference in which to return the NVML index of the device + * + * @return + * - \ref NVML_SUCCESS if \a index has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a index is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetHandleByIndex() + * @see nvmlDeviceGetCount() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetIndex(nvmlDevice_t device, unsigned int *index); + +/** + * Retrieves the globally unique board serial number associated with this device's board. + * + * For all products with an inforom. + * + * The serial number is an alphanumeric string that will not exceed 30 characters (including the NULL terminator). + * This number matches the serial number tag that is physically attached to the board. See \ref + * nvmlConstants::NVML_DEVICE_SERIAL_BUFFER_SIZE. + * + * @param device The identifier of the target device + * @param serial Reference in which to return the board/module serial number + * @param length The maximum allowed length of the string returned in \a serial + * + * @return + * - \ref NVML_SUCCESS if \a serial has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a serial is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSerial(nvmlDevice_t device, char *serial, unsigned int length); + +/** + * Get a unique identifier for the device module on the baseboard + * + * This API retrieves a unique identifier for each GPU module that exists on a given baseboard. + * For non-baseboard products, this ID would always be 0. + * + * @param device The identifier of the target device + * @param moduleId Unique identifier for the GPU module + * + * @return + * - \ref NVML_SUCCESS if \a moduleId has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a moduleId is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetModuleId(nvmlDevice_t device, unsigned int *moduleId); + +/** + * Retrieves the Device's C2C Mode information + * + * @param device The identifier of the target device + * @param c2cModeInfo Output struct containing the device's C2C Mode info + * + * @return + * - \ref NVML_SUCCESS if \a C2C Mode Infor query is successful + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a serial is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetC2cModeInfoV(nvmlDevice_t device, nvmlC2cModeInfo_v1_t *c2cModeInfo); + +/***************************************************************************************************/ + +/** @defgroup nvmlAffinity CPU and Memory Affinity + * This chapter describes NVML operations that are associated with CPU and memory + * affinity. + * @{ + */ +/***************************************************************************************************/ + +//! Scope of NUMA node for affinity queries +#define NVML_AFFINITY_SCOPE_NODE 0 +//! Scope of processor socket for affinity queries +#define NVML_AFFINITY_SCOPE_SOCKET 1 + +typedef unsigned int nvmlAffinityScope_t; + +/** + * Retrieves an array of unsigned ints (sized to nodeSetSize) of bitmasks with + * the ideal memory affinity within node or socket for the device. + * For example, if NUMA node 0, 1 are ideal within the socket for the device and nodeSetSize == 1, + * result[0] = 0x3 + * + * \note If requested scope is not applicable to the target topology, the API + * will fall back to reporting the memory affinity for the immediate non-I/O + * ancestor of the device. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param nodeSetSize The size of the nodeSet array that is safe to access + * @param nodeSet Array reference in which to return a bitmask of NODEs, 64 NODEs per + * unsigned long on 64-bit machines, 32 on 32-bit machines + * @param scope Scope that change the default behavior + * + * @return + * - \ref NVML_SUCCESS if \a NUMA node Affinity has been filled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, nodeSetSize == 0, nodeSet is NULL or scope is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryAffinity(nvmlDevice_t device, unsigned int nodeSetSize, unsigned long *nodeSet, nvmlAffinityScope_t scope); + +/** + * Retrieves an array of unsigned ints (sized to cpuSetSize) of bitmasks with the + * ideal CPU affinity within node or socket for the device. + * For example, if processors 0, 1, 32, and 33 are ideal for the device and cpuSetSize == 2, + * result[0] = 0x3, result[1] = 0x3 + * + * \note If requested scope is not applicable to the target topology, the API + * will fall back to reporting the CPU affinity for the immediate non-I/O + * ancestor of the device. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param cpuSetSize The size of the cpuSet array that is safe to access + * @param cpuSet Array reference in which to return a bitmask of CPUs, 64 CPUs per + * unsigned long on 64-bit machines, 32 on 32-bit machines + * @param scope Scope that change the default behavior + * + * @return + * - \ref NVML_SUCCESS if \a cpuAffinity has been filled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, cpuSetSize == 0, cpuSet is NULL or sope is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceGetCpuAffinityWithinScope(nvmlDevice_t device, unsigned int cpuSetSize, unsigned long *cpuSet, nvmlAffinityScope_t scope); + +/** + * Retrieves an array of unsigned ints (sized to cpuSetSize) of bitmasks with the ideal CPU affinity for the device + * For example, if processors 0, 1, 32, and 33 are ideal for the device and cpuSetSize == 2, + * result[0] = 0x3, result[1] = 0x3 + * This is equivalent to calling \ref nvmlDeviceGetCpuAffinityWithinScope with \ref NVML_AFFINITY_SCOPE_NODE. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param cpuSetSize The size of the cpuSet array that is safe to access + * @param cpuSet Array reference in which to return a bitmask of CPUs, 64 CPUs per + * unsigned long on 64-bit machines, 32 on 32-bit machines + * + * @return + * - \ref NVML_SUCCESS if \a cpuAffinity has been filled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, cpuSetSize == 0, or cpuSet is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCpuAffinity(nvmlDevice_t device, unsigned int cpuSetSize, unsigned long *cpuSet); + +/** + * Sets the ideal affinity for the calling thread and device using the guidelines + * given in nvmlDeviceGetCpuAffinity(). Note, this is a change as of version 8.0. + * Older versions set the affinity for a calling process and all children. + * Currently supports up to 1024 processors. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if the calling process has been successfully bound + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetCpuAffinity(nvmlDevice_t device); + +/** + * Clear all affinity bindings for the calling thread. Note, this is a change as of version + * 8.0 as older versions cleared the affinity for a calling process and all children. + * + * For Kepler &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if the calling process has been successfully unbound + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceClearCpuAffinity(nvmlDevice_t device); + +/** + * Get the NUMA node of the given GPU device. + * This only applies to platforms where the GPUs are NUMA nodes. + * + * @param[in] device The device handle + * @param[out] node NUMA node ID of the device + * + * @returns + * - \ref NVML_SUCCESS if the NUMA node is retrieved successfully + * - \ref NVML_ERROR_NOT_SUPPORTED if request is not supported on the current platform + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device \a node is invalid + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNumaNodeId(nvmlDevice_t device, unsigned int *node); + +/** + * Get the addressing mode for a given GPU. Addressing modes can be one of: + * 1. HMM: System allocated memory (malloc, mmap) is addressable from the device (GPU), + * via software-based mirroring of the CPU's page tables, on the GPU. + * 2. ATS: System allocated memory (malloc, mmap) is addressable from the device (GPU), + * via Address Translation Services. This means that there is (effectively) + * a single set of page tables, and the CPU and GPU both use them. + * 3. None: Neither HMM nor ATS is active. + * + * For Turing &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param[in] device The device handle + * @param[out] mode Pointer to addressing mode of the device + * + * @returns + * - \ref NVML_SUCCESS if \a mode is retrieved successfully + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED if request is not supported on the current platform + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device \a node is invalid + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAddressingMode(nvmlDevice_t device, nvmlDeviceAddressingMode_t *mode); + +/** + * Get the repair status for TPC/Channel repair + * + * For Ampere &tm; or newer fully supported devices. + * + * @param[in] device The identifier of the target device + * @param[out] repairStatus Reference to \a nvmlRepairStatus_t + * + * @return + * - \ref NVML_SUCCESS if the query was successful + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the provided version is invalid/unsupported + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRepairStatus(nvmlDevice_t device, nvmlRepairStatus_t *repairStatus); + +/** + * Retrieve the common ancestor for two devices + * For all products. + * Supported on Linux only. + * + * @param device1 The identifier of the first device + * @param device2 The identifier of the second device + * @param pathInfo A \ref nvmlGpuTopologyLevel_t that gives the path type + * + * @return + * - \ref NVML_SUCCESS if \a pathInfo has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device1, or \a device2 is invalid, or \a pathInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or OS does not support this feature + * - \ref NVML_ERROR_UNKNOWN an error has occurred in underlying topology discovery + */ + +/** @} */ +nvmlReturn_t DECLDIR nvmlDeviceGetTopologyCommonAncestor(nvmlDevice_t device1, nvmlDevice_t device2, nvmlGpuTopologyLevel_t *pathInfo); + +/** + * Retrieve the set of GPUs that are nearest to a given device at a specific interconnectivity level + * For all products. + * Supported on Linux only. + * + * @param device The identifier of the first device + * @param level The \ref nvmlGpuTopologyLevel_t level to search for other GPUs + * @param count When zero, is set to the number of matching GPUs such that \a deviceArray + * can be malloc'd. When non-zero, \a deviceArray will be filled with \a count + * number of device handles. + * @param deviceArray An array of device handles for GPUs found at \a level + * + * @return + * - \ref NVML_SUCCESS if \a deviceArray or \a count (if initially zero) has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a level, or \a count is invalid, or \a deviceArray is NULL with a non-zero \a count + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or OS does not support this feature + * - \ref NVML_ERROR_UNKNOWN an error has occurred in underlying topology discovery + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTopologyNearestGpus(nvmlDevice_t device, nvmlGpuTopologyLevel_t level, unsigned int *count, nvmlDevice_t *deviceArray); + +/** + * Retrieve the status for a given p2p capability index between a given pair of GPU + * + * @param device1 The first device + * @param device2 The second device + * @param p2pIndex p2p Capability Index being looked for between \a device1 and \a device2 + * @param p2pStatus Reference in which to return the status of the \a p2pIndex + * between \a device1 and \a device2 + * @return + * - \ref NVML_SUCCESS if \a p2pStatus has been populated + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device1 or \a device2 or \a p2pIndex is invalid or \a p2pStatus is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetP2PStatus(nvmlDevice_t device1, nvmlDevice_t device2, nvmlGpuP2PCapsIndex_t p2pIndex,nvmlGpuP2PStatus_t *p2pStatus); + +/** + * Retrieves the globally unique immutable UUID associated with this device, as a 5 part hexadecimal string, + * that augments the immutable, board serial identifier. + * + * For all products. + * + * The UUID is a globally unique identifier. It is the only available identifier for pre-Fermi-architecture products. + * It does NOT correspond to any identifier printed on the board. It will not exceed 96 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_DEVICE_UUID_V2_BUFFER_SIZE. + * + * When used with MIG device handles the API returns globally unique UUIDs which can be used to identify MIG + * devices across both GPU and MIG devices. UUIDs are immutable for the lifetime of a MIG device. + * + * @param device The identifier of the target device + * @param uuid Reference in which to return the GPU UUID + * @param length The maximum allowed length of the string returned in \a uuid + * + * @return + * - \ref NVML_SUCCESS if \a uuid has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a uuid is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetUUID(nvmlDevice_t device, char *uuid, unsigned int length); + +/** + * Retrieves minor number for the device. The minor number for the device is such that the Nvidia device node file for + * each GPU will have the form /dev/nvidia[minor number]. + * + * For all products. + * Supported only for Linux + * + * @param device The identifier of the target device + * @param minorNumber Reference in which to return the minor number for the device + * @return + * - \ref NVML_SUCCESS if the minor number is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minorNumber is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMinorNumber(nvmlDevice_t device, unsigned int *minorNumber); + +/** + * Retrieves the the device board part number which is programmed into the board's InfoROM + * + * For all products. + * + * @param device Identifier of the target device + * @param partNumber Reference to the buffer to return + * @param length Length of the buffer reference + * + * @return + * - \ref NVML_SUCCESS if \a partNumber has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED if the needed VBIOS fields have not been filled + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a serial is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBoardPartNumber(nvmlDevice_t device, char* partNumber, unsigned int length); + +/** + * Retrieves the version information for the device's infoROM object. + * + * For all products with an inforom. + * + * Fermi and higher parts have non-volatile on-board memory for persisting device info, such as aggregate + * ECC counts. The version of the data structures in this memory may change from time to time. It will not + * exceed 16 characters in length (including the NULL terminator). + * See \ref nvmlConstants::NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE. + * + * See \ref nvmlInforomObject_t for details on the available infoROM objects. + * + * @param device The identifier of the target device + * @param object The target infoROM object + * @param version Reference in which to return the infoROM version + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have an infoROM + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetInforomImageVersion + */ +nvmlReturn_t DECLDIR nvmlDeviceGetInforomVersion(nvmlDevice_t device, nvmlInforomObject_t object, char *version, unsigned int length); + +/** + * Retrieves the global infoROM image version + * + * For all products with an inforom. + * + * Image version just like VBIOS version uniquely describes the exact version of the infoROM flashed on the board + * in contrast to infoROM object version which is only an indicator of supported features. + * Version string will not exceed 16 characters in length (including the NULL terminator). + * See \ref nvmlConstants::NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE. + * + * @param device The identifier of the target device + * @param version Reference in which to return the infoROM image version + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have an infoROM + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetInforomVersion + */ +nvmlReturn_t DECLDIR nvmlDeviceGetInforomImageVersion(nvmlDevice_t device, char *version, unsigned int length); + +/** + * Retrieves the checksum of the configuration stored in the device's infoROM. + * + * For all products with an inforom. + * + * Can be used to make sure that two GPUs have the exact same configuration. + * Current checksum takes into account configuration stored in PWR and ECC infoROM objects. + * Checksum can change between driver releases or when user changes configuration (e.g. disable/enable ECC) + * + * @param device The identifier of the target device + * @param checksum Reference in which to return the infoROM configuration checksum + * + * @return + * - \ref NVML_SUCCESS if \a checksum has been set + * - \ref NVML_ERROR_CORRUPTED_INFOROM if the device's checksum couldn't be retrieved due to infoROM corruption + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a checksum is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetInforomConfigurationChecksum(nvmlDevice_t device, unsigned int *checksum); + +/** + * Reads the infoROM from the flash and verifies the checksums. + * + * For all products with an inforom. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if infoROM is not corrupted + * - \ref NVML_ERROR_CORRUPTED_INFOROM if the device's infoROM is corrupted + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceValidateInforom(nvmlDevice_t device); + +/** + * Retrieves the timestamp and the duration of the last flush of the BBX (blackbox) infoROM object during the current run. + * + * For all products with an inforom. + * + * @param device The identifier of the target device + * @param timestamp The start timestamp of the last BBX Flush + * @param durationUs The duration (us) of the last BBX Flush + * + * @return + * - \ref NVML_SUCCESS if \a timestamp and \a durationUs are successfully retrieved + * - \ref NVML_ERROR_NOT_READY if the BBX object has not been flushed yet + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have an infoROM + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetInforomVersion + */ +nvmlReturn_t DECLDIR nvmlDeviceGetLastBBXFlushTime(nvmlDevice_t device, unsigned long long *timestamp, + unsigned long *durationUs); + +/** + * Retrieves the display mode for the device. + * + * For all products. + * + * This method indicates whether a physical display (e.g. monitor) is currently connected to + * any of the device's connectors. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param display Reference in which to return the display mode + * + * @return + * - \ref NVML_SUCCESS if \a display has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a display is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDisplayMode(nvmlDevice_t device, nvmlEnableState_t *display); + +/** + * Retrieves the display active state for the device. + * + * For all products. + * + * This method indicates whether a display is initialized on the device. + * For example whether X Server is attached to this device and has allocated memory for the screen. + * + * Display can be active even when no monitor is physically attached. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param isActive Reference in which to return the display active state + * + * @return + * - \ref NVML_SUCCESS if \a isActive has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a isActive is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDisplayActive(nvmlDevice_t device, nvmlEnableState_t *isActive); + +/** + * Retrieves the persistence mode associated with this device. + * + * For all products. + * For Linux only. + * + * When driver persistence mode is enabled the driver software state is not torn down when the last + * client disconnects. By default this feature is disabled. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current driver persistence mode + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetPersistenceMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPersistenceMode(nvmlDevice_t device, nvmlEnableState_t *mode); + +/** + * Retrieves PCI attributes of this device. + * + * For all products. + * + * See \ref nvmlPciInfoExt_v1_t for details on the available PCI info. + * + * @param device The identifier of the target device + * @param pci Reference in which to return the PCI info + * + * @return + * - \ref NVML_SUCCESS if \a pci has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pci is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfoExt(nvmlDevice_t device, nvmlPciInfoExt_t *pci); + +/** + * Retrieves the PCI attributes of this device. + * + * For all products. + * + * See \ref nvmlPciInfo_t for details on the available PCI info. + * + * @param device The identifier of the target device + * @param pci Reference in which to return the PCI info + * + * @return + * - \ref NVML_SUCCESS if \a pci has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pci is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfo_v3(nvmlDevice_t device, nvmlPciInfo_t *pci); + +/** + * Retrieves the maximum PCIe link generation possible with this device and system + * + * I.E. for a generation 2 PCIe device attached to a generation 1 PCIe bus the max link generation this function will + * report is generation 1. + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param maxLinkGen Reference in which to return the max PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a maxLinkGen has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a maxLinkGen is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxPcieLinkGeneration(nvmlDevice_t device, unsigned int *maxLinkGen); + +/** + * Retrieves the maximum PCIe link generation supported by this device + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param maxLinkGenDevice Reference in which to return the max PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a maxLinkGenDevice has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a maxLinkGenDevice is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuMaxPcieLinkGeneration(nvmlDevice_t device, unsigned int *maxLinkGenDevice); + +/** + * Retrieves the maximum PCIe link width possible with this device and system + * + * I.E. for a device with a 16x PCIe bus width attached to a 8x PCIe system bus this function will report + * a max link width of 8. + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param maxLinkWidth Reference in which to return the max PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a maxLinkWidth has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a maxLinkWidth is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxPcieLinkWidth(nvmlDevice_t device, unsigned int *maxLinkWidth); + +/** + * Retrieves the current PCIe link generation + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param currLinkGen Reference in which to return the current PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a currLinkGen has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a currLinkGen is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrPcieLinkGeneration(nvmlDevice_t device, unsigned int *currLinkGen); + +/** + * Retrieves the current PCIe link width + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param currLinkWidth Reference in which to return the current PCIe link generation + * + * @return + * - \ref NVML_SUCCESS if \a currLinkWidth has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a currLinkWidth is null + * - \ref NVML_ERROR_NOT_SUPPORTED if PCIe link information is not available + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrPcieLinkWidth(nvmlDevice_t device, unsigned int *currLinkWidth); + +/** + * Retrieve PCIe utilization information. + * This function is querying a byte counter over a 20ms interval and thus is the + * PCIe throughput over that interval. + * + * For Maxwell &tm; or newer fully supported devices. + * + * This method is not supported in virtual machines running virtual GPU (vGPU). + * + * @param device The identifier of the target device + * @param counter The specific counter that should be queried \ref nvmlPcieUtilCounter_t + * @param value Reference in which to return throughput in KB/s + * + * @return + * - \ref NVML_SUCCESS if \a value has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a counter is invalid, or \a value is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieThroughput(nvmlDevice_t device, nvmlPcieUtilCounter_t counter, unsigned int *value); + +/** + * Retrieve the PCIe replay counter. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param value Reference in which to return the counter's value + * + * @return + * - \ref NVML_SUCCESS if \a value has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a value is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieReplayCounter(nvmlDevice_t device, unsigned int *value); + +/** + * Retrieves the current clock speeds for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlClockType_t for details on available clock information. + * + * @param device The identifier of the target device + * @param type Identify which clock domain to query + * @param clock Reference in which to return the clock speed in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clock has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clock is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device cannot report the specified clock + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClockInfo(nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock); + +/** + * Retrieves the maximum clock speeds for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlClockType_t for details on available clock information. + * + * \note Current P0 clocks (reported by \ref nvmlDeviceGetClockInfo) can differ from max clocks + * by a few MHz. + * + * @param device The identifier of the target device + * @param type Identify which clock domain to query + * @param clock Reference in which to return the clock speed in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clock has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clock is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device cannot report the specified clock + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock); + +/** + * Retrieve the GPCCLK VF offset value + * @param[in] device The identifier of the target device + * @param[out] offset The retrieved GPCCLK VF offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpcClkVfOffset(nvmlDevice_t device, int *offset); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetApplicationsClock(nvmlDevice_t device, nvmlClockType_t clockType, unsigned int *clockMHz); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetDefaultApplicationsClock(nvmlDevice_t device, nvmlClockType_t clockType, unsigned int *clockMHz); + +/** + * Retrieves the clock speed for the clock specified by the clock type and clock ID. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param clockType Identify which clock domain to query + * @param clockId Identify which clock in the domain to query + * @param clockMHz Reference in which to return the clock in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clockMHz has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clockMHz is NULL or \a clockType is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClock(nvmlDevice_t device, nvmlClockType_t clockType, nvmlClockId_t clockId, unsigned int *clockMHz); + +/** + * Retrieves the customer defined maximum boost clock speed specified by the given clock type. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param clockType Identify which clock domain to query + * @param clockMHz Reference in which to return the clock in MHz + * + * @return + * - \ref NVML_SUCCESS if \a clockMHz has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clockMHz is NULL or \a clockType is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device or the \a clockType on this device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxCustomerBoostClock(nvmlDevice_t device, nvmlClockType_t clockType, unsigned int *clockMHz); + +/** + * Retrieves the list of possible memory clocks that can be used as an argument for \ref nvmlDeviceSetMemoryLockedClocks. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param count Reference in which to provide the \a clocksMHz array size, and + * to return the number of elements + * @param clocksMHz Reference in which to return the clock in MHz + * + * @return + * - \ref NVML_SUCCESS if \a count and \a clocksMHz have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a count is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small (\a count is set to the number of + * required elements) + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetMemoryLockedClocks + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedMemoryClocks(nvmlDevice_t device, unsigned int *count, unsigned int *clocksMHz); + +/** + * Retrieves the list of possible graphics clocks that can be used as an argument for \ref nvmlDeviceSetGpuLockedClocks. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param memoryClockMHz Memory clock for which to return possible graphics clocks + * @param count Reference in which to provide the \a clocksMHz array size, and + * to return the number of elements + * @param clocksMHz Reference in which to return the clocks in MHz + * + * @return + * - \ref NVML_SUCCESS if \a count and \a clocksMHz have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_FOUND if the specified \a memoryClockMHz is not a supported frequency + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clock is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetGpuLockedClocks + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedGraphicsClocks(nvmlDevice_t device, unsigned int memoryClockMHz, unsigned int *count, unsigned int *clocksMHz); + +/** + * Retrieve the current state of Auto Boosted clocks on a device and store it in \a isEnabled + * + * For Kepler &tm; or newer fully supported devices. + * + * Auto Boosted clocks are enabled by default on some hardware, allowing the GPU to run at higher clock rates + * to maximize performance as thermal limits allow. + * + * On Pascal and newer hardware, Auto Aoosted clocks are controlled through application clocks. + * Use \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks to control Auto Boost + * behavior. + * + * @param device The identifier of the target device + * @param isEnabled Where to store the current state of Auto Boosted clocks of the target device + * @param defaultIsEnabled Where to store the default Auto Boosted clocks behavior of the target device that the device will + * revert to when no applications are using the GPU + * + * @return + * - \ref NVML_SUCCESS If \a isEnabled has been been set with the Auto Boosted clocks state of \a device + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a isEnabled is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support Auto Boosted clocks + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAutoBoostedClocksEnabled(nvmlDevice_t device, nvmlEnableState_t *isEnabled, nvmlEnableState_t *defaultIsEnabled); + +/** + * Retrieves the intended operating speed of the device's fan. + * + * Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, the + * output will not match the actual fan speed. + * + * For all discrete products with dedicated fans. + * + * The fan speed is expressed as a percentage of the product's maximum noise tolerance fan speed. + * This value may exceed 100% in certain cases. + * + * @param device The identifier of the target device + * @param speed Reference in which to return the fan speed percentage + * + * @return + * - \ref NVML_SUCCESS if \a speed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a speed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanSpeed(nvmlDevice_t device, unsigned int *speed); + +/** + * Retrieves the intended operating speed of the device's specified fan. + * + * Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, the + * output will not match the actual fan speed. + * + * For all discrete products with dedicated fans. + * + * The fan speed is expressed as a percentage of the product's maximum noise tolerance fan speed. + * This value may exceed 100% in certain cases. + * + * @param device The identifier of the target device + * @param fan The index of the target fan, zero indexed. + * @param speed Reference in which to return the fan speed percentage + * + * @return + * - \ref NVML_SUCCESS if \a speed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a fan is not an acceptable index, or \a speed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan or is newer than Maxwell + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanSpeed_v2(nvmlDevice_t device, unsigned int fan, unsigned int * speed); + +/** + * Retrieves the intended operating speed in rotations per minute (RPM) of the device's specified fan. + * + * For Maxwell &tm; or newer fully supported devices. + * + * For all discrete products with dedicated fans. + * + * Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, the + * output will not match the actual fan speed. + * + * @param device The identifier of the target device + * @param fanSpeed Structure specifying the index of the target fan (input) and + * retrieved fan speed value (output) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, \a fan is not an acceptable + * index, or \a speed is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the \a device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanSpeedRPM(nvmlDevice_t device, nvmlFanSpeedInfo_t *fanSpeed); + +/** + * Retrieves the intended target speed of the device's specified fan. + * + * Normally, the driver dynamically adjusts the fan based on + * the needs of the GPU. But when user set fan speed using nvmlDeviceSetFanSpeed_v2, + * the driver will attempt to make the fan achieve the setting in + * nvmlDeviceSetFanSpeed_v2. The actual current speed of the fan + * is reported in nvmlDeviceGetFanSpeed_v2. + * + * For all discrete products with dedicated fans. + * + * The fan speed is expressed as a percentage of the product's maximum noise tolerance fan speed. + * This value may exceed 100% in certain cases. + * + * @param device The identifier of the target device + * @param fan The index of the target fan, zero indexed. + * @param targetSpeed Reference in which to return the fan speed percentage + * + * @return + * - \ref NVML_SUCCESS if \a speed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a fan is not an acceptable index, or \a speed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan or is newer than Maxwell + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTargetFanSpeed(nvmlDevice_t device, unsigned int fan, unsigned int *targetSpeed); + +/** + * Retrieves the min and max fan speed that user can set for the GPU fan. + * + * For all cuda-capable discrete products with fans + * + * @param device The identifier of the target device + * @param minSpeed The minimum speed allowed to set + * @param maxSpeed The maximum speed allowed to set + * + * return + * NVML_SUCCESS if speed has been adjusted + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if device is invalid + * NVML_ERROR_NOT_SUPPORTED if the device does not support this + * (doesn't have fans) + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMinMaxFanSpeed(nvmlDevice_t device, unsigned int * minSpeed, + unsigned int * maxSpeed); + +/** + * Gets current fan control policy. + * + * For Maxwell &tm; or newer fully supported devices. + * + * For all cuda-capable discrete products with fans + * + * device The identifier of the target \a device + * policy Reference in which to return the fan control \a policy + * + * return + * NVML_SUCCESS if \a policy has been populated + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a policy is null or the \a fan given doesn't reference + * a fan that exists. + * NVML_ERROR_NOT_SUPPORTED if the \a device is older than Maxwell + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFanControlPolicy_v2(nvmlDevice_t device, unsigned int fan, + nvmlFanControlPolicy_t *policy); + +/** + * Retrieves the number of fans on the device. + * + * For all discrete products with dedicated fans. + * + * @param device The identifier of the target device + * @param numFans The number of fans + * + * @return + * - \ref NVML_SUCCESS if \a fan number query was successful + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a numFans is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a fan + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNumFans(nvmlDevice_t device, unsigned int *numFans); + +/** + * @deprecated Use \ref nvmlDeviceGetTemperatureV instead + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetTemperature(nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp); + +/** + * Retrieves the cooler's information. + * Returns a cooler's control signal characteristics. The possible types are restricted, Variable and Toggle. + * See \ref nvmlCoolerControl_t for details on available signal types. + * Returns objects that cooler cools. Targets may be GPU, Memory, Power Supply or All of these. + * See \ref nvmlCoolerTarget_t for details on available targets. + * + * For Maxwell &tm; or newer fully supported devices. + * + * For all discrete products with dedicated fans. + * + * @param[in] device The identifier of the target device + * @param[out] coolerInfo Structure specifying the cooler's control signal characteristics (out) + * and the target that cooler cools (out) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, \a signalType or \a target is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the \a device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCoolerInfo(nvmlDevice_t device, nvmlCoolerInfo_t *coolerInfo); + +/** + * Structure used to encapsulate temperature info + */ +typedef struct +{ + unsigned int version; + nvmlTemperatureSensors_t sensorType; + int temperature; +} nvmlTemperature_v1_t; + +typedef nvmlTemperature_v1_t nvmlTemperature_t; + +#define nvmlTemperature_v1 NVML_STRUCT_VERSION(Temperature, 1) + +/** + * Retrieves the current temperature readings (in degrees C) for the given device. + * + * For all products. + * + * @param[in] device Target device identifier. + * @param[in,out] temperature Structure specifying the sensor type (input) and retrieved + * temperature value (output). + * + * @return + * - \ref NVML_SUCCESS if \a temp has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a sensorType is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have the specified sensor + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTemperatureV(nvmlDevice_t device, nvmlTemperature_t *temperature); + + +/** + * Retrieves the temperature threshold for the GPU with the specified threshold type in degrees C. + * + * For Kepler &tm; or newer fully supported devices. + * + * See \ref nvmlTemperatureThresholds_t for details on available temperature thresholds. + * + * Note: This API is no longer the preferred interface for retrieving the following temperature thresholds + * on Ada and later architectures: NVML_TEMPERATURE_THRESHOLD_SHUTDOWN, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN, + * NVML_TEMPERATURE_THRESHOLD_MEM_MAX and NVML_TEMPERATURE_THRESHOLD_GPU_MAX. + * + * Support for reading these temperature thresholds for Ada and later architectures would be removed from this + * API in future releases. Please use \ref nvmlDeviceGetFieldValues with NVML_FI_DEV_TEMPERATURE_* fields to retrieve + * temperature thresholds on these architectures. + * + * @param device The identifier of the target device + * @param thresholdType The type of threshold value queried + * @param temp Reference in which to return the temperature reading + * @return + * - \ref NVML_SUCCESS if \a temp has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a thresholdType is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a temperature sensor or is unsupported + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTemperatureThreshold(nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, unsigned int *temp); + +/** + * Retrieves the thermal margin temperature (distance to nearest slowdown threshold). + * + * @param[in] device The identifier of the target device + * @param[in,out] marginTempInfo Versioned structure in which to return the temperature reading + * + * @returns + * - \ref NVML_SUCCESS if the margin temperature was retrieved successfully + * - \ref NVML_ERROR_NOT_SUPPORTED if request is not supported on the current platform + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a temperature is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the right versioned structure is not used + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMarginTemperature(nvmlDevice_t device, nvmlMarginTemperature_t *marginTempInfo); + +/** + * Used to execute a list of thermal system instructions. + * + * @param device The identifier of the target device + * @param sensorIndex The index of the thermal sensor + * @param pThermalSettings Reference in which to return the thermal sensor information + * + * @return + * - \ref NVML_SUCCESS if \a pThermalSettings has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pThermalSettings is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetThermalSettings(nvmlDevice_t device, unsigned int sensorIndex, nvmlGpuThermalSettings_t *pThermalSettings); + +/** + * Retrieves the current performance state for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlPstates_t for details on allowed performance states. + * + * @param device The identifier of the target device + * @param pState Reference in which to return the performance state reading + * + * @return + * - \ref NVML_SUCCESS if \a pState has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pState is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPerformanceState(nvmlDevice_t device, nvmlPstates_t *pState); + +/** + * Retrieves current clocks event reasons. + * + * For all fully supported products. + * + * \note More than one bit can be enabled at the same time. Multiple reasons can be affecting clocks at once. + * + * @param device The identifier of the target device + * @param clocksEventReasons Reference in which to return bitmask of active clocks event + * reasons + * + * @return + * - \ref NVML_SUCCESS if \a clocksEventReasons has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a clocksEventReasons is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlClocksEventReasons + * @see nvmlDeviceGetSupportedClocksEventReasons + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClocksEventReasons(nvmlDevice_t device, unsigned long long *clocksEventReasons); + +/** + * @deprecated Use \ref nvmlDeviceGetCurrentClocksEventReasons instead + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClocksThrottleReasons(nvmlDevice_t device, unsigned long long *clocksThrottleReasons); + +/** + * Retrieves bitmask of supported clocks event reasons that can be returned by + * \ref nvmlDeviceGetCurrentClocksEventReasons + * + * For all fully supported products. + * + * This method is not supported in virtual machines running virtual GPU (vGPU). + * + * @param device The identifier of the target device + * @param supportedClocksEventReasons Reference in which to return bitmask of supported + * clocks event reasons + * + * @return + * - \ref NVML_SUCCESS if \a supportedClocksEventReasons has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a supportedClocksEventReasons is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlClocksEventReasons + * @see nvmlDeviceGetCurrentClocksEventReasons + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedClocksEventReasons(nvmlDevice_t device, unsigned long long *supportedClocksEventReasons); + +/** + * @deprecated Use \ref nvmlDeviceGetSupportedClocksEventReasons instead + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetSupportedClocksThrottleReasons(nvmlDevice_t device, unsigned long long *supportedClocksThrottleReasons); + +/** + * @deprecated Use \ref nvmlDeviceGetPerformanceState. This function exposes an incorrect generalization. + * + * Retrieve the current performance state for the device. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlPstates_t for details on allowed performance states. + * + * @param device The identifier of the target device + * @param pState Reference in which to return the performance state reading + * + * @return + * - \ref NVML_SUCCESS if \a pState has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pState is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetPowerState(nvmlDevice_t device, nvmlPstates_t *pState); + +/** + * Retrieve performance monitor samples from the associated subdevice. + * + * @param device + * @param pDynamicPstatesInfo + * + * @return + * - \ref NVML_SUCCESS if \a pDynamicPstatesInfo has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pDynamicPstatesInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDynamicPstatesInfo(nvmlDevice_t device, nvmlGpuDynamicPstatesInfo_t *pDynamicPstatesInfo); + +/** + * Retrieve the MemClk (Memory Clock) VF offset value. + * @param[in] device The identifier of the target device + * @param[out] offset The retrieved MemClk VF offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemClkVfOffset(nvmlDevice_t device, int *offset); + +/** + * Retrieve min and max clocks of some clock domain for a given PState + * + * @param device The identifier of the target device + * @param type Clock domain + * @param pstate PState to query + * @param minClockMHz Reference in which to return min clock frequency + * @param maxClockMHz Reference in which to return max clock frequency + * + * @return + * - \ref NVML_SUCCESS if everything worked + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a type or \a minClockMHz and \a maxClockMHz are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN if \a type or \a pstate are invalid or any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMinMaxClockOfPState(nvmlDevice_t device, nvmlClockType_t type, nvmlPstates_t pstate, + unsigned int * minClockMHz, unsigned int * maxClockMHz); + +/** + * Get all supported Performance States (P-States) for the device. + * + * The returned array would contain a contiguous list of valid P-States supported by + * the device. If the number of supported P-States is fewer than the size of the array + * supplied missing elements would contain \a NVML_PSTATE_UNKNOWN. + * + * The number of elements in the returned list will never exceed \a NVML_MAX_GPU_PERF_PSTATES. + * + * @param device The identifier of the target device + * @param pstates Container to return the list of performance states + * supported by device + * @param size Size of the supplied \a pstates array in bytes + * + * @return + * - \ref NVML_SUCCESS if \a pstates array has been retrieved + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if the the container supplied was not large enough to + * hold the resulting list + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a pstates is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support performance state readings + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedPerformanceStates(nvmlDevice_t device, + nvmlPstates_t *pstates, unsigned int size); + +/** + * Retrieve the GPCCLK min max VF offset value. + * @param[in] device The identifier of the target device + * @param[out] minOffset The retrieved GPCCLK VF min offset value + * @param[out] maxOffset The retrieved GPCCLK VF max offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpcClkMinMaxVfOffset(nvmlDevice_t device, + int *minOffset, int *maxOffset); + +/** + * Retrieve the MemClk (Memory Clock) min max VF offset value. + * @param[in] device The identifier of the target device + * @param[out] minOffset The retrieved MemClk VF min offset value + * @param[out] maxOffset The retrieved MemClk VF max offset value + * + * @return + * - \ref NVML_SUCCESS if \a offset has been successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemClkMinMaxVfOffset(nvmlDevice_t device, + int *minOffset, int *maxOffset); + +/** + * Retrieve min, max and current clock offset of some clock domain for a given PState + * + * For Maxwell &tm; or newer fully supported devices. + * + * Note: \ref nvmlDeviceGetGpcClkVfOffset, \ref nvmlDeviceGetMemClkVfOffset, \ref nvmlDeviceGetGpcClkMinMaxVfOffset and + * \ref nvmlDeviceGetMemClkMinMaxVfOffset will be deprecated in a future release. + Use \ref nvmlDeviceGetClockOffsets instead. + * + * @param device The identifier of the target device + * @param info Structure specifying the clock type (input) and the pstate (input) + * retrieved clock offset value (output), min clock offset (output) + * and max clock offset (output) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a type or \a pstate are invalid or both + * \a minClockOffsetMHz and \a maxClockOffsetMHz are NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClockOffsets(nvmlDevice_t device, nvmlClockOffset_t *info); + +/** + * Control current clock offset of some clock domain for a given PState + * + * For Maxwell &tm; or newer fully supported devices. + * + * Requires privileged user. + * + * @param device The identifier of the target device + * @param info Structure specifying the clock type (input), the pstate (input) + * and clock offset value (input) + * + * @return + * - \ref NVML_SUCCESS If everything worked + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_NO_PERMISSION If the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a type or \a pstate are invalid or both + * \a clockOffsetMHz is out of allowed range. + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + */ +nvmlReturn_t DECLDIR nvmlDeviceSetClockOffsets(nvmlDevice_t device, nvmlClockOffset_t *info); + +/** + * Retrieves a performance mode string with all the + * performance modes defined for this device along with their associated + * GPU Clock and Memory Clock values. + * Not all tokens will be reported on all GPUs, and additional tokens + * may be added in the future. + * For backwards compatibility we still provide nvclock and memclock; + * those are the same as nvclockmin and memclockmin. + * + * Note: These clock values take into account the offset + * set by clients through /ref nvmlDeviceSetClockOffsets. + * + * Maximum available Pstate (P15) shows the minimum performance level (0) and vice versa. + * + * Each performance modes are returned as a comma-separated list of + * "token=value" pairs. Each set of performance mode tokens are separated + * by a ";". Valid tokens: + * + * Token Value + * "perf" unsigned int - the Performance level + * "nvclock" unsigned int - the GPU clocks (in MHz) for the perf level + * "nvclockmin" unsigned int - the GPU clocks min (in MHz) for the perf level + * "nvclockmax" unsigned int - the GPU clocks max (in MHz) for the perf level + * "nvclockeditable" unsigned int - if the GPU clock domain is editable for the perf level + * "memclock" unsigned int - the memory clocks (in MHz) for the perf level + * "memclockmin" unsigned int - the memory clocks min (in MHz) for the perf level + * "memclockmax" unsigned int - the memory clocks max (in MHz) for the perf level + * "memclockeditable" unsigned int - if the memory clock domain is editable for the perf level + * "memtransferrate" unsigned int - the memory transfer rate (in MHz) for the perf level + * "memtransferratemin" unsigned int - the memory transfer rate min (in MHz) for the perf level + * "memtransferratemax" unsigned int - the memory transfer rate max (in MHz) for the perf level + * "memtransferrateeditable" unsigned int - if the memory transfer rate is editable for the perf level + * + * Example: + * + * perf=0, nvclock=324, nvclockmin=324, nvclockmax=324, nvclockeditable=0, + * memclock=324, memclockmin=324, memclockmax=324, memclockeditable=0, + * memtransferrate=648, memtransferratemin=648, memtransferratemax=648, + * memtransferrateeditable=0 ; + * perf=1, nvclock=324, nvclockmin=324, nvclockmax=640, nvclockeditable=0, + * memclock=810, memclockmin=810, memclockmax=810, memclockeditable=0, + * memtransferrate=1620, memtransferrate=1620, memtransferrate=1620, + * memtransferrateeditable=0 ; + * + * + * @param device The identifier of the target device + * @param perfModes Reference in which to return the performance level string + * + * @return + * - \ref NVML_SUCCESS if \a perfModes has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPerformanceModes(nvmlDevice_t device, nvmlDevicePerfModes_t *perfModes); + +/** + * Retrieves a string with the associated current GPU Clock and Memory Clock values. + * + * Not all tokens will be reported on all GPUs, and additional tokens + * may be added in the future. + * + * Note: These clock values take into account the offset + * set by clients through /ref nvmlDeviceSetClockOffsets. + * + * Clock values are returned as a comma-separated list of + * "token=value" pairs. + * Valid tokens: + * + * Token Value + * "perf" unsigned int - the Performance level + * "nvclock" unsigned int - the GPU clocks (in MHz) for the perf level + * "nvclockmin" unsigned int - the GPU clocks min (in MHz) for the perf level + * "nvclockmax" unsigned int - the GPU clocks max (in MHz) for the perf level + * "nvclockeditable" unsigned int - if the GPU clock domain is editable for the perf level + * "memclock" unsigned int - the memory clocks (in MHz) for the perf level + * "memclockmin" unsigned int - the memory clocks min (in MHz) for the perf level + * "memclockmax" unsigned int - the memory clocks max (in MHz) for the perf level + * "memclockeditable" unsigned int - if the memory clock domain is editable for the perf level + * "memtransferrate" unsigned int - the memory transfer rate (in MHz) for the perf level + * "memtransferratemin" unsigned int - the memory transfer rate min (in MHz) for the perf level + * "memtransferratemax" unsigned int - the memory transfer rate max (in MHz) for the perf level + * "memtransferrateeditable" unsigned int - if the memory transfer rate is editable for the perf level + * + * Example: + * + * nvclock=324, nvclockmin=324, nvclockmax=324, nvclockeditable=0, + * memclock=324, memclockmin=324, memclockmax=324, memclockeditable=0, + * memtransferrate=648, memtransferratemin=648, memtransferratemax=648, + * memtransferrateeditable=0 ; + * + * + * @param device The identifier of the target device + * @param currentClockFreqs Reference in which to return the performance level string + * + * @return + * - \ref NVML_SUCCESS if \a currentClockFreqs has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClockFreqs(nvmlDevice_t device, nvmlDeviceCurrentClockFreqs_t *currentClockFreqs); + +/** + * @deprecated This API has been deprecated. + * + * Retrieves the power management mode associated with this device. + * + * For products from the Fermi family. + * - Requires \a NVML_INFOROM_POWER version 3.0 or higher. + * + * For from the Kepler or newer families. + * - Does not require \a NVML_INFOROM_POWER object. + * + * This flag indicates whether any power management algorithm is currently active on the device. An + * enabled state does not necessarily mean the device is being actively throttled -- only that + * that the driver will do so if the appropriate conditions are met. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current power management mode + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementMode(nvmlDevice_t device, nvmlEnableState_t *mode); + +/** + * Retrieves the power management limit associated with this device. + * + * For Fermi &tm; or newer fully supported devices. + * + * The power limit defines the upper boundary for the card's power draw. If + * the card's total power draw reaches this limit the power management algorithm kicks in. + * + * This reading is only available if power management mode is supported. + * See \ref nvmlDeviceGetPowerManagementMode. + * + * @param device The identifier of the target device + * @param limit Reference in which to return the power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a limit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementLimit(nvmlDevice_t device, unsigned int *limit); + +/** + * Retrieves information about possible values of power management limits on this device. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param minLimit Reference in which to return the minimum power management limit in milliwatts + * @param maxLimit Reference in which to return the maximum power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a minLimit and \a maxLimit have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minLimit or \a maxLimit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetPowerManagementLimit + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementLimitConstraints(nvmlDevice_t device, unsigned int *minLimit, unsigned int *maxLimit); + +/** + * Retrieves default power management limit on this device, in milliwatts. + * Default power management limit is a power management limit that the device boots with. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param defaultLimit Reference in which to return the default power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a defaultLimit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a defaultLimit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerManagementDefaultLimit(nvmlDevice_t device, unsigned int *defaultLimit); + +/** + * Retrieves power usage for this GPU in milliwatts and its associated circuitry (e.g. memory) + * + * For Fermi &tm; or newer fully supported devices. + * + * On Fermi and Kepler GPUs the reading is accurate to within +/- 5% of current power draw. On Ampere + * (except GA100) or newer GPUs, the API returns power averaged over 1 sec interval. On GA100 and + * older architectures, instantaneous power is returned. + * + * See \ref NVML_FI_DEV_POWER_AVERAGE and \ref NVML_FI_DEV_POWER_INSTANT to query specific power + * values. + * + * It is only available if power management mode is supported. See \ref nvmlDeviceGetPowerManagementMode. + * + * @param device The identifier of the target device + * @param power Reference in which to return the power usage information + * + * @return + * - \ref NVML_SUCCESS if \a power has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a power is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support power readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerUsage(nvmlDevice_t device, unsigned int *power); + +/** + * Retrieves current power mizer mode on this device. + * + * PowerMizerMode provides a hint to the driver as to how to manage the performance of the GPU. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param powerMizerMode Reference in which to return the power mizer mode + * @param supportedPowerMizerModes Reference in which to return the bitmask of supported power mizer modes on this device. + * The supported modes can be combined using the bitwise OR operator '|'. + * For example, if a device supports all PowerMizer modes, the bitmask would be: + * supportedPowerMizerModes = ((1 << NVML_POWER_MIZER_MODE_ADAPTIVE) | + * (1 << NVML_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE) | + * (1 << NVML_POWER_MIZER_MODE_AUTO) | + * (1 << NVML_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE)); + * This bitmask can be used to check which power mizer modes are available on the device by performing + * a bitwise AND operation with the specific mode you want to check. + * + * @return + * - \ref NVML_SUCCESS if \a powerMizerMode has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a powerMizerMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support powerMizerMode readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceGetPowerMizerMode_v1(nvmlDevice_t device, nvmlDevicePowerMizerModes_v1_t *powerMizerMode); + +/** + * Sets the new power mizer mode. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param powerMizerMode Reference in which to set the power mizer mode. + * + * @return + * - \ref NVML_SUCCESS if \a powerMizerMode has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a powerMizerMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support powerMizerMode readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ + +nvmlReturn_t DECLDIR nvmlDeviceSetPowerMizerMode_v1(nvmlDevice_t device, nvmlDevicePowerMizerModes_v1_t *powerMizerMode); + + +/** + * Retrieves total energy consumption for this GPU in millijoules (mJ) since the driver was last reloaded + * + * For Volta &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param energy Reference in which to return the energy consumption information + * + * @return + * - \ref NVML_SUCCESS if \a energy has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a energy is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support energy readings + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTotalEnergyConsumption(nvmlDevice_t device, unsigned long long *energy); + +/** + * Get the effective power limit that the driver enforces after taking into account all limiters + * + * Note: This can be different from the \ref nvmlDeviceGetPowerManagementLimit if other limits are set elsewhere + * This includes the out of band power limit interface + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The device to communicate with + * @param limit Reference in which to return the power management limit in milliwatts + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a limit is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEnforcedPowerLimit(nvmlDevice_t device, unsigned int *limit); + +/** + * Retrieves the current GOM and pending GOM (the one that GPU will switch to after reboot). + * + * For GK110 M-class and X-class Tesla &tm; products from the Kepler family. + * Modes \ref NVML_GOM_LOW_DP and \ref NVML_GOM_ALL_ON are supported on fully supported GeForce products. + * Not supported on Quadro ® and Tesla &tm; C-class products. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current GOM + * @param pending Reference in which to return the pending GOM + * + * @return + * - \ref NVML_SUCCESS if \a mode has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a current or \a pending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlGpuOperationMode_t + * @see nvmlDeviceSetGpuOperationMode + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuOperationMode(nvmlDevice_t device, nvmlGpuOperationMode_t *current, nvmlGpuOperationMode_t *pending); + +/** + * Retrieves the amount of used, free, reserved and total memory available on the device, in bytes. + * The reserved amount is supported on version 2 only. + * + * For all products. + * + * Enabling ECC reduces the amount of total available memory, due to the extra required parity bits. + * Under WDDM most device memory is allocated and managed on startup by Windows. + * + * Under Linux and Windows TCC, the reported amount of used memory is equal to the sum of memory allocated + * by all active channels on the device. + * + * See \ref nvmlMemory_v2_t for details on available memory info. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate + * information, only if the caller has appropriate privileges. Per-instance + * information can be queried by using specific MIG device handles. + * + * @note nvmlDeviceGetMemoryInfo_v2 adds additional memory information. + * + * @note On systems where GPUs are NUMA nodes, the accuracy of FB memory utilization + * provided by this API depends on the memory accounting of the operating system. + * This is because FB memory is managed by the operating system instead of the NVIDIA GPU driver. + * Typically, pages allocated from FB memory are not released even after + * the process terminates to enhance performance. In scenarios where + * the operating system is under memory pressure, it may resort to utilizing FB memory. + * Such actions can result in discrepancies in the accuracy of memory reporting. + * + * @note On certain SOC platforms, the integrated GPU (iGPU) does not use a dedicated framebuffer + * but instead shares memory with the system. As a result, \ref NVML_ERROR_NOT_SUPPORTED + * will be returned in this case. + * + * @param device The identifier of the target device + * @param memory Reference in which to return the memory information + * + * @return + * - \ref NVML_SUCCESS if \a memory has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if video memory is unsupported on the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo(nvmlDevice_t device, nvmlMemory_t *memory); + +/** + * nvmlDeviceGetMemoryInfo_v2 accounts separately for reserved memory and includes it in the used memory amount. + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo_v2(nvmlDevice_t device, nvmlMemory_v2_t *memory); + +/** + * Retrieves the current compute mode for the device. + * + * For all products. + * + * See \ref nvmlComputeMode_t for details on allowed compute modes. + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current compute mode + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetComputeMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetComputeMode(nvmlDevice_t device, nvmlComputeMode_t *mode); + +/** + * Retrieves the CUDA compute capability of the device. + * + * For all products. + * + * Returns the major and minor compute capability version numbers of the + * device. The major and minor versions are equivalent to the + * CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR and + * CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR attributes that would be + * returned by CUDA's cuDeviceGetAttribute(). + * + * @param device The identifier of the target device + * @param major Reference in which to return the major CUDA compute capability + * @param minor Reference in which to return the minor CUDA compute capability + * + * @return + * - \ref NVML_SUCCESS if \a major and \a minor have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a major or \a minor are NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCudaComputeCapability(nvmlDevice_t device, int *major, int *minor); + +/** + * Retrieves the current and pending DRAM Encryption modes for the device. + * + * For Blackwell &tm; or newer fully supported devices. + * Only applicable to devices that support DRAM Encryption + * Requires \a NVML_INFOROM_DEN version 1.0 or higher. + * + * Changing DRAM Encryption modes requires a reboot. The "pending" DRAM Encryption mode refers to the target mode following + * the next reboot. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current DRAM Encryption mode + * @param pending Reference in which to return the pending DRAM Encryption mode + * + * @return + * - \ref NVML_SUCCESS if \a current and \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or either \a current or \a pending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the argument version is not supported + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetDramEncryptionMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDramEncryptionMode(nvmlDevice_t device, nvmlDramEncryptionInfo_t *current, nvmlDramEncryptionInfo_t *pending); + +/** + * Set the DRAM Encryption mode for the device. + * + * For Kepler &tm; or newer fully supported devices. + * Only applicable to devices that support DRAM Encryption. + * Requires \a NVML_INFOROM_DEN version 1.0 or higher. + * Requires root/admin permissions. + * + * The DRAM Encryption mode determines whether the GPU enables its DRAM Encryption support. + * + * This operation takes effect after the next reboot. + * + * See \ref nvmlEnableState_t for details on available modes. + * + * @param device The identifier of the target device + * @param dramEncryption The target DRAM Encryption mode + * + * @return + * - \ref NVML_SUCCESS if the DRAM Encryption mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a DRAM Encryption is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the argument version is not supported + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetDramEncryptionMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDramEncryptionMode(nvmlDevice_t device, const nvmlDramEncryptionInfo_t *dramEncryption); + +/** + * Retrieves the current and pending ECC modes for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * + * Changing ECC modes requires a reboot. The "pending" ECC mode refers to the target mode following + * the next reboot. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current ECC mode + * @param pending Reference in which to return the pending ECC mode + * + * @return + * - \ref NVML_SUCCESS if \a current and \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or either \a current or \a pending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetEccMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEccMode(nvmlDevice_t device, nvmlEnableState_t *current, nvmlEnableState_t *pending); + +/** + * Retrieves the default ECC modes for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * + * See \ref nvmlEnableState_t for details on allowed modes. + * + * @param device The identifier of the target device + * @param defaultMode Reference in which to return the default ECC mode + * + * @return + * - \ref NVML_SUCCESS if \a current and \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a default is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetEccMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDefaultEccMode(nvmlDevice_t device, nvmlEnableState_t *defaultMode); + +/** + * Retrieves the device boardId from 0-N. + * Devices with the same boardId indicate GPUs connected to the same PLX. Use in conjunction with + * \ref nvmlDeviceGetMultiGpuBoard() to decide if they are on the same board as well. + * The boardId returned is a unique ID for the current configuration. Uniqueness and ordering across + * reboots and system configurations is not guaranteed (i.e. if a Tesla K40c returns 0x100 and + * the two GPUs on a Tesla K10 in the same system returns 0x200 it is not guaranteed they will + * always return those values but they will always be different from each other). + * + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param boardId Reference in which to return the device's board ID + * + * @return + * - \ref NVML_SUCCESS if \a boardId has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a boardId is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBoardId(nvmlDevice_t device, unsigned int *boardId); + +/** + * Retrieves whether the device is on a Multi-GPU Board + * Devices that are on multi-GPU boards will set \a multiGpuBool to a non-zero value. + * + * For Fermi &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param multiGpuBool Reference in which to return a zero or non-zero value + * to indicate whether the device is on a multi GPU board + * + * @return + * - \ref NVML_SUCCESS if \a multiGpuBool has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a multiGpuBool is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMultiGpuBoard(nvmlDevice_t device, unsigned int *multiGpuBool); + +/** + * Retrieves the total ECC error counts for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * Requires ECC Mode to be enabled. + * + * The total error count is the sum of errors across each of the separate memory systems, i.e. the total set of + * errors across the entire device. + * + * See \ref nvmlMemoryErrorType_t for a description of available error types.\n + * See \ref nvmlEccCounterType_t for a description of available counter types. + * + * @param device The identifier of the target device + * @param errorType Flag that specifies the type of the errors. + * @param counterType Flag that specifies the counter-type of the errors. + * @param eccCounts Reference in which to return the specified ECC errors + * + * @return + * - \ref NVML_SUCCESS if \a eccCounts has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a errorType or \a counterType is invalid, or \a eccCounts is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceClearEccErrorCounts() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetTotalEccErrors(nvmlDevice_t device, nvmlMemoryErrorType_t errorType, nvmlEccCounterType_t counterType, unsigned long long *eccCounts); + +/** + * Retrieves the detailed ECC error counts for the device. + * + * @deprecated This API supports only a fixed set of ECC error locations + * On different GPU architectures different locations are supported + * See \ref nvmlDeviceGetMemoryErrorCounter + * + * For Fermi &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 2.0 or higher to report aggregate location-based ECC counts. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher to report all other ECC counts. + * Requires ECC Mode to be enabled. + * + * Detailed errors provide separate ECC counts for specific parts of the memory system. + * + * Reports zero for unsupported ECC error counters when a subset of ECC error counters are supported. + * + * See \ref nvmlMemoryErrorType_t for a description of available bit types.\n + * See \ref nvmlEccCounterType_t for a description of available counter types.\n + * See \ref nvmlEccErrorCounts_t for a description of provided detailed ECC counts. + * + * @param device The identifier of the target device + * @param errorType Flag that specifies the type of the errors. + * @param counterType Flag that specifies the counter-type of the errors. + * @param eccCounts Reference in which to return the specified ECC errors + * + * @return + * - \ref NVML_SUCCESS if \a eccCounts has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a errorType or \a counterType is invalid, or \a eccCounts is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceClearEccErrorCounts() + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetDetailedEccErrors(nvmlDevice_t device, nvmlMemoryErrorType_t errorType, nvmlEccCounterType_t counterType, nvmlEccErrorCounts_t *eccCounts); + +/** + * Retrieves the requested memory error counter for the device. + * + * For Fermi &tm; or newer fully supported devices. + * Requires \a NVML_INFOROM_ECC version 2.0 or higher to report aggregate location-based memory error counts. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher to report all other memory error counts. + * + * Only applicable to devices with ECC. + * + * Requires ECC Mode to be enabled. + * + * @note On MIG-enabled GPUs, per instance information can be queried using specific + * MIG device handles. Per instance information is currently only supported for + * non-DRAM uncorrectable volatile errors. Querying volatile errors using device + * handles is currently not supported. + * + * See \ref nvmlMemoryErrorType_t for a description of available memory error types.\n + * See \ref nvmlEccCounterType_t for a description of available counter types.\n + * See \ref nvmlMemoryLocation_t for a description of available counter locations.\n + * + * @param device The identifier of the target device + * @param errorType Flag that specifies the type of error. + * @param counterType Flag that specifies the counter-type of the errors. + * @param locationType Specifies the location of the counter. + * @param count Reference in which to return the ECC counter + * + * @return + * - \ref NVML_SUCCESS if \a count has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a bitTyp,e \a counterType or \a locationType is + * invalid, or \a count is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support ECC error reporting in the specified memory + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryErrorCounter(nvmlDevice_t device, nvmlMemoryErrorType_t errorType, + nvmlEccCounterType_t counterType, + nvmlMemoryLocation_t locationType, unsigned long long *count); + +/** + * Retrieves the current utilization rates for the device's major subsystems. + * + * For Fermi &tm; or newer fully supported devices. + * + * See \ref nvmlUtilization_t for details on available utilization rates. + * + * \note During driver initialization when ECC is enabled one can see high GPU and Memory Utilization readings. + * This is caused by ECC Memory Scrubbing mechanism that is performed during driver initialization. + * + * @note On MIG-enabled GPUs, querying device utilization rates is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference in which to return the utilization information + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a utilization is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetUtilizationRates(nvmlDevice_t device, nvmlUtilization_t *utilization); + +/** + * Retrieves the current utilization and sampling size in microseconds for the Encoder + * + * For Kepler &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying encoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for encoder utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** + * Retrieves the current capacity of the device's encoder, as a percentage of maximum encoder capacity with valid values in the range 0-100. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param encoderQueryType Type of encoder to query + * @param encoderCapacity Reference to an unsigned int for the encoder capacity + * + * @return + * - \ref NVML_SUCCESS if \a encoderCapacity is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a encoderCapacity is NULL, or \a device or \a encoderQueryType + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if device does not support the encoder specified in \a encodeQueryType + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderCapacity (nvmlDevice_t device, nvmlEncoderType_t encoderQueryType, unsigned int *encoderCapacity); + +/** + * Retrieves the current encoder statistics for a given device. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param sessionCount Reference to an unsigned int for count of active encoder sessions + * @param averageFps Reference to an unsigned int for trailing average FPS of all active sessions + * @param averageLatency Reference to an unsigned int for encode latency in microseconds + * + * @return + * - \ref NVML_SUCCESS if \a sessionCount, \a averageFps and \a averageLatency is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount, or \a device or \a averageFps, + * or \a averageLatency is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderStats (nvmlDevice_t device, unsigned int *sessionCount, + unsigned int *averageFps, unsigned int *averageLatency); + +/** + * Retrieves information about active encoder sessions on a target device. + * + * An array of active encoder sessions is returned in the caller-supplied buffer pointed at by \a sessionInfos. The + * array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions + * written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the active session array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlEncoderSessionInfo_t array required in \a sessionCount. + * To query the number of active encoder sessions, call this function with *sessionCount = 0. The code will return + * NVML_SUCCESS with number of active encoder sessions updated in *sessionCount. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param sessionCount Reference to caller supplied array size, and returns the number of sessions. + * @param sessionInfos Reference in which to return the session information + * + * @return + * - \ref NVML_SUCCESS if \a sessionInfos is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is returned in \a sessionCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount is NULL. + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetEncoderSessions(nvmlDevice_t device, unsigned int *sessionCount, nvmlEncoderSessionInfo_t *sessionInfos); + +/** + * Retrieves the current utilization and sampling size in microseconds for the Decoder + * + * For Kepler &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for decoder utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDecoderUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** + * Retrieves the current utilization and sampling size in microseconds for the JPG + * + * For Turing &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for jpg utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetJpgUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** + * Retrieves the current utilization and sampling size in microseconds for the OFA (Optical Flow Accelerator) + * + * For Turing &tm; or newer fully supported devices. + * + * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Reference to an unsigned int for ofa utilization info + * @param samplingPeriodUs Reference to an unsigned int for the sampling period in US + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetOfaUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs); + +/** +* Retrieves the active frame buffer capture sessions statistics for a given device. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @param device The identifier of the target device +* @param fbcStats Reference to nvmlFBCStats_t structure containing NvFBC stats +* +* @return +* - \ref NVML_SUCCESS if \a fbcStats is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a fbcStats is NULL +* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetFBCStats(nvmlDevice_t device, nvmlFBCStats_t *fbcStats); + +/** +* Retrieves information about active frame buffer capture sessions on a target device. +* +* An array of active FBC sessions is returned in the caller-supplied buffer pointed at by \a sessionInfo. The +* array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions +* written to the buffer. +* +* If the supplied buffer is not large enough to accommodate the active session array, the function returns +* NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlFBCSessionInfo_t array required in \a sessionCount. +* To query the number of active FBC sessions, call this function with *sessionCount = 0. The code will return +* NVML_SUCCESS with number of active FBC sessions updated in *sessionCount. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @note hResolution, vResolution, averageFPS and averageLatency data for a FBC session returned in \a sessionInfo may +* be zero if there are no new frames captured since the session started. +* +* @param device The identifier of the target device +* @param sessionCount Reference to caller supplied array size, and returns the number of sessions. +* @param sessionInfo Reference in which to return the session information +* +* @return +* - \ref NVML_SUCCESS if \a sessionInfo is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is returned in \a sessionCount +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount is NULL. +* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetFBCSessions(nvmlDevice_t device, unsigned int *sessionCount, nvmlFBCSessionInfo_t *sessionInfo); + +/** + * Retrieves the current and pending driver model for the device. + * + * For Kepler &tm; or newer fully supported devices. + * For windows only. + * + * On Windows platforms the device driver can run in either WDDM, MCDM or WDM (TCC) modes. If a display is attached + * to the device it must run in WDDM mode. MCDM mode is preferred if a display is not attached. TCC mode is deprecated. + * + * See \ref nvmlDriverModel_t for details on available driver models. + * + * @param device The identifier of the target device + * @param current Reference in which to return the current driver model + * @param pending Reference in which to return the pending driver model + * + * @return + * - \ref NVML_SUCCESS if either \a current and/or \a pending have been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or both \a current and \a pending are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the platform is not windows + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetDriverModel_v2() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDriverModel_v2(nvmlDevice_t device, nvmlDriverModel_t *current, nvmlDriverModel_t *pending); + +/** + * Get VBIOS version of the device. + * + * For all products. + * + * The VBIOS version may change from time to time. It will not exceed 32 characters in length + * (including the NULL terminator). See \ref nvmlConstants::NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE. + * + * @param device The identifier of the target device + * @param version Reference to which to return the VBIOS version + * @param length The maximum allowed length of the string returned in \a version + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a version is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVbiosVersion(nvmlDevice_t device, char *version, unsigned int length); + +/** + * Get Bridge Chip Information for all the bridge chips on the board. + * + * For all fully supported products. + * Only applicable to multi-GPU products. + * + * @param device The identifier of the target device + * @param bridgeHierarchy Reference to the returned bridge chip Hierarchy + * + * @return + * - \ref NVML_SUCCESS if bridge chip exists + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a bridgeInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if bridge chip not supported on the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBridgeChipInfo(nvmlDevice_t device, nvmlBridgeChipHierarchy_t *bridgeHierarchy); + +/** + * Get information about processes with a compute context on a device + * + * For Fermi &tm; or newer fully supported devices. + * + * This function returns information only about compute running processes (e.g. CUDA application which have + * active context). Any graphics applications (e.g. using OpenGL, DirectX) won't be listed by this function. + * + * To query the current number of running compute processes, call this function with *infoCount = 0. The + * return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if none are running. For this call + * \a infos is allowed to be NULL. + * + * The usedGpuMemory field returned is all of the memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a infos table in case new compute processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in vGPU Host virtualization mode. + * + * @param device The device handle or MIG device handle + * @param infoCount Reference in which to provide the \a infos array size, and + * to return the number of returned elements + * @param infos Reference in which to return the process information + * + * @return + * - \ref NVML_SUCCESS if \a infoCount and \a infos have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a infoCount indicates that the \a infos array is too small + * \a infoCount will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, either of \a infoCount or \a infos is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see \ref nvmlSystemGetProcessName + */ +nvmlReturn_t DECLDIR nvmlDeviceGetComputeRunningProcesses_v3(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_t *infos); + +/** + * Get information about processes with a graphics context on a device + * + * For Kepler &tm; or newer fully supported devices. + * + * This function returns information only about graphics based processes + * (eg. applications using OpenGL, DirectX) + * + * To query the current number of running graphics processes, call this function with *infoCount = 0. The + * return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if none are running. For this call + * \a infos is allowed to be NULL. + * + * The usedGpuMemory field returned is all of the memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a infos table in case new graphics processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in vGPU Host virtualization mode. + * + * @param device The device handle or MIG device handle + * @param infoCount Reference in which to provide the \a infos array size, and + * to return the number of returned elements + * @param infos Reference in which to return the process information + * + * @return + * - \ref NVML_SUCCESS if \a infoCount and \a infos have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a infoCount indicates that the \a infos array is too small + * \a infoCount will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, either of \a infoCount or \a infos is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see \ref nvmlSystemGetProcessName + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGraphicsRunningProcesses_v3(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_t *infos); + +/** + * Get information about processes with a Multi-Process Service (MPS) compute context on a device + * + * For Volta &tm; or newer fully supported devices. + * + * This function returns information only about compute running processes (e.g. CUDA application which have + * active context) utilizing MPS. Any graphics applications (e.g. using OpenGL, DirectX) won't be listed by + * this function. + * + * To query the current number of running compute processes, call this function with *infoCount = 0. The + * return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if none are running. For this call + * \a infos is allowed to be NULL. + * + * The usedGpuMemory field returned is all of the memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a infos table in case new compute processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in vGPU Host virtualization mode. + * + * @param device The device handle or MIG device handle + * @param infoCount Reference in which to provide the \a infos array size, and + * to return the number of returned elements + * @param infos Reference in which to return the process information + * + * @return + * - \ref NVML_SUCCESS if \a infoCount and \a infos have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a infoCount indicates that the \a infos array is too small + * \a infoCount will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, either of \a infoCount or \a infos is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see \ref nvmlSystemGetProcessName + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses_v3(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_t *infos); + +/** + * Get information about running processes on a device for input context + * + * For Hopper &tm; or newer fully supported devices. + * + * This function returns information only about running processes (e.g. CUDA application which have + * active context). + * + * To determine the size of the \a plist->procArray array to allocate, call the function with + * \a plist->numProcArrayEntries set to zero and \a plist->procArray set to NULL. The return + * code will be either NVML_ERROR_INSUFFICIENT_SIZE (if there are valid processes of type + * \a plist->mode to report on, in which case the \a plist->numProcArrayEntries field will + * indicate the required number of entries in the array) or NVML_SUCCESS (if no processes of type + * \a plist->mode exist). + * + * The usedGpuMemory field returned is all of the memory used by the application. + * The usedGpuCcProtectedMemory field returned is all of the protected memory used by the application. + * + * Keep in mind that information returned by this call is dynamic and the number of elements might change in + * time. Allocate more space for \a plist->procArray table in case new processes are spawned. + * + * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if + * the caller has appropriate privileges. Per-instance information can be queried by using + * specific MIG device handles. + * Querying per-instance information using MIG device handles is not supported if the device is in + * vGPU Host virtualization mode. + * Protected memory usage is currently not available in MIG mode and in windows. + * + * @param device The device handle or MIG device handle + * @param plist Reference in which to process detail list + * \a plist->version The api version + * \a plist->mode The process mode + * \a plist->procArray Reference in which to return the process information + * \a plist->numProcArrayEntries Proc array size of returned entries + * + * @return + * - \ref NVML_SUCCESS if \a plist->numprocArrayEntries and \a plist->procArray have been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a plist->numprocArrayEntries indicates that the \a plist->procArray is too small + * \a plist->numprocArrayEntries will contain minimal amount of space necessary for + * the call to complete + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a plist is NULL, \a plist->version is invalid, + * \a plist->mode is invalid, + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by \a device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRunningProcessDetailList(nvmlDevice_t device, nvmlProcessDetailList_t *plist); + +/** + * Check if the GPU devices are on the same physical board. + * + * For all fully supported products. + * + * @param device1 The first GPU device + * @param device2 The second GPU device + * @param onSameBoard Reference in which to return the status. + * Non-zero indicates that the GPUs are on the same board. + * + * @return + * - \ref NVML_SUCCESS if \a onSameBoard has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a dev1 or \a dev2 are invalid or \a onSameBoard is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this check is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the either GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceOnSameBoard(nvmlDevice_t device1, nvmlDevice_t device2, int *onSameBoard); + +/** + * Retrieves the root/admin permissions on the target API. See \a nvmlRestrictedAPI_t for the list of supported APIs. + * If an API is restricted only root users can call that API. See \a nvmlDeviceSetAPIRestriction to change current permissions. + * + * For all fully supported products. + * + * @param device The identifier of the target device + * @param apiType Target API type for this operation + * @param isRestricted Reference in which to return the current restriction + * NVML_FEATURE_ENABLED indicates that the API is root-only + * NVML_FEATURE_DISABLED indicates that the API is accessible to all users + * + * @return + * - \ref NVML_SUCCESS if \a isRestricted has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a apiType incorrect or \a isRestricted is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device or the device does not support + * the feature that is being queried (E.G. Enabling/disabling Auto Boosted clocks is + * not supported by the device) + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlRestrictedAPI_t + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAPIRestriction(nvmlDevice_t device, nvmlRestrictedAPI_t apiType, nvmlEnableState_t *isRestricted); + +/** + * Gets recent samples for the GPU. + * + * For Kepler &tm; or newer fully supported devices. + * + * Based on type, this method can be used to fetch the power, utilization or clock samples maintained in the buffer by + * the driver. + * + * Power, Utilization and Clock samples are returned as type "unsigned int" for the union nvmlValue_t. + * + * To get the size of samples that user needs to allocate, the method is invoked with samples set to NULL. + * The returned samplesCount will provide the number of samples that can be queried. The user needs to + * allocate the buffer with size as samplesCount * sizeof(nvmlSample_t). + * + * lastSeenTimeStamp represents CPU timestamp in microseconds. Set it to 0 to fetch all the samples maintained by the + * underlying buffer. Set lastSeenTimeStamp to one of the timeStamps retrieved from the date of the previous query + * to get more recent samples. + * + * This method fetches the number of entries which can be accommodated in the provided samples array, and the + * reference samplesCount is updated to indicate how many samples were actually retrieved. The advantage of using this + * method for samples in contrast to polling via existing methods is to get get higher frequency data at lower polling cost. + * + * @note On MIG-enabled GPUs, querying the following sample types, NVML_GPU_UTILIZATION_SAMPLES, NVML_MEMORY_UTILIZATION_SAMPLES + * NVML_ENC_UTILIZATION_SAMPLES and NVML_DEC_UTILIZATION_SAMPLES, is not currently supported. + * + * @param device The identifier for the target device + * @param type Type of sampling event + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + * @param sampleValType Output parameter to represent the type of sample value as described in nvmlSampleVal_t + * @param sampleCount Reference to provide the number of elements which can be queried in samples array + * @param samples Reference in which samples are returned + + * @return + * - \ref NVML_SUCCESS if samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a samplesCount is NULL or + * reference to \a sampleCount is 0 for non null \a samples + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSamples(nvmlDevice_t device, nvmlSamplingType_t type, unsigned long long lastSeenTimeStamp, + nvmlValueType_t *sampleValType, unsigned int *sampleCount, nvmlSample_t *samples); + +/** + * Gets Total, Available and Used size of BAR1 memory. + * + * BAR1 is used to map the FB (device memory) so that it can be directly accessed by the CPU or by 3rd party + * devices (peer-to-peer on the PCIE bus). + * + * @note In MIG mode, if device handle is provided, the API returns aggregate + * information, only if the caller has appropriate privileges. Per-instance + * information can be queried by using specific MIG device handles. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param bar1Memory Reference in which BAR1 memory + * information is returned. + * + * @return + * - \ref NVML_SUCCESS if BAR1 memory is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a bar1Memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBAR1MemoryInfo(nvmlDevice_t device, nvmlBAR1Memory_t *bar1Memory); + +/** + * @deprecated Use \ref nvmlDeviceGetFieldValues to query this data. + * This API will be removed in CUDA 14.0. + * + * Translations are as follows: + + * + * NVML_PERF_POLICY_POWER -> NVML_FI_DEV_CLOCKS_EVENT_REASON_SW_POWER_CAP + * NVML_PERF_POLICY_THERMAL -> NVML_FI_DEV_CLOCKS_EVENT_REASON_SW_THERM_SLOWDOWN + * NVML_PERF_POLICY_SYNC_BOOST -> NVML_FI_DEV_CLOCKS_EVENT_REASON_SYNC_BOOST + * NVML_PERF_POLICY_BOARD_LIMIT -> NVML_FI_DEV_PERF_POLICY_BOARD_LIMIT + * NVML_PERF_POLICY_LOW_UTILIZATION -> NVML_FI_DEV_PERF_POLICY_LOW_UTILIZATION + * NVML_PERF_POLICY_RELIABILITY -> NVML_FI_DEV_PERF_POLICY_RELIABILITY + * NVML_PERF_POLICY_TOTAL_APP_CLOCKS -> DEPRECATED, Do not use + * NVML_PERF_POLICY_TOTAL_BASE_CLOCKS -> NVML_FI_DEV_PERF_POLICY_TOTAL_BASE_CLOCKS + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetViolationStatus(nvmlDevice_t device, nvmlPerfPolicyType_t perfPolicyType, nvmlViolationTime_t *violTime); + +/** + * Gets the device's interrupt number + * + * @param device The identifier of the target device + * @param irqNum The interrupt number associated with the specified device + * + * @return + * - \ref NVML_SUCCESS if irq number is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a irqNum is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetIrqNum(nvmlDevice_t device, unsigned int *irqNum); + +/** + * Gets the device's core count + * + * @note On MIG-enabled GPUs, querying the device's core count is currently not supported using this API. + * Please use \ref nvmlDeviceGetGpuInstanceProfileInfo to fetch the MIG device's core count. + * + * @param device The identifier of the target device + * @param numCores The number of cores for the specified device + * + * @return + * - \ref NVML_SUCCESS if GPU core count is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a numCores is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device or a mig device. + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNumGpuCores(nvmlDevice_t device, unsigned int *numCores); + +/** + * Gets the devices power source + * + * @param device The identifier of the target device + * @param powerSource The power source of the device + * + * @return + * - \ref NVML_SUCCESS if the current power source was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a powerSource is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPowerSource(nvmlDevice_t device, nvmlPowerSource_t *powerSource); + +/** + * Gets the device's memory bus width + * + * @param device The identifier of the target device + * @param busWidth The devices's memory bus width + * + * @return + * - \ref NVML_SUCCESS if the memory bus width is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a busWidth is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMemoryBusWidth(nvmlDevice_t device, unsigned int *busWidth); + +/** + * Gets the device's PCIE Max Link speed in MBPS + * + * @param device The identifier of the target device + * @param maxSpeed The devices's PCIE Max Link speed in MBPS + * + * @return + * - \ref NVML_SUCCESS if PCIe Max Link Speed is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a maxSpeed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieLinkMaxSpeed(nvmlDevice_t device, unsigned int *maxSpeed); + +/** + * Gets the device's PCIe Link speed in Mbps + * + * @param device The identifier of the target device + * @param pcieSpeed The devices's PCIe Max Link speed in Mbps + * + * @return + * - \ref NVML_SUCCESS if \a pcieSpeed has been retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pcieSpeed is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support PCIe speed getting + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPcieSpeed(nvmlDevice_t device, unsigned int *pcieSpeed); + +/** + * Gets the device's Adaptive Clock status + * + * @param device The identifier of the target device + * @param adaptiveClockStatus The current adaptive clocking status, either + * NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED + * or NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED + * + * @return + * - \ref NVML_SUCCESS if the current adaptive clocking status is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a adaptiveClockStatus is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAdaptiveClockInfoStatus(nvmlDevice_t device, unsigned int *adaptiveClockStatus); + +/** + * Get the type of the GPU Bus (PCIe, PCI, ...) + * + * @param device The identifier of the target device + * @param type The PCI Bus type + * + * return + * - \ref NVML_SUCCESS if the bus \a type is successfully retreived + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a type is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetBusType(nvmlDevice_t device, nvmlBusType_t *type); + + + /** + * @deprecated Will be deprecated in a future release. Use \ref nvmlDeviceGetGpuFabricInfoV instead + * + * Get fabric information associated with the device. + * + * For Hopper &tm; or newer fully supported devices. + * + * On Hopper + NVSwitch systems, GPU is registered with the NVIDIA Fabric Manager + * Upon successful registration, the GPU is added to the NVLink fabric to enable + * peer-to-peer communication. + * This API reports the current state of the GPU in the NVLink fabric + * along with other useful information. + * + * + * @param device The identifier of the target device + * @param gpuFabricInfo Information about GPU fabric state + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support gpu fabric + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetGpuFabricInfo(nvmlDevice_t device, nvmlGpuFabricInfo_t *gpuFabricInfo); + +/** +* Versioned wrapper around \ref nvmlDeviceGetGpuFabricInfo that accepts a versioned +* \ref nvmlGpuFabricInfo_v2_t or later output structure. +* +* @note The caller must set the \ref nvmlGpuFabricInfoV_t.version field to the +* appropriate version prior to calling this function. For example: +* \code +* nvmlGpuFabricInfoV_t fabricInfo = +* { .version = nvmlGpuFabricInfo_v2 }; +* nvmlReturn_t result = nvmlDeviceGetGpuFabricInfoV(device,&fabricInfo); +* \endcode +* +* For Hopper &tm; or newer fully supported devices. +* +* @param device The identifier of the target device +* @param gpuFabricInfo Information about GPU fabric state +* +* @return +* - \ref NVML_SUCCESS Upon success +* - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support gpu fabric +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuFabricInfoV(nvmlDevice_t device, + nvmlGpuFabricInfoV_t *gpuFabricInfo); + +/** + * Get Conf Computing System capabilities. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param capabilities System CC capabilities + * + * @return + * - \ref NVML_SUCCESS if \a capabilities were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a capabilities is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeCapabilities(nvmlConfComputeSystemCaps_t *capabilities); + +/** + * Get Conf Computing System State. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param state System CC State + * + * @return + * - \ref NVML_SUCCESS if \a state were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a state is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeState(nvmlConfComputeSystemState_t *state); + +/** + * Get Conf Computing Protected and Unprotected Memory Sizes. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device Device handle + * @param memInfo Protected/Unprotected Memory sizes + * + * @return + * - \ref NVML_SUCCESS if \a memInfo were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a memInfo or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeMemSizeInfo(nvmlDevice_t device, nvmlConfComputeMemSizeInfo_t *memInfo); + +/** + * Get Conf Computing GPUs ready state. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param isAcceptingWork Returns GPU current work accepting state, + * NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE or + * NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE + * + * return + * - \ref NVML_SUCCESS if \a current GPUs ready state were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a isAcceptingWork is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeGpusReadyState(unsigned int *isAcceptingWork); + +/** + * Get Conf Computing protected memory usage. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param memory Reference in which to return the memory information + * + * @return + * - \ref NVML_SUCCESS if \a memory has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeProtectedMemoryUsage(nvmlDevice_t device, nvmlMemory_t *memory); + +/** + * Get Conf Computing GPU certificate details. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param gpuCert Reference in which to return the gpu certificate information + * + * @return + * - \ref NVML_SUCCESS if \a gpu certificate info has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeGpuCertificate(nvmlDevice_t device, + nvmlConfComputeGpuCertificate_t *gpuCert); + +/** + * Get Conf Computing GPU attestation report. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param gpuAtstReport Reference in which to return the gpu attestation report + * + * @return + * - \ref NVML_SUCCESS if \a gpu attestation report has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeGpuAttestationReport(nvmlDevice_t device, + nvmlConfComputeGpuAttestationReport_t *gpuAtstReport); +/** + * Get Conf Computing key rotation threshold detail. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param pKeyRotationThrInfo Reference in which to return the key rotation threshold data + * + * @return + * - \ref NVML_SUCCESS if \a gpu key rotation threshold info has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeKeyRotationThresholdInfo( + nvmlConfComputeGetKeyRotationThresholdInfo_t *pKeyRotationThrInfo); + +/** + * Set Conf Computing Unprotected Memory Size. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device Device Handle + * @param sizeKiB Unprotected Memory size to be set in KiB + * + * @return + * - \ref NVML_SUCCESS if \a sizeKiB successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlDeviceSetConfComputeUnprotectedMemSize(nvmlDevice_t device, unsigned long long sizeKiB); + +/** + * Set Conf Computing GPUs ready state. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param isAcceptingWork GPU accepting new work, NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE or + * NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE + * + * return + * - \ref NVML_SUCCESS if \a current GPUs ready state is successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a isAcceptingWork is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlSystemSetConfComputeGpusReadyState(unsigned int isAcceptingWork); + +/** + * Set Conf Computing key rotation threshold. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * This function is to set the confidential compute key rotation threshold parameters. + * \a pKeyRotationThrInfo->maxAttackerAdvantage should be in the range from + * NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MIN to NVML_CC_KEY_ROTATION_THRESHOLD_ATTACKER_ADVANTAGE_MAX. + * Default value is 60. + * + * @param pKeyRotationThrInfo Reference to the key rotation threshold data + * + * @return + * - \ref NVML_SUCCESS if \a key rotation threashold max attacker advantage has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a memory is NULL + * - \ref NVML_ERROR_INVALID_STATE if confidential compute GPU ready state is enabled + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemSetConfComputeKeyRotationThresholdInfo( + nvmlConfComputeSetKeyRotationThresholdInfo_t *pKeyRotationThrInfo); + +/** + * Get Conf Computing System Settings. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param settings System CC settings + * + * @return + * - \ref NVML_SUCCESS If the query is success + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a counters is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlSystemGetConfComputeSettings(nvmlSystemConfComputeSettings_t *settings); + +/** + * Retrieve GSP firmware version. + * + * The caller passes in buffer via \a version and corresponding GSP firmware numbered version + * is returned with the same parameter in string format. + * + * @param device Device handle + * @param version The retrieved GSP firmware version + * + * @return + * - \ref NVML_SUCCESS if GSP firmware version is sucessfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or GSP \a version pointer is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if GSP firmware is not enabled for GPU + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGspFirmwareVersion(nvmlDevice_t device, char *version); + +/** + * Retrieve GSP firmware mode. + * + * The caller passes in integer pointers. GSP firmware enablement and default mode information is returned with + * corresponding parameters. The return value in \a isEnabled and \a defaultMode should be treated as boolean. + * + * @param device Device handle + * @param isEnabled Pointer to specify if GSP firmware is enabled + * @param defaultMode Pointer to specify if GSP firmware is supported by default on \a device + * + * @return + * - \ref NVML_SUCCESS if GSP firmware mode is sucessfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or any of \a isEnabled or \a defaultMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if GSP firmware is not enabled for GPU + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGspFirmwareMode(nvmlDevice_t device, unsigned int *isEnabled, unsigned int *defaultMode); + +/** + * Get SRAM ECC error status of this device. + * + * For Ampere &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlEccSramErrorStatus_v1_t for more information on the struct. + * + * @param device The identifier of the target device + * @param status Returns SRAM ECC error status + * + * @return + * - \ref NVML_SUCCESS If \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a counters is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a nvmlEccSramErrorStatus_t is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSramEccErrorStatus(nvmlDevice_t device, + nvmlEccSramErrorStatus_t *status); + +/** + * Set new power limit of this device. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlDeviceGetPowerManagementLimitConstraints to check the allowed ranges of values. + * + * See \ref nvmlPowerValue_v2_t for more information on the struct. + * + * \note Limit is not persistent across reboots or driver unloads. + * Enable persistent mode to prevent driver from unloading when no application is using the device. + * + * This API replaces nvmlDeviceSetPowerManagementLimit. It can be used as a drop-in replacement for the older version. + * + * @param device The identifier of the target device + * @param powerValue Power management limit in milliwatts to set + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a powerValue is NULL or contains invalid values + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see NVML_FI_DEV_POWER_AVERAGE + * @see NVML_FI_DEV_POWER_INSTANT + * @see NVML_FI_DEV_POWER_MIN_LIMIT + * @see NVML_FI_DEV_POWER_MAX_LIMIT + * @see NVML_FI_DEV_POWER_CURRENT_LIMIT + */ +nvmlReturn_t DECLDIR nvmlDeviceSetPowerManagementLimit_v2(nvmlDevice_t device, nvmlPowerValue_v2_t *powerValue); + +/** + * @} // @defgroup nvmlDeviceQueries Device Queries + */ + +/** @addtogroup nvmlAccountingStats + * @{ + */ + +/** + * Queries the state of per process accounting mode. + * + * For Kepler &tm; or newer fully supported devices. + * + * See \ref nvmlDeviceGetAccountingStats for more details. + * See \ref nvmlDeviceSetAccountingMode + * + * @param device The identifier of the target device + * @param mode Reference in which to return the current accounting mode + * + * @return + * - \ref NVML_SUCCESS if the mode has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingMode(nvmlDevice_t device, nvmlEnableState_t *mode); + +/** + * Queries process's accounting stats. + * + * For Kepler &tm; or newer fully supported devices. + * + * Accounting stats capture GPU utilization and other statistics across the lifetime of a process. + * Accounting stats can be queried during life time of the process and after its termination. + * The time field in \ref nvmlAccountingStats_t is reported as 0 during the lifetime of the process and + * updated to actual running time after its termination. + * Accounting stats are kept in a circular buffer, newly created processes overwrite information about old + * processes. + * + * See \ref nvmlAccountingStats_t for description of each returned metric. + * List of processes that can be queried can be retrieved from \ref nvmlDeviceGetAccountingPids. + * + * @note Accounting Mode needs to be on. See \ref nvmlDeviceGetAccountingMode. + * @note Only compute and graphics applications stats can be queried. Monitoring applications stats can't be + * queried since they don't contribute to GPU utilization. + * @note In case of pid collision stats of only the latest process (that terminated last) will be reported + * + * @warning On Kepler devices per process statistics are accurate only if there's one process running on a GPU. + * + * @param device The identifier of the target device + * @param pid Process Id of the target process to query stats for + * @param stats Reference in which to return the process's accounting stats + * + * @return + * - \ref NVML_SUCCESS if stats have been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a stats are NULL + * - \ref NVML_ERROR_NOT_FOUND if process stats were not found + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device doesn't support this feature or accounting mode is disabled + * or on vGPU host. + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetAccountingBufferSize + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingStats(nvmlDevice_t device, unsigned int pid, nvmlAccountingStats_t *stats); + +/** + * Queries list of processes that can be queried for accounting stats. The list of processes returned + * can be in running or terminated state. + * + * For Kepler &tm; or newer fully supported devices. + * + * To query the number of processes under Accounting Mode, call this function with *count = 0 and pids=NULL. + * The return code will be NVML_ERROR_INSUFFICIENT_SIZE with an updated count value indicating the number of processes. + * + * For more details see \ref nvmlDeviceGetAccountingStats. + * + * @note In case of PID collision some processes might not be accessible before the circular buffer is full. + * + * @param device The identifier of the target device + * @param count Reference in which to provide the \a pids array size, and + * to return the number of elements ready to be queried + * @param pids Reference in which to return list of process ids + * + * @return + * - \ref NVML_SUCCESS if pids were successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a count is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device doesn't support this feature or accounting mode is disabled + * or on vGPU host. + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small (\a count is set to + * expected value) + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetAccountingBufferSize + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingPids(nvmlDevice_t device, unsigned int *count, unsigned int *pids); + +/** + * Returns the number of processes that the circular buffer with accounting pids can hold. + * + * For Kepler &tm; or newer fully supported devices. + * + * This is the maximum number of processes that accounting information will be stored for before information + * about oldest processes will get overwritten by information about new processes. + * + * @param device The identifier of the target device + * @param bufferSize Reference in which to provide the size (in number of elements) + * of the circular buffer for accounting stats. + * + * @return + * - \ref NVML_SUCCESS if buffer size was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a bufferSize is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetAccountingStats + * @see nvmlDeviceGetAccountingPids + */ +nvmlReturn_t DECLDIR nvmlDeviceGetAccountingBufferSize(nvmlDevice_t device, unsigned int *bufferSize); + +/** @} */ + +/** @addtogroup nvmlDeviceQueries + * @{ + */ + +/** + * Returns the list of retired pages by source, including pages that are pending retirement + * The address information provided from this API is the hardware address of the page that was retired. Note + * that this does not match the virtual address used in CUDA, but will match the address information in Xid 63 + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param cause Filter page addresses by cause of retirement + * @param pageCount Reference in which to provide the \a addresses buffer size, and + * to return the number of retired pages that match \a cause + * Set to 0 to query the size without allocating an \a addresses buffer + * @param addresses Buffer to write the page addresses into + * + * @return + * - \ref NVML_SUCCESS if \a pageCount was populated and \a addresses was filled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a pageCount indicates the buffer is not large enough to store all the + * matching page addresses. \a pageCount is set to the needed size. + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a pageCount is NULL, \a cause is invalid, or + * \a addresses is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRetiredPages(nvmlDevice_t device, nvmlPageRetirementCause_t cause, + unsigned int *pageCount, unsigned long long *addresses); + +/** + * Returns the list of retired pages by source, including pages that are pending retirement + * The address information provided from this API is the hardware address of the page that was retired. Note + * that this does not match the virtual address used in CUDA, but will match the address information in Xid 63 + * + * \note nvmlDeviceGetRetiredPages_v2 adds an additional timestamps parameter to return the time of each page's + * retirement. This is supported for Pascal and newer architecture. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param cause Filter page addresses by cause of retirement + * @param pageCount Reference in which to provide the \a addresses buffer size, and + * to return the number of retired pages that match \a cause + * Set to 0 to query the size without allocating an \a addresses buffer + * @param addresses Buffer to write the page addresses into + * @param timestamps Buffer to write the timestamps of page retirement, additional for _v2 + * + * @return + * - \ref NVML_SUCCESS if \a pageCount was populated and \a addresses was filled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a pageCount indicates the buffer is not large enough to store all the + * matching page addresses. \a pageCount is set to the needed size. + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a pageCount is NULL, \a cause is invalid, or + * \a addresses is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRetiredPages_v2(nvmlDevice_t device, nvmlPageRetirementCause_t cause, + unsigned int *pageCount, unsigned long long *addresses, unsigned long long *timestamps); + +/** + * Check if any pages are pending retirement and need a reboot to fully retire. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param isPending Reference in which to return the pending status + * + * @return + * - \ref NVML_SUCCESS if \a isPending was populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a isPending is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRetiredPagesPendingStatus(nvmlDevice_t device, nvmlEnableState_t *isPending); + +/** + * Get number of remapped rows. The number of rows reported will be based on + * the cause of the remapping. isPending indicates whether or not there are + * pending remappings. A reset will be required to actually remap the row. + * failureOccurred will be set if a row remapping ever failed in the past. A + * pending remapping won't affect future work on the GPU since + * error-containment and dynamic page blacklisting will take care of that. + * + * @note On MIG-enabled GPUs with active instances, querying the number of + * remapped rows is not supported + * + * For Ampere &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param corrRows Reference for number of rows remapped due to correctable errors + * @param uncRows Reference for number of rows remapped due to uncorrectable errors + * @param isPending Reference for whether or not remappings are pending + * @param failureOccurred Reference that is set when a remapping has failed in the past + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a corrRows, \a uncRows, \a isPending or \a failureOccurred is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN Unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRemappedRows(nvmlDevice_t device, unsigned int *corrRows, unsigned int *uncRows, + unsigned int *isPending, unsigned int *failureOccurred); + +/** + * Get the row remapper histogram. Returns the remap availability for each bank + * on the GPU. + * + * @param device Device handle + * @param values Histogram values + * + * @return + * - \ref NVML_SUCCESS On success + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetRowRemapperHistogram(nvmlDevice_t device, nvmlRowRemapperHistogramValues_t *values); + +/** + * Get architecture for device + * + * @param device The identifier of the target device + * @param arch Reference where architecture is returned, if call successful. + * Set to NVML_DEVICE_ARCH_* upon success + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a arch (output refererence) are invalid + */ +nvmlReturn_t DECLDIR nvmlDeviceGetArchitecture(nvmlDevice_t device, nvmlDeviceArchitecture_t *arch); + +/** + * Retrieves the frequency monitor fault status for the device. + * + * For Ampere &tm; or newer fully supported devices. + * Requires root user. + * + * See \ref nvmlClkMonStatus_t for details on decoding the status output. + * + * @param device The identifier of the target device + * @param status Reference in which to return the clkmon fault status + * + * @return + * - \ref NVML_SUCCESS if \a status has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a status is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetClkMonStatus() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetClkMonStatus(nvmlDevice_t device, nvmlClkMonStatus_t *status); + +/** + * Retrieves the current utilization and process ID + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder for processes running. + * Utilization values are returned as an array of utilization sample structures in the caller-supplied buffer pointed at + * by \a utilization. One utilization sample structure is returned per process running, that had some non-zero utilization + * during the last sample period. It includes the CPU timestamp at which the samples were recorded. Individual utilization values + * are returned as "unsigned int" values. If no valid sample entries are found since the lastSeenTimeStamp, NVML_ERROR_NOT_FOUND + * is returned. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a utilization set to NULL. The caller should allocate a buffer of size + * processSamplesCount * sizeof(nvmlProcessUtilizationSample_t). Invoke the function again with the allocated buffer passed + * in \a utilization, and \a processSamplesCount set to the number of entries the buffer is sized for. + * + * On successful return, the function updates \a processSamplesCount with the number of process utilization sample + * structures that were actually written. This may differ from a previously read value as instances are created or + * destroyed. + * + * lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @note On MIG-enabled GPUs, querying process utilization is not currently supported. + * + * @param device The identifier of the target device + * @param utilization Pointer to caller-supplied buffer in which guest process utilization samples are returned + * @param processSamplesCount Pointer to caller-supplied array size, and returns number of processes running + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetProcessUtilization(nvmlDevice_t device, nvmlProcessUtilizationSample_t *utilization, + unsigned int *processSamplesCount, unsigned long long lastSeenTimeStamp); + +/** + * Retrieves the recent utilization and process ID for all running processes + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder, jpeg decoder, OFA (Optical Flow Accelerator) + * for all running processes. Utilization values are returned as an array of utilization sample structures in the caller-supplied buffer pointed at + * by \a procesesUtilInfo->procUtilArray. One utilization sample structure is returned per process running, that had some non-zero utilization + * during the last sample period. It includes the CPU timestamp at which the samples were recorded. Individual utilization values + * are returned as "unsigned int" values. + * + * The caller should allocate a buffer of size processSamplesCount * sizeof(nvmlProcessUtilizationInfo_t). If the buffer is too small, the API will + * return \a NVML_ERROR_INSUFFICIENT_SIZE, with the recommended minimal buffer size at \a procesesUtilInfo->processSamplesCount. The caller should + * invoke the function again with the allocated buffer passed in \a procesesUtilInfo->procUtilArray, and \a procesesUtilInfo->processSamplesCount + * set to the number no less than the recommended value by the previous API return. + * + * On successful return, the function updates \a procesesUtilInfo->processSamplesCount with the number of process utilization info structures + * that were actually written. This may differ from a previously read value as instances are created or destroyed. + * + * \a procesesUtilInfo->lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set \a procesesUtilInfo->lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * \a procesesUtilInfo->version is the version number of the structure nvmlProcessesUtilizationInfo_t, the caller should set the correct version + * number to retrieve the specific version of processes utilization information. + * + * @note On MIG-enabled GPUs, querying process utilization is not currently supported. + * + * @param device The identifier of the target device + * @param procesesUtilInfo Pointer to the caller-provided structure of nvmlProcessesUtilizationInfo_t. + + * @return + * - \ref NVML_SUCCESS If \a procesesUtilInfo->procUtilArray has been populated + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, or \a procesesUtilInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_NOT_FOUND If sample entries are not found + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a procesesUtilInfo is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a procesesUtilInfo->procUtilArray is NULL, or the buffer size of procesesUtilInfo->procUtilArray is too small. + * The caller should check the minimul array size from the returned procesesUtilInfo->processSamplesCount, and call + * the function again with a buffer no smaller than procesesUtilInfo->processSamplesCount * sizeof(nvmlProcessUtilizationInfo_t) + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetProcessesUtilizationInfo(nvmlDevice_t device, nvmlProcessesUtilizationInfo_t *procesesUtilInfo); + +/** + * Get platform information of this device. + * + * For Blackwell &tm; or newer fully supported devices. + * + * See \ref nvmlPlatformInfo_v2_t for more information on the struct. + * + * @param device The identifier of the target device + * @param platformInfo Pointer to the caller-provided structure of nvmlPlatformInfo_t. + * + * @return + * - \ref NVML_SUCCESS If \a platformInfo has been retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a platformInfo is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_MEMORY if system memory is insufficient + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a nvmlPlatformInfo_t is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPlatformInfo(nvmlDevice_t device, nvmlPlatformInfo_t *platformInfo); + +/** + * Retrieves the Per Device Identifier (PDI) associated with this device. + * + * For Pascal &tm; or newer fully supported devices. + * + * See \ref nvmlPdi_v1_t for more information on the struct. + * + * @param[in] device The identifier of the target device + * @param[out] pdi Reference to the caller-provided structure to return the GPU PDI + * + * @return + * - \ref NVML_SUCCESS if \a pdi has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a pdi is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPdi(nvmlDevice_t device, nvmlPdi_t *pdi); + +/** + * Set the hostname for the device. + * + * For Blackwell &tm; or newer fully supported devices. + * Requires root/admin permissions. + * Supported on Linux only. + * + * Sets a hostname string for the GPU device. This operation takes effect immediately. + * + * The hostname is not stored persistently across GPU resets or driver reloads. + * + * @param device The identifier of the target device + * @param hostname Reference to the caller-provided \ref nvmlHostname_v1_t struct containing the hostname + * + * @return + * - \ref NVML_SUCCESS if the hostname was set successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a hostname is NULL or contains invalid characters + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetHostname_v1() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetHostname_v1(nvmlDevice_t device, nvmlHostname_v1_t *hostname); + +/** + * Get the hostname for the device. + * + * For Blackwell &tm; or newer fully supported devices. + * Supported on Linux only. + * + * Retrieves the hostname string for the GPU device that was set using \ref nvmlDeviceSetHostname_v1(). + * + * @param device The identifier of the target device + * @param hostname Reference to the caller-provided \ref nvmlHostname_v1_t struct to return the hostname + * + * @return + * - \ref NVML_SUCCESS if the hostname was retrieved successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a hostname is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceSetHostname_v1() + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHostname_v1(nvmlDevice_t device, nvmlHostname_v1_t *hostname); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlUnitCommands Unit Commands + * This chapter describes NVML operations that change the state of the unit. For S-class products. + * Each of these requires root/admin access. Non-admin users will see an NVML_ERROR_NO_PERMISSION + * error code when invoking any of these methods. + * @{ + */ +/***************************************************************************************************/ + +/** + * Set the LED state for the unit. The LED can be either green (0) or amber (1). + * + * For S-class products. + * Requires root/admin permissions. + * + * This operation takes effect immediately. + * + * + * Current S-Class products don't provide unique LEDs for each unit. As such, both front + * and back LEDs will be toggled in unison regardless of which unit is specified with this command. + * + * See \ref nvmlLedColor_t for available colors. + * + * @param unit The identifier of the target unit + * @param color The target LED color + * + * @return + * - \ref NVML_SUCCESS if the LED color has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a unit or \a color is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this is not an S-class product + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlUnitGetLedState() + */ +nvmlReturn_t DECLDIR nvmlUnitSetLedState(nvmlUnit_t unit, nvmlLedColor_t color); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlDeviceCommands Device Commands + * This chapter describes NVML operations that change the state of the device. + * Each of these requires root/admin access. Non-admin users will see an NVML_ERROR_NO_PERMISSION + * error code when invoking any of these methods. + * @{ + */ +/***************************************************************************************************/ + +/** + * Set the persistence mode for the device. + * + * For all products. + * For Linux only. + * Requires root/admin permissions. + * + * The persistence mode determines whether the GPU driver software is torn down after the last client + * exits. + * + * This operation takes effect immediately. It is not persistent across reboots. After each reboot the + * persistence mode is reset to "Disabled". + * + * See \ref nvmlEnableState_t for available modes. + * + * After calling this API with mode set to NVML_FEATURE_DISABLED on a device that has its own NUMA + * memory, the given device handle will no longer be valid, and to continue to interact with this + * device, a new handle should be obtained from one of the nvmlDeviceGetHandleBy*() APIs. This + * limitation is currently only applicable to devices that have a coherent NVLink connection to + * system memory. + * + * @param device The identifier of the target device + * @param mode The target persistence mode + * + * @return + * - \ref NVML_SUCCESS if the persistence mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetPersistenceMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetPersistenceMode(nvmlDevice_t device, nvmlEnableState_t mode); + +/** + * Set the compute mode for the device. + * + * For all products. + * Requires root/admin permissions. + * + * The compute mode determines whether a GPU can be used for compute operations and whether it can + * be shared across contexts. + * + * This operation takes effect immediately. Under Linux it is not persistent across reboots and + * always resets to "Default". Under windows it is persistent. + * + * Under windows compute mode may only be set to DEFAULT when running in WDDM + * + * @note On MIG-enabled GPUs, compute mode would be set to DEFAULT and changing it is not supported. + * + * See \ref nvmlComputeMode_t for details on available compute modes. + * + * @param device The identifier of the target device + * @param mode The target compute mode + * + * @return + * - \ref NVML_SUCCESS if the compute mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetComputeMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetComputeMode(nvmlDevice_t device, nvmlComputeMode_t mode); + +/** + * Set the ECC mode for the device. + * + * For Kepler &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher. + * Requires root/admin permissions. + * + * The ECC mode determines whether the GPU enables its ECC support. + * + * This operation takes effect after the next reboot. + * + * See \ref nvmlEnableState_t for details on available modes. + * + * @param device The identifier of the target device + * @param ecc The target ECC mode + * + * @return + * - \ref NVML_SUCCESS if the ECC mode was set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a ecc is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetEccMode() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetEccMode(nvmlDevice_t device, nvmlEnableState_t ecc); + +/** + * Clear the ECC error and other memory error counts for the device. + * + * For Kepler &tm; or newer fully supported devices. + * Only applicable to devices with ECC. + * Requires \a NVML_INFOROM_ECC version 2.0 or higher to clear aggregate location-based ECC counts. + * Requires \a NVML_INFOROM_ECC version 1.0 or higher to clear all other ECC counts. + * Requires root/admin permissions. + * Requires ECC Mode to be enabled. + * + * Sets all of the specified ECC counters to 0, including both detailed and total counts. + * + * This operation takes effect immediately. + * + * See \ref nvmlMemoryErrorType_t for details on available counter types. + * + * @param device The identifier of the target device + * @param counterType Flag that indicates which type of errors should be cleared. + * + * @return + * - \ref NVML_SUCCESS if the error counts were cleared + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a counterType is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see + * - nvmlDeviceGetDetailedEccErrors() + * - nvmlDeviceGetTotalEccErrors() + */ +nvmlReturn_t DECLDIR nvmlDeviceClearEccErrorCounts(nvmlDevice_t device, nvmlEccCounterType_t counterType); + +/** + * Set the driver model for the device. + * + * For Fermi &tm; or newer fully supported devices. + * For windows only. + * Requires root/admin permissions. + * + * On Windows platforms the device driver can run in either WDDM or WDM (TCC) mode. If a display is attached + * to the device it must run in WDDM mode. + * + * It is possible to force the change to WDM (TCC) while the display is still attached with a force flag (nvmlFlagForce). + * This should only be done if the host is subsequently powered down and the display is detached from the device + * before the next reboot. + * + * This operation takes effect after the next reboot. + * + * Windows driver model may only be set to WDDM when running in DEFAULT compute mode. + * + * Change driver model to WDDM is not supported when GPU doesn't support graphics acceleration or + * will not support it after reboot. See \ref nvmlDeviceSetGpuOperationMode. + * + * See \ref nvmlDriverModel_t for details on available driver models. + * See \ref nvmlFlagDefault and \ref nvmlFlagForce + * + * @param device The identifier of the target device + * @param driverModel The target driver model + * @param flags Flags that change the default behavior + * + * @return + * - \ref NVML_SUCCESS if the driver model has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a driverModel is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the platform is not windows or the device does not support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetDriverModel() + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDriverModel(nvmlDevice_t device, nvmlDriverModel_t driverModel, unsigned int flags); + +typedef enum nvmlClockLimitId_enum { + NVML_CLOCK_LIMIT_ID_RANGE_START = 0xffffff00, + NVML_CLOCK_LIMIT_ID_TDP, + NVML_CLOCK_LIMIT_ID_UNLIMITED +} nvmlClockLimitId_t; + +/** + * Set clocks that device will lock to. + * + * Sets the clocks that the device will be running at to the value in the range of minGpuClockMHz to maxGpuClockMHz. + * + * Can be used as a setting to request constant performance. + * + * This can be called with a pair of integer clock frequencies in MHz, or a pair of /ref nvmlClockLimitId_t values. + * See the table below for valid combinations of these values. + * + * minGpuClock | maxGpuClock | Effect + * ------------+-------------+-------------------------------------------------- + * tdp | tdp | Lock clock to TDP + * unlimited | tdp | Upper bound is TDP but clock may drift below this + * tdp | unlimited | Lower bound is TDP but clock may boost above this + * unlimited | unlimited | Unlocked (== nvmlDeviceResetGpuLockedClocks) + * + * If one arg takes one of these values, the other must be one of these values as + * well. Mixed numeric and symbolic calls return NVML_ERROR_INVALID_ARGUMENT. + * + * Requires root/admin permissions. + * + * After system reboot or driver reload GPU clocks go back to their default value. + * See \ref nvmlDeviceResetGpuLockedClocks. + * + * For Volta &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param minGpuClockMHz Requested minimum gpu clock in MHz + * @param maxGpuClockMHz Requested maximum gpu clock in MHz + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minGpuClockMHz and \a maxGpuClockMHz + * is not a valid clock combination + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetGpuLockedClocks(nvmlDevice_t device, unsigned int minGpuClockMHz, unsigned int maxGpuClockMHz); + +/** + * Resets the gpu clock to the default value + * + * This is the gpu clock that will be used after system reboot or driver reload. + * Default values are idle clocks. + * + * @see nvmlDeviceSetGpuLockedClocks + * + * For Volta &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceResetGpuLockedClocks(nvmlDevice_t device); + +/** + * Set memory clocks that device will lock to. + * + * Sets the device's memory clocks to the value in the range of minMemClockMHz to maxMemClockMHz. + * + * Can be used as a setting to request constant performance. + * + * Requires root/admin permissions. + * + * After system reboot or driver reload memory clocks go back to their default value. + * See \ref nvmlDeviceResetMemoryLockedClocks. + * + * For Ampere &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param minMemClockMHz Requested minimum memory clock in MHz + * @param maxMemClockMHz Requested maximum memory clock in MHz + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a minGpuClockMHz and \a maxGpuClockMHz + * is not a valid clock combination + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetMemoryLockedClocks(nvmlDevice_t device, unsigned int minMemClockMHz, unsigned int maxMemClockMHz); + +/** + * Resets the memory clock to the default value + * + * This is the memory clock that will be used after system reboot or driver reload. + * Default values are idle clocks. + * + * @see nvmlDeviceSetMemoryLockedClocks + * + * For Ampere &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if new settings were successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceResetMemoryLockedClocks(nvmlDevice_t device); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + * + * Please use \ref nvmlDeviceSetMemoryLockedClocks for Memory Clocks and + * \ref nvmlDeviceSetGpuLockedClocks for Graphics Clocks. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetApplicationsClocks(nvmlDevice_t device, unsigned int memClockMHz, unsigned int graphicsClockMHz); + +/** + * @deprecated Applications clocks are deprecated and will be removed in CUDA 14.0. + * + * Please use \ref nvmlDeviceResetMemoryLockedClocks for Memory Clocks and + * \ref nvmlDeviceResetGpuLockedClocks for Graphics Clocks. + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceResetApplicationsClocks(nvmlDevice_t device); + +/** + * Try to set the current state of Auto Boosted clocks on a device. + * + * For Kepler &tm; or newer fully supported devices. + * + * Auto Boosted clocks are enabled by default on some hardware, allowing the GPU to run at higher clock rates + * to maximize performance as thermal limits allow. Auto Boosted clocks should be disabled if fixed clock + * rates are desired. + * + * Non-root users may use this API by default but can be restricted by root from using this API by calling + * \ref nvmlDeviceSetAPIRestriction with apiType=NVML_RESTRICTED_API_SET_AUTO_BOOSTED_CLOCKS. + * Note: Persistence Mode is required to modify current Auto Boost settings, therefore, it must be enabled. + * + * On Pascal and newer hardware, Auto Boosted clocks are controlled through application clocks. + * Use \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks to control Auto Boost + * behavior. + * + * @param device The identifier of the target device + * @param enabled What state to try to set Auto Boosted clocks of the target device to + * + * @return + * - \ref NVML_SUCCESS If the Auto Boosted clocks were successfully set to the state specified by \a enabled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support Auto Boosted clocks + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceSetAutoBoostedClocksEnabled(nvmlDevice_t device, nvmlEnableState_t enabled); + +/** + * Try to set the default state of Auto Boosted clocks on a device. This is the default state that Auto Boosted clocks will + * return to when no compute running processes (e.g. CUDA application which have an active context) are running + * + * For Kepler &tm; or newer non-GeForce fully supported devices and Maxwell or newer GeForce devices. + * Requires root/admin permissions. + * + * Auto Boosted clocks are enabled by default on some hardware, allowing the GPU to run at higher clock rates + * to maximize performance as thermal limits allow. Auto Boosted clocks should be disabled if fixed clock + * rates are desired. + * + * On Pascal and newer hardware, Auto Boosted clocks are controlled through application clocks. + * Use \ref nvmlDeviceSetApplicationsClocks and \ref nvmlDeviceResetApplicationsClocks to control Auto Boost + * behavior. + * + * @param device The identifier of the target device + * @param enabled What state to try to set default Auto Boosted clocks of the target device to + * @param flags Flags that change the default behavior. Currently Unused. + * + * @return + * - \ref NVML_SUCCESS If the Auto Boosted clock's default state was successfully set to the state specified by \a enabled + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NO_PERMISSION If the calling user does not have permission to change Auto Boosted clock's default state. + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support Auto Boosted clocks + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDefaultAutoBoostedClocksEnabled(nvmlDevice_t device, nvmlEnableState_t enabled, unsigned int flags); + +/** + * Sets the speed of the fan control policy to default. + * + * For all cuda-capable discrete products with fans + * + * @param device The identifier of the target device + * @param fan The index of the fan, starting at zero + * + * return + * NVML_SUCCESS if speed has been adjusted + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if device is invalid + * NVML_ERROR_NOT_SUPPORTED if the device does not support this + * (doesn't have fans) + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetDefaultFanSpeed_v2(nvmlDevice_t device, unsigned int fan); + +/** + * Sets current fan control policy. + * + * For Maxwell &tm; or newer fully supported devices. + * + * Requires privileged user. + * + * For all cuda-capable discrete products with fans + * + * device The identifier of the target \a device + * policy The fan control \a policy to set + * + * return + * NVML_SUCCESS if \a policy has been set + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a policy is null or the \a fan given doesn't reference + * a fan that exists. + * NVML_ERROR_NOT_SUPPORTED if the \a device is older than Maxwell + * NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetFanControlPolicy(nvmlDevice_t device, unsigned int fan, + nvmlFanControlPolicy_t policy); + +/** + * Sets the temperature threshold for the GPU with the specified threshold type in degrees C. + * + * For Maxwell &tm; or newer fully supported devices. + * + * See \ref nvmlTemperatureThresholds_t for details on available temperature thresholds. + * + * @param device The identifier of the target device + * @param thresholdType The type of threshold value to be set + * @param temp Reference which hold the value to be set + * @return + * - \ref NVML_SUCCESS if \a temp has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a thresholdType is invalid or \a temp is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a temperature sensor or is unsupported + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetTemperatureThreshold(nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, int *temp); + +/** + * Set new power limit of this device. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlDeviceGetPowerManagementLimitConstraints to check the allowed ranges of values. + * + * \note Limit is not persistent across reboots or driver unloads. + * Enable persistent mode to prevent driver from unloading when no application is using the device. + * + * @param device The identifier of the target device + * @param limit Power management limit in milliwatts to set + * + * @return + * - \ref NVML_SUCCESS if \a limit has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a defaultLimit is out of range + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceGetPowerManagementLimitConstraints + * @see nvmlDeviceGetPowerManagementDefaultLimit + */ +nvmlReturn_t DECLDIR nvmlDeviceSetPowerManagementLimit(nvmlDevice_t device, unsigned int limit); + +/** + * Sets new GOM. See \a nvmlGpuOperationMode_t for details. + * + * For GK110 M-class and X-class Tesla &tm; products from the Kepler family. + * Modes \ref NVML_GOM_LOW_DP and \ref NVML_GOM_ALL_ON are supported on fully supported GeForce products. + * Not supported on Quadro ® and Tesla &tm; C-class products. + * Requires root/admin permissions. + * + * Changing GOMs requires a reboot. + * The reboot requirement might be removed in the future. + * + * Compute only GOMs don't support graphics acceleration. Under windows switching to these GOMs when + * pending driver model is WDDM is not supported. See \ref nvmlDeviceSetDriverModel. + * + * @param device The identifier of the target device + * @param mode Target GOM + * + * @return + * - \ref NVML_SUCCESS if \a mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a mode incorrect + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support GOM or specific mode + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlGpuOperationMode_t + * @see nvmlDeviceGetGpuOperationMode + */ +nvmlReturn_t DECLDIR nvmlDeviceSetGpuOperationMode(nvmlDevice_t device, nvmlGpuOperationMode_t mode); + +/** + * Changes the root/admin restructions on certain APIs. See \a nvmlRestrictedAPI_t for the list of supported APIs. + * This method can be used by a root/admin user to give non-root/admin access to certain otherwise-restricted APIs. + * The new setting lasts for the lifetime of the NVIDIA driver; it is not persistent. See \a nvmlDeviceGetAPIRestriction + * to query the current restriction settings. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * @param device The identifier of the target device + * @param apiType Target API type for this operation + * @param isRestricted The target restriction + * + * @return + * - \ref NVML_SUCCESS if \a isRestricted has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a apiType incorrect + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support changing API restrictions or the device does not support + * the feature that api restrictions are being set for (E.G. Enabling/disabling auto + * boosted clocks is not supported by the device) + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlRestrictedAPI_t + */ +nvmlReturn_t DECLDIR nvmlDeviceSetAPIRestriction(nvmlDevice_t device, nvmlRestrictedAPI_t apiType, nvmlEnableState_t isRestricted); + +/** + * Sets the speed of a specified fan. + * + * WARNING: This function changes the fan control policy to manual. It means that YOU have to monitor + * the temperature and adjust the fan speed accordingly. + * If you set the fan speed too low you can burn your GPU! + * Use nvmlDeviceSetDefaultFanSpeed_v2 to restore default control policy. + * + * For all cuda-capable discrete products with fans that are Maxwell or Newer. + * + * device The identifier of the target device + * fan The index of the fan, starting at zero + * speed The target speed of the fan [0-100] in % of max speed + * + * return + * NVML_SUCCESS if the fan speed has been set + * NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * NVML_ERROR_INVALID_ARGUMENT if the device is not valid, or the speed is outside acceptable ranges, + * or if the fan index doesn't reference an actual fan. + * NVML_ERROR_NOT_SUPPORTED if the device is older than Maxwell. + * NVML_ERROR_UNKNOWN if there was an unexpected error. + */ +nvmlReturn_t DECLDIR nvmlDeviceSetFanSpeed_v2(nvmlDevice_t device, unsigned int fan, unsigned int speed); + +/** + * @deprecated Will be deprecated in a future release. Use \ref nvmlDeviceSetClockOffsets instead. It works + * on Maxwell onwards GPU architectures. + * + * Set the GPCCLK VF offset value + * @param[in] device The identifier of the target device + * @param[in] offset The GPCCLK VF offset value to set + * + * @return + * - \ref NVML_SUCCESS if \a offset has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetGpcClkVfOffset(nvmlDevice_t device, int offset); + +/** + * @deprecated Will be deprecated in a future release. Use \ref nvmlDeviceSetClockOffsets instead. It works + * on Maxwell onwards GPU architectures. + * + * Set the MemClk (Memory Clock) VF offset value. It requires elevated privileges. + * @param[in] device The identifier of the target device + * @param[in] offset The MemClk VF offset value to set + * + * @return + * - \ref NVML_SUCCESS if \a offset has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetMemClkVfOffset(nvmlDevice_t device, int offset); + +/** + * @} + */ + +/** @addtogroup nvmlAccountingStats + * @{ + */ + +/** + * Enables or disables per process accounting. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * @note This setting is not persistent and will default to disabled after driver unloads. + * Enable persistence mode to be sure the setting doesn't switch off to disabled. + * + * @note Enabling accounting mode has no negative impact on the GPU performance. + * + * @note Disabling accounting clears all accounting pids information. + * + * @note On MIG-enabled GPUs, accounting mode would be set to DISABLED and changing it is not supported. + * + * See \ref nvmlDeviceGetAccountingMode + * See \ref nvmlDeviceGetAccountingStats + * See \ref nvmlDeviceClearAccountingPids + * + * @param device The identifier of the target device + * @param mode The target accounting mode + * + * @return + * - \ref NVML_SUCCESS if the new mode has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a mode are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetAccountingMode(nvmlDevice_t device, nvmlEnableState_t mode); + +/** + * Clears accounting information about all processes that have already terminated. + * + * For Kepler &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * See \ref nvmlDeviceGetAccountingMode + * See \ref nvmlDeviceGetAccountingStats + * See \ref nvmlDeviceSetAccountingMode + * + * @param device The identifier of the target device + * + * @return + * - \ref NVML_SUCCESS if accounting information has been cleared + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceClearAccountingPids(nvmlDevice_t device); + +/** @} */ // @addtogroup nvmlAccountingStats + +/***************************************************************************************************/ +/** @defgroup NvLink NvLink Methods + * This chapter describes methods that NVML can perform on NVLINK enabled devices. + * @{ + */ +/***************************************************************************************************/ + +#define NVML_NVLINK_BER_MANTISSA_SHIFT 8 +#define NVML_NVLINK_BER_MANTISSA_WIDTH 0xf + +#define NVML_NVLINK_BER_EXP_SHIFT 0 +#define NVML_NVLINK_BER_EXP_WIDTH 0xff + +/** + * Nvlink Error counter BER can be obtained using the below macros + * Ex - NVML_NVLINK_ERROR_COUNTER_BER_GET(var, BER_MANTISSA) + */ +#define NVML_NVLINK_ERROR_COUNTER_BER_GET(var, type) \ + (((var) >> NVML_NVLINK_##type##_SHIFT) & \ + (NVML_NVLINK_##type##_WIDTH)) \ + +/* + * NVML_FI_DEV_NVLINK_GET_STATE state enums + */ +#define NVML_NVLINK_STATE_INACTIVE 0x0 +#define NVML_NVLINK_STATE_ACTIVE 0x1 +#define NVML_NVLINK_STATE_SLEEP 0x2 + +#define NVML_NVLINK_TOTAL_SUPPORTED_BW_MODES 23 + +typedef struct +{ + unsigned int version; + unsigned char bwModes[NVML_NVLINK_TOTAL_SUPPORTED_BW_MODES]; + unsigned char totalBwModes; +} nvmlNvlinkSupportedBwModes_v1_t; +typedef nvmlNvlinkSupportedBwModes_v1_t nvmlNvlinkSupportedBwModes_t; +#define nvmlNvlinkSupportedBwModes_v1 NVML_STRUCT_VERSION(NvlinkSupportedBwModes, 1) + +typedef struct +{ + unsigned int version; + unsigned int bIsBest; + unsigned char bwMode; +} nvmlNvlinkGetBwMode_v1_t; +typedef nvmlNvlinkGetBwMode_v1_t nvmlNvlinkGetBwMode_t; +#define nvmlNvlinkGetBwMode_v1 NVML_STRUCT_VERSION(NvlinkGetBwMode, 1) + +typedef struct +{ + unsigned int version; + unsigned int bSetBest; + unsigned char bwMode; +} nvmlNvlinkSetBwMode_v1_t; +typedef nvmlNvlinkSetBwMode_v1_t nvmlNvlinkSetBwMode_t; +#define nvmlNvlinkSetBwMode_v1 NVML_STRUCT_VERSION(NvlinkSetBwMode, 1) + +/** + * Struct to represent per device NVLINK information v1 + */ +typedef struct +{ + unsigned int version; //!< IN - the API version number + unsigned int isNvleEnabled; //!< OUT - NVLINK encryption enablement +} nvmlNvLinkInfo_v1_t; +#define nvmlNvLinkInfo_v1 NVML_STRUCT_VERSION(NvLinkInfo, 1) + +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_MSE 0x1 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR 0x2 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR_UPHY 0x3 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR_CLN 0x4 +#define NVML_NVLINK_FIRMWARE_UCODE_TYPE_NETIR_DLN 0x5 +#define NVML_NVLINK_FIRMWARE_VERSION_LENGTH 100 + +/** + * Struct to represent NVLINK firmware Semantic versioning and ucode type + */ +typedef struct +{ + unsigned char ucodeType; + unsigned int major; + unsigned int minor; + unsigned int subMinor; +} nvmlNvlinkFirmwareVersion_t; + +/** + * Struct to represent NVLINK firmware information + */ +typedef struct +{ + nvmlNvlinkFirmwareVersion_t firmwareVersion[NVML_NVLINK_FIRMWARE_VERSION_LENGTH]; //!< OUT - NVLINK firmware version + unsigned int numValidEntries; //!< OUT - Number of valid firmware entries +} nvmlNvlinkFirmwareInfo_t; + +/** + * Struct to represent per device NVLINK information v2 + */ +typedef struct +{ + unsigned int version; //!< IN - the API version number + unsigned int isNvleEnabled; //!< OUT - NVLINK encryption enablement + nvmlNvlinkFirmwareInfo_t firmwareInfo; //!< OUT - NVLINK Firmware info +} nvmlNvLinkInfo_v2_t; +typedef nvmlNvLinkInfo_v2_t nvmlNvLinkInfo_t; +#define nvmlNvLinkInfo_v2 NVML_STRUCT_VERSION(NvLinkInfo, 2) + +/** + * Retrieves the state of the device's NvLink for the link specified + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param isActive \a nvmlEnableState_t where NVML_FEATURE_ENABLED indicates that + * the link is active and NVML_FEATURE_DISABLED indicates it + * is inactive + * + * @return + * - \ref NVML_SUCCESS if \a isActive has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid or \a isActive is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkState(nvmlDevice_t device, unsigned int link, nvmlEnableState_t *isActive); + +/** + * Retrieves the version of the device's NvLink for the link specified + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param version Requested NvLink version from nvmlNvlinkVersion_t + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid or \a version is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkVersion(nvmlDevice_t device, unsigned int link, unsigned int *version); + +/** + * Retrieves the requested capability from the device's NvLink for the link specified + * Please refer to the \a nvmlNvLinkCapability_t structure for the specific caps that can be queried + * The return value should be treated as a boolean. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param capability Specifies the \a nvmlNvLinkCapability_t to be queried + * @param capResult A boolean for the queried capability indicating that feature is available + * + * @return + * - \ref NVML_SUCCESS if \a capResult has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, or \a capability is invalid or \a capResult is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkCapability(nvmlDevice_t device, unsigned int link, + nvmlNvLinkCapability_t capability, unsigned int *capResult); + +/** + * Retrieves the PCI information for the remote node on a NvLink link + * Note: pciSubSystemId is not filled in this function and is indeterminate + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param pci \a nvmlPciInfo_t of the remote node for the specified link + * + * @return + * - \ref NVML_SUCCESS if \a pci has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid or \a pci is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkRemotePciInfo_v2(nvmlDevice_t device, unsigned int link, nvmlPciInfo_t *pci); + +/** + * Retrieves the specified error counter value + * Please refer to \a nvmlNvLinkErrorCounter_t for error counters that are available + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param counter Specifies the NvLink counter to be queried + * @param counterValue Returned counter value + * + * @return + * - \ref NVML_SUCCESS if \a counter has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, or \a counter is invalid or \a counterValue is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkErrorCounter(nvmlDevice_t device, unsigned int link, + nvmlNvLinkErrorCounter_t counter, unsigned long long *counterValue); + +/** + * Resets all error counters to zero + * Please refer to \a nvmlNvLinkErrorCounter_t for the list of error counters that are reset + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * + * @return + * - \ref NVML_SUCCESS if the reset is successful + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceResetNvLinkErrorCounters(nvmlDevice_t device, unsigned int link); + +/** + * @deprecated Setting utilization counter control is no longer supported. + * + * Set the NVLINK utilization counter control information for the specified counter, 0 or 1. + * Please refer to \a nvmlNvLinkUtilizationControl_t for the structure definition. Performs a reset + * of the counters if the reset parameter is non-zero. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param counter Specifies the counter that should be set (0 or 1). + * @param link Specifies the NvLink link to be queried + * @param control A reference to the \a nvmlNvLinkUtilizationControl_t to set + * @param reset Resets the counters on set if non-zero + * + * @return + * - \ref NVML_SUCCESS if the control has been set successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a counter, \a link, or \a control is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceSetNvLinkUtilizationControl(nvmlDevice_t device, unsigned int link, unsigned int counter, + nvmlNvLinkUtilizationControl_t *control, unsigned int reset); + +/** + * @deprecated Getting utilization counter control is no longer supported. + * + * Get the NVLINK utilization counter control information for the specified counter, 0 or 1. + * Please refer to \a nvmlNvLinkUtilizationControl_t for the structure definition + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param counter Specifies the counter that should be set (0 or 1). + * @param link Specifies the NvLink link to be queried + * @param control A reference to the \a nvmlNvLinkUtilizationControl_t to place information + * + * @return + * - \ref NVML_SUCCESS if the control has been set successfully + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a counter, \a link, or \a control is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkUtilizationControl(nvmlDevice_t device, unsigned int link, unsigned int counter, + nvmlNvLinkUtilizationControl_t *control); + + +/** + * @deprecated Use \ref nvmlDeviceGetFieldValues with NVML_FI_DEV_NVLINK_THROUGHPUT_* as field values instead. + * + * Retrieve the NVLINK utilization counter based on the current control for a specified counter. + * In general it is good practice to use \a nvmlDeviceSetNvLinkUtilizationControl + * before reading the utilization counters as they have no default state + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param counter Specifies the counter that should be read (0 or 1). + * @param rxcounter Receive counter return value + * @param txcounter Transmit counter return value + * + * @return + * - \ref NVML_SUCCESS if \a rxcounter and \a txcounter have been successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a counter, or \a link is invalid or \a rxcounter or \a txcounter are NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkUtilizationCounter(nvmlDevice_t device, unsigned int link, unsigned int counter, + unsigned long long *rxcounter, unsigned long long *txcounter); + +/** + * @deprecated Freezing NVLINK utilization counters is no longer supported. + * + * Freeze the NVLINK utilization counters + * Both the receive and transmit counters are operated on by this function + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be queried + * @param counter Specifies the counter that should be frozen (0 or 1). + * @param freeze NVML_FEATURE_ENABLED = freeze the receive and transmit counters + * NVML_FEATURE_DISABLED = unfreeze the receive and transmit counters + * + * @return + * - \ref NVML_SUCCESS if counters were successfully frozen or unfrozen + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, \a counter, or \a freeze is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceFreezeNvLinkUtilizationCounter (nvmlDevice_t device, unsigned int link, + unsigned int counter, nvmlEnableState_t freeze); + +/** + * @deprecated Resetting NVLINK utilization counters is no longer supported. + * + * Reset the NVLINK utilization counters + * Both the receive and transmit counters are operated on by this function + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param link Specifies the NvLink link to be reset + * @param counter Specifies the counter that should be reset (0 or 1) + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a link, or \a counter is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlDeviceResetNvLinkUtilizationCounter (nvmlDevice_t device, unsigned int link, unsigned int counter); + +/** +* Get the NVLink device type of the remote device connected over the given link. +* +* @param device The device handle of the target GPU +* @param link The NVLink link index on the target GPU +* @param pNvLinkDeviceType Pointer in which the output remote device type is returned +* +* @return +* - \ref NVML_SUCCESS if \a pNvLinkDeviceType has been set +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_NOT_SUPPORTED if NVLink is not supported +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a link is invalid, or +* \a pNvLinkDeviceType is NULL +* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is +* otherwise inaccessible +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkRemoteDeviceType(nvmlDevice_t device, unsigned int link, nvmlIntNvLinkDeviceType_t *pNvLinkDeviceType); + +/** + * Set NvLink Low Power Threshold for device. + * + * For Hopper &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param info Reference to \a nvmlNvLinkPowerThres_t struct + * input parameters + * + * @return + * - \ref NVML_SUCCESS if the \a Threshold is successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a Threshold is not within range + * - \ref NVML_ERROR_NOT_READY if an internal driver setting prevents the threshold from being used + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * + **/ +nvmlReturn_t DECLDIR nvmlDeviceSetNvLinkDeviceLowPowerThreshold(nvmlDevice_t device, nvmlNvLinkPowerThres_t *info); + +/** + * Set the global nvlink bandwith mode + * + * @param nvlinkBwMode nvlink bandwidth mode + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid argument is provided + * - \ref NVML_ERROR_IN_USE if P2P object exists + * - \ref NVML_ERROR_NOT_SUPPORTED if GPU is not Hopper or newer architecture. + * - \ref NVML_ERROR_NO_PERMISSION if not root user + */ +nvmlReturn_t DECLDIR nvmlSystemSetNvlinkBwMode(unsigned int nvlinkBwMode); + +/** + * Get the global nvlink bandwith mode + * + * @param nvlinkBwMode reference of nvlink bandwidth mode + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid pointer is provided + * - \ref NVML_ERROR_NOT_SUPPORTED if GPU is not Hopper or newer architecture. + * - \ref NVML_ERROR_NO_PERMISSION if not root user + */ +nvmlReturn_t DECLDIR nvmlSystemGetNvlinkBwMode(unsigned int *nvlinkBwMode); + +/** + * Get the supported NvLink Reduced Bandwidth Modes of the device + * + * For Blackwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param supportedBwMode Reference to \a nvmlNvlinkSupportedBwModes_t + * + * @return + * - \ref NVML_SUCCESS if the query was successful + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or supportedBwMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified is not supported + **/ +nvmlReturn_t DECLDIR nvmlDeviceGetNvlinkSupportedBwModes(nvmlDevice_t device, + nvmlNvlinkSupportedBwModes_t *supportedBwMode); + +/** + * Get the NvLink Reduced Bandwidth Mode for the device + * + * For Blackwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param getBwMode Reference to \a nvmlNvlinkGetBwMode_t + * + * @return + * - \ref NVML_SUCCESS if the query was successful + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or getBwMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified is not supported + **/ +nvmlReturn_t DECLDIR nvmlDeviceGetNvlinkBwMode(nvmlDevice_t device, + nvmlNvlinkGetBwMode_t *getBwMode); + +/** + * Set the NvLink Reduced Bandwidth Mode for the device + * + * For Blackwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param setBwMode Reference to \a nvmlNvlinkSetBwMode_t + * + * @return + * - \ref NVML_SUCCESS if the Bandwidth mode was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or setBwMode is NULL + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change Bandwidth mode + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified is not supported + **/ +nvmlReturn_t DECLDIR nvmlDeviceSetNvlinkBwMode(nvmlDevice_t device, + nvmlNvlinkSetBwMode_t *setBwMode); + +/** + * Query NVLINK information associated with this device. + * + * @param[in] device The identifier of the target device + * @param[out] info Reference to \a nvmlNvLinkInfo_t + * + * @return + * - \ref NVML_SUCCESS if query is success + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a info is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version is invalid/unsupported + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkInfo(nvmlDevice_t device, nvmlNvLinkInfo_t *info); + +/** @} */ // @defgroup NvLink NvLink Methods + +/***************************************************************************************************/ +/** @defgroup nvmlEvents Event Handling Methods + * This chapter describes methods that NVML can perform against each device to register and wait for + * some event to occur. + * @{ + */ +/***************************************************************************************************/ + +/** + * Create an empty set of events. + * Event set should be freed by \ref nvmlEventSetFree + * + * For Fermi &tm; or newer fully supported devices. + * @param set Reference in which to return the event handle + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a set is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventSetFree + */ +nvmlReturn_t DECLDIR nvmlEventSetCreate(nvmlEventSet_t *set); + +/** + * Starts recording of events on a specified devices and add the events to specified \ref nvmlEventSet_t + * + * For Fermi &tm; or newer fully supported devices. + * ECC events are available only on ECC-enabled devices (see \ref nvmlDeviceGetTotalEccErrors) + * Power capping events are available only on Power Management enabled devices (see \ref nvmlDeviceGetPowerManagementMode) + * + * For Linux only. + * + * This call starts recording of events on specific device. + * All events that occurred before this call are not recorded. + * Checking if some event occurred can be done with \ref nvmlEventSetWait_v2 + * + * If function reports NVML_ERROR_UNKNOWN, event set is in undefined state and should be freed. + * If function reports NVML_ERROR_NOT_SUPPORTED, event set can still be used. None of the requested eventTypes + * are registered in that case. + * + * @param device The identifier of the target device + * @param eventTypes Bitmask of \ref nvmlEventType to record + * @param set Set to which add new event types + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a eventTypes is invalid or \a set is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the platform does not support this feature or some of requested event types + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventType + * @see nvmlDeviceGetSupportedEventTypes + * @see nvmlEventSetWait + * @see nvmlEventSetFree + */ +nvmlReturn_t DECLDIR nvmlDeviceRegisterEvents(nvmlDevice_t device, unsigned long long eventTypes, nvmlEventSet_t set); + +/** + * Returns information about events supported on device + * + * For Fermi &tm; or newer fully supported devices. + * + * Events are not supported on Windows. So this function returns an empty mask in \a eventTypes on Windows. + * + * @param device The identifier of the target device + * @param eventTypes Reference in which to return bitmask of supported events + * + * @return + * - \ref NVML_SUCCESS if the eventTypes has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a eventType is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventType + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedEventTypes(nvmlDevice_t device, unsigned long long *eventTypes); + +/** + * Waits on events and delivers events + * + * For Fermi &tm; or newer fully supported devices. + * + * If some events are ready to be delivered at the time of the call, function returns immediately. + * If there are no events ready to be delivered, function sleeps till event arrives + * but not longer than specified timeout. This function in certain conditions can return before + * specified timeout passes (e.g. when interrupt arrives) + * + * On Windows, in case of Xid error, the function returns the most recent Xid error type seen by the system. + * If there are multiple Xid errors generated before nvmlEventSetWait is invoked then the last seen Xid error + * type is returned for all Xid error events. + * + * On Linux, every Xid error event would return the associated event data and other information if applicable. + * + * In MIG mode, if device handle is provided, the API reports all the events for the available instances, + * only if the caller has appropriate privileges. In absence of required privileges, only the events which + * affect all the instances (i.e. whole device) are reported. + * + * This API does not currently support per-instance event reporting using MIG device handles. + * + * @param set Reference to set of events to wait on + * @param data Reference in which to return event data + * @param timeoutms Maximum amount of wait time in milliseconds for registered event + * + * @return + * - \ref NVML_SUCCESS if the data has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a data is NULL + * - \ref NVML_ERROR_TIMEOUT if no event arrived in specified timeout or interrupt arrived + * - \ref NVML_ERROR_GPU_IS_LOST if a GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlEventType + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlEventSetWait_v2(nvmlEventSet_t set, nvmlEventData_t * data, unsigned int timeoutms); + +/** + * Releases events in the set + * + * For Fermi &tm; or newer fully supported devices. + * + * @param set Reference to events to be released + * + * @return + * - \ref NVML_SUCCESS if the event has been successfully released + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlEventSetFree(nvmlEventSet_t set); + +/** + * Create an empty set of system events. + * Event set should be freed by \ref nvmlSystemEventSetFree + * + * For Fermi &tm; or newer fully supported devices. + * @param request Reference to nvmlSystemEventSetCreateRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlSystemEventSetFree + */ +nvmlReturn_t DECLDIR nvmlSystemEventSetCreate(nvmlSystemEventSetCreateRequest_t *request); + +/** + * Releases system event set + * + * For Fermi &tm; or newer fully supported devices. + * + * @param request Reference to nvmlSystemEventSetFreeRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlDeviceRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlSystemEventSetFree(nvmlSystemEventSetFreeRequest_t *request); + +/** + * Starts recording of events on system and add the events to specified \ref nvmlSystemEventSet_t + * + * For Linux only. + * + * This call starts recording of events on specific device. + * All events that occurred before this call are not recorded. + * Checking if some event occurred can be done with \ref nvmlSystemEventSetWait + * + * If function reports NVML_ERROR_UNKNOWN, event set is in undefined state and should be freed. + * If function reports NVML_ERROR_NOT_SUPPORTED, event set can still be used. None of the requested eventTypes + * are registered in that case. + * + * @param request Reference to the struct nvmlSystemRegisterEventRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlSystemEventType + * @see nvmlSystemEventSetWait + * @see nvmlEventSetFree + */ +nvmlReturn_t DECLDIR nvmlSystemRegisterEvents(nvmlSystemRegisterEventRequest_t *request); + +/** + * Waits on system events and delivers events + * + * For Fermi &tm; or newer fully supported devices. + * + * If some events are ready to be delivered at the time of the call, function returns immediately. + * If there are no events ready to be delivered, function sleeps till event arrives + * but not longer than specified timeout. This function in certain conditions can return before + * specified timeout passes (e.g. when interrupt arrives) + * + * if the return request->numEvent equals to request->dataSize, there might be outstanding + * event, it is recommended to call nvmlSystemEventSetWait again to query all the events. + * + * @param request Reference in which to nvmlSystemEventSetWaitRequest_t + * + * @return + * - \ref NVML_SUCCESS if the event has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if request is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH for unsupported version + * - \ref NVML_ERROR_TIMEOUT if no event notification after timeoutms + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlSystemEventType + * @see nvmlSystemRegisterEvents + */ +nvmlReturn_t DECLDIR nvmlSystemEventSetWait(nvmlSystemEventSetWaitRequest_t *request); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlZPI Drain states + * This chapter describes methods that NVML can perform against each device to control their drain state + * and recognition by NVML and NVIDIA kernel driver. These methods can be used with out-of-band tools to + * power on/off GPUs, enable robust reset scenarios, etc. + * @{ + */ +/***************************************************************************************************/ + +/** + * Modify the drain state of a GPU. This method forces a GPU to no longer accept new incoming requests. + * Any new NVML process will no longer see this GPU. Persistence mode for this GPU must be turned off before + * this call is made. + * Must be called as administrator. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI address of the GPU drain state to be modified + * @param newState The drain state that should be entered, see \ref nvmlEnableState_t + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a nvmlIndex or \a newState is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_NO_PERMISSION if the calling process has insufficient permissions to perform operation + * - \ref NVML_ERROR_IN_USE if the device has persistence mode turned on + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceModifyDrainState (nvmlPciInfo_t *pciInfo, nvmlEnableState_t newState); + +/** + * Query the drain state of a GPU. This method is used to check if a GPU is in a currently draining + * state. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI address of the GPU drain state to be queried + * @param currentState The current drain state for this GPU, see \ref nvmlEnableState_t + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a nvmlIndex or \a currentState is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceQueryDrainState (nvmlPciInfo_t *pciInfo, nvmlEnableState_t *currentState); + +/** + * This method will remove the specified GPU from the view of both NVML and the NVIDIA kernel driver + * as long as no other processes are attached. If other processes are attached, this call will return + * NVML_ERROR_IN_USE and the GPU will be returned to its original "draining" state. Note: the + * only situation where a process can still be attached after nvmlDeviceModifyDrainState() is called + * to initiate the draining state is if that process was using, and is still using, a GPU before the + * call was made. Also note, persistence mode counts as an attachment to the GPU thus it must be disabled + * prior to this call. + * + * For long-running NVML processes please note that this will change the enumeration of current GPUs. + * For example, if there are four GPUs present and GPU1 is removed, the new enumeration will be 0-2. + * Also, device handles after the removed GPU will not be valid and must be re-established. + * Must be run as administrator. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI address of the GPU to be removed + * @param gpuState Whether the GPU is to be removed, from the OS + * see \ref nvmlDetachGpuState_t + * @param linkState Requested upstream PCIe link state, see \ref nvmlPcieLinkState_t + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a nvmlIndex is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the device doesn't support this feature + * - \ref NVML_ERROR_IN_USE if the device is still in use and cannot be removed + */ +nvmlReturn_t DECLDIR nvmlDeviceRemoveGpu_v2(nvmlPciInfo_t *pciInfo, nvmlDetachGpuState_t gpuState, nvmlPcieLinkState_t linkState); + +/** + * Request the OS and the NVIDIA kernel driver to rediscover a portion of the PCI subsystem looking for GPUs that + * were previously removed. The portion of the PCI tree can be narrowed by specifying a domain, bus, and device. + * If all are zeroes then the entire PCI tree will be searched. Please note that for long-running NVML processes + * the enumeration will change based on how many GPUs are discovered and where they are inserted in bus order. + * + * In addition, all newly discovered GPUs will be initialized and their ECC scrubbed which may take several seconds + * per GPU. Also, all device handles are no longer guaranteed to be valid post discovery. + * + * Must be run as administrator. + * For Linux only. + * + * For Pascal &tm; or newer fully supported devices. + * Some Kepler devices supported. + * + * @param pciInfo The PCI tree to be searched. Only the domain, bus, and device + * fields are used in this call. + * + * @return + * - \ref NVML_SUCCESS if counters were successfully reset + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a pciInfo is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if the operating system does not support this feature + * - \ref NVML_ERROR_OPERATING_SYSTEM if the operating system is denying this feature + * - \ref NVML_ERROR_NO_PERMISSION if the calling process has insufficient permissions to perform operation + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceDiscoverGpus (nvmlPciInfo_t *pciInfo); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlFieldValueQueries Field Value Queries + * This chapter describes NVML operations that are associated with retrieving Field Values from NVML + * @{ + */ +/***************************************************************************************************/ + +/** + * Request values for a list of fields for a device. This API allows multiple fields to be queried at once. + * If any of the underlying fieldIds are populated by the same driver call, the results for those field IDs + * will be populated from a single call rather than making a driver call for each fieldId. + * + * @param device The device handle of the GPU to request field values for + * @param valuesCount Number of entries in values that should be retrieved + * @param values Array of \a valuesCount structures to hold field values. + * Each value's fieldId must be populated prior to this call + * + * @return + * - \ref NVML_SUCCESS if any values in \a values were populated. Note that you must + * check the nvmlReturn field of each value for each individual + * status + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a values is NULL + */ +nvmlReturn_t DECLDIR nvmlDeviceGetFieldValues(nvmlDevice_t device, int valuesCount, nvmlFieldValue_t *values); + +/** + * Clear values for a list of fields for a device. This API allows multiple fields to be cleared at once. + * + * @param device The device handle of the GPU to request field values for + * @param valuesCount Number of entries in values that should be cleared + * @param values Array of \a valuesCount structures to hold field values. + * Each value's fieldId must be populated prior to this call + * + * @return + * - \ref NVML_SUCCESS if any values in \a values were cleared. Note that you must + * check the nvmlReturn field of each value for each individual + * status + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a values is NULL + */ +nvmlReturn_t DECLDIR nvmlDeviceClearFieldValues(nvmlDevice_t device, int valuesCount, nvmlFieldValue_t *values); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVirtualGpuQueries vGPU APIs + * This chapter describes operations that are associated with NVIDIA vGPU Software products. + * @{ + */ +/***************************************************************************************************/ + +/** + * This method is used to get the virtualization mode corresponding to the GPU. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device Identifier of the target device + * @param pVirtualMode Reference to virtualization mode. One of NVML_GPU_VIRTUALIZATION_? + * + * @return + * - \ref NVML_SUCCESS if \a pVirtualMode is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pVirtualMode is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVirtualizationMode(nvmlDevice_t device, nvmlGpuVirtualizationMode_t *pVirtualMode); + +/** + * Queries if SR-IOV host operation is supported on a vGPU supported device. + * + * Checks whether SR-IOV host capability is supported by the device and the + * driver, and indicates device is in SR-IOV mode if both of these conditions + * are true. + * + * @param device The identifier of the target device + * @param pHostVgpuMode Reference in which to return the current vGPU mode + * + * @return + * - \ref NVML_SUCCESS if device's vGPU mode has been successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device handle is 0 or \a pVgpuMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device doesn't support this feature. + * - \ref NVML_ERROR_UNKNOWN if any unexpected error occurred + */ +nvmlReturn_t DECLDIR nvmlDeviceGetHostVgpuMode(nvmlDevice_t device, nvmlHostVgpuMode_t *pHostVgpuMode); + +/** + * This method is used to set the virtualization mode corresponding to the GPU. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device Identifier of the target device + * @param virtualMode virtualization mode. One of NVML_GPU_VIRTUALIZATION_? + * + * @return + * - \ref NVML_SUCCESS if \a virtualMode is set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a virtualMode is NULL + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_SUPPORTED if setting of virtualization mode is not supported. + * - \ref NVML_ERROR_NO_PERMISSION if setting of virtualization mode is not allowed for this client. + */ +nvmlReturn_t DECLDIR nvmlDeviceSetVirtualizationMode(nvmlDevice_t device, nvmlGpuVirtualizationMode_t virtualMode); + +/** + * Get the vGPU heterogeneous mode for the device. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * On successful return, the function returns \a pHeterogeneousMode->mode with the current vGPU heterogeneous mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to retrieve the vGPU heterogeneous mode. + * \a pHeterogeneousMode->mode can either be \ref NVML_FEATURE_ENABLED or \ref NVML_FEATURE_DISABLED. + * + * @param device The identifier of the target device + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a pHeterogeneousMode is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device doesn't support this feature + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuHeterogeneousMode(nvmlDevice_t device, nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** + * Enable or disable vGPU heterogeneous mode for the device. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * API would return an appropriate error code upon unsuccessful activation. For example, the heterogeneous mode + * set will fail with error \ref NVML_ERROR_IN_USE if any vGPU instance is active on the device. The caller of this API + * is expected to shutdown the vGPU VMs and retry setting the \a mode. + * On KVM platform, setting heterogeneous mode is allowed, if no MDEV device is created on the device, else will fail + * with same error \ref NVML_ERROR_IN_USE. + * On successful return, the function updates the vGPU heterogeneous mode with the user provided \a pHeterogeneousMode->mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to set the vGPU heterogeneous mode. + * + * @param device Identifier of the target device + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a pHeterogeneousMode is NULL or \a pHeterogeneousMode->mode is invalid + * - \ref NVML_ERROR_IN_USE If the \a device is in use + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device doesn't support this feature + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetVgpuHeterogeneousMode(nvmlDevice_t device, const nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** + * Query the placement ID of active vGPU instance. + * + * When in vGPU heterogeneous mode, this function returns a valid placement ID as \a pPlacement->placementId + * else NVML_INVALID_VGPU_PLACEMENT_ID is returned. + * \a pPlacement->version is the version number of the structure nvmlVgpuPlacementId_t, the caller should + * set the correct version number to get placement id of the vGPU instance \a vgpuInstance. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param pPlacement Pointer to vGPU placement ID structure \a nvmlVgpuPlacementId_t + * + * @return + * - \ref NVML_SUCCESS If information is successfully retrieved + * - \ref NVML_ERROR_NOT_FOUND If \a vgpuInstance does not match a valid active vGPU instance + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuInstance is invalid or \a pPlacement is NULL + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pPlacement is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetPlacementId(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuPlacementId_t *pPlacement); + +/** + * Query the supported vGPU placement ID of the vGPU type. + * + * The function returns an array of supported vGPU placement IDs for the specified vGPU type ID in the buffer provided + * by the caller at \a pPlacementList->placementIds. The required memory for the placementIds array must be allocated + * based on the maximum number of vGPU type instances, which is retrievable through \ref nvmlVgpuTypeGetMaxInstances(). + * If the provided count by the caller is insufficient, the function will return NVML_ERROR_INSUFFICIENT_SIZE along with + * the number of required entries in \a pPlacementList->count. The caller should then reallocate a buffer with the size + * of pPlacementList->count * sizeof(pPlacementList->placementIds) and invoke the function again. + * + * To obtain a list of homogeneous placement IDs, the caller needs to set \a pPlacementList->mode to NVML_VGPU_PGPU_HOMOGENEOUS_MODE. + * For heterogeneous placement IDs, \a pPlacementList->mode should be set to NVML_VGPU_PGPU_HETEROGENEOUS_MODE. + * By default, a list of heterogeneous placement IDs is returned. + * + * @param device Identifier of the target device + * @param vgpuTypeId Handle to vGPU type. The vGPU type ID + * @param pPlacementList Pointer to the vGPU placement structure \a nvmlVgpuPlacementList_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a vgpuTypeId is invalid or \a pPlacementList is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device or \a vgpuTypeId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pPlacementList is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If the buffer is small, element count is returned in \a pPlacementList->count + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuTypeSupportedPlacements(nvmlDevice_t device, nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuPlacementList_t *pPlacementList); + +/** + * Query the creatable vGPU placement ID of the vGPU type. + * + * An array of creatable vGPU placement IDs for the vGPU type ID indicated by \a vgpuTypeId is returned in the + * caller-supplied buffer of \a pPlacementList->placementIds. Memory needed for the placementIds array should be + * allocated based on maximum instances of a vGPU type which can be queried via \ref nvmlVgpuTypeGetMaxInstances(). + * If the provided count by the caller is insufficient, the function will return NVML_ERROR_INSUFFICIENT_SIZE along with + * the number of required entries in \a pPlacementList->count. The caller should then reallocate a buffer with the size + * of pPlacementList->count * sizeof(pPlacementList->placementIds) and invoke the function again. + * + * The creatable vGPU placement IDs may differ over time, as there may be restrictions on what type of vGPU the + * vGPU instance is running. + * + * @param device The identifier of the target device + * @param vgpuTypeId Handle to vGPU type. The vGPU type ID + * @param pPlacementList Pointer to the list of vGPU placement structure \a nvmlVgpuPlacementList_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device or \a vgpuTypeId is invalid or \a pPlacementList is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device or \a vgpuTypeId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pPlacementList is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuTypeCreatablePlacements(nvmlDevice_t device, nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuPlacementList_t *pPlacementList); + +/** + * Retrieve the static GSP heap size of the vGPU type in bytes + * + * @param vgpuTypeId Handle to vGPU type + * @param gspHeapSize Reference to return the GSP heap size value + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuTypeId is invalid, or \a gspHeapSize is NULL + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetGspHeapSize(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *gspHeapSize); + +/** + * Retrieve the static framebuffer reservation of the vGPU type in bytes + * + * @param vgpuTypeId Handle to vGPU type + * @param fbReservation Reference to return the framebuffer reservation + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuTypeId is invalid, or \a fbReservation is NULL + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetFbReservation(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *fbReservation); + +/** + * Retrieve the currently used runtime state size of the vGPU instance + * + * This size represents the maximum in-memory data size utilized by a vGPU instance during standard operation. + * This measurement is exclusive of frame buffer (FB) data size assigned to the vGPU instance. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param pState Pointer to the vGPU runtime state's structure \a nvmlVgpuRuntimeState_t + * + * @return + * - \ref NVML_SUCCESS If information is successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuInstance is invalid, or \a pState is NULL + * - \ref NVML_ERROR_NOT_FOUND If \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pState is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetRuntimeStateSize(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuRuntimeState_t *pState); + +/** + * Set the desirable vGPU capability of a device + * + * Refer to the \a nvmlDeviceVgpuCapability_t structure for the specific capabilities that can be set. + * See \ref nvmlEnableState_t for available state. + * + * @param device The identifier of the target device + * @param capability Specifies the \a nvmlDeviceVgpuCapability_t to be set + * @param state The target capability mode + * + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, or \a capability is invalid, or \a state is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported in current state, or \a device not in vGPU mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceSetVgpuCapabilities(nvmlDevice_t device, nvmlDeviceVgpuCapability_t capability, nvmlEnableState_t state); + +/** + * Retrieve the vGPU Software licensable features. + * + * Identifies whether the system supports vGPU Software Licensing. If it does, return the list of licensable feature(s) + * and their current license status. + * + * @param device Identifier of the target device + * @param pGridLicensableFeatures Pointer to structure in which vGPU software licensable features are returned + * + * @return + * - \ref NVML_SUCCESS if licensable features are successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a pGridLicensableFeatures is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures_v4(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVgpu vGPU Management + * @{ + * + * This chapter describes APIs supporting NVIDIA vGPU. + */ +/***************************************************************************************************/ + +/** + * Retrieve the requested vGPU driver capability. + * + * Refer to the \a nvmlVgpuDriverCapability_t structure for the specific capabilities that can be queried. + * The return value in \a capResult should be treated as a boolean, with a non-zero value indicating that the capability + * is supported. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param capability Specifies the \a nvmlVgpuDriverCapability_t to be queried + * @param capResult A boolean for the queried capability indicating that feature is supported + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a capability is invalid, or \a capResult is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED the API is not supported in current state or \a devices not in vGPU mode + * - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlGetVgpuDriverCapabilities(nvmlVgpuDriverCapability_t capability, unsigned int *capResult); + +/** + * Retrieve the requested vGPU capability for GPU. + * + * Refer to the \a nvmlDeviceVgpuCapability_t structure for the specific capabilities that can be queried. + * The return value in \a capResult reports a non-zero value indicating that the capability + * is supported, and also reports the capability's data based on the queried capability. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param capability Specifies the \a nvmlDeviceVgpuCapability_t to be queried + * @param capResult Specifies that the queried capability is supported, and also returns capability's data + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a capability is invalid, or \a capResult is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED the API is not supported in current state or \a device not in vGPU mode + * - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuCapabilities(nvmlDevice_t device, nvmlDeviceVgpuCapability_t capability, unsigned int *capResult); + +/** + * Retrieve the supported vGPU types on a physical GPU (device). + * + * An array of supported vGPU types for the physical GPU indicated by \a device is returned in the caller-supplied buffer + * pointed at by \a vgpuTypeIds. The element count of nvmlVgpuTypeId_t array is passed in \a vgpuCount, and \a vgpuCount + * is used to return the number of vGPU types written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the vGPU type array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlVgpuTypeId_t array required in \a vgpuCount. + * To query the number of vGPU types supported for the GPU, call this function with *vgpuCount = 0. + * The code will return NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if no vGPU types are supported. + * + * @param device The identifier of the target device + * @param vgpuCount Pointer to caller-supplied array size, and returns number of vGPU types + * @param vgpuTypeIds Pointer to caller-supplied array in which to return list of vGPU types + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a vgpuTypeIds buffer is too small, array element count is returned in \a vgpuCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuCount is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSupportedVgpus(nvmlDevice_t device, unsigned int *vgpuCount, nvmlVgpuTypeId_t *vgpuTypeIds); + +/** + * Retrieve the currently creatable vGPU types on a physical GPU (device). + * + * An array of creatable vGPU types for the physical GPU indicated by \a device is returned in the caller-supplied buffer + * pointed at by \a vgpuTypeIds. The element count of nvmlVgpuTypeId_t array is passed in \a vgpuCount, and \a vgpuCount + * is used to return the number of vGPU types written to the buffer. + * + * The creatable vGPU types for a device may differ over time, as there may be restrictions on what type of vGPU types + * can concurrently run on a device. For example, if only one vGPU type is allowed at a time on a device, then the creatable + * list will be restricted to whatever vGPU type is already running on the device. + * + * If the supplied buffer is not large enough to accommodate the vGPU type array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlVgpuTypeId_t array required in \a vgpuCount. + * To query the number of vGPU types that can be created for the GPU, call this function with *vgpuCount = 0. + * The code will return NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if no vGPU types are creatable. + * + * @param device The identifier of the target device + * @param vgpuCount Pointer to caller-supplied array size, and returns number of vGPU types + * @param vgpuTypeIds Pointer to caller-supplied array in which to return list of vGPU types + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a vgpuTypeIds buffer is too small, array element count is returned in \a vgpuCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuCount is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCreatableVgpus(nvmlDevice_t device, unsigned int *vgpuCount, nvmlVgpuTypeId_t *vgpuTypeIds); + +/** + * Retrieve the class of a vGPU type. It will not exceed 64 characters in length (including the NUL terminator). + * See \ref nvmlConstants::NVML_DEVICE_NAME_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuTypeClass Pointer to string array to return class in + * @param size Size of string + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a vgpuTypeClass is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetClass(nvmlVgpuTypeId_t vgpuTypeId, char *vgpuTypeClass, unsigned int *size); + +/** + * Retrieve the vGPU type name. + * + * The name is an alphanumeric string that denotes a particular vGPU, e.g. GRID M60-2Q. It will not + * exceed 64 characters in length (including the NUL terminator). See \ref + * nvmlConstants::NVML_DEVICE_NAME_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuTypeName Pointer to buffer to return name + * @param size Size of buffer + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a name is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetName(nvmlVgpuTypeId_t vgpuTypeId, char *vgpuTypeName, unsigned int *size); + +/** + * Retrieve the GPU Instance Profile ID for the given vGPU type ID. + * The API will return a valid GPU Instance Profile ID for the MIG capable vGPU types, else INVALID_GPU_INSTANCE_PROFILE_ID is + * returned. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param gpuInstanceProfileId GPU Instance Profile ID + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_NOT_SUPPORTED if \a device is not in vGPU Host virtualization mode + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a gpuInstanceProfileId is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetGpuInstanceProfileId(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *gpuInstanceProfileId); + +/** + * Retrieve the device ID of a vGPU type. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param deviceID Device ID and vendor ID of the device contained in single 32 bit value + * @param subsystemID Subsystem ID and subsystem vendor ID of the device contained in single 32 bit value + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a deviceId or \a subsystemID are NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetDeviceID(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *deviceID, unsigned long long *subsystemID); + +/** + * Retrieve the vGPU framebuffer size in bytes. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param fbSize Pointer to framebuffer size in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a fbSize is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetFramebufferSize(nvmlVgpuTypeId_t vgpuTypeId, unsigned long long *fbSize); + +/** + * Retrieve count of vGPU's supported display heads. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param numDisplayHeads Pointer to number of display heads + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a numDisplayHeads is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetNumDisplayHeads(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *numDisplayHeads); + +/** + * Retrieve vGPU display head's maximum supported resolution. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param displayIndex Zero-based index of display head + * @param xdim Pointer to maximum number of pixels in X dimension + * @param ydim Pointer to maximum number of pixels in Y dimension + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a xdim or \a ydim are NULL, or \a displayIndex + * is out of range. + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetResolution(nvmlVgpuTypeId_t vgpuTypeId, unsigned int displayIndex, unsigned int *xdim, unsigned int *ydim); + +/** + * Retrieve license requirements for a vGPU type + * + * The license type and version required to run the specified vGPU type is returned as an alphanumeric string, in the form + * ",", for example "GRID-Virtual-PC,2.0". If a vGPU is runnable with* more than one type of license, + * the licenses are delimited by a semicolon, for example "GRID-Virtual-PC,2.0;GRID-Virtual-WS,2.0;GRID-Virtual-WS-Ext,2.0". + * + * The total length of the returned string will not exceed 128 characters, including the NUL terminator. + * See \ref nvmlVgpuConstants::NVML_GRID_LICENSE_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuTypeLicenseString Pointer to buffer to return license info + * @param size Size of \a vgpuTypeLicenseString buffer + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a vgpuTypeLicenseString is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetLicense(nvmlVgpuTypeId_t vgpuTypeId, char *vgpuTypeLicenseString, unsigned int size); + +/** + * Retrieve the static frame rate limit value of the vGPU type + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param frameRateLimit Reference to return the frame rate limit value + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_NOT_SUPPORTED if frame rate limiter is turned off for the vGPU type + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a frameRateLimit is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetFrameRateLimit(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *frameRateLimit); + +/** + * Retrieve the maximum number of vGPU instances creatable on a device for given vGPU type + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param vgpuTypeId Handle to vGPU type + * @param vgpuInstanceCount Pointer to get the max number of vGPU instances + * that can be created on a deicve for given vgpuTypeId + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid or is not supported on target device, + * or \a vgpuInstanceCount is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetMaxInstances(nvmlDevice_t device, nvmlVgpuTypeId_t vgpuTypeId, unsigned int *vgpuInstanceCount); + +/** + * Retrieve the maximum number of vGPU instances supported per VM for given vGPU type + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param vgpuInstanceCountPerVm Pointer to get the max number of vGPU instances supported per VM for given \a vgpuTypeId + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a vgpuInstanceCountPerVm is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetMaxInstancesPerVm(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *vgpuInstanceCountPerVm); + +/** + * Retrieve the BAR1 info for given vGPU type. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuTypeId Handle to vGPU type + * @param bar1Info Pointer to the vGPU type BAR1 information structure \a nvmlVgpuTypeBar1Info_t + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a bar1Info is NULL + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetBAR1Info(nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuTypeBar1Info_t *bar1Info); + +/** + * Retrieve the active vGPU instances on a device. + * + * An array of active vGPU instances is returned in the caller-supplied buffer pointed at by \a vgpuInstances. The + * array element count is passed in \a vgpuCount, and \a vgpuCount is used to return the number of vGPU instances + * written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the vGPU instance array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlVgpuInstance_t array required in \a vgpuCount. + * To query the number of active vGPU instances, call this function with *vgpuCount = 0. The code will return + * NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if no vGPU Types are supported. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param device The identifier of the target device + * @param vgpuCount Pointer which passes in the array size as well as get + * back the number of types + * @param vgpuInstances Pointer to array in which to return list of vGPU instances + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, or \a vgpuCount is NULL + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetActiveVgpus(nvmlDevice_t device, unsigned int *vgpuCount, nvmlVgpuInstance_t *vgpuInstances); + +/** + * Retrieve the VM ID associated with a vGPU instance. + * + * The VM ID is returned as a string, not exceeding 80 characters in length (including the NUL terminator). + * See \ref nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE. + * + * The format of the VM ID varies by platform, and is indicated by the type identifier returned in \a vmIdType. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param vmId Pointer to caller-supplied buffer to hold VM ID + * @param size Size of buffer in bytes + * @param vmIdType Pointer to hold VM ID type + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vmId or \a vmIdType is NULL, or \a vgpuInstance is 0 + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetVmID(nvmlVgpuInstance_t vgpuInstance, char *vmId, unsigned int size, nvmlVgpuVmIdType_t *vmIdType); + +/** + * Retrieve the UUID of a vGPU instance. + * + * The UUID is a globally unique identifier associated with the vGPU, and is returned as a 5-part hexadecimal string, + * not exceeding 80 characters in length (including the NULL terminator). + * See \ref nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param uuid Pointer to caller-supplied buffer to hold vGPU UUID + * @param size Size of buffer in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a uuid is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetUUID(nvmlVgpuInstance_t vgpuInstance, char *uuid, unsigned int size); + +/** + * Retrieve the NVIDIA driver version installed in the VM associated with a vGPU. + * + * The version is returned as an alphanumeric string in the caller-supplied buffer \a version. The length of the version + * string will not exceed 80 characters in length (including the NUL terminator). + * See \ref nvmlConstants::NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE. + * + * nvmlVgpuInstanceGetVmDriverVersion() may be called at any time for a vGPU instance. The guest VM driver version is + * returned as "Not Available" if no NVIDIA driver is installed in the VM, or the VM has not yet booted to the point where the + * NVIDIA driver is loaded and initialized. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param version Caller-supplied buffer to return driver version string + * @param length Size of \a version buffer + * + * @return + * - \ref NVML_SUCCESS if \a version has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0 + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetVmDriverVersion(nvmlVgpuInstance_t vgpuInstance, char* version, unsigned int length); + +/** + * Retrieve the framebuffer usage in bytes. + * + * Framebuffer usage is the amont of vGPU framebuffer memory that is currently in use by the VM. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance The identifier of the target instance + * @param fbUsage Pointer to framebuffer usage in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a fbUsage is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFbUsage(nvmlVgpuInstance_t vgpuInstance, unsigned long long *fbUsage); + +/** + * @deprecated Use \ref nvmlVgpuInstanceGetLicenseInfo_v2. + * + * Retrieve the current licensing state of the vGPU instance. + * + * If the vGPU is currently licensed, \a licensed is set to 1, otherwise it is set to 0. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param licensed Reference to return the licensing status + * + * @return + * - \ref NVML_SUCCESS if \a licensed has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a licensed is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +DEPRECATED(13.0) nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseStatus(nvmlVgpuInstance_t vgpuInstance, unsigned int *licensed); + +/** + * Retrieve the vGPU type of a vGPU instance. + * + * Returns the vGPU type ID of vgpu assigned to the vGPU instance. + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param vgpuTypeId Reference to return the vgpuTypeId + * + * @return + * - \ref NVML_SUCCESS if \a vgpuTypeId has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a vgpuTypeId is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetType(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuTypeId_t *vgpuTypeId); + +/** + * Retrieve the frame rate limit set for the vGPU instance. + * + * Returns the value of the frame rate limit set for the vGPU instance + * + * For Kepler &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param frameRateLimit Reference to return the frame rate limit + * + * @return + * - \ref NVML_SUCCESS if \a frameRateLimit has been set + * - \ref NVML_ERROR_NOT_SUPPORTED if frame rate limiter is turned off for the vGPU type + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a frameRateLimit is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFrameRateLimit(nvmlVgpuInstance_t vgpuInstance, unsigned int *frameRateLimit); + +/** + * Retrieve the current ECC mode of vGPU instance. + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param eccMode Reference in which to return the current ECC mode + * + * @return + * - \ref NVML_SUCCESS if the vgpuInstance's ECC mode has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a mode is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEccMode(nvmlVgpuInstance_t vgpuInstance, nvmlEnableState_t *eccMode); + +/** + * Retrieve the encoder capacity of a vGPU instance, as a percentage of maximum encoder capacity with valid values in the range 0-100. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param encoderCapacity Reference to an unsigned int for the encoder capacity + * + * @return + * - \ref NVML_SUCCESS if \a encoderCapacity has been retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a encoderQueryType is invalid + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEncoderCapacity(nvmlVgpuInstance_t vgpuInstance, unsigned int *encoderCapacity); + +/** + * Set the encoder capacity of a vGPU instance, as a percentage of maximum encoder capacity with valid values in the range 0-100. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param encoderCapacity Unsigned int for the encoder capacity value + * + * @return + * - \ref NVML_SUCCESS if \a encoderCapacity has been set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a encoderCapacity is out of range of 0-100. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceSetEncoderCapacity(nvmlVgpuInstance_t vgpuInstance, unsigned int encoderCapacity); + +/** + * Retrieves the current encoder statistics of a vGPU Instance + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param sessionCount Reference to an unsigned int for count of active encoder sessions + * @param averageFps Reference to an unsigned int for trailing average FPS of all active sessions + * @param averageLatency Reference to an unsigned int for encode latency in microseconds + * + * @return + * - \ref NVML_SUCCESS if \a sessionCount, \a averageFps and \a averageLatency is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount , or \a averageFps or \a averageLatency is NULL + * or \a vgpuInstance is 0. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEncoderStats(nvmlVgpuInstance_t vgpuInstance, unsigned int *sessionCount, + unsigned int *averageFps, unsigned int *averageLatency); + +/** + * Retrieves information about all active encoder sessions on a vGPU Instance. + * + * An array of active encoder sessions is returned in the caller-supplied buffer pointed at by \a sessionInfo. The + * array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions + * written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the active session array, the function returns + * NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlEncoderSessionInfo_t array required in \a sessionCount. + * To query the number of active encoder sessions, call this function with *sessionCount = 0. The code will return + * NVML_SUCCESS with number of active encoder sessions updated in *sessionCount. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param sessionCount Reference to caller supplied array size, and returns + * the number of sessions. + * @param sessionInfo Reference to caller supplied array in which the list + * of session information us returned. + * + * @return + * - \ref NVML_SUCCESS if \a sessionInfo is fetched + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is + returned in \a sessionCount + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a sessionCount is NULL, or \a vgpuInstance is 0. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetEncoderSessions(nvmlVgpuInstance_t vgpuInstance, unsigned int *sessionCount, nvmlEncoderSessionInfo_t *sessionInfo); + +/** +* Retrieves the active frame buffer capture sessions statistics of a vGPU Instance +* +* For Maxwell &tm; or newer fully supported devices. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param fbcStats Reference to nvmlFBCStats_t structure containing NvFBC stats +* +* @return +* - \ref NVML_SUCCESS if \a fbcStats is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a fbcStats is NULL +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFBCStats(nvmlVgpuInstance_t vgpuInstance, nvmlFBCStats_t *fbcStats); + +/** +* Retrieves information about active frame buffer capture sessions on a vGPU Instance. +* +* An array of active FBC sessions is returned in the caller-supplied buffer pointed at by \a sessionInfo. The +* array element count is passed in \a sessionCount, and \a sessionCount is used to return the number of sessions +* written to the buffer. +* +* If the supplied buffer is not large enough to accommodate the active session array, the function returns +* NVML_ERROR_INSUFFICIENT_SIZE, with the element count of nvmlFBCSessionInfo_t array required in \a sessionCount. +* To query the number of active FBC sessions, call this function with *sessionCount = 0. The code will return +* NVML_SUCCESS with number of active FBC sessions updated in *sessionCount. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @note hResolution, vResolution, averageFPS and averageLatency data for a FBC session returned in \a sessionInfo may +* be zero if there are no new frames captured since the session started. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param sessionCount Reference to caller supplied array size, and returns the number of sessions. +* @param sessionInfo Reference in which to return the session information +* +* @return +* - \ref NVML_SUCCESS if \a sessionInfo is fetched +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a sessionCount is NULL. +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a sessionCount is too small, array element count is returned in \a sessionCount +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetFBCSessions(nvmlVgpuInstance_t vgpuInstance, unsigned int *sessionCount, nvmlFBCSessionInfo_t *sessionInfo); + +/** +* Retrieve the GPU Instance ID for the given vGPU Instance. +* The API will return a valid GPU Instance ID for MIG backed vGPU Instance, else INVALID_GPU_INSTANCE_ID is returned. +* +* For Kepler &tm; or newer fully supported devices. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param gpuInstanceId GPU Instance ID +* +* @return +* - \ref NVML_SUCCESS successful completion +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a gpuInstanceId is NULL. +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetGpuInstanceId(nvmlVgpuInstance_t vgpuInstance, unsigned int *gpuInstanceId); + +/** +* Retrieves the PCI Id of the given vGPU Instance i.e. the PCI Id of the GPU as seen inside the VM. +* +* The vGPU PCI id is returned as "00000000:00:00.0" if NVIDIA driver is not installed on the vGPU instance. +* +* @param vgpuInstance Identifier of the target vGPU instance +* @param vgpuPciId Caller-supplied buffer to return vGPU PCI Id string +* @param length Size of the vgpuPciId buffer +* +* @return +* - \ref NVML_SUCCESS if vGPU PCI Id is sucessfully retrieved +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a vgpuPciId is NULL +* - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system +* - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running on the vGPU instance +* - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a length is too small, \a length is set to required length +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetGpuPciId(nvmlVgpuInstance_t vgpuInstance, char *vgpuPciId, unsigned int *length); + +/** +* Retrieve the requested capability for a given vGPU type. Refer to the \a nvmlVgpuCapability_t structure +* for the specific capabilities that can be queried. The return value in \a capResult should be treated as +* a boolean, with a non-zero value indicating that the capability is supported. +* +* For Maxwell &tm; or newer fully supported devices. +* +* @param vgpuTypeId Handle to vGPU type +* @param capability Specifies the \a nvmlVgpuCapability_t to be queried +* @param capResult A boolean for the queried capability indicating that feature is supported +* +* @return +* - \ref NVML_SUCCESS successful completion +* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized +* - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuTypeId is invalid, or \a capability is invalid, or \a capResult is NULL +* - \ref NVML_ERROR_UNKNOWN on any unexpected error +*/ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetCapabilities(nvmlVgpuTypeId_t vgpuTypeId, nvmlVgpuCapability_t capability, unsigned int *capResult); + +/** + * Retrieve the MDEV UUID of a vGPU instance. + * + * The MDEV UUID is a globally unique identifier of the mdev device assigned to the VM, and is returned as a 5-part hexadecimal string, + * not exceeding 80 characters in length (including the NULL terminator). + * MDEV UUID is displayed only on KVM platform. + * See \ref nvmlConstants::NVML_DEVICE_UUID_BUFFER_SIZE. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param mdevUuid Pointer to caller-supplied buffer to hold MDEV UUID + * @param size Size of buffer in bytes + * + * @return + * - \ref NVML_SUCCESS successful completion + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_NOT_SUPPORTED on any hypervisor other than KVM + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a mdevUuid is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a size is too small + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetMdevUUID(nvmlVgpuInstance_t vgpuInstance, char *mdevUuid, unsigned int size); + +/** + * Query the currently creatable vGPU types on a specific GPU Instance. + * + * The function returns an array of vGPU types that can be created for a specified GPU instance. This array is stored + * in a caller-supplied buffer, with the buffer's element count passed through \a pVgpus->vgpuCount. The number of + * vGPU types written to the buffer is indicated by \a pVgpus->vgpuCount. If the buffer is too small to hold the vGPU + * type array, the function returns NVML_ERROR_INSUFFICIENT_SIZE and updates \a pVgpus->vgpuCount with the required + * element count. + * + * To determine the creatable vGPUs for a GPU Instance, invoke this function with \a pVgpus->vgpuCount set to 0 and + * \a pVgpus->vgpuTypeIds as NULL. This will result in NVML_ERROR_INSUFFICIENT_SIZE being returned, along with the + * count value in \a pVgpus->vgpuCount. + * + * The creatable vGPU types may differ over time, as there may be restrictions on what type of vGPUs can concurrently + * run on the device. + * + * @param gpuInstance The GPU instance handle + * @param pVgpus Pointer to the caller-provided structure of nvmlVgpuTypeIdInfo_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pVgpus is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a pVgpus->vgpuTypeIds buffer is small + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pVgpus is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetCreatableVgpus(nvmlGpuInstance_t gpuInstance, nvmlVgpuTypeIdInfo_t *pVgpus); + +/** + * Retrieve the maximum number of vGPU instances per GPU instance for given vGPU type + * + * @param pMaxInstance Pointer to the caller-provided structure of nvmlVgpuTypeMaxInstance_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pMaxInstance is NULL or \a pMaxInstance->vgpuTypeId is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or non-MIG vGPU type + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pMaxInstance is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuTypeGetMaxInstancesPerGpuInstance(nvmlVgpuTypeMaxInstance_t *pMaxInstance); + +/** + * Retrieve the active vGPU instances within a GPU instance. + * + * An array of active vGPU instances is returned in the caller-supplied buffer pointed + * at by \a pVgpuInstanceInfo->vgpuInstances. The array element count is passed in + * \a pVgpuInstanceInfo->vgpuCount, and \a pVgpuInstanceInfo->vgpuCount is used to return + * the number of vGPU instances written to the buffer. + * + * If the supplied buffer is not large enough to accommodate the vGPU instance array, + * the function returns NVML_ERROR_INSUFFICIENT_SIZE, with the element count of + * nvmlVgpuInstance_t array required in \a pVgpuInstanceInfo->vgpuCount. To query the + * number of active vGPU instances, call this function with pVgpuInstanceInfo->vgpuCount = 0 + * and pVgpuInstanceInfo->vgpuTypeIds = NULL. The code will return NVML_ERROR_INSUFFICIENT_SIZE, + * or NVML_SUCCESS if no vGPU Types are active. + * + * @param gpuInstance The GPU instance handle + * @param pVgpuInstanceInfo Pointer to the vGPU instance information structure \a nvmlActiveVgpuInstanceInfo_t + * + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pVgpuInstanceInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a pVgpuInstanceInfo->vgpuTypeIds buffer is too small, + * array element count is returned in \a pVgpuInstanceInfo->vgpuCount + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pVgpuInstanceInfo is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetActiveVgpus(nvmlGpuInstance_t gpuInstance, nvmlActiveVgpuInstanceInfo_t *pVgpuInstanceInfo); + +/** + * Set vGPU scheduler state for the given GPU instance + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * Scheduler state and params will be allowed to set only when no VM is running within the GPU instance. + * In \a nvmlVgpuSchedulerState_t, IFF enableARRMode is enabled then provide the avgFactor and frequency + * as input. If enableARRMode is disabled then provide timeslice as input. + * + * The scheduler state change won't persist across module load/unload and GPU Instance creation/deletion. + * + * @param gpuInstance The GPU instance handle + * @param pScheduler Pointer to the caller-provided structure of nvmlVgpuSchedulerState_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pScheduler is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_RESET_REQUIRED If setting the state failed with fatal error, reboot is required + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or if any vGPU instance exists + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pScheduler is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceSetVgpuSchedulerState(nvmlGpuInstance_t gpuInstance, nvmlVgpuSchedulerState_t *pScheduler); + +/** + * Returns the vGPU scheduler state for the given GPU instance. + * The information returned in \a nvmlVgpuSchedulerStateInfo_t is not relevant if the BEST EFFORT policy is set. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * @param gpuInstance The GPU instance handle + * @param pSchedulerStateInfo Reference in which \a pSchedulerStateInfo is returned + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler state is successfully obtained + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pSchedulerStateInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pSchedulerStateInfo is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuSchedulerState(nvmlGpuInstance_t gpuInstance, nvmlVgpuSchedulerStateInfo_t *pSchedulerStateInfo); + +/** + * Returns the vGPU scheduler logs for the given GPU instance. + * \a pSchedulerLogInfo points to a caller-allocated structure to contain the logs. The number of elements returned will + * never exceed \a NVML_SCHEDULER_SW_MAX_LOG_ENTRIES. + * + * To get the entire logs, call the function atleast 5 times a second. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * @param gpuInstance The GPU instance handle + * @param pSchedulerLogInfo Reference in which \a pSchedulerLogInfo is written + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler logs are successfully obtained + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pSchedulerLogInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pSchedulerLogInfo is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuSchedulerLog(nvmlGpuInstance_t gpuInstance, nvmlVgpuSchedulerLogInfo_t *pSchedulerLogInfo); + +/** + * Query the creatable vGPU placement ID of the vGPU type within a GPU instance. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * An array of creatable vGPU placement IDs for the vGPU type ID indicated by \a pCreatablePlacementInfo->vgpuTypeId + * is returned in the caller-supplied buffer of \a pCreatablePlacementInfo->placementIds. Memory needed for the + * placementIds array should be allocated based on maximum instances of a vGPU type per GPU instance which can be + * queried via \ref nvmlVgpuTypeGetMaxInstancesPerGpuInstance(). + * If the provided count by the caller is insufficient, the function will return NVML_ERROR_INSUFFICIENT_SIZE along with + * the number of required entries in \a pCreatablePlacementInfo->count. The caller should then reallocate a buffer with the size + * of pCreatablePlacementInfo->count * sizeof(pCreatablePlacementInfo->placementIds) and invoke the function again. + * The creatable vGPU placement IDs may differ over time, as there may be restrictions on what type of vGPU the + * vGPU instance is running. + * + * @param gpuInstance The GPU instance handle + * @param pCreatablePlacementInfo Pointer to the list of vGPU creatable placement structure \a nvmlVgpuCreatablePlacementInfo_t + * + * @return + * - \ref NVML_SUCCESS Successful completion + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pCreatablePlacementInfo is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If the buffer is small, element count is returned in \a pCreatablePlacementInfo->count + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pCreatablePlacementInfo is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or vGPU heterogeneous mode is not enabled + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuTypeCreatablePlacements(nvmlGpuInstance_t gpuInstance, nvmlVgpuCreatablePlacementInfo_t *pCreatablePlacementInfo); + +/** + * Get the vGPU heterogeneous mode for the GPU instance. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * On successful return, the function returns \a pHeterogeneousMode->mode with the current vGPU heterogeneous mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to retrieve the vGPU heterogeneous mode. + * \a pHeterogeneousMode->mode can either be \ref NVML_FEATURE_ENABLED or \ref NVML_FEATURE_DISABLED. + * + * For Blackwell &tm GB20x; or newer fully supported devices. + * + * @param gpuInstance The GPU instance handle + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, or \a pHeterogeneousMode is NULL + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU or not in MIG mode + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetVgpuHeterogeneousMode(nvmlGpuInstance_t gpuInstance, nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** + * Enable or disable vGPU heterogeneous mode for the GPU instance. + * + * When in heterogeneous mode, a vGPU can concurrently host timesliced vGPUs with differing framebuffer sizes. + * + * API would return an appropriate error code upon unsuccessful activation. For example, the heterogeneous mode + * set will fail with error \ref NVML_ERROR_IN_USE if any vGPU instance is active within the GPU instance. + * The caller of this API is expected to shutdown the vGPU VMs and retry setting the \a mode. + * On successful return, the function updates the vGPU heterogeneous mode with the user provided \a pHeterogeneousMode->mode. + * \a pHeterogeneousMode->version is the version number of the structure nvmlVgpuHeterogeneousMode_t, the caller should + * set the correct version number to set the vGPU heterogeneous mode. + * + * @param gpuInstance The GPU instance handle + * @param pHeterogeneousMode Pointer to the caller-provided structure of nvmlVgpuHeterogeneousMode_t + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is NULL or invalid, + * or \a pHeterogeneousMode is NULL or \a pHeterogeneousMode->mode is invalid + * or GPU Instance Id is invalid + * - \ref NVML_ERROR_IN_USE If the \a gpuInstance is in use + * - \ref NVML_ERROR_NOT_SUPPORTED If not on a vGPU host or an unsupported GPU + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a pHeterogeneousMode is invalid + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceSetVgpuHeterogeneousMode(nvmlGpuInstance_t gpuInstance, const nvmlVgpuHeterogeneousMode_t *pHeterogeneousMode); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlVgpuMigration vGPU Migration + * This chapter describes operations that are associated with vGPU Migration. + * @{ + */ +/***************************************************************************************************/ + +/** + * Structure representing range of vGPU versions. + */ +typedef struct nvmlVgpuVersion_st +{ + unsigned int minVersion; //!< Minimum vGPU version. + unsigned int maxVersion; //!< Maximum vGPU version. +} nvmlVgpuVersion_t; + +/** + * vGPU metadata structure. + */ +typedef struct nvmlVgpuMetadata_st +{ + unsigned int version; //!< Current version of the structure + unsigned int revision; //!< Current revision of the structure + nvmlVgpuGuestInfoState_t guestInfoState; //!< Current state of Guest-dependent fields + char guestDriverVersion[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< Version of driver installed in guest + char hostDriverVersion[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< Version of driver installed in host + unsigned int reserved[6]; //!< Reserved for internal use + unsigned int vgpuVirtualizationCaps; //!< vGPU virtualization capabilities bitfield + unsigned int guestVgpuVersion; //!< vGPU version of guest driver + unsigned int opaqueDataSize; //!< Size of opaque data field in bytes + char opaqueData[4]; //!< Opaque data +} nvmlVgpuMetadata_t; + +/** + * Physical GPU metadata structure + */ +typedef struct nvmlVgpuPgpuMetadata_st +{ + unsigned int version; //!< Current version of the structure + unsigned int revision; //!< Current revision of the structure + char hostDriverVersion[NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE]; //!< Host driver version + unsigned int pgpuVirtualizationCaps; //!< Pgpu virtualization capabilities bitfield + unsigned int reserved[5]; //!< Reserved for internal use + nvmlVgpuVersion_t hostSupportedVgpuRange; //!< vGPU version range supported by host driver + unsigned int opaqueDataSize; //!< Size of opaque data field in bytes + char opaqueData[4]; //!< Opaque data +} nvmlVgpuPgpuMetadata_t; + +/** + * vGPU VM compatibility codes + */ +typedef enum nvmlVgpuVmCompatibility_enum +{ + NVML_VGPU_VM_COMPATIBILITY_NONE = 0x0, //!< vGPU is not runnable + NVML_VGPU_VM_COMPATIBILITY_COLD = 0x1, //!< vGPU is runnable from a cold / powered-off state (ACPI S5) + NVML_VGPU_VM_COMPATIBILITY_HIBERNATE = 0x2, //!< vGPU is runnable from a hibernated state (ACPI S4) + NVML_VGPU_VM_COMPATIBILITY_SLEEP = 0x4, //!< vGPU is runnable from a sleeped state (ACPI S3) + NVML_VGPU_VM_COMPATIBILITY_LIVE = 0x8 //!< vGPU is runnable from a live/paused (ACPI S0) +} nvmlVgpuVmCompatibility_t; + +/** + * vGPU-pGPU compatibility limit codes + */ +typedef enum nvmlVgpuPgpuCompatibilityLimitCode_enum +{ + NVML_VGPU_COMPATIBILITY_LIMIT_NONE = 0x0, //!< Compatibility is not limited. + NVML_VGPU_COMPATIBILITY_LIMIT_HOST_DRIVER = 0x1, //!< ompatibility is limited by host driver version. + NVML_VGPU_COMPATIBILITY_LIMIT_GUEST_DRIVER = 0x2, //!< Compatibility is limited by guest driver version. + NVML_VGPU_COMPATIBILITY_LIMIT_GPU = 0x4, //!< Compatibility is limited by GPU hardware. + NVML_VGPU_COMPATIBILITY_LIMIT_OTHER = 0x80000000 //!< Compatibility is limited by an undefined factor. +} nvmlVgpuPgpuCompatibilityLimitCode_t; + +/** + * vGPU-pGPU compatibility structure + */ +typedef struct nvmlVgpuPgpuCompatibility_st +{ + nvmlVgpuVmCompatibility_t vgpuVmCompatibility; //!< Compatibility of vGPU VM. See \ref nvmlVgpuVmCompatibility_t + nvmlVgpuPgpuCompatibilityLimitCode_t compatibilityLimitCode; //!< Limiting factor for vGPU-pGPU compatibility. See \ref nvmlVgpuPgpuCompatibilityLimitCode_t +} nvmlVgpuPgpuCompatibility_t; + +/** + * Returns vGPU metadata structure for a running vGPU. The structure contains information about the vGPU and its associated VM + * such as the currently installed NVIDIA guest driver version, together with host driver version and an opaque data section + * containing internal state. + * + * nvmlVgpuInstanceGetMetadata() may be called at any time for a vGPU instance. Some fields in the returned structure are + * dependent on information obtained from the guest VM, which may not yet have reached a state where that information + * is available. The current state of these dependent fields is reflected in the info structure's \ref nvmlVgpuGuestInfoState_t field. + * + * The VMM may choose to read and save the vGPU's VM info as persistent metadata associated with the VM, and provide + * it to Virtual GPU Manager when creating a vGPU for subsequent instances of the VM. + * + * The caller passes in a buffer via \a vgpuMetadata, with the size of the buffer in \a bufferSize. If the vGPU Metadata structure + * is too large to fit in the supplied buffer, the function returns NVML_ERROR_INSUFFICIENT_SIZE with the size needed + * in \a bufferSize. + * + * @param vgpuInstance vGPU instance handle + * @param vgpuMetadata Pointer to caller-supplied buffer into which vGPU metadata is written + * @param bufferSize Size of vgpuMetadata buffer + * + * @return + * - \ref NVML_SUCCESS vGPU metadata structure was successfully returned + * - \ref NVML_ERROR_INSUFFICIENT_SIZE vgpuMetadata buffer is too small, required size is returned in \a bufferSize + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a bufferSize is NULL or \a vgpuInstance is 0; if \a vgpuMetadata is NULL and the value of \a bufferSize is not 0. + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetMetadata(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuMetadata_t *vgpuMetadata, unsigned int *bufferSize); + +/** + * Returns a vGPU metadata structure for the physical GPU indicated by \a device. The structure contains information about + * the GPU and the currently installed NVIDIA host driver version that's controlling it, together with an opaque data section + * containing internal state. + * + * The caller passes in a buffer via \a pgpuMetadata, with the size of the buffer in \a bufferSize. If the \a pgpuMetadata + * structure is too large to fit in the supplied buffer, the function returns NVML_ERROR_INSUFFICIENT_SIZE with the size needed + * in \a bufferSize. + * + * @param device The identifier of the target device + * @param pgpuMetadata Pointer to caller-supplied buffer into which \a pgpuMetadata is written + * @param bufferSize Pointer to size of \a pgpuMetadata buffer + * + * @return + * - \ref NVML_SUCCESS GPU metadata structure was successfully returned + * - \ref NVML_ERROR_INSUFFICIENT_SIZE pgpuMetadata buffer is too small, required size is returned in \a bufferSize + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a bufferSize is NULL or \a device is invalid; if \a pgpuMetadata is NULL and the value of \a bufferSize is not 0. + * - \ref NVML_ERROR_NOT_SUPPORTED vGPU is not supported by the system + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuMetadata(nvmlDevice_t device, nvmlVgpuPgpuMetadata_t *pgpuMetadata, unsigned int *bufferSize); + +/** + * Takes a vGPU instance metadata structure read from \ref nvmlVgpuInstanceGetMetadata(), and a vGPU metadata structure for a + * physical GPU read from \ref nvmlDeviceGetVgpuMetadata(), and returns compatibility information of the vGPU instance and the + * physical GPU. + * + * The caller passes in a buffer via \a compatibilityInfo, into which a compatibility information structure is written. The + * structure defines the states in which the vGPU / VM may be booted on the physical GPU. If the vGPU / VM compatibility + * with the physical GPU is limited, a limit code indicates the factor limiting compatability. + * (see \ref nvmlVgpuPgpuCompatibilityLimitCode_t for details). + * + * Note: vGPU compatibility does not take into account dynamic capacity conditions that may limit a system's ability to + * boot a given vGPU or associated VM. + * + * @param vgpuMetadata Pointer to caller-supplied vGPU metadata structure + * @param pgpuMetadata Pointer to caller-supplied GPU metadata structure + * @param compatibilityInfo Pointer to caller-supplied buffer to hold compatibility info + * + * @return + * - \ref NVML_SUCCESS vGPU metadata structure was successfully returned + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a vgpuMetadata or \a pgpuMetadata or \a bufferSize are NULL + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlGetVgpuCompatibility(nvmlVgpuMetadata_t *vgpuMetadata, nvmlVgpuPgpuMetadata_t *pgpuMetadata, nvmlVgpuPgpuCompatibility_t *compatibilityInfo); + +/** + * Returns the properties of the physical GPU indicated by the device in an ascii-encoded string format. + * + * The caller passes in a buffer via \a pgpuMetadata, with the size of the buffer in \a bufferSize. If the + * string is too large to fit in the supplied buffer, the function returns NVML_ERROR_INSUFFICIENT_SIZE with the size needed + * in \a bufferSize. + * + * @param device The identifier of the target device + * @param pgpuMetadata Pointer to caller-supplied buffer into which \a pgpuMetadata is written + * @param bufferSize Pointer to size of \a pgpuMetadata buffer + * + * @return + * - \ref NVML_SUCCESS GPU metadata structure was successfully returned + * - \ref NVML_ERROR_INSUFFICIENT_SIZE \a pgpuMetadata buffer is too small, required size is returned in \a bufferSize + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a bufferSize is NULL or \a device is invalid; if \a pgpuMetadata is NULL and the value of \a bufferSize is not 0. + * - \ref NVML_ERROR_NOT_SUPPORTED If vGPU is not supported by the system + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetPgpuMetadataString(nvmlDevice_t device, char *pgpuMetadata, unsigned int *bufferSize); + +/** + * Returns the vGPU Software scheduler logs. + * \a pSchedulerLog points to a caller-allocated structure to contain the logs. The number of elements returned will + * never exceed \a NVML_SCHEDULER_SW_MAX_LOG_ENTRIES. + * + * To get the entire logs, call the function atleast 5 times a second. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target \a device + * @param pSchedulerLog Reference in which \a pSchedulerLog is written + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler logs were successfully obtained + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pSchedulerLog is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device not in vGPU host mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerLog(nvmlDevice_t device, nvmlVgpuSchedulerLog_t *pSchedulerLog); + +/** + * Returns the vGPU scheduler state. + * The information returned in \a nvmlVgpuSchedulerGetState_t is not relevant if the BEST EFFORT policy is set. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target \a device + * @param pSchedulerState Reference in which \a pSchedulerState is returned + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler state is successfully obtained + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pSchedulerState is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device not in vGPU host mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerState(nvmlDevice_t device, nvmlVgpuSchedulerGetState_t *pSchedulerState); + +/** + * Returns the vGPU scheduler capabilities. + * The list of supported vGPU schedulers returned in \a nvmlVgpuSchedulerCapabilities_t is from + * the NVML_VGPU_SCHEDULER_POLICY_*. This list enumerates the supported scheduler policies + * if the engine is Graphics type. + * The other values in \a nvmlVgpuSchedulerCapabilities_t are also applicable if the engine is + * Graphics type. For other engine types, it is BEST EFFORT policy. + * If ARR is supported and enabled, scheduling frequency and averaging factor are applicable + * else timeSlice is applicable. + * + * For Pascal &tm; or newer fully supported devices. + * + * @param device The identifier of the target \a device + * @param pCapabilities Reference in which \a pCapabilities is written + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler capabilities were successfully obtained + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pCapabilities is NULL or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported in current state or \a device not in vGPU host mode + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerCapabilities(nvmlDevice_t device, nvmlVgpuSchedulerCapabilities_t *pCapabilities); + +/** + * Sets the vGPU scheduler state. + * + * For Pascal &tm; or newer fully supported devices. + * + * The scheduler state change won't persist across module load/unload. + * Scheduler state and params will be allowed to set only when no VM is running. + * In \a nvmlVgpuSchedulerSetState_t, IFF enableARRMode is enabled then + * provide avgFactorForARR and frequency as input. If enableARRMode is disabled + * then provide timeslice as input. + * + * @param device The identifier of the target \a device + * @param pSchedulerState vGPU \a pSchedulerState to set + * + * @return + * - \ref NVML_SUCCESS vGPU scheduler state has been successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a pSchedulerState is NULL or \a device is invalid + * - \ref NVML_ERROR_RESET_REQUIRED If setting \a pSchedulerState failed with fatal error, + * reboot is required to overcome from this error. + * - \ref NVML_ERROR_NOT_SUPPORTED If MIG is enabled or \a device not in vGPU host mode + * or if any vGPU instance currently exists on the \a device + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceSetVgpuSchedulerState(nvmlDevice_t device, nvmlVgpuSchedulerSetState_t *pSchedulerState); + +/* + * Virtual GPU (vGPU) version + * + * The NVIDIA vGPU Manager and the guest drivers are tagged with a range of supported vGPU versions. This determines the range of NVIDIA guest driver versions that + * are compatible for vGPU feature support with a given NVIDIA vGPU Manager. For vGPU feature support, the range of supported versions for the NVIDIA vGPU Manager + * and the guest driver must overlap. Otherwise, the guest driver fails to load in the VM. + * + * When the NVIDIA guest driver loads, either when the VM is booted or when the driver is installed or upgraded, a negotiation occurs between the guest driver + * and the NVIDIA vGPU Manager to select the highest mutually compatible vGPU version. The negotiated vGPU version stays the same across VM migration. + */ + +/** + * Query the ranges of supported vGPU versions. + * + * This function gets the linear range of supported vGPU versions that is preset for the NVIDIA vGPU Manager and the range set by an administrator. + * If the preset range has not been overridden by \ref nvmlSetVgpuVersion, both ranges are the same. + * + * The caller passes pointers to the following \ref nvmlVgpuVersion_t structures, into which the NVIDIA vGPU Manager writes the ranges: + * 1. \a supported structure that represents the preset range of vGPU versions supported by the NVIDIA vGPU Manager. + * 2. \a current structure that represents the range of supported vGPU versions set by an administrator. By default, this range is the same as the preset range. + * + * @param supported Pointer to the structure in which the preset range of vGPU versions supported by the NVIDIA vGPU Manager is written + * @param current Pointer to the structure in which the range of supported vGPU versions set by an administrator is written + * + * @return + * - \ref NVML_SUCCESS The vGPU version range structures were successfully obtained. + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported. + * - \ref NVML_ERROR_INVALID_ARGUMENT The \a supported parameter or the \a current parameter is NULL. + * - \ref NVML_ERROR_UNKNOWN An error occurred while the data was being fetched. + */ +nvmlReturn_t DECLDIR nvmlGetVgpuVersion(nvmlVgpuVersion_t *supported, nvmlVgpuVersion_t *current); + +/** + * Override the preset range of vGPU versions supported by the NVIDIA vGPU Manager with a range set by an administrator. + * + * This function configures the NVIDIA vGPU Manager with a range of supported vGPU versions set by an administrator. This range must be a subset of the + * preset range that the NVIDIA vGPU Manager supports. The custom range set by an administrator takes precedence over the preset range and is advertised to + * the guest VM for negotiating the vGPU version. See \ref nvmlGetVgpuVersion for details of how to query the preset range of versions supported. + * + * This function takes a pointer to vGPU version range structure \ref nvmlVgpuVersion_t as input to override the preset vGPU version range that the NVIDIA vGPU Manager supports. + * + * After host system reboot or driver reload, the range of supported versions reverts to the range that is preset for the NVIDIA vGPU Manager. + * + * @note 1. The range set by the administrator must be a subset of the preset range that the NVIDIA vGPU Manager supports. Otherwise, an error is returned. + * 2. If the range of supported guest driver versions does not overlap the range set by the administrator, the guest driver fails to load. + * 3. If the range of supported guest driver versions overlaps the range set by the administrator, the guest driver will load with a negotiated + * vGPU version that is the maximum value in the overlapping range. + * 4. No VMs must be running on the host when this function is called. If a VM is running on the host, the call to this function fails. + * + * @param vgpuVersion Pointer to a caller-supplied range of supported vGPU versions. + * + * @return + * - \ref NVML_SUCCESS The preset range of supported vGPU versions was successfully overridden. + * - \ref NVML_ERROR_NOT_SUPPORTED The API is not supported. + * - \ref NVML_ERROR_IN_USE The range was not overridden because a VM is running on the host. + * - \ref NVML_ERROR_INVALID_ARGUMENT The \a vgpuVersion parameter specifies a range that is outside the range supported by the NVIDIA vGPU Manager or if \a vgpuVersion is NULL. + */ +nvmlReturn_t DECLDIR nvmlSetVgpuVersion(nvmlVgpuVersion_t *vgpuVersion); + +/** @} */ // @defgroup nvmlVgpuMigration vGPU Migration + +/***************************************************************************************************/ +/** @defgroup nvmlUtil vGPU Utilization and Accounting + * This chapter describes operations that are associated with vGPU Utilization and Accounting. + * @{ + */ +/***************************************************************************************************/ + +/** + * Retrieves current utilization for vGPUs on a physical GPU (device). + * + * For Kepler &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder for vGPU instances running + * on a device. Utilization values are returned as an array of utilization sample structures in the caller-supplied buffer + * pointed at by \a utilizationSamples. One utilization sample structure is returned per vGPU instance, and includes the + * CPU timestamp at which the samples were recorded. Individual utilization values are returned as "unsigned int" values + * in nvmlValue_t unions. The function sets the caller-supplied \a sampleValType to NVML_VALUE_TYPE_UNSIGNED_INT to + * indicate the returned value type. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a utilizationSamples set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current vGPU instance + * count in \a vgpuInstanceSamplesCount, or NVML_SUCCESS if the current vGPU instance count is zero. The caller should allocate + * a buffer of size vgpuInstanceSamplesCount * sizeof(nvmlVgpuInstanceUtilizationSample_t). Invoke the function again with + * the allocated buffer passed in \a utilizationSamples, and \a vgpuInstanceSamplesCount set to the number of entries the + * buffer is sized for. + * + * On successful return, the function updates \a vgpuInstanceSampleCount with the number of vGPU utilization sample + * structures that were actually written. This may differ from a previously read value as vGPU instances are created or + * destroyed. + * + * lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + * @param sampleValType Pointer to caller-supplied buffer to hold the type of returned sample values + * @param vgpuInstanceSamplesCount Pointer to caller-supplied array size, and returns number of vGPU instances + * @param utilizationSamples Pointer to caller-supplied buffer in which vGPU utilization samples are returned + + * @return + * - \ref NVML_SUCCESS if utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a vgpuInstanceSamplesCount or \a sampleValType is + * NULL, or a sample count of 0 is passed with a non-NULL \a utilizationSamples + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if supplied \a vgpuInstanceSamplesCount is too small to return samples for all + * vGPU instances currently executing on the device + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuUtilization(nvmlDevice_t device, unsigned long long lastSeenTimeStamp, + nvmlValueType_t *sampleValType, unsigned int *vgpuInstanceSamplesCount, + nvmlVgpuInstanceUtilizationSample_t *utilizationSamples); + +/** + * Retrieves recent utilization for vGPU instances running on a physical GPU (device). + * + * For Kepler &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, video decoder, jpeg decoder, and OFA for vGPU + * instances running on a device. Utilization values are returned as an array of utilization sample structures in the caller-supplied + * buffer pointed at by \a vgpuUtilInfo->vgpuUtilArray. One utilization sample structure is returned per vGPU instance, and includes the + * CPU timestamp at which the samples were recorded. Individual utilization values are returned as "unsigned int" values + * in nvmlValue_t unions. The function sets the caller-supplied \a vgpuUtilInfo->sampleValType to NVML_VALUE_TYPE_UNSIGNED_INT to + * indicate the returned value type. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a vgpuUtilInfo->vgpuUtilArray set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current vGPU instance + * count in \a vgpuUtilInfo->vgpuInstanceCount, or NVML_SUCCESS if the current vGPU instance count is zero. The caller should allocate + * a buffer of size vgpuUtilInfo->vgpuInstanceCount * sizeof(nvmlVgpuInstanceUtilizationInfo_t). Invoke the function again with + * the allocated buffer passed in \a vgpuUtilInfo->vgpuUtilArray, and \a vgpuUtilInfo->vgpuInstanceCount set to the number of entries the + * buffer is sized for. + * + * On successful return, the function updates \a vgpuUtilInfo->vgpuInstanceCount with the number of vGPU utilization sample + * structures that were actually written. This may differ from a previously read value as vGPU instances are created or + * destroyed. + * + * \a vgpuUtilInfo->lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set \a vgpuUtilInfo->lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param vgpuUtilInfo Pointer to the caller-provided structure of nvmlVgpuInstancesUtilizationInfo_t + + * @return + * - \ref NVML_SUCCESS If utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, \a vgpuUtilInfo is NULL, or \a vgpuUtilInfo->vgpuInstanceCount is 0 + * - \ref NVML_ERROR_NOT_SUPPORTED If vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a vgpuUtilInfo is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a vgpuUtilInfo->vgpuUtilArray is NULL, or the buffer size of vgpuUtilInfo->vgpuInstanceCount is too small. + * The caller should check the current vGPU instance count from the returned vgpuUtilInfo->vgpuInstanceCount, and call + * the function again with a buffer of size vgpuUtilInfo->vgpuInstanceCount * sizeof(nvmlVgpuInstanceUtilizationInfo_t) + * - \ref NVML_ERROR_NOT_FOUND If sample entries are not found + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuInstancesUtilizationInfo(nvmlDevice_t device, + nvmlVgpuInstancesUtilizationInfo_t *vgpuUtilInfo); + +/** + * Retrieves current utilization for processes running on vGPUs on a physical GPU (device). + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, and video decoder for processes running on + * vGPU instances active on a device. Utilization values are returned as an array of utilization sample structures in the + * caller-supplied buffer pointed at by \a utilizationSamples. One utilization sample structure is returned per process running + * on vGPU instances, that had some non-zero utilization during the last sample period. It includes the CPU timestamp at which + * the samples were recorded. Individual utilization values are returned as "unsigned int" values. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a utilizationSamples set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current vGPU instance + * count in \a vgpuProcessSamplesCount. The caller should allocate a buffer of size + * vgpuProcessSamplesCount * sizeof(nvmlVgpuProcessUtilizationSample_t). Invoke the function again with + * the allocated buffer passed in \a utilizationSamples, and \a vgpuProcessSamplesCount set to the number of entries the + * buffer is sized for. + * + * On successful return, the function updates \a vgpuSubProcessSampleCount with the number of vGPU sub process utilization sample + * structures that were actually written. This may differ from a previously read value depending on the number of processes that are active + * in any given sample period. + * + * lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param lastSeenTimeStamp Return only samples with timestamp greater than lastSeenTimeStamp. + * @param vgpuProcessSamplesCount Pointer to caller-supplied array size, and returns number of processes running on vGPU instances + * @param utilizationSamples Pointer to caller-supplied buffer in which vGPU sub process utilization samples are returned + + * @return + * - \ref NVML_SUCCESS if utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a vgpuProcessSamplesCount or a sample count of 0 is + * passed with a non-NULL \a utilizationSamples + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if supplied \a vgpuProcessSamplesCount is too small to return samples for all + * vGPU instances currently executing on the device + * - \ref NVML_ERROR_NOT_SUPPORTED if vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND if sample entries are not found + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuProcessUtilization(nvmlDevice_t device, unsigned long long lastSeenTimeStamp, + unsigned int *vgpuProcessSamplesCount, + nvmlVgpuProcessUtilizationSample_t *utilizationSamples); + +/** + * Retrieves recent utilization for processes running on vGPU instances on a physical GPU (device). + * + * For Maxwell &tm; or newer fully supported devices. + * + * Reads recent utilization of GPU SM (3D/Compute), framebuffer, video encoder, video decoder, jpeg decoder, and OFA for processes running + * on vGPU instances active on a device. Utilization values are returned as an array of utilization sample structures in the caller-supplied + * buffer pointed at by \a vgpuProcUtilInfo->vgpuProcUtilArray. One utilization sample structure is returned per process running + * on vGPU instances, that had some non-zero utilization during the last sample period. It includes the CPU timestamp at which + * the samples were recorded. Individual utilization values are returned as "unsigned int" values. + * + * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with + * \a vgpuProcUtilInfo->vgpuProcUtilArray set to NULL. The function will return NVML_ERROR_INSUFFICIENT_SIZE, with the current processes' count + * running on vGPU instances in \a vgpuProcUtilInfo->vgpuProcessCount. The caller should allocate a buffer of size + * vgpuProcUtilInfo->vgpuProcessCount * sizeof(nvmlVgpuProcessUtilizationSample_t). Invoke the function again with the allocated buffer passed + * in \a vgpuProcUtilInfo->vgpuProcUtilArray, and \a vgpuProcUtilInfo->vgpuProcessCount set to the number of entries the buffer is sized for. + * + * On successful return, the function updates \a vgpuProcUtilInfo->vgpuProcessCount with the number of vGPU sub process utilization sample + * structures that were actually written. This may differ from a previously read value depending on the number of processes that are active + * in any given sample period. + * + * vgpuProcUtilInfo->lastSeenTimeStamp represents the CPU timestamp in microseconds at which utilization samples were last read. Set it to 0 + * to read utilization based on all the samples maintained by the driver's internal sample buffer. Set vgpuProcUtilInfo->lastSeenTimeStamp + * to a timeStamp retrieved from a previous query to read utilization since the previous query. + * + * @param device The identifier for the target device + * @param vgpuProcUtilInfo Pointer to the caller-provided structure of nvmlVgpuProcessesUtilizationInfo_t + + * @return + * - \ref NVML_SUCCESS If utilization samples are successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid, or \a vgpuProcUtilInfo is null + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the version of \a vgpuProcUtilInfo is invalid + * - \ref NVML_ERROR_INSUFFICIENT_SIZE If \a vgpuProcUtilInfo->vgpuProcUtilArray is null, or supplied \a vgpuProcUtilInfo->vgpuProcessCount + * is too small to return samples for all processes on vGPU instances currently executing on the device. + * The caller should check the current processes count from the returned \a vgpuProcUtilInfo->vgpuProcessCount, + * and call the function again with a buffer of size + * vgpuProcUtilInfo->vgpuProcessCount * sizeof(nvmlVgpuProcessUtilizationSample_t) + * - \ref NVML_ERROR_NOT_SUPPORTED If vGPU is not supported by the device + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_NOT_FOUND If sample entries are not found + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetVgpuProcessesUtilizationInfo(nvmlDevice_t device, nvmlVgpuProcessesUtilizationInfo_t *vgpuProcUtilInfo); + +/** + * Queries the state of per process accounting mode on vGPU. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param mode Reference in which to return the current accounting mode + * + * @return + * - \ref NVML_SUCCESS if the mode has been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a mode is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running on the vGPU instance + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetAccountingMode(nvmlVgpuInstance_t vgpuInstance, nvmlEnableState_t *mode); + +/** + * Queries list of processes running on vGPU that can be queried for accounting stats. The list of processes + * returned can be in running or terminated state. + * + * For Maxwell &tm; or newer fully supported devices. + * + * To just query the maximum number of processes that can be queried, call this function with *count = 0 and + * pids=NULL. The return code will be NVML_ERROR_INSUFFICIENT_SIZE, or NVML_SUCCESS if list is empty. + * + * For more details see \ref nvmlVgpuInstanceGetAccountingStats. + * + * @note In case of PID collision some processes might not be accessible before the circular buffer is full. + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param count Reference in which to provide the \a pids array size, and + * to return the number of elements ready to be queried + * @param pids Reference in which to return list of process ids + * + * @return + * - \ref NVML_SUCCESS if pids were successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a count is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a count is too small (\a count is set to expected value) + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + * + * @see nvmlVgpuInstanceGetAccountingPids + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetAccountingPids(nvmlVgpuInstance_t vgpuInstance, unsigned int *count, unsigned int *pids); + +/** + * Queries process's accounting stats. + * + * For Maxwell &tm; or newer fully supported devices. + * + * Accounting stats capture GPU utilization and other statistics across the lifetime of a process, and + * can be queried during life time of the process or after its termination. + * The time field in \ref nvmlAccountingStats_t is reported as 0 during the lifetime of the process and + * updated to actual running time after its termination. + * Accounting stats are kept in a circular buffer, newly created processes overwrite information about old + * processes. + * + * See \ref nvmlAccountingStats_t for description of each returned metric. + * List of processes that can be queried can be retrieved from \ref nvmlVgpuInstanceGetAccountingPids. + * + * @note Accounting Mode needs to be on. See \ref nvmlVgpuInstanceGetAccountingMode. + * @note Only compute and graphics applications stats can be queried. Monitoring applications stats can't be + * queried since they don't contribute to GPU utilization. + * @note In case of pid collision stats of only the latest process (that terminated last) will be reported + * + * @param vgpuInstance The identifier of the target vGPU instance + * @param pid Process Id of the target process to query stats for + * @param stats Reference in which to return the process's accounting stats + * + * @return + * - \ref NVML_SUCCESS if stats have been successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a stats is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * or \a stats is not found + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetAccountingStats(nvmlVgpuInstance_t vgpuInstance, unsigned int pid, nvmlAccountingStats_t *stats); + +/** + * Clears accounting information of the vGPU instance that have already terminated. + * + * For Maxwell &tm; or newer fully supported devices. + * Requires root/admin permissions. + * + * @note Accounting Mode needs to be on. See \ref nvmlVgpuInstanceGetAccountingMode. + * @note Only compute and graphics applications stats are reported and can be cleared since monitoring applications + * stats don't contribute to GPU utilization. + * + * @param vgpuInstance The identifier of the target vGPU instance + * + * @return + * - \ref NVML_SUCCESS if accounting information has been cleared + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is invalid + * - \ref NVML_ERROR_NO_PERMISSION if the user doesn't have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if the vGPU doesn't support this feature or accounting mode is disabled + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceClearAccountingPids(nvmlVgpuInstance_t vgpuInstance); + +/** + * Query the license information of the vGPU instance. + * + * For Maxwell &tm; or newer fully supported devices. + * + * @param vgpuInstance Identifier of the target vGPU instance + * @param licenseInfo Pointer to vGPU license information structure + * + * @return + * - \ref NVML_SUCCESS if information is successfully retrieved + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a vgpuInstance is 0, or \a licenseInfo is NULL + * - \ref NVML_ERROR_NOT_FOUND if \a vgpuInstance does not match a valid active vGPU instance on the system + * - \ref NVML_ERROR_DRIVER_NOT_LOADED if NVIDIA driver is not running on the vGPU instance + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseInfo_v2(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuLicenseInfo_t *licenseInfo); +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlExcludedGpuQueries Excluded GPU Queries + * This chapter describes NVML operations that are associated with excluded GPUs. + * @{ + */ +/***************************************************************************************************/ + +/** + * Excluded GPU device information + **/ +typedef struct nvmlExcludedDeviceInfo_st +{ + nvmlPciInfo_t pciInfo; //!< The PCI information for the excluded GPU + char uuid[NVML_DEVICE_UUID_BUFFER_SIZE]; //!< The ASCII string UUID for the excluded GPU +} nvmlExcludedDeviceInfo_t; + + /** + * Retrieves the number of excluded GPU devices in the system. + * + * For all products. + * + * @param deviceCount Reference in which to return the number of excluded devices + * + * @return + * - \ref NVML_SUCCESS if \a deviceCount has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a deviceCount is NULL + */ +nvmlReturn_t DECLDIR nvmlGetExcludedDeviceCount(unsigned int *deviceCount); + +/** + * Acquire the device information for an excluded GPU device, based on its index. + * + * For all products. + * + * Valid indices are derived from the \a deviceCount returned by + * \ref nvmlGetExcludedDeviceCount(). For example, if \a deviceCount is 2 the valid indices + * are 0 and 1, corresponding to GPU 0 and GPU 1. + * + * @param index The index of the target GPU, >= 0 and < \a deviceCount + * @param info Reference in which to return the device information + * + * @return + * - \ref NVML_SUCCESS if \a device has been set + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a index is invalid or \a info is NULL + * + * @see nvmlGetExcludedDeviceCount + */ +nvmlReturn_t DECLDIR nvmlGetExcludedDeviceInfoByIndex(unsigned int index, nvmlExcludedDeviceInfo_t *info); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlGPUPRMAccess PRM Access + * This chapter describes NVML operations that are associated with PRM register reads + * @{ + */ +/***************************************************************************************************/ + +#define NVML_PRM_DATA_MAX_SIZE 496 +/** + * Main PRM input structure + */ +typedef struct +{ + /* I/O parameters */ + unsigned dataSize; //!< Size of the input TLV data. + unsigned status; //!< OUT: status of the PRM command + union { + /* Input data in TLV format */ + unsigned char inData[NVML_PRM_DATA_MAX_SIZE]; //!< IN: Input data in TLV format + /* Output data in TLV format */ + unsigned char outData[NVML_PRM_DATA_MAX_SIZE]; //!< OUT: Output PRM data in TLV format + }; +} nvmlPRMTLV_v1_t; + +/** + * Read or write a GPU PRM register. The input is assumed to be in TLV format in + * network byte order. + * + * For Blackwell &tm; or newer fully supported devices. + * + * Supported on Linux only. + * + * @param device Identifer of target GPU device + * @param buffer Structure holding the input data in TLV format as well as + * the PRM register contents in TLV format (in the case of a successful + * read operation). + * Note: the input data and any returned data shall be in network byte order. + * + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if \p device or \p buffer are invalid + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to perform this operation + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the version specified in \p buffer is not supported + */ +nvmlReturn_t DECLDIR nvmlDeviceReadWritePRM_v1(nvmlDevice_t device, nvmlPRMTLV_v1_t *buffer); + +/** @} */ + +/***************************************************************************************************/ +/** @defgroup nvmlMultiInstanceGPU Multi Instance GPU Management + * This chapter describes NVML operations that are associated with Multi Instance GPU management. + * @{ + */ +/***************************************************************************************************/ + +/** + * Disable Multi Instance GPU mode. + */ +#define NVML_DEVICE_MIG_DISABLE 0x0 + +/** + * Enable Multi Instance GPU mode. + */ +#define NVML_DEVICE_MIG_ENABLE 0x1 + +/** + * GPU instance profiles. + * + * These macros should be passed to \ref nvmlDeviceGetGpuInstanceProfileInfo to retrieve the + * detailed information about a GPU instance such as profile ID, engine counts. + */ +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE 0x0 +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE 0x1 +#define NVML_GPU_INSTANCE_PROFILE_3_SLICE 0x2 +#define NVML_GPU_INSTANCE_PROFILE_4_SLICE 0x3 +#define NVML_GPU_INSTANCE_PROFILE_7_SLICE 0x4 +#define NVML_GPU_INSTANCE_PROFILE_8_SLICE 0x5 +#define NVML_GPU_INSTANCE_PROFILE_6_SLICE 0x6 +// 1_SLICE profile with at least one (if supported at all) of Decoder, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV1 0x7 +// 2_SLICE profile with at least one (if supported at all) of Decoder, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_REV1 0x8 +// 1_SLICE profile with twice the amount of memory resources. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_REV2 0x9 +// 1_SLICE gfx capable profile +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_GFX 0x0A +// 2_SLICE gfx capable profile +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_GFX 0x0B +// 4_SLICE gfx capable profile +#define NVML_GPU_INSTANCE_PROFILE_4_SLICE_GFX 0x0C +// 1_SLICE profile with none of Decode, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_NO_ME 0x0D +// 2_SLICE profile with none of Decode, Encoder, JPEG, OFA engines. +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_NO_ME 0x0E +// 1_SLICE profile with all of GPU Decode, Encoder, JPEG, OFA engines. +// Allocation of instance of this profile prevents allocation of +// all but _NO_ME profiles. +#define NVML_GPU_INSTANCE_PROFILE_1_SLICE_ALL_ME 0x0F +// 2_SLICE profile with all of GPU Decode, Encoder, JPEG, OFA engines. +// Allocation of instance of this profile prevents allocation of +// all but _NO_ME profiles. +#define NVML_GPU_INSTANCE_PROFILE_2_SLICE_ALL_ME 0x10 +#define NVML_GPU_INSTANCE_PROFILE_COUNT 0x11 + +/** + * MIG GPU instance profile capability. + * + * Bit field values representing MIG profile capabilities + * \ref nvmlGpuInstanceProfileInfo_v3_t.capabilities + */ +#define NVML_GPU_INSTANCE_PROFILE_CAPS_P2P 0x1 +#define NVML_GPU_INTSTANCE_PROFILE_CAPS_P2P 0x1 //!< Deprecated, do not use +#define NVML_GPU_INSTANCE_PROFILE_CAPS_GFX 0x2 + +/** + * MIG compute instance profile capability. + * + * Bit field values representing MIG profile capabilities + * \ref nvmlComputeInstanceProfileInfo_v3_t.capabilities + */ +#define NVML_COMPUTE_INSTANCE_PROFILE_CAPS_GFX 0x1 + +typedef struct nvmlGpuInstancePlacement_st +{ + unsigned int start; //!< Index of first occupied memory slice + unsigned int size; //!< Number of memory slices occupied +} nvmlGpuInstancePlacement_t; + +/** + * GPU instance profile information. + */ +typedef struct nvmlGpuInstanceProfileInfo_st +{ + unsigned int id; //!< Unique profile ID within the device + unsigned int isP2pSupported; //!< Peer-to-Peer support + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< GPU instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int copyEngineCount; //!< Copy Engine count + unsigned int decoderCount; //!< Decoder Engine count + unsigned int encoderCount; //!< Encoder Engine count + unsigned int jpegCount; //!< JPEG Engine count + unsigned int ofaCount; //!< OFA Engine count + unsigned long long memorySizeMB; //!< Memory size in MBytes +} nvmlGpuInstanceProfileInfo_t; + +/** + * GPU instance profile information (v2). + * + * Version 2 adds the \ref nvmlGpuInstanceProfileInfo_v2_t.version field + * to the start of the structure, and the \ref nvmlGpuInstanceProfileInfo_v2_t.name + * field to the end. This structure is not backwards-compatible with + * \ref nvmlGpuInstanceProfileInfo_t. + */ +typedef struct nvmlGpuInstanceProfileInfo_v2_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlGpuInstanceProfileInfo_v2) + unsigned int id; //!< Unique profile ID within the device + unsigned int isP2pSupported; //!< Peer-to-Peer support + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< GPU instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int copyEngineCount; //!< Copy Engine count + unsigned int decoderCount; //!< Decoder Engine count + unsigned int encoderCount; //!< Encoder Engine count + unsigned int jpegCount; //!< JPEG Engine count + unsigned int ofaCount; //!< OFA Engine count + unsigned long long memorySizeMB; //!< Memory size in MBytes + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name +} nvmlGpuInstanceProfileInfo_v2_t; + +/** + * Version identifier value for \ref nvmlGpuInstanceProfileInfo_v2_t.version. + */ +#define nvmlGpuInstanceProfileInfo_v2 NVML_STRUCT_VERSION(GpuInstanceProfileInfo, 2) + +/** + * GPU instance profile information (v3). + * + * Version 3 removes isP2pSupported field and adds the \ref nvmlGpuInstanceProfileInfo_v3_t.capabilities + * field \ref nvmlGpuInstanceProfileInfo_t. + */ +typedef struct nvmlGpuInstanceProfileInfo_v3_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlGpuInstanceProfileInfo_v3) + unsigned int id; //!< Unique profile ID within the device + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< GPU instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int copyEngineCount; //!< Copy Engine count + unsigned int decoderCount; //!< Decoder Engine count + unsigned int encoderCount; //!< Encoder Engine count + unsigned int jpegCount; //!< JPEG Engine count + unsigned int ofaCount; //!< OFA Engine count + unsigned long long memorySizeMB; //!< Memory size in MBytes + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name + unsigned int capabilities; //!< Additional capabilities +} nvmlGpuInstanceProfileInfo_v3_t; + +/** + * Version identifier value for \ref nvmlGpuInstanceProfileInfo_v3_t.version. + */ +#define nvmlGpuInstanceProfileInfo_v3 NVML_STRUCT_VERSION(GpuInstanceProfileInfo, 3) + +typedef struct nvmlGpuInstanceInfo_st +{ + nvmlDevice_t device; //!< Parent device + unsigned int id; //!< Unique instance ID within the device + unsigned int profileId; //!< Unique profile ID within the device + nvmlGpuInstancePlacement_t placement; //!< Placement for this instance +} nvmlGpuInstanceInfo_t; + +/** + * Compute instance profiles. + * + * These macros should be passed to \ref nvmlGpuInstanceGetComputeInstanceProfileInfo to retrieve the + * detailed information about a compute instance such as profile ID, engine counts + */ +#define NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE 0x0 +#define NVML_COMPUTE_INSTANCE_PROFILE_2_SLICE 0x1 +#define NVML_COMPUTE_INSTANCE_PROFILE_3_SLICE 0x2 +#define NVML_COMPUTE_INSTANCE_PROFILE_4_SLICE 0x3 +#define NVML_COMPUTE_INSTANCE_PROFILE_7_SLICE 0x4 +#define NVML_COMPUTE_INSTANCE_PROFILE_8_SLICE 0x5 +#define NVML_COMPUTE_INSTANCE_PROFILE_6_SLICE 0x6 +#define NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE_REV1 0x7 +#define NVML_COMPUTE_INSTANCE_PROFILE_COUNT 0x8 + +#define NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_SHARED 0x0 //!< All the engines except multiprocessors would be shared +#define NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_COUNT 0x1 + +typedef struct nvmlComputeInstancePlacement_st +{ + unsigned int start; //!< Index of first occupied compute slice + unsigned int size; //!< Number of compute slices occupied +} nvmlComputeInstancePlacement_t; + +/** + * Compute instance profile information. + */ +typedef struct nvmlComputeInstanceProfileInfo_st +{ + unsigned int id; //!< Unique profile ID within the GPU instance + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< Compute instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count +} nvmlComputeInstanceProfileInfo_t; + +/** + * Compute instance profile information (v2). + * + * Version 2 adds the \ref nvmlComputeInstanceProfileInfo_v2_t.version field + * to the start of the structure, and the \ref nvmlComputeInstanceProfileInfo_v2_t.name + * field to the end. This structure is not backwards-compatible with + * \ref nvmlComputeInstanceProfileInfo_t. + */ +typedef struct nvmlComputeInstanceProfileInfo_v2_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlComputeInstanceProfileInfo_v2) + unsigned int id; //!< Unique profile ID within the GPU instance + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< Compute instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name +} nvmlComputeInstanceProfileInfo_v2_t; + +/** + * Version identifier value for \ref nvmlComputeInstanceProfileInfo_v2_t.version. + */ +#define nvmlComputeInstanceProfileInfo_v2 NVML_STRUCT_VERSION(ComputeInstanceProfileInfo, 2) + +/** + * Compute instance profile information (v3). + * + * Version 3 adds the \ref nvmlComputeInstanceProfileInfo_v3_t.capabilities field + * \ref nvmlComputeInstanceProfileInfo_t. + */ +typedef struct nvmlComputeInstanceProfileInfo_v3_st +{ + unsigned int version; //!< Structure version identifier (set to \ref nvmlComputeInstanceProfileInfo_v3) + unsigned int id; //!< Unique profile ID within the GPU instance + unsigned int sliceCount; //!< GPU Slice count + unsigned int instanceCount; //!< Compute instance count + unsigned int multiprocessorCount; //!< Streaming Multiprocessor count + unsigned int sharedCopyEngineCount; //!< Shared Copy Engine count + unsigned int sharedDecoderCount; //!< Shared Decoder Engine count + unsigned int sharedEncoderCount; //!< Shared Encoder Engine count + unsigned int sharedJpegCount; //!< Shared JPEG Engine count + unsigned int sharedOfaCount; //!< Shared OFA Engine count + char name[NVML_DEVICE_NAME_V2_BUFFER_SIZE]; //!< Profile name + unsigned int capabilities; //!< Additional capabilities +} nvmlComputeInstanceProfileInfo_v3_t; + +/** + * Version identifier value for \ref nvmlComputeInstanceProfileInfo_v3_t.version. + */ +#define nvmlComputeInstanceProfileInfo_v3 NVML_STRUCT_VERSION(ComputeInstanceProfileInfo, 3) + +typedef struct nvmlComputeInstanceInfo_st +{ + nvmlDevice_t device; //!< Parent device + nvmlGpuInstance_t gpuInstance; //!< Parent GPU instance + unsigned int id; //!< Unique instance ID within the GPU instance + unsigned int profileId; //!< Unique profile ID within the GPU instance + nvmlComputeInstancePlacement_t placement; //!< Placement for this instance within the GPU instance's compute slice range {0, sliceCount} +} nvmlComputeInstanceInfo_t; + +typedef struct nvmlComputeInstance_st* nvmlComputeInstance_t; + +/** + * Set MIG mode for the device. + * + * For Ampere &tm; or newer fully supported devices. + * Requires root user. + * + * This mode determines whether a GPU instance can be created. + * + * This API may unbind or reset the device to activate the requested mode. Thus, the attributes associated with the + * device, such as minor number, might change. The caller of this API is expected to query such attributes again. + * + * On certain platforms like pass-through virtualization, where reset functionality may not be exposed directly, VM + * reboot is required. \a activationStatus would return \ref NVML_ERROR_RESET_REQUIRED for such cases. + * + * \a activationStatus would return the appropriate error code upon unsuccessful activation. For example, if device + * unbind fails because the device isn't idle, \ref NVML_ERROR_IN_USE would be returned. The caller of this API + * is expected to idle the device and retry setting the \a mode. + * + * @note On Windows, only disabling MIG mode is supported. \a activationStatus would return \ref + * NVML_ERROR_NOT_SUPPORTED as GPU reset is not supported on Windows through this API. + * + * @param device The identifier of the target device + * @param mode The mode to be set, \ref NVML_DEVICE_MIG_DISABLE or + * \ref NVML_DEVICE_MIG_ENABLE + * @param activationStatus The activationStatus status + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device,\a mode or \a activationStatus are invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG mode + */ +nvmlReturn_t DECLDIR nvmlDeviceSetMigMode(nvmlDevice_t device, unsigned int mode, nvmlReturn_t *activationStatus); + +/** + * Get MIG mode for the device. + * + * For Ampere &tm; or newer fully supported devices. + * + * Changing MIG modes may require device unbind or reset. The "pending" MIG mode refers to the target mode following the + * next activation trigger. + * + * @param device The identifier of the target device + * @param currentMode Returns the current mode, \ref NVML_DEVICE_MIG_DISABLE or + * \ref NVML_DEVICE_MIG_ENABLE + * @param pendingMode Returns the pending mode, \ref NVML_DEVICE_MIG_DISABLE or + * \ref NVML_DEVICE_MIG_ENABLE + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a currentMode or \a pendingMode are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG mode + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMigMode(nvmlDevice_t device, unsigned int *currentMode, unsigned int *pendingMode); + +/** + * Get GPU instance profile information + * + * Information provided by this API is immutable throughout the lifetime of a MIG mode. + * + * @note This API can be used to enumerate all MIG profiles supported by NVML in a forward compatible + * way by invoking it on \a profile values starting from 0, until the API returns \ref NVML_ERROR_INVALID_ARGUMENT. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param profile One of the NVML_GPU_INSTANCE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile or \a info are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG or \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceProfileInfo(nvmlDevice_t device, unsigned int profile, + nvmlGpuInstanceProfileInfo_t *info); + +/** + * Versioned wrapper around \ref nvmlDeviceGetGpuInstanceProfileInfo that accepts a versioned + * \ref nvmlGpuInstanceProfileInfo_v2_t or later output structure. + * + * @note The caller must set the \ref nvmlGpuInstanceProfileInfo_v2_t.version field to the + * appropriate version prior to calling this function. For example: + * \code + * nvmlGpuInstanceProfileInfo_v2_t profileInfo = + * { .version = nvmlGpuInstanceProfileInfo_v2 }; + * nvmlReturn_t result = nvmlDeviceGetGpuInstanceProfileInfoV(device, + * profile, + * &profileInfo); + * \endcode + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param profile One of the NVML_GPU_INSTANCE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile, \a info, or \a info->version are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceProfileInfoV(nvmlDevice_t device, unsigned int profile, + nvmlGpuInstanceProfileInfo_v2_t *info); + +/** + * GPU instance profile query function that accepts profile ID, instead of profile name. + * It accepts a versioned \ref nvmlGpuInstanceProfileInfo_v2_t or later output structure. + * + * @note The caller must set the \ref nvmlGpuInstanceProfileInfo_v2_t.version field to the + * appropriate version prior to calling this function. For example: + * \code + * nvmlGpuInstanceProfileInfo_v2_t profileInfo = + * { .version = nvmlGpuInstanceProfileInfo_v2 }; + * nvmlReturn_t result = nvmlDeviceGetGpuInstanceProfileInfoV(device, + * profile, + * &profileInfo); + * \endcode + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device The identifier of the target device + * @param profileId One of the profile IDs. + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId, \a info, or \a info->version are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceProfileInfoByIdV(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstanceProfileInfo_v2_t *info); + +/** + * Get GPU instance placements. + * + * A placement represents the location of a GPU instance within a device. This API only returns all the possible + * placements for the given profile regardless of whether MIG is enabled or not. + * A created GPU instance occupies memory slices described by its placement. Creation of new GPU instance will + * fail if there is overlap with the already occupied memory slices. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param placements Returns placements allowed for the profile. Can be NULL to discover number + * of allowed placements for this profile. If non-NULL must be large enough + * to accommodate the placements supported by the profile. + * @param count Returns number of allowed placemenets for the profile. + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't support MIG or \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstancePossiblePlacements_v2(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstancePlacement_t *placements, + unsigned int *count); + +/** + * Get GPU instance profile capacity. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param count Returns remaining instance count for the profile ID + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceRemainingCapacity(nvmlDevice_t device, unsigned int profileId, + unsigned int *count); + +/** + * Create GPU instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the GPU instance is destroyed explicitly, the GPU instance handle would + * become invalid. The GPU instance must be recreated to acquire a valid handle. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param gpuInstance Returns the GPU instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile, \a profileId or \a gpuInstance are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or in vGPU guest + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested GPU instance could not be created + */ +nvmlReturn_t DECLDIR nvmlDeviceCreateGpuInstance(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstance_t *gpuInstance); + +/** + * Create GPU instance with the specified placement. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the GPU instance is destroyed explicitly, the GPU instance handle would + * become invalid. The GPU instance must be recreated to acquire a valid handle. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param placement The requested placement. See \ref nvmlDeviceGetGpuInstancePossiblePlacements_v2 + * @param gpuInstance Returns the GPU instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profile, \a profileId, \a placement or \a gpuInstance + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or in vGPU guest + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested GPU instance could not be created + */ +nvmlReturn_t DECLDIR nvmlDeviceCreateGpuInstanceWithPlacement(nvmlDevice_t device, unsigned int profileId, + const nvmlGpuInstancePlacement_t *placement, + nvmlGpuInstance_t *gpuInstance); +/** + * Destroy GPU instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The GPU instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or in vGPU guest + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_IN_USE If the GPU instance is in use. This error would be returned if processes + * (e.g. CUDA application) or compute instances are active on the + * GPU instance. + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceDestroy(nvmlGpuInstance_t gpuInstance); + +/** + * Get GPU instances for given profile ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param profileId The GPU instance profile ID. See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param gpuInstances Returns pre-exiting GPU instances, the buffer must be large enough to + * accommodate the instances supported by the profile. + * See \ref nvmlDeviceGetGpuInstanceProfileInfo + * @param count The count of returned GPU instances + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a profileId, \a gpuInstances or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstances(nvmlDevice_t device, unsigned int profileId, + nvmlGpuInstance_t *gpuInstances, unsigned int *count); + +/** + * Get GPU instances for given instance ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param device The identifier of the target device + * @param id The GPU instance ID + * @param gpuInstance Returns GPU instance + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a id or \a gpuInstance are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_FOUND If the GPU instance is not found. + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceById(nvmlDevice_t device, unsigned int id, nvmlGpuInstance_t *gpuInstance); + +/** + * Get GPU instance information. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param gpuInstance The GPU instance handle + * @param info Return GPU instance information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance or \a info are invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetInfo(nvmlGpuInstance_t gpuInstance, nvmlGpuInstanceInfo_t *info); + +/** + * Get compute instance profile information. + * + * Information provided by this API is immutable throughout the lifetime of a MIG mode. + * + * @note This API can be used to enumerate all MIG profiles supported by NVML in a forward compatible + * way by invoking it on \a profile values starting from 0, until the API returns \ref NVML_ERROR_INVALID_ARGUMENT. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profile One of the NVML_COMPUTE_INSTANCE_PROFILE_* + * @param engProfile One of the NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a engProfile or \a info are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceProfileInfo(nvmlGpuInstance_t gpuInstance, unsigned int profile, + unsigned int engProfile, + nvmlComputeInstanceProfileInfo_t *info); + +/** + * Versioned wrapper around \ref nvmlGpuInstanceGetComputeInstanceProfileInfo that accepts a versioned + * \ref nvmlComputeInstanceProfileInfo_v2_t or later output structure. + * + * @note The caller must set the \ref nvmlGpuInstanceProfileInfo_v2_t.version field to the + * appropriate version prior to calling this function. For example: + * \code + * nvmlComputeInstanceProfileInfo_v2_t profileInfo = + * { .version = nvmlComputeInstanceProfileInfo_v2 }; + * nvmlReturn_t result = nvmlGpuInstanceGetComputeInstanceProfileInfoV(gpuInstance, + * profile, + * engProfile, + * &profileInfo); + * \endcode + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profile One of the NVML_COMPUTE_INSTANCE_PROFILE_* + * @param engProfile One of the NVML_COMPUTE_INSTANCE_ENGINE_PROFILE_* + * @param info Returns detailed profile information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a engProfile, \a info, or \a info->version are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profile isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceProfileInfoV(nvmlGpuInstance_t gpuInstance, unsigned int profile, + unsigned int engProfile, + nvmlComputeInstanceProfileInfo_v2_t *info); + +/** + * Get compute instance profile capacity. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param count Returns remaining instance count for the profile ID + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profileId or \a availableCount are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceRemainingCapacity(nvmlGpuInstance_t gpuInstance, + unsigned int profileId, unsigned int *count); + +/** + * Get compute instance placements. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * A placement represents the location of a compute instance within a GPU instance. This API only returns all the possible + * placements for the given profile. + * A created compute instance occupies compute slices described by its placement. Creation of new compute instance will + * fail if there is overlap with the already occupied compute slices. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param placements Returns placements allowed for the profile. Can be NULL to discover number + * of allowed placements for this profile. If non-NULL must be large enough + * to accommodate the placements supported by the profile. + * @param count Returns number of allowed placemenets for the profile. + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profileId or \a count are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled or \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstancePossiblePlacements(nvmlGpuInstance_t gpuInstance, + unsigned int profileId, + nvmlComputeInstancePlacement_t *placements, + unsigned int *count); + +/** + * Create compute instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the parent GPU instance is destroyed or the compute instance is destroyed + * explicitly, the compute instance handle would become invalid. The compute instance must be recreated to acquire + * a valid handle. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param computeInstance Returns the compute instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a profileId or \a computeInstance + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested compute instance could not be created + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceCreateComputeInstance(nvmlGpuInstance_t gpuInstance, unsigned int profileId, + nvmlComputeInstance_t *computeInstance); + +/** + * Create compute instance with the specified placement. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * If the parent device is unbound, reset or the parent GPU instance is destroyed or the compute instance is destroyed + * explicitly, the compute instance handle would become invalid. The compute instance must be recreated to acquire + * a valid handle. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param placement The requested placement. See \ref nvmlGpuInstanceGetComputeInstancePossiblePlacements + * @param computeInstance Returns the compute instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profile, \a profileId or \a computeInstance + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_INSUFFICIENT_RESOURCES If the requested compute instance could not be created + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceCreateComputeInstanceWithPlacement(nvmlGpuInstance_t gpuInstance, unsigned int profileId, + const nvmlComputeInstancePlacement_t *placement, + nvmlComputeInstance_t *computeInstance); + +/** + * Destroy compute instance. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param computeInstance The compute instance handle + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a computeInstance is invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_IN_USE If the compute instance is in use. This error would be returned if + * processes (e.g. CUDA application) are active on the compute instance. + */ +nvmlReturn_t DECLDIR nvmlComputeInstanceDestroy(nvmlComputeInstance_t computeInstance); + +/** + * Get compute instances for given profile ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The identifier of the target GPU instance + * @param profileId The compute instance profile ID. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param computeInstances Returns pre-exiting compute instances, the buffer must be large enough to + * accommodate the instances supported by the profile. + * See \ref nvmlGpuInstanceGetComputeInstanceProfileInfo + * @param count The count of returned compute instances + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a gpuInstance, \a profileId, \a computeInstances or \a count + * are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a profileId isn't supported + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstances(nvmlGpuInstance_t gpuInstance, unsigned int profileId, + nvmlComputeInstance_t *computeInstances, unsigned int *count); + +/** + * Get compute instance for given instance ID. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * Requires privileged user. + * + * @param gpuInstance The identifier of the target GPU instance + * @param id The compute instance ID + * @param computeInstance Returns compute instance + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device, \a ID or \a computeInstance are invalid + * - \ref NVML_ERROR_NOT_SUPPORTED If \a device doesn't have MIG mode enabled + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + * - \ref NVML_ERROR_NOT_FOUND If the compute instance is not found. + */ +nvmlReturn_t DECLDIR nvmlGpuInstanceGetComputeInstanceById(nvmlGpuInstance_t gpuInstance, unsigned int id, + nvmlComputeInstance_t *computeInstance); + +/** + * Get compute instance information. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param computeInstance The compute instance handle + * @param info Return compute instance information + * + * @return + * - \ref NVML_SUCCESS Upon success + * - \ref NVML_ERROR_UNINITIALIZED If library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a computeInstance or \a info are invalid + * - \ref NVML_ERROR_NO_PERMISSION If user doesn't have permission to perform the operation + */ +nvmlReturn_t DECLDIR nvmlComputeInstanceGetInfo_v2(nvmlComputeInstance_t computeInstance, nvmlComputeInstanceInfo_t *info); + +/** + * Test if the given handle refers to a MIG device. + * + * A MIG device handle is an NVML abstraction which maps to a MIG compute instance. + * These overloaded references can be used (with some restrictions) interchangeably + * with a GPU device handle to execute queries at a per-compute instance granularity. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device NVML handle to test + * @param isMigDevice True when handle refers to a MIG device + * + * @return + * - \ref NVML_SUCCESS if \a device status was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device handle or \a isMigDevice reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this check is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceIsMigDeviceHandle(nvmlDevice_t device, unsigned int *isMigDevice); + +/** + * Get GPU instance ID for the given MIG device handle. + * + * GPU instance IDs are unique per device and remain valid until the GPU instance is destroyed. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Target MIG device handle + * @param id GPU instance ID + * + * @return + * - \ref NVML_SUCCESS if instance ID was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a id reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstanceId(nvmlDevice_t device, unsigned int *id); + +/** + * Get compute instance ID for the given MIG device handle. + * + * Compute instance IDs are unique per GPU instance and remain valid until the compute instance + * is destroyed. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Target MIG device handle + * @param id Compute instance ID + * + * @return + * - \ref NVML_SUCCESS if instance ID was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a id reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetComputeInstanceId(nvmlDevice_t device, unsigned int *id); + +/** + * Get the maximum number of MIG devices that can exist under a given parent NVML device. + * + * Returns zero if MIG is not supported or enabled. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Target device handle + * @param count Count of MIG devices + * + * @return + * - \ref NVML_SUCCESS if \a count was successfully retrieved + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device or \a count reference is invalid + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMaxMigDeviceCount(nvmlDevice_t device, unsigned int *count); + +/** + * Get MIG device handle for the given index under its parent NVML device. + * + * If the compute instance is destroyed either explicitly or by destroying, + * resetting or unbinding the parent GPU instance or the GPU device itself + * the MIG device handle would remain invalid and must be requested again + * using this API. Handles may be reused and their properties can change in + * the process. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param device Reference to the parent GPU device handle + * @param index Index of the MIG device + * @param migDevice Reference to the MIG device handle + * + * @return + * - \ref NVML_SUCCESS if \a migDevice handle was successfully created + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device, \a index or \a migDevice reference is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_NOT_FOUND if no valid MIG device was found at \a index + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetMigDeviceHandleByIndex(nvmlDevice_t device, unsigned int index, + nvmlDevice_t *migDevice); + +/** + * Get parent device handle from a MIG device handle. + * + * For Ampere &tm; or newer fully supported devices. + * Supported on Linux only. + * + * @param migDevice MIG device handle + * @param device Device handle + * + * @return + * - \ref NVML_SUCCESS if \a device handle was successfully created + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a migDevice or \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetDeviceHandleFromMigDeviceHandle(nvmlDevice_t migDevice, nvmlDevice_t *device); + +/** @} */ // @defgroup nvmlMultiInstanceGPU + + +/***************************************************************************************************/ +/** @defgroup GPM NVML GPM + * @note For NVIDIA vGPU Software products + * @note (A) GPM is supported only on MIG-backed vGPU profiles that are allocated all of the instance's frame buffer + * @note (B) No GPM support on Windows + * @{ + */ +/***************************************************************************************************/ +/** @defgroup nvmlGpmEnums GPM Enums + * @{ + */ +/***************************************************************************************************/ + +/** + * GPM Metric Identifiers + */ +typedef enum +{ + NVML_GPM_METRIC_GRAPHICS_UTIL = 1, //!< Percentage of time any compute/graphics app was active on the GPU. 0.0 - 100.0 + NVML_GPM_METRIC_SM_UTIL = 2, //!< Percentage of SMs that were busy. 0.0 - 100.0 + NVML_GPM_METRIC_SM_OCCUPANCY = 3, //!< Percentage of warps that were active vs theoretical maximum. 0.0 - 100.0 + NVML_GPM_METRIC_INTEGER_UTIL = 4, //!< Percentage of time the GPU's SMs were doing integer operations. 0.0 - 100.0 + NVML_GPM_METRIC_ANY_TENSOR_UTIL = 5, //!< Percentage of time the GPU's SMs were doing ANY tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_DFMA_TENSOR_UTIL = 6, //!< Percentage of time the GPU's SMs were doing DFMA tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_HMMA_TENSOR_UTIL = 7, //!< Percentage of time the GPU's SMs were doing HMMA tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_IMMA_TENSOR_UTIL = 9, //!< Percentage of time the GPU's SMs were doing IMMA tensor operations. 0.0 - 100.0 + NVML_GPM_METRIC_DRAM_BW_UTIL = 10, //!< Percentage of DRAM bw used vs theoretical maximum. 0.0 - 100.0 */ + NVML_GPM_METRIC_FP64_UTIL = 11, //!< Percentage of time the GPU's SMs were doing non-tensor FP64 math. 0.0 - 100.0 + NVML_GPM_METRIC_FP32_UTIL = 12, //!< Percentage of time the GPU's SMs were doing non-tensor FP32 math. 0.0 - 100.0 + NVML_GPM_METRIC_FP16_UTIL = 13, //!< Percentage of time the GPU's SMs were doing non-tensor FP16 math. 0.0 - 100.0 + NVML_GPM_METRIC_PCIE_TX_PER_SEC = 20, //!< PCIe traffic from this GPU in MiB/sec + NVML_GPM_METRIC_PCIE_RX_PER_SEC = 21, //!< PCIe traffic to this GPU in MiB/sec + NVML_GPM_METRIC_NVDEC_0_UTIL = 30, //!< Percent utilization of NVDEC 0. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_1_UTIL = 31, //!< Percent utilization of NVDEC 1. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_2_UTIL = 32, //!< Percent utilization of NVDEC 2. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_3_UTIL = 33, //!< Percent utilization of NVDEC 3. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_4_UTIL = 34, //!< Percent utilization of NVDEC 4. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_5_UTIL = 35, //!< Percent utilization of NVDEC 5. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_6_UTIL = 36, //!< Percent utilization of NVDEC 6. 0.0 - 100.0 + NVML_GPM_METRIC_NVDEC_7_UTIL = 37, //!< Percent utilization of NVDEC 7. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_0_UTIL = 40, //!< Percent utilization of NVJPG 0. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_1_UTIL = 41, //!< Percent utilization of NVJPG 1. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_2_UTIL = 42, //!< Percent utilization of NVJPG 2. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_3_UTIL = 43, //!< Percent utilization of NVJPG 3. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_4_UTIL = 44, //!< Percent utilization of NVJPG 4. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_5_UTIL = 45, //!< Percent utilization of NVJPG 5. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_6_UTIL = 46, //!< Percent utilization of NVJPG 6. 0.0 - 100.0 + NVML_GPM_METRIC_NVJPG_7_UTIL = 47, //!< Percent utilization of NVJPG 7. 0.0 - 100.0 + NVML_GPM_METRIC_NVOFA_0_UTIL = 50, //!< Percent utilization of NVOFA 0. 0.0 - 100.0 + NVML_GPM_METRIC_NVOFA_1_UTIL = 51, //!< Percent utilization of NVOFA 1. 0.0 - 100.0 + NVML_GPM_METRIC_NVLINK_TOTAL_RX_PER_SEC = 60, //!< NvLink read bandwidth for all links in MiB/sec + NVML_GPM_METRIC_NVLINK_TOTAL_TX_PER_SEC = 61, //!< NvLink write bandwidth for all links in MiB/sec + NVML_GPM_METRIC_NVLINK_L0_RX_PER_SEC = 62, //!< NvLink read bandwidth for link 0 in MiB/sec + NVML_GPM_METRIC_NVLINK_L0_TX_PER_SEC = 63, //!< NvLink write bandwidth for link 0 in MiB/sec + NVML_GPM_METRIC_NVLINK_L1_RX_PER_SEC = 64, //!< NvLink read bandwidth for link 1 in MiB/sec + NVML_GPM_METRIC_NVLINK_L1_TX_PER_SEC = 65, //!< NvLink write bandwidth for link 1 in MiB/sec + NVML_GPM_METRIC_NVLINK_L2_RX_PER_SEC = 66, //!< NvLink read bandwidth for link 2 in MiB/sec + NVML_GPM_METRIC_NVLINK_L2_TX_PER_SEC = 67, //!< NvLink write bandwidth for link 2 in MiB/sec + NVML_GPM_METRIC_NVLINK_L3_RX_PER_SEC = 68, //!< NvLink read bandwidth for link 3 in MiB/sec + NVML_GPM_METRIC_NVLINK_L3_TX_PER_SEC = 69, //!< NvLink write bandwidth for link 3 in MiB/sec + NVML_GPM_METRIC_NVLINK_L4_RX_PER_SEC = 70, //!< NvLink read bandwidth for link 4 in MiB/sec + NVML_GPM_METRIC_NVLINK_L4_TX_PER_SEC = 71, //!< NvLink write bandwidth for link 4 in MiB/sec + NVML_GPM_METRIC_NVLINK_L5_RX_PER_SEC = 72, //!< NvLink read bandwidth for link 5 in MiB/sec + NVML_GPM_METRIC_NVLINK_L5_TX_PER_SEC = 73, //!< NvLink write bandwidth for link 5 in MiB/sec + NVML_GPM_METRIC_NVLINK_L6_RX_PER_SEC = 74, //!< NvLink read bandwidth for link 6 in MiB/sec + NVML_GPM_METRIC_NVLINK_L6_TX_PER_SEC = 75, //!< NvLink write bandwidth for link 6 in MiB/sec + NVML_GPM_METRIC_NVLINK_L7_RX_PER_SEC = 76, //!< NvLink read bandwidth for link 7 in MiB/sec + NVML_GPM_METRIC_NVLINK_L7_TX_PER_SEC = 77, //!< NvLink write bandwidth for link 7 in MiB/sec + NVML_GPM_METRIC_NVLINK_L8_RX_PER_SEC = 78, //!< NvLink read bandwidth for link 8 in MiB/sec + NVML_GPM_METRIC_NVLINK_L8_TX_PER_SEC = 79, //!< NvLink write bandwidth for link 8 in MiB/sec + NVML_GPM_METRIC_NVLINK_L9_RX_PER_SEC = 80, //!< NvLink read bandwidth for link 9 in MiB/sec + NVML_GPM_METRIC_NVLINK_L9_TX_PER_SEC = 81, //!< NvLink write bandwidth for link 9 in MiB/sec + NVML_GPM_METRIC_NVLINK_L10_RX_PER_SEC = 82, //!< NvLink read bandwidth for link 10 in MiB/sec + NVML_GPM_METRIC_NVLINK_L10_TX_PER_SEC = 83, //!< NvLink write bandwidth for link 10 in MiB/sec + NVML_GPM_METRIC_NVLINK_L11_RX_PER_SEC = 84, //!< NvLink read bandwidth for link 11 in MiB/sec + NVML_GPM_METRIC_NVLINK_L11_TX_PER_SEC = 85, //!< NvLink write bandwidth for link 11 in MiB/sec + NVML_GPM_METRIC_NVLINK_L12_RX_PER_SEC = 86, //!< NvLink read bandwidth for link 12 in MiB/sec + NVML_GPM_METRIC_NVLINK_L12_TX_PER_SEC = 87, //!< NvLink write bandwidth for link 12 in MiB/sec + NVML_GPM_METRIC_NVLINK_L13_RX_PER_SEC = 88, //!< NvLink read bandwidth for link 13 in MiB/sec + NVML_GPM_METRIC_NVLINK_L13_TX_PER_SEC = 89, //!< NvLink write bandwidth for link 13 in MiB/sec + NVML_GPM_METRIC_NVLINK_L14_RX_PER_SEC = 90, //!< NvLink read bandwidth for link 14 in MiB/sec + NVML_GPM_METRIC_NVLINK_L14_TX_PER_SEC = 91, //!< NvLink write bandwidth for link 14 in MiB/sec + NVML_GPM_METRIC_NVLINK_L15_RX_PER_SEC = 92, //!< NvLink read bandwidth for link 15 in MiB/sec + NVML_GPM_METRIC_NVLINK_L15_TX_PER_SEC = 93, //!< NvLink write bandwidth for link 15 in MiB/sec + NVML_GPM_METRIC_NVLINK_L16_RX_PER_SEC = 94, //!< NvLink read bandwidth for link 16 in MiB/sec + NVML_GPM_METRIC_NVLINK_L16_TX_PER_SEC = 95, //!< NvLink write bandwidth for link 16 in MiB/sec + NVML_GPM_METRIC_NVLINK_L17_RX_PER_SEC = 96, //!< NvLink read bandwidth for link 17 in MiB/sec + NVML_GPM_METRIC_NVLINK_L17_TX_PER_SEC = 97, //!< NvLink write bandwidth for link 17 in MiB/sec + //Put new metrics for BLACKWELL here... + NVML_GPM_METRIC_C2C_TOTAL_TX_PER_SEC = 100, + NVML_GPM_METRIC_C2C_TOTAL_RX_PER_SEC = 101, + NVML_GPM_METRIC_C2C_DATA_TX_PER_SEC = 102, + NVML_GPM_METRIC_C2C_DATA_RX_PER_SEC = 103, + NVML_GPM_METRIC_C2C_LINK0_TOTAL_TX_PER_SEC = 104, + NVML_GPM_METRIC_C2C_LINK0_TOTAL_RX_PER_SEC = 105, + NVML_GPM_METRIC_C2C_LINK0_DATA_TX_PER_SEC = 106, + NVML_GPM_METRIC_C2C_LINK0_DATA_RX_PER_SEC = 107, + NVML_GPM_METRIC_C2C_LINK1_TOTAL_TX_PER_SEC = 108, + NVML_GPM_METRIC_C2C_LINK1_TOTAL_RX_PER_SEC = 109, + NVML_GPM_METRIC_C2C_LINK1_DATA_TX_PER_SEC = 110, + NVML_GPM_METRIC_C2C_LINK1_DATA_RX_PER_SEC = 111, + NVML_GPM_METRIC_C2C_LINK2_TOTAL_TX_PER_SEC = 112, + NVML_GPM_METRIC_C2C_LINK2_TOTAL_RX_PER_SEC = 113, + NVML_GPM_METRIC_C2C_LINK2_DATA_TX_PER_SEC = 114, + NVML_GPM_METRIC_C2C_LINK2_DATA_RX_PER_SEC = 115, + NVML_GPM_METRIC_C2C_LINK3_TOTAL_TX_PER_SEC = 116, + NVML_GPM_METRIC_C2C_LINK3_TOTAL_RX_PER_SEC = 117, + NVML_GPM_METRIC_C2C_LINK3_DATA_TX_PER_SEC = 118, + NVML_GPM_METRIC_C2C_LINK3_DATA_RX_PER_SEC = 119, + NVML_GPM_METRIC_C2C_LINK4_TOTAL_TX_PER_SEC = 120, + NVML_GPM_METRIC_C2C_LINK4_TOTAL_RX_PER_SEC = 121, + NVML_GPM_METRIC_C2C_LINK4_DATA_TX_PER_SEC = 122, + NVML_GPM_METRIC_C2C_LINK4_DATA_RX_PER_SEC = 123, + NVML_GPM_METRIC_C2C_LINK5_TOTAL_TX_PER_SEC = 124, + NVML_GPM_METRIC_C2C_LINK5_TOTAL_RX_PER_SEC = 125, + NVML_GPM_METRIC_C2C_LINK5_DATA_TX_PER_SEC = 126, + NVML_GPM_METRIC_C2C_LINK5_DATA_RX_PER_SEC = 127, + NVML_GPM_METRIC_C2C_LINK6_TOTAL_TX_PER_SEC = 128, + NVML_GPM_METRIC_C2C_LINK6_TOTAL_RX_PER_SEC = 129, + NVML_GPM_METRIC_C2C_LINK6_DATA_TX_PER_SEC = 130, + NVML_GPM_METRIC_C2C_LINK6_DATA_RX_PER_SEC = 131, + NVML_GPM_METRIC_C2C_LINK7_TOTAL_TX_PER_SEC = 132, + NVML_GPM_METRIC_C2C_LINK7_TOTAL_RX_PER_SEC = 133, + NVML_GPM_METRIC_C2C_LINK7_DATA_TX_PER_SEC = 134, + NVML_GPM_METRIC_C2C_LINK7_DATA_RX_PER_SEC = 135, + NVML_GPM_METRIC_C2C_LINK8_TOTAL_TX_PER_SEC = 136, + NVML_GPM_METRIC_C2C_LINK8_TOTAL_RX_PER_SEC = 137, + NVML_GPM_METRIC_C2C_LINK8_DATA_TX_PER_SEC = 138, + NVML_GPM_METRIC_C2C_LINK8_DATA_RX_PER_SEC = 139, + NVML_GPM_METRIC_C2C_LINK9_TOTAL_TX_PER_SEC = 140, + NVML_GPM_METRIC_C2C_LINK9_TOTAL_RX_PER_SEC = 141, + NVML_GPM_METRIC_C2C_LINK9_DATA_TX_PER_SEC = 142, + NVML_GPM_METRIC_C2C_LINK9_DATA_RX_PER_SEC = 143, + NVML_GPM_METRIC_C2C_LINK10_TOTAL_TX_PER_SEC = 144, + NVML_GPM_METRIC_C2C_LINK10_TOTAL_RX_PER_SEC = 145, + NVML_GPM_METRIC_C2C_LINK10_DATA_TX_PER_SEC = 146, + NVML_GPM_METRIC_C2C_LINK10_DATA_RX_PER_SEC = 147, + NVML_GPM_METRIC_C2C_LINK11_TOTAL_TX_PER_SEC = 148, + NVML_GPM_METRIC_C2C_LINK11_TOTAL_RX_PER_SEC = 149, + NVML_GPM_METRIC_C2C_LINK11_DATA_TX_PER_SEC = 150, + NVML_GPM_METRIC_C2C_LINK11_DATA_RX_PER_SEC = 151, + NVML_GPM_METRIC_C2C_LINK12_TOTAL_TX_PER_SEC = 152, + NVML_GPM_METRIC_C2C_LINK12_TOTAL_RX_PER_SEC = 153, + NVML_GPM_METRIC_C2C_LINK12_DATA_TX_PER_SEC = 154, + NVML_GPM_METRIC_C2C_LINK12_DATA_RX_PER_SEC = 155, + NVML_GPM_METRIC_C2C_LINK13_TOTAL_TX_PER_SEC = 156, + NVML_GPM_METRIC_C2C_LINK13_TOTAL_RX_PER_SEC = 157, + NVML_GPM_METRIC_C2C_LINK13_DATA_TX_PER_SEC = 158, + NVML_GPM_METRIC_C2C_LINK13_DATA_RX_PER_SEC = 159, + NVML_GPM_METRIC_HOSTMEM_CACHE_HIT = 160, + NVML_GPM_METRIC_HOSTMEM_CACHE_MISS = 161, + NVML_GPM_METRIC_PEERMEM_CACHE_HIT = 162, + NVML_GPM_METRIC_PEERMEM_CACHE_MISS = 163, + NVML_GPM_METRIC_DRAM_CACHE_HIT = 164, + NVML_GPM_METRIC_DRAM_CACHE_MISS = 165, + NVML_GPM_METRIC_NVENC_0_UTIL = 166, + NVML_GPM_METRIC_NVENC_1_UTIL = 167, + NVML_GPM_METRIC_NVENC_2_UTIL = 168, + NVML_GPM_METRIC_NVENC_3_UTIL = 169, + NVML_GPM_METRIC_GR0_CTXSW_CYCLES_ELAPSED = 170, + NVML_GPM_METRIC_GR0_CTXSW_CYCLES_ACTIVE = 171, + NVML_GPM_METRIC_GR0_CTXSW_REQUESTS = 172, + NVML_GPM_METRIC_GR0_CTXSW_CYCLES_PER_REQ = 173, + NVML_GPM_METRIC_GR0_CTXSW_ACTIVE_PCT = 174, + NVML_GPM_METRIC_GR1_CTXSW_CYCLES_ELAPSED = 175, + NVML_GPM_METRIC_GR1_CTXSW_CYCLES_ACTIVE = 176, + NVML_GPM_METRIC_GR1_CTXSW_REQUESTS = 177, + NVML_GPM_METRIC_GR1_CTXSW_CYCLES_PER_REQ = 178, + NVML_GPM_METRIC_GR1_CTXSW_ACTIVE_PCT = 179, + NVML_GPM_METRIC_GR2_CTXSW_CYCLES_ELAPSED = 180, + NVML_GPM_METRIC_GR2_CTXSW_CYCLES_ACTIVE = 181, + NVML_GPM_METRIC_GR2_CTXSW_REQUESTS = 182, + NVML_GPM_METRIC_GR2_CTXSW_CYCLES_PER_REQ = 183, + NVML_GPM_METRIC_GR2_CTXSW_ACTIVE_PCT = 184, + NVML_GPM_METRIC_GR3_CTXSW_CYCLES_ELAPSED = 185, + NVML_GPM_METRIC_GR3_CTXSW_CYCLES_ACTIVE = 186, + NVML_GPM_METRIC_GR3_CTXSW_REQUESTS = 187, + NVML_GPM_METRIC_GR3_CTXSW_CYCLES_PER_REQ = 188, + NVML_GPM_METRIC_GR3_CTXSW_ACTIVE_PCT = 189, + NVML_GPM_METRIC_GR4_CTXSW_CYCLES_ELAPSED = 190, + NVML_GPM_METRIC_GR4_CTXSW_CYCLES_ACTIVE = 191, + NVML_GPM_METRIC_GR4_CTXSW_REQUESTS = 192, + NVML_GPM_METRIC_GR4_CTXSW_CYCLES_PER_REQ = 193, + NVML_GPM_METRIC_GR4_CTXSW_ACTIVE_PCT = 194, + NVML_GPM_METRIC_GR5_CTXSW_CYCLES_ELAPSED = 195, + NVML_GPM_METRIC_GR5_CTXSW_CYCLES_ACTIVE = 196, + NVML_GPM_METRIC_GR5_CTXSW_REQUESTS = 197, + NVML_GPM_METRIC_GR5_CTXSW_CYCLES_PER_REQ = 198, + NVML_GPM_METRIC_GR5_CTXSW_ACTIVE_PCT = 199, + NVML_GPM_METRIC_GR6_CTXSW_CYCLES_ELAPSED = 200, + NVML_GPM_METRIC_GR6_CTXSW_CYCLES_ACTIVE = 201, + NVML_GPM_METRIC_GR6_CTXSW_REQUESTS = 202, + NVML_GPM_METRIC_GR6_CTXSW_CYCLES_PER_REQ = 203, + NVML_GPM_METRIC_GR6_CTXSW_ACTIVE_PCT = 204, + NVML_GPM_METRIC_GR7_CTXSW_CYCLES_ELAPSED = 205, + NVML_GPM_METRIC_GR7_CTXSW_CYCLES_ACTIVE = 206, + NVML_GPM_METRIC_GR7_CTXSW_REQUESTS = 207, + NVML_GPM_METRIC_GR7_CTXSW_CYCLES_PER_REQ = 208, + NVML_GPM_METRIC_GR7_CTXSW_ACTIVE_PCT = 209, + NVML_GPM_METRIC_MAX = 210, //!< Maximum value above +1. Note that changing this should also change NVML_GPM_METRICS_GET_VERSION due to struct size change +} nvmlGpmMetricId_t; + +/** @} */ // @defgroup nvmlGpmEnums + + +/***************************************************************************************************/ +/** @defgroup nvmlGpmStructs GPM Structs + * @{ + */ +/***************************************************************************************************/ + +/** + * Handle to an allocated GPM sample allocated with nvmlGpmSampleAlloc(). Free this with nvmlGpmSampleFree(). + */ +typedef struct nvmlGpmSample_st* nvmlGpmSample_t; + +/** + * GPM metric information. + */ +typedef struct +{ + unsigned int metricId; //!< IN: NVML_GPM_METRIC_? define of which metric to retrieve + nvmlReturn_t nvmlReturn; //!< OUT: Status of this metric. If this is nonzero, then value is not valid + double value; //!< OUT: Value of this metric. Is only valid if nvmlReturn is 0 (NVML_SUCCESS) + struct + { + char *shortName; + char *longName; + char *unit; + } metricInfo; //!< OUT: Metric name and unit. Those can be NULL if not defined +} nvmlGpmMetric_t; + +/** + * GPM buffer information. + */ +typedef struct +{ + unsigned int version; //!< IN: Set to NVML_GPM_METRICS_GET_VERSION + unsigned int numMetrics; //!< IN: How many metrics to retrieve in metrics[] + nvmlGpmSample_t sample1; //!< IN: Sample buffer + nvmlGpmSample_t sample2; //!< IN: Sample buffer + nvmlGpmMetric_t metrics[NVML_GPM_METRIC_MAX]; //!< IN/OUT: Array of metrics. Set metricId on call. See nvmlReturn and value on return +} nvmlGpmMetricsGet_t; + +#define NVML_GPM_METRICS_GET_VERSION 1 + +/** + * GPM device information. + */ +typedef struct +{ + unsigned int version; //!< IN: Set to NVML_GPM_SUPPORT_VERSION + unsigned int isSupportedDevice; //!< OUT: Indicates device support +} nvmlGpmSupport_t; + +#define NVML_GPM_SUPPORT_VERSION 1 + +/** @} */ // @defgroup nvmlGPMStructs + +/***************************************************************************************************/ +/** @defgroup nvmlGpmFunctions GPM Functions + * @{ + */ +/***************************************************************************************************/ + +/** + * Calculate GPM metrics from two samples. + * + * For Hopper &tm; or newer fully supported devices. + * + * To retrieve metrics, the user must first allocate the two sample buffers at \a metricsGet->sample1 + * and \a metricsGet->sample2 by calling \a nvmlGpmSampleAlloc(). Next, the user should fill in the ID of each metric + * in \a metricsGet->metrics[i].metricId and specify the total number of metrics to retrieve in \a metricsGet->numMetrics, + * The version should be set to NVML_GPM_METRICS_GET_VERSION in \a metricsGet->version. The user then calls the + * \a nvmlGpmSampleGet() API twice to obtain 2 samples of counters. + * + * @note The interval between these two \a nvmlGpmSampleGet() calls should be greater than 100ms due to the + * internal sample refresh rate. Finally, the user calls \a nvmlGpmMetricsGet to retrieve the metrics, which will + * be stored at \a metricsGet->metrics + * + * + * @param metricsGet IN/OUT: populated \a nvmlGpmMetricsGet_t struct + * + * @return + * - \ref NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum on error + */ +nvmlReturn_t DECLDIR nvmlGpmMetricsGet(nvmlGpmMetricsGet_t *metricsGet); + + +/** + * Free an allocated sample buffer that was allocated with \ref nvmlGpmSampleAlloc() + * + * For Hopper &tm; or newer fully supported devices. + * + * @param gpmSample Sample to free + * + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid pointer is provided + */ +nvmlReturn_t DECLDIR nvmlGpmSampleFree(nvmlGpmSample_t gpmSample); + + +/** + * Allocate a sample buffer to be used with NVML GPM . You will need to allocate + * at least two of these buffers to use with the NVML GPM feature + * + * For Hopper &tm; or newer fully supported devices. + * + * @param gpmSample Where the allocated sample will be stored + * + * @return + * - \ref NVML_SUCCESS on success + * - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid pointer is provided + * - \ref NVML_ERROR_MEMORY if system memory is insufficient + */ +nvmlReturn_t DECLDIR nvmlGpmSampleAlloc(nvmlGpmSample_t *gpmSample); + +/** + * Read a sample of GPM metrics into the provided \a gpmSample buffer. After + * two samples are gathered, you can call nvmlGpmMetricGet on those samples to + * retrive metrics + * + * For Hopper &tm; or newer fully supported devices. + * + * @note The interval between two \a nvmlGpmSampleGet() calls should be greater than 100ms due to + * the internal sample refresh rate. + * + * @param device Device to get samples for + * @param gpmSample Buffer to read samples into + * + * @return + * - \ref NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum on error + */ +nvmlReturn_t DECLDIR nvmlGpmSampleGet(nvmlDevice_t device, nvmlGpmSample_t gpmSample); + +/** + * Read a sample of GPM metrics into the provided \a gpmSample buffer for a MIG GPU Instance. + * + * After two samples are gathered, you can call nvmlGpmMetricGet on those + * samples to retrive metrics + * + * For Hopper &tm; or newer fully supported devices. + * + * @note The interval between two \a nvmlGpmMigSampleGet() calls should be greater than 100ms due to + * the internal sample refresh rate. + * + * @param device Device to get samples for + * @param gpuInstanceId MIG GPU Instance ID + * @param gpmSample Buffer to read samples into + * + * @return + * - \ref NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum on error + */ +nvmlReturn_t DECLDIR nvmlGpmMigSampleGet(nvmlDevice_t device, unsigned int gpuInstanceId, nvmlGpmSample_t gpmSample); + +/** + * Indicate whether the supplied device supports GPM + * + * For Hopper &tm; or newer fully supported devices. + * + * @param device NVML device to query for + * @param gpmSupport Structure to indicate GPM support \a nvmlGpmSupport_t. Indicates + * GPM support per system for the supplied device + * + * @return + * - NVML_SUCCESS on success + * - Nonzero NVML_ERROR_? enum if there is an error in processing the query + */ +nvmlReturn_t DECLDIR nvmlGpmQueryDeviceSupport(nvmlDevice_t device, nvmlGpmSupport_t *gpmSupport); + +/* GPM Stream State */ +/** + * Get GPM stream state. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param state Returns GPM stream state + * NVML_FEATURE_DISABLED or NVML_FEATURE_ENABLED + * + * @return + * - \ref NVML_SUCCESS if \a current GPM stream state were successfully queried + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a state is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlGpmQueryIfStreamingEnabled(nvmlDevice_t device, unsigned int *state); + +/** + * Set GPM stream state. + * + * For Hopper &tm; or newer fully supported devices. + * Supported on Linux, Windows TCC. + * + * @param device The identifier of the target device + * @param state GPM stream state, + * NVML_FEATURE_DISABLED or NVML_FEATURE_ENABLED + * + * @return + * - \ref NVML_SUCCESS if \a current GPM stream state is successfully set + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid + * - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device + */ +nvmlReturn_t DECLDIR nvmlGpmSetStreamingEnabled(nvmlDevice_t device, unsigned int state); + +/** @} */ // @defgroup nvmlGpmFunctions +/** @} */ // @defgroup GPM + +#define NVML_DEV_CAP_EGM (1 << 0) // Extended GPU memory +/** + * Device capabilities + */ +typedef struct +{ + unsigned int version; //!< the API version number + unsigned int capMask; //!< OUT: Bit mask of capabilities. +} nvmlDeviceCapabilities_v1_t; +typedef nvmlDeviceCapabilities_v1_t nvmlDeviceCapabilities_t; +#define nvmlDeviceCapabilities_v1 NVML_STRUCT_VERSION(DeviceCapabilities, 1) + +/** + * Get device capabilities + * + * See \ref nvmlDeviceCapabilities_v1_t for more information on the struct. + * + * @param device The identifier of the target device + * @param caps Returns GPU's capabilities + * + * @return + * - \ref NVML_SUCCESS If the query is success + * - \ref NVML_ERROR_UNINITIALIZED If the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT If \a device is invalid or \a counters is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED If the device does not support this feature + * - \ref NVML_ERROR_GPU_IS_LOST If the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH If the provided version is invalid/unsupported + * - \ref NVML_ERROR_UNKNOWN On any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetCapabilities(nvmlDevice_t device, + nvmlDeviceCapabilities_t *caps); + + +/* + * Generic bitmask to hold 255 bits, represented by 8 elements of 32 bits + */ +#define NVML_255_MASK_BITS_PER_ELEM 32 +#define NVML_255_MASK_NUM_ELEMS 8 +#define NVML_255_MASK_BIT_SET(index, nvmlMask) \ + nvmlMask.mask[index / NVML_255_MASK_BITS_PER_ELEM] |= (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +#define NVML_255_MASK_BIT_GET(index, nvmlMask) \ + nvmlMask.mask[index / NVML_255_MASK_BITS_PER_ELEM] & (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +#define NVML_255_MASK_BIT_SET_PTR(index, nvmlMask) \ + nvmlMask->mask[index / NVML_255_MASK_BITS_PER_ELEM] |= (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +#define NVML_255_MASK_BIT_GET_PTR(index, nvmlMask) \ + nvmlMask->mask[index / NVML_255_MASK_BITS_PER_ELEM] & (1 << (index % NVML_255_MASK_BITS_PER_ELEM)) + +typedef struct +{ + unsigned int mask[NVML_255_MASK_NUM_ELEMS]; //profileId is used and + * the rest of the structure is ignored. + * + * @return + * - \ref NVML_SUCCESS if the Desired Profile was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or structure was NULL + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change the profile number + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * + **/ +nvmlReturn_t DECLDIR nvmlDevicePowerSmoothingActivatePresetProfile(nvmlDevice_t device, + nvmlPowerSmoothingProfile_t *profile); + +/** + * Update the value of a specific profile parameter contained within \ref nvmlPowerSmoothingProfile_v1_t. + * Requires root/admin permissions. + * + * For Blackwell &tm; or newer fully supported devices. + * + * NVML_POWER_SMOOTHING_PROFILE_PARAM_PERCENT_TMP_FLOOR expects a value as a percentage from 00.00-100.00% + * NVML_POWER_SMOOTHING_PROFILE_PARAM_RAMP_UP_RATE expects a value in W/s + * NVML_POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_RATE expects a value in W/s + * NVML_POWER_SMOOTHING_PROFILE_PARAM_RAMP_DOWN_HYSTERESIS expects a value in ms + * + * @param device The identifier of the target device + * @param profile Reference to \ref nvmlPowerSmoothingProfile_v1_t struct + * + * @return + * - \ref NVML_SUCCESS if the Active Profile was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or profile parameter/value was invalid + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change any profile parameters + * - \ref NVML_ERROR_ARGUMENT_VERSION_MISMATCH if the structure version is not supported + * + **/ +nvmlReturn_t DECLDIR nvmlDevicePowerSmoothingUpdatePresetProfileParam(nvmlDevice_t device, + nvmlPowerSmoothingProfile_t *profile); +/** + * Enable or disable the Power Smoothing Feature. + * Requires root/admin permissions. + * + * For Blackwell &tm; or newer fully supported devices. + * + * See \ref nvmlEnableState_t for details on allowed states + * + * @param device The identifier of the target device + * @param state Reference to \ref nvmlPowerSmoothingState_v1_t + * + * @return + * - \ref NVML_SUCCESS if the feature state was successfully set + * - \ref NVML_ERROR_INVALID_ARGUMENT if device is invalid or state is NULL + * - \ref NVML_ERROR_NO_PERMISSION if user does not have permission to change feature state + * - \ref NVML_ERROR_NOT_SUPPORTED if this feature is not supported by the device + * + **/ +nvmlReturn_t DECLDIR nvmlDevicePowerSmoothingSetState(nvmlDevice_t device, + nvmlPowerSmoothingState_t *state); +/** @} */ // @defgroup + +/** + * Retrieves the counts of SRAM unique uncorrected ECC errors + * + * For Blackwell &tm; or newer fully supported devices. + * + * Reads SRAM unique uncorrected ECC error counts. The total number of unique errors is returned by + * \a errorCounts->entryCount. Error counts are returned as an array of in the caller-supplied buffer pointed at by + * \a errorCounts->entries. Each error count entry holds the location/address of the unique error, the error count and + * whether the error is parity or not. + * + * To read SRAM unique uncorrected ECC error counts, first determine the size of buffer required to hold the error + * counts by invoking the function with \a errorCounts->entries set to NULL. The required array size is returned in + * \a errorCounts->entryCount. The caller should allocate a buffer of size "errorCounts->entryCount * + * sizeof(nvmlEccSramUniqueUncorrectedErrorCounts_t)". Invoke the function again with the allocated buffer passed in + * \a errorCounts->entries. This time \a errorCounts->entryCount will be taken as the entry array size that caller + * allocates for \a errorCounts->entries. + * + * On successful return of the second query, the function updates \a errorCounts->entries with all unique errors. This + * may fail if \a errorCounts->entryCount is smaller than the actual number of unique errors. This can happen in cases + * like new errors occur since the previous query of \a errorCounts->entryCount. No matter the query succeeds or not, + * the latest number of unique errors will be returned in \a errorCounts->entryCount. + * + * @note The query is only supported when ECC mode is enabled. + * + * @param device The identifier of the target device + * @param errorCounts Pointer to caller-supplied array which returns the unique error count entries + * + * @return + * - \ref NVML_SUCCESS if \a utilization has been populated + * - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized + * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a errorCounts->entryCount is NULL + * - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature or ECC mods is not enabled + * - \ref NVML_ERROR_INSUFFICIENT_SIZE if the allocated error entry array is not big enough + * - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible + * - \ref NVML_ERROR_UNKNOWN on any unexpected error + */ +nvmlReturn_t DECLDIR nvmlDeviceGetSramUniqueUncorrectedEccErrorCounts(nvmlDevice_t device, + nvmlEccSramUniqueUncorrectedErrorCounts_t *errorCounts); + +/** + * NVML API versioning support + */ + +#ifdef NVML_NO_UNVERSIONED_FUNC_DEFS +nvmlReturn_t DECLDIR nvmlInit(void); +nvmlReturn_t DECLDIR nvmlDeviceGetCount(unsigned int *deviceCount); +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByIndex(unsigned int index, nvmlDevice_t *device); +nvmlReturn_t DECLDIR nvmlDeviceGetHandleByPciBusId(const char *pciBusId, nvmlDevice_t *device); +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfo(nvmlDevice_t device, nvmlPciInfo_t *pci); +nvmlReturn_t DECLDIR nvmlDeviceGetPciInfo_v2(nvmlDevice_t device, nvmlPciInfo_t *pci); +nvmlReturn_t DECLDIR nvmlDeviceGetNvLinkRemotePciInfo(nvmlDevice_t device, unsigned int link, nvmlPciInfo_t *pci); +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures_v2(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); +nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures_v3(nvmlDevice_t device, nvmlGridLicensableFeatures_t *pGridLicensableFeatures); +nvmlReturn_t DECLDIR nvmlDeviceRemoveGpu(nvmlPciInfo_t *pciInfo); +nvmlReturn_t DECLDIR nvmlEventSetWait(nvmlEventSet_t set, nvmlEventData_t * data, unsigned int timeoutms); +nvmlReturn_t DECLDIR nvmlDeviceGetAttributes(nvmlDevice_t device, nvmlDeviceAttributes_t *attributes); +nvmlReturn_t DECLDIR nvmlComputeInstanceGetInfo(nvmlComputeInstance_t computeInstance, nvmlComputeInstanceInfo_t *info); +nvmlReturn_t DECLDIR nvmlDeviceGetComputeRunningProcesses(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v1_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetComputeRunningProcesses_v2(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v2_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetGraphicsRunningProcesses(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v1_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetGraphicsRunningProcesses_v2(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v2_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v1_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses_v2(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v2_t *infos); +nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstancePossiblePlacements(nvmlDevice_t device, unsigned int profileId, nvmlGpuInstancePlacement_t *placements, unsigned int *count); +nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseInfo(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuLicenseInfo_t *licenseInfo); +nvmlReturn_t DECLDIR nvmlDeviceGetDriverModel(nvmlDevice_t device, nvmlDriverModel_t *current, nvmlDriverModel_t *pending); +#endif // #ifdef NVML_NO_UNVERSIONED_FUNC_DEFS + +#if defined(NVML_NO_UNVERSIONED_FUNC_DEFS) +// We don't define APIs to run new versions if this guard is present so there is +// no need to undef +#elif defined(__NVML_API_VERSION_INTERNAL) +#undef nvmlDeviceGetGraphicsRunningProcesses +#undef nvmlDeviceGetComputeRunningProcesses +#undef nvmlDeviceGetMPSComputeRunningProcesses +#undef nvmlDeviceGetAttributes +#undef nvmlComputeInstanceGetInfo +#undef nvmlEventSetWait +#undef nvmlDeviceGetGridLicensableFeatures +#undef nvmlDeviceRemoveGpu +#undef nvmlDeviceGetNvLinkRemotePciInfo +#undef nvmlDeviceGetPciInfo +#undef nvmlDeviceGetCount +#undef nvmlDeviceGetHandleByIndex +#undef nvmlDeviceGetHandleByPciBusId +#undef nvmlInit +#undef nvmlBlacklistDeviceInfo_t +#undef nvmlGetBlacklistDeviceCount +#undef nvmlGetBlacklistDeviceInfoByIndex +#undef nvmlDeviceGetGpuInstancePossiblePlacements +#undef nvmlVgpuInstanceGetLicenseInfo +#undef nvmlDeviceGetDriverModel +#undef nvmlDeviceSetPowerManagementLimit + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/var/pkgs/cuda/13.0/targets/x86_64-linux/lib/stubs/libnvidia-ml.a b/var/pkgs/cuda/13.0/targets/x86_64-linux/lib/stubs/libnvidia-ml.a new file mode 100644 index 0000000000000000000000000000000000000000..2bbacd8fd8f49767e01c9adbd66d2a32416a4a4f GIT binary patch literal 557156 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

>=Uw>jTk=~I4@dzkZgi(g?ppXWSi-Q;9E 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 Pk&=I}CI9=srTPB{Z_=_5 literal 0 HcmV?d00001 diff --git a/var/pkgs/ipxe/bootx64.efi b/var/pkgs/ipxe/bootx64.efi new file mode 100644 index 0000000000000000000000000000000000000000..3dc370ea5f827c341ddc2817d39f911113b4a8ce GIT binary patch literal 959224 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

|kQ__px)+NKW2GxmIVWwF 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

oG1e=k-{5`_ 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∨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 z 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 PoA&zK3E%xg=e*Z_W;evv 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

AJh#vZ1~5=>ir^cm8fso#{U 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�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 f;hnCL^nZLOimj$+OWFV5;hVB*r=3=T- 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%0A<6iYMA^Ps9T+53_ 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

>xkXIS(v9vyMsRFqRHGEGQ+7Of9E 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

  • {fM&tZ?QIj4jpjD)e_0XbF0Ma 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

    QSzt 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

    a9qg@j2ePX=y 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 z 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 Yr4xVRh>Rv7B*X3h|FmG`#vl^>LHwr_C;$Ke literal 0 HcmV?d00001 diff --git a/var/pkgs/scripts/init.sh b/var/pkgs/scripts/init.sh new file mode 100644 index 0000000..859de7e --- /dev/null +++ b/var/pkgs/scripts/init.sh @@ -0,0 +1,751 @@ +#!/bin/bash +# ============================================================================ +# Sun HPC 系统初始化脚本 +# 功能:系统安装完成后自动配置 HPC 计算节点环境 +# 版本:1.0 +# ============================================================================ + +set -e + +# ============================================================================ +# 配置变量(根据实际环境修改) +# ============================================================================ + +# 日志文件 +LOG_FILE="/var/log/sunhpc-init.log" + +FRONTEND_IP='172.16.9.254' + +# HTTP 服务器地址 +HTTP_SERVER="http://${FRONTEND_IP}" + +# YUM 仓库配置 +YUM_REPO_NAME="sunhpc-local" +YUM_REPO_BASEURL="${HTTP_SERVER}/rockylinux/9.7" +YUM_REPO_GPGCHECK=0 + +# 主机名映射文件(在 HTTP 服务器上) +HOSTNAME_MAP_URL="${HTTP_SERVER}/ks/hostname-map.txt" + +# MOTD 文件 URL +MOTD_URL="${HTTP_SERVER}/ks/motd" + +# NTP 服务器 +NTP_SERVER="ntp.aliyun.com" + +# DNS 服务器 +DNS_SERVERS="114.114.114.114 223.5.5.5" + +# ============================================================================ +# 颜色输出函数 +# ============================================================================ + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE +} + +log_step() { + echo -e "${BLUE}[STEP]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE +} + +# ============================================================================ +# 基础环境准备 +# ============================================================================ + +init_log() { + # 创建日志文件 + touch $LOG_FILE + chmod 644 $LOG_FILE + log_info "==========================================" + log_info "Sun HPC Node Initialization Started" + log_info "==========================================" +} + +check_network() { + log_step "Checking network connectivity..." + + # 测试网络连接 + if ping -c 1 -W 3 $FRONTEND_IP &>/dev/null; then + log_info "Network connectivity: OK" + return 0 + else + log_warn "Cannot reach HTTP server, will retry later" + return 1 + fi +} + +# ============================================================================ +# 1. 创建 .sunhpc-release 文件 +# ============================================================================ + +create_release_file() { + log_step "Creating .sunhpc-release file..." + + cat > /.sunhpc-release << EOF +Sun HPC Platform Release 1.0 +Build Date: $(date '+%Y-%m-%d %H:%M:%S') +Hostname: $(hostname) +Kernel: $(uname -r) +Architecture: $(uname -m) +EOF + + chmod 644 /.sunhpc-release + log_info "Created /.sunhpc-release file" +} + +# ============================================================================ +# 2. 配置主机名和 /etc/hosts +# ============================================================================ + +configure_hostname() { + log_step "Configuring hostname and /etc/hosts..." + + local mac=$(ip link show | grep -oP 'ether \K[0-9a-f:]+' | head -1 | tr '[:upper:]' '[:lower:]') + local hostname="" + + # 从 HTTP 服务器获取主机名映射 + if check_network; then + # 下载主机名映射文件 + local map_file="/tmp/hostname-map.txt" + curl -s -o "$map_file" "$HOSTNAME_MAP_URL" 2>/dev/null + + if [[ -f "$map_file" ]]; then + # 根据 MAC 地址查找主机名 + hostname=$(grep -i "$mac" "$map_file" | awk '{print $2}' | head -1) + + # 如果没有找到,根据 IP 最后一段生成 + if [[ -z "$hostname" ]]; then + local ip_addr=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1) + local ip_last=$(echo $ip_addr | awk -F'.' '{print $4}') + hostname="cn$(printf "%03d" $ip_last)" + log_warn "No hostname mapping for MAC $mac, using generated: $hostname" + fi + else + log_warn "Cannot download hostname map, using default" + local ip_addr=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1) + local ip_last=$(echo $ip_addr | awk -F'.' '{print $4}') + hostname="cn$(printf "%03d" $ip_last)" + fi + else + # 网络不通时使用默认主机名 + hostname="node-$(hostname -s)" + fi + + # 设置主机名 + hostnamectl set-hostname "$hostname" + log_info "Hostname set to: $hostname" + + # 备份原始 hosts 文件 + cp /etc/hosts /etc/hosts.bak.$(date +%Y%m%d) + + # 构建新的 hosts 文件 + cat > /etc/hosts << EOF +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 + +# Sun HPC Node Configuration +$ip_addr $hostname + +# Management Node +$FRONTEND_IP cluster + +# Optional: Add other compute nodes here +EOF + + # 尝试下载完整的集群 hosts 文件 + if check_network; then + local cluster_hosts="${HTTP_SERVER}/ks/cluster-hosts.txt" + if wget --spider -q "$cluster_hosts" 2>/dev/null; then + wget -q -O /tmp/cluster-hosts.txt "$cluster_hosts" + cat /tmp/cluster-hosts.txt >> /etc/hosts + log_info "Downloaded cluster hosts configuration" + else + log_warn "$cluster_hosts not found on server." + fi + fi + + log_info "Updated /etc/hosts" +} + +# ============================================================================ +# 3. 配置 MOTD (Message of The Day) +# ============================================================================ + +configure_motd() { + log_step "Configuring MOTD..." + + # 备份原始 MOTD + if [[ -f /etc/motd ]]; then + cp /etc/motd /etc/motd.bak.$(date +%Y%m%d) + fi + + # 尝试从服务器下载 MOTD + if check_network; then + if wget --spider -q "$MOTD_URL" 2>/dev/null; then + wget -q -O /etc/motd "$MOTD_URL" + log_info "Downloaded MOTD from server" + else + log_warn "Cannot download MOTD, creating default" + create_default_motd + fi + else + create_default_motd + fi + + chmod 644 /etc/motd +} + +create_default_motd() { + cat > /etc/motd << EOF +=========================================================== + Sun HPC Platform - Compute Node +=========================================================== + Welcome to Sun High Performance Computing Cluster + + System Information: + -------------------- + Hostname....: $(hostname) + IP Address..: $(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1) + OS Version..: $(cat /etc/redhat-release 2>/dev/null || echo "Rocky Linux") + Kernel......: $(uname -r) + Architecture: $(uname -m) + CPU Cores...: $(nproc) + Memory......: $(free -h | awk '/^Mem:/{print $2}') + + Important URLs: + -------------------- + • Documentation : http://172.16.9.254/docs + • Job Submission : http://172.16.9.254/slurm + • Monitoring: http : http://172.16.9.254/monitor + + Slurm Commands: + -------------------- + sinfo - View partition information + squeue - View job queue + srun - Run interactive job + sbatch - Submit batch job + scancel - Cancel job + +=========================================================== + * Unauthorized access is prohibited + * All activities are logged and monitored + * For support: hpc@sun.com or ext. 12345 +=========================================================== +EOF +} + +# ============================================================================ +# 4. 配置 YUM 本地仓库 +# ============================================================================ + +configure_yum_repo() { + log_step "Configuring YUM repository..." + + local repo_file="/etc/yum.repos.d/${YUM_REPO_NAME}.repo" + + # 备份现有 repo 文件 + if [[ -f "$repo_file" ]]; then + cp "$repo_file" "${repo_file}.bak.$(date +%Y%m%d)" + fi + + # 创建仓库配置文件 + cat > "$repo_file" << EOF +[${YUM_REPO_NAME}] +name=Sun HPC Local Repository +baseurl=${YUM_REPO_BASEURL} +enabled=1 +gpgcheck=${YUM_REPO_GPGCHECK} +priority=1 +EOF + + # 如果是 Rocky 8/9,可能需要配置 appstream + if [[ -d "/etc/yum.repos.d" ]]; then + local appstream_repo="/etc/yum.repos.d/${YUM_REPO_NAME}-appstream.repo" + cat > "$appstream_repo" << EOF +[${YUM_REPO_NAME}-appstream] +name=Sun HPC Local AppStream Repository +baseurl=${YUM_REPO_BASEURL}-appstream +enabled=1 +gpgcheck=${YUM_REPO_GPGCHECK} +priority=1 +EOF + fi + + # 清理 YUM 缓存并测试 + yum clean all &>/dev/null + yum makecache &>/dev/null + + if [[ $? -eq 0 ]]; then + log_info "YUM repository configured successfully" + else + log_warn "YUM repository configured but cache generation failed (network may be down)" + fi + + # 显示启用的仓库 + log_info "Enabled repositories:" + yum repolist 2>/dev/null | grep -E "^${YUM_REPO_NAME}" | tee -a $LOG_FILE +} + +# ============================================================================ +# 5. 配置 DNS 解析 +# ============================================================================ + +configure_dns() { + log_step "Configuring DNS resolution..." + + # 备份 resolv.conf + cp /etc/resolv.conf /etc/resolv.conf.bak.$(date +%Y%m%d) 2>/dev/null || true + + # 配置 DNS + cat > /etc/resolv.conf << EOF +# Sun HPC DNS Configuration +nameserver ${DNS_SERVERS%% *} +$(for dns in ${DNS_SERVERS}; do echo "nameserver $dns"; done | tail -n +2) + +# Local domain +search sunhpc.local local +EOF + + # 防止 NetworkManager 覆盖 resolv.conf + if [[ -f /etc/NetworkManager/NetworkManager.conf ]]; then + if ! grep -q "dns=none" /etc/NetworkManager/NetworkManager.conf; then + sed -i '/^\[main\]/a dns=none' /etc/NetworkManager/NetworkManager.conf + systemctl restart NetworkManager 2>/dev/null || true + fi + fi + + log_info "DNS configured: ${DNS_SERVERS}" +} + +# ============================================================================ +# 6. 配置 NTP 时间同步 +# ============================================================================ + +configure_ntp() { + log_step "Configuring NTP time synchronization..." + + # 使用 chrony (Rocky 8/9 默认) + if command -v chronyd &>/dev/null; then + # 备份配置 + cp /etc/chrony.conf /etc/chrony.conf.bak.$(date +%Y%m%d) + + # 配置 chrony + cat > /etc/chrony.conf << EOF +# Sun HPC NTP Configuration +server ${NTP_SERVER} iburst +pool 2.rocky.pool.ntp.org iburst + +# Record the rate at which the system clock gains/losses time. +driftfile /var/lib/chrony/drift + +# Allow the system clock to be stepped in the first three updates +makestep 1.0 3 + +# Enable kernel synchronization of the real-time clock (RTC) +rtcsync + +# Specify file containing keys for NTP authentication +keyfile /etc/chrony.keys + +# Specify directory for log files +logdir /var/log/chrony +EOF + + # 重启 chrony + systemctl restart chronyd &>/dev/null + systemctl enable chronyd &>/dev/null + + log_info "Chrony NTP configured with server: ${NTP_SERVER}" + else + # 使用 ntpd (旧系统) + if command -v ntpd &>/dev/null; then + cat > /etc/ntp.conf << EOF +server ${NTP_SERVER} iburst +restrict default nomodify notrap nopeer noquery +restrict 127.0.0.1 +restrict ::1 +driftfile /var/lib/ntp/drift +EOF + systemctl restart ntpd &>/dev/null + systemctl enable ntpd &>/dev/null + log_info "NTP configured with server: ${NTP_SERVER}" + else + log_warn "No NTP service found (chronyd or ntpd)" + fi + fi +} + +# ============================================================================ +# 7. 配置 SSH 服务 +# ============================================================================ + +configure_ssh() { + log_step "Configuring SSH service..." + + # 备份配置 + cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d) + + # 优化 SSH 配置 + sed -i 's/#PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config + sed -i 's/#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config + sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config + sed -i 's/#UseDNS.*/UseDNS no/' /etc/ssh/sshd_config + sed -i 's/#GSSAPIAuthentication.*/GSSAPIAuthentication no/' /etc/ssh/sshd_config + + # 重启 SSH 服务 + systemctl restart sshd &>/dev/null + + log_info "SSH service configured" +} + +# ============================================================================ +# 8. 配置防火墙 +# ============================================================================ + +configure_firewall() { + log_step "Configuring firewall..." + + # 检查 firewalld 是否运行 + if systemctl is-active firewalld &>/dev/null; then + # 开放常用端口 + firewall-cmd --permanent --add-service=ssh &>/dev/null + firewall-cmd --permanent --add-service=dhcp &>/dev/null + firewall-cmd --permanent --add-port=873/tcp &>/dev/null # rsync + firewall-cmd --permanent --add-port=111/udp &>/dev/null # rpcbind + + # 重新加载 + firewall-cmd --reload &>/dev/null + + log_info "Firewall configured" + else + log_warn "Firewalld not running, skipping configuration" + fi +} + +# ============================================================================ +# 9. 安装常用软件包 +# ============================================================================ + +install_packages() { + log_step "Installing common packages..." + + local packages=( + wget curl vim nano + htop iotop iftop + net-tools bind-utils + telnet nc tcpdump + rsync tree lsof + gcc make autoconf automake + openssl-devel zlib-devel + nfs-utils cifs-utils + ntpdate + ) + + if check_network; then + for pkg in "${packages[@]}"; do + if rpm -q "$pkg" &>/dev/null; then + log_info "Package already installed: $pkg" + else + log_info "Installing package: $pkg" + yum install -y "$pkg" &>> $LOG_FILE || log_warn "Failed to install: $pkg" + fi + done + else + log_warn "Network unavailable, skipping package installation" + fi +} + +# ============================================================================ +# 11. 配置用户环境 +# ============================================================================ + +configure_user_env() { + log_step "Configuring user environment..." + + # 创建共享目录 + mkdir -p /share/{apps,home} + mkdir -p /state/partition1/{tmp,work} + + # 设置权限 + chmod 755 /share + chmod 1777 /state/partition1/tmp + + # 配置全局环境变量 + cat > /etc/profile.d/sunhpc.sh << 'EOF' +# Sun HPC Environment Variables +export SHARE_HOME=/share +export STATE_HOME=/state/partition1 +EOF + + chmod 644 /etc/profile.d/sunhpc.sh + log_info "User environment configured" +} + +# ============================================================================ +# 12. 配置系统优化参数 +# ============================================================================ + +configure_sysctl() { + log_step "Configuring system optimization..." + + cat > /etc/sysctl.d/99-sunhpc.conf << EOF +# Sun HPC System Optimization + +# Network optimization +net.core.rmem_max = 134217728 +net.core.wmem_max = 134217728 +net.ipv4.tcp_rmem = 4096 87380 134217728 +net.ipv4.tcp_wmem = 4096 65536 134217728 +net.core.netdev_max_backlog = 5000 +net.ipv4.tcp_max_syn_backlog = 8192 +net.ipv4.tcp_sack = 1 +net.ipv4.tcp_timestamps = 1 + +# Memory optimization +vm.swappiness = 10 +vm.dirty_ratio = 30 +vm.dirty_background_ratio = 5 +vm.vfs_cache_pressure = 50 + +# File system +fs.file-max = 1048576 +fs.inotify.max_user_watches = 1048576 + +# Process scheduler +kernel.sched_autogroup_enabled = 0 +kernel.sched_migration_cost_ns = 5000000 +EOF + + sysctl -p /etc/sysctl.d/99-sunhpc.conf &>/dev/null + log_info "System optimization configured" +} + +# ============================================================================ +# 13. 配置系统限制 +# ============================================================================ + +configure_limits() { + log_step "Configuring system limits..." + + cat > /etc/security/limits.d/99-sunhpc.conf << EOF +# Sun HPC System Limits +* soft nofile 1048576 +* hard nofile 1048576 +* soft nproc 131072 +* hard nproc 131072 +* soft memlock unlimited +* hard memlock unlimited +root soft nofile 1048576 +root hard nofile 1048576 +EOF + + log_info "System limits configured" +} + +# ============================================================================ +# 14. 配置定时任务 +# ============================================================================ + +configure_crontab() { + log_step "Configuring cron jobs..." + + cat > /etc/cron.d/sunhpc << EOF +# Sun HPC Cron Jobs + +# Sync time every hour +0 * * * * root /usr/sbin/chronyc -a makestep &>/dev/null + +# Clean old logs daily +0 2 * * * root find /var/log -name "*.log" -mtime +30 -delete 2>/dev/null + +# Report node status every 5 minutes +*/5 * * * * root /usr/local/bin/node-status-report &>/dev/null +EOF + + chmod 644 /etc/cron.d/sunhpc + log_info "Cron jobs configured" +} + +# ============================================================================ +# 15. 创建节点状态上报脚本 +# ============================================================================ + +create_report_script() { + log_step "Creating node status report script..." + + cat > /usr/local/bin/node-status-report << 'EOF' +#!/bin/bash +# Node status report script for Sun HPC + +HTTP_SERVER="http://172.16.9.254" +NODE_NAME=$(hostname) +IP_ADDR=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1) +LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1) +MEM_TOTAL=$(free -g | awk '/^Mem:/{print $2}') +MEM_USED=$(free -g | awk '/^Mem:/{print $3}') +DISK_USED=$(df -h / | awk 'NR==2{print $5}' | sed 's/%//') +SLURM_STATUS=$(systemctl is-active slurm-slurmd 2>/dev/null || echo "unknown") + +# Build status JSON +STATUS_JSON="{\"node\":\"$NODE_NAME\",\"ip\":\"$IP_ADDR\",\"load\":$LOAD_AVG,\"mem_total\":$MEM_TOTAL,\"mem_used\":$MEM_USED,\"disk_used\":$DISK_USED,\"slurm\":\"$SLURM_STATUS\",\"timestamp\":\"$(date -Iseconds)\"}" + +# Send to management node +curl -s -X POST -H "Content-Type: application/json" -d "$STATUS_JSON" ${HTTP_SERVER}/api/node-status &>/dev/null +EOF + + chmod +x /usr/local/bin/node-status-report + log_info "Node status report script created" +} + +# ============================================================================ +# 16. 配置日志轮转 +# ============================================================================ + +configure_logrotate() { + log_step "Configuring log rotation..." + + cat > /etc/logrotate.d/sunhpc << EOF +/var/log/sunhpc-init.log { + daily + rotate 30 + compress + delaycompress + missingok + notifempty + create 644 root root +} +EOF + + log_info "Log rotation configured" +} + +# ============================================================================ +# 17. 清理临时文件 +# ============================================================================ + +cleanup() { + log_step "Cleaning up temporary files..." + + # 删除临时文件 + rm -f /tmp/hostname-map.txt 2>/dev/null + rm -f /tmp/cluster-hosts.txt 2>/dev/null + + # 清除 YUM 缓存 + yum clean all &>/dev/null + + log_info "Cleanup completed" +} + +# ============================================================================ +# 18. 生成初始化完成报告 +# ============================================================================ + +generate_report() { + log_step "Generating initialization report..." + + cat > /root/init-report.txt << EOF +=========================================== +Sun HPC Node Initialization Report +=========================================== +Init Time: $(date '+%Y-%m-%d %H:%M:%S') +Hostname: $(hostname) +IP Address: $(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1) +MAC Address: $(ip link show | grep -oP 'ether \K[0-9a-f:]+' | head -1) + +Services Status: +- NetworkManager: $(systemctl is-active NetworkManager) +- chronyd: $(systemctl is-active chronyd 2>/dev/null || echo "stopped") +- sshd: $(systemctl is-active sshd) +- slurm-slurmd: $(systemctl is-active slurm-slurmd 2>/dev/null || echo "stopped") +- firewalld: $(systemctl is-active firewalld) + +YUM Repositories: +$(yum repolist) + +Files Created: +- /.sunhpc-release +- /etc/hosts (updated) +- /etc/motd (updated) +- /etc/yum.repos.d/sunhpc-local.repo +- /etc/chrony.conf (updated) +- /etc/security/limits.d/99-sunhpc.conf +- /etc/sysctl.d/99-sunhpc.conf + +=========================================== +EOF + + cat /root/init-report.txt >> $LOG_FILE + log_info "Initialization report saved to /root/init-report.txt" +} + +# ============================================================================ +# 主函数 +# ============================================================================ + +main() { + log_info "Starting Sun HPC node initialization..." + + # 执行所有初始化步骤 + init_log + check_network + create_release_file + configure_hostname + configure_motd + configure_yum_repo + configure_dns + configure_ntp + configure_ssh + configure_firewall + install_packages + configure_slurm + configure_user_env + configure_sysctl + configure_limits + configure_crontab + create_report_script + configure_logrotate + cleanup + generate_report + + log_info "==========================================" + log_info "Sun HPC node initialization completed!" + log_info "==========================================" + + # 显示关键信息 + echo "" + echo -e "${GREEN}=== Initialization Complete ===${NC}" + echo -e "Hostname: $(hostname)" + echo -e "Release file: $(cat /.sunhpc-release | head -1)" + echo -e "Log file: $LOG_FILE" + echo -e "Report: /root/init-report.txt" + echo "" +} + +# ============================================================================ +# 脚本入口 +# ============================================================================ + +# 检查是否需要重启 +if [[ "$1" == "--reboot" ]]; then + main + log_info "Rebooting in 5 seconds..." + sleep 5 + reboot +else + main + log_info "Initialization completed. You may reboot if needed." +fi diff --git a/var/pkgs/scripts/ipxe.sh b/var/pkgs/scripts/ipxe.sh new file mode 100644 index 0000000..79652a7 --- /dev/null +++ b/var/pkgs/scripts/ipxe.sh @@ -0,0 +1,21 @@ +#!ipxe + +:main_menu +menu iPXE boot menu + +item rockylinux Install Rockylinux 9.7 +item local Boot from Local Disk + +choose --default rockylinux --timeout 5000 selected || goto local + +:rockylinux +echo Booting Rockylinux from networking +kernel http://172.16.9.254/linux/rockylinux/9.7/images/pxeboot/vmlinuz \ + net.ifnames=0 biosdevname=0 inst.sshd \ + inst.repo=http://172.16.9.254/linux/rockylinux/9.7 \ + inst.ks=http://172.16.9.254/linux/ks/rhel.ks +initrd http://172.16.9.254/linux/rockylinux/9.7/images/pxeboot/initrd.img +boot + +:local +exit diff --git a/var/pkgs/scripts/rhel.ks b/var/pkgs/scripts/rhel.ks new file mode 100644 index 0000000..a401bff --- /dev/null +++ b/var/pkgs/scripts/rhel.ks @@ -0,0 +1,77 @@ +graphical +timezone Asia/Shanghai --utc +keyboard --xlayouts="us" +lang en_US.UTF-8 +selinux --disabled + +url --url='http://172.16.9.254/linux/rockylinux/9.7' + +network --bootproto=dhcp --device=link --ipv6=auto --activate + +# Partition clearing information +# zerombr +# clearpart --all --initlabel +# ignoredisk --only-use=sda +# part /boot --fstype="xfs" --ondisk=sda --size=1024 +# part swap --fstype="swap" --ondisk=sda --size=4096 +# part / --fstype="xfs" --ondisk=sda --size=97278 +# part /home --fstype="xfs" --ondisk=sda --size=20480 + +# autopart --type=lvm +# autopart --type=plain +# autopart --nohome +# autopart --noswap + + +%include /tmp/diskinfo + +%packages +@^minimal-environment +@development +@standard +vim +wget +curl +autofs +nfs-utils +nfs4-acl-tools +sssd-nfs-idmap +%end + +rootpw --plaintext "admin_b101" +user --name=dell --plaintext --password="admin_b101" --gecos="dell" +reboot + +%pre --interpreter=/bin/bash +if [ -d /sys/firmware/efi ]; then + cat > /tmp/diskinfo < /tmp/diskinfo <