Store intermediate results of cost function when solver is run in parallel
3 views (last 30 days)
Show older comments
Cedric Kotitschke
on 4 Jan 2024
Commented: Edric Ellis
on 30 Jan 2024
Hey,
I have a cost function that is comprised of two intermediate results f1 and f2.
When I run some solver to minimize this function, I would like to keep track of f1 and f2 in each iteration. Is there any way to do that? I know that you can specify output functions but they only give you the value of J and x and not f1 and f2.
What I tried to do is to use global variables:
global f1Array f2Array
f1Array = []; f2Array = [];
opts = optimoptions('fmincon', 'UseParallel', true, 'Display', 'off');
[x, ~, ~, output] = fmincon(@fun, 1, [], [], [], [], 0.1, 2, [], opts);
fprintf('fcount according to fmincon: %d\n', output.funcCount)
fprintf('fcount as stored in object: %d\n', numel(f1Array))
function J = fun(x)
global f1Array f2Array
f1 = 1/x^2;
f2 = sqrt(x);
J = max(f1, f2)
f1Array(end+1) = f1;
f2Array(end+1) = f2;
end
However, when you run this optimization in parallel, not all function calls are being kept track of.
It works fine in serial but how do I solve this in parallel?
Thanks!
0 Comments
Accepted Answer
Edric Ellis
on 4 Jan 2024
You could use a parallel.pool.PollableDataQueue to let the workers send the data to the client. The idea is that you create the queue at the client where you will receive the data, and give it to the workers who then call send to send across the intermediate values. Here's one way:
% This queue will receive all the messages
dq = parallel.pool.PollableDataQueue();
opts = optimoptions('fmincon', 'UseParallel', true, 'Display', 'off');
% Bind the DataQueue into the function
[x, ~, ~, output] = fmincon(@(x) fun(x,dq), 1, [], [], [], [], 0.1, 2, [], opts);
% Drain all the results from the DataQueue.
% (It might be simpler to use a parallel.pool.DataQueue together with
% afterEach rather than PollableDataQueue and poll).
f1f2 = {};
ok = true;
while ok
[data, ok] = dq.poll(0);
if ok
f1f2{end+1} = data;
end
end
fprintf('fcount according to fmincon: %d\n', output.funcCount)
fprintf('fcount as stored in object: %d\n', numel(f1f2))
function J = fun(x, dq)
f1 = 1/x^2;
f2 = sqrt(x);
% Send intermediate values to client
send(dq, {f1, f2});
J = max(f1, f2);
end
3 Comments
Edric Ellis
on 30 Jan 2024
Hm, that doesn't sound right, the send should always make it through - I don't know of any reason why it wouldn't. You could try contacting MathWorks support who can help you set up Parallel Computing Toolbox diagnostic logging which might help work out what's going wrong.
More Answers (0)
See Also
Categories
Find more on Optimization 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!