The functions listed in this document are implemented in the Quasar runtime library (Quasar.exe). Hence, the source code of these functions is not available.
builtin_functions.q | The functions listed in this document are implemented in the Quasar runtime library (Quasar.exe). |
built-in constants | |
mathematical functions | Mathematical functions that can be used in both device/kernel functions or host code. |
abs | Computes the absolute value of a real-valued number/matrix, the modulus of a complex number/matrix. |
asin | Computes the arcus sine of a real-valued number/matrix. |
acos | Computes the arcus cosine of a real-valued number/matrix |
atan | Computes the arcus tangent of a real-valued number/matrix. |
atan2 | Computes the arcus tangent of a real-valued number/matrix with two parameters Returns the principal value of the arc tangent of y/x, expressed in radians. |
ceil | Returns the nearest integer not less than x |
round | Rounds to the nearest integer |
cos | Computes the cosine of x, where x is specified in radials |
sin | Computes the sine of x, where x is specified in radials |
exp | Computes e^x |
exp2 | Computes 2^x |
floor | Returns the nearest integer not greater than x. |
mod | Computes the modulus of x after division by a |
frac | Computes the fractional part of x such that x = floor(x) + frac(x) |
log | Computes the natural logarithm of x |
log2 | Computes the logarithm of x base 2 |
log10 | Computes the logarithm of x base 10 |
max | Computes the maximum value of all elements x. |
min | Computes the minimum value of all elements x. |
pow | Returns x to the power a. |
saturate | Saturates the values of x to the range [0,1] |
sign | Returns +1 if x is positive, 0 if x == 0, and -1 if x is negative. |
sqrt | Returns the square root of x. |
tan | Computes the tangent of x, where x is specified in radials |
conj | Returns the conjugate of a complex-valued number (or matrix) |
float | Converts an integer number to floating point |
int | Converts a floating point number to integer |
isinf | Returns 1 if x is infinite, 0 otherwise |
isfinite | Returns 1 if x is finite, 0 otherwise |
isnan | Returns 1 if x is NaN, 0 otherwise |
periodize | Periodic extension of input coordinate between [0,p[. |
mirror_ext | Mirror extension of the input coordinate between [0,p[ |
clamp | Clamps the input coordinate between [0,p], i.e. |
factorial | Returns x! |
discrete Fourier transforms | |
fft1 | Computes the 1D Discrete Fourier Transform (DFT) of x along the last dimension that has size != 1. |
fft2 | Computes the 2D Discrete Fourier Transform (DFT) of x along the first (0) and second (1) dimension of x |
fft3 | Computes the 3D Discrete Fourier Transform (DFT) of x. |
ifft1 | Computes the 1D inverse Discrete Fourier Transform (DFT) of x along the last dimension that has size != 1. |
ifft2 | Computes the 2D inverse Discrete Fourier Transform (DFT) of x along the first (0) and second (1) dimension of x |
ifft3 | Computes the 3D inverse Discrete Fourier Transform (DFT) of x. |
matrix processing/ | |
numel | Returns the number of elements in x |
size | Returns a vector of length 3 with the size of x |
size | Returns the size of x along dimension y (y=0,1,2) |
complex | Converts a real-valued number/matrix to a complex-valued number/matrix |
complex | Returns a complex-valued number/matrix, based on the specified real/imaginary parts |
real | Returns the real part of a complex number / matrix |
transpose | Transposes a matrix. |
imag | Returns the imaginary part of a complex number / matrix |
sum | Computes the sum of all elements of a matrix (along all dimensions) |
sum | Computes the sum of all elements of a matrix, along the specified dimension d=0,1,2 |
cumsum | Computes the cumulative sum of all elements of a matrix (along the rows) |
prod | Computes the product of all elements of a matrix (along all dimensions) |
prod | Computes the product of all elements of a matrix, along the specified dimension d=0,1,2 |
cumprod | Computes the cumulative product of all elements of a matrix (along the rows) |
linspace | Returns a linearly spaced vector from a (inclusive) to b (inclusive), containing c elements. |
copy | Returns a one-level deep copy of the specified variable. |
eye | Creates an n x n identity matrix |
repmat | Repeats the matrix ‘dims’ times. |
reshape | Changes the dimensions of a matrix, by reordering the elements of the matrix. |
shuffledims | Performs a permutation on the dimensions of a matrix |
matrix creation/ | |
shared | Allocates uninitialized shared memory according to the dimensions x. |
shared_zeros | Allocates zero-initialized shared memory according to the dimensions x. |
cshared | Allocates uninitialized complex-valued shared memory according to the dimensions x. |
cshared_zeros | Allocates zero-initialized complex-valued shared memory according to the dimensions x. |
zeros | Creates a zero-initialized real-valued data vector of length a |
zeros | Creates a zero-initialized real-valued data matrix of dimensions a x b |
zeros | Creates a zero-initialized real-valued data cube of dimensions a x b x c |
ones | Creates a one-initialized real-valued data vector of length a |
ones | Creates a one-initialized real-valued data matrix of dimensions a x b |
ones | Creates a one-initialized real-valued data vector of dimensions a x b x c |
uninit | Creates an uninitialized real-valued data vector of length a |
uninit | Creates a uninitialized real-valued data matrix of dimensions a x b |
uninit | Creates a uninitialized real-valued data vector of dimensions a x b x c |
czeros | Creates a zero-initialized complex-valued data vector of length a |
czeros | Creates a zero-initialized complex-valued data matrix of dimensions a x b |
czeros | Creates a zero-initialized complex-valued data matrix of dimensions a x b x c |
czeros | Creates a uninitialized complex-valued data vector of length a |
cuninit | Creates a uninitialized complex-valued data matrix of dimensions a x b |
czeros | Creates a uninitialized complex-valued data matrix of dimensions a x b x c |
random number generators | |
rand | Creates a uniformly distributed data vector of length a (values are in the range [0,1[) |
rand | Creates a uniformly distributed data vector of dimensions a x b (values are in the range [0,1[) |
rand | Creates a uniformly distributed data vector of dimensions a x b x c (values are in the range [0,1[) |
randn | Creates a Gaussian distributed data vector of length a, with mean=0 and standard deviation=1 |
randn | Creates a Gaussian distributed data vector of dimensions a x b, with mean=0 and standard deviation=1 |
randn | Creates a Gaussian distributed data vector of dimensions a x b x c, with mean=0 and standard deviation=1 |
cell matrix functions | |
cell | Creates an empty cell vector of length a |
cell | Creates an empty cell matrix of dimensions a x b |
cell | Creates an empty cell vector of dimensions a x b x c |
image I/ | |
imread | Reads an image input file. |
imwrite | Saves an image as a file |
imwrite | Saves an image as a file |
general utility functions | |
type | Returns the type of an object |
type | Checks whether the variable ‘x’ is of type ‘y’ |
tic | Set a timer to be read by the next call to toc. |
toc | Print and return the time elapsed since the last tic |
object | Creates an empty untyped object, which can be used to store data. |
Prints text to the console | |
error | Generates an error with the specified message |
assert | Asserts that x is true, and generates an error otherwise (if x is false) |
eval | Dynamic expression evaluation |
pause | Delays the program for “delay” milliseconds |
string parsing/ | |
sprintf | C-like string formatting |
sscanf | Parses a string using C-style formatting rules |
printf | C-like printing to the console |
strcat | Concatenates strings |
File I/ | File input/output routines |
fopen | Opens the specified file for reading or writing. |
fclose | Closes the specified file (that was previously opened using fopen) |
fread | Reads binary data from a file (opened in binary mode) |
fwrite | Writes binary data to a file (opened in binary mode) |
fprint | Prints text to a file (opened in text mode) |
fprintf | Prints C-style formatted text to a file (opened in text mode) |
fscanf | Reads C-style formatted text from a file (opened in text mode) |
dir | Lists all files in a given directory according to the specification |
save | Saves variables to a file |
load | Loads variables from a file |
parallel processing functions | |
parallel_do | Lauches a given kernel function fn in parallel to every element of a certain matrix |
serial_do | Lauches a given kernel function fn in serial to every element of a certain matrix |
max_block_size | Returns the maximum block size that can be used for the function parallel_do. |
visualization functions | |
disp | Shows a visualizer window for matrices |
hold | Retain current graph when adding new graphs (plot, scatter or imshow function). |
sync_framerate | Sets the synchronization framerate for the imshow function, in number of frames displayed per second. |
plot | Data visualization function |
scatter | Data visualization function |
title | Modifies the title of the previous plot |
xlabel | Modifies the label of the x-axis of the previous plot |
ylabel | Modifies the label of the y-axis of the previous plot |
xlim | Modifies the range of the x-axis of the previous plot |
ylim | Modifies the range of the y-axis of the previous plot |
imshow | Image visualization function. |
imshow | Image visualization function. |
form | Opens a new window |
Transposes a matrix.
function y = transpose(r)
Returns a one-level deep copy of the specified variable. This is useful for creating e.g. a temporary copy of a matrix that can be changed without affecting the original matrix. Note: to copy nested objects (such as cell matrices), it can be useful to use the function <deepcopy>
function y = copy(x)
<deepcopy>
Changes the dimensions of a matrix, by reordering the elements of the matrix. Note that Quasar uses a row-major ordering of the elements by default.
function y = reshape(a,dims)
a | the matrix to reshape |
dims | the new dimensions of the matrix. Note that the number of elements may not change, i.e. it is required that prod(dims) = numel(a) |
Performs a permutation on the dimensions of a matrix
function y = shuffledims(a,dims)
a | the matrix to change |
dims | the new order of the dimensions. For example: |
Allocates uninitialized shared memory according to the dimensions x.
function y = shared(x)
Allocates zero-initialized shared memory according to the dimensions x. It is important to use the keyword ‘syncthreads’ because the zero- initialization operation is distributed along all threads. The ‘syncthreads’ keyword then ensures that all threads see a fully zero-initialized copy of y.
function y = shared_zeros(x) syncthreads
Allocates uninitialized complex-valued shared memory according to the dimensions x.
function y = cshared(x) function y = complex(shared(x)) % through reductions
Allocates zero-initialized complex-valued shared memory according to the dimensions x. It is important to use the keyword ‘syncthreads’ because the zero- initialization operation is distributed along all threads. The ‘syncthreads’ keyword then ensures that all threads see a fully zero-initialized copy of y.
function y = cshared_zeros(x) function y = complex(shared_zeros(x)) % through reductions syncthreads
Saves an image as a file
function y = imwrite(filename,data)
filename | the output file name |
data | the data to save |
Supported file formats are: BMP, GIF, JPEG, EXIF, PNG, TIFF. The input ‘data’ is in the range [0-255] for 8-bit images, and in the range [0-65535] for 16-bit images. Values outside this range are automatically clipped
Saves an image as a file
function y = imwrite(filename,data,range)
filename | the output file name |
data | the data to save |
range | the range of the data. The data will be automatically scaled using the specified range to the default ranges (i.e. [0-255] for 8-bit images, and [0-65535] for 16-bit images). |
Supported file formats are: BMP, GIF, JPEG, EXIF, PNG, TIFF.
Asserts that x is true, and generates an error otherwise (if x is false)
function [] = assert(x)
x | the condition to test. |
function y = do_something(x : ??) assert(type(x, "vec[int]")) end
Dynamic expression evaluation
function y = eval(expr : string)
val = eval("(x) -> 3*eye(x)")(8)
Here, the eval function parses the string expression (x) -> 3*eye(x) and returns a corresponding lambda expression. This lambda expression can then be evaluated at the same speed as regular lambda expressions. This can be useful for simulations (e.g. passing functions through the command line).
Parses a string using C-style formatting rules
function [varargs] = sscanf(text, fmt)
text | the text to parse |
fmt | a C-style format specifier (e.g. “%s %d %c”) |
A cell array with the results. It is possible to use this cell array in a multiple-variable assignment. For example:
[x,y,z] = sscanf("[0.2,0.5,0.8], "[%f,%d,%f]")
Opens the specified file for reading or writing. The file handle must be closed using fclose
function file_handle = fopen(filename : string, options)
filename | the path of the file to open |
options | a string containing the options for loading: |
Reads binary data from a file (opened in binary mode)
function y = fread(file_handle, dims, typestring : string)
file_handle | the handle of the file (obtained using fopen) to read from |
dims | the dimensions of the data to read |
typestring | the data type to read. Supported typestrings are: int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64 |
a matrix of dimensions ‘dims’. Note that row-major order is used in Quasar. In case column-major order is desired, the function shuffledims can be used to change the order.
Writes binary data to a file (opened in binary mode)
function y = fwrite(file_handle, value, typestring : string)
file_handle | the handle of the file (obtained using fopen) to write to |
value | the data to write. Note that row-major order is used in Quasar. In case column-major order is desired, the function shuffledims can be used to change the order. |
typestring | the data type to read. Supported typestrings are: int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64 |
Reads C-style formatted text from a file (opened in text mode)
function [varargs] = fscanf(file_handle, fmt)
file_handle | the handle of the file (obtained using fopen) to read from |
fmt | a C-style format specifier (e.g. “%s %d %c”) |
A cell array with the results. It is possible to use this cell array in a multiple-variable assignment. For example:
[x,y,z] = fscanf(handle, "[%f,%d,%f]")
Saves variables to a file
function [] = save(file_name : string, varargs) builtin
save("out.dat",A,B,C)
Loads variables from a file
function [varargs] = load(file_name : string)
[A,B,C] = load("out.dat") [A:scalar, B:cube, C:vec[cube]] = load("out.dat")
Lauches a given kernel function fn in parallel to every element of a certain matrix
function [] = parallel_do(dim,varargs,fn : kernel_function)
A kernel function is a Quasar function with a special attribute kernel , that can be parallelized. Kernel functions are launched in parallel on every element of a certain matrix, using the parallel_do built-in function. The kernel attribute specifies that the function should be natively compiled for the targeted computation engine (e.g. CUDA, CPU). Consequently, kernel functions are considerably faster than regular functions, not only due to their parallelization. As example, consider the following algorithm:
function [] = __kernel__ color_temperature(x : cube, y : cube, temp, cold : vec3, hot : vec3, pos : vec2) input = x[pos[0],pos[1],0..2] if temp<0 output = lerp(input,cold,(-0.25)*temp) else output = lerp(input,hot,0.25*temp) endif y[pos[0],pos[1],0..2] = output end hot = [1.0,0.2,0.0]*255 cold = [0.3,0.4,1]*255 img_out = zeros(size(img_in)) parallel_do(size(img_out,0..1),img_in,img_out,temp,cold,hot,color_temperature)
The kernel function is launched on a grid of dimensions size(img_out,0..1) using the parallel_do construct. This means that every pixel in img_out will be addressed individually by parallel_do, and correspondingly the function color_temperature will be called for every pixel position.
For a kernel function, all arguments need to be explicitly typed. Recall that untyped arguments (or arguments without type) in Quasar are denoted by ??. Untyped arguments are not allowed because these arguments can not be mapped onto a device architecture.
Kernel functions differ from regular functions, in the sense that in addition to the standard data types, some special data types are allowed:
However, some datatypes can currently not be passed as arguments to kernel functions: cell matrices containing unknown types (??) and strings. To pass cell matrices, use parametrized matrix types (vec[cube], mat[cube], mat[vec], etc., see [sec:Typing-system-full] ). Device functions ( device ) possibly containing closure variables (see [sub:closures]), can also be passed.
For vectors of length \leq16, it is more efficient to use the dedicated datatypes vecx, ivecx, cvecx, with x=1,2,varargs,16 since they are treated in a special way (e.g. passed by value on the stack, SIMD instructions if the underlying C/C++ compiler supports them.). Note that inside kernel functions, it is recommended to use integers instead of scalars (when possible). This may yield a speed-up of about 30% using the CUDA computation engine. When a scalar constant contains a decimal point (e.g., 1.2), the compiler will consider this constant to be a floating point number, otherwise it will be considered to be an integer.
dims | vector of length 3. |
fn | the kernel function to apply in parallel |
Note that a kernel function cannot have output arguments. Instead, the return values should be written to the input arguments passed by reference, i.e. arguments of types vec, mat, cube, cvec, cmat, ccube. There are some special arguments that can be defined in the kernel function declaration, but that do not need to be passed to parallel_do:
The parallel_do function performs the following sequential program in parallel:
blkdim = choose_optimal_block_size(kernel_function) for m=0..dimensions[0]-1 for n=0..dimensions[1]-1 for p=0..dimensions[2]-1 pos = [m,n,p] blkpos = mod(pos, blkdim) blkidx = floor(pos/blkdim) kernel_function(inarg1, varargs, inargN, [pos], [blkpos], [blkidx], [blkdim]) end end end
Here, first optimal block dimensions (blkdim) for the given kernel function are being selected. Then, kernel_function is run inside the three loops, prod(dimensions)=dimensions[0]\times dimensions[1] x dimensions[2] times.
Special modifiers are available for kernel function arguments. The modifiers are specified using the apostrophe-symbol:
function [] = __kernel__ imfilter_kernel_nonsep_mirror_ext(y : cube'unchecked, x : cube'unchecked, mask : mat'unchecked'const, center : ivec2, pos : ivec3)
These modifiers specify how vector/matrix/cube elements are accessed, and in particular enable efficient boundary handling in image processing:
See also: serial_do
Lauches a given kernel function fn in serial to every element of a certain matrix
function [] = serial_do(dim,varargs,fn : kernel_function)
The parameters of the serial_do function are exactly the same as those of parallel_do. The main difference between serial_do and parallel_do is that the operations are performed sequentially rather than in parallel. This is useful for algorithms that cannot be parallelized (or that are very difficult to parallelize). Generally, the serial operations will be performed by the host CPU.
See also: parallel_do
Returns the maximum block size that can be used for the function parallel_do.
function y = max_block_size() function y = max_block_size(sz) function y = max_block_size(fn : kernel_function, sz)
sz | the upper bound for the size returned by max_block_size. A vector of length 1, 2 or 3. |
fn | the kernel function for which the maximum block size is determined. Depending on the register usage (see below), the actual maximal block size can be lower than the maximal block size of the device. |
The block size (blkdim) can be manually specified, through the function parallel_do. ‘sz’ depends on the amount of shared memory you want to use within the kernel. The function max_block_size computes the maximally allowed block size for the given kernel function. Note that for:
Retain current graph when adding new graphs (plot, scatter or imshow function). Note that a graph should already have been created when the function is called.
function success = hold(val : string) hold("on") hold("off")
val | either “on” or “off” |
success | returns TRUE if a graph is existing |
sync_framerate(25) % set frame rate to 25 frames/second repeat frame = ... % generate a frame imshow(frame,[0,255]) until !hold("on")
Sets the synchronization framerate for the imshow function, in number of frames displayed per second. This function is useful when you want to display images at a given frame rate.
function [] = sync_framerate(fps : scalar)
fps | the number of frames per second |