From c795ea5f5886fb9bf2438102f9966f90a8735b27 Mon Sep 17 00:00:00 2001 From: martinjrobins Date: Mon, 13 Jul 2026 09:55:34 +0000 Subject: [PATCH 1/3] fix: unary plus tangent --- diffsl/src/ast/mod.rs | 1 + diffsl/src/execution/compiler.rs | 1 + diffsl/src/execution/cranelift/codegen.rs | 1 + diffsl/src/execution/llvm/codegen.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/diffsl/src/ast/mod.rs b/diffsl/src/ast/mod.rs index 2240307..bd87477 100644 --- a/diffsl/src/ast/mod.rs +++ b/diffsl/src/ast/mod.rs @@ -583,6 +583,7 @@ impl<'a> Ast<'a> { }, AstKind::Monop(monop) => match monop.op { '-' => Self::new_monop('-', monop.child.tangent()), + '+' => monop.child.tangent(), _ => panic!("Tangent not implemented for operator {}", monop.op), }, AstKind::Call(call) => { diff --git a/diffsl/src/execution/compiler.rs b/diffsl/src/execution/compiler.rs index cfdf151..58f5f46 100644 --- a/diffsl/src/execution/compiler.rs +++ b/diffsl/src/execution/compiler.rs @@ -3142,6 +3142,7 @@ mod tests { 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.], + unary_plus_grad: "r { +y }" expect "r" vec![1.] ; vec![1.] ; vec![0.] ; vec![0.], } macro_rules! tensor_test_big_state { diff --git a/diffsl/src/execution/cranelift/codegen.rs b/diffsl/src/execution/cranelift/codegen.rs index b92ba00..a233527 100644 --- a/diffsl/src/execution/cranelift/codegen.rs +++ b/diffsl/src/execution/cranelift/codegen.rs @@ -1382,6 +1382,7 @@ impl<'ctx, M: Module> CraneliftCodeGen<'ctx, M> { self.jit_compile_expr(name, monop.child.as_ref(), index, elmt, expr_index)?; match monop.op { '-' => Ok(self.builder.ins().fneg(child)), + '+' => Ok(child), unknown => Err(anyhow!("unknown monop op '{}'", unknown)), } } diff --git a/diffsl/src/execution/llvm/codegen.rs b/diffsl/src/execution/llvm/codegen.rs index ce80a80..d2fbfb8 100644 --- a/diffsl/src/execution/llvm/codegen.rs +++ b/diffsl/src/execution/llvm/codegen.rs @@ -3021,6 +3021,7 @@ impl<'ctx> CodeGen<'ctx> { self.jit_compile_expr(name, monop.child.as_ref(), index, elmt, expr_index)?; match monop.op { '-' => Ok(self.builder.build_float_neg(child, name)?), + '+' => Ok(child), unknown => Err(anyhow!("unknown monop op '{}'", unknown)), } } From 0fb93f6752fafa076ef99f157d8fe565dcc39e69 Mon Sep 17 00:00:00 2001 From: martinjrobins Date: Mon, 13 Jul 2026 10:13:48 +0000 Subject: [PATCH 2/3] fix: clippy --- diffsl/src/continuous/builder.rs | 2 +- diffsl/src/execution/cranelift/codegen.rs | 12 ++++++------ diffsl/src/execution/data_layout.rs | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/diffsl/src/continuous/builder.rs b/diffsl/src/continuous/builder.rs index 1cd7e23..f2a2588 100644 --- a/diffsl/src/continuous/builder.rs +++ b/diffsl/src/continuous/builder.rs @@ -371,7 +371,7 @@ impl<'s> ModelInfo<'s> { } } - for (_, v_cell) in self.variables.iter() { + for v_cell in self.variables.values() { // check all non-algebraic state variables have an initial condition let v = v_cell.borrow(); if v.is_state() && v.has_equation() { diff --git a/diffsl/src/execution/cranelift/codegen.rs b/diffsl/src/execution/cranelift/codegen.rs index a233527..dcb5b36 100644 --- a/diffsl/src/execution/cranelift/codegen.rs +++ b/diffsl/src/execution/cranelift/codegen.rs @@ -1642,13 +1642,13 @@ impl<'ctx, M: Module> CraneliftCodeGen<'ctx, M> { ) -> Result { let mut hasher = std::collections::hash_map::DefaultHasher::new(); if call.is_tangent { - std::hash::Hash::hash(&format!("{:?}", &call.args[0]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[2]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[4]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[0]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[2]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[4]), &mut hasher); } else { - std::hash::Hash::hash(&format!("{:?}", &call.args[0]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[1]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[2]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[0]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[1]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[2]), &mut hasher); } let hash_key = std::hash::Hasher::finish(&hasher); let info = self diff --git a/diffsl/src/execution/data_layout.rs b/diffsl/src/execution/data_layout.rs index fc7a568..789c99e 100644 --- a/diffsl/src/execution/data_layout.rs +++ b/diffsl/src/execution/data_layout.rs @@ -353,9 +353,9 @@ impl DataLayout { // deterministic hash from the call args (x, y, q) // — must match codegen; only hash base args, never the full Call let mut hasher = std::collections::hash_map::DefaultHasher::new(); - format!("{:?}", &call.args[0]).hash(&mut hasher); - format!("{:?}", &call.args[1]).hash(&mut hasher); - format!("{:?}", &call.args[2]).hash(&mut hasher); + format!("{:?}", call.args[0]).hash(&mut hasher); + format!("{:?}", call.args[1]).hash(&mut hasher); + format!("{:?}", call.args[2]).hash(&mut hasher); let hash_key = hasher.finish(); let info = Interp1dInfo { From ff932848336e735f8b4d1e71d5430a59305aa1d7 Mon Sep 17 00:00:00 2001 From: martinjrobins Date: Mon, 13 Jul 2026 10:28:33 +0000 Subject: [PATCH 3/3] fix: clippy --- diffsl/src/execution/llvm/codegen.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/diffsl/src/execution/llvm/codegen.rs b/diffsl/src/execution/llvm/codegen.rs index d2fbfb8..8e9e06c 100644 --- a/diffsl/src/execution/llvm/codegen.rs +++ b/diffsl/src/execution/llvm/codegen.rs @@ -3271,13 +3271,13 @@ impl<'ctx> CodeGen<'ctx> { let mut hasher = std::collections::hash_map::DefaultHasher::new(); if call.is_tangent { // tangent has doubled args: take original (x, y, q) at indices 0, 2, 4 - std::hash::Hash::hash(&format!("{:?}", &call.args[0]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[2]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[4]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[0]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[2]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[4]), &mut hasher); } else { - std::hash::Hash::hash(&format!("{:?}", &call.args[0]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[1]), &mut hasher); - std::hash::Hash::hash(&format!("{:?}", &call.args[2]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[0]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[1]), &mut hasher); + std::hash::Hash::hash(&format!("{:?}", call.args[2]), &mut hasher); } let hash_key = std::hash::Hasher::finish(&hasher); let info = self