Skip to content

Commit 5ad3d0c

Browse files
committed
using scf.parallel+memref.store to zero out a memref
1 parent c91370d commit 5ad3d0c

1 file changed

Lines changed: 25 additions & 10 deletions

File tree

enzyme/Enzyme/MLIR/Implementations/MemRefAutoDiffOpInterfaceImpl.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@
1818
#include "Interfaces/GradientUtilsReverse.h"
1919

2020
#include "mlir/Dialect/MemRef/IR/MemRef.h"
21+
#include "mlir/Dialect/SCF/IR/SCF.h"
2122
#include "mlir/IR/DialectRegistry.h"
2223
#include "mlir/Support/LogicalResult.h"
2324

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-
2825
using namespace mlir;
2926
using namespace mlir::enzyme;
3027

@@ -348,14 +345,32 @@ class MemRefAutoDiffTypeInterface
348345
LogicalResult zeroInPlace(Type self, OpBuilder &builder, Location loc,
349346
Value val) const {
350347
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())
357350
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();
358356
}
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+
});
359374
return success();
360375
}
361376

0 commit comments

Comments
 (0)