4
votes

I'm sorry that currently I'm not able to boil my code down to a minimal example. It's a huge bunch of image processing code.

I have a loop that iterates over images (descriptors in variable stphogs) and for each image runs a detection.

function hogpatches = extractDetectionsFromImages(stphogs, poselet)
    hogpatches = cell(1,length(stphogs));

    parfor i = 1:length(stphogs)
        tmp = extractDetectionsFromImage(stphogs(i), poselet); %e.g. 1x6 struct

        if ~isempty(tmp)
            hogpatches{i} = tmp;
        end
    end

    hogpatches = cell2mat(hogpatches);
end

So this is the main loop. But the function calls in extractDetectionsFromImage go very deep.

My problem: Running this with a normal for-loop gives the correct result. When using PARFOR as above, hogpatches only contains 5 instead of 18 structs.

Where can I start to look for the error? I had a global variable the program did change. I removed that already. There is still a global variable 'config' which is however only read.. Any other hints? What could be the problem?

EDIT: Even if I just run one iteration (size of stphogs is 1), the parfor fails. It doesn't have anything to do with the isempty part. Problem persists if I remove that.

EDIT2: Ok here I boiled it to a minimal working example. It is indeed caused by a global variable:

function parGlobalTest()
    global testVar;

    testVar = 123;

    parfor i = 1:1
        fprintf('A Value: %d\n', testVar);
        testFunction();
    end
end

function testFunction()
    global testVar;
    fprintf('B Value: %d\n', testVar);
end

In this example. The output for A will be 123, for B it will be nothing (undefined). Why is that?

1
perhaps something is happinging in your extractDetectionsFromImage function that isn't working in the parallel case. How many times does isempty(tmp) evaluate to true in the for and parfor implementations? - slayton
One of the other questions you might want to ask yourself is if things in the parfor loop need to happen sequentially or if they can in fact work in parallel. - Ben A.

1 Answers

1
votes

Ok, here is my solution:

function syncTestVar()
    global testVar;
    save('syncvar.mat', 'testVar');
    pctRunOnAll global testVar;
    pctRunOnAll load('syncvar.mat');
end

If someone has a better approach please tell me... This one works though

Btw: The save/load is needed because in my real program, testVar is a complex struct