spaic.Backend package

Submodules

spaic.Backend.Builder module

Created on 2020/9/15 @project: SPAIC @filename: Builder @author: Hong Chaofei @contact: hongchf@gmail.com

@description:

spaic.Backend.Backend module

Created on 2020/8/6 @project: SPAIC @filename: Backend @author: Hong Chaofei @contact: hongchf@gmail.com @description: 定义网络仿真使用的backend,如 Pytorch, Tensorflow, CUDA, 达尔文芯片等,以及相应的微分方程求解方法比如 Euler, 2阶 Runge-Kutta等

class spaic.Backend.Backend.Backend(dt=0.1)[source]

Bases: ABC

Basic backend class. All specified backend backend should subclass it. The backend is a parameter for the build function and becomes an attribute of all objects defined in the frontend backend network in building process. These objects build their initial data and specified operations into the attributes of backend, according to _variables and _operations respectively. The data will update in each step according the computation graph. :param dt: the length of a backend timestep, in millisecond. :type dt: float, optional

Variables:
  • device (str) – the desired device of returned tensor. Its value can be ‘cpu’ or ‘cuda’. If None, uses the current device for the default tensor type.

  • builded (bool) – whether the object defined in the frontend backend network has been builded.

  • time (float) – current backend time, in millisecond.

  • n_time_step (int) – the num of current time step.

  • _variables (OrderedDict) – records all variables from the build function of frontend objects.

  • _parameters_dict (OrderedDict) – records the variables to be trained.

  • _InitVariables_dict (OrderedDict) – reserves a copy of the initialization variables for initialization.

  • _graph_var_dicts (dict) – has following format: {‘variables_dict’: self._variables, ‘temp_dict’: dict(), ‘update_dict’: dict(), ‘reduce_dict’: dict()}, recording the intermediate value of variables in computation progress.

  • basic_operate (dict) – dictionary of basic operators, mapping from operator names using in frontend to the funtion objects implemented in backend.

  • _operations (list) – records all basic operations from the build function of frontend objects, each of which has following format: [ret_var_name: str, operation_name, input_var_name1: str, input_var_name2 :str, …].

  • _graph_operations (list) – redefine each basic operation, that is, add the corresponding keyword in the _graph_var_dicts to each variable, which has following format: [(dict_type, ret_var_name), operation_name, [(dict_type1, input_var_name1),(dict_type2, input_var_name2),…]].

  • _standalone_operations (list) – records all standalone operations from the build function of frontend objects, each of which has following format: (ret_var_name: str, function, input_var_names: list).

  • _initial_operations (list) – records all initial operations from the build function of frontend objects, each of which has following format: (ret_var_name: str, function, input_var_names: list).

  • _monitors (list) – records all monitors defined in fronted network through build function of Monitor object.

build_graph()[source]

build a computation graph before performing the calculation.

graph_update_step()[source]

update value of _graph_var_dicts.

initial_step()[source]

initialize network variables.

update_step()[source]

update the return variables of standalone operations and basic operations and current backend time.

r_update_step()[source]

update the return variables of basic operations without using graph_update_step().

add_variable()[source]

add variables from front objects to _variables of Backend.

add_backend_variable()[source]

add variables according to the specified backend.

add_operation()[source]

add basic operations from front objects to _operations of Backend.

register_standalone()[source]

add standalone operations from front objects to _standalone_operations of Backend.

register_initial()[source]

add initial operations from front objects to _initial_operations of Backend.

basic_operate = {}
param_init_operate = {}
backend_name = 'None'
set_batch_size(batch_size)[source]
get_batch_size()[source]
set_runtime(runtime)[source]
register_basic_op(name, op_function)[source]

register the function as basic operation to backend’s _basic_operation dict :param name: :param op_function:

Returns:

build_graph()[source]

Build a computation graph before performing the calculation. Note that only the basic operations are redefiend into the _graph_operations list. The format of _graph_operations is as follows: [(dict_type, ret_var_name), operation_name, [(dict_type1, input_var_name1),(dict_type2, input_var_name2),…]]. Traverse all basic operations and add the corresponding keyword in the _graph_var_dicts as dict_type to each variable in basic operation.

get_dependency()[source]
set_func_grad()[source]
var_check(op, *args)[source]

For specified operation, check the type or the shape of input variables.

graph_update_step_r()[source]
get_place()[source]
graph_update_step()[source]
push_update_step()[source]
fetch_update_step()[source]
initial_step()[source]

Initialize network variables.

clear_step()[source]

Returns:

initial_continue_step()[source]

Initialize network for continuous run.

update_step()[source]

Update the return variables of standalone operations and basic operations and current backend time. :returns: tuple(self._variables.values())

update_time_steps()[source]
r_update_step()[source]

Update the return variables of basic operations without using graph_update_step(). :returns: tuple(self._variables.values())

reduce_sum_update(value)[source]
get_varialble(name)[source]
set_variable_value(name, value, is_parameter)[source]

Set the backend value, in specific Backend :param name: :param value: :param is_parameter:

Returns:

add_variable(module, name: str, shape, value=None, is_parameter=False, is_sparse=False, init=None, init_param=None, min=None, max=None, is_constant=False, prefer_device=None)[source]

Add variables from front objects to _variables of Backend and get copies to assign to _parameters_dict and _InitVariables_dict. :param module: the parent Module object the variable is belongs to :type module: spaic.BaseModule :param name: the name of the added variable :type name: str :param shape: the shape of the variable :type shape: list, int :param value: the value of the variable :type value: optional :param is_parameter: whether the variable is trainable :type is_parameter: bool, optional :param init: :type init: optional

has_variable(name: str)[source]
add_delay(var_name, max_delay)[source]
abstract add_backend_variable(module, name, shape, value=None, grad=False, is_sparse=False, init=None, init_param=None)[source]

This method will be overwritten by different subclasses to add variables to _variables of specified backend. :param module: the parent Module object the variable is belongs to :type module: spaic.BaseModule :param name: the name of the added variable :type name: str :param shape: the shape of the variable :type shape: list, int :param value: the value of the variable :type value: optional :param is_parameter: whether the variable is trainable :type is_parameter: bool, optional :param init: :type init: optinal :param grad: whether to use grad :type grad: bool, optional

abstract sparse_to_dense(index_name, value_name, shape_name)[source]

This method will be sparse matrix to dense matrix. :param index_name: :type index_name: str :param value_name: :type value_name: str :param shape_name: :type shape_name: str

add_operation(op)[source]

Add basic operations from front objects to _operations of Backend.

register_standalone(op)[source]

Add standalone operations from front objects to _standalone_operations of Backend.

register_initial(op)[source]

Add initial operations from front objects to _initial_operations of Backend.. op = {output, func, input, owner, place, requires_grad}

store(name='default')[source]

Store backend_name and _variables into _stored_states dictionary. :param name: the name of network state. :type name: str, optional

restore(name='default')[source]

Restore network state from _stored_states dictionary. :param name: the name of network state. :type name: str

check_key(ckey, target_dict)[source]
abstract to_nograd_func(func)[source]

Define the function as with no_grad :param func:

Returns:

abstract to_grad_func(func)[source]

Define the function as with enable_grad :param func:

Returns:

abstract threshold(v, v_th)[source]
Parameters:
  • v – membrane voltage

  • v_th – threshold

Returns:

v> v_th

abstract reset(v, o)[source]
Parameters:
  • v – membrane voltage

  • o – output spike

Returns:

if o>0, return 0 else reutn v

abstract cat(x, dim=1)[source]

Joining data together along a dimension. Note that the total dimension of the data remains the same after cat. :param x: :type x: list :param dim: the dimension to cat. :type dim: int

Returns:

concat(x, dim)

abstract stack(x, dim=1)[source]

Add new dimension when stack data. :param x: :type x: list :param dim: the dimension to stack. :type dim: int

Returns:

stack(x, dim)

abstract permute(x, permute_dim)[source]
Parameters:
  • input (x--->) –

  • operation (permute_dim---> the dimension index of permute) –

abstract view(x, view_dim)[source]
Parameters:
  • input (x--->) –

  • operation (view_dim---> the shape of view) –

assign(x)[source]
Parameters:
  • target (y--->) –

  • input (x--->) –

  • x (y =) –

abstract unsqueeze(x, dim)[source]
Parameters:
  • input (x--->) –

  • operation (dim---> the dim of unsqueeze) –

abstract reduce_sum(x, *dim)[source]

Reduce the dimensions of the data :param x: :type x: list :param dim: the dimension to reduce. :type dim: tuple(int)

Returns:

sum(x, dim)

abstract index_select(x, indices, dim=1)[source]
Parameters:
  • x

  • indices

abstract scatter(x, indices)[source]
Parameters:
  • x

  • indices

abstract conv1d(x, kernel)[source]
Parameters:
  • x

  • kernel

abstract conv_2d_complex(x, kernel, stride, padding, dilation, groups, beta, delay=None)[source]
Parameters:
  • x

  • kernel

  • stride

  • padding

  • dilation

  • groups

  • beta

Returns:

abstract conv_trans2d(x, kernel, stride, padding, dilation, groups)[source]

transposed conv 2d :param x: :param kernel:

abstract conv_trans1d(x, kernel)[source]

transposed conv 1d :param x: :param kernel:

abstract im2col_indices(x, kh, kw, padding, stride)[source]
Parameters:
  • x (4D array N, FH, FW, C_{in}) –

  • kh (kernel_height) –

  • kw (kernel_width) –

  • stride

  • padding

abstract conv2d_flatten(x)[source]
Parameters:
  • x (4D array (batch_size, out_channels, height, width)) –

  • Returns

  • (batch_size (3D array) –

  • out_channels

  • width) (height *) –

  • ----------

abstract feature_map_flatten(x)[source]

For RSTDP and STDP learning rules which is follwed with conv pre_layer :param x: :type x: 4D array (batch_size, out_channels, height, width) :param Returns: :param 2D array (batch_size: :param out_channels * height * width): :param ———-:

abstract add(x, y)[source]

Add the tensor y to the input x and returns a new result. :param x: input :type x: Tensor :param y: the second input :type y: Tensor or Number

Returns:

x + y

abstract minus(x, y)[source]

The first input minus the second input :param x: input :type x: Tensor :param y: the second input :type y: Tensor or Number

Returns:

x - y

abstract div(x, y)[source]

The first input div the second input :param x: input :type x: Tensor :param y: the second input :type y: Tensor or Number

Returns:

x/y

abstract relu(x)[source]

Rectified Linear :param x:

Returns:

x = x if x>0. else x = 0

abstract mat_mult_weight(A, X)[source]

Matrix product. :param A: the first input to be multiplied :type A: Tensor :param X: the second input to be multiplied :type X: Tensor

Returns:

mat_mult_weight(A,X)

abstract mat_mult_weight_complex(A, X, beta, delay=None)[source]
abstract mat_mult_weight_2complex(A, X, beta)[source]
abstract mat_mult_pre(A, X)[source]

Matrix product. :param A: the first input to be multiplied :type A: Tensor :param X: the second input to be multiplied :type X: Tensor

Returns:

mat_mult_pre(A,X)

abstract sigmoid(x)[source]
Parameters:

x

Returns:

abstract upsample(x, scale)[source]
abstract mat_mult(A, X)[source]

Matrix product. :param A: the first input to be multiplied :type A: Tensor :param X: the second input to be multiplied :type X: Tensor

Returns:

mat_mult(A,X)

abstract reshape_mat_mult(A, X)[source]

Matrix product. :param A: the first input to be multiplied :type A: Tensor :param X: the second input to be multiplied :type X: Tensor

Returns:

abstract bmm(A, X)[source]

Performs a batch matrix-matrix product. :param A: the first input to be multiplied [batch_size, n, m] :type A: Tensor :param X: the second input to be multiplied [batch_size, m, p] :type X: Tensor

Returns:

bmm(A,X) [batch_size, n, p]

abstract sparse_mat_mult_weight(A, X)[source]

Sparse matrix product. :param A: the first input to be multiplied :type A: Tensor :param X: the second input to be multiplied :type X: Tensor

Returns:

sparse_mat_mult_weight(A,X)

abstract var_mult(A, X)[source]
Parameters:
  • A

  • X

Returns:

A * X

abstract mult_sum_weight(A, X)[source]

sum(A*X, dim=-2)

Parameters:
  • A

  • X

Returns:

abstract mat_linear(A, X, b)[source]
Parameters:
  • A

  • X

  • b

Returns:

mat_mul(A,X)+b

abstract ger(A, X)[source]
Parameters:
  • A

  • X

Returns:

ger(A,X)

abstract var_linear(A, X, b)[source]

If A is matrix, then A and X should have the same shape, A*X is elemen-wise multiplication else A should be a scalar value. :returns: A*X +b

abstract to_numpy(data)[source]
Args:

data

Returns:

data.numpy()

abstract to_tensor(data)[source]
Parameters:

data

Returns:

torch.tensor(data)

abstract clamp_(data, min, max)[source]

in-place clamp the data

abstract clamp_max_(data, max)[source]

in-place clamp the max of the data

abstract clamp_min_(data, min)[source]

in-place clamp the min of the data

abstract uniform(data, a=0.0, b=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • a (float) – the lower bound of the uniform distribution

  • b (float) – the upper bound of the uniform distribution

Returns:

torch.nn.init.uniform_(data, a=0.0, b=1.0)

abstract normal(data, mean=0.0, std=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • mean (float) – the mean of the normal distribution

  • std (float) – the standard deviation of the normal distribution

Returns:

torch.nn.init.normal_(data, mean=0.0, std=1.0)

abstract xavier_normal(data, gain=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • gain – an optional scaling factor

Returns:

torch.nn.init.xavier_normal_(data, gain=1.0)

abstract xavier_uniform(data, gain=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • gain – an optional scaling factor

Returns:

torch.nn.init.xavier_uniform_(data, gain=1.0)

abstract kaiming_normal(data, a=0, mode='fan_in', nonlinearity='leaky_relu')[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • a – the negative slope of the rectifier used after this layer (only used with ‘leaky_relu’)

  • mode – either ‘fan_in’ (default) or ‘fan_out’. Choosing ‘fan_in’ preserves the magnitude of the variance of the weights in the forward pass. Choosing ‘fan_out’ preserves the magnitudes in the backwards pass.

  • nonlinearity – the non-linear function (nn.functional name), recommended to use only with ‘relu’ or ‘leaky_relu’ (default).

Returns:

torch.nn.init.kaiming_normal_(data, a=0, mode=’fan_in’, nonlinearity=’leaky_relu’)

abstract kaiming_uniform(data, a=0, mode='fan_in', nonlinearity='leaky_relu')[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • a – the negative slope of the rectifier used after this layer (only used with ‘leaky_relu’)

  • mode – either ‘fan_in’ (default) or ‘fan_out’. Choosing ‘fan_in’ preserves the magnitude of the variance of the weights in the forward pass. Choosing ‘fan_out’ preserves the magnitudes in the backwards pass.

  • nonlinearity – the non-linear function (nn.functional name), recommended to use only with ‘relu’ or ‘leaky_relu’ (default).

Returns:

torch.nn.init.kaiming_uniform_(data, a=0, mode=’fan_in’, nonlinearity=’leaky_relu’)

abstract constant(data, constant_value=0.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • constant_value (float) – the value to fill the tensor with

Returns:

torch.nn.init.constant_(data, constant_value)

abstract to(data, device)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • constant_value (float) – the value to fill the tensor with

Returns:

torch.nn.init.constant_(data, constant_value)

abstract weight_norm(weight, amp)[source]

w = g/||v|| * v :param weight: v :param amp: g

Returns: amp*weight/norm(weight)

exp(x)[source]
Parameters:

x (tensor) – an n-dimensional torch.Tensor

Returns:

return exp(x)

sin(x)[source]
Parameters:

x (tensor) – an n-dimensional torch.Tensor

Returns:

return exp(x)

cos(x)[source]
Parameters:

x (tensor) – an n-dimensional torch.Tensor

Returns:

return exp(x)

tan(x)[source]
Parameters:

x (tensor) – an n-dimensional torch.Tensor

Returns:

return exp(x)

log(x)[source]
Parameters:

x (tensor) – an n-dimensional torch.Tensor

Returns:

return exp(x)

log2(x)[source]
Parameters:

x (tensor) – an n-dimensional torch.Tensor

Returns:

return exp(x)

log10(x)[source]
Parameters:

x (tensor) – an n-dimensional torch.Tensor

Returns:

return exp(x)

spaic.Backend.TF_Backend module

spaic.Backend.Torch_Backend module

Created on 2020/9/14 @project: SPAIC @filename: Torch_Backend @author: Hong Chaofei @contact: hongchf@gmail.com @description:

class spaic.Backend.Torch_Backend.Torch_Engine(graph_operations)[source]

Bases: Module

forward(variables: Dict[str, Tensor])[source]
training: bool
class spaic.Backend.Torch_Backend.Torch_Backend(device='cpu')[source]

Bases: Backend

backend_name = 'pytorch'
build()[source]
build_graph()[source]
remove_tensor(inputs)[source]
is_insert(inputs)[source]
move_compute_and_assign_tensors(op)[source]
graph_update_step_multigpu()[source]
to_nograd_func(func)[source]
to_grad_func(func)[source]
add_backend_variable(module, name, shape, value=None, grad=False, is_sparse=False, init=None, init_param=None, prefer_device=None)[source]
Parameters:
  • name

  • shape

  • value

  • init

set_variable_value(name, value, is_parameter)[source]
sparse_to_dense(index_name, value_name, shape_name)[source]
get_str(level)[source]
threshold(x, v_th)[source]
reset(v, o)[source]
cat(x, dim=1)[source]
stack(x, dim=1)[source]
reduce_sum(x, *dim)[source]
index_select(x, indices, dim=1)[source]
permute(x, permute_dim)[source]
view(x, view_dim)[source]
scatter(x, indices)[source]
conv1d(x, kernel)[source]
conv_trans1d(x, kernel, bias=None)[source]
conv_2d(x, kernel, stride, padding, dilation, groups, bias=None, padding_mode='constant')[source]
conv_2d_complex(x, kernel, stride, padding, dilation, groups, beta, bias=None, delay=None)[source]
conv_trans2d(x, kernel, stride=1, padding=0, dilation=0, groups=1)[source]
conv_max_pool2d(x, kernel, pool_kernel, stride, pool_stride, padding, pool_padding, dilation, groups)[source]
conv_avg_pool2d(x, kernel, pool_kernel, stride, pool_stride, padding, pool_padding, dilation, groups)[source]
conv_add_bias(x, bias)[source]
max_pool2d(x, pool_kernel, pool_stride, pool_padding)[source]
post_max_pool2d_complex(x, pool_kernel, pool_stride, pool_padding)[source]
avg_pool2d(x, pool_kernel, pool_stride, pool_padding)[source]
batchnorm2d(x, num_features)[source]
dropout(x, p, inplace=False)[source]
reshape_mat_mult(A, X)[source]
im2col_indices(x, kh, kw, padding, stride)[source]
conv2d_flatten(x)[source]
feature_map_flatten(x)[source]
add(x, y)[source]
minus(x, y)[source]
div(x, y)[source]
relu(x)[source]
sigmoid(x)[source]
mat_mult_weight(A, X)[source]
Parameters:
  • A--->preGroup (input) –

  • X--->postGroup (weight) –

mat_mult_weight_complex(A, X, beta, delay=None)[source]
Parameters:
  • A--->preGroup (input) –

  • X--->postGroup (weight) –

  • postGroup (beta--->) –

mat_mult_weight_2complex(A, X, beta, delay=None)[source]
mat_mult_pre(A, X)[source]
Parameters:
  • A--->preGroup (input) –

  • X--->postGroup (weight) –

mat_mult(A, X)[source]
Parameters:
  • A--->preGroup (input) –

  • X--->postGroup (weight) –

bmm(A, X)[source]
Parameters:
  • postGroup (A--->) –

  • preGroup (X--->) –

ger(A, X)[source]
Parameters:
  • postGroup (A--->) –

  • preGroup (X--->) –

sparse_mat_mult_weight(A, X)[source]
Parameters:
  • A--->preGroup (sparseWeight(post, pre)) –

  • X--->postGroup (input(batch, pre)) –

var_mult(A, X)[source]
mult_sum_weight(A, X)[source]
mat_linear(A, X, b)[source]
var_linear(A, X, b)[source]
unsqueeze(X, dim)[source]
to_numpy(data: Tensor)[source]
to_tensor(data)[source]
upsample(x, scale)[source]
exp(x)[source]
clamp_(data, min, max)[source]
clamp_max_(data, max)[source]
clamp_min_(data, min)[source]
uniform(data, a=-0.0, b=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • a (float) – the lower bound of the uniform distribution

  • b (float) – the upper bound of the uniform distribution

Returns:

torch.nn.init.uniform_(data, a=0.0, b=1.0)

normal(data, mean=0.0, std=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • mean (float) – the mean of the normal distribution

  • std (float) – the standard deviation of the normal distribution

Returns:

torch.nn.init.normal_(data, mean=0.0, std=1.0)

xavier_normal(data, gain=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • gain – an optional scaling factor

Returns:

torch.nn.init.xavier_normal_(data, gain=1.0)

xavier_uniform(data, gain=1.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • gain – an optional scaling factor

Returns:

torch.nn.init.xavier_uniform_(data, gain=1.0)

kaiming_normal(data, a=0, mode='fan_in', nonlinearity='leaky_relu')[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • a – the negative slope of the rectifier used after this layer (only used with ‘leaky_relu’)

  • mode – either ‘fan_in’ (default) or ‘fan_out’. Choosing ‘fan_in’ preserves the magnitude of the variance of the weights in the forward pass. Choosing ‘fan_out’ preserves the magnitudes in the backwards pass.

  • nonlinearity – the non-linear function (nn.functional name), recommended to use only with ‘relu’ or ‘leaky_relu’ (default).

Returns:

torch.nn.init.kaiming_normal_(data, a=0, mode=’fan_in’, nonlinearity=’leaky_relu’)

kaiming_uniform(data, a=0, mode='fan_in', nonlinearity='leaky_relu')[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • a – the negative slope of the rectifier used after this layer (only used with ‘leaky_relu’)

  • mode – either ‘fan_in’ (default) or ‘fan_out’. Choosing ‘fan_in’ preserves the magnitude of the variance of the weights in the forward pass. Choosing ‘fan_out’ preserves the magnitudes in the backwards pass.

  • nonlinearity – the non-linear function (nn.functional name), recommended to use only with ‘relu’ or ‘leaky_relu’ (default).

Returns:

torch.nn.init.kaiming_uniform_(data, a=0, mode=’fan_in’, nonlinearity=’leaky_relu’)

constant(data, constant_value=0.0)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • constant_value (float) – the value to fill the tensor with

Returns:

torch.nn.init.constant_(data, constant_value)

sparse(data, sparsity=0.1, std=0.01)[source]
Parameters:
  • data (tensor) – an n-dimensional torch.Tensor

  • sparsity (float) – The fraction of elements in each column to be set to zero

  • std (float) – the standard deviation of the normal distribution used to generate

  • values (the non-zero) –

Returns:

torch.nn.init.sparse_(data, sparsity, std)

weight_norm(weight, amp)[source]
to(x, device)[source]
sin(x)[source]
cos(x)[source]
tan(x)[source]
log(x)[source]
log2(x)[source]
log10(x)[source]

Module contents

Created on 2020/8/11 @project: SPAIC @author: Hong Chaofei @contact: hongchf@gmail.com

@description: