23#ifndef ENZYME_CALL_MARKERS_H
24#define ENZYME_CALL_MARKERS_H
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/StringSwitch.h"
78 auto activity = [](
DIFFE_TYPE a,
unsigned extra = 0) {
81 auto flag = [](
unsigned extra = 0) {
84 auto flagWithActivity = [](
DIFFE_TYPE a,
unsigned extra) {
88 return llvm::StringSwitch<std::optional<MarkerInfo>>(name)
98 .Case(
"enzyme_interleave",
101 .Case(
"enzyme_not_overwritten",
104 .Case(
"enzyme_noret", flag())
105 .Case(
"enzyme_nofree", flag())
106 .Case(
"enzyme_runtime_activity", flag())
107 .Case(
"enzyme_strong_zero", flag())
108 .Case(
"enzyme_primal_return", flag())
109 .Case(
"enzyme_const_return", flag())
110 .Case(
"enzyme_active_return", flag())
111 .Case(
"enzyme_dup_return", flag())
113 .Case(
"enzyme_byref", flag(1))
114 .Case(
"enzyme_allocated", flag(1))
115 .Case(
"enzyme_tape", flag(1))
116 .Case(
"enzyme_width", flag(1))
117 .Case(
"enzyme_interface", flag(1))
118 .Case(
"enzyme_active_rand_var", flag(1))
124 .Default(std::nullopt);
146template <
typename MarkerAtFn>
148 MarkerAtFn markerAt) {
149 for (
unsigned i = first; i < count; ++i) {
150 std::optional<llvm::StringRef> name = markerAt(i);
151 if (name && *name ==
"enzyme_interleave")
152 return {i, i + 1,
true};
154 return {count, 0,
false};
DIFFE_TYPE
Potential differentiable argument classifications.
MarkerRole
What a marker does to the call it appears in.
@ CallFlag
Configures the call rather than an argument: nothing follows it that is an argument.
@ Modifier
Changes how the argument that follows is read without naming an activity.
@ Interleave
Says the shadows come after all of the primals rather than beside each one, in the same order.
@ Activity
Names the activity of the argument that follows it.
bool markerActivityTakesShadow(DIFFE_TYPE a)
Whether an activity is one that a shadow goes with.
InterleaveSplit findEnzymeInterleave(unsigned first, unsigned count, MarkerAtFn markerAt)
Find enzyme_interleave among the operands, which has to be done before walking them: it says where th...
std::optional< MarkerInfo > lookupEnzymeMarker(llvm::StringRef name)
The one description of the __enzyme_* argument markers.
Where the primals stop and the shadows start.
unsigned shadowStart
The first shadow operand, meaningful only when interleaved.
unsigned primalEnd
One past the last operand that can be a primal.
std::optional< DIFFE_TYPE > activity
Set where the role is Activity, and for the few call flags that also fix the activity of what they na...
unsigned extraOperands
Operands the marker itself takes, before whatever follows it.