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

C interface and nagfor: segmentation fault with `nagfor -C=undefined` #143

Closed zaikunzhang closed 5 months ago

zaikunzhang commented 5 months ago

The following code encounters segmentation faults with nagfor 7.1, gcc 13.2, and AppleClang 1.5.0.

#!/bin/bash
git clone git@github.com:libprima/prima.git
git checkout 39a4667
cd prima
export CC='gcc'  # OR: export CC='clang'
export FC='nagfor'
export FFLAGS='-C=undefined'
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=. -LAH -DCMAKE_Fortran_FLAGS="${FFLAGS}" .
cmake --build . --target install
cmake --build . --target tests
ctest --output-on-failure -V -E stress

Note that only the C tests encounter failures. The Fortran tests work correctly.

zaikunzhang commented 5 months ago

This turns out not a bug of the compiler or the PRIMA code.

The technical support of NAG commented as follows.

I note that the repository contains C code, and your configuration commands include a C compiler. I quote from our documentation:

“The -C=undefined option is subject to a number of limitations; in particular, it is not binary compatible with Fortran code compiled without that option, and is not compatible with calling C code via a BIND(C) interface.”

The section giving details on the option further states:

“Program units compiled with this option use a different ABI, which means that they are incompatible with program units compiled without this option, and not interoperable with C; thus the whole program must be Fortran code and compiled the same way.”

In principle, -C=undefined can never be interoperable with C, because there is no way of C communicating any definition status changes to Fortran. The definition status information is passed through the argument list, that is why it is a different ABI.

That means that if you are linking with any C code, a segmentation fault is certainly expected. This would not be a compiler bug.