Code executed on the GPU works with memory physically located on the video card, so it is necessary to be able to allocate arrays in that memory and move data between device and host memory.
To make this more convenient, this library provides a generic interface based on the lisp array API. It is also implemented for lisp arrays themselves.
This method can be used to check if the object implements the interface.
For supported objects it returns either :lisp or :foreign; this specifies which of the element type representations is native for this object’s implementation.
These methods can be used for manual control of memory deallocation.
Note: accessing a deallocated buffer results in a safe runtime exception.
If the buffer is actually backed by a lisp array, returns (values arr t). Otherwise, creates a compatible lisp array, copies the contents there unless no-copy is specified, and returns (values arr nil).
These methods replicate standard library functions for arrays:
These methods can be used in place of aref or row-major-aref to read or write individual buffer elements:
Note that their performance characteristics are not guaranteed to be good enough to make them useful outside of debugging code or REPL. Production code should use bulk copy functions.
The buffers must have the same element type. If t is passed as count, the maximum possible valid value is used.
The result is undefined if the source and destination areas overlap.
The buffers must have the same element type and size. Does nothing if (eq source dest).
Like lisp arrays, a buffer can be displaced to another buffer. All displaced views of the same underlying storage area share the reference count.
The following attributes can be used to define a displaced view (each of the pairs is mutually exclusive):
Specific implementations of the buffer interface may support additional attributes, or impose restrictions on the argument values. For instance, standard lisp arrays don’t support changing the element type or using byte offsets that aren’t divisible by the element size.
Apart from an implementation of buffer methods for standard lisp arrays, the library includes the following buffer types:
This allocates a reference-counted buffer based on CFFI foreign memory:
The element type defaults to single-float (:float).
If the buffer object is garbage-collected, the foreign memory is automatically released.
This allocates a reference-counted buffer based on CUDA linear memory:
The pitch-elt-size argument must be 4, 8 or 16. If it is specified, a pitched block is allocated. The pitch-level parameter specifies how many innermost dimensions are placed within the pitch row; it defaults to 1.
All displaced views of a pitched buffer must either fit within a pitch row, or ensure that the dimensions can be evenly split on the pitch boundary.
Memory blocks from garbage-collected buffers are collected in a queue and released once you try to allocate more memory from the same context. The memory cannot be released directly in the finalizer because of thread affinity issues.
CUDA supports allocating blocks of non-pageable host memory for asynchronous data transfer purposes. This can be exploited via the following interface:
The function is similar to make-foreign-array, but allows one additional key argument that may contain a list of flag keywords:
Device-host memory mapping is exposed through an additional parameter of the buffer-displace generic function:
The following values of the mapping parameter are supported:
Both types of conversion flags do nothing if the buffer is already of the desired type. The mapping parameter may be used together with other displacement attributes, or on its own.
Last edited by angavrilov,