Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8052bde
Add enzyme_mod containing activity descriptor bindings
joewallwork May 7, 2026
47c59bd
Hook Fortran bindings up in build system
joewallwork May 7, 2026
27b7edc
Rename enzyme_mod->enzyme
joewallwork May 7, 2026
eec1139
Use implicit interface in square example
joewallwork May 7, 2026
b34ce86
Add bindings for __enzyme_autodiff and __enzyme_fwddiff to the Fortra…
joewallwork May 7, 2026
3c11497
Use __enzyme_autodiff binding in square example
joewallwork May 7, 2026
237ebc6
Prepend function hooks with f
joewallwork May 11, 2026
2338caf
Trigger Fortran CI on changes to enzyme/Fortran
joewallwork May 11, 2026
3219957
Merge branch 'main' into 2808_fortran-implicit-interfaces
joewallwork May 18, 2026
16090da
Reorder to compile Fortran module before tests
joewallwork May 18, 2026
b7685e0
Drop duplicate option
joewallwork May 18, 2026
96ddb90
Build with ENZYME_FORTRAN=ON in CI
joewallwork May 18, 2026
7a84258
Only build Fortran tests if ENZYME_FORTRAN
joewallwork May 18, 2026
89abe9f
Remove CMake commands not needed
joewallwork May 18, 2026
981e5c0
Use enzyme.mod in Fortran square test
joewallwork May 18, 2026
9822b1c
Add back in CMake from Fortran subdir
joewallwork May 18, 2026
48db7db
Drop unrelated editor changes
joewallwork May 18, 2026
9f65061
Fixes for root CMakeLists
joewallwork May 18, 2026
ebcfca1
Add messages for building Fortran bindings and tests
joewallwork May 18, 2026
db7cbff
Move message into Fortran subdir
joewallwork May 18, 2026
be84f81
Make EnzymeFortran a shared object
joewallwork May 18, 2026
e6e07ca
Try putting module in modules dir
joewallwork May 18, 2026
2be33a7
Introduce another module for function hooks to facilitate aliasing
joewallwork May 18, 2026
6847dd6
Add EnzymeFortran to test dependencies
joewallwork May 19, 2026
090547b
Apply suggestions from code review
joewallwork May 19, 2026
b50179c
Set CMake Fortran compiler in test suite
joewallwork May 19, 2026
fa15388
Hook Fortran compiler up in test suite
joewallwork May 19, 2026
57855fa
Revert to f__enzyme_autodiff
joewallwork Jun 11, 2026
9c5e14a
Merge branch 'main' into 2808_fortran-implicit-interfaces
joewallwork Jun 11, 2026
53ea72d
Revert 57855fae9cb71c56bcf18383c6b92e009f2b522c
joewallwork Jun 11, 2026
c76b261
Disable -O0 test for now
joewallwork Jun 11, 2026
42d8f08
Drop unnecessary semicolon
joewallwork Jun 11, 2026
70a98be
Add README for Fortran bindings
joewallwork Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/fortran.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
paths:
- '.github/workflows/fortran.yml'
- 'enzyme/Enzyme/**'
- 'enzyme/Fortran/**'
- 'enzyme/includes/**'
- 'enzyme/test/**'
- 'enzyme/tools/**'
Expand All @@ -20,6 +21,7 @@ on:
paths:
- '.github/workflows/fortran.yml'
- 'enzyme/Enzyme/**'
- 'enzyme/Fortran/**'
- 'enzyme/includes/**'
- 'enzyme/test/**'
- 'enzyme/tools/**'
Expand Down Expand Up @@ -70,7 +72,7 @@ jobs:
- name: generate build system
run: |
rm -rf build && mkdir build && cd build
cmake ../enzyme -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build }} -DLLVM_DIR=/usr/lib/llvm-${{ matrix.llvm }}/lib/cmake/llvm -DLLVM_EXTERNAL_LIT=`which lit` -DENZYME_IFX=ON
cmake ../enzyme -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build }} -DLLVM_DIR=/usr/lib/llvm-${{ matrix.llvm }}/lib/cmake/llvm -DLLVM_EXTERNAL_LIT=`which lit` -DENZYME_FORTRAN=ON -DENZYME_IFX=ON
Comment thread
vchuravy marked this conversation as resolved.
Outdated
Comment thread
joewallwork marked this conversation as resolved.
Outdated
Comment thread
joewallwork marked this conversation as resolved.
Outdated
- name: build enzyme
working-directory: 'build'
run: ninja LLVMEnzyme-${{ matrix.llvm }}
Expand Down
7 changes: 3 additions & 4 deletions enzyme/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ option(ENZYME_CLANG "Build enzyme clang plugin" ON)
option(ENZYME_FLANG "Build enzyme flang symlink" OFF)
option(ENZYME_MLIR "Build enzyme mlir plugin" OFF)
option(ENZYME_IFX "Enable enzyme support for the Intel Fortran compiler IFX" OFF)
option(ENZYME_IFX "Enable enzyme support for the Intel Fortran compiler IFX" OFF)
option(ENZYME_EXTERNAL_SHARED_LIB "Build external shared library" OFF)
option(ENZYME_APPLE_DYNAMIC_LOOKUP
"On Apple, link Enzyme shared library with -flat_namespace/-undefined,dynamic_lookup instead of linking LLVM"
Expand Down Expand Up @@ -298,12 +297,12 @@ add_subdirectory(Enzyme)
if (ENZYME_BC_LOADER)
add_subdirectory(BCLoad)
endif()
if (ENZYME_ENABLE_PLUGINS)
add_subdirectory(test)
endif()
if (ENZYME_FORTRAN)
add_subdirectory(Fortran)
endif()
if (ENZYME_ENABLE_PLUGINS)
add_subdirectory(test)
endif()

# The benchmarks data are not in git-exported source archives to minimize size.
# Only add the benchmarks if the directory exists.
Expand Down
9 changes: 8 additions & 1 deletion enzyme/Fortran/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
message("Building Fortran bindings")

enable_language(Fortran)
include(FortranCInterface)
FortranCInterface_VERIFY(QUIET)

add_library(EnzymeFortran enzyme.f90)
# Initialize Fortran module build output directory for all subsequent targets
if(NOT DEFINED CMAKE_Fortran_MODULE_DIRECTORY)
set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules")
endif()

add_library(EnzymeFortran SHARED enzyme.f90 enzyme_function_hooks.f90)

# Install library, create target file
install(
Expand Down
6 changes: 6 additions & 0 deletions enzyme/Fortran/enzyme.f90
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
! ===----------------------------------------------------------------------=== !
module enzyme
use iso_c_binding, only: c_int
use enzyme_function_hooks, only: enzyme_autodiff => f__enzyme_autodiff, &
enzyme_fwddiff => f__enzyme_fwddiff
implicit none
private

Expand All @@ -33,4 +35,8 @@ module enzyme
integer(c_int), public, bind(C, name="enzyme_scalar") :: enzyme_scalar
integer(c_int), public, bind(C, name="enzyme_width") :: enzyme_width
integer(c_int), public, bind(C, name="enzyme_vector") :: enzyme_vector

! Bindings for function hooks
public :: enzyme_autodiff
public :: enzyme_fwddiff
end module enzyme
39 changes: 39 additions & 0 deletions enzyme/Fortran/enzyme_function_hooks.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
! ===- enzyme_function_hooks.f90 - Fortran bindings function hooks --------=== !
!
! Enzyme Project
!
! Part of the Enzyme Project, under the Apache License v2.0 with LLVM
! Exceptions. See https://llvm.org/LICENSE.txt for license information.
! SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
!
! If using this code in an academic setting, please cite the following:
! @misc{enzymeGithub,
! author = {William S. Moses and Valentin Churavy},
! title = {Enzyme: High Performance Automatic Differentiation of LLVM},
! year = {2020},
! howpublished = {\url{https://github.com/wsmoses/Enzyme}},
! note = {commit xxxxxxx}
! }
!
! ===----------------------------------------------------------------------=== !
!
! This file provides Fortran bindings for Enzyme's function hooks.
!
! The fact that the double-underscore function hook names appears in the
! implicit interfaces defined in this module is sufficient to get Enzyme to be
! applied in the appropriate way. We provide cleaner bindings without
! double-underscores in the main Fortran Enzyme module in enzyme.f90.
!
! ===----------------------------------------------------------------------=== !
module enzyme_function_hooks
Comment thread
vchuravy marked this conversation as resolved.
implicit none
private

! Bindings for function hooks
! NOTE: Leading underscores are not permitted by some Fortran compilers so we
! prepend with 'f' in the Fortran versions of the function hooks.
public :: f__enzyme_autodiff
public :: f__enzyme_fwddiff
external :: f__enzyme_autodiff
external :: f__enzyme_fwddiff
end module enzyme_function_hooks
3 changes: 2 additions & 1 deletion enzyme/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ add_custom_target(test-cmake COMMAND rm -rf ${CMAKE_CURRENT_BINARY_DIR}/test_cma
endif()
endif()
endif()
if (ENZYME_IFX)
if (ENZYME_FORTRAN AND ENZYME_IFX)
Comment thread
joewallwork marked this conversation as resolved.
Outdated
list(APPEND ENZYME_TEST_DEPS EnzymeFortran)
add_subdirectory(Fortran)
endif()
if (ENZYME_BC_LOADER)
Expand Down
2 changes: 2 additions & 0 deletions enzyme/test/Fortran/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
message("Building Fortran tests")

add_subdirectory(ForwardMode)
add_subdirectory(ReverseMode)

Expand Down
25 changes: 7 additions & 18 deletions enzyme/test/Fortran/ReverseMode/square.f90
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O0 -c %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O0 %t -o %t1 && %t1 | FileCheck %s; fi
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O1 -c %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O1 %t -o %t1 && %t1 | FileCheck %s; fi
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O2 -c %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O2 %t -o %t1 && %t1 | FileCheck %s; fi
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O3 -c %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O3 %t -o %t1 && %t1 | FileCheck %s; fi
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O0 -c %loadFortran %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O0 %t -o %t1 && %t1 | FileCheck %s; fi
Comment thread
joewallwork marked this conversation as resolved.
Outdated
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O1 -c %loadFortran %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O1 %t -o %t1 && %t1 | FileCheck %s; fi
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O2 -c %loadFortran %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O2 %t -o %t1 && %t1 | FileCheck %s; fi
! RUN: if [ %llvmver -ge 13 ]; then ifx -flto -O3 -c %loadFortran %s -o /dev/stdout | %opt %loadEnzyme -enzyme -o %t && ifx -flto -O3 %t -o %t1 && %t1 | FileCheck %s; fi

module math
interface
subroutine square__enzyme_autodiff(fn, x, dx)
interface
real function fn_decal(a)
real, intent(in) :: a
end function
end interface
procedure(fn_decal) :: fn
real, intent(in) :: x
real, intent(inout) :: dx
end subroutine
end interface
contains
real function square( x )
real, intent(in) :: x
Expand All @@ -24,15 +12,16 @@ real function square( x )
end module math

program app
use math
use enzyme, only: enzyme_autodiff
use math, only: square
implicit none
real :: x, dx

x = 3
print *, square(x)

dx = 0
call square__enzyme_autodiff(square, x, dx);
call enzyme_autodiff(square, x, dx);

print *, dx
end program app
Expand Down
1 change: 1 addition & 0 deletions enzyme/test/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ config.substitutions.append(('%OPnewLoadEnzyme', newPMOP))
config.substitutions.append(('%enzyme', ('-enzyme' if int(config.llvm_ver) < 16 else '-passes="enzyme"')))
config.substitutions.append(('%simplifycfg', ("simplify-cfg" if int(config.llvm_ver) < 11 else "simplifycfg")))
config.substitutions.append(('%loopmssa', ("loop" if int(config.llvm_ver) < 11 else "loop-mssa")))
config.substitutions.append(('%loadFortran', '-I@ENZYME_BINARY_DIR@/modules'))

config.substitutions.append(('%loadBC', ''
+ ' @ENZYME_BINARY_DIR@/BCLoad/BCPass-' + config.llvm_ver + config.llvm_shlib_ext
Expand Down
Loading