libprima / prima

PRIMA is a package for solving general nonlinear optimization problems without using derivatives. It provides the reference implementation for Powell's derivative-free optimization methods, i.e., COBYLA, UOBYQA, NEWUOA, BOBYQA, and LINCOA. PRIMA means Reference Implementation for Powell's methods with Modernization and Amelioration, P for Powell.
http://libprima.net
BSD 3-Clause "New" or "Revised" License
291 stars 35 forks source link

Test cmake and c interface with `PRIMA_REAL_PRECISION` being in [32, 64, 128], `PRIMA_INTEGER_KIND` being in [16, 32, 64], and `PRIMA_DEBUGGING` being in [0, 1] #129

Open zaikunzhang opened 6 months ago

zaikunzhang commented 6 months ago

The Fortran code allows REAL(RP) to be different from 64-bit real, and INTEGER(IK) to be different from 32-bit integer. This can be done by setting PRIMA_REAL_PRECISION and PRIMA_INTEGER_KIND in fortran/common/ppf.h.

We should make sure that the cmake and c interface (or any other interface) still work if we vary these values from the default.

In addition, PRIMA_DEBUGGING in ppf.h controls whether the Fortran code is in the debug mode, which enables checking of pre/postconditions in the Fortran code. This should also be tested.

Moreover, PRIMA does not tolerate any warning. This has been achieved by the Fortran code. The standard should be maintained by any other interface and implementation.

@nbelakovski , we discussed this before. Could you have a look? Thanks.

nbelakovski commented 6 months ago

Since the C interface has been written with double and int which are 8 and 4, respectively, on most platforms, does it make any sense to compile the C interface with RP != 8? Or would this effort include work to set up the C API in such a way that it can choose the precision of its floating point value based on RP or some other #define?

zaikunzhang commented 6 months ago

Or would this effort include work to set up the C API in such a way that it can choose the precision of its floating point value based on RP or some other #define?

This will be nice, but I don't think it is a must for the time being if it takes too much effort. For the moment, we only need to test. If someone wants RP to be different from the default value, he can modify fortran/common/ppf.h manually. (Edit: see the comment below.)

Since the C interface has been written with double and int which are 8 and 4, respectively, on most platforms, does it make any sense to compile the C interface with RP != 8?

First of all, if a piece of code fails to compile when we change some macros to some non-default but correct values, then the code is wrong. It is logically wrong to assume that RP corresponds to double precision.

Secondly, RP != 8 may be beneficial in terms of memory, computing time, or precision, depending on the problem and the platform. For example, if the function values are noisy, it may not be necessary to use RP = 8 for the internal computing of the solver.

Thirdly, indeed, double precision does not necessarily correspond to RP = 8. It is the case for gfortran and ifx, but not for nagfor. The particular value of RP is platform-dependent. But double precision does correspond to PRIMA_REAL_PRECISION = 64.

Thank you.

zaikunzhang commented 6 months ago

Or would this effort include work to set up the C API in such a way that it can choose the precision of its floating point value based on RP or some other #define?

This will be nice, but I don't think it is a must for the time being if it takes too much effort. For the moment, we only need to test. If someone wants RP to be different from the default value, he can modify fortran/common/ppf.h manually.

The MATLAB interface provides two options debug and precision to end users. debug is a boolean, default to false; precision is a string and can be "single", "double", or "quadruple", default to "double". The interface will call an appropriate binary according to their values. There are 6 such binaries, compiled with 6 combinations of PRIMA_DEBUGGING and PRIMA_REAL_PRECISION.

I do hope that other interfaces can do the same one day, which will take some effort but it is doable, as I have done in MATLAB. Before that day comes, users can modify PRIMA_DEBUGGING and PRIMA_REAL_PRECISION in fortran/common/ppf.h if they need a customized library different from the default, where PRIMA_DEBUGGING = 0 (no debugging) and PRIMA_REAL_PRECISION = 64 (double precision).

BTW, PRIMA will gradually unveil its complexity when you know it more. Enjoy! :)