├── .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 |
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 | Build status | Windows binaries |
147 |
148 |  |
151 | 32-bit |
152 | 64-bit |
153 |
154 |
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 |
--------------------------------------------------------------------------------