├── .appveyor.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── Makefile.win ├── README.md ├── TODO ├── fetch-opencl-dev-win.cmd ├── legalcode.txt ├── make.cmd ├── man1 └── clinfo.1 ├── new-version.sh └── src ├── clinfo.c ├── ctx_prop.h ├── error.h ├── ext.h ├── fmtmacros.h ├── info_loc.h ├── info_ret.h ├── memory.h ├── ms_support.h ├── opt_out.h └── strbuf.h /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 2.2.18.03.22-{build} 2 | 3 | image: Visual Studio 2015 4 | 5 | shallow_clone: true 6 | 7 | platform: 8 | - x86 9 | - x64 10 | 11 | init: 12 | - cmd: C:\"Program Files (x86)"\"Microsoft Visual Studio 12.0"\VC\vcvarsall.bat %PLATFORM% 13 | 14 | install: 15 | - cmd: fetch-opencl-dev-win.cmd %PLATFORM% 16 | 17 | build_script: 18 | - cmd: make.cmd 19 | 20 | test_script: 21 | - cmd: clinfo 22 | 23 | artifacts: 24 | - path: clinfo.exe 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | clinfo 2 | .*.swp 3 | *.o 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | - osx 4 | arch: 5 | - amd64 6 | - ppc64le 7 | 8 | dist: trusty 9 | addons: 10 | apt: 11 | sources: 12 | - sourceline: "deb http://archive.ubuntu.com/ubuntu trusty universe" 13 | packages: 14 | - ocl-icd-opencl-dev 15 | 16 | language: c 17 | compiler: 18 | - gcc 19 | - clang 20 | 21 | script: make && ./clinfo 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | clinfo by Giuseppe Bilotta 2 | 3 | To the extent possible under law, the person who associated CC0 with 4 | clinfo has waived all copyright and related or neighboring rights 5 | to clinfo. 6 | 7 | You should have received a copy of the CC0 legalcode along with this 8 | work. If not, see 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # An interesting trick to run a shell command: 2 | # GNU Make uses $(shell cmd), whereas 3 | # BSD make use $(var:sh), where ${var} holds the command 4 | # We can run a shell command on both by storing the value of the command 5 | # in a variable var and then using $(shell $(var))$(var:sh). 6 | 7 | # To detect the operating system it's generally sufficient to run `uname -s`, 8 | # but this way Android is detected as Linux. Android can be detected by `uname -o`, 9 | # but not all `uname` implementation even have the `-o` flag. 10 | # So we first detect the kernel, and then if it's Linux we use the -o detection 11 | # to find if this is Android, otherwise falling back to whatever the kernel was. 12 | 13 | OS.exec = t="$$(uname -s)" ; [ Linux = "$$t" ] && uname -o || printf "%s\n" "$$t" 14 | OS ?= $(shell $(OS.exec))$(OS.exec:sh) 15 | # Force expansion 16 | OS := $(OS) 17 | 18 | # Headers 19 | 20 | PROG = clinfo 21 | MAN = man1/$(PROG).1 22 | 23 | HDR = src/error.h \ 24 | src/ext.h \ 25 | src/ctx_prop.h \ 26 | src/fmtmacros.h \ 27 | src/memory.h \ 28 | src/ms_support.h \ 29 | src/info_loc.h \ 30 | src/info_ret.h \ 31 | src/opt_out.h \ 32 | src/strbuf.h 33 | 34 | VPATH = src 35 | 36 | # Make it easier to find the OpenCL headers on systems 37 | # that don't ship them by default; the user can just clone 38 | # them on a parallel directory from the official repository 39 | CPPFLAGS += -I../OpenCL-Headers 40 | 41 | CFLAGS ?= -g -pedantic -Werror 42 | CFLAGS += -std=c99 -Wall -Wextra 43 | 44 | SPARSE ?= sparse 45 | SPARSEFLAGS=-Wsparse-all -Wno-decl 46 | 47 | # BSD make does not define RM 48 | RM ?= rm -f 49 | 50 | # Installation paths and modes 51 | PREFIX ?= /usr/local 52 | BINDIR ?= $(PREFIX)/bin 53 | BINMODE ?= 555 54 | MANDIR ?= $(PREFIX)/man 55 | MAN1DIR ?= $(MANDIR)/man1 56 | MANMODE ?= 444 57 | 58 | ANDROID_VENDOR_PATH ?= ${ANDROID_ROOT}/vendor/lib64 59 | 60 | LDFLAGS_Android += -Wl,-rpath-link=${ANDROID_VENDOR_PATH} -L${ANDROID_VENDOR_PATH} 61 | 62 | LDFLAGS += $(LDFLAGS_$(OS)) 63 | 64 | # Common library includes 65 | LDLIBS__common = -lOpenCL -ldl 66 | 67 | # OS-specific library includes 68 | LDLIBS_Darwin = -framework OpenCL 69 | LDLIBS_Darwin_exclude = -lOpenCL 70 | 71 | LDLIBS += $(LDLIBS_${OS}) $(LDLIBS__common:$(LDLIBS_${OS}_exclude)=) 72 | 73 | # The main target is the executable, which is normally called clinfo. 74 | # However, on Android, due to the lack of support for RPATH, clinfo 75 | # needs an approprite LD_LIBRARY_PATH, so we map `clinfo` to a shell script 76 | # that sets LD_LIBRARY_PATH and invokes the real program, which is now called 77 | # clinfo.real. 78 | # 79 | # Of course on Android we need to buid both, but not on other OSes 80 | 81 | 82 | EXT.Android = .real 83 | EXENAME = $(PROG)$(EXT.${OS}) 84 | 85 | TARGETS.Android = $(PROG) 86 | TARGETS = $(EXENAME) $(TARGETS.${OS}) 87 | 88 | all: $(TARGETS) 89 | 90 | # 91 | # Targets to actually build the stuff 92 | # 93 | # Many versions of make define a LINK.c as a synthetic rule to link 94 | # C object files. In case it's not defined already, propose our own: 95 | LINK.c ?= $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) 96 | 97 | # Recipe for the actual executable, either clinfo (non-Android) 98 | # or clinfo.real (on Androd) 99 | $(EXENAME): $(PROG).o 100 | $(LINK.c) -o $@ $< $(LDLIBS) 101 | 102 | $(PROG).o: $(PROG).c $(HDR) 103 | 104 | # For Android: create a wrapping shell script to run 105 | # clinfo with the appropriate LD_LIBRARY_PATH. 106 | $(OS:Android=)$(PROG): 107 | @echo '#!/bin/sh' > $@ 108 | @echo 'wrapperdir="$$(dirname "$$(readlink -n -f "$$(command -v "$$0")")")"' >> $@ 109 | @echo 'LD_LIBRARY_PATH="${ANDROID_VENDOR_PATH}:${ANDROID_VENDOR_PATH}/egl:$$LD_LIBRARY_PATH" $${wrapperdir}/$(EXENAME) "$$@"' >> $@ 110 | chmod +x $@ 111 | 112 | clean: 113 | $(RM) $(PROG).o $(TARGETS) 114 | 115 | install: all 116 | install -d $(DESTDIR)$(BINDIR) 117 | install -d $(DESTDIR)$(MAN1DIR) 118 | 119 | install -p -m $(BINMODE) $(PROG) $(DESTDIR)$(BINDIR)/$(PROG) 120 | install -p -m $(MANMODE) $(MAN) $(DESTDIR)$(MAN1DIR) 121 | 122 | sparse: $(PROG).c 123 | $(SPARSE) $(CPPFLAGS) $(CFLAGS) $(SPARSEFLAGS) $^ 124 | 125 | show: 126 | @printf 'OS=%s\n' "${OS}" 127 | @printf 'CFLAGS=%s\n' "${CFLAGS}" 128 | @printf 'CPPFLAGS=%s\n' "${CPPFLAGS}" 129 | @printf 'LDFLAGS=%s\n' "${LDFLAGS}" 130 | @printf 'LDLIBS=%s\n' "${LDLIBS}" 131 | @printf 'TARGETS=%s\n' "${TARGETS}" 132 | 133 | 134 | 135 | .PHONY: clean sparse install show 136 | -------------------------------------------------------------------------------- /Makefile.win: -------------------------------------------------------------------------------- 1 | # TODO FIXME find a better way to detect the directory to use 2 | # for OpenCL development files 3 | !IF "$(OPENCLDIR)" == "" 4 | OPENCLDIR = $(INTELOCLSDKROOT) 5 | !ENDIF 6 | !IF "$(OPENCLDIR)" == "" 7 | OPENCLDIR = $(AMDAPPSDKROOT) 8 | !ENDIF 9 | !IF "$(OPENCLDIR)" == "" 10 | OPENCLDIR = $(MAKEDIR) 11 | !ENDIF 12 | !IF "$(OPENCLDIR)" == "" 13 | OPENCLDIR = . 14 | !ENDIF 15 | !MESSAGE OpenCL dir: $(OPENCLDIR) 16 | 17 | 18 | HDR = src/error.h \ 19 | src/ext.h \ 20 | src/ctx_prop.h \ 21 | src/fmtmacros.h \ 22 | src/memory.h \ 23 | src/ms_support.h \ 24 | src/info_loc.h \ 25 | src/info_ret.h \ 26 | src/opt_out.h \ 27 | src/strbuf.h 28 | 29 | CFLAGS = /GL /Ox /W4 /Zi /I"$(OPENCLDIR)\include" /nologo 30 | LIBS = libOpenCL.a 31 | 32 | # TODO there's most likely a better way to do the multiarch 33 | # switching 34 | !IF "$(PROCESSOR_ARCHITECTURE)" == "AMD64" 35 | ARCH=64 36 | !ELSE 37 | ARCH=32 38 | !ENDIF 39 | 40 | # Platform=x64 in the 64-bit cross-platform build of my VS 41 | !IF "$(PLATFORM)" == "x64" || "$(PLATFORM)" == "X64" 42 | ARCH=64 43 | !ELSE IF "$(PLATFORM)" == "x86" || "$(PLATFORM)" == "X86" 44 | ARCH=32 45 | !ENDIF 46 | 47 | !MESSAGE Building for $(ARCH)-bit (processor architecture: $(PROCESSOR_ARCHITECTURE), platform: $(PLATFORM)) 48 | 49 | LIBPATH32 = /LIBPATH:"$(OPENCLDIR)\lib" /LIBPATH:"$(OPENCLDIR)\lib\x86" 50 | LIBPATH64 = /LIBPATH:"$(OPENCLDIR)\lib\x64" /LIBPATH:"$(OPENCLDIR)\lib\x86_64" /LIBPATH:"$(OPENCLDIR)\lib\x86_amd64" 51 | 52 | # And since we can't do $(LIBPATH$(ARCH)) with nmake ... 53 | !IF "$(ARCH)" == "64" 54 | LINKOPTS = /LTCG $(LIBPATH64) /nologo 55 | !ELSE 56 | LINKOPTS = /LTCG $(LIBPATH32) /nologo 57 | !ENDIF 58 | 59 | clinfo.exe: clinfo.obj 60 | link $(LINKOPTS) $(LIBS) clinfo.obj /out:clinfo.exe 61 | 62 | clinfo.obj: src/clinfo.c $(HDR) 63 | $(CC) $(CFLAGS) /c src/clinfo.c /Foclinfo.obj 64 | 65 | clean: 66 | del /F /Q clinfo.exe clinfo.obj 67 | 68 | .PHONY: clean 69 | 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is this? 2 | 3 | clinfo is a simple command-line application that enumerates all possible 4 | (known) properties of the OpenCL platform and devices available on the 5 | system. 6 | 7 | Inspired by AMD's program of the same name, it is coded in pure C and it 8 | tries to output all possible information, including those provided by 9 | platform-specific extensions, trying not to crash on unsupported 10 | properties (e.g. 1.2 properties on 1.1 platforms). 11 | 12 | # Usage 13 | 14 | clinfo [options...] 15 | 16 | Common used options are `-l` to show a synthetic summary of the 17 | available devices (without properties), and `-a`, to try and show 18 | properties even if `clinfo` would otherwise think they aren't supported 19 | by the platform or device. 20 | 21 | Refer to the man page for further information. 22 | 23 | ## Use cases 24 | 25 | * verify that your OpenCL environment is set up correctly; 26 | if `clinfo` cannot find any platform or devices (or fails to load 27 | the OpenCL dispatcher library), chances are high no other OpenCL 28 | application will run; 29 | * verify that your OpenCL _development_ environment is set up 30 | correctly: if `clinfo` fails to build, chances are high no 31 | other OpenCL application will build; 32 | * explore/report the actual properties of the available device(s). 33 | 34 | ## Segmentation faults 35 | 36 | Some faulty OpenCL platforms may cause `clinfo` to crash. There isn't 37 | much `clinfo` itself can do about it, but you can try and isolate the 38 | platform responsible for this. On POSIX systems, you can generally find 39 | the platform responsible for the fault with the following one-liner: 40 | 41 | find /etc/OpenCL/vendors/ -name '*.icd' | while read OPENCL_VENDOR_PATH ; do clinfo -l > /dev/null ; echo "$? ${OPENCL_VENDOR_PATH}" ; done 42 | 43 | ## Missing information 44 | 45 | If you know of device properties that are exposed in OpenCL (either as core 46 | properties or as extensions), but are not shown by `clinfo`, please [open 47 | an issue](https://github.com/Oblomov/clinfo/issues) providing as much 48 | information as you can. Patches and pull requests accepted too. 49 | 50 | 51 | # Building 52 | 53 | Build status on Travis 57 | 58 | Building requires an OpenCL SDK (or at least OpenCL headers and 59 | development files), and the standard build environment for the platform. 60 | No special build system is used (autotools, CMake, meson, ninja, etc), 61 | as I feel adding more dependencies for such a simple program would be 62 | excessive. Simply running `make` at the project root should work. 63 | 64 | ## Android support 65 | 66 | ### Local build via Termux 67 | 68 | One way to build the application on Android, pioneered by 69 | [truboxl][truboxl] and described [here][issue46], requires the 70 | installation of [Termux][termux], that can be installed via Google Play 71 | as well as via F-Droid. 72 | 73 | [truboxl]: https://github.com/truboxl 74 | [issue46]: https://github.com/Oblomov/clinfo/issues/46 75 | [termux]: https://termux.com/ 76 | 77 | Inside Termux, you will first need to install some common tools: 78 | 79 | pkg install git make clang -y 80 | 81 | 82 | You will also need to clone the `clinfo` repository, and fetch the 83 | OpenCL headers (we'll use the official `KhronosGroup/OpenCL-Headers` 84 | repository for that): 85 | 86 | git clone https://github.com/Oblomov/clinfo 87 | git clone https://github.com/KhronosGroup/OpenCL-Headers 88 | 89 | (I prefer doing this from a `src` directory I have created for 90 | development, but as long as `clinfo` and `OpenCL-Headers` are sibling 91 | directories, the headers will be found. If not, you will have to 92 | override `CPPFLAGS` with e.g. `export CPPFLAGS=-I/path/to/where/headers/are` 93 | before running `make`. 94 | Of course `/path/to/where/headers/are` should be replaced with the actual 95 | path to which the `OpenCL-Headers` repository was cloned.) 96 | 97 | You can then `cd clinfo` and build the application. You can try simply 98 | running `make` since Android should be autodetected now, buf it 99 | this fails you can also force the detectio with 100 | 101 | make OS=Android 102 | 103 | If linking fails due to a missing `libOpenCL.so`, then your Android 104 | machine probably doesn't support OpenCL. Otherwise, you should have a 105 | working `clinfo` you can run. You will most probably need to set 106 | `LD_LIBRARY_PATH` to let the program know where the OpenCL library is at 107 | runtime: you will need at least `${ANDROID_ROOT}/vendor/lib64`, but on 108 | some machine the OpenCL library actually maps to a different library 109 | (e.g., on one of my systems, it maps to the GLES library, which is in a 110 | different subdirectory). 111 | 112 | Due to this requirement, on Android the actual binary is now called 113 | `clinfo.real`, and the produced `clinfo` is just a shell script that 114 | will run the actual binary after setting `LD_LIBRARY_PATH`. If this 115 | is not sufficient on your installation, please open an issue and we'll 116 | try to improve the shell script to cover your use case as well. 117 | 118 | ## MacOS support 119 | 120 | clinfo should build without issues out of the box on most macOS installations 121 | (starting from OS X v10.6). 122 | In contrast to most other operating systems, 123 | the macOS system OpenCL library only supports Apple's own OpenCL platform. 124 | 125 | To use other platforms such as [PoCL](https://portablecl.org), 126 | it is necessary to install an alternative OpenCL library that works as an ICD loader, 127 | such as [Homebrew](https://brew.sh)'s [ocl-icd](https://formulae.brew.sh/formula/ocl-icd). 128 | 129 | To build `clinfo` using the Homebrew OpenCL library instead of the macOS system library, 130 | you can use 131 | 132 | make OS=Homebrew 133 | 134 | 135 | ## Windows support 136 | 137 | The application can usually be built in Windows too (support for which 138 | required way more time than I should have spent, really, but I digress), 139 | by running `make` in a Developer Command Prompt for Visual Studio, 140 | provided an OpenCL SDK (such as the Intel or AMD one) is installed. 141 | 142 | Precompiled Windows executable are available as artefacts of the 143 | AppVeyor CI. 144 | 145 | 146 | 147 | 148 | 151 | 152 | 153 | 154 |
Build statusWindows binaries
Build status on AppVeyor32-bit64-bit
155 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | cl_khr_integer_dot_product https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#cl_khr_integer_dot_product 2 | 3 | cl_khr_kernel_clock https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#cl_khr_kernel_clock 4 | (extension is provisional; defines have already been imported in ext.h) 5 | 6 | cl_khr_command_buffer_multi_device https://registry.khronos.org/OpenCL/sdk/3.0/docs/man/html/cl_khr_command_buffer_multi_device.html 7 | (extension is provisional; defines have already been imported in ext.h) 8 | -------------------------------------------------------------------------------- /fetch-opencl-dev-win.cmd: -------------------------------------------------------------------------------- 1 | REM call as fetch-opencl-dev-win x86|x86_64|x64 2 | 3 | git clone https://github.com/KhronosGroup/OpenCL-Headers include 4 | 5 | set sub=%1 6 | 7 | if /i "%sub%" == "x64" set sub=x86_64 8 | 9 | mkdir lib\%sub% 10 | curl -L -o lib/%sub%/libOpenCL.a https://github.com/AMD-FirePro/SDK/raw/master/external/opencl-1.2/lib/%sub%/libOpenCL.a -o lib/%sub%/OpenCL.lib https://github.com/AMD-FirePro/SDK/raw/master/external/opencl-1.2/lib/%sub%/OpenCL.lib -o OpenCL.dll https://github.com/AMD-FirePro/SDK/raw/master/external/opencl-1.2/bin/%sub%/OpenCL.dll 11 | -------------------------------------------------------------------------------- /legalcode.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /make.cmd: -------------------------------------------------------------------------------- 1 | nmake /F Makefile.win /nologo %* 2 | -------------------------------------------------------------------------------- /man1/clinfo.1: -------------------------------------------------------------------------------- 1 | .TH CLINFO 1 "2025-02-14" "clinfo 3.0.25.02.14" 2 | 3 | .SH NAME 4 | 5 | clinfo \- show OpenCL platforms and devices 6 | 7 | .SH SYNOPSIS 8 | .B clinfo 9 | .RI [ "options ..." ] 10 | 11 | .SH DESCRIPTION 12 | .B clinfo 13 | prints all available information about all OpenCL platforms 14 | available on the system and the devices they expose. 15 | 16 | .SH OPTIONS 17 | .B clinfo 18 | accepts the following options: 19 | .TP 2 20 | .BR -a ", " --all-props 21 | try to retrieve all properties, even those not officially supported 22 | (e.g. because they require specific extensions), but only show them 23 | if the property could be retrieved successfully; see also the 24 | .B LIMITATIONS 25 | section below; note that even though this may reveal hidden properties, 26 | there is no guarantee that the returned values are meaningful, nor that 27 | the corresponding feature is actually available at all; 28 | .TP 29 | .BR -A ", " --always-all-props 30 | like 31 | .BR -a , 32 | but also show errors; 33 | .TP 34 | .B --human 35 | produce human-friendly output; this is the default (except 36 | as noted below); 37 | .TP 38 | .B --raw 39 | produce machine-friendly output; this is the default if 40 | .B clinfo 41 | is invoked with a name that contains the string 42 | .RI \*(lq raw \*(rq; 43 | .TP 44 | .B --json 45 | outputs the raw data (cf. the 46 | .B --raw 47 | option) in JSON format; support for this option is experimental, 48 | as the representation of some of the values is not finalized; 49 | .TP 50 | .B --offline 51 | shows also offline devices for platforms that expose this feature; 52 | .TP 53 | .B --null-platform 54 | tries to handle the NULL platform as a normal platform, 55 | retrieving and showing its properties and devices; 56 | this is in addition to the NULL platform behavior tests done at the end, 57 | and can be useful on systems where there are no ICD platforms, 58 | but there is a platform hard-coded in the OpenCL library itself; 59 | .TP 60 | .BR -l ", " --list 61 | list platforms and devices by name, with no (other) properties; 62 | .TP 63 | .BI -d " platform_index" : device_index 64 | .TQ 65 | .BI --device " platform_index" : device_index 66 | only show properties for the specified device in the specified platform; 67 | multiple device specifications may be given on the command-line; 68 | .TP 69 | .BI --prop " property-name" 70 | only show properties whose symbolic name matches 71 | (contains as a substring) the given 72 | .IR property-name ; 73 | the name is normalized as upper-case and with minus sign (-) 74 | replaced by underscore signs (_); 75 | multiple property specifications may be given on the command-line; 76 | when this flag is specified, raw mode is forced; 77 | .TP 78 | .BR --help ", " -? ", " -h 79 | show usage; 80 | .TP 81 | .BR --version ", " -v 82 | show program version. 83 | 84 | .SH CONFORMING TO 85 | 86 | OpenCL 1.1, OpenCL 1.2, OpenCL 2.0, OpenCL 2.1, OpenCL 2.2, OpenCL 3.0. 87 | 88 | .SH EXTENSIONS 89 | 90 | Supported OpenCL extensions: 91 | .TP 2 92 | .B cl_khr_device_uuid 93 | for the UUID, LUID and node mask of the device; 94 | .TP 95 | .B cl_khr_extended_versioning 96 | for the extended platform, device, extension and IL versioned properties 97 | backported from OpenCL 3.0 to previous OpenCL versions; 98 | .TP 99 | .BR cl_khr_fp16 ", " cl_khr_fp64 ", " cl_amd_fp64 ", " cl_APPLE_fp64_basic_ops 100 | for information about support for half-precision and double-precision 101 | floating-point data types; 102 | .TP 103 | .B cl_khr_image2d_from_buffer 104 | for information about the base address and pitch alignment requirements 105 | of buffers to be used as base for 2D images; 106 | .TP 107 | .B cl_khr_il_program 108 | for information about the supported IL (Intermediate Language) representations; 109 | .TP 110 | .B cl_khr_spir 111 | for information about the supported SPIR (Standard Portable Intermediate 112 | Representation) versions; 113 | .TP 114 | .B cl_khr_icd 115 | for the suffix of vendor extensions functions; 116 | .TP 117 | .B cl_khr_subgroup_named_barrier 118 | for the maximum number of named sub-group barriers; 119 | .TP 120 | .BI cl_khr_terminate_context ", " cl_arm_controlled_kernel_termination 121 | for the terminate capabilities for the device; 122 | .TP 123 | .B cl_ext_device_fission 124 | for device fission support in OpenCL 1.1 devices; 125 | .TP 126 | .B cl_khr_pci_bus_info 127 | for the PCI bus information (see also 128 | .BR cl_nv_device_attribute_query " and" 129 | .BR cl_amd_device_attribute_query ) 130 | .TP 131 | .B cl_ext_atomic_counters_32 132 | .TQ 133 | .B cl_ext_atomic_counters_64 134 | for the atomic counter extension; 135 | .TP 136 | .B cl_ext_float_atomics 137 | for the floating-point atomic capabilities for half, single and double precision 138 | (depending on hardware floating-point size support); 139 | .TP 140 | .B cl_ext_cxx_for_opencl 141 | for the version of the C++ for OpenCL language supported by the device compiler; 142 | .TP 143 | .B cl_amd_device_attribute_query 144 | for AMD-specific device attributes; 145 | .TP 146 | .B cl_amd_object_metadata 147 | to show the maximum number of keys supported by the platform; 148 | .TP 149 | .B cl_amd_offline_devices 150 | to show offline devices exposed by the platform, if requested (see 151 | .B --offline 152 | option); 153 | .TP 154 | .B cl_amd_copy_buffer_p2p 155 | to show the number and IDs of available P2P devices; 156 | .TP 157 | .B cl_amd_svm 158 | .TQ 159 | .B cl_arm_shared_virtual_memory 160 | for Shared Virtual Memory (SVM) capabilities in OpenCL 1.2 devices; 161 | .TP 162 | .B cl_arm_core_id 163 | to show the (potentially sparse) list of the core IDs that the device may 164 | return; 165 | .TP 166 | .B cl_arm_job_slot_selection 167 | to show the (potentially sparse) list of available job slots for command 168 | submission; 169 | .TP 170 | .B cl_arm_scheduling_controls 171 | to show the supported work scheduling controls and the available sets of register allocations; 172 | .TP 173 | .B cl_nv_device_attribute_query 174 | for NVIDIA-specific device attributes; 175 | .TP 176 | .B cl_intel_device_attribute_query 177 | for Intel-specific device attributes; 178 | .TP 179 | .B cl_intel_exec_by_local_thread 180 | for the Intel extension allowing CPU devices to run kernels as part of 181 | the current host thread; 182 | .TP 183 | .B cl_intel_advanced_motion_estimation 184 | for the version of the Intel Motion Estimation accelerator version; 185 | .TP 186 | .B cl_intel_device_side_avc_motion_estimation 187 | for the version and supported features of Intel's device-side AVC Motion; 188 | .TP 189 | .B cl_intel_planar_yuv 190 | for the maximum dimensions of planar YUV images; 191 | .TP 192 | .B cl_intel_simultaneous_sharing 193 | for simultaneous CL/GL/DirectX context sharing (only partial support); 194 | .TP 195 | .B cl_intel_required_subgroup_size 196 | to enumerate allowed sub-group sizes; 197 | .TP 198 | .B cl_intel_command_queue_families 199 | to enumerate the available command queues and their properties and capabilities; 200 | .TP 201 | .B cl_altera_device_temperature 202 | for the Altera extension to query the core temperature of the device; 203 | .TP 204 | .B cl_qcom_ext_host_ptr 205 | for the QUALCOMM extension to query page size and required padding in external 206 | memory allocation. 207 | 208 | .SH NOTES 209 | Some information is duplicated when available from multiple sources. 210 | Examples: 211 | .IP \(bu 2 212 | supported device partition types and domains as obtained using the 213 | .B cl_ext_device_fission 214 | extension typically match the ones obtained using 215 | the core OpenCL 1.2 device partition feature; 216 | .IP \(bu 217 | the preferred work-group size multiple matches the NVIDIA warp size (on 218 | NVIDIA devices) or the AMD wavefront width (on AMD devices). 219 | 220 | .P 221 | Some floating-point configuration flags may only be meaningful for 222 | specific precisions and/or specific OpenCL versions. For example, 223 | .B CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT 224 | is only relevant for single precision in OpenCL 1.2 devices. 225 | 226 | .P 227 | The implementation-defined behavior for NULL platform or context 228 | properties is tested for the following API calls: 229 | .TP 2 230 | .B clGetPlatformInfo() 231 | by trying to show the platform name; 232 | .TP 233 | .B clGetDeviceIDs() 234 | by trying to enumerate devices; the corresponding platform (if any) 235 | is then detected by querying the device platform of the first device; 236 | .TP 237 | .B clCreateteContext() 238 | by trying to create a context from a device from the previous 239 | list (if any), and a context from a device from a different platform; 240 | .TP 241 | .B clCreateteContextFromType() 242 | by trying to create contexts for each device type (except DEFAULT). 243 | 244 | .SH EXPERIMENTAL FEATURES 245 | .P 246 | Support for OpenCL 2.x properties is not fully tested. 247 | 248 | .P 249 | Support for 250 | .B cl_khr_subgroup_named_barrier 251 | is experimental due to missing definitions in the official OpenCL headers. 252 | 253 | .P 254 | Raw (machine-parsable) output is considered experimental, the output format 255 | might still undergo changes. 256 | 257 | .P 258 | The properties of the ICD loader will also be queried if the 259 | .B clGetICDLoaderInfoOCLICD 260 | extension function is found. 261 | 262 | .P 263 | Support for the properties exposed by 264 | .B cl_amd_copy_buffer_p2p 265 | is experimental. 266 | 267 | .P 268 | Support for some (documented and undocumented) properties exposed by 269 | .B cl_amd_device_attribute_query 270 | is experimental (see also 271 | .BR LIMITATIONS ). 272 | 273 | .P 274 | Support for the interop lists exposed by 275 | .B cl_intel_simultaneous_sharing 276 | is experimental. 277 | 278 | .P 279 | The highest OpenCL version supported by the ICD loader is detected 280 | with some trivial heuristics (symbols found); a notice is output 281 | if this is lower than the highest platform OpenCL version, or 282 | if the detected version doesn't match the one declared by the ICD 283 | loader itself. 284 | 285 | .SH LIMITATIONS 286 | 287 | .P 288 | OpenCL did not provide an explicit mean to detect the supported version 289 | of any extension exposed by a device until version 3.0. This makes it impossible 290 | in many circumstances to determine a priori if it will be possible to successfully query 291 | a device about a specific property even if it declares support for a given extension. 292 | Additionally, the actual size and meaning of some properties are not 293 | officially declared anywhere. 294 | 295 | .P 296 | Most notably, this affects extensions such as 297 | .BR cl_amd_device_attribute_query , 298 | .B cl_nv_device_attribute_query 299 | and 300 | .BR cl_arm_core_id . 301 | Heuristics based on standard version support are partially used in the code to 302 | determine which version may be supported. 303 | 304 | .P 305 | Properties which are known to be affected by these limitations include: 306 | 307 | .TP 2 308 | .B CL_DEVICE_GLOBAL_FREE_MEMORY_AMD 309 | documented in v3 of the 310 | .B cl_amd_device_attribute_query 311 | extension specification as being the global free memory in KBytes, without 312 | any explanation given on why there are two values, although in the source code 313 | of the 314 | .B ROCm 315 | stack the second value is documented as being the largest free block; 316 | .TP 317 | .B CL_DEVICE_AVAILABLE_ASYNC_QUEUES_AMD 318 | documented in v3 of the 319 | .B cl_amd_device_attribute_query 320 | extension specification, but not reported by drivers supporting other v3 321 | properties. This has now been enabled for drivers 322 | .I assumed 323 | to support v4 of the same extension; 324 | .TP 325 | .B CL_DEVICE_TERMINATE_CAPABILITY_KHR 326 | exposed by the 327 | .B cl_khr_terminate_context 328 | has changed value between OpenCL 1.x and 2.x, and it's 329 | .I allegedly 330 | a bitfield, whose values are however not defined anywhere. 331 | 332 | .SH BUGS 333 | 334 | .SS General 335 | 336 | .P 337 | Please report any issues on 338 | .UR http://github.com/Oblomov/clinfo 339 | the project tracker on GitHub 340 | .UE . 341 | 342 | .SS LLVM CommandLine errors 343 | 344 | .P 345 | If multiple OpenCL platforms using shared 346 | .B LLVM 347 | libraries are present in the system, 348 | .B clinfo 349 | (and other OpenCL application) may crash with errors 350 | to the tune of 351 | .PP 352 | .nf 353 | .RS 354 | .B : CommandLine Error: Option '(some option name)' registered more than once! 355 | .B LLVM ERROR: inconsistency in registered CommandLine options 356 | .RE 357 | .fi 358 | .PP 359 | or similar. This is not an issue in 360 | .BR clinfo "," 361 | or in any OpenCL platform or application, but it is due to the way 362 | .B LLVM 363 | handles its own command-line options parsing. 364 | The issue has been reported upstream 365 | .UR https://bugs.llvm.org/show_bug.cgi?id=30587 366 | as issue #30587 367 | .UE . 368 | See the next point for possible workarounds and assistance in identifying the 369 | conflicting platforms. 370 | 371 | .SS Segmentation faults 372 | 373 | .P 374 | Faulty OpenCL platforms may cause segmentation faults in 375 | .B clinfo 376 | during the information gathering phase, sometimes even 377 | before any output is shown. There is very little 378 | .B clinfo 379 | can do to avoid this. If you see this happening, 380 | try disabling all platforms and then re-enabling 381 | them one by one until you experience the crash again. 382 | Chances are the last platform you enabled is defective 383 | in some way (either by being incompatible with other 384 | platforms or by missing necessary components and 385 | not handling their absence gracefully). 386 | 387 | .P 388 | To selectively enable/disable platforms, one 389 | way is to move or rename the 390 | .I *.icd 391 | files present in 392 | .I /etc/OpenCL/vendors/ 393 | and then restoring them one by one. When using 394 | the free-software 395 | .B ocl-icd 396 | OpenCL library, a similar effect can be achieved 397 | by setting the 398 | .B OPENCL_VENDOR_PATH 399 | or 400 | .B OCL_ICD_VENDORS 401 | environment variables, as documented in 402 | .BR libOpenCL (7). 403 | Other implementations of 404 | .B libOpenCL 405 | are known to support 406 | .B OPENCL_VENDOR_PATH 407 | too. 408 | 409 | .TP 2 410 | .B Example 411 | find /etc/OpenCL/vendors/ -name '*.icd' | while read OPENCL_VENDOR_PATH ; do clinfo -l > /dev/null ; echo "$? ${OPENCL_VENDOR_PATH}" ; done 412 | 413 | .P 414 | This one liner will run 415 | .B clinfo -l 416 | for each platform individually (hiding the normal output), 417 | and report the 418 | .I .icd 419 | path prefixed by 420 | .B 0 421 | for successful runs, and a non-zero value for faulty 422 | platforms. 423 | -------------------------------------------------------------------------------- /new-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Change the version recorded in src/clinfo.c and man1/clinfo.1 to 4 | # the current highest OpenCL supported standard followed by current 5 | # yy.mm.dd 6 | 7 | abort() { 8 | echo "$1" >&2 9 | exit 1 10 | } 11 | 12 | test -n "$(git status --porcelain | grep -v '??')" && abort "Uncommited changes, aborting" 13 | 14 | DATE=$(date +%Y-%m-%d) 15 | MAJOR=$(awk '/^OpenCL/ { print $NF ; exit }' man1/clinfo.1) 16 | SUBV=$(date +%y.%m.%d) 17 | VERSION="$MAJOR$SUBV" 18 | 19 | sed -i -e "/clinfo version/ s/version \S\+\"/version $VERSION\"/" src/clinfo.c && 20 | sed -i -e "1 s/\".\+$/\"$DATE\" \"clinfo $VERSION\"/" man1/clinfo.1 && 21 | sed -i -e "1 s/\".\+$/version: $VERSION-{build}/" .appveyor.yml && 22 | git commit -m "Version $VERSION" -e -a && 23 | git tag -m "Version $VERSION" $VERSION 24 | -------------------------------------------------------------------------------- /src/ctx_prop.h: -------------------------------------------------------------------------------- 1 | /* List of OpenCL context properties used to interoperate with a different API */ 2 | 3 | #ifndef CTX_PROP 4 | #define CTX_PROP 5 | 6 | /* cl_khr_gl_sharing */ 7 | #define CL_GL_CONTEXT_KHR 0x2008 8 | #define CL_EGL_DISPLAY_KHR 0x2009 9 | #define CL_GLX_DISPLAY_KHR 0x200A 10 | #define CL_WGL_HDC_KHR 0x200B 11 | #define CL_CGL_SHAREGROUP_KHR 0x200C 12 | 13 | /* cl_khr_dx9_media_sharing */ 14 | #define CL_CONTEXT_ADAPTER_D3D9_KHR 0x2025 15 | #define CL_CONTEXT_ADAPTER_D3D9EX_KHR 0x2026 16 | #define CL_CONTEXT_ADAPTER_DXVA_KHR 0x2027 17 | 18 | /* cl_khr_d3d10_sharing */ 19 | #define CL_CONTEXT_D3D10_DEVICE_KHR 0x4014 20 | 21 | /* cl_khr_d3d11_sharing */ 22 | #define CL_CONTEXT_D3D11_DEVICE_KHR 0x401D 23 | 24 | /* cl_intel_dx9_media_sharing */ 25 | #define CL_CONTEXT_D3D9_DEVICE_INTEL 0x4026 26 | #define CL_CONTEXT_D3D9EX_DEVICE_INTEL 0x4072 27 | #define CL_CONTEXT_DXVA_DEVICE_INTEL 0x4073 28 | 29 | /* cl_intel_va_api_media_sharing */ 30 | #define CL_CONTEXT_VA_API_DISPLAY_INTEL 0x4097 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/error.h: -------------------------------------------------------------------------------- 1 | /* OpenCL error handling */ 2 | 3 | #ifndef ERROR_H 4 | #define ERROR_H 5 | 6 | #include 7 | 8 | #include "ext.h" 9 | #include "info_loc.h" 10 | #include "fmtmacros.h" 11 | #include "strbuf.h" 12 | 13 | cl_int 14 | check_ocl_error(cl_int err, const char *what, const char *func, int line) 15 | { 16 | if (err != CL_SUCCESS) { 17 | fflush(stdout); 18 | fflush(stderr); 19 | fprintf(stderr, "%s:%u: %s : error %d\n", 20 | func, line, what, err); 21 | fflush(stderr); 22 | } 23 | return err; 24 | } 25 | 26 | cl_int 27 | report_ocl_error_basic(struct _strbuf *str, cl_int err, const char *what, const char *func, int line) 28 | { 29 | if (err != CL_SUCCESS) { 30 | snprintf(str->buf, str->sz, "<%s:%d: %s : error %d>", 31 | func, line, what, err); 32 | } 33 | return err; 34 | } 35 | 36 | 37 | cl_int 38 | report_ocl_error_loc(struct _strbuf *str, cl_int err, const char *fmt, 39 | const struct info_loc *loc) 40 | { 41 | static char full_fmt[1024]; 42 | if (err != CL_SUCCESS) { 43 | snprintf(full_fmt, 1024, "<%s:%" PRIuS ": %s : error %d>", 44 | loc->function, loc->line, fmt, err); 45 | snprintf(str->buf, str->sz, full_fmt, loc->sname); 46 | } 47 | return err != CL_SUCCESS; 48 | } 49 | 50 | void 51 | report_size_mismatch(struct _strbuf *str, size_t req, size_t ours, 52 | const struct info_loc *loc) 53 | { 54 | snprintf(str->buf, str->sz, "<%s:%" PRIuS ": %s : size mismatch " 55 | "(requested %" PRIuS ", we offer %" PRIuS ")>", 56 | loc->function, loc->line, loc->sname, 57 | req, ours); 58 | } 59 | 60 | #define CHECK_ERROR(error, what) if (check_ocl_error(error, what, __func__, __LINE__)) exit(1) 61 | 62 | #define REPORT_ERROR(str, err, what) report_ocl_error_basic(str, err, what, __func__, __LINE__) 63 | #define REPORT_ERROR_LOC(ret, err, loc, what) report_ocl_error_loc(&((ret)->err_str), err, what, loc) 64 | #define REPORT_SIZE_MISMATCH(str, loc, req, ours) report_size_mismatch(str, req, ours, loc) 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/ext.h: -------------------------------------------------------------------------------- 1 | /* Include OpenCL header, and define OpenCL extensions, since what is and is not 2 | * available in the official headers is very system-dependent */ 3 | 4 | #ifndef EXT_H 5 | #define EXT_H 6 | 7 | /* Khronos now provides unified headers for all OpenCL versions, and 8 | * it should be included after defining a target OpenCL version 9 | * (otherwise, the maximum version will simply be used, but a message 10 | * will be printed). 11 | * 12 | * TODO: until 3.0 gets finalized, we only target 2.2 because the 3.0 13 | * defines etc are still changing, so users may have an older version 14 | * of the 3.0 headers lying around, which may prevent clinfo from being 15 | * compilable. 16 | */ 17 | #define CL_TARGET_OPENCL_VERSION 220 18 | 19 | /* We will use the deprecated clGetExtensionFunctionAddress, 20 | * so let the headers know that we don't care about it being deprecated. 21 | * The standard CL_USE_DEPRECATED_OPENCL_1_1_APIS define apparently 22 | * doesn't work for macOS, so we'll just tell the compiler to not 23 | * warn about deprecated functions. 24 | * A more correct solution would be to suppress the warning only around the 25 | * clGetExtensionFunctionAddress call, but honestly I just cleaned up that 26 | * piece of code. And I'm actually wondering if it even makes sense to 27 | * build that part of the code on macOS: does anybody actually use 28 | * ocl-icd as OpenCL dispatcher on macOS? 29 | */ 30 | 31 | #ifdef __APPLE__ 32 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 33 | #include 34 | #else 35 | #define CL_USE_DEPRECATED_OPENCL_1_1_APIS 36 | #include 37 | #endif 38 | 39 | /* Very old headers will be missing these defines */ 40 | #ifndef CL_VERSION_1_1 41 | #define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 42 | #define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 43 | #define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 44 | #define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 45 | #define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 46 | #define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 47 | #define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A 48 | #define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B 49 | #define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C 50 | #define CL_DEVICE_OPENCL_C_VERSION 0x103D 51 | 52 | #define CL_FP_SOFT_FLOAT (1 << 6) 53 | 54 | #define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3 55 | #endif 56 | 57 | #ifndef CL_VERSION_1_2 58 | #define CL_DEVICE_TYPE_CUSTOM (1 << 4) 59 | 60 | #define CL_DEVICE_LINKER_AVAILABLE 0x103E 61 | #define CL_DEVICE_BUILT_IN_KERNELS 0x103F 62 | #define CL_DEVICE_IMAGE_MAX_BUFFER_SIZE 0x1040 63 | #define CL_DEVICE_IMAGE_MAX_ARRAY_SIZE 0x1041 64 | #define CL_DEVICE_PARTITION_MAX_SUB_DEVICES 0x1043 65 | #define CL_DEVICE_PARTITION_PROPERTIES 0x1044 66 | #define CL_DEVICE_PARTITION_AFFINITY_DOMAIN 0x1045 67 | #define CL_DEVICE_PARTITION_TYPE 0x1046 68 | #define CL_DEVICE_PREFERRED_INTEROP_USER_SYNC 0x1048 69 | #define CL_DEVICE_PRINTF_BUFFER_SIZE 0x1049 70 | #define CL_DEVICE_IMAGE_PITCH_ALIGNMENT 0x104A 71 | #define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 0x104B 72 | 73 | #define CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT (1 << 7) 74 | 75 | /* cl_device_partition_property */ 76 | #define CL_DEVICE_PARTITION_EQUALLY 0x1086 77 | #define CL_DEVICE_PARTITION_BY_COUNTS 0x1087 78 | #define CL_DEVICE_PARTITION_BY_COUNTS_LIST_END 0x0 79 | #define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN 0x1088 80 | 81 | /* cl_device_affinity_domain */ 82 | #define CL_DEVICE_AFFINITY_DOMAIN_NUMA (1 << 0) 83 | #define CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE (1 << 1) 84 | #define CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE (1 << 2) 85 | #define CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE (1 << 3) 86 | #define CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE (1 << 4) 87 | #define CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE (1 << 5) 88 | 89 | #endif 90 | 91 | /* These two defines were introduced in the 1.2 headers 92 | * on 2012-11-30, so earlier versions don't have them 93 | * (e.g. Debian wheezy) 94 | */ 95 | 96 | #ifndef CL_DEVICE_IMAGE_PITCH_ALIGNMENT 97 | #define CL_DEVICE_IMAGE_PITCH_ALIGNMENT 0x104A 98 | #define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 0x104B 99 | #endif 100 | 101 | /* 2.0 headers are not very common for the time being, so 102 | * let's copy the defines for the new CL_DEVICE_* properties 103 | * here. 104 | */ 105 | #ifndef CL_VERSION_2_0 106 | #define CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS 0x104C 107 | #define CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE 0x104D 108 | #define CL_DEVICE_QUEUE_ON_HOST_PROPERTIES 0x102A 109 | #define CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES 0x104E 110 | #define CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE 0x104F 111 | #define CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE 0x1050 112 | #define CL_DEVICE_MAX_ON_DEVICE_QUEUES 0x1051 113 | #define CL_DEVICE_MAX_ON_DEVICE_EVENTS 0x1052 114 | #define CL_DEVICE_SVM_CAPABILITIES 0x1053 115 | #define CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE 0x1054 116 | #define CL_DEVICE_MAX_PIPE_ARGS 0x1055 117 | #define CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS 0x1056 118 | #define CL_DEVICE_PIPE_MAX_PACKET_SIZE 0x1057 119 | #define CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT 0x1058 120 | #define CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT 0x1059 121 | #define CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT 0x105A 122 | 123 | #define CL_DEVICE_SVM_COARSE_GRAIN_BUFFER (1 << 0) 124 | #define CL_DEVICE_SVM_FINE_GRAIN_BUFFER (1 << 1) 125 | #define CL_DEVICE_SVM_FINE_GRAIN_SYSTEM (1 << 2) 126 | #define CL_DEVICE_SVM_ATOMICS (1 << 3) 127 | 128 | typedef cl_bitfield cl_device_svm_capabilities; 129 | #endif 130 | 131 | #ifndef CL_VERSION_2_1 132 | #define CL_PLATFORM_HOST_TIMER_RESOLUTION 0x0905 133 | #define CL_DEVICE_IL_VERSION 0x105B 134 | #define CL_DEVICE_MAX_NUM_SUB_GROUPS 0x105C 135 | #define CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS 0x105D 136 | #endif 137 | 138 | #ifndef CL_VERSION_3_0 139 | #define CL_PLATFORM_NUMERIC_VERSION 0x0906 140 | #define CL_PLATFORM_EXTENSIONS_WITH_VERSION 0x0907 141 | #define CL_DEVICE_NUMERIC_VERSION 0x105E 142 | #define CL_DEVICE_EXTENSIONS_WITH_VERSION 0x1060 143 | #define CL_DEVICE_ILS_WITH_VERSION 0x1061 144 | #define CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION 0x1062 145 | #define CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES 0x1063 146 | #define CL_DEVICE_ATOMIC_FENCE_CAPABILITIES 0x1064 147 | #define CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT 0x1065 148 | #define CL_DEVICE_OPENCL_C_ALL_VERSIONS 0x1066 149 | #define CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x1067 150 | #define CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT 0x1068 151 | #define CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT 0x1069 152 | #define CL_DEVICE_OPENCL_C_FEATURES 0x106F 153 | #define CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES 0x1070 154 | #define CL_DEVICE_PIPE_SUPPORT 0x1071 155 | #define CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED 0x1072 156 | 157 | 158 | typedef cl_bitfield cl_device_atomic_capabilities; 159 | typedef cl_bitfield cl_device_device_enqueue_capabilities; 160 | typedef cl_uint cl_version; 161 | 162 | #define CL_NAME_VERSION_MAX_NAME_SIZE 64 163 | 164 | typedef struct _cl_name_version { 165 | cl_version version; 166 | char name[CL_NAME_VERSION_MAX_NAME_SIZE]; 167 | } cl_name_version; 168 | 169 | /* cl_device_atomic_capabilities */ 170 | #define CL_DEVICE_ATOMIC_ORDER_RELAXED (1 << 0) 171 | #define CL_DEVICE_ATOMIC_ORDER_ACQ_REL (1 << 1) 172 | #define CL_DEVICE_ATOMIC_ORDER_SEQ_CST (1 << 2) 173 | #define CL_DEVICE_ATOMIC_SCOPE_WORK_ITEM (1 << 3) 174 | #define CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP (1 << 4) 175 | #define CL_DEVICE_ATOMIC_SCOPE_DEVICE (1 << 5) 176 | #define CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES (1 << 6) 177 | 178 | /* cl_device_device_enqueue_capabilities */ 179 | #define CL_DEVICE_QUEUE_SUPPORTED (1 << 0) 180 | #define CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT (1 << 1) 181 | 182 | #endif 183 | 184 | /* 185 | * Extensions 186 | */ 187 | 188 | /* cl_khr_extended_versioning */ 189 | // the _KHR fields are the same as the unsuffixed from OpenCL 3 190 | #define CL_PLATFORM_NUMERIC_VERSION_KHR CL_PLATFORM_NUMERIC_VERSION 191 | #define CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR CL_PLATFORM_EXTENSIONS_WITH_VERSION 192 | #define CL_DEVICE_NUMERIC_VERSION_KHR CL_DEVICE_NUMERIC_VERSION 193 | #define CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR 0x105F 194 | #define CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR CL_DEVICE_EXTENSIONS_WITH_VERSION 195 | #define CL_DEVICE_ILS_WITH_VERSION_KHR CL_DEVICE_ILS_WITH_VERSION 196 | #define CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION 197 | 198 | /* cl_khr_image2d_from_buffer */ 199 | // the _KHR fields are the same as the unsuffixed from OpenCL 2 200 | #define CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR CL_DEVICE_IMAGE_PITCH_ALIGNMENT 201 | #define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 202 | 203 | 204 | /* cl_khr_icd */ 205 | #define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920 206 | #define CL_PLATFORM_NOT_FOUND_KHR -1001 207 | 208 | /* cl_khr_kernel_clock */ 209 | #define CL_DEVICE_KERNEL_CLOCK_CAPABILITIES_KHR 0x1076 210 | typedef cl_bitfield cl_device_kernel_clock_capabilities_khr; 211 | #define CL_DEVICE_KERNEL_CLOCK_SCOPE_DEVICE_KHR (1 << 0) 212 | #define CL_DEVICE_KERNEL_CLOCK_SCOPE_WORK_GROUP_KHR (1 << 1) 213 | #define CL_DEVICE_KERNEL_CLOCK_SCOPE_SUB_GROUP_KHR (1 << 2) 214 | 215 | /* cl_amd_object_metadata */ 216 | #define CL_PLATFORM_MAX_KEYS_AMD 0x403C 217 | 218 | /* cl_khr_device_uuid extension */ 219 | 220 | #define CL_UUID_SIZE_KHR 16 221 | #define CL_LUID_SIZE_KHR 8 222 | 223 | #define CL_DEVICE_UUID_KHR 0x106A 224 | #define CL_DRIVER_UUID_KHR 0x106B 225 | #define CL_DEVICE_LUID_VALID_KHR 0x106C 226 | #define CL_DEVICE_LUID_KHR 0x106D 227 | #define CL_DEVICE_NODE_MASK_KHR 0x106E 228 | 229 | /* cl_khr_fp64 */ 230 | #define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 231 | 232 | /* cl_khr_fp16 */ 233 | #define CL_DEVICE_HALF_FP_CONFIG 0x1033 234 | 235 | /* cl_khr_il_program */ 236 | #define CL_DEVICE_IL_VERSION_KHR 0x105B 237 | 238 | /* cl_khr_command_buffer */ 239 | #define CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR 0x12A9 240 | #define CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR 0x12AA 241 | typedef cl_bitfield cl_device_command_buffer_capabilities_khr; 242 | 243 | /* cl_khr_command_buffer_multi_device */ 244 | #define CL_PLATFORM_COMMAND_BUFFER_CAPABILITIES_KHR 0x0908 245 | typedef cl_bitfield cl_platform_command_buffer_capabilities_khr; 246 | #define CL_COMMAND_BUFFER_PLATFORM_UNIVERSAL_SYNC_KHR (1 << 0) 247 | #define CL_COMMAND_BUFFER_PLATFORM_REMAP_QUEUES_KHR (1 << 1) 248 | #define CL_COMMAND_BUFFER_PLATFORM_AUTOMATIC_REMAP_KHR (1 << 2) 249 | 250 | #define CL_DEVICE_COMMAND_BUFFER_NUM_SYNC_DEVICES_KHR 0x12AB 251 | #define CL_DEVICE_COMMAND_BUFFER_SYNC_DEVICES_KHR 0x12AC 252 | 253 | /* cl_khr_command_buffer_mutable_dispatch */ 254 | #define CL_DEVICE_MUTABLE_DISPATCH_CAPABILITIES_KHR 0x12B0 255 | typedef cl_bitfield cl_mutable_dispatch_fields_khr; 256 | 257 | /* cl_khr_terminate_context */ 258 | #define CL_DEVICE_TERMINATE_CAPABILITY_KHR_1x 0x200F 259 | #define CL_DEVICE_TERMINATE_CAPABILITY_KHR 0x2031 260 | 261 | /* TODO: I cannot find official definitions for these, 262 | * so I'm currently extrapolating them from the specification 263 | */ 264 | typedef cl_bitfield cl_device_terminate_capability_khr; 265 | #define CL_DEVICE_TERMINATE_CAPABILITY_CONTEXT_KHR (1<<0) 266 | 267 | /* cl_khr_subgroup_named_barrier */ 268 | #define CL_DEVICE_MAX_NAMED_BARRIER_COUNT_KHR 0x2035 269 | 270 | /* cl_khr_semaphore */ 271 | #define CL_PLATFORM_SEMAPHORE_TYPES_KHR 0x2036 272 | #define CL_DEVICE_SEMAPHORE_TYPES_KHR 0x204C 273 | typedef cl_uint cl_semaphore_type_khr; 274 | 275 | /* cl_khr_external_semaphore */ 276 | #define CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR 0x2037 277 | #define CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR 0x2038 278 | #define CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR 0x204D 279 | #define CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR 0x204E 280 | typedef cl_uint cl_external_semaphore_handle_type_khr; 281 | 282 | /* cl_khr_external_memory */ 283 | #define CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR 0x2044 284 | #define CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR 0x204F 285 | // introduced in 0.9.3, according to https://registry.khronos.org/OpenCL/sdk/3.0/docs/man/html/cl_khr_external_memory.html 286 | #define CL_DEVICE_EXTERNAL_MEMORY_IMPORT_ASSUME_LINEAR_IMAGES_HANDLE_TYPES_KHR 0x2052 287 | typedef cl_uint cl_external_memory_handle_type_khr; 288 | 289 | 290 | /* cl_khr_pci_bus_info */ 291 | typedef struct _cl_device_pci_bus_info_khr { 292 | cl_uint pci_domain; 293 | cl_uint pci_bus; 294 | cl_uint pci_device; 295 | cl_uint pci_function; 296 | } cl_device_pci_bus_info_khr; 297 | 298 | #define CL_DEVICE_PCI_BUS_INFO_KHR 0x410F 299 | 300 | /* cl_nv_device_attribute_query */ 301 | #define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000 302 | #define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001 303 | #define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002 304 | #define CL_DEVICE_WARP_SIZE_NV 0x4003 305 | #define CL_DEVICE_GPU_OVERLAP_NV 0x4004 306 | #define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005 307 | #define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006 308 | #define CL_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT_NV 0x4007 309 | #define CL_DEVICE_PCI_BUS_ID_NV 0x4008 310 | #define CL_DEVICE_PCI_SLOT_ID_NV 0x4009 311 | #define CL_DEVICE_PCI_DOMAIN_ID_NV 0x400A 312 | 313 | /* cl_ext_atomic_counters_{32,64} */ 314 | #define CL_DEVICE_MAX_ATOMIC_COUNTERS_EXT 0x4032 315 | 316 | /* cl_ext_float_atomics */ 317 | typedef cl_bitfield cl_device_fp_atomic_capabilities_ext; 318 | /* cl_device_fp_atomic_capabilities_ext */ 319 | #define CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT (1 << 0) 320 | #define CL_DEVICE_GLOBAL_FP_ATOMIC_ADD_EXT (1 << 1) 321 | #define CL_DEVICE_GLOBAL_FP_ATOMIC_MIN_MAX_EXT (1 << 2) 322 | #define CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT (1 << 16) 323 | #define CL_DEVICE_LOCAL_FP_ATOMIC_ADD_EXT (1 << 17) 324 | #define CL_DEVICE_LOCAL_FP_ATOMIC_MIN_MAX_EXT (1 << 18) 325 | 326 | /* cl_device_info */ 327 | #define CL_DEVICE_SINGLE_FP_ATOMIC_CAPABILITIES_EXT 0x4231 328 | #define CL_DEVICE_DOUBLE_FP_ATOMIC_CAPABILITIES_EXT 0x4232 329 | #define CL_DEVICE_HALF_FP_ATOMIC_CAPABILITIES_EXT 0x4233 330 | 331 | /* cl_amd_device_attribute_query */ 332 | #define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036 333 | #define CL_DEVICE_TOPOLOGY_AMD 0x4037 334 | #define CL_DEVICE_BOARD_NAME_AMD 0x4038 335 | #define CL_DEVICE_GLOBAL_FREE_MEMORY_AMD 0x4039 336 | #define CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD 0x4040 337 | #define CL_DEVICE_SIMD_WIDTH_AMD 0x4041 338 | #define CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD 0x4042 339 | #define CL_DEVICE_WAVEFRONT_WIDTH_AMD 0x4043 340 | #define CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD 0x4044 341 | #define CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD 0x4045 342 | #define CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD 0x4046 343 | #define CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD 0x4047 344 | #define CL_DEVICE_LOCAL_MEM_BANKS_AMD 0x4048 345 | #define CL_DEVICE_THREAD_TRACE_SUPPORTED_AMD 0x4049 346 | #define CL_DEVICE_GFXIP_MAJOR_AMD 0x404A 347 | #define CL_DEVICE_GFXIP_MINOR_AMD 0x404B 348 | #define CL_DEVICE_AVAILABLE_ASYNC_QUEUES_AMD 0x404C 349 | /* These two are undocumented */ 350 | #define CL_DEVICE_MAX_REAL_TIME_COMPUTE_QUEUES_AMD 0x404D 351 | #define CL_DEVICE_MAX_REAL_TIME_COMPUTE_UNITS_AMD 0x404E 352 | /* These were added in v4 of the extension, but have values lower than 353 | * than the older ones, and spanning around the cl_ext_atomic_counters_* 354 | * define 355 | */ 356 | #define CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_AMD 0x4030 357 | #define CL_DEVICE_MAX_WORK_GROUP_SIZE_AMD 0x4031 358 | #define CL_DEVICE_PREFERRED_CONSTANT_BUFFER_SIZE_AMD 0x4033 359 | #define CL_DEVICE_PCIE_ID_AMD 0x4034 360 | 361 | #ifndef CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD 362 | #define CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD 1 363 | 364 | typedef union 365 | { 366 | struct { cl_uint type; cl_uint data[5]; } raw; 367 | struct { cl_uint type; cl_char unused[17]; cl_char bus; cl_char device; cl_char function; } pcie; 368 | } cl_device_topology_amd; 369 | #endif 370 | 371 | /* cl_amd_offline_devices */ 372 | #define CL_CONTEXT_OFFLINE_DEVICES_AMD 0x403F 373 | 374 | /* cl_amd_copy_buffer_p2p */ 375 | #define CL_DEVICE_NUM_P2P_DEVICES_AMD 0x4088 376 | #define CL_DEVICE_P2P_DEVICES_AMD 0x4089 377 | 378 | /* cl_ext_cxx_for_opencl */ 379 | #define CL_DEVICE_CXX_FOR_OPENCL_NUMERIC_VERSION_EXT 0x4230 380 | 381 | /* cl_ext_device_fission */ 382 | #define cl_ext_device_fission 1 383 | 384 | typedef cl_ulong cl_device_partition_property_ext; 385 | 386 | #define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050 387 | #define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051 388 | #define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052 389 | #define CL_DEVICE_PARTITION_BY_NAMES_INTEL 0x4052 /* cl_intel_device_partition_by_names */ 390 | #define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053 391 | 392 | #define CL_DEVICE_PARENT_DEVICE_EXT 0x4054 393 | #define CL_DEVICE_PARTITION_TYPES_EXT 0x4055 394 | #define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056 395 | #define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057 396 | #define CL_DEVICE_PARTITION_STYLE_EXT 0x4058 397 | 398 | #define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1 399 | #define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2 400 | #define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3 401 | #define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4 402 | #define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10 403 | #define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100 404 | 405 | /* cl_intel_advanced_motion_estimation */ 406 | #define CL_DEVICE_ME_VERSION_INTEL 0x407E 407 | 408 | /* cl_intel_device_side_avc_motion_estimation */ 409 | #define CL_DEVICE_AVC_ME_VERSION_INTEL 0x410B 410 | #define CL_DEVICE_AVC_ME_SUPPORTS_TEXTURE_SAMPLER_USE_INTEL 0x410C 411 | #define CL_DEVICE_AVC_ME_SUPPORTS_PREEMPTION_INTEL 0x410D 412 | 413 | /* cl_intel_planar_yuv */ 414 | #define CL_DEVICE_PLANAR_YUV_MAX_WIDTH_INTEL 0x417E 415 | #define CL_DEVICE_PLANAR_YUV_MAX_HEIGHT_INTEL 0x417F 416 | 417 | /* cl_intel_unified_shared_memory */ 418 | #define CL_DEVICE_HOST_MEM_CAPABILITIES_INTEL 0x4190 419 | #define CL_DEVICE_DEVICE_MEM_CAPABILITIES_INTEL 0x4191 420 | #define CL_DEVICE_SINGLE_DEVICE_SHARED_MEM_CAPABILITIES_INTEL 0x4192 421 | #define CL_DEVICE_CROSS_DEVICE_SHARED_MEM_CAPABILITIES_INTEL 0x4193 422 | #define CL_DEVICE_SHARED_SYSTEM_MEM_CAPABILITIES_INTEL 0x4194 423 | 424 | /* cl_qcom_ext_host_ptr */ 425 | #define CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM 0x40A0 426 | #define CL_DEVICE_PAGE_SIZE_QCOM 0x40A1 427 | 428 | /* cl_arm_shared_virtual_memory */ 429 | #define CL_DEVICE_SVM_CAPABILITIES_ARM 0x40B6 430 | #define CL_DEVICE_SVM_COARSE_GRAIN_BUFFER_ARM CL_DEVICE_SVM_COARSE_GRAIN_BUFFER 431 | #define CL_DEVICE_SVM_FINE_GRAIN_BUFFER_ARM CL_DEVICE_SVM_FINE_GRAIN_BUFFER 432 | #define CL_DEVICE_SVM_FINE_GRAIN_SYSTEM_ARM CL_DEVICE_SVM_FINE_GRAIN_SYSTEM 433 | #define CL_DEVICE_SVM_ATOMICS_ARM CL_DEVICE_SVM_ATOMICS 434 | 435 | /* cl_arm_core_id */ 436 | #define CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM 0x40BF 437 | 438 | /* cl_arm_controlled_kernel_termination */ 439 | #define CL_DEVICE_CONTROLLED_TERMINATION_CAPABILITIES_ARM 0x41EE 440 | 441 | typedef cl_bitfield cl_device_controlled_termination_capabilities_arm; 442 | #define CL_DEVICE_CONTROLLED_TERMINATION_SUCCESS_ARM (1 << 0) 443 | #define CL_DEVICE_CONTROLLED_TERMINATION_FAILURE_ARM (1 << 1) 444 | #define CL_DEVICE_CONTROLLED_TERMINATION_QUERY_ARM (1 << 2) 445 | 446 | /* cl_khr_spir */ 447 | #define CL_DEVICE_SPIR_VERSIONS 0x40E0 448 | 449 | /* cl_altera_device_temperature */ 450 | #define CL_DEVICE_CORE_TEMPERATURE_ALTERA 0x40F3 451 | 452 | /* cl_intel_simultaneous_sharing */ 453 | #define CL_DEVICE_SIMULTANEOUS_INTEROPS_INTEL 0x4104 454 | #define CL_DEVICE_NUM_SIMULTANEOUS_INTEROPS_INTEL 0x4105 455 | 456 | /* cl_intel_required_subgroup_size */ 457 | #define CL_DEVICE_SUB_GROUP_SIZES_INTEL 0x4108 458 | 459 | /* cl_intel_command_queue_families */ 460 | #define CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL 0x418B 461 | 462 | typedef cl_bitfield cl_command_queue_capabilities_intel; 463 | 464 | #define CL_QUEUE_FAMILY_MAX_NAME_SIZE_INTEL 64 465 | typedef struct _cl_queue_family_properties_intel { 466 | cl_command_queue_properties properties; 467 | cl_command_queue_capabilities_intel capabilities; 468 | cl_uint count; 469 | char name[CL_QUEUE_FAMILY_MAX_NAME_SIZE_INTEL]; 470 | } cl_queue_family_properties_intel; 471 | 472 | /* cl_arm_job_slot_selection */ 473 | #define CL_DEVICE_JOB_SLOTS_ARM 0x41E0 474 | 475 | /* cl_arm_scheduling_controls */ 476 | 477 | typedef cl_bitfield cl_device_scheduling_controls_capabilities_arm; 478 | 479 | #define CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM 0x41E4 480 | 481 | #define CL_DEVICE_SCHEDULING_KERNEL_BATCHING_ARM (1 << 0) 482 | #define CL_DEVICE_SCHEDULING_WORKGROUP_BATCH_SIZE_ARM (1 << 1) 483 | #define CL_DEVICE_SCHEDULING_WORKGROUP_BATCH_SIZE_MODIFIER_ARM (1 << 2) 484 | #define CL_DEVICE_SCHEDULING_DEFERRED_FLUSH_ARM (1 << 3) 485 | #define CL_DEVICE_SCHEDULING_REGISTER_ALLOCATION_ARM (1 << 4) 486 | #define CL_DEVICE_SCHEDULING_WARP_THROTTLING_ARM (1 << 5) 487 | #define CL_DEVICE_SCHEDULING_COMPUTE_UNIT_BATCH_QUEUE_SIZE_ARM (1 << 6) 488 | #define CL_DEVICE_SCHEDULING_COMPUTE_UNIT_LIMIT_ARM (1 << 7) 489 | 490 | #define CL_DEVICE_MAX_WARP_COUNT_ARM 0x41EA 491 | #define CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM 0x41EB 492 | 493 | /* cl_intel_device_attribute_query */ 494 | 495 | typedef cl_bitfield cl_device_feature_capabilities_intel; 496 | 497 | #define CL_DEVICE_FEATURE_FLAG_DP4A_INTEL (1 << 0) 498 | #define CL_DEVICE_FEATURE_FLAG_DPAS_INTEL (1 << 1) 499 | 500 | #define CL_DEVICE_IP_VERSION_INTEL 0x4250 501 | #define CL_DEVICE_ID_INTEL 0x4251 502 | #define CL_DEVICE_NUM_SLICES_INTEL 0x4252 503 | #define CL_DEVICE_NUM_SUB_SLICES_PER_SLICE_INTEL 0x4253 504 | #define CL_DEVICE_NUM_EUS_PER_SUB_SLICE_INTEL 0x4254 505 | #define CL_DEVICE_NUM_THREADS_PER_EU_INTEL 0x4255 506 | #define CL_DEVICE_FEATURE_CAPABILITIES_INTEL 0x4256 507 | 508 | /* clGeICDLoaderInfoOCLICD */ 509 | typedef enum { 510 | CL_ICDL_OCL_VERSION=1, 511 | CL_ICDL_VERSION=2, 512 | CL_ICDL_NAME=3, 513 | CL_ICDL_VENDOR=4, 514 | } cl_icdl_info; 515 | 516 | #endif 517 | -------------------------------------------------------------------------------- /src/fmtmacros.h: -------------------------------------------------------------------------------- 1 | /* cl_ulong is always a 64bit integer, so in a few places 2 | we want to use its shadow type uint64_t, and print the 3 | values using PRIu64. We'll similarly define one for 4 | size_t, to make support for non-standard/older compiler 5 | easier. 6 | */ 7 | 8 | #ifndef FMT_MACROS_H 9 | #define FMT_MACROS_H 10 | 11 | #ifdef _WIN32 12 | /* TODO FIXME WIN64 support */ 13 | # include 14 | # include // size_t 15 | # define PRIu32 "I32u" 16 | # define PRId32 "I32d" 17 | # define PRIx32 "I32x" 18 | # define PRIX32 "I32X" 19 | # define PRIu64 "I64u" 20 | # define PRIx64 "I64x" 21 | # define PRIX64 "I64X" 22 | # define PRIuS "Iu" 23 | #if INTPTR_MAX <= INT32_MAX 24 | # define PRIXPTR PRIX32 25 | # define PRIxPTR PRIx32 26 | #else 27 | # define PRIXPTR PRIX64 28 | # define PRIxPTR PRIx64 29 | #endif 30 | #else 31 | # define __STDC_FORMAT_MACROS 32 | # include 33 | #endif 34 | 35 | // size_t print spec 36 | #ifndef PRIuS 37 | # define PRIuS "zu" 38 | #endif 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/info_loc.h: -------------------------------------------------------------------------------- 1 | #ifndef INFO_LOC_H 2 | #define INFO_LOC_H 3 | 4 | #include "ext.h" 5 | 6 | struct info_loc { 7 | const char *function; 8 | const char *sname; // parameter symbolic name 9 | const char *pname; // parameter printable name 10 | size_t line; 11 | cl_platform_id plat; 12 | cl_device_id dev; 13 | union { 14 | cl_platform_info plat; 15 | cl_device_info dev; 16 | cl_icdl_info icdl; 17 | } param; 18 | }; 19 | 20 | static inline void reset_loc(struct info_loc *loc, const char *func) 21 | { 22 | loc->function = func; 23 | loc->sname = loc->pname = NULL; 24 | loc->line = 0; 25 | loc->plat = NULL; 26 | loc->dev = NULL; 27 | loc->param.plat = 0; 28 | } 29 | 30 | #define RESET_LOC_PARAM(_loc, _dev, _param) do { \ 31 | _loc.param._dev = _param; \ 32 | _loc.sname = #_param; \ 33 | } while (0) 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/info_ret.h: -------------------------------------------------------------------------------- 1 | #ifndef INFO_RET_H 2 | #define INFO_RET_H 3 | 4 | #include "ext.h" 5 | #include "strbuf.h" 6 | 7 | /* Return type of the functions that gather platform info */ 8 | struct platform_info_ret 9 | { 10 | cl_int err; 11 | /* string representation of the value (if any) */ 12 | struct _strbuf str; 13 | /* error representation of the value (if any) */ 14 | struct _strbuf err_str; 15 | /* actual value, when not a string */ 16 | union { 17 | size_t s; 18 | cl_uint u32; 19 | cl_ulong u64; 20 | } value; 21 | /* Does this ret need escaping as JSON? */ 22 | cl_bool needs_escaping; 23 | }; 24 | 25 | /* Return type of the functions that print device info */ 26 | struct device_info_ret { 27 | cl_int err; 28 | /* string representation of the value (if any) */ 29 | struct _strbuf str; 30 | /* error representation of the value (if any) */ 31 | struct _strbuf err_str; 32 | /* actual value, when not a string */ 33 | union { 34 | size_t s; 35 | cl_long i64; 36 | cl_ulong u64; 37 | cl_ulong2 u64v2; 38 | cl_ulong4 u64v; 39 | cl_int i32; 40 | cl_uint u32; 41 | cl_uint4 u32v; 42 | cl_bitfield bits; 43 | cl_bool b; 44 | cl_device_type devtype; 45 | cl_device_mem_cache_type cachetype; 46 | cl_device_local_mem_type lmemtype; 47 | cl_device_topology_amd devtopo_amd; 48 | cl_device_pci_bus_info_khr devtopo_khr; 49 | cl_device_scheduling_controls_capabilities_arm sched_controls; 50 | cl_device_affinity_domain affinity_domain; 51 | cl_device_fp_config fpconfig; 52 | cl_device_fp_atomic_capabilities_ext fp_atomic_caps; 53 | cl_command_queue_properties qprop; 54 | cl_device_command_buffer_capabilities_khr cmdbufcap; 55 | cl_device_exec_capabilities execap; 56 | cl_device_svm_capabilities svmcap; 57 | cl_device_terminate_capability_khr termcap; 58 | } value; 59 | /* pointer base for array data or other auxiliary information */ 60 | union { 61 | void *ptr; // TODO 62 | cl_context ctx; // associated context 63 | } base; 64 | /* Does this ret need escaping as JSON? */ 65 | cl_bool needs_escaping; 66 | }; 67 | 68 | /* Return type of the functions that gather ICD loader info */ 69 | struct icdl_info_ret 70 | { 71 | cl_int err; 72 | /* string representation of the value (if any) */ 73 | struct _strbuf str; 74 | /* error representation of the value (if any) */ 75 | struct _strbuf err_str; 76 | }; 77 | 78 | #define RET_BUF(ret) (ret.err ? &ret.err_str : &ret.str) 79 | #define RET_BUF_PTR(ret) (ret->err ? &ret->err_str : &ret->str) 80 | #define INIT_RET(ret, msg) do { \ 81 | init_strbuf(&ret.str, msg " info string values"); \ 82 | init_strbuf(&ret.err_str, msg " info error values"); \ 83 | } while (0) 84 | 85 | #define UNINIT_RET(ret) do { \ 86 | free_strbuf(&ret.str); \ 87 | free_strbuf(&ret.err_str); \ 88 | } while (0) 89 | 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | /* Memory handling */ 2 | 3 | #ifndef MEMORY_H 4 | #define MEMORY_H 5 | 6 | #include 7 | 8 | #define CHECK_MEM(var, what) do { \ 9 | if (!(var)) { \ 10 | fprintf(stderr, "%s:%d: %s : Out of memory\n", \ 11 | __func__, __LINE__, what); \ 12 | exit(1); \ 13 | } \ 14 | } while (0) 15 | 16 | #define ALLOC(var, num, what) do { \ 17 | var = calloc(num, sizeof(*(var))); \ 18 | CHECK_MEM(var, what); \ 19 | } while (0) 20 | 21 | #define REALLOC(var, num, what) do { \ 22 | var = realloc(var, (num)*sizeof(*(var))); \ 23 | CHECK_MEM(var, what); \ 24 | } while (0) 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/ms_support.h: -------------------------------------------------------------------------------- 1 | /* Missing functions and other misc stuff to support 2 | * the horrible MS C compiler 3 | * 4 | * TODO could be improved by version-checking for C99 support 5 | */ 6 | 7 | #ifndef MS_SUPPORT 8 | #define MS_SUPPORT 9 | 10 | // disable warning about unsafe strncpy vs strncpy_s usage 11 | #pragma warning(disable : 4996) 12 | // disable warning about constant conditional expressions 13 | #pragma warning(disable : 4127) 14 | // disable warning about non-constant aggregate initializer 15 | #pragma warning(disable : 4204) 16 | 17 | // disable warning about global shadowing 18 | #pragma warning(disable : 4459) 19 | // disable warning about parameter shadowing 20 | #pragma warning(disable : 4457) 21 | 22 | // Suppress warning about unused parameters. The macro definition 23 | // _should_ work, but it doesn't on VS2012 (cl 17), may be a version thing 24 | #define UNUSED(x) x __pragma(warning(suppress: 4100)) 25 | // TODO FIXME remove full-blown warning removal where not needed 26 | #pragma warning(disable: 4100) 27 | 28 | // No inline in MS C 29 | #define inline __inline 30 | 31 | // No snprintf in MS C, copy over implementation taken from 32 | // stackoverflow 33 | 34 | #include 35 | #include 36 | 37 | inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) 38 | { 39 | int count = -1; 40 | 41 | if (size != 0) 42 | count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); 43 | if (count == -1) 44 | count = _vscprintf(format, ap); 45 | 46 | return count; 47 | } 48 | 49 | inline int c99_snprintf(char* str, size_t size, const char* format, ...) 50 | { 51 | int count; 52 | va_list ap; 53 | 54 | va_start(ap, format); 55 | count = c99_vsnprintf(str, size, format, ap); 56 | va_end(ap); 57 | 58 | return count; 59 | } 60 | 61 | #define snprintf c99_snprintf 62 | 63 | // And no __func__ either 64 | 65 | #define __func__ __FUNCTION__ 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/opt_out.h: -------------------------------------------------------------------------------- 1 | /* clinfo output options */ 2 | #ifndef OPT_OUT_H 3 | #define OPT_OUT_H 4 | 5 | #include 6 | 7 | #include "ext.h" 8 | 9 | enum output_modes { 10 | CLINFO_HUMAN = 1, /* more human readable */ 11 | CLINFO_RAW = 2, /* property-by-property */ 12 | CLINFO_BOTH = CLINFO_HUMAN | CLINFO_RAW 13 | }; 14 | 15 | /* Specify how we should handle conditional properties. */ 16 | enum cond_prop_modes { 17 | COND_PROP_CHECK = 0, /* default: check, skip if invalid */ 18 | COND_PROP_TRY = 1, /* try, don't print an error if invalid */ 19 | COND_PROP_SHOW = 2 /* try, print an error if invalid */ 20 | }; 21 | 22 | /* Output options */ 23 | struct opt_out { 24 | enum output_modes mode; 25 | enum cond_prop_modes cond; 26 | 27 | /* Specify that we should only print information about specific devices */ 28 | /* TODO proper memory management */ 29 | #define MAX_SELECTED_DEVICES 256 30 | cl_uint2 selected_devices[MAX_SELECTED_DEVICES]; 31 | size_t num_selected_devices; 32 | 33 | /* Specify that we should only print information about a specific property */ 34 | /* TODO proper memory management */ 35 | #define MAX_SELECTED_PROPS 256 36 | const char *selected_props[MAX_SELECTED_PROPS]; 37 | size_t num_selected_props; 38 | 39 | /* Specify if we should only be listing the platform and devices; 40 | * can be done in both human and raw mode, and only the platform 41 | * and device names (and number) will be shown 42 | * TODO check if terminal supports UTF-8 and use Unicode line-drawing 43 | * for the tree in list mode 44 | */ 45 | cl_bool brief; 46 | cl_bool detailed; // !brief 47 | cl_bool offline; 48 | cl_bool null_platform; 49 | 50 | /* JSON output for RAW */ 51 | cl_bool json; 52 | 53 | /* clGetDeviceInfo returns CL_INVALID_VALUE both for unknown properties 54 | * and when the destination variable is too small. Set the following to CL_TRUE 55 | * to check which one is the case 56 | */ 57 | cl_bool check_size; 58 | }; 59 | 60 | static inline cl_bool is_selected_platform(const struct opt_out *output, cl_uint p) { 61 | if (output->num_selected_devices == 0) return CL_TRUE; 62 | 63 | for (cl_uint i = 0; i < output->num_selected_devices; ++i) { 64 | if (p == output->selected_devices[i].s[0]) return CL_TRUE; 65 | } 66 | return CL_FALSE; 67 | } 68 | 69 | static inline cl_bool is_selected_device(const struct opt_out *output, cl_uint p, cl_uint d) { 70 | if (output->num_selected_devices == 0) return CL_TRUE; 71 | 72 | for (cl_uint i = 0; i < output->num_selected_devices; ++i) { 73 | const cl_uint2 cmp = output->selected_devices[i]; 74 | if (p == cmp.s[0] && d == cmp.s[1]) return CL_TRUE; 75 | } 76 | return CL_FALSE; 77 | } 78 | 79 | static inline cl_bool is_selected_prop(const struct opt_out *output, const char *prop) { 80 | if (output->num_selected_props == 0) return CL_TRUE; 81 | 82 | for (cl_uint i = 0; i < output->num_selected_props; ++i) { 83 | if (strstr(prop, output->selected_props[i])) return CL_TRUE; 84 | } 85 | return CL_FALSE; 86 | } 87 | static inline cl_bool is_requested_prop(const struct opt_out *output, const char *prop) { 88 | // NOTE the difference compared to the above: here we are checking if a specific property 89 | // was *requested*, so if none was explicitly requested we return false here. 90 | if (output->num_selected_props == 0) return CL_FALSE; 91 | 92 | for (cl_uint i = 0; i < output->num_selected_props; ++i) { 93 | if (strstr(prop, output->selected_props[i])) return CL_TRUE; 94 | } 95 | return CL_FALSE; 96 | } 97 | #endif 98 | -------------------------------------------------------------------------------- /src/strbuf.h: -------------------------------------------------------------------------------- 1 | /* multi-purpose string _strbuf, will be initialized to be 2 | * at least 1024 bytes long. 3 | */ 4 | 5 | #ifndef STRBUF_H 6 | #define STRBUF_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "memory.h" 14 | #include "fmtmacros.h" 15 | 16 | struct _strbuf 17 | { 18 | char *buf; 19 | size_t sz; /* allocated size */ 20 | size_t end; /* offset to terminating null byte */ 21 | }; 22 | 23 | static inline void realloc_strbuf(struct _strbuf *str, size_t nusz, const char* what) 24 | { 25 | if (nusz > str->sz) { 26 | REALLOC(str->buf, nusz, what); 27 | str->sz = nusz; 28 | } 29 | } 30 | 31 | static inline void reset_strbuf(struct _strbuf *str) 32 | { 33 | str->end = 0; 34 | if (str->buf) str->buf[0] = '\0'; 35 | } 36 | 37 | static inline void init_strbuf(struct _strbuf *str, const char *what) 38 | { 39 | str->sz = 0; 40 | str->buf = NULL; 41 | realloc_strbuf(str, 1024, what); 42 | reset_strbuf(str); 43 | } 44 | 45 | static inline void free_strbuf(struct _strbuf *str) 46 | { 47 | free(str->buf); 48 | str->buf = NULL; 49 | reset_strbuf(str); 50 | } 51 | 52 | static inline void strbuf_append(const char *what, struct _strbuf *str, const char *fmt, ...) 53 | { 54 | va_list ap; 55 | size_t room = str->sz - str->end - 1; 56 | size_t written = 0; 57 | 58 | /* write if we have room */ 59 | va_start(ap, fmt); 60 | written = vsnprintf(str->buf + str->end, room, fmt, ap); 61 | va_end(ap); 62 | 63 | /* if we would have written more, we need to expand the storage */ 64 | if (written >= room) { 65 | realloc_strbuf(str, str->end + written + 1, what); 66 | room = str->sz - str->end; 67 | 68 | /* and re-write */ 69 | va_start(ap, fmt); 70 | written = vsnprintf(str->buf + str->end, room, fmt, ap); 71 | va_end(ap); 72 | } 73 | str->end += written; 74 | } 75 | 76 | static inline void strbuf_append_str_len(const char *what, struct _strbuf *str, 77 | const char *to_append, /* string to append */ 78 | size_t len) /* length of string to append */ 79 | { 80 | size_t room = str->sz - str->end - 1; 81 | 82 | if (len >= room) { 83 | realloc_strbuf(str, str->end + len + 1, what); 84 | } 85 | /* copy up to the terminating NULL */ 86 | memcpy(str->buf + str->end, to_append, len); 87 | str->end += len; 88 | /* ensure we have a NULL in last position, since len may have been used 89 | * to override the original string length */ 90 | str->buf[str->end] = '\0'; 91 | } 92 | 93 | static inline void strbuf_append_str(const char *what, struct _strbuf *str, const char *to_append) 94 | { 95 | strbuf_append_str_len(what, str, to_append, strlen(to_append)); 96 | } 97 | 98 | #define GET_STRING(str, err, cmd, param, param_str, ...) do { \ 99 | size_t nusz; \ 100 | err = cmd(__VA_ARGS__, param, 0, NULL, &nusz); \ 101 | if (REPORT_ERROR(str, err, "get " param_str " size")) break; \ 102 | realloc_strbuf(str, nusz, #param); \ 103 | err = cmd(__VA_ARGS__, param, (str)->sz, (str)->buf, NULL); \ 104 | if (REPORT_ERROR(str, err, "get " param_str)) break; \ 105 | (str)->end = nusz; \ 106 | } while (0) 107 | 108 | #define GET_STRING_LOC(ret, loc, cmd, ...) do { \ 109 | size_t nusz; \ 110 | ret->err = REPORT_ERROR_LOC(ret, \ 111 | cmd(__VA_ARGS__, 0, NULL, &nusz), \ 112 | loc, "get %s size"); \ 113 | if (!ret->err) { \ 114 | realloc_strbuf(&ret->str, nusz, loc->sname); \ 115 | ret->err = REPORT_ERROR_LOC(ret, \ 116 | cmd(__VA_ARGS__, ret->str.sz, ret->str.buf, NULL), \ 117 | loc, "get %s"); \ 118 | } \ 119 | if (!ret->err) { \ 120 | ret->str.end = nusz; \ 121 | } \ 122 | } while (0) 123 | 124 | /* Skip leading whitespace in a string */ 125 | static inline const char* skip_leading_ws(const char *str) 126 | { 127 | const char *ret = str; 128 | while (isspace((unsigned char) *ret)) ++ret; 129 | return ret; 130 | } 131 | 132 | /* Separators: we want to be able to prepend separators as needed to _strbuf, 133 | * which we do only if halfway through the buffer. The callers should first 134 | * call a 'set_separator' and then use add_separator(&offset) to add it, where szval 135 | * is an offset inside the buffer, which will be incremented as needed 136 | */ 137 | 138 | const char *sep; 139 | size_t sepsz; 140 | 141 | void set_separator(const char* _sep) 142 | { 143 | sep = _sep; 144 | sepsz = strlen(sep); 145 | } 146 | 147 | #endif 148 | --------------------------------------------------------------------------------