diff --git a/diffsl/Cargo.toml b/diffsl/Cargo.toml index aed7ec6..56555f2 100644 --- a/diffsl/Cargo.toml +++ b/diffsl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "diffsl" -version = "0.11.11" +version = "0.12.0" edition.workspace = true license.workspace = true authors.workspace = true diff --git a/diffsl/Enzyme b/diffsl/Enzyme index db74433..6f0b4c9 160000 --- a/diffsl/Enzyme +++ b/diffsl/Enzyme @@ -1 +1 @@ -Subproject commit db7443336d020d3184cdc7eab00288fc34983e78 +Subproject commit 6f0b4c9945ada9461d054d7afd6455f78dacaa9f diff --git a/diffsl/src/execution/compiler.rs b/diffsl/src/execution/compiler.rs index 9ffe743..a9ed093 100644 --- a/diffsl/src/execution/compiler.rs +++ b/diffsl/src/execution/compiler.rs @@ -2875,7 +2875,7 @@ mod tests { state_and_const_grad2: "r_i { 3 * y, 2 * y }" expect "r" vec![3., 2.] ; vec![5.] ; vec![0., 0.] ; vec![0.], state_and_const_grad3: "r_i { 2 * p, 3 }" expect "r" vec![2., 0.] ; vec![2.] ; vec![2., 0.] ; vec![2.], state_and_const_grad4: "r_i { 3 * p, 2 * p }" expect "r" vec![3., 2.] ; vec![5.] ; vec![3., 2.] ; vec![5.], - + pow_zero_grad: "r { pow(y - p, p) }" expect "r" vec![0.] ; vec![0.] ; vec![-1.] ; vec![-1.], } macro_rules! tensor_test_big_state { diff --git a/diffsl/src/execution/functions.rs b/diffsl/src/execution/functions.rs index 1cfc8f7..c872c2a 100644 --- a/diffsl/src/execution/functions.rs +++ b/diffsl/src/execution/functions.rs @@ -315,7 +315,12 @@ extern "C" fn pow_f64(x: f64, y: f64) -> f64 { x.powf(y) } extern "C" fn dpow_f64(x: f64, dx: f64, y: f64, dy: f64) -> f64 { - x.powf(y - 1.0) * (y * dx + x * dx.ln() * dy) + let d_dy = if x == 0.0 { + 0.0 // lim x→0+ x^y * ln(x) = 0 for y > 0, avoids NaN from 0 * (-inf) + } else { + x * x.ln() * dy + }; + x.powf(y - 1.0) * (y * dx + d_dy) } extern "C" fn min_f64(x: f64, y: f64) -> f64 { @@ -465,7 +470,12 @@ extern "C" fn pow_f32(x: f32, y: f32) -> f32 { x.powf(y) } extern "C" fn dpow_f32(x: f32, dx: f32, y: f32, dy: f32) -> f32 { - x.powf(y - 1.0) * (y * dx + x * dx.ln() * dy) + let d_dy = if x == 0.0 { + 0.0 // lim x→0+ x^y * ln(x) = 0 for y > 0, avoids NaN from 0 * (-inf) + } else { + x * x.ln() * dy + }; + x.powf(y - 1.0) * (y * dx + d_dy) } extern "C" fn min_f32(x: f32, y: f32) -> f32 {