Source files in this subdirectory provides Fortran bindings for Enzyme, as detailed in the following.
We provide bindings for the __enzyme_fwddiff and __enzyme_autodiff function
hooks using implicit interfaces. Some Fortran compilers disallow procedure names
starting with an underscore so we rename the function hooks to remove the
leading double underscore.
To make use of the enzyme_autodiff function hook in your code, import via
use enzyme, only: enzyme_autodiffand call it as a subroutine or function as appropriate. For example, if you have a function
real function square(x)
real, intent(in) :: x
square = x**2
end functionthen you can compute its derivative with reverse mode with the call
call enzyme_autodiff(square, x, dx)Similarly for
enzyme_fwddiff. Thanks to the implicit interface, arbitrary signatures are
supported, with the following caveats.
Note
A limitation of the implicit interfacing is that it only works for arguments
that are passed by reference - the default in Fortran. If you want to pass any
arguments by value using the value attribute then you will need to write an
explicit interface block to the function hook yourself.
Warning
The implicit interfacing approach is not supported by the Intel Fortran
compiler ifx when running without optimizations, i.e., running with -O0. If
you want to use ifx with -O0 then you will need to write an explicit
interface block, even if you are only passing arguments by reference.
Warning
Differentiation with respect to procedures with assumed shape arrays is not currently supported when compiling with Flang. It should work with ifx, however.
We provide bindings for the activity descriptors enzyme_const, enzyme_dup,
enzyme_dupnoneed, and enzyme_out, as well as the descriptors
enzyme_scalar, enzyme_width, and enzyme_vector. To make use of these in
your code, import via
use enzyme, only: enzyme_const, enzyme_dupand then include them in calls to function hooks as you would in C or C++. For example, if you have a subroutine
subroutine my_subroutine(n, x, y)
integer, intent(in) :: n
real, dimension(n), intent(in) :: x
real, dimension(n), intent(out) :: y
! ...
end subroutine my_subroutinethen you can make use of activity descriptors like so:
call enzyme_autodiff(my_subroutine, enzyme_const, n, &
enzyme_dup, x, dx, enzyme_dup, y, dy