-
Notifications
You must be signed in to change notification settings - Fork 0
F2CCallingConventions
LAPACK/BLAS functions are called thru FFI. Smallapack thus has to declare correctly the interface for calling these functions. Unfortunately, among the variety of distributions, some of the LAPACK/BLAS libraries uses F2C calling conventions that do not conform to the standard ABI.
F2C does two unusual things:
- functions that return float are promoted to double
- function that return a complex (single or double precision) pass the result via a pointer in 1st argument
This also is the case for the g77 compiler that uses same conventions, or gfortran if ever the flag -ff2c is forced.
The vecLib framework on MacOSX is known to use f2c conventions, at least up to El Capitan. Some windows port of LAPACK/BLAS might also use F2C. Recent linux distributions seems to use a regular ABI. CLAPACK variants presumably use F2C conventions too.
The float promotion to double did work in x86 (IA32) ABI, because the result was promoted to double anyway thru ST0 register. But it does not work on x86_64 ABI (neither sysv nor win64) which use only 4bytes of xmm0. It might fail in other architectures too.
Consequently we have to deal with two possible FFI interfaces for the same function depending on compiler and/or compiler options (defeating the purpose of an ABI...).
We can imagine the main reason behind those choices: doing so, the generated code works without having to declare the function prototypes. A clever hack? Maybe... Or a case of EASY versus SIMPLE (the lazy solution wins over the right solution). Whatever the reasons, a big thanks to F2C for complexifying our world!
In order to work around this problem, some preferences have been added to Smallapack for Squeak and Pharo (Dolphin and VW workarounds are still to come).
How to choose your preferences?
The best thing is to test with a small snippet:
(LapackSGEMatrix rows: #((2.3))) absMax
If it answers something near 2.3 - ((FloatArray with: 2.3) first)
, then you have the right preference selected.
If it answers a weird result like 3.6893488147419103e19 - ((ByteArray new: 8) doubleAt: 1 put: (FloatArray with: 2.3) first; floatAt: 1)
, then you need to switch F2Cconvention preference on.
If it answers a weird result like 5.31120626e-315 - ((ByteArray new: 8) floatAt: 1 put: (FloatArray with: 2.3) first; doubleAt: 1)
, then you need to switch F2Cconvention preference off.
Though unlikely, there might be different conventions for BLAS, LAPACK and CLAPACK, so there are 3 preferences in Smallapack.