GCOMPILE Usage

From Jacket Wiki

Jump to: navigation, search
Back to GFOR Usage, Forward to Function List

Contents

Introduction

GCOMPILE (and ARRAYFUN) enable Jacket programmers to define GPU kernels using M-code. Through this mechanism, Jacket is able to perform various additional optimizations, which it is otherwise unable to do in standard dynamic MATLAB mode. See our blog post for some examples.

These static optimizations are available through two functions, which can be used interchangeably: GCOMPILE and ARRAYFUN. GCOMPILE can accept strings or function handles, while ARRAYFUN requires function handles. In practice, using GCOMPILE directly can yield a few percent performance improvement as it avoids some caching checks that ARRAYFUN incurs.

GCOMPILE Usage

There are two options for invoking GCOMPILE on your MATLAB code:

M-File Convention

my_fn = gcompile('filename.m');
[A, B, ...] = my_fn(C, ...)

The filename.m file must be in the current MATLAB path.

Inlined Convention

Another method is using the GCOMPILE function call, with the code to inlined directly in your code.


Example 1:

my_fn = gcompile(verbatim);
%{
function [x, y] = foo(z)
  x = z / 4;
  y = z * 2;
%}
 
[A, B] = my_fn(C);

Example 2:

my_fn = gcompile(verbatim);
%{
function x = foo(y)
  x = y .* y;
end
%}
 
input = grand(9);
result = my_fn(input);

Example 3:

my_fn = gcompile(verbatim);
%{
function [out, tag] = foo(src, val)
  out = val;
  tag = 0;
  for i = 1:10
    if out >= 50
      tag = 1;
    end
    out = out + val;
  end
end%}
B = my_fn(A, 5)

ARRAYFUN Usage

ARRAYFUN may be used as follows:

A = arrayfun(fun, S)
A = arrayfun(fun, S, T, ...)
[A, B, ...] = arrayfun(fun, S, ...)

Note that fun must be a function handle. The implementation of fun must be written in M language as a function stored in a file in the path named fun.m

p = gsingle(rand(3));
m = arrayfun(@my_fn, p);

In this example, the file my_fn.m will be compiled by GCOMPILE and then executed. During the first ARRAYFUN call, the function will be called. In subsequent calls, the generated function will be reused. The MATLAB command WHICH can be used to determine which file ARRAYFUN will use.

A function created using GCOMPILE may also be used in ARRAYFUN:

my_fn = gcompile(verbatim);
%{
function x = foo(y)
  x = y .* y;
end
%}
 
input = grand(9);
result = arrayfun(@my_fn, input);

Features

  • Condition statements (e.g. IF) are supported.
  • Loops (e.g. FOR and WHILE) are supported.

Limitations

  • Subscripting/Indexing are not supported.
  • Reductions are not supported within a GCOMPILE function.
  • GCOMPILE functions cannot call other user-defined functions.
  • All input parameters must be either scalar or of the same size. For example, if the first input is a 3x3 matrix, all other inputs must also be either scalar or a 3x3 matrices.
  • All operations are element-wise. As a result, the * and / operators are equivalent to the .* and ./ operators.
  • When using ARRAYFUN, at least one input parameter must be a Jacket datatype, such as GSINGLE or GDOUBLE.
  • Take care when using loops such as FOR and WHILE. GPU kernels have a driver-imposed limitation on the amount of time for execution. Excessive use of loops may cause kernels to time out.
  • FOR loops may only use constants in the loop, and may only increment by a value >= 1, for example:
for i=0:10,      % GOOD
  ...
end
 
for i=0:2:10,    % GOOD
  ...
end

or

for i=0:0.5:10,  % BAD
  ...
end
  • A variable's type is determined by its first usage. For example, in this function, x will be a LOGICAL, and as a result, if y <= 0, x will be true rather than 5.
function x = foo(y)
  if (y > 0)
    x = true;
  else
    x = 5;
  end;
end;
  • Only a single function per file or verbatim block is supported.
  • Switch statements are not supported.
  • Functions such as SQRT with real input only support real output. In the below example, the first result would be NaN, and the second would be 0 + i.
fn = gcompile(verbatim);
%{
function x = foo(y)
  x = sqrt(y);
end
%}
 
fn(gsingle(-1))
fn(gsingle(complex(-1,0)))
Back to the Main Page

Introduction

GCOMPILE (and ARRAYFUN) enable Jacket programmers to define GPU kernels using M-code. Through this mechanism, Jacket is able to perform various additional optimizations, which it is otherwise unable to do in standard dynamic MATLAB mode.

These static optimizations are available through two functions, which can be used interchangeably: GCOMPILE and ARRAYFUN. In practice, we find that GCOMPILE is faster than ARRAYFUN.

GCOMPILE Usage

There are two options for invoking GCOMPILE on your MATLAB code:

M-File Convention

my_fn = gcompile('filename.m');
[A, B, ...] = my_fn(C, ...)

The filename.m file must be in the current MATLAB path.

Inlined Convention

Another method is using the GCOMPILE function call, with the code to inlined directly in your code.


Example 1:

my_fn = gcompile(verbatim);
%{
function [x, y] = foo(z)
  x = z / 4;
  y = z * 2;
%}
 
[A, B] = my_fn(C);

Example 2:

my_fn = gcompile(verbatim);
%{
function x = foo(y)
  x = y .* y;
end
%}
 
input = grand(9);
result = my_fn(input);

Example 3:

my_fn = gcompile(verbatim);
%{
function [out, tag] = foo(src, val)
  out = val;
  tag = 0;
  for i = 1:10
    if out >= 50
      tag = 1;
    end
    out = out + val;
  end
end%}
B = my_fn(A, 5)

ARRAYFUN Usage

ARRAYFUN may be used as follows:

A = arrayfun(fun, S)
A = arrayfun(fun, S, T, ...)
[A, B, ...] = arrayfun(fun, S, ...)

Note that fun must be a function handle. The implementation of fun must be written in M language as a function stored in a file in the path named fun.m

p = gsingle(rand(3));
m = arrayfun(@my_fn, p);

In this example, the file my_fn.m will be compiled by GCOMPILE and then executed. During the first ARRAYFUN call, the function will be called. In subsequent calls, the generated function will be reused. The MATLAB command WHICH can be used to determine which file ARRAYFUN will use.

A function created using GCOMPILE may also be used in ARRAYFUN:

my_fn = gcompile(verbatim);
%{
function x = foo(y)
  x = y .* y;
end
%}
 
input = grand(9);
result = arrayfun(@my_fn, input);

Features

  • Condition statements (e.g. IF) are supported.
  • Loops (e.g. FOR and WHILE) are supported.

Limitations

  • Subscripting/Indexing are not supported.
  • Reductions are not supported within a GCOMPILE function.
  • All input parameters must be either scalar or of the same size. For example, if the first input is a 3x3 matrix, all other inputs must also be either scalar or a 3x3 matrices.
  • All operations are element-wise. As a result, the * and / operators are equivalent to the .* and ./ operators.
  • When using ARRAYFUN, at least one input parameter must be a Jacket datatype, such as GSINGLE or GDOUBLE.
  • Take care when using loops such as FOR and WHILE. GPU kernels have a driver-imposed limitation on the amount of time for execution. Excessive use of loops may cause kernels to time out.
  • FOR loops may only use constants in the loop, and may only increment by a value >= 1, for example:
for i=0:10,      % GOOD
  ...
end
 
for i=0:2:10,    % GOOD
  ...
end

or

for i=0:0.5:10,  % BAD
  ...
end
  • A variable's type is determined by its first usage. For example, in this function, x will be a LOGICAL, and as a result, if y <= 0, x will be true rather than 5.
function x = foo(y)
  if (y > 0)
    x = true;
  else
    x = 5;
  end;
end;
  • Only a single function per file or verbatim block is supported.
  • Switch statements are not supported.
  • Functions such as SQRT with real input only support real output. In the below example, the first result would be NaN, and the second would be 0 + i.
fn = gcompile(verbatim);
%{
function x = foo(y)
  x = sqrt(y);
end
%}
 
fn(gsingle(-1))
fn(gsingle(complex(-1,0)))

Known Issues

  • ~n operator is not mapping properly. Instead, use not(n). (Will be fixed in 1.5.1)
  • a ^ b is not mapping properly. Instead, use power(a,b). (Will be fixed in 1.5.1)

Supported Functions

See the GCOMPILE Supported Category for a list of functions supported with GCOMPILE and ARRAYFUN.

Forward to Function List
Personal tools