Inevitable broadcast variable in parfor?
Show older comments
Hi,
I want to perform some calculations in a parfor loop using the neighbouring data in a 3D matrix. Currently I am using the following code, which has the problem that data is a 'broadcast variable'. This slows down the calculations and causes memory problems. (This is a small scale example where 18.5 MB is send to the workers.The actual data matrix will be around 100x100x65336 (i.e. 2.6 GB vs 3.6 MB in this example).)
rng('default');
height = 60;
width = 60;
ntimes = 2^8;
radius = 10;
block_size = 2*radius+1;
data = randn(height, width, ntimes, 'single'); % create some random data
output = zeros(height, width, ntimes, 'single');
result = zeros(height-2*radius, width-2*radius, block_size, block_size, ntimes, 'single');
ticBytes(gcp); tic;
parfor y = radius+1:height-radius
% create temporary array for parfor loop
temp_r = zeros(width-2*radius, block_size, block_size, ntimes, 'single');
for x = radius+1:width-radius
% here I calculate the fft of a block surrounding the pixel of interest.
% Since it violates rules of indexing, data is a broadcast variable
a = fft(data(y-radius:y+radius, x-radius:x+radius, :), [], 3);
% For simplicity sake I store the fft (In reality I do more calculations).
temp_r(x-radius, :, :, :) = real(a);
end
result(y-radius, :, :, :, :) = temp_r;
end
toc; tocBytes(gcp);
To overcome this problem I considered using linear indexing. However, I then cannot figure out how to overcome the broadcasting. Due to the large size of the actual data, I think that separating the data in blocks (2*radius+1) for every single pixel is not feasible.
rng('default');
height = 60;
width = 60;
ntimes = 2^8;
radius = 10;
data = randn(height, width, ntimes, 'single'); % create some random data
data = reshape(data, [height*width, ntimes]);
% determination of linear indices
[cols, rows] = meshgrid(radius+1:height-radius, radius+1:width-radius);
linear_ids = sub2ind([height, width], rows, cols);
% create an array with linear ids of neighbouring pixels
[x,y] = meshgrid(radius*(-height-1):height:radius*height-radius, 0:radius*2);
mask = x + y;
% the neighbour matrix has 2*radius+1 columns (the neighbours)
% and the rows are the different pixels under study
neighbour_matrix = bsxfun(@plus, linear_ids(:), mask(:)');
output = zeros(length(cols) * length(rows),(2*radius+1)^2, ntimes);
ticBytes(gcp); tic;
parfor i = 1:length(cols) * length(rows)
neighbours = neighbour_matrix(i,:);
% calculate fft using the neighbours here, but data is still a broadcast variable
% but how do I make data a sliced variable
a = fft(data(neighbours, :), [], 2);
output(i, :, :) = a;
end
toc; tocBytes(gcp);
I would be very grateful if someone could point me in the right direction. Thank you in advance!
tl;dr
Is it possible to avoid having a broadcast variable when a vector of indices is being used?
2 Comments
The actual data matrix will be around 100x100x65336 (i.e. 2.6 GB vs 3.6 MB in this example).)
I think you should probably decimate your time samples from 65336 to maybe a few hundred. It shouldn't take that many samples just to fit a line ('poly1') unless you have seriously bad measurement noise.
pigeon
on 2 Sep 2019
Accepted Answer
More Answers (0)
Categories
Find more on Neighborhood and Block Processing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!