Build system: enable the interleaved API in MEX files for Octave ⩾ 8.4.0

Unfortunately it is not possible to enable it for all supported Octave
versions (which would have allowed us to remove the old codepath), because of
this bug: https://savannah.gnu.org/bugs/?64687
dcontrib-log
Sébastien Villemot 2023-11-23 18:14:13 +01:00
parent c0e39d40a7
commit f21fda7dfa
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
4 changed files with 44 additions and 8 deletions

View File

@ -203,7 +203,17 @@ else # Octave build
exe_rpath = octlibdir
exe_link_args = [ '-L' + octlibdir ] + octave_libs
# Minimal Octave version for which we enable the interleaved API.
# Octave 7 is supposed to support it, but it crashes due to this bug:
# https://savannah.gnu.org/bugs/?64687
octave_minimal_version_for_interleaved_api = '8.4.0'
octave_defs = [ '-DOCTAVE_MEX_FILE', '-DMEXEXT=".mex"' ]
if octave_version.version_compare('>=' + octave_minimal_version_for_interleaved_api)
# Mimic the behaviour of mkoctfile which adds this define when the
# interleaved API is requested.
octave_defs += '-DMX_HAS_INTERLEAVED_COMPLEX=1'
endif
mex_kwargs = { 'name_prefix' : '',
'name_suffix' : 'mex',
@ -215,6 +225,12 @@ else # Octave build
'install' : true,
'install_dir' : 'lib/dynare/mex/octave' }
if octave_version.version_compare('>=' + octave_minimal_version_for_interleaved_api)
# Mimic the behaviour of mkoctfile which compiles in a similar source file
# when interleaved API is requested.
mex_kwargs += { 'sources' : 'mex/sources/octave_interleaved.c' }
endif
# The -L argument is useful when cross-compiling.
blas_dep = declare_dependency(link_args : [ '-L' + (octlibdir / '../..') ] + run_command(mkoctfile_exe, '-p', 'BLAS_LIBS', check : true).stdout().split())
lapack_dep = declare_dependency(link_args : run_command(mkoctfile_exe, '-p', 'LAPACK_LIBS', check : true).stdout().split(),

View File

@ -1 +1,7 @@
#define MX_HAS_INTERLEAVED_COMPLEX (defined(MATLAB_MEX_FILE))
! Under Octave, MX_HAS_INTERLEAVED_COMPLEX is defined through the command-line
! defines (as is done by mkoctfile), while under MATLAB it is defined through
! the present file (because it is defined by mex.h there).
#ifdef MATLAB_MEX_FILE
# define MX_HAS_INTERLEAVED_COMPLEX 1
#endif

View File

@ -13,6 +13,9 @@
! was an API_VER2 define for those.
! For each function, the information can be retrieved from either matrix.h or
! mex.h.
! Under Octave, when the interleaved API is used, some functions have a
! different symbol name, handled through the API_VER_INTERLEAVED define;
! see octave/mexproto.h for the list of affected functions.
! — C passes arguments by value, so the “value” keyword is often needed
! — Strings passed to C must be null terminated (hence a wrapper is needed to
! append c_null_char)
@ -48,15 +51,21 @@
! You should have received a copy of the GNU General Public License
! along with Dynare. If not, see <https://www.gnu.org/licenses/>.
#include "defines.F08"
#ifdef MATLAB_MEX_FILE
# define API_VER "_800"
# define API_VER_INTERLEAVED "_800"
#else
! Octave
# define API_VER ""
# if MX_HAS_INTERLEAVED_COMPLEX
# define API_VER_INTERLEAVED "_interleaved"
# else
# define API_VER_INTERLEAVED ""
# endif
#endif
#include "defines.F08"
!!! C Matrix API
!!! Listed in same order as https://fr.mathworks.com/help/matlab/cc-mx-matrix-library.html
module matlab_mat
@ -109,14 +118,14 @@ module matlab_mat
!! Create, Query, and Access Data Types
! Numeric types
type(c_ptr) function mxCreateDoubleMatrix(m, n, ComplexFlag) bind(c, name="mxCreateDoubleMatrix"//API_VER)
type(c_ptr) function mxCreateDoubleMatrix(m, n, ComplexFlag) bind(c, name="mxCreateDoubleMatrix"//API_VER_INTERLEAVED)
use iso_c_binding
import :: mwSize, mxComplexity
integer(mwSize), intent(in), value :: m, n
integer(mxComplexity), intent(in), value :: ComplexFlag
end function mxCreateDoubleMatrix
type(c_ptr) function mxCreateDoubleScalar(value) bind(c, name="mxCreateDoubleScalar"//API_VER)
type(c_ptr) function mxCreateDoubleScalar(value) bind(c, name="mxCreateDoubleScalar"//API_VER_INTERLEAVED)
use iso_c_binding
real(c_double), intent(in), value :: value
end function mxCreateDoubleScalar
@ -171,7 +180,7 @@ module matlab_mat
#endif
! Sparse
type(c_ptr) function mxCreateSparse(m, n, nzmax, ComplexFlag) bind(c, name="mxCreateSparse"//API_VER)
type(c_ptr) function mxCreateSparse(m, n, nzmax, ComplexFlag) bind(c, name="mxCreateSparse"//API_VER_INTERLEAVED)
use iso_c_binding
import :: mwSize, mxComplexity
integer(mwSize), intent(in), value :: m, n, nzmax
@ -216,7 +225,7 @@ module matlab_mat
type(c_ptr), intent(in), value :: array_ptr
end function mxIsLogicalScalar
type(c_ptr) function mxCreateLogicalScalar(value) bind(c, name="mxCreateLogicalScalar"//API_VER)
type(c_ptr) function mxCreateLogicalScalar(value) bind(c, name="mxCreateLogicalScalar"//API_VER_INTERLEAVED)
use iso_c_binding
import :: mxLogical
logical(mxLogical), intent(in), value :: value
@ -235,7 +244,8 @@ module matlab_mat
end function mxIsClass_internal
! Structure
type(c_ptr) function mxCreateStructMatrix_internal(m, n, nfields, fieldnames) bind(c, name="mxCreateStructMatrix"//API_VER)
type(c_ptr) function mxCreateStructMatrix_internal(m, n, nfields, fieldnames) bind(c, name="mxCreateStructMatrix" &
//API_VER_INTERLEAVED)
use iso_c_binding
import :: mwSize
integer(mwSize), intent(in), value :: m, n

View File

@ -0,0 +1,4 @@
/* This file must be compiled in any Octave MEX for which we want the
interleaved API. This is similar to what mkoctfile does when this API is
requested. */
const int __mx_has_interleaved_complex__ = 1;