-
Notifications
You must be signed in to change notification settings - Fork 7
Code Definition
This page describes how GPU code and variables can be defined.
Note: see the Definer Syntax page for an explanation of the def macro.
- (def (gpu-macro e) name (args…) …)
Defines a GPU-specific macro. The behavior requirements are similar to normal compiler macros.
- (def (gpu-type e :gpu-only t) name (args…) …)
This definition is equivalent to deftype, but expanders defined this way are also accessible by the GPU code translator.
If :gpu-only is true, an ordinary deftype is not performed, so effectively the type is defined only for GPU code.
GPU code is packaged in modules, which can contain a number of variables and functions that are compiled together. A module can be defined in the following way:
(def (gpu-module e) name specs...)
The following item specifications are supported:
- (:conc-name prefix)
Defines a new prefix to prepend to variable and function names. The default is module name + “-”, as with standard structure accessors.
- (:variable name type)
- (:global name type)
Defines a module variable. It can be written from the GPU code.
Variables can either have a primitive scalar type, or point to a specialized array of primitive items. If all dimensions of an array are specified as constants, it is statically allocated; otherwise you have to allocate an appropriately typed buffer and assign it to the variable from the host.
- (:variables type names…)
- (:globals type names…)
A shortcut for defining many globals of the same type.
- (:constant name type)
- (:constants type names…)
Define module variables that can only be read from GPU code. They can still be modified from lisp.
Appropriately marking variables constant allows their values to be cached by the GPU hardware, thus boosting the read performance tremendously. Note that since GPU code cannot allocate memory, and therefore has no need to change internal pointers used to implement dynamic array globals, they are automatically declared constant.
- (:kernel name (args…) body…)
Defines a kernel, i.e. a GPU function callable from ordinary lisp code.
All kernel argument types must be declared. Optional and rest arguments are not allowed. Keyword and &aux arguments are supported, but they are evaluated in lisp code before the real GPU function is invoked. This causes &aux arguments to behave differently from top-level let bindings, thus making them actually useful.
Kernels accept additional pre-defined keyword arguments that specify things like the number of threads to launch.
On the lisp side, a GPU module definition creates wrapper symbol macros and functions for all listed variables and kernels. Their names are derived in a way similar to struct field accessors. If the export flag is passed to the definer, all of their names are exported.
The wrappers implicitly depend on the active GPU context of the current thread.