|
18 | 18 | #include "Interfaces/GradientUtilsReverse.h" |
19 | 19 |
|
20 | 20 | #include "mlir/Dialect/MemRef/IR/MemRef.h" |
| 21 | +#include "mlir/Dialect/SCF/IR/SCF.h" |
21 | 22 | #include "mlir/IR/DialectRegistry.h" |
22 | 23 | #include "mlir/Support/LogicalResult.h" |
23 | 24 |
|
24 | | -// TODO: We need a way to zero out a memref (which linalg.fill does), but |
25 | | -// ideally we wouldn't depend on the linalg dialect. |
26 | | -#include "mlir/Dialect/Linalg/IR/Linalg.h" |
27 | | - |
28 | 25 | using namespace mlir; |
29 | 26 | using namespace mlir::enzyme; |
30 | 27 |
|
@@ -348,14 +345,32 @@ class MemRefAutoDiffTypeInterface |
348 | 345 | LogicalResult zeroInPlace(Type self, OpBuilder &builder, Location loc, |
349 | 346 | Value val) const { |
350 | 347 | auto MT = cast<MemRefType>(self); |
351 | | - if (auto iface = dyn_cast<AutoDiffTypeInterface>(MT.getElementType())) { |
352 | | - if (!iface.isMutable()) { |
353 | | - Value zero = iface.createNullValue(builder, loc); |
354 | | - linalg::FillOp::create(builder, loc, zero, val); |
355 | | - } |
356 | | - } else { |
| 348 | + auto eltIface = dyn_cast<AutoDiffTypeInterface>(MT.getElementType()); |
| 349 | + if (!eltIface || eltIface.isMutable()) |
357 | 350 | return failure(); |
| 351 | + Value zero = eltIface.createNullValue(builder, loc); |
| 352 | + |
| 353 | + if (MT.getRank() == 0) { |
| 354 | + memref::StoreOp::create(builder, loc, zero, val, ValueRange{}); |
| 355 | + return success(); |
358 | 356 | } |
| 357 | + |
| 358 | + Value c0 = arith::ConstantIndexOp::create(builder, loc, 0); |
| 359 | + Value c1 = arith::ConstantIndexOp::create(builder, loc, 1); |
| 360 | + |
| 361 | + SmallVector<Value> lbs(MT.getRank(), c0); |
| 362 | + SmallVector<Value> steps(MT.getRank(), c1); |
| 363 | + SmallVector<Value> ubs; |
| 364 | + 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()); |
| 368 | + } |
| 369 | + |
| 370 | + 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 | + }); |
359 | 374 | return success(); |
360 | 375 | } |
361 | 376 |
|
|
0 commit comments