Effacer les filtres
Effacer les filtres

Parfor "Out of Memory during deserialization" in large matrix operations

21 vues (au cours des 30 derniers jours)
Preetham Manjunatha
Preetham Manjunatha le 12 Mai 2024
Réponse apportée : Namnendra le 26 Juin 2024 à 18:58
I am trying to use parfor for a large matrix operation. I am getting Out of Memory during deserialization error. Is there a way to minimize the memory? Below is the minimal example code:
clc; clear;
warpedImages = num2cell(uint8(randi([0,255], 1654, 6288, 3, 35)),1:3);
warpedImages = reshape(warpedImages,1,[]);
% Initialze
n = length(warpedImages);
sigmaN = 10;
sigmag = 0.1;
panoramasize = size(warpedImages{1});
Amat = cell(n);
Bvec = zeros(n,1);
IuppeIdx = nonzeros(triu(reshape(1:numel(Amat), size(Amat))));
Amat_temp = cell(1,length(IuppeIdx));
matSize = size(Amat);
% 4D warped images (Slicing)
wim_4d = cell2mat(reshape(warpedImages,1,1,1,[]));
% Get the Ibarijs and Nijs
parfor i = 1:length(IuppeIdx)
% Index to subscripts
[ii,jj] = ind2sub(matSize, IuppeIdx(i));
if ii == jj
diag_val_1 = 0;
diag_val_2 = 0;
Z = 1:n;
Z(Z==ii) = [];
for d = Z
[Ibarij, Ibarji, Nij] = getIbarNij(panoramasize, wim_4d(:,:,:,ii), wim_4d(:,:,:,d));
diag_val_1 = diag_val_1 + ( (Nij + Nij) .* Ibarij.^2 );
diag_val_2 = diag_val_2 + Nij;
end
diag_val = diag_val_1 + (sigmaN^2/sigmag^2) * diag_val_2;
B_val = (sigmaN^2/sigmag^2) * diag_val_2;
Amat_temp{i} = diag_val;
Bvec(i) = B_val
end
if ii ~= jj
[Ibarij,Ibarji,Nij] = getIbarNij(panoramasize, wim_4d(:,:,:,ii), wim_4d(:,:,:,jj));
Amat_temp{i} = -(Nij+Nij) .* (Ibarij .* Ibarji);
end
end
function [Ibarij,Ibarji,Nij] = getIbarNij(panoramasize, Imij, Imji)
Ibarij = zeros(panoramasize,'uint8');
Ibarji = zeros(panoramasize,'uint8');
% Overlay the warpedImage onto the panorama.
maski = imbinarize(rgb2gray(255 * Imij));
maskj = imbinarize(rgb2gray(255 * Imji));
% Find the overlap mask
Nij_im = maski & maskj;
Nij_im = imfill(Nij_im, 'holes');
Nijidx = repmat(Nij_im, 1, 1, size(Imij,3));
% Get the overlapping region RGB values for two images
Ibarij(Nijidx) = Imij(Nijidx);
Ibarji(Nijidx) = Imji(Nijidx);
% Convert to double
Ibarij_double = double(Ibarij);
Ibarji_double = double(Ibarji);
% Nij
Nij = sum(sum(Nij_im));
% Ibar ijs
Ibarij = reshape(sum(sum(Ibarij_double)) ./ Nij, 1, 3);
Ibarji = reshape(sum(sum(Ibarji_double)) ./ Nij, 1, 3);
% Replace NaNs by zeros
Ibarij(isnan(Ibarij)) = 0;
Ibarji(isnan(Ibarji)) = 0;
end
Line [Ibarij, Ibarji, Nij] = getIbarNij(panoramasize, wim_4d(:,:,:,ii), wim_4d(:,:,:,d)); throws a warning message: The entire array or structure 'wim_4d' is a broadcast variable. This might result in unnecessary communication overhead. I have used ind2sub for getting the subscripts as it is easy to work. However, wim_4d(:,:,:,ii) and others cannot be sliced. Any other suggestion and help is appreciated!

Réponses (1)

Namnendra
Namnendra le 26 Juin 2024 à 18:58
Hello Preetham,
I understand that you want to optimize your program by reducing memory usage.
When using `parfor` in MATLAB, one common issue is the memory overhead caused by broadcasting large variables to all workers. In your case, the entire `wim_4d` array is being broadcasted to each worker, which leads to high memory usage and can cause out-of-memory errors.
One way to minimize the memory overhead is to avoid broadcasting large variables and instead use more efficient slicing or data partitioning strategies. Here are a few suggestions to help you reduce memory usage:
1. Precompute Subsets of Data
Instead of passing the entire `wim_4d` array to each worker, you can precompute and pass only the necessary slices of the array.
2. Use `parfor` with Sliced Variables
Ensure that the variables used inside the `parfor` loop are sliced properly. This means that each worker should only work on a subset of the data.
3. Optimize Memory Usage within `parfor`
Minimize the amount of data being passed to and from the workers. Try to reduce the size of intermediate variables and avoid unnecessary copies of data.
Here's a modified version of your code that attempts to address these issues:
clc; clear;
warpedImages = num2cell(uint8(randi([0,255], 1654, 6288, 3, 35)),1:3);
warpedImages = reshape(warpedImages,1,[]);
% Initialize
n = length(warpedImages);
sigmaN = 10;
sigmag = 0.1;
panoramasize = size(warpedImages{1});
Amat = cell(n);
Bvec = zeros(n,1);
IuppeIdx = nonzeros(triu(reshape(1:numel(Amat), size(Amat))));
Amat_temp = cell(1,length(IuppeIdx));
matSize = size(Amat);
% Precompute the necessary slices of wim_4d
wim_4d_slices = cell(1, n);
for i = 1:n
wim_4d_slices{i} = wim_4d(:,:,:,i);
end
% Get the Ibarijs and Nijs
parfor i = 1:length(IuppeIdx)
% Index to subscripts
[ii,jj] = ind2sub(matSize, IuppeIdx(i));
if ii == jj
diag_val_1 = 0;
diag_val_2 = 0;
Z = 1:n;
Z(Z==ii) = [];
for d = Z
[Ibarij, Ibarji, Nij] = getIbarNij(panoramasize, wim_4d_slices{ii}, wim_4d_slices{d});
diag_val_1 = diag_val_1 + ( (Nij + Nij) .* Ibarij.^2 );
diag_val_2 = diag_val_2 + Nij;
end
diag_val = diag_val_1 + (sigmaN^2/sigmag^2) * diag_val_2;
B_val = (sigmaN^2/sigmag^2) * diag_val_2;
Amat_temp{i} = diag_val;
Bvec(i) = B_val;
end
if ii ~= jj
[Ibarij, Ibarji, Nij] = getIbarNij(panoramasize, wim_4d_slices{ii}, wim_4d_slices{jj});
Amat_temp{i} = -(Nij+Nij) .* (Ibarij .* Ibarji);
end
end
function [Ibarij,Ibarji,Nij] = getIbarNij(panoramasize, Imij, Imji)
Ibarij = zeros(panoramasize,'uint8');
Ibarji = zeros(panoramasize,'uint8');
% Overlay the warpedImage onto the panorama.
maski = imbinarize(rgb2gray(255 * Imij));
maskj = imbinarize(rgb2gray(255 * Imji));
% Find the overlap mask
Nij_im = maski & maskj;
Nij_im = imfill(Nij_im, 'holes');
Nijidx = repmat(Nij_im, 1, 1, size(Imij,3));
% Get the overlapping region RGB values for two images
Ibarij(Nijidx) = Imij(Nijidx);
Ibarji(Nijidx) = Imji(Nijidx);
% Convert to double
Ibarij_double = double(Ibarij);
Ibarji_double = double(Ibarji);
% Nij
Nij = sum(sum(Nij_im));
% Ibar ijs
Ibarij = reshape(sum(sum(Ibarij_double)) ./ Nij, 1, 3);
Ibarji = reshape(sum(sum(Ibarji_double)) ./ Nij, 1, 3);
% Replace NaNs by zeros
Ibarij(isnan(Ibarij)) = 0;
Ibarji(isnan(Ibarji)) = 0;
end
I hope the above information helps you.
Thank you.

Catégories

En savoir plus sur Parallel for-Loops (parfor) dans Help Center et File Exchange

Produits


Version

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by