Enzyme main
Loading...
Searching...
No Matches
Ops.h
Go to the documentation of this file.
1//===- EnzymeOps.h - Enzyme dialect ops -------------------------*- C++ -*-===//
2//
3// This file is licensed 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#ifndef ENZYMEOPS_H
10#define ENZYMEOPS_H
11
12#include <type_traits>
13
14#include "mlir/Dialect/Arith/IR/Arith.h"
15#include "mlir/IR/BuiltinTypes.h"
16#include "mlir/IR/Dialect.h"
17#include "mlir/IR/OpDefinition.h"
18#include "mlir/IR/SymbolTable.h"
19#include "mlir/Interfaces/ControlFlowInterfaces.h"
20#include "mlir/Interfaces/MemorySlotInterfaces.h"
21#include "mlir/Interfaces/SideEffectInterfaces.h"
22#include "mlir/Interfaces/ViewLikeInterface.h"
23
24#include "mlir/Bytecode/BytecodeOpInterface.h"
25
26#include "Dialect/EnzymeAttributeInterfaces.h.inc"
27#include "Dialect/EnzymeEnums.h.inc"
28
29#define GET_ATTRDEF_CLASSES
30#include "Dialect/EnzymeAttributes.h.inc"
31
32#define GET_TYPEDEF_CLASSES
33#include "Dialect/EnzymeOpsTypes.h.inc"
34
35// forward declare Enzyme op definitions
36#include "Dialect/EnzymeOps.h.inc"
37
38namespace mlir {
39namespace enzyme {
40namespace detail {
41
42// For any differentiation op, we either return input primal values or selective
43// derivative values. When `filterGrad` is true, `includeShadows` controls
44// whether input shadow arguments (activity `enzyme_dup` / `enzyme_dupnoneed`)
45// are collected, while `includeDifferentialReturns` controls whether
46// reverse-mode output shadows (`enzyme_active` / `enzyme_activenoneed`) are
47// collected.
48template <typename SourceOp, bool filterGrad, bool includeShadows = true,
49 bool includeDifferentialReturns = true>
50llvm::SmallVector<mlir::Value, 2> filterGradInputs(SourceOp uop) {
51 llvm::SmallVector<mlir::Value, 2> outs;
52 size_t in_idx = 0;
53
54 for (auto act : uop.getActivity()) {
55 auto iattr = cast<ActivityAttr>(act);
56 auto act_val = iattr.getValue();
57
58 if constexpr (!filterGrad) {
59 outs.push_back(uop.getInputs()[in_idx]);
60 }
61
62 ++in_idx;
63
64 if (act_val == Activity::enzyme_dup ||
65 act_val == Activity::enzyme_dupnoneed) {
66
67 if constexpr (filterGrad && includeShadows) {
68 outs.push_back(uop.getInputs()[in_idx]);
69 }
70
71 ++in_idx;
72 }
73 }
74
75 // For reverse mode AD, add derivative values corresponding to active outputs
76 // clang-format off
77 if constexpr ((std::is_same_v<SourceOp, AutoDiffOp> ||
78 std::is_same_v<SourceOp, AutoDiffRegionOp>) &&
79 filterGrad && includeDifferentialReturns) {
80 // clang-format on
81 if (in_idx != uop.getInputs().size()) {
82 for (auto act : uop.getRetActivity()) {
83 auto iattr = cast<ActivityAttr>(act);
84 auto act_val = iattr.getValue();
85
86 if (act_val == Activity::enzyme_active ||
87 act_val == Activity::enzyme_activenoneed) {
88 outs.push_back(uop.getInputs()[in_idx]);
89 in_idx++;
90 }
91 }
92 }
93 }
94
95 return outs;
96}
97
98} // namespace detail
99} // namespace enzyme
100} // namespace mlir
101
102#define GET_OP_CLASSES
103#include "Dialect/EnzymeOps.h.inc"
104
105// #include "Dialect/EnzymeTypes.h.inc"
106
107#endif // ENZYMEOPS_H
llvm::SmallVector< mlir::Value, 2 > filterGradInputs(SourceOp uop)
Definition Ops.h:50