Skip to content

Commit ad79e42

Browse files
committed
add test for memref.alloca
1 parent 5ad3d0c commit ad79e42

2 files changed

Lines changed: 37 additions & 7 deletions

File tree

enzyme/Enzyme/MLIR/Implementations/MemRefAutoDiffOpInterfaceImpl.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ class MemRefAutoDiffTypeInterface
349349
if (!eltIface || eltIface.isMutable())
350350
return failure();
351351
Value zero = eltIface.createNullValue(builder, loc);
352-
352+
353353
if (MT.getRank() == 0) {
354354
memref::StoreOp::create(builder, loc, zero, val, ValueRange{});
355355
return success();
@@ -362,15 +362,16 @@ class MemRefAutoDiffTypeInterface
362362
SmallVector<Value> steps(MT.getRank(), c1);
363363
SmallVector<Value> ubs;
364364
for (auto [i, d] : llvm::enumerate(MT.getShape())) {
365-
ubs.push_back(d == ShapedType::kDynamic
366-
? memref::DimOp::create(builder, loc, val, i).getResult()
367-
: arith::ConstantIndexOp::create(builder, loc, d).getResult());
365+
ubs.push_back(
366+
d == ShapedType::kDynamic
367+
? memref::DimOp::create(builder, loc, val, i).getResult()
368+
: arith::ConstantIndexOp::create(builder, loc, d).getResult());
368369
}
369370

370371
scf::ParallelOp::create(builder, loc, lbs, ubs, steps,
371-
[&](OpBuilder &b, Location l, ValueRange ivs) {
372-
memref::StoreOp::create(b, l, zero, val, ivs);
373-
});
372+
[&](OpBuilder &b, Location l, ValueRange ivs) {
373+
memref::StoreOp::create(b, l, zero, val, ivs);
374+
});
374375
return success();
375376
}
376377

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %eopt --split-input-file --enzyme --canonicalize --remove-unnecessary-enzyme-ops --enzyme-simplify-math %s | FileCheck %s
2+
3+
func.func @foo_flat(%x : f64) -> f64 {
4+
%buf = memref.alloca() : memref<f64>
5+
memref.store %x, %buf[] : memref<f64>
6+
%y = memref.load %buf[] : memref<f64>
7+
return %y : f64
8+
}
9+
10+
func.func @dfoo_flat(%x: f64, %dout : f64) -> f64 {
11+
%dx = enzyme.autodiff @foo_flat(%x, %dout) {
12+
activity = [#enzyme<activity enzyme_active>],
13+
ret_activity = [#enzyme<activity enzyme_activenoneed>]
14+
} : (f64, f64) -> (f64)
15+
return %dx : f64
16+
}
17+
18+
// CHECK-LABEL: func.func private @diffefoo_flat(
19+
// CHECK-SAME: %[[X:[^,]+]]: f64,
20+
// CHECK-SAME: %[[DOUT:[^)]+]]: f64) -> f64 {
21+
// A shadow memref.alloca must be created and zero-initialized so the
22+
// reverse-mode adjoint can accumulate gradients into it.
23+
// CHECK-DAG: %[[ZERO:.*]] = arith.constant 0.000000e+00 : f64
24+
// CHECK-DAG: %[[DBUF:.*]] = memref.alloca() : memref<f64>
25+
// CHECK: memref.store %[[ZERO]], %[[DBUF]][] : memref<f64>
26+
// No leftover placeholders should survive the differentiation.
27+
// CHECK-NOT: enzyme.placeholder
28+
// The function ultimately returns the gradient w.r.t. x (= dout).
29+
// CHECK: return %{{.*}} : f64

0 commit comments

Comments
 (0)