Search code examples
matlabparfor

matlab using evalin in parfor


I have an issue with using evalin within a function that is being called in the body of a parfor-loop. The function looks as follow:

function returnData = extractFun(input)

    % assign close price to function call
    x = evalin('base','data');

    % extract prices
    returnData = x(input);

end

And the script calling the function looks like this:

% data-array = n-by-1 double
data = [1:1000]';

% loop and extract data
parfor i = 1:10

    % n-by-1 cell array containing 1-by-x doubles
    % doubles in var1 contain valid indicies for the data-variable

    var1 = {[1:10]; [1:30]};

    % perform cell-function since, cell2mat will not work due to
    % inconsistent dimensions of the double arrays contained in the cells

    extractData = cellfun(@returnData,var1,'UniformOutput',false);

    % do something with extractData

end

When I run the script in a parfor-loop, matlab throws an error, that the index exceeds the matrix dimensions, which must mean that the variable x is empty (or not being evaluated correctly). The weird thing is, that when I run the loop as a normal for-loop, everything works fine. I know about the transparency-issues with parfor-loops, hence I put the evalin into a separate function.

I would also be open to alternative solutions to my problem, which is extracting data from One data variable into a n-by-1 cell array as doubles without the use of additional loops, as I am intending to run this loop with a very high number of iterations.

Can anyone help me out? Thanks!


Solution

  • evalin and parfor don't mix. Even if you run parfor with a local pool, you want to think of the workers that run the loop iterations as completely separate processes. In other words, they have no visibility of your base workspace at all. evalin is not allowed in the loop body for a reason; hiding it in a function doesn't change the fact that there is no variable data in the local base workspace of the worker, which will make the statement fail.

    It is not clear to me why you fear the loop so much in this context. First of all, it's no longer 2006, when loops were still pretty bad for you; there has been some work done optimizing Matlab. Second, your cellfun call with evalin is a fairly inefficient way to simply read indices, and cellfun doesn't do much more than hide a loop away. Third, you're planning to run parfor here, which means that you may not be able to handle the likely higher memory usage coming from a fully vectorized loop replacement.

    Consequently, just replace the cellfun-call with

    extractData = cell(size(var));
    for iVar = 1:numel(var)
        extractData{iVar} = data(var{iVar});
    end