Open desal opened 11 months ago
Hello @desal , thank you so much for your interest in adopting PRIMA in dlib, and for raising your concern.
Apologies for my long-delayed response.
A short answer to your question: PRIMA pays more attention to reducing the number of function evaluations and improving the code clarity & simplicity, even if this is at the cost of more flop taken inside the solvers.
Why is this reasonable? PRIMA is designed as a package for derivative-free optimization problems, where the cost is dominated by function evaluations, not the flop inside the solvers. In these problems, each function evaluation may take several minutes, hours, or days, and hence it makes little sense to care about how to save the flop and reduce the internal computational time by several milliseconds per iteration.
Of course, this does not mean that PRIMA does not care about the internal cost of solvers. This just means that there is a priority:
Reducing number of function evaluations >> improving code simplicity & clarity >> saving internal cost of solvers.
In your test, as you measured, each function evaluation takes an extremely short time. Therefore, the computing time is dominated by the internal cost of the solvers. However, this is normally not the case in practice --- or I should say, PRIMA is not designed for such a situation.
If your interest is to solve problems where the function evaluation is cheap, then Powell's solver may not be the correct choice. If you decide to adopt Powell's solvers while concerned about the internal cost of the solvers, then there are two possibilities.
matprod
, inprod
, etc; you only need to consider the procedures in fortran/common/linalg.f90). However, I am not sure whether such a version will be much more efficient (in terms of internal costs of the solvers) than the current one. To elaborate things better, I have posted a discussion. I hope it is not too long to read (the length partially explains the delay). I will be very glad to see your comments there.
Given the above comments, the results of your test are still a bit strange to me.
PRIMA_DEBUGGING
to 1 in fortran/common/ppf.h
? Such a setting will be expensive and should not be used in production.
I've been looking at dropping in prima as a replacement for dlib's BOBYQA implementation. I've noticed that prima is significantly slower for comparable number of evaluations. I can appreciate that the time spent in the optimiser itself is typically small compared to typical cost of evaluating the objective function, and correctness/maintainability of the code is worth paying some performance penalty. However, in my use case the overhead (i.e. time spent in optimiser outside of objective function) went from ~5% to ~50%. It's also not a strictly fair comparison, as they aren't bug-for-bug compatible and are going to have differences in stopping conditions, path dependency, etc.
I'm not sure if this is a priority right now (as my use case maybe somewhat extreme in how fast the objective function runs), but at least for me having this a lot closer would mean that I could start to consider Prima as a by-default choice for any problems.
Here's a (rather contrived) quick and dirty example illustrating the difference:
and with dlib:
which gives me the following results:
I've done some basic tweaking of optimisation flags, but didn't make much of a difference either way.