21 auto [s_in, s_out, input] = arg->
projs<3>();
22 auto callee = c->as<
App>();
23 auto [T, r] = callee->
args<2>();
24 w.log().d(
"broadcast: input = {}: {}, T = {}, r = {}, s_in = {}, s_out = {}", input, input->type(), T, r, s_in,
27 if (s_in == s_out || input->type() == type)
return input;
37 auto [Tr, s_in, s_out] = c->as<
App>()->uncurry_args<3>();
38 if (s_in == s_out || arg->
type() == type)
return arg;
45 auto [Trr, s_in, s_out] = c->as<
App>()->uncurry_args<3>();
46 if (s_in == s_out || arg->
type() == type)
return arg;
51 auto callee = c->as<
App>()->decurry();
53 if (!perm)
return nullptr;
54 auto r = perm->size();
55 if (std::ranges::equal(*perm, std::views::iota(
u64(0),
u64(r))))
return arg;
58 if (!app)
return nullptr;
60 if (!inner || inner->size() != r)
return nullptr;
64 auto comp =
DefVec(r, [&](
size_t j) {
return w.lit_idx(r, (*perm)[(*inner)[j]]); });
65 return w.app(w.app(w.app(callee->callee(), w.tuple(comp)), app->decurry()->arg()), app->arg());
70 auto [Tr, s_in, params] = c->as<
App>()->uncurry_args<3>();
71 auto [start, step, s_out] = params->projs<3>();
72 if (s_out != s_in)
return nullptr;
74 if (!r)
return nullptr;
75 for (
u64 d = 0; d != *r; ++d) {
78 if (!st || *st != 0 || !sp || *sp != 1)
return nullptr;
87 auto [Tr, s_in, params] = c->as<
App>()->uncurry_args<3>();
88 auto [mode, lo, hi] = params->projs<3>();
90 if (!r)
return nullptr;
91 for (
u64 d = 0; d != *r; ++d) {
94 if (!l || *l != 0 || !h || *h != 0)
return nullptr;
96 return arg->
proj(2, 0);
105 auto [k, s, d] = arg->
projs<3>();
117 auto& w = arg->
world();
118 auto [r, t] = arg->
projs<2>();
120 if (!r_l || *r_l == 0)
return r;
122 if (!pr)
return w.lit_nat(*r_l - 1);
126 if (!r_src || *r_src == 0)
return r;
129 if (!r_dom || *r_dom != *r_l)
return r;
131 auto markers =
DefVec(*r_l, [&](
size_t i) {
return w.call<
affine::lit>(w.lit_nat(i + 1)); });
132 auto last = w.app(pr->map, w.tuple(markers))->proj(*r_src, *r_src - 1);
136 if (!v || *v < 1 || *v > *r_l)
return r;
137 return w.lit_nat(*v - 1);
141constexpr std::array
Vec_widths = {1_u64, 4_u64, 8_u64, 16_u64};
145 auto& w = arg->
world();
146 auto n = w.driver().arg_nat(
"tensor",
"vec-width");
149 w.log().w(
"ignoring `-X tensor:vec-width={}`: not one of {}", *n, fe::Join(
Vec_widths,
", "));
152 return w.lit_nat(*n);
157 auto& w = c->world();
159 if (!r)
return nullptr;
160 if (*r == 0)
return w.tuple();
162 auto arr = arg->
type()->isa<
Arr>();
163 if (!arr)
return nullptr;
164 auto shape = arr->shape();
165 auto rank =
shape.rank();
166 if (!rank || *rank < *r)
return nullptr;
167 return *
shape.take(*r);
auto args(Projector auto f) const noexcept
A (possibly paramterized) Array.
static auto isa(const Def *def)
const Def * proj(nat_t a, nat_t i) const
Similar to World::extract while assuming an arity of a, but also works on Sigmas and Arrays.
World & world() const noexcept
auto projs(Projector auto f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
const Def * arity() const
Number of elements available to Extract / Insert (may be dynamic).
static std::optional< T > isa(const Def *def)
A dependent function type.
const Def * codom() const
const Def * normalize_if_static(const Def *, const Def *, const Def *arg)
const Def * normalize_slice(const Def *, const Def *c, const Def *arg)
const Def * normalize_transpose(const Def *, const Def *c, const Def *arg)
const Def * normalize_pad(const Def *, const Def *c, const Def *arg)
const Def * normalize_broadcast_in_dim(const Def *, const Def *, const Def *)
std::optional< PureRead > is_pure_read(const Def *value)
If value is a pure re-indexed read — a copy-combiner map_reduce without reduction loops that writes i...
const Def * normalize_concat(const Def *, const Def *, const Def *)
const Def * normalize_fastest_axis(const Def *, const Def *, const Def *arg)
std::optional< fe::Vector< u64 > > transpose_perm(const App *app)
The permutation of a transpose app, if it is literal.
std::optional< fe::Vector< u64 > > lit_perm(const Def *perm)
perm as literals, if it is literal.
const Def * normalize_shape(const Def *, const Def *c, const Def *arg)
constexpr std::array Vec_widths
The vector widths -X tensor:vec-width accepts.
const Def * normalize_flip(const Def *, const Def *, const Def *)
const Def * normalize_broadcast(const Def *type, const Def *c, const Def *arg)
const Def * normalize_vec_width(const Def *, const Def *, const Def *arg)
const Def * normalize_repeat(const Def *type, const Def *c, const Def *arg)
const Def * normalize_reshape(const Def *type, const Def *c, const Def *arg)
fe::Vector< const Def * > DefVec
#define MIM_tensor_NORMALIZER_IMPL