Hi Mary,
calling a C from Fortran is not a big issue per-se. However with your MATLAB generated routines there are other aspects which make things complicated.
- You will need to install the MATLAB Runtime Library - a standalone shared library of 3.9 GB (the 64-bit Linux version).
- To link your generated MATLAB C functions, it’s recommended to use
mbuild
, MATLAB’s C and C++ compiler and linker wrapper. This tool is aware of the MATLAB runtime path and settings. With your Fortran main program you will be on your own. - The MATLAB runtime is stateful, it has to be initialized and terminated appropriately. In Fortan this would look like this:
program main
use, intrinsic :: iso_c_binding
! MATLAB C Library (C function interfaces)
use mcl, only: &
mclInitializeApplication, &
mclRunMain, &
mclTerminateApplication
! Generated library YYY (C function interfaces)
use libYYY, only: &
libYYYInitialize, libYYYTerminate, &
mlfBodyfatFcn
implicit none
logical(c_bool) :: success
integer(c_int) :: stat
success = mclInitializeApplication(c_null_ptr, 0)
if (.not. success) then
write(*,'(A)') "Error: Initialization failed."
stop 1
end if
! ... main stuff goes here ...
success = mclTerminateApplication()
if (.not. success) then
write(*,'(A)') "Error: termination failed"
end if
end program
- The shared library generated by MATLAB is stateful, it has it’s own initialization and termination routines (
libBodyfatInitialize
/libBodyfatTerminate
). Each shared library you export will have it’s own. Your program will be like an onion of setup/teardown calls. - Finally, everything is initialized… but it’s not time to celebrate yet - we need to create some
mxArray
instances. You can choose between the C Matrix API or the (old-fashioned) Fortran counterpart that requires a preprocessor and is probably bound to the MATLAB-provided compilers. Both API’s require a non-negligible amount of setup and pointer manipulation to fill themxArray
or retrieve values out of it. I would probably pick the C version. - Now that the MATLAB
mxArray
s are ready, the generated function can be called. How? Either you write an explicit C interface for the generated function (the ones prepended withmlx
andmlf
) or you write a C wrapper with name-mangling matching your Fortran compiler (e.g.mlfBodyfatFcn_( /* ... */ )
). You should probably only be using the MATLAB supported compilers with the generated functions, so heck why not. - Now you are ready to call your function.
nargout
is the number of outputs you want (Y
,Xf
, andAf
are output arguments).X
is your input. I suspect that_U4b
and_U4x
are cell arrays for some neural-network parameters. Consult the MATLAB documentation for an explanation. - If everything so far has worked, you will get the
Y
values that you can now reuse in your Fortran program. Hooray!
Personally, before settling on this plan I would investigate exporting the network to some other format. MATLAB provides exportONNXNetwork
(maybe join forces with this other thread) and exportNetworkToTensorFlow
. If you save the network in HDF5 format you may be able to import it into neural-fortran. (one caveat is the architecture you are dealing with might not be supported).