Enzyme main
Loading...
Searching...
No Matches
GPUAutoDiffOpInterfaceImpl.cpp
Go to the documentation of this file.
1//===- GPUAutoDiffOpInterfaceImpl.cpp - Interface external model ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the external model implementation of the automatic
10// differentiation op interfaces for the upstream MLIR GPU dialect.
11//
12//===----------------------------------------------------------------------===//
13
17
18#include "mlir/Dialect/GPU/IR/GPUDialect.h"
19#include "mlir/Dialect/MemRef/IR/MemRef.h"
20#include "mlir/IR/DialectRegistry.h"
21#include "mlir/Support/LogicalResult.h"
22
23using namespace mlir;
24using namespace mlir::enzyme;
25
26namespace {
27struct GPUAllocOpInterface
28 : public MultidimensionalAllocInterface::ExternalModel<GPUAllocOpInterface,
29 gpu::AllocOp> {
30 Value allocate(Operation *op, OpBuilder &rewriter, Location loc, Type newType,
31 ValueRange dynamicDims) const {
32 return gpu::AllocOp::create(rewriter, loc, cast<MemRefType>(newType),
33 /*asyncDependencies=*/ValueRange{}, dynamicDims,
34 /*symbolOperands=*/ValueRange{})
35 .getMemref();
36 }
37
38 void deallocate(Operation *op, OpBuilder &rewriter, Location loc,
39 Value val) const {
40 gpu::DeallocOp::create(rewriter, loc, /*resultTypes=*/TypeRange(),
41 /*asyncDependencies=*/ValueRange(), val);
42 }
43
44 bool isDeallocation(Operation *op, Operation *user) const {
45 return isa<gpu::DeallocOp>(user);
46 }
47};
48
49struct GPULaunchOpInterface
50 : public AutoDiffOpInterface::ExternalModel<GPULaunchOpInterface,
51 gpu::LaunchOp> {
52 LogicalResult createForwardModeTangent(Operation *op, OpBuilder &builder,
53 MGradientUtils *gutils) const {
54 // The launch operands (async dependencies, grid/block/cluster sizes,
55 // dynamic shared memory) and the optional token result carry no
56 // tangents; the tangent of a launch is the launch itself with a
57 // differentiated body.
58 for (auto &region : op->getRegions())
59 for (auto &block : region)
60 for (Operation &o : block)
61 if (failed(gutils->visitChild(&o)))
62 return failure();
63 return success();
64 }
65};
66} // namespace
67
69 DialectRegistry &registry) {
70 registry.addExtension(+[](MLIRContext *context, gpu::GPUDialect *) {
71 gpu::AllocOp::attachInterface<GPUAllocOpInterface>(*context);
72 gpu::LaunchOp::attachInterface<GPULaunchOpInterface>(*context);
74 });
75}
LogicalResult visitChild(Operation *op)
void registerGPUDialectAutoDiffInterface(DialectRegistry &registry)
void registerAutoDiffUsingRegionTerminatorInterface(MLIRContext &context)