Store intermediate results of cost function when solver is run in parallel

2 次查看(过去 30 天)
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!

采纳的回答

Edric Ellis
Edric Ellis 2024-1-4
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 个评论
Cedric Kotitschke
Cedric Kotitschke 2024-1-30
Now that I implemented this in my framework, I noticed that in some cases, the number of data points in the data queue is less than the number of function evaluations. What exactly causes this? It seems like the send command does not work all the time. The problem is that I can't reproduce this with simple examples...
Edric Ellis
Edric Ellis 2024-1-30
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.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Optimization 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by