SPMD Error detected on worker

10 views (last 30 days)
Seb Jowett
Seb Jowett on 22 May 2021
Commented: Seb Jowett on 23 May 2021
I am new to matlab, and I'm trying to learn how to use parallel processing.
I am trying to use SPMD, and have writen some simple code below:
clc;
close all;
clear variables;
arraySize = 10000000;
tArray = [1:arraySize];
tic;
spmd
startIndex = (labindex -1)/numlabs*arraySize+1;
endIndex = startIndex + arraySize/numlabs
for index = startIndex:endIndex
if tArray(index) > 50
tAray(index) = 50;
end
end
end
toc;
When I run this code, this is the output:
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 6).
Lab 1:
endIndex =
1.6667e+06
Lab 4:
endIndex =
6.6667e+06
Lab 6:
endIndex =
10000001
Lab 2:
endIndex =
3.3333e+06
Lab 3:
endIndex =
5000001
Lab 5:
endIndex =
8.3333e+06
Error using spmd_test (line 9)
Error detected on worker 6.
Caused by:
Error using spmd_test (line 9)
Array indices must be positive integers or logical values.
The worker which causes the problem changes everytime I run the code.
If anyone has any idea what might be causeing this error, your help would be much appreciated

Accepted Answer

Raymond Norris
Raymond Norris on 22 May 2021
Since this is about learning parallel programming, I'll avoid the suggestion of how to run this serially, as this example will run slower in parallel than serial. Since you're learning about spmd, I'll avoid the parfor solution (which is faster than spmd).
Your spmd issue is that index is not always an integer. I'm going to show three different ways you might try, but they may not all work. Additionally, some might run faster than others. Lastly, I test this with arraySize set to a small prime (say 97) so it's easiest to test (and so that you can ensure it doesn't benefit from an easily divisable number), but you'll see the performance difference when you set it back to 1e7. One other note, you have a typo in your tAray assignment, it should be tArray.
% Original (slightly modified)
tArray = 1:arraySize;
tic;
spmd
startIndex = (labindex -1)/numlabs*arraySize+1;
endIndex = startIndex + arraySize/numlabs-1;
for index = startIndex:endIndex
if tArray(index) > 50
tArray(index) = 50;
end
end
end
toc
The issue here is that the size of the array may not be a multiple of the number of workers (labs). This'll give you the error you see. Second, tArray is first a double, but then becomes a composite array. If the number of workers evenly divided arraySize, you might see something like this
>> whos tArray
Name Size Bytes Class Attributes
tArray 1x4 489 Composite
Where each element of tArray is 1xN and only tArray{3} and tArray{4} are modified (since they represent > 50), but this won't work as is. You'd need to marry all of these together. Messy.
The trick to using for-loops in spmd that needs to automagically divide evenly is to use drange.
% drange with Composite
tArray2 = 1:arraySize;
tic;
spmd
for index = drange(1:arraySize)
if tArray2(index) > 50
tArray2(index) = 50;
end
end
end
toc
Now MATLAB will automatically divide arraySize amongst the workers for you. However, you still have the issue where each tArray2 element is a local variant.
The solution I would look at is using drange and distributed arrays.
% drange with distributed
tArray3 = 1:arraySize;
d_tArray3 = distributed(tArray3);
tic;
spmd
for index = drange(1:arraySize)
if d_tArray3(index) > 50
d_tArray3(index) = 50;
end
end
end
toc
Given a distributed array, you'll see
>> whos d_tArray3
Name Size Bytes Class Attributes
d_tArray3 1x97 525 distributed
This should give you what you want. The issue is speed -- this is quite slow. But then again, I don't think you're trying to find the fastest solution, you're trying to learn about for-loops and spmd.
  1 Comment
Seb Jowett
Seb Jowett on 23 May 2021
Amazing, this worked really well
Thank you!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!