Inevitable broadcast variable in parfor?
Afficher commentaires plus anciens
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 commentaires
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
le 2 Sep 2019
Réponse acceptée
Plus de réponses (0)
Catégories
En savoir plus sur Neighborhood and Block Processing dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!