Using iprint = 0 negatively influences the performance
Sven-MintTower opened this issue · comments
Using the function fmin_cobyla the iprint variable influences the performance non-trivially. Putting iprint to 0 reduces the performance by a factor of 100x. Whereas iprint is 1,2,3 perform in line. (1 being the fastest due to less printing)
Weird! I've tried on the paraboloid example. It runs in ~10ms +/- 5ms on my machine whatever the iprint value, anyway I am far from seeing a x100 factor. Could you provide info on your setup and the code showing the problem?
Unfortunately, I cannot provide my current setup. However, I think we have fixed it. In src/cobyla.rs line 523 should be an if statement around the println!. Now the current_block is not set and the loop isn't broken if iprint is set to 0.
Sorry, I am not sure to understand your fix. Could you copy it here?
if nfvals >= maxfun
&& nfvals > 0 as libc::c_int as libc::c_long {
status = -(2 as libc::c_int);
if iprint > 0 as libc::c_int as libc::c_long {
println!("Return from subroutine COBYLA because {:?}.\n",
cobyla_reason(status));
};
current_block = 2880604979707412946;
break;
Hmmm... If there is a bug it seems to come from the original code (the iprint>0
condition is tested with the others)
a) original c code :
Line 478 in f83fcff
b) rust code from c2rust:
Line 466 in f83fcff
c) edited rust code:
Line 521 in f83fcff
I agree that your fix is relevant as changing the verbosity should not change the logic like the status setting. On your test case if iprintf is set to zero, the algorithm still terminates? What is the value of the status then?
With the bug: the algorithm indeed still terminates. However, with status -2 mostly.
Without the bug: the algorithm also still terminates. But, with significantly more zeros as status.
The translation of the Fortran to C. The Fortan code of scipy doesn't seem to have this bug. https://github.com/scipy/scipy/blob/686422c4f0a71be1b4258309590fd3e9de102e18/scipy/optimize/cobyla/cobyla2.f#L141C4-L141C4 IF (NFVALS .GE. MAXFUN .AND. NFVALS .GT. 0) THEN IF (IPRINT .GE. 1) PRINT 50 50 FORMAT (/3X,'Return from subroutine COBYLA because the ', 1 'MAXFUN limit has been reached.') DINFO(1)=2.0d0 GOTO 600
My bad! I've finally found, I've introduced this bug in the commit 409d753 😔 Maybe a leftover for a test/debug session... Do not remember. The original code did not test iprint
at all at this point.
I will issue a release with your fix.
Thanks for the good catch!
Just to notice that the bug is present at another line:
Line 1617 in f83fcff
The C code includes itself at some point, hence the duplication in the Rust code.