cns
cns
function. This includes initializing a model on a GPU, running it, getting and setting fields, etc.
cns
function causes MATLAB to wait until the operation is complete. For ease of exposition in these sections, only the single-session, synchronous syntax is given for each command.
Initializing and Deallocating cns('init')
Initialize a network model on a GPU (or CPU). cns('test')
Test initialization, displaying memory usage. cns('platform')
Change the defaults for some 'init'
parameters.cns('done')
Deallocate model, freeing resources.
Getting and Setting Fieldscns('get')
Retrieve fields from an initialized model. cns('update')
Retrieve all variables from an initialized model. cns('set')
Change the value of fields in an initialized model.
Running the Modelcns('run')
Run an initialized model for some number of full iterations, possibly retrieving time series of some variables. cns('step')
Run an initialized model through one or more steps of a single iteration, possibly retrieving some variables.
General Remarks on Asynchronous Operation Asynchronous Mode Syntax: a Multi-Session Example Script Initializing and Deallocating Sessions Running and Waiting Input and Output Other Useful Commands
cns('init')
cns('init', m) cns('init', m, platform) cns('init', m, platform, nice) |
m
platform
'gpu'
):
'gpu'
- use the first available GPU (assuming exclusive access has been set up -- if not, this is the same as 'gpu0'
).
'gpu#'
- use the specified GPU ('gpu0'
, 'gpu1'
, etc.)
'cpu'
- use the CPU.
'debug'
- use the CPU in debug mode, which enables the PRINT
and ERROR
macros.
nice
'nice'
):
'nice'
- yield CPU while waiting for the GPU.
'mean'
- don't yield CPU while waiting for the GPU.
init
, you can call it again to re-initialize using a different model structure, without first calling done
, as long as the new model uses the same package and the platform
and nice
flag do not change. Omitting the done
call means you do not release the GPU, avoiding the possibility of it being claimed by another user.
The platform
call can be used to change the default values of platform
and nice
so you do not have to provide values with every init
call.
CPU mode is much slower than GPU mode, but is useful when you don't have access to a GPU, or want to use the PRINT
and ERROR
macros for debugging.
The mean
option can be about 10% faster than nice
, but it causes CPU usage to stay pinned at 100% even when the only processing is happening on the GPU, making the CPU unavailable to other processes.
Initialization sets the value of ITER_NO
to 1.
cns('test')
init
call might be failing.
init
call.
test
call deallocates the model immediately, whether the initialization succeeds or not.
cns('platform')
init
call so that you do not have to provide them in every init
call.
cns('platform', platform) cns('platform', platform, nice) |
platform, nice
init
call.
init
call. These defaults will persist until MATLAB exits.
cns('done')
cns('done') |
cns('get')
a = cns('get', field-params) [a, a, ...] = cns('get', {field-params}, {field-params}, ...) |
field-params
a
field-params
.
cns('update')
m2 = cns('update', m1) |
m1
m2
update
call would still store separate values for every cell and synapse in the updated model structure.
cns('set')
cns('set', field-params, a) cns('set', {field-params, a}, {field-params, a}, ...) |
field-params
a
cns('run')
cns('run') cns('run', iterations) [s, s, ...] = cns('run', {field-params}, {field-params}, ...) [s, s, ...] = cns('run', iterations, {field-params}, {field-params}, ...) [s, s, ...] = cns('run', iterations, sampleRate, {field-params}, {field-params}, ...) [s, s, ...] = cns('run', iterations, sampleRate, bufferSize, {field-params}, {field-params}, ...) |
iterations
field-params
sampleRate
.
s
field-params
. Because sampling may have occurred multiple times (depending on iterations
and sampleRate
), each output will have an additional dimension representing the sample number. This will be dimension 1.
sampleRate
bufferSize
[s, s, ...]
in GPU memory and transfer them back to MATLAB when the run
call is complete. This is fastest, but may require more GPU memory than is available. Setting bufferSize
to n
means CNS will perform a GPU-MATLAB transfer whenever it has collected n
samples (and any remaining samples will get transferred when the run
call completes).
run
call automatically increments ITER_NO
after every iteration.
cns('step')
cns('step', step) [a, a, ...] = cns('step', step, {field-params}, {field-params}, ...) |
step
field-params
a
field-params
.
step
call does not update ITER_NO
, although you may do so yourself via a set
call.
get
and set
calls, and optionally the run
and step
calls, all involve identifying fields or subranges of fields.
z, field |
z
0
for a model-level field.
(Note: for the get
and set
calls only, you may pass a negative number (-g
) to indicate an entire group of layers (group g
). In this case, the corresponding value a
returned by get
will be a cell array of values, one per layer in the group. Similarly, the corresponding value a
accepted by set
must be a cell array.)
field
z, field, additional-arguments |
These are as follows:
Field Class | Optional (*) Additional Arguments | |
Single-Valued | Multivalued | |
parameter | none | values |
N-D array | c1, c2, ... |
values (*) values (*), c1, c2, ... |
cell field | c1, c2, ... |
values values, c1, c2, ... |
synapse field | synapses synapses, c1, c2, ... |
values values, synapses values, synapses, c1, c2, ... |
ITER_NO | none | n/a |
values
Negative indices count backwards from the number of values: -1 means the last value, -2 the second-to-last, [-3 -1] means the last three values, etc.
(*) Note: for multivalued N-D array fields, this parameter is actually required, and must be a scalar.
synapses
c1, c2, ...
z
using from 1 to N indices, where N is the dimensionality of layer z
. (See cns_iconv
for an explanation of using less than N indices.) If no indices are provided, defaults to the entire layer.
Each index cn
can be a scalar indicating a single position, a two-element vector indicating a range of positions, or [] indicating all positions for that dimension. Negative indices count backwards from the size of the dimension: -1 means the last position, -2 the second-to-last, [-3 -1] means the last three positions, etc.
For N-D array fields, everything is the same, except you are identifying elements of an array, not cells of a layer. If no indices are provided, defaults to the entire array.
Even in single-GPU systems, asynchronous operation can help maximize use of computing resources by allowing a MATLAB script to perform (CPU-based) processing while a model is executing on the GPU.
Note 1: this functionality is currently only available under Linux or Mac OS. Your compiler must have the <pthread.h>
library.
Note 2: concurrency involving multiple computers is outside the scope of CNS, but since CNS is called just like any other MATLAB program, it will be compatible with any multi-computer concurrency solution that can run MATLAB jobs.
To run one or more models asynchronously, one writes a MATLAB script that:
Most cns
commands are the same as in the synchronous case, but with the addition of a session ID to identify which concurrently running session is being referred to. The session ID variable is shown in red
below. When given as input, the session ID is always the second argument to the cns
function, right after the command name ('run'
, 'get'
, etc.) There are also a few new commands (e.g. the 'wait'
command) that only work with session IDs.
The following sections discuss asynchronous mode
m = ...; % a model structure z_in = ...; % number of the model's input layer z_out = ...; % number of the model's output layer paths = ...; % a cell array of image paths % Create one session per GPU. Initially none of them will be running. % Note we are assuming the GPUs have been configured for exclusive access. for i = 1 : cns('devcount') sid = cns('init', cns_newsession, m); % Initialize a new session and get its session ID. cns('set', sid, '$imno', 0); % Create session property '$imno' and set it to 0. end next_imno = 1; while true % Read the next image. If this is not the first time through the loop, this can happen % while earlier images are still being processed. if next_imno <= numel(paths) im = imread(paths{next_imno}); end % Wait for any session to finish processing the image it's currently working on. If % we're just starting, all sessions will be waiting and the one with the lowest session % ID will be chosen. When we've run out of images, code below will start closing the % sessions. When there are no more open sessions, we're done. sid = cns('wait', 'any'); if isempty(sid), break; end % Retrieve the image number the session was working on (stored in the '$imno' property). imno = cns('get', sid, '$imno'); if imno > 0 out = cns('get', sid, z_out, 'val'); % Retrieve the output. ... % Do something useful with the output here. end % If there are still images left to process, load the next one into the waiting session % and start it running again. Otherwise, close the session. if next_imno <= numel(paths) cns('set', sid, z_in, 'val', im); % Load the input image. cns('set', sid, '$imno', next_imno); % Remember the image number. cns('run', sid); % Process the image (asynchronously). next_imno = next_imno + 1; else cns('done', sid); end end
cns
commands in more detail.
cns('init')
command:
The first version creates a new session and returns the session ID. The second version is used to re-initialize an existing session with a new model structure. Other arguments (not shown here) are identical to those in the basic
sid = cns('init', cns_newsession, m, ...) sid = cns('init', sid, m, ...)
cns('init')
command. Note that setting exclusive access can be very helpful when working with multiple sessions.
The cns_newsession
function can be used to preallocate an array of session IDs, like this:
Sessions can be closed using the following commands:sids = cns_newsession(1, 4); for i = 1 : 4 sids(i) = cns('init', cns_newsession, m, ...); end
Where:
cns('done', sids) cns('done', 'all')
sids
is an array of zero or more session IDs
'all'
means close all active sessions
cns('run')
and cns('step')
are:
Aside from the session ID, all the arguments are the same as in the synchronous case, except that there can be no output arguments. You can still request variables to be retrieved (i.e. you can still specify field-params), but if you supply output arguments, then CNS will block your MATLAB script until the
cns('run', sid, ...) cns('step', sid, ...)
'run'
or 'step'
call is complete -- i.e. the call will not be asynchronous. If you want the call to return immediately so that your MATLAB script can move on to do something else while the 'run'
or 'step'
call executes, you have to omit the output arguments. You can pick up any outputs later using a cns('output')
call.
Once you have issued an asynchronous 'run'
or 'step'
call for a session, making any other cns
call for that session (for example, a 'get'
or 'set'
call) will implicitly cause MATLAB to stop and wait for the previous asynchronous call to complete.
Waiting can be explicitly controlled using the following commands, both of which block MATLAB until at least one of a list of sessions completes its work:
The first version waits for any of a list of sessions whose IDs you supply; the second waits for any active session. The return value will be the ID of the first session of interest to complete. (If
sid = cns('wait', sids) sid = cns('wait', 'any')
sids
is empty, or there are no active sessions, the return value will be empty.)The following commands are similar, except that there is no waiting; these calls always return immediately:
Here, if any of the sessions of interest have completed, the return value will be one of their IDs; otherwise the return value will be empty. It is an error to call this function with
sid = cns('poll', sids) sid = cns('poll', 'any')
sids
empty or with no active sessions.
cns('run')
or cns('step')
command.
The number of output parameters must match the number of outputs requested in the
[s, s, ...] = cns('output', sid) [a, a, ...] = cns('output', sid)
'run'
or 'step' call.
The other input/output commands ('get'
, 'update'
, and 'set'
) all have identical syntax to their synchronous counterparts, except that the second argument is a session ID. All these commands, and the 'output'
command, implicitly cause MATLAB to wait if the session is still executing.
'$imno'
(image number) property with every session. This information doesn't need to be propagated over to the GPU; it just needs to be available from within MATLAB. Such 'session properties' can be set and retrieved as follows:
Here,
cns('set', sid, propname, value) value = cns('get', sid, propname)
propname
must be a string starting with '$'
, such as our '$imno'
example.The following call reports the number of devices (e.g. GPUs) your computer has:
The first version reports this number for the currently selected platform (
count = cns('devcount') count = cns('devcount', platform)
'gpu'
by default). The second version reports this number for the platform you supply.
The following call returns a vector of session IDs for all active sessions:
if the platform is: count
will be:'gpu'
the number of GPUs in the computer 'gpu#'
1 'cpu' or 'debug'
inf
Finally, this last call is useful when you have multiple sessions and:
sids = cns('sessions')
cns
calls, but
'use'
call allows you to set a session ID that will be used by cns
calls that do not pass a session ID explicitly. The affected calls are init
, done
, get
, update
, set
, run
, and step
. The following three commands allow you to set, clear and retrieve this session ID.
cns('use', sid) cns('use', 'none') sid = cns('use')