EnzymeAD / EnzymeAD/Enzyme

Segfault on O0 and error on O1

Open
#2,966 5 comments 0 reactions 0 assignees View on GitHub
fortran
Dominant language
LLVM
Stars
1.7k
Forks
188
Avg merge
1d 22h
Merged PRs (30d)
26

Description

I am trying to compile some fortran code with DVODE. I am getting a segmentation fault if I precompile the individual files with O0, and an compile-time error during `opt` if I compile it at O1. See my [Makefile](https://github.com/user-attachments/files/30259866/Makefile.txt)
[dvode.f90.txt](https://github.com/user-attachments/files/30259883/dvode.f90.txt)

When running `flang-22 -O1`, I get the following error: [error_O1.log](https://github.com/user-attachments/files/30259848/error_O1.log)
When running `flang-22 -O0` instead, I get the following segmentation fault: [error_O0.log](https://github.com/user-attachments/files/30259847/error_O0.log)

Contents of `main.f90`:
```fortran
MODULE robertston
IMPLICIT NONE

DOUBLE PRECISION, PARAMETER :: initial_time = 0.0D0
DOUBLE PRECISION, PARAMETER :: final_time = 40.D0

DOUBLE PRECISION, PARAMETER, DIMENSION(3) :: default_rate_constants = (/0.04D0, 1.0D4, 3.0D7/)
DOUBLE PRECISION, PARAMETER, DIMENSION(3) :: default_initial_abundances = (/1.D0, 0.D0, 0.D0/)

CONTAINS
PURE FUNCTION get_reaction_rates(abundances, rate_constants) RESULT(reaction_rates)
DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: abundances
DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: rate_constants

DOUBLE PRECISION, DIMENSION(SIZE(rate_constants)) :: reaction_rates

reaction_rates(1) = rate_constants(1) * abundances(1)
reaction_rates(2) = rate_constants(2) * abundances(2) * abundances(3)
reaction_rates(3) = rate_constants(3) * (abundances(2) ** 2)
END FUNCTION get_reaction_rates

PURE FUNCTION get_rates_of_change(abundances, rate_constants) RESULT(rates_of_change)
DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: abundances
DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: rate_constants

DOUBLE PRECISION, DIMENSION(SIZE(abundances)) :: rates_of_change

DOUBLE PRECISION, DIMENSION(SIZE(rate_constants)) :: reaction_rates

reaction_rates = get_reaction_rates(abundances, rate_constants)
rates_of_change(1) = -reaction_rates(1) + reaction_rates(2)
rates_of_change(2) = reaction_rates(1) - reaction_rates(2) - reaction_rates(3)
rates_of_change(3) = reaction_rates(3)
END FUNCTION get_rates_of_change

SUBROUTINE ROBERTSTON_F(NEQUATIONS, T, Y, YDOT)
INTEGER, INTENT(IN) :: NEQUATIONS

DOUBLE PRECISION, INTENT(IN) :: T
DOUBLE PRECISION, DIMENSION(NEQUATIONS), INTENT(IN) :: Y
DOUBLE PRECISION, DIMENSION(NEQUATIONS), INTENT(OUT) :: YDOT

YDOT = get_rates_of_change(Y, default_rate_constants)
END SUBROUTINE ROBERTSTON_F
END MODULE robertston

MODULE solver
USE DVODE_F90_M
USE robertston, ONLY: ROBERTSTON_F

IMPLICIT NONE

ABSTRACT INTERFACE
PURE FUNCTION I_YDOT_function(abundances, rate_constants) RESULT(YDOT)
DOUBLE PRECISION, INTENT(IN), DIMENSION(:) :: abundances
DOUBLE PRECISION, INTENT(IN), DIMENSION(:) :: rate_constants

DOUBLE PRECISION, DIMENSION(SIZE(abundances)) :: YDOT
END FUNCTION I_YDOT_function
END INTERFACE

CONTAINS
SUBROUTINE solve_abundances(nspecies, nreactions, nsteps, &
rate_constants, initial_abundances, &
final_time, YDOT_function, abundances)
INTEGER, INTENT(IN) :: nspecies, nreactions, nsteps
DOUBLE PRECISION, DIMENSION(nreactions), INTENT(IN) :: rate_constants
DOUBLE PRECISION, DIMENSION(nspecies), INTENT(IN) :: initial_abundances
DOUBLE PRECISION, INTENT(IN) :: final_time
PROCEDURE(I_YDOT_function) :: YDOT_function

DOUBLE PRECISION, DIMENSION(nspecies, nreactions), INTENT(OUT) :: abundances

DOUBLE PRECISION :: target_time
INTEGER :: time_idx
DOUBLE PRECISION :: time_step
DOUBLE PRECISION :: current_time

INTEGER :: ITASK, ISTATE
TYPE(VODE_OPTS), SAVE :: OPTIONS

CHARACTER(LEN=*), PARAMETER :: FMT = "(F15.8,E15.8,E15.8,E15.8)"

ITASK = 1
ISTATE = 1
OPTIONS = SET_OPTS(METHOD_FLAG=22, ABSERR=1.0D-8, RELERR=1.0D-8, &
USER_SUPPLIED_JACOBIAN=.False., NEVENTS=0)

current_time = 0.0D0
time_step = (final_time - current_time) / NSTEPS

abundances(:, 1) = initial_abundances
WRITE(*,FMT) current_time, abundances(1, 1), abundances(2, 1), abundances(3, 1)
DO time_idx = 1, NSTEPS
target_time = current_time + time_step

CALL DVODE_F90(F, nspecies, abundances(:, time_idx), current_time, target_time, &
& ITASK, ISTATE, OPTIONS)
current_time = target_time
WRITE(*,FMT) current_time, abundances(1, time_idx), abundances(2, time_idx), abundances(3, time_idx)
END DO

CONTAINS
SUBROUTINE F(NEQUATIONS, T, Y, YDOT)
INTEGER, INTENT(IN) :: NEQUATIONS

INTEGER, PARAMETER :: WP = KIND(1.0D0)
REAL(WP), INTENT(IN) :: T
REAL(WP), DIMENSION(NEQUATIONS), INTENT(IN) :: Y
REAL(WP), DIMENSION(NEQUATIONS), INTENT(OUT) :: YDOT

YDOT = YDOT_function(Y, rate_constants)
END SUBROUTINE F
END SUBROUTINE solve_abundances

FUNCTION get_final_abundance(nspecies, nreactions, nsteps, &
rate_constants, initial_abundances, &
final_time, YDOT_function, species_index) RESULT(final_abundance)
INTEGER, INTENT(IN) :: nspecies, nreactions, nsteps, species_index
DOUBLE PRECISION, DIMENSION(nreactions), INTENT(IN) :: rate_constants
DOUBLE PRECISION, DIMENSION(nspecies), INTENT(IN) :: initial_abundances
DOUBLE PRECISION, INTENT(IN) :: final_time
PROCEDURE(I_YDOT_function) :: YDOT_function

DOUBLE PRECISION :: final_abundance

DOUBLE PRECISION, DIMENSION(nspecies, nreactions) :: abundances

CALL solve_abundances(nspecies, nreactions, nsteps, &
rate_constants, initial_abundances, &
final_time, YDOT_function, abundances)

final_abundance = abundances(species_index, NSTEPS)
END FUNCTION get_final_abundance
END MODULE solver

PROGRAM main
USE robertston, ONLY: default_rate_constants, &
default_initial_abundances, initial_time, final_time, get_rates_of_change
USE enzyme, only: enzyme_const, enzyme_dup, enzyme_fwddiff
USE solver, only: solve_abundances, get_final_abundance

IMPLICIT NONE

INTEGER, PARAMETER :: NSPECIES = SIZE(default_initial_abundances)
INTEGER, PARAMETER :: NREACTIONS = SIZE(default_rate_constants)
INTEGER, PARAMETER :: NSTEPS = 2000
DOUBLE PRECISION, DIMENSION(NSPECIES, NSTEPS) :: abundances

DOUBLE PRECISION, DIMENSION(NREACTIONS) :: d_rate_constants = 0
DOUBLE PRECISION, DIMENSION(NREACTIONS) :: d_initial_abundances = 0
CALL enzyme_fwddiff(get_final_abundance, enzyme_const, NSPECIES, enzyme_const, NREACTIONS, &
enzyme_const, NSTEPS, &
enzyme_dup, default_rate_constants, d_rate_constants, &
enzyme_dup, default_initial_abundances, d_initial_abundances, &
enzyme_const, final_time, &
enzyme_const, get_rates_of_change, &
enzyme_const, 1)
END PROGRAM main
```

Could anyone help me out with this? Is this an issue in my Makefile, or just asking something of Enzyme it cannot do? If I remove all the calls to enzyme and just compile as usual, flang can compile it just fine.

Thank you!

Contributor guide

Open the contributing guide

Research direction

Start with the attached Makefile, main.f90, error_O1.log, and error_O0.log; reproduce with flang-22 at -O0 and -O1, focusing on the enzyme_fwddiff(get_final_abundance, ...) entry point. Done means identifying whether the failure is in the build, the Enzyme/Flang interaction, or unsupported input, and documenting a reproducible diagnosis or fix.

Written by the indexing model from the issue text.

Assessment

Tech stack
fortran
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.