Skip to content

Commit

Permalink
Merge pull request #217 from mldiego/master
Browse files Browse the repository at this point in the history
GPU support, Conv1D issue
  • Loading branch information
mldiego authored Mar 29, 2024
2 parents 8a818ef + 1eaadd5 commit 11f085f
Show file tree
Hide file tree
Showing 140 changed files with 2,749 additions and 94,781 deletions.
50 changes: 41 additions & 9 deletions code/nnv/engine/nn/NN.m
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@
reachOptions = struct; % empty options, run with default values
end

% Change if want to execute on GPU
if isfield(reachOptions, 'device')
if strcmp(reachOptions.device, 'gpu')
obj = obj.params2gpu;
inputSet = inputSet.changeDevice('gpu');
end
end

% Process reachability options
if ~isstruct(reachOptions)
error("The reachability parameters must be specified as a struct.")
Expand Down Expand Up @@ -308,7 +316,7 @@
fprintf('\nPerform reachability analysis for the network %s \n', obj.Name);
end

outputSet = obj.reach_withConns(inputSet);
outputSet = obj.reach_withConns(inputSet, 'sequence');

end

Expand Down Expand Up @@ -946,6 +954,7 @@
reachOptions.reachOption = 'single';
reachOptions.numCores = 1;
end

end

% Ensure input and parameter precision is the same
Expand All @@ -969,6 +978,24 @@
end
end

% Change paramters to gpu
function obj = params2gpu(obj)
% change the parameters layer by layer
for i = 1:length(obj.Layers)
gpuLayer = obj.Layers{i}.toGPU;
obj.Layers{i} = gpuLayer;
end
end

% Change params precision
function obj = changeParamsPrecision(obj, precision)
% change the parameters layer by layer
for i = 1:length(obj.Layers)
pLayer = obj.Layers{i}.changeParamsPrecision(precision);
obj.Layers{i} = pLayer;
end
end

% Create input set based on input vector and bounds
function R = create_input_set(obj, x_in, disturbance, lb_allowable, ub_allowable) % assume tol is applied to every vale of the input
% R = create_input_set(obj, x_in, disturbance, lb_allowable, ub_allowable)
Expand Down Expand Up @@ -1212,7 +1239,7 @@ function start_pool(obj)
end

% reach NN based on connections table (test it)
function outSet = reach_withConns(obj, inSet)
function outSet = reach_withConns(obj, inSet, varargin)
% Initialize variables to store reachable sets and computation time
obj.reachSet = cell(1, obj.numLayers);
obj.reachTime = zeros(1, obj.numLayers);
Expand All @@ -1221,6 +1248,12 @@ function start_pool(obj)
fprintf('\nPerform reachability analysis for the network %s...', obj.Name);
end

if nargin == 3
reachType = varargin{1};
else
reachType = 'default';
end

% Begin reachability computation
for i=1:height(obj.Connections)

Expand All @@ -1245,7 +1278,7 @@ function start_pool(obj)
fprintf('\nPerforming analysis for Layer %d (%s)...', i-1, source);
end
t = tic;
if isequal(class(obj.Layers{1,1}), 'SequenceInputLayer')
if strcmp(reachType, 'sequence')
outSet = obj.Layers{source_indx}.reachSequence(inSet, obj.reachMethod, obj.reachOption, obj.relaxFactor, obj.dis_opt, obj.lp_solver);
else
outSet = obj.Layers{source_indx}.reach(inSet, obj.reachMethod, obj.reachOption, obj.relaxFactor, obj.dis_opt, obj.lp_solver);
Expand Down Expand Up @@ -1311,16 +1344,15 @@ function start_pool(obj)
% Assume last layer in array is the output layer
if isempty(obj.reachSet{end})
inSet = obj.reachSet{end-1};
outSet = obj.Layers{end}.reach(inSet, obj.reachMethod, obj.reachOption, obj.relaxFactor, obj.dis_opt, obj.lp_solver);
if strcmp(reachType, 'sequence')
outSet = obj.Layers{end}.reachSequence(inSet, obj.reachMethod, obj.reachOption, obj.relaxFactor, obj.dis_opt, obj.lp_solver);
else
outSet = obj.Layers{end}.reach(inSet, obj.reachMethod, obj.reachOption, obj.relaxFactor, obj.dis_opt, obj.lp_solver);
end
obj.reachSet{end} = outSet;
end
end

% Ensure precision for layer parameters and inputs is consistent
% function validate_precision(obj, inSet)
%
%
% end
end % end helper functions


Expand Down
19 changes: 17 additions & 2 deletions code/nnv/engine/nn/layers/ActivationFunctionLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
methods

% constructor of the class
function obj = ActivationFunctionLayer(varargin)
function obj = ActivationFunctionLayer(varargin)
% author: Diego Mazanas Lopez
% date: 12/06/2022

Expand Down Expand Up @@ -104,7 +104,6 @@

end


% MAIN REACHABILITY METHOD
function images = reach(varargin)
% @in_image: an input imagestar
Expand Down Expand Up @@ -172,6 +171,7 @@

end

% reach for time-sequence data
function seqs = reachSequence(varargin)
obj = varargin{1};
% relaxFactor = 0.8;
Expand All @@ -180,6 +180,21 @@
seqs.im_lb = lb;
seqs.im_ub = ub;
end

end

methods % helper method

% change params to gpuArrays
function obj = toGPU(obj)
% nothing to change in here (no params)
end

% Change params precision
function obj = changeParamsPrecision(obj, ~)
% nothing to change in here (no params)
end

end

end
Expand Down
20 changes: 17 additions & 3 deletions code/nnv/engine/nn/layers/AdditionLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
methods % main methods

% evaluate
function outputs = evaluate(obj, inputs)
function outputs = evaluate(~, inputs)
% addition layer takes usually two inputs, but allows many (N)
%
% first input is obj, the second is a cell array containing the
Expand All @@ -89,8 +89,8 @@

end

% reach (TODO)
function outputs = reach_single_input(obj, inputs)
% reach
function outputs = reach_single_input(~, inputs)
% @in_image: input imagestar
% @image: output set

Expand Down Expand Up @@ -187,6 +187,20 @@
end

end

methods % helper functions

% change params to gpuArrays
function obj = toGPU(obj)
% nothing to change in here (no params)
end

% Change params precision
function obj = changeParamsPrecision(obj, ~)
% nothing to change in here (no params)
end

end


methods(Static)
Expand Down
20 changes: 18 additions & 2 deletions code/nnv/engine/nn/layers/AveragePooling2DLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,16 @@ function set_padding(obj, padding)
end
end

% change params to gpuArrays
function obj = toGPU(obj)
% nothing to change in here (no params)
end

% Change params precision
function obj = changeParamsPrecision(obj, ~)
% nothing to change in here (no params)
end

end


Expand All @@ -228,8 +238,14 @@ function set_padding(obj, padding)
% author: Dung Tran
% date: 12/10/2018
% update: 7/26/2019

y = vl_nnpool(input, obj.PoolSize, 'Stride', obj.Stride, 'Pad', obj.PaddingSize, 'Method', 'avg');

if isa(input, 'gpuArray')
x = dlarray(input, "SSCB");
y = avgpool(x, obj.PoolSize, 'Stride', obj.Stride, 'Padding', obj.PaddingSize);
y = extractdata(y);
else
y = vl_nnpool(input, obj.PoolSize, 'Stride', obj.Stride, 'Pad', obj.PaddingSize, 'Method', 'avg');
end

end

Expand Down
10 changes: 10 additions & 0 deletions code/nnv/engine/nn/layers/AveragePooling3DLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ function set_padding(obj, padding)
end

end

% change params to gpuArrays
function obj = toGPU(obj)
% nothing to change in here (no params)
end

% Change params precision
function obj = changeParamsPrecision(obj, ~)
% nothing to change in here (no params)
end

end

Expand Down
30 changes: 29 additions & 1 deletion code/nnv/engine/nn/layers/BatchNormalizationLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
methods

% constructor of the class
function obj = BatchNormalizationLayer(varargin)
function obj = BatchNormalizationLayer(varargin)
% author: Dung Tran
% date: 1/1/2020
% update:
Expand Down Expand Up @@ -81,6 +81,34 @@

end

% change params to gpuArrays
function obj = toGPU(obj)
obj.Offset = gpuArray(obj.Offset);
obj.Scale = gpuArray(obj.Scale);
obj.Epsilon = gpuArray(obj.Epsilon);
obj.TrainedMean = gpuArray(obj.TrainedMean);
obj.TrainedVariance = gpuArray(obj.TrainedVariance);
end

% Change params precision
function obj = changeParamsPrecision(obj, precision)
if strcmp(precision, "double")
obj.Offset = double(obj.Offset);
obj.Scale = double(obj.Scale);
obj.Epsilon = double(obj.Epsilon);
obj.TrainedMean = double(obj.TrainedMean);
obj.TrainedVariance = double(obj.TrainedVariance);
elseif strcmp(precision, "single")
obj.Offset = single(obj.Offset);
obj.Scale = single(obj.Scale);
obj.Epsilon = single(obj.Epsilon);
obj.TrainedMean = single(obj.TrainedMean);
obj.TrainedVariance = single(obj.TrainedVariance);
else
error("Parameter numerical precision must be 'single' or 'double'");
end
end

end


Expand Down
15 changes: 15 additions & 0 deletions code/nnv/engine/nn/layers/ConcatenationLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,21 @@
end

end


methods % helper method

% change params to gpuArrays
function obj = toGPU(obj)
% nothing to change in here (no params)
end

% Change params precision
function obj = changeParamsPrecision(obj, ~)
% nothing to change in here (no params)
end

end


methods(Static)
Expand Down
Loading

0 comments on commit 11f085f

Please sign in to comment.