function outVals = combineSlicesAcrossWorkers(localVals, rows, dim)
%COMBINESLICESACROSSWORKERS combines slices from different workers based on
%which rows each worker filled. 
% Be careful if the output has been reshaped - we need to combine
% vectorized.

%   Copyright 2021-2022 The MathWorks, Inc.

origSz = size(localVals);
if numel(origSz) < dim
    % The slice appears to have fewer dimensions than the dimension on
    % which we're combining, so add new singleton dimensions to it.
    origSz = [origSz, ones(1, dim - numel(origSz))];
end
if numel(localVals)>1 && numel(rows) ~= origSz(dim)
    localVals = localVals(:);
end
localStruct = struct("Values", localVals, "Rows", rows, "Dim", dim);
combStruct = spmdReduce(@combineSliceStruct, localStruct);
outVals = reshape(combStruct.Values, origSz);
end

function out = combineSliceStruct(in1, in2)
%COMBINESLICESTRUCT Combines the values filled in for local input 1 and 2 
% based on which slices they set.

dim = in1.Dim;
outVals = assignSlices(in1.Values, in2.Rows, extractSlices(in2.Values, in2.Rows, dim), dim);
outRows = in1.Rows | in2.Rows;
out = struct("Values", outVals, "Rows", outRows, "Dim", dim);
end
