MATLAB - Use a user-defined class method in parallel on GPU - matlab

Let's say I have a class named Stack and it has a method that takes some other properties of Stack objects as input arguments which consist of vectors and scalars. The input vectors and output matrix change sizes depending on the object.
classdef Stack
...
...
function out = some_method(scalar1,scalar2,...,vec1,vec2...) % out has different number of
% columns depending on the size of vec1,vec2 etc.
...
out = ... % size of (4,m) where m changes for each object
end
This specific method of Stack should be called thousands of times to be used in another script for some other purpose. Since it takes time to use this method serially, a parallel solution will save a lot of time for bigger calculations.
I attempted to use cellfun by passing the indices of Stack objects inside a function hoping that I could run it on my GPU but cellfun doesn't support GPU computing. I also tried to use arrayfun but it doesn't support UniformOutput parameter on GPUs. I can't store different sizes of outputs inside a cell if I want to use my GPU.
My question is, is parallel computing on GPU possible for a class method/function that returns different sizes of outputs each time? If not, what could be a possible workaround for this problem?
Update: A short summary of my problem is; I would like to run the same function in parallel for each Stack object with their own inputs individually, knowing that their outputs don't match in sizes and collect them in a cell array at the end.

Related

Is it possible to create a sub-array without using additional memory on Matlab?

Well, I am trying to implement an algorithm on Matlab. It requires the usage of a slice of an high dimensional array inside a for loop. When I try to use the logical indexing, Matlab creates an additional copy of that slice and since my array is huge, it takes a lot of time.
slice = x(startInd:endInd);
What I am trying to do is to use that slice without copying it. I just need the slice data to input a linear operator. I won't update that part during the iterations.
To do so, I tried to write a Mex file whose output is a double
type array and whose size is equal to the intended slice data size.
plhs[0] = mxCreateUninitNumericMatrix(0, 0, mxDOUBLE_CLASS,mxREAL); % initialize but do not allocate any additional memory
ptr1 = mxGetPr(prhs[0]); % get the pointer of the input data
Then set the pointer of the output to the starting index of the input data.
mxSetPr(plhs[0], ptr1+startInd);
mxSetM(plhs[0], 1);
mxSetN(plhs[0], (endInd-startInd)); % Update the dimensions as intended
When I set the starting index to be zero, it just works fine. When I try to give
other values than 0, Mex file compiles with no error but Matlab crashes when the Mex function is called.
slice = mex_slicer(x, startInd, endInd);
What might be the problem here?
The way you assign the data pointer to the array, it means that MATLAB will attempt to free that memory when the array is deleted or has something else assigned to it. Attempting to call free using a pointer that was not obtained by malloc will cause a crash.
Unfortunately, MATLAB does not support "views", arrays that point at parts of a different array. So there is no way to do what you want to do.
An alternative solution would be to:
store your data differently, so that it doesn't take as much time to index (e.g. in smaller arrays)?
perform all your computations in C or C++ inside a MEX-file, where you can very simply point at sub-ranges of a larger data block.
See this FEX submission on creating MATLAB variables that "point" to the interior data of an existing variable. You can either do it as a shared data copy which is designed to be safe (but incurs some additional overhead), or as an unprotected direct reference (faster but risks crashing MATLAB if you don't clear it properly).
https://www.mathworks.com/matlabcentral/fileexchange/65842-sharedchild-creates-a-shared-data-copy-of-a-contiguous-subsection-of-an-existing-variable

How can I optimize machine learning hyperparameters to be reused in multiple models?

I have a number of datasets, to each of which I want to fit a Gaussian process regression model. The default hyperparameters selected by fitrgp seem subjectively to produce less-than-ideal models. Enabling hyperparameter optimisation tends to result in a meaningful improvement but occasionally produces extreme overfitted values and is a computationally hungry process which prohibits an optimization for every model anyway.
Since fitrgp simply wraps bayesopt for its hyperparameter optimization, is it possible to call bayesopt directly to minimize some aggregate of the loss for multiple models (say, the mean) rather than the loss for one model at a time?
For example, if each dataset is contained in a cell array of tables tbls, I want to find a single value for sigma which can be imposed in calls to fitrgp for each table:
gprMdls = cellfun(#(tbl) {fitrgp(tbl,'ResponseVarName', 'Sigma',sigma)}, tbls);
Where numel(tbls) == 1 the process would be equivalent to:
gprMdl = fitrgp(tbls{1},'ResponseVarName', 'OptimizeHyperparameters','auto');
sigma = gprMdl.Sigma;
but this implementation doesn't naturally extend to a result where a single Sigma value is optimized for multiple models.
I managed this in the end by directly intervening in the built-in optimization routines.
By placing a breakpoint at the start of bayesopt (via edit bayesopt) and calling fitrgp with a single input dataset, I was able to determine from the Function Call Stack that the objective function used by bayesopt is constructed with a call to classreg.learning.paramoptim.createObjFcn. I also captured and stored the remaining input arguments to bayesopt to ensure my function call would be exactly analagous to one constructed by fitrgp.
Placing a breakpoint at the start of classreg.learning.paramoptim.createObjFcn and making a fresh call to fitrgp I was able to capture and store the input arguments to this function, so I could then create objective functions for different tables of predictors.
For my cell array of tables tbls, and all other variables kept as named in the captured createObjFcn scope:
objFcns = cell(size(tbls));
for ii = 1:numel(tbls)
objFcn{ii} = classreg.learning.paramoptim.createObjFcn( ...
BOInfo, FitFunctionArgs, tbls{ii}, Response, ...
ValidationMethod, ValidationVal, Repartition, Verbose);
end
An overall objective function can then be constructed by taking the mean of the objective functions for each dataset:
objFcn = #(varargin) mean(cellfun(#(f) f(varargin{:}),objFcns));
I was then able to call bayesopt with this objFcn along with the remaining arguments captured from the original call. This produced a set of hyperparameters as required and they seem to perform well for all datasets.

MATLAB execute function for multiple variables in loop

To process data in MATLAB I have to execute a certain function, let's call it function(). Since there is much data to be processed, like large array Time or Voltage (but many more) I execute those one by one like this:
TimeNew = function(Time);
VoltageNew = function(Voltage);
... etc
So this is done around 10 times. Moreover, I have to do such a thing multiple times, resulting in around 30 lines of code which all do the same thing but to a different variable.
Is there a way to optimize this? I am using the most recent version of MATLAB (2015b) and have all toolboxes installed.
A possible solution could be to store the input array into a struct, them use that struct as input of the function.
In the function you can identify the number and content of each field by using fieldnames and getfiled built-in function.
The function could return a structure as output whose names can be made the same as the ones of the input struct.
In the example below, three arrays are generated and the function siply compute their square.
var_1=1:10;
var_2=11:20;
var_3=21:30;
str_in=struct('var_1',var_1,'var_2',var_2,'var_3',var_3)
str_out=my_function(str_in)
The function
function [str_out]=my_function(str_in)
f_names=fieldnames(str_in)
n_fields=length(f_names);
for i=1:n_fields
x=getfield(str_in,f_names{i})
str_out.(f_names{i})=x.^2;
end
Hope this helps.
Qapla'
You could try cellfun
allResultsAsACell = cellfun(#function, {Time,Voltage,...,varN});
This is equivalent to
allResultsAsACell{1} = function(Time);
allResultsAsACell{2} = function(Voltage);
...
allResultsAsACell{N} = function{VarN};
The issue is just matching up the indices with the values. I'm sure you could code those in as well if you needed (e.g. timeInd = 1; voltageInd =2; ...)
To see more on the cellfun method, type
help cellfun
into your MATLAB terminal.

S-function documentation that "S-function level-1 supports vector inputs and outputs. DOES NOT support multiple input and output ports"

I read in S-function documentation that "S-function level-1 supports vector inputs and outputs. DOES NOT support multiple input and output ports".
Does the second sentence mean the input and output dimension must be the same?
I have been using S-function level-1 to do the following:
[a1, b1] = choose_cells(c, d);
where a1 and b1 are outputs, c and d are inputs. All the variables are having a single value, except d is an array with 6 values.
Referring to the image attached, we all know that in S-function block, the input dimension must be SAME as output dimension, else we will get error, in this case, the input dimension is 7 while the output dimension is 2, so I have to include the "Terminator" blocks in the diagram for it to work perfectly, otherwise, I will get an error.
My problem is, when the system gets bigger, the array d could contain hundreds of variables, using this method, it means I would have to add hundreds of "Terminator" blocks in order to get this work, this definitely does not sound practical.
Could you please suggest me a wise way to implement this?
http://imgur.com/ib6BTTp
http://imageshack.us/content_round.php?page=done&id=4tHclZ2klaGtl66S36zY2KfO5co
Updated: actually I have been trying to convert my level-1 S-function to level-2 but I got stuck at calling another sub function at function Output(block) trying to look for other threads but to no avail, do you mind to provide related links?
My output depends on a lot processing with the inputs, this is the reason I need to call the sub-function in order to calculate and then return output values, all the examples that I can see are calculating their outputs directly in "function Output(block)", in my case I thought it is not possible.
I then tried to use Interpreted Matlab Function block but failed due to the output dimension is NOT the same as input dimension, also it does not support the return of more than ONE output................
Level-1 s-function supports single input and single output port. These ports must be vectors. But there is no restriction on the length. Input and output can have different lengths. You can use selector block to select only relevant data. You do not need to use Bus in the output.
There is also no restriction on calling other sub-functions from Output. If your sub-function is not in the same file it must be in the path or in the current directory.
If your MATLAB code is compatible with MATLAB Function block, I recommend using that block. It is simpler to setup and use.

matlab local static variable

In order to test an algorithm in different scenarios, in need to iteratively call a matlab function alg.m.
The bottleneck in alg.m is something like:
load large5Dmatrix.mat
small2Dmatrix=large5Dmatrix(:,:,i,j,k) % i,j and k change at every call of alg.m
clear large5Dmatrix
In order to speed up my tests, i would like to have large5Dmatrix loaded only at the first call of alg.m, and valid for future calls, possibly only within the scope of alg.m
Is there a way to acheve this in matlab other then setting large5Dmatrix as global?
Can you think of a better way to work with this large matrix of constant values within alg.m?
You can use persistent for static local variables:
function myfun(myargs)
persistent large5Dmatrix
if isempty(large5Dmatrix)
load large5Dmatrix.mat;
end
small2Dmatrix=large5Dmatrix(:,:,i,j,k) % i,j and k change at every call of alg.m
% ...
end
but since you're not changing large5Dmatrix, #High Performance Mark answer is better suited and has no computational implications. Unless you really, really don't want large5Dmatrix in the scope of the caller.
When you pass an array as an argument to a Matlab function the array is only copied if the function updates it, if the function only reads the array then no copy is made. So any performance penalty the function pays, in time and space, should only kick in if the function updates the large array.
I've never tested this with a recursive function but I don't immediately see why it should start copying the large array if it is only read from.
So your strategy would be to load the array outside the function, then pass it into the function as an argument.
This note may clarify.