1#ifndef HALIDE_GENERATOR_H_
2#define HALIDE_GENERATOR_H_
270#include <type_traits>
280#if !(__cplusplus >= 201703L || _MSVC_LANG >= 201703L)
281#error "Halide requires C++17 or later; please upgrade your compiler."
298 for (
const auto &key_value : enum_map) {
299 if (t == key_value.second) {
300 return key_value.first;
303 user_error <<
"Enumeration value not found.\n";
309 auto it = enum_map.find(s);
310 user_assert(it != enum_map.end()) <<
"Enumeration value not found: " << s <<
"\n";
379template<
bool B,
typename T>
385template<
typename First,
typename... Rest>
386struct select_type : std::conditional<First::value, typename First::type, typename select_type<Rest...>::type> {};
388template<
typename First>
390 using type =
typename std::conditional<First::value, typename First::type, void>::type;
400 const std::string &
name()
const {
412#define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE) \
413 virtual void set(const TYPE &new_value) = 0;
431#undef HALIDE_GENERATOR_PARAM_TYPED_SETTER
434 void set(
const std::string &new_value) {
437 void set(
const char *new_value) {
472 const std::string name_;
489template<
typename FROM,
typename TO>
491 template<typename TO2 = TO, typename std::enable_if<!std::is_same<TO2, bool>::value>::type * =
nullptr>
492 static TO2
value(
const FROM &from) {
493 return static_cast<TO2
>(from);
496 template<typename TO2 = TO, typename std::enable_if<std::is_same<TO2, bool>::value>::type * =
nullptr>
497 static TO2
value(
const FROM &from) {
517 return this->
value();
524#define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE) \
525 void set(const TYPE &new_value) override { \
526 typed_setter_impl<TYPE>(new_value, #TYPE); \
545#undef HALIDE_GENERATOR_PARAM_TYPED_SETTER
548 void set(
const std::string &new_value) {
564 template<
typename FROM,
typename std::enable_if<
565 !std::is_convertible<FROM, T>::value>
::type * =
nullptr>
571 template<
typename FROM,
typename std::enable_if<
572 std::is_same<FROM, T>::value>
::type * =
nullptr>
579 template<
typename FROM,
typename std::enable_if<
580 !std::is_same<FROM, T>::value &&
581 std::is_convertible<FROM, T>::value &&
582 std::is_convertible<T, FROM>::value>
::type * =
nullptr>
587 if (value2 !=
value) {
594 template<
typename FROM,
typename std::enable_if<
595 !std::is_same<FROM, T>::value &&
596 std::is_convertible<FROM, T>::value &&
597 !std::is_convertible<T, FROM>::value>
::type * =
nullptr>
621 return this->
value().to_string();
625 std::ostringstream oss;
626 oss << v <<
".to_string()";
647 bool try_set(
const std::string &key,
const std::string &
value);
679 if (new_value_string ==
"root") {
681 }
else if (new_value_string ==
"inlined") {
684 user_error <<
"Unable to parse " << this->
name() <<
": " << new_value_string;
701 return "LoopLevel::inlined()";
703 return "LoopLevel::root()";
712 return std::string();
729 const T &min = std::numeric_limits<T>::lowest(),
730 const T &max = std::numeric_limits<T>::max())
737 user_assert(new_value >= min && new_value <= max) <<
"Value out of range: " << new_value;
742 std::istringstream iss(new_value_string);
747 if (
sizeof(T) ==
sizeof(
char) && !std::is_same<T, bool>::value) {
754 user_assert(!iss.fail() && iss.get() == EOF) <<
"Unable to parse: " << new_value_string;
759 std::ostringstream oss;
760 oss << this->
value();
761 if (std::is_same<T, float>::value) {
764 if (oss.str().find(
'.') == std::string::npos) {
773 std::ostringstream oss;
774 oss <<
"std::to_string(" << v <<
")";
779 std::ostringstream oss;
780 if (std::is_same<T, float>::value) {
782 }
else if (std::is_same<T, double>::value) {
784 }
else if (std::is_integral<T>::value) {
785 if (std::is_unsigned<T>::value) {
788 oss <<
"int" << (
sizeof(T) * 8) <<
"_t";
809 if (new_value_string ==
"true" || new_value_string ==
"True") {
811 }
else if (new_value_string ==
"false" || new_value_string ==
"False") {
814 user_assert(
false) <<
"Unable to parse bool: " << new_value_string;
820 return this->
value() ?
"true" :
"false";
824 std::ostringstream oss;
825 oss <<
"std::string((" << v <<
") ? \"true\" : \"false\")";
844 template<typename T2 = T, typename std::enable_if<!std::is_same<T2, Type>::value>
::type * =
nullptr>
850 auto it = enum_map.find(new_value_string);
851 user_assert(it != enum_map.end()) <<
"Enumeration value not found: " << new_value_string;
856 return "Enum_" + this->
name() +
"_map().at(" + v +
")";
860 return "Enum_" + this->
name();
868 std::ostringstream oss;
869 oss <<
"enum class Enum_" << this->
name() <<
" {\n";
870 for (
auto key_value : enum_map) {
871 oss <<
" " << key_value.first <<
",\n";
878 oss <<
"inline HALIDE_NO_USER_CODE_INLINE const std::map<Enum_" << this->
name() <<
", std::string>& Enum_" << this->
name() <<
"_map() {\n";
879 oss <<
" static const std::map<Enum_" << this->
name() <<
", std::string> m = {\n";
880 for (
auto key_value : enum_map) {
881 oss <<
" { Enum_" << this->
name() <<
"::" << key_value.first <<
", \"" << key_value.first <<
"\"},\n";
884 oss <<
" return m;\n";
890 const std::map<std::string, T> enum_map;
901 return "Halide::Internal::halide_type_to_enum_string(" + v +
")";
924 this->
set(new_value_string);
928 return "\"" + this->
value() +
"\"";
936 return "std::string";
991 template<typename T2 = T, typename std::enable_if<!std::is_same<T2, std::string>::value>::type * =
nullptr>
993 :
Internal::GeneratorParamImplBase<T>(name, value) {
1000 GeneratorParam(
const std::string &name,
const T &value,
const std::map<std::string, T> &enum_map)
1001 :
Internal::GeneratorParamImplBase<T>(name, value, enum_map) {
1005 :
Internal::GeneratorParamImplBase<T>(name, value) {
1012template<
typename Other,
typename T>
1016template<
typename Other,
typename T>
1025template<
typename Other,
typename T>
1029template<
typename Other,
typename T>
1038template<
typename Other,
typename T>
1042template<
typename Other,
typename T>
1051template<
typename Other,
typename T>
1055template<
typename Other,
typename T>
1064template<
typename Other,
typename T>
1068template<
typename Other,
typename T>
1077template<
typename Other,
typename T>
1081template<
typename Other,
typename T>
1090template<
typename Other,
typename T>
1094template<
typename Other,
typename T>
1103template<
typename Other,
typename T>
1107template<
typename Other,
typename T>
1116template<
typename Other,
typename T>
1120template<
typename Other,
typename T>
1129template<
typename Other,
typename T>
1133template<
typename Other,
typename T>
1142template<
typename Other,
typename T>
1146template<
typename Other,
typename T>
1155template<
typename Other,
typename T>
1159template<
typename Other,
typename T>
1165 return (T)a && (T)b;
1172template<
typename Other,
typename T>
1176template<
typename Other,
typename T>
1182 return (T)a || (T)b;
1196template<
typename Other,
typename T>
1198 return min(a, (T)b);
1200template<
typename Other,
typename T>
1202 return min((T)a, b);
1205template<
typename Other,
typename T>
1207 return max(a, (T)b);
1209template<
typename Other,
typename T>
1211 return max((T)a, b);
1220template<
typename Other,
typename T>
1224template<
typename Other,
typename T>
1233template<
typename Other,
typename T>
1237template<
typename Other,
typename T>
1251template<
typename T2>
1252class GeneratorInput_Buffer;
1263template<typename T = void, int Dims = Buffer<>::AnyDims>
1266 template<
typename T2>
1268 template<
typename T2,
int D2>
1282 template<
typename T2,
int D2>
1298 template<
typename T2,
int D2>
1300 : parameter_(parameter_from_buffer(b)) {
1303 template<
typename T2>
1305 return {t.parameter_};
1308 template<
typename T2>
1310 std::vector<Parameter> r;
1311 r.reserve(v.size());
1312 for (
const auto &s : v) {
1313 r.push_back(s.parameter_);
1319class AbstractGenerator;
1334 template<
typename... Args>
1336 return f.realize(std::forward<Args>(args)...,
get_target());
1339 template<
typename Dst>
1357template<
typename T =
void>
1359 template<
typename T2>
1369 const std::shared_ptr<AbstractGenerator> &gen) {
1370 std::vector<StubOutputBuffer<T>> result;
1371 for (
const Func &
f : v) {
1372 result.push_back(StubOutputBuffer<T>(
f, gen));
1391 template<
typename T2>
1472 const std::string &
name,
1474 const std::vector<Type> &types,
1507 template<
typename ElemType>
1517 template<
typename T>
1541 const std::string &
name,
1543 const std::vector<Type> &t,
1580template<
typename T,
typename ValueType>
1583 using TBase =
typename std::remove_all_extents<T>::type;
1586 return std::is_array<T>::value;
1589 template<
typename T2 = T,
typename std::enable_if<
1591 !std::is_array<T2>::value>::type * =
nullptr>
1596 template<
typename T2 = T,
typename std::enable_if<
1598 std::is_array<T2>::value && std::rank<T2>::value == 1 && (std::extent<T2, 0>::value > 0)>::type * =
nullptr>
1603 template<
typename T2 = T,
typename std::enable_if<
1605 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>::type * =
nullptr>
1611 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1617 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1623 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1624 const ValueType &
at(
size_t i)
const {
1629 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1630 typename std::vector<ValueType>::const_iterator
begin()
const {
1635 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1636 typename std::vector<ValueType>::const_iterator
end()
const {
1650#define HALIDE_FORWARD_METHOD(Class, Method) \
1651 template<typename... Args> \
1652 inline auto Method(Args &&...args) -> typename std::remove_reference<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))>::type { \
1653 return this->template as<Class>().Method(std::forward<Args>(args)...); \
1656#define HALIDE_FORWARD_METHOD_CONST(Class, Method) \
1657 template<typename... Args> \
1658 inline auto Method(Args &&...args) const -> \
1659 typename std::remove_reference<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))>::type { \
1660 this->check_gio_access(); \
1661 return this->template as<Class>().Method(std::forward<Args>(args)...); \
1672 friend class ::Halide::Func;
1673 friend class ::Halide::Stage;
1676 if (TBase::has_static_halide_type) {
1677 return "Halide::Internal::StubInputBuffer<" +
1681 return "Halide::Internal::StubInputBuffer<>";
1685 template<
typename T2>
1693 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
1694 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
1699 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Input<Buffer<T>> if T is void or omitted.");
1700 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Input<Buffer<T, D>> if D is -1 or omitted.");
1705 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Input<Buffer<T>> if T is void or omitted.");
1710 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
1712 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Input<Buffer<T, D>> if D is -1 or omitted.");
1715 template<
typename... Args>
1718 return Func(*
this)(std::forward<Args>(args)...);
1723 return Func(*
this)(std::move(args));
1726 template<
typename T2>
1728 user_assert(!this->
is_array()) <<
"Cannot assign an array type to a non-array type for Input " << this->
name();
1734 return this->
funcs().at(0);
1756 return Func(*this).in();
1761 return Func(*this).in(other);
1766 return Func(*this).in(others);
1771 user_assert(!this->
is_array()) <<
"Cannot convert an Input<Buffer<>[]> to an ImageParam; use an explicit subscript operator: " << this->
name();
1775 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1781 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1787 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1793 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1794 typename std::vector<ImageParam>::const_iterator
begin()
const {
1795 user_error <<
"Input<Buffer<>>::begin() is not supported.";
1799 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1800 typename std::vector<ImageParam>::const_iterator
end()
const {
1801 user_error <<
"Input<Buffer<>>::end() is not supported.";
1838 template<
typename T2>
1882 template<
typename... Args>
1885 return this->
funcs().at(0)(std::forward<Args>(args)...);
1890 return this->
funcs().at(0)(args);
1895 return this->
funcs().at(0);
1922 return Func(*this).
in(other);
1927 return Func(*this).
in(others);
1955 static_assert(std::is_same<typename std::remove_all_extents<T>::type,
Expr>::value,
"GeneratorInput_DynamicScalar is only legal to use with T=Expr for now");
1965 user_assert(!std::is_array<T>::value) <<
"Input<Expr[]> is not allowed";
1972 return this->
exprs().at(0);
2019 template<typename TBase2 = TBase, typename std::enable_if<!std::is_pointer<TBase2>::value>::type * =
nullptr>
2024 template<typename TBase2 = TBase, typename std::enable_if<std::is_pointer<TBase2>::value>::type * =
nullptr>
2026 user_assert(value == 0) <<
"Zero is the only legal default value for Inputs which are pointer types.\n";
2040 const std::string &
name)
2045 const std::string &
name,
2054 return this->
exprs().at(0);
2064 template<typename T2 = T, typename std::enable_if<std::is_pointer<T2>::value>::type * =
nullptr>
2067 user_assert(value ==
nullptr) <<
"nullptr is the only valid estimate for Input<PointerType>";
2074 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value && !std::is_pointer<T2>::value>::type * =
nullptr>
2078 if (std::is_same<T2, bool>::value) {
2086 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2090 if (std::is_same<T2, bool>::value) {
2114 if (!std::is_same<TBase, bool>::value) {
2116 if (
min_.defined()) {
2119 if (
max_.defined()) {
2137 const std::string &
name)
2142 const std::string &
name,
2155 const std::string &
name,
2168template<
typename T2,
typename =
void>
2171template<
typename T2>
2174template<typename T, typename TBase = typename std::remove_all_extents<T>::type>
2212 : Super(name, def) {
2216 : Super(array_size, name, def) {
2221 : Super(name, def,
min,
max) {
2226 : Super(array_size, name, def,
min,
max) {
2230 : Super(name, t, d) {
2243 : Super(array_size, name, t, d) {
2247 : Super(array_size, name, t) {
2253 : Super(array_size, name, d) {
2257 : Super(array_size, name) {
2265 template<typename T2, typename std::enable_if<std::is_same<T2, Func>::value>::type * =
nullptr>
2267 static_assert(std::is_same<T2, Func>::value,
"Only Func allowed here");
2271 user_assert(
funcs_.size() == 1) <<
"Use [] to access individual Funcs in Output<Func[]>";
2341#undef HALIDE_OUTPUT_FORWARD
2342#undef HALIDE_OUTPUT_FORWARD_CONST
2351 const std::string &
name,
2353 const std::vector<Type> &t,
2358 const std::vector<Type> &t,
2384 using TBase =
typename std::remove_all_extents<T>::type;
2388 return std::is_array<T>::value;
2391 template<
typename T2 = T,
typename std::enable_if<
2393 !std::is_array<T2>::value>::type * =
nullptr>
2398 template<
typename T2 = T,
typename std::enable_if<
2400 std::is_array<T2>::value && std::rank<T2>::value == 1 && (std::extent<T2, 0>::value > 0)>::type * =
nullptr>
2405 template<
typename T2 = T,
typename std::enable_if<
2407 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>::type * =
nullptr>
2413 template<
typename... Args,
typename T2 = T,
typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2419 template<typename ExprOrVar, typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2425 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2431 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2437 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2443 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2449 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2455 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2456 typename std::vector<ValueType>::const_iterator
begin()
const {
2461 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2462 typename std::vector<ValueType>::const_iterator
end()
const {
2467 template<
typename T2 = T,
typename std::enable_if<
2469 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>::type * =
nullptr>
2487 const auto &my_types = this->
gio_types();
2489 <<
"Cannot assign Func \"" << f.
name()
2490 <<
"\" to Output \"" << this->
name() <<
"\"\n"
2491 <<
"Output " << this->
name()
2492 <<
" is declared to have " << my_types.size() <<
" tuple elements"
2493 <<
" but Func " << f.
name()
2494 <<
" has " << f.
types().size() <<
" tuple elements.\n";
2495 for (
size_t i = 0; i < my_types.size(); i++) {
2497 <<
"Cannot assign Func \"" << f.
name()
2498 <<
"\" to Output \"" << this->
name() <<
"\"\n"
2499 << (my_types.size() > 1 ?
"In tuple element " + std::to_string(i) +
", " :
"")
2500 <<
"Output " << this->
name()
2501 <<
" has declared type " << my_types[i]
2502 <<
" but Func " << f.
name()
2503 <<
" has type " << f.
types().at(i) <<
"\n";
2508 <<
"Cannot assign Func \"" << f.
name()
2509 <<
"\" to Output \"" << this->
name() <<
"\"\n"
2510 <<
"Output " << this->
name()
2511 <<
" has declared dimensionality " << this->
dims()
2512 <<
" but Func " << f.
name()
2513 <<
" has dimensionality " << f.
dimensions() <<
"\n";
2526 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2527 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
2534 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Output<Buffer<T, D>> if T is void or omitted.");
2535 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2541 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Output<Buffer<T, D>> if T is void or omitted.");
2546 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2549 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2554 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2555 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
2562 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Output<Buffer<T, D>> if T is void or omitted.");
2563 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2569 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Output<Buffer<T, D>> if T is void or omitted.");
2574 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2577 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2581 if (TBase::has_static_halide_type) {
2582 return "Halide::Internal::StubOutputBuffer<" +
2586 return "Halide::Internal::StubOutputBuffer<>";
2590 template<typename T2, typename std::enable_if<!std::is_same<T2, Func>::value>::type * =
nullptr>
2602 template<
typename T2,
int D2>
2608 <<
"Cannot assign to the Output \"" << this->
name()
2609 <<
"\": the expression is not convertible to the same Buffer type and/or dimensions.\n";
2613 <<
"Output " << this->
name() <<
" should have type=" << this->
gio_type() <<
" but saw type=" <<
Type(buffer.
type()) <<
"\n";
2617 <<
"Output " << this->
name() <<
" should have dim=" << this->
dims() <<
" but saw dim=" << buffer.dimensions() <<
"\n";
2622 this->
funcs_.at(0)(_) = buffer(_);
2630 template<
typename T2>
2633 assign_from_func(stub_output_buffer.
f);
2642 assign_from_func(f);
2648 user_assert(!this->
is_array()) <<
"Cannot convert an Output<Buffer<>[]> to an ImageParam; use an explicit subscript operator: " << this->
name();
2650 return this->
funcs_.at(0).output_buffer();
2656 user_assert(!this->
is_array()) <<
"Cannot call set_estimates() on an array Output; use an explicit subscript operator: " << this->
name();
2658 this->
funcs_.at(0).set_estimates(estimates);
2662 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2669 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2700 return this->
funcs_.at(i);
2728 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2735 get_assignable_func_ref(0) = f;
2740 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2744 return get_assignable_func_ref(i);
2748 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2758 f.set_estimate(var,
min, extent);
2767 f.set_estimates(estimates);
2790template<typename T, typename TBase = typename std::remove_all_extents<T>::type>
2820 : Super(array_size, name) {
2828 : Super(name, {t}) {
2836 : Super(name, {t}, d) {
2840 : Super(name, t, d) {
2844 : Super(array_size, name, d) {
2848 : Super(array_size, name, {t}) {
2851 explicit GeneratorOutput(
size_t array_size,
const std::string &name,
const std::vector<Type> &t)
2852 : Super(array_size, name, t) {
2856 : Super(array_size, name, {t}, d) {
2859 explicit GeneratorOutput(
size_t array_size,
const std::string &name,
const std::vector<Type> &t,
int d)
2860 : Super(array_size, name, t, d) {
2866 template<
typename T2,
int D2>
2868 Super::operator=(buffer);
2872 template<
typename T2>
2874 Super::operator=(stub_output_buffer);
2879 Super::operator=(f);
2888 std::istringstream iss(value);
2891 user_assert(!iss.fail() && iss.get() == EOF) <<
"Unable to parse: " << value;
2909 if (!error_msg.empty()) {
2912 set_from_string_impl<T>(new_value_string);
2917 return std::string();
2922 return std::string();
2927 return std::string();
2937 static std::unique_ptr<Internal::GeneratorParamBase> make(
2939 const std::string &generator_name,
2940 const std::string &gpname,
2944 std::string error_msg = defined ?
"Cannot set the GeneratorParam " + gpname +
" for " + generator_name +
" because the value is explicitly specified in the C++ source." :
"";
2945 return std::unique_ptr<GeneratorParam_Synthetic<T>>(
2946 new GeneratorParam_Synthetic<T>(gpname, gio, which, error_msg));
2953 template<typename T2 = T, typename std::enable_if<std::is_same<T2, ::Halide::Type>::value>::type * =
nullptr>
2954 void set_from_string_impl(
const std::string &new_value_string) {
2956 gio.types_ = parse_halide_type_list(new_value_string);
2959 template<typename T2 = T, typename std::enable_if<std::is_integral<T2>::value>::type * =
nullptr>
2960 void set_from_string_impl(
const std::string &new_value_string) {
2961 if (which == SyntheticParamType::Dim) {
2962 gio.dims_ = parse_scalar<T2>(new_value_string);
2963 }
else if (which == SyntheticParamType::ArraySize) {
2964 gio.array_size_ = parse_scalar<T2>(new_value_string);
2972 const std::string error_msg;
3030 return autoscheduler_params_;
3038 template<
typename T>
3040 return T::create(*
this);
3042 template<
typename T,
typename... Args>
3043 std::unique_ptr<T>
apply(
const Args &...args)
const {
3078 template<
typename T>
3085 template<
typename T>
3087 template<
typename T = void,
int D = -1>
3089 template<
typename T>
3107template<
typename... Args>
3113template<
typename T,
typename... Args>
3124 std::set<std::string> names;
3127 std::vector<Internal::GeneratorParamBase *> filter_generator_params;
3130 std::vector<Internal::GeneratorInputBase *> filter_inputs;
3133 std::vector<Internal::GeneratorOutputBase *> filter_outputs;
3138 std::vector<std::unique_ptr<Internal::GeneratorParamBase>> owned_synthetic_params;
3141 std::vector<std::unique_ptr<Internal::GIOBase>> owned_extras;
3149 return filter_generator_params;
3151 const std::vector<Internal::GeneratorInputBase *> &
inputs()
const {
3152 return filter_inputs;
3154 const std::vector<Internal::GeneratorOutputBase *> &
outputs()
const {
3155 return filter_outputs;
3171 template<
typename data_t>
3173 return get_target().natural_vector_size<data_t>();
3186 template<
typename... Args>
3191 <<
"Expected exactly " << pi.
inputs().size()
3192 <<
" inputs but got " <<
sizeof...(args) <<
"\n";
3193 set_inputs_vector(build_inputs(std::forward_as_tuple<const Args &...>(args...), std::make_index_sequence<
sizeof...(Args)>{}));
3197 this->check_scheduled(
"realize");
3203 template<
typename... Args,
typename std::enable_if<
NoRealizations<Args...>::value>::type * =
nullptr>
3205 this->check_scheduled(
"realize");
3210 this->check_scheduled(
"realize");
3223 <<
"Cannot add " << param_type <<
" with name " <<
name
3224 <<
". It is already taken by another input or output parameter.";
3225 param_info_ptr->names.insert(
name);
3230 template<
typename T,
3231 typename std::enable_if<std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3236 p->generator =
this;
3237 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3238 param_info_ptr->filter_inputs.push_back(p);
3243 template<
typename T,
3244 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3246 static_assert(!T::has_static_halide_type,
"You can only call this version of add_input() for a Buffer<T, D> where T is void or omitted .");
3247 static_assert(!T::has_static_dimensions,
"You can only call this version of add_input() for a Buffer<T, D> where D is -1 or omitted.");
3251 p->generator =
this;
3252 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3253 param_info_ptr->filter_inputs.push_back(p);
3258 template<
typename T,
3259 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3261 static_assert(T::has_static_halide_type,
"You can only call this version of add_input() for a Buffer<T, D> where T is not void.");
3262 static_assert(!T::has_static_dimensions,
"You can only call this version of add_input() for a Buffer<T, D> where D is -1 or omitted.");
3266 p->generator =
this;
3267 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3268 param_info_ptr->filter_inputs.push_back(p);
3273 template<
typename T,
3274 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3276 static_assert(T::has_static_halide_type,
"You can only call this version of add_input() for a Buffer<T, D> where T is not void.");
3277 static_assert(T::has_static_dimensions,
"You can only call this version of add_input() for a Buffer<T, D> where D is not -1.");
3281 p->generator =
this;
3282 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3283 param_info_ptr->filter_inputs.push_back(p);
3287 template<
typename T,
3288 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3293 p->generator =
this;
3294 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3295 param_info_ptr->filter_inputs.push_back(p);
3299 template<
typename T,
3300 typename std::enable_if<std::is_same<T, Expr>::value>::type * =
nullptr>
3305 p->generator =
this;
3307 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3308 param_info_ptr->filter_inputs.push_back(p);
3313 template<
typename T,
3314 typename std::enable_if<std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3319 p->generator =
this;
3320 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3321 param_info_ptr->filter_outputs.push_back(p);
3325 template<
typename T,
3326 typename std::enable_if<std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3332 template<
typename T,
3333 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3335 static_assert(!T::has_static_halide_type,
"You can only call this version of add_output() for a Buffer<T, D> where T is void or omitted .");
3336 static_assert(!T::has_static_dimensions,
"You can only call this version of add_output() for a Buffer<T, D> where D is -1 or omitted.");
3340 p->generator =
this;
3341 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3342 param_info_ptr->filter_outputs.push_back(p);
3346 template<
typename T,
3347 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3354 template<
typename T,
3355 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3357 static_assert(!T::has_static_dimensions,
"You can only call this version of add_output() for a Buffer<T, D> where D is -1 or omitted.");
3361 p->generator =
this;
3362 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3363 param_info_ptr->filter_outputs.push_back(p);
3368 template<
typename T,
3369 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3371 static_assert(!T::has_static_halide_type,
"You can only call this version of add_output() for a Buffer<T, D> where T is void or omitted.");
3372 static_assert(T::has_static_dimensions,
"You can only call this version of add_output() for a Buffer<void, D> where D is not -1.");
3376 p->generator =
this;
3377 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3378 param_info_ptr->filter_outputs.push_back(p);
3382 template<
typename T,
3383 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3389 template<
typename T,
3390 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3392 static_assert(T::has_static_halide_type,
"You can only call this version of add_output() for a Buffer<T, D> where T is not void.");
3393 static_assert(T::has_static_dimensions,
"You can only call this version of add_output() for a Buffer<T, D> where D is not -1.");
3397 p->generator =
this;
3398 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3399 param_info_ptr->filter_outputs.push_back(p);
3405 template<
typename... Args,
3408 std::vector<Expr> collected_args;
3491 template<
typename T>
3494 template<
typename T>
3538 friend void ::Halide::Internal::generator_test();
3550 std::unique_ptr<GeneratorParamInfo> param_info_ptr;
3552 std::string generator_registered_name, generator_stub_name;
3555 struct Requirement {
3557 std::vector<Expr> error_args;
3559 std::vector<Requirement> requirements;
3564 template<
typename T>
3565 T *find_by_name(
const std::string &name,
const std::vector<T *> &v) {
3567 if (t->name() == name) {
3574 Internal::GeneratorInputBase *find_input_by_name(
const std::string &name);
3575 Internal::GeneratorOutputBase *find_output_by_name(
const std::string &name);
3577 void check_scheduled(
const char *m)
const;
3579 void build_params(
bool force =
false);
3588 void set_inputs_vector(
const std::vector<std::vector<StubInput>> &inputs);
3590 static void check_input_is_singular(Internal::GeneratorInputBase *in);
3591 static void check_input_is_array(Internal::GeneratorInputBase *in);
3592 static void check_input_kind(Internal::GeneratorInputBase *in, Internal::ArgInfoKind kind);
3598 template<
typename T,
int Dims>
3599 std::vector<StubInput> build_input(
size_t i,
const Buffer<T, Dims> &arg) {
3600 auto *in = param_info().inputs().at(i);
3601 check_input_is_singular(in);
3602 const auto k = in->kind();
3603 if (k == Internal::ArgInfoKind::Buffer) {
3604 Halide::Buffer<> b = arg;
3605 StubInputBuffer<> sib(b);
3608 }
else if (k == Internal::ArgInfoKind::Function) {
3609 Halide::Func f(arg.name() +
"_im");
3610 f(Halide::_) = arg(Halide::_);
3614 check_input_kind(in, Internal::ArgInfoKind::Buffer);
3623 template<
typename T,
int Dims>
3624 std::vector<StubInput> build_input(
size_t i,
const GeneratorInput<Buffer<T, Dims>> &arg) {
3625 auto *in = param_info().inputs().at(i);
3626 check_input_is_singular(in);
3627 const auto k = in->kind();
3628 if (k == Internal::ArgInfoKind::Buffer) {
3629 StubInputBuffer<> sib = arg;
3632 }
else if (k == Internal::ArgInfoKind::Function) {
3633 Halide::Func f = arg.funcs().at(0);
3637 check_input_kind(in, Internal::ArgInfoKind::Buffer);
3643 std::vector<StubInput> build_input(
size_t i,
const Func &arg) {
3644 auto *in = param_info().inputs().at(i);
3645 check_input_kind(in, Internal::ArgInfoKind::Function);
3646 check_input_is_singular(in);
3647 const Halide::Func &f = arg;
3653 std::vector<StubInput> build_input(
size_t i,
const std::vector<Func> &arg) {
3654 auto *in = param_info().inputs().at(i);
3655 check_input_kind(in, Internal::ArgInfoKind::Function);
3656 check_input_is_array(in);
3658 std::vector<StubInput> siv;
3659 siv.reserve(arg.size());
3660 for (
const auto &f : arg) {
3661 siv.emplace_back(f);
3667 std::vector<StubInput> build_input(
size_t i,
const Expr &arg) {
3668 auto *in = param_info().inputs().at(i);
3669 check_input_kind(in, Internal::ArgInfoKind::Scalar);
3670 check_input_is_singular(in);
3676 std::vector<StubInput> build_input(
size_t i,
const std::vector<Expr> &arg) {
3677 auto *in = param_info().inputs().at(i);
3678 check_input_kind(in, Internal::ArgInfoKind::Scalar);
3679 check_input_is_array(in);
3680 std::vector<StubInput> siv;
3681 siv.reserve(arg.size());
3682 for (
const auto &value : arg) {
3683 siv.emplace_back(value);
3690 template<
typename T,
3691 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3692 std::vector<StubInput> build_input(
size_t i,
const T &arg) {
3693 auto *in = param_info().inputs().at(i);
3694 check_input_kind(in, Internal::ArgInfoKind::Scalar);
3695 check_input_is_singular(in);
3703 template<
typename T,
3704 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3705 std::vector<StubInput> build_input(
size_t i,
const std::vector<T> &arg) {
3706 auto *in = param_info().inputs().at(i);
3707 check_input_kind(in, Internal::ArgInfoKind::Scalar);
3708 check_input_is_array(in);
3709 std::vector<StubInput> siv;
3710 siv.reserve(arg.size());
3711 for (
const auto &value : arg) {
3715 siv.emplace_back(e);
3720 template<
typename... Args,
size_t... Indices>
3721 std::vector<std::vector<StubInput>> build_inputs(
const std::tuple<const Args &...> &t, std::index_sequence<Indices...>) {
3722 return {build_input(Indices, std::get<Indices>(t))...};
3727 template<
typename T>
3728 static void get_arguments(std::vector<AbstractGenerator::ArgInfo> &args, ArgInfoDirection dir,
const T &t) {
3730 args.push_back({e->name(),
3733 e->gio_types_defined() ? e->gio_types() : std::vector<Type>{},
3734 e->dims_defined() ? e->dims() : 0});
3767class GeneratorRegistry {
3778 using GeneratorFactoryMap = std::map<const std::string, GeneratorFactory>;
3780 GeneratorFactoryMap factories;
3783 static GeneratorRegistry &get_registry();
3785 GeneratorRegistry() =
default;
3789 GeneratorRegistry &
operator=(
const GeneratorRegistry &) =
delete;
3791 GeneratorRegistry &
operator=(GeneratorRegistry &&that) =
delete;
3807 auto g = std::make_unique<T>();
3808 g->init_from_context(
context);
3814 const std::string ®istered_name,
3815 const std::string &stub_name) {
3817 g->set_generator_names(registered_name, stub_name);
3821 template<
typename... Args>
3829 template<
typename T2>
3834 template<
typename T2,
typename... Args>
3835 std::unique_ptr<T2>
apply(
const Args &...args)
const {
3849 template<
typename T2,
typename =
void>
3850 struct has_configure_method : std::false_type {};
3852 template<
typename T2>
3853 struct has_configure_method<T2, typename type_sink<decltype(std::declval<T2>().configure())>::type> : std::true_type {};
3855 template<
typename T2,
typename =
void>
3856 struct has_generate_method : std::false_type {};
3858 template<
typename T2>
3859 struct has_generate_method<T2, typename type_sink<decltype(std::declval<T2>().generate())>::type> : std::true_type {};
3861 template<
typename T2,
typename =
void>
3862 struct has_schedule_method : std::false_type {};
3864 template<
typename T2>
3865 struct has_schedule_method<T2, typename type_sink<decltype(std::declval<T2>().
schedule())>::type> : std::true_type {};
3867 Pipeline build_pipeline_impl() {
3874 t->call_generate_impl();
3875 t->call_schedule_impl();
3876 return get_pipeline();
3879 void call_configure_impl() {
3881 if constexpr (has_configure_method<T>::value) {
3883 static_assert(std::is_void<
decltype(t->configure())>::value,
"configure() must return void");
3889 void call_generate_impl() {
3891 static_assert(has_generate_method<T>::value,
"Expected a generate() method here.");
3893 static_assert(std::is_void<
decltype(t->generate())>::value,
"generate() must return void");
3898 void call_schedule_impl() {
3900 if constexpr (has_schedule_method<T>::value) {
3902 static_assert(std::is_void<
decltype(t->schedule())>::value,
"schedule() must return void");
3911 return this->build_pipeline_impl();
3915 this->call_configure_impl();
3919 this->call_generate_impl();
3923 this->call_schedule_impl();
3927 friend void ::Halide::Internal::generator_test();
3928 friend void ::Halide::Internal::generator_test();
3929 friend class ::Halide::GeneratorContext;
4032 const std::string &name,
4035 const std::string &name,
4045struct halide_global_ns;
4048#define _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) \
4049 namespace halide_register_generator { \
4050 struct halide_global_ns; \
4051 namespace GEN_REGISTRY_NAME##_ns { \
4052 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \
4053 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context) { \
4054 using GenType = std::remove_pointer<decltype(new GEN_CLASS_NAME)>::type; \
4055 return GenType::create(context, #GEN_REGISTRY_NAME, #FULLY_QUALIFIED_STUB_NAME); \
4059 auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
4062 static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \
4063 "HALIDE_REGISTER_GENERATOR must be used at global scope");
4065#define _HALIDE_REGISTER_GENERATOR2(GEN_CLASS_NAME, GEN_REGISTRY_NAME) \
4066 _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, GEN_REGISTRY_NAME)
4068#define _HALIDE_REGISTER_GENERATOR3(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) \
4069 _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME)
4074#define __HALIDE_REGISTER_ARGCOUNT_IMPL(_1, _2, _3, COUNT, ...) \
4077#define _HALIDE_REGISTER_ARGCOUNT_IMPL(ARGS) \
4078 __HALIDE_REGISTER_ARGCOUNT_IMPL ARGS
4080#define _HALIDE_REGISTER_ARGCOUNT(...) \
4081 _HALIDE_REGISTER_ARGCOUNT_IMPL((__VA_ARGS__, 3, 2, 1, 0))
4083#define ___HALIDE_REGISTER_CHOOSER(COUNT) \
4084 _HALIDE_REGISTER_GENERATOR##COUNT
4086#define __HALIDE_REGISTER_CHOOSER(COUNT) \
4087 ___HALIDE_REGISTER_CHOOSER(COUNT)
4089#define _HALIDE_REGISTER_CHOOSER(COUNT) \
4090 __HALIDE_REGISTER_CHOOSER(COUNT)
4092#define _HALIDE_REGISTER_GENERATOR_PASTE(A, B) \
4095#define HALIDE_REGISTER_GENERATOR(...) \
4096 _HALIDE_REGISTER_GENERATOR_PASTE(_HALIDE_REGISTER_CHOOSER(_HALIDE_REGISTER_ARGCOUNT(__VA_ARGS__)), (__VA_ARGS__))
4112#define HALIDE_REGISTER_GENERATOR_ALIAS(GEN_REGISTRY_NAME, ORIGINAL_REGISTRY_NAME, ...) \
4113 namespace halide_register_generator { \
4114 struct halide_global_ns; \
4115 namespace ORIGINAL_REGISTRY_NAME##_ns { \
4116 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \
4118 namespace GEN_REGISTRY_NAME##_ns { \
4119 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context) { \
4120 auto g = ORIGINAL_REGISTRY_NAME##_ns::factory(context); \
4121 const Halide::GeneratorParamsMap m = __VA_ARGS__; \
4122 g->set_generatorparam_values(m); \
4127 auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
4130 static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \
4131 "HALIDE_REGISTER_GENERATOR_ALIAS must be used at global scope");
4136#define HALIDE_GENERATOR_PYSTUB(GEN_REGISTRY_NAME, MODULE_NAME) \
4137 static_assert(PY_MAJOR_VERSION >= 3, "Python bindings for Halide require Python 3+"); \
4138 extern "C" PyObject *_halide_pystub_impl(const char *module_name, const Halide::Internal::GeneratorFactory &factory); \
4139 namespace halide_register_generator::GEN_REGISTRY_NAME##_ns { \
4140 extern std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \
4142 extern "C" HALIDE_EXPORT_SYMBOL PyObject *PyInit_##MODULE_NAME() { \
4143 const auto factory = halide_register_generator::GEN_REGISTRY_NAME##_ns::factory; \
4144 return _halide_pystub_impl(#MODULE_NAME, factory); \
#define internal_assert(c)
Defines Func - the front-end handle on a halide function, and related classes.
#define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE)
#define HALIDE_FORWARD_METHOD(Class, Method)
#define HALIDE_FORWARD_METHOD_CONST(Class, Method)
#define HALIDE_ALWAYS_INLINE
Classes for declaring image parameters to halide pipelines.
Provides a single global registry of Generators, GeneratorParams, and Params indexed by this pointer.
Defines the structure that describes a Halide target.
#define HALIDE_NO_USER_CODE_INLINE
bool defined() const
Check if this Buffer refers to an existing Buffer.
static bool can_convert_from(const Buffer< T2, D2 > &other)
Helper class for identifying purpose of an Expr passed to memoize.
bool defined() const
Does this function have at least a pure definition.
int dimensions() const
The dimensionality (number of arguments) of this function.
const std::vector< Type > & types() const
const std::string & name() const
The name of this function, either given during construction, or automatically generated.
Func in(const Func &f)
Creates and returns a new identity Func that wraps this Func.
A fragment of front-end syntax of the form f(x, y, z), where x, y, z are Vars or Exprs.
GeneratorContext is a class that is used when using Generators (or Stubs) directly; it is used to all...
GeneratorContext with_target(const Target &t) const
GeneratorContext(const Target &t)
std::unique_ptr< T > apply(const Args &...args) const
std::unique_ptr< T > create() const
GeneratorContext & operator=(GeneratorContext &&)=default
GeneratorContext & operator=(const GeneratorContext &)=default
const Target & target() const
GeneratorContext(const Target &t, const AutoschedulerParams &autoscheduler_params)
GeneratorContext()=default
GeneratorContext(const GeneratorContext &)=default
const AutoschedulerParams & autoscheduler_params() const
GeneratorContext(GeneratorContext &&)=default
void call_generate() override
Generator(Generator &&that)=delete
static std::unique_ptr< T > create(const Halide::GeneratorContext &context, const std::string ®istered_name, const std::string &stub_name)
void call_schedule() override
std::unique_ptr< T2 > apply(const Args &...args) const
static std::unique_ptr< T > create(const Halide::GeneratorContext &context)
Generator & operator=(Generator &&that)=delete
Generator & operator=(const Generator &)=delete
void apply(const Args &...args)
void call_configure() override
std::unique_ptr< T2 > create() const
Pipeline build_pipeline() override
Build and return the Pipeline for this AbstractGenerator.
Generator(const Generator &)=delete
typename Super::TBase TBase
GeneratorOutput(const std::string &name)
GeneratorOutput(const std::string &name, const std::vector< Type > &t, int d)
GeneratorOutput< T > & operator=(const Internal::StubOutputBuffer< T2 > &stub_output_buffer)
GeneratorOutput(const char *name)
GeneratorOutput(const std::string &name, const std::vector< Type > &t)
GeneratorOutput(size_t array_size, const std::string &name, int d)
GeneratorOutput(size_t array_size, const std::string &name, const Type &t, int d)
GeneratorOutput(const std::string &name, const Type &t, int d)
GeneratorOutput< T > & operator=(Buffer< T2, D2 > &buffer)
GeneratorOutput(size_t array_size, const std::string &name, const std::vector< Type > &t, int d)
GeneratorOutput(const std::string &name, int d)
GeneratorOutput(size_t array_size, const std::string &name)
GeneratorOutput(const std::string &name, const Type &t)
GeneratorOutput(size_t array_size, const std::string &name, const std::vector< Type > &t)
GeneratorOutput(size_t array_size, const std::string &name, const Type &t)
GeneratorOutput< T > & operator=(const Func &f)
GeneratorParam is a templated class that can be used to modify the behavior of the Generator at code-...
GeneratorParam(const std::string &name, const std::string &value)
GeneratorParam(const std::string &name, const T &value, const T &min, const T &max)
GeneratorParam(const std::string &name, const T &value)
GeneratorParam(const std::string &name, const T &value, const std::map< std::string, T > &enum_map)
An Image parameter to a halide pipeline.
AbstractGenerator is an ABC that defines the API a Generator must provide to work with the existing G...
A reference-counted handle to Halide's internal representation of a function.
GIOBase is the base class for all GeneratorInput<> and GeneratorOutput<> instantiations; it is not pa...
const std::string & name() const
GIOBase & operator=(const GIOBase &)=delete
size_t array_size() const
virtual const char * input_or_output() const =0
GIOBase(size_t array_size, const std::string &name, ArgInfoKind kind, const std::vector< Type > &types, int dims)
void check_matching_dims(int d) const
friend class GeneratorBase
bool array_size_defined() const
const std::vector< Type > & gio_types() const
bool dims_defined() const
GIOBase & operator=(GIOBase &&)=delete
const std::vector< Func > & funcs() const
std::vector< Type > types_
void check_matching_types(const std::vector< Type > &t) const
std::string array_name(size_t i) const
virtual void check_value_writable() const =0
GIOBase(const GIOBase &)=delete
void check_matching_array_size(size_t size) const
friend class GeneratorStub
GIOBase(GIOBase &&)=delete
void check_gio_access() const
void set_dimensions(int dims)
void set_array_size(int size)
std::vector< Func > funcs_
friend class GeneratorParamInfo
virtual bool is_array() const
virtual void verify_internals()
virtual ~GIOBase()=default
friend class GeneratorParam_Synthetic
std::vector< Expr > exprs_
void set_type(const Type &type)
bool gio_types_defined() const
GeneratorBase * generator
const std::vector< Expr > & exprs() const
const std::vector< ElemType > & get_values() const
GeneratorContext context() const override
Return the Target and autoscheduler info that this Generator was created with.
void ensure_configure_has_been_called()
std::string name() override
Return the name of this Generator.
friend class StubOutputBufferBase
virtual void call_schedule()=0
bool allow_out_of_order_inputs_and_outputs() const override
By default, a Generator must declare all Inputs before all Outputs.
GeneratorParam< Target > target
void bind_input(const std::string &name, const std::vector< Parameter > &v) override
Rebind a specified Input to refer to the given piece of IR, replacing the default ImageParam / Param ...
GeneratorInput< T > * add_input(const std::string &name)
std::vector< Func > output_func(const std::string &name) override
Given the name of an output, return the Func(s) for that output.
void claim_name(const std::string &name, const char *param_type)
std::vector< Parameter > input_parameter(const std::string &name) override
Given the name of an input, return the Parameter(s) for that input.
void bind_input(const std::string &name, const std::vector< Func > &v) override
void bind_input(const std::string &name, const std::vector< Expr > &v) override
bool emit_hlpipe(const std::string &hlpipe_file_path) override
Emit a Serialized Halide Pipeline (.hlpipe) file to the given path.
Realization realize(Args &&...args)
GeneratorBase(const GeneratorBase &)=delete
virtual void call_generate()=0
GeneratorOutput< T > * add_output(const std::string &name)
GeneratorBase(size_t size)
GeneratorOutput< T > Output
int natural_vector_size() const
Given a data type, return an estimate of the "natural" vector size for that data type when compiling ...
friend class GeneratorInputBase
Target get_target() const
~GeneratorBase() override
virtual void init_from_context(const Halide::GeneratorContext &context)
GeneratorOutput< T > * add_output(const std::string &name, const Type &t)
void check_exact_phase(Phase expected_phase) const
void set_generatorparam_value(const std::string &name, const LoopLevel &loop_level) override
void check_min_phase(Phase expected_phase) const
void realize(Realization r)
enum Halide::Internal::GeneratorBase::Phase Created
void set_generator_names(const std::string ®istered_name, const std::string &stub_name)
Realization realize(std::vector< int32_t > sizes)
GeneratorInput< T > * add_input(const std::string &name, int dimensions)
std::vector< ArgInfo > arginfos() override
Return a list of all the ArgInfos for this generator.
virtual void call_configure()=0
GeneratorInput< T > * add_input(const std::string &name, const Type &type)
void set_generatorparam_value(const std::string &name, const std::string &value) override
Set the value for a specific GeneratorParam for an AbstractGenerator instance.
GeneratorBase(GeneratorBase &&that)=delete
GeneratorOutput< T > * add_output(const std::string &name, int dimensions)
bool using_autoscheduler() const
friend class GeneratorParamBase
bool emit_cpp_stub(const std::string &stub_file_path) override
Emit a Generator Stub (.stub.h) file to the given path.
friend class GeneratorParamInfo
GeneratorInput< T > Input
GeneratorOutput< T > * add_output(const std::string &name, const std::vector< Type > &t, int dimensions)
GeneratorOutput< T > * add_output(const std::string &name, const std::vector< Type > &t)
GeneratorBase & operator=(const GeneratorBase &)=delete
GeneratorBase & operator=(GeneratorBase &&that)=delete
void set_inputs(const Args &...args)
set_inputs is a variadic wrapper around set_inputs_vector, which makes usage much simpler in many cas...
GeneratorParam_AutoSchedulerParams autoscheduler_
HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...error_args)
GeneratorInput< T > * add_input(const std::string &name, const Type &t, int dimensions)
void add_requirement(const Expr &condition, const std::vector< Expr > &error_args)
int natural_vector_size(Halide::Type t) const
Given a data type, return an estimate of the "natural" vector size for that data type when compiling ...
void advance_phase(Phase new_phase)
GeneratorOutput< T > * add_output(const std::string &name, const Type &t, int dimensions)
friend class GeneratorOutputBase
GeneratorFactoryProvider provides a way to customize the Generators that are visible to generate_filt...
virtual AbstractGeneratorPtr create(const std::string &name, const Halide::GeneratorContext &context) const =0
Create an instance of the Generator that is registered under the given name.
GeneratorFactoryProvider(const GeneratorFactoryProvider &)=delete
GeneratorFactoryProvider()=default
GeneratorFactoryProvider & operator=(GeneratorFactoryProvider &&)=delete
GeneratorFactoryProvider(GeneratorFactoryProvider &&)=delete
GeneratorFactoryProvider & operator=(const GeneratorFactoryProvider &)=delete
virtual std::vector< std::string > enumerate() const =0
Return a list of all registered Generators that are available for use with the create() method.
virtual ~GeneratorFactoryProvider()=default
GeneratorOutput_Arithmetic(const std::string &name)
GeneratorOutput_Arithmetic(size_t array_size, const std::string &name)
typename Super::TBase TBase
GeneratorOutput_Buffer(const std::string &name, int d)
GeneratorOutput_Buffer(size_t array_size, const std::string &name)
typename Super::TBase TBase
GeneratorOutput_Buffer(size_t array_size, const std::string &name, const std::vector< Type > &t, int d)
GeneratorOutput_Buffer< T > & operator=(const StubOutputBuffer< T2 > &stub_output_buffer)
GeneratorOutput_Buffer(const std::string &name)
HALIDE_NO_USER_CODE_INLINE std::string get_c_type() const override
GeneratorOutput_Buffer< T > & set_estimates(const Region &estimates)
HALIDE_NO_USER_CODE_INLINE T2 as() const
GeneratorOutput_Buffer(const std::string &name, const std::vector< Type > &t)
GeneratorOutput_Buffer(size_t array_size, const std::string &name, int d)
GeneratorOutput_Buffer< T > & operator=(const Func &f)
HALIDE_NO_USER_CODE_INLINE GeneratorOutput_Buffer< T > & operator=(Buffer< T2, D2 > &buffer)
const Func & operator[](size_t i) const
GeneratorOutput_Buffer(size_t array_size, const std::string &name, const std::vector< Type > &t)
GeneratorOutput_Buffer(const std::string &name, const std::vector< Type > &t, int d)
Func operator[](size_t i)
const Func & operator[](size_t i) const
GeneratorOutput_Func(const std::string &name)
typename Super::TBase TBase
GeneratorOutput_Func< T > & operator=(const Func &f)
GeneratorOutput_Func(const std::string &name, const std::vector< Type > &t, int d)
GeneratorOutput_Func(size_t array_size, const std::string &name, const std::vector< Type > &t, int d)
GeneratorOutput_Func(const std::string &name, int d)
GeneratorOutput_Func< T > & set_estimate(const Var &var, const Expr &min, const Expr &extent)
Func & operator[](size_t i)
GeneratorOutput_Func(const std::string &name, const std::vector< Type > &t)
GeneratorOutput_Func< T > & set_estimates(const Region &estimates)
void set_type(const std::vector< Type > &types)
Set types dynamically for tuple outputs.
const char * input_or_output() const override
~GeneratorOutputBase() override
friend class GeneratorBase
GeneratorOutputBase(const std::string &name, ArgInfoKind kind, const std::vector< Type > &t, int d)
virtual std::string get_c_type() const
HALIDE_NO_USER_CODE_INLINE T2 as() const
void check_value_writable() const override
GeneratorOutputBase(size_t array_size, const std::string &name, ArgInfoKind kind, const std::vector< Type > &t, int d)
std::vector< ValueType >::const_iterator end() const
const ValueType & operator[](size_t i) const
GeneratorOutputImpl(const std::string &name, ArgInfoKind kind, const std::vector< Type > &t, int d)
const ValueType & at(size_t i) const
std::vector< ValueType >::const_iterator begin() const
bool is_array() const override
FuncRef operator()(std::vector< ExprOrVar > args) const
typename std::remove_all_extents< T >::type TBase
FuncRef operator()(Args &&...args) const
void set_from_string(const std::string &new_value_string) override
std::string get_c_type() const override
GeneratorParam_Arithmetic(const std::string &name, const T &value, const T &min=std::numeric_limits< T >::lowest(), const T &max=std::numeric_limits< T >::max())
std::string get_default_value() const override
std::string call_to_string(const std::string &v) const override
void set_impl(const T &new_value) override
GeneratorParam_AutoSchedulerParams()
std::string get_c_type() const override
friend class GeneratorBase
void set_from_string(const std::string &new_value_string) override
std::string get_default_value() const override
std::string call_to_string(const std::string &v) const override
void set_from_string(const std::string &new_value_string) override
std::string get_default_value() const override
std::string call_to_string(const std::string &v) const override
GeneratorParam_Bool(const std::string &name, const T &value)
std::string get_c_type() const override
std::string call_to_string(const std::string &v) const override
std::string get_default_value() const override
GeneratorParam_Enum(const std::string &name, const T &value, const std::map< std::string, T > &enum_map)
void set_from_string(const std::string &new_value_string) override
std::string get_c_type() const override
std::string get_type_decls() const override
GeneratorParam_LoopLevel(const std::string &name, const LoopLevel &value)
std::string get_c_type() const override
std::string call_to_string(const std::string &v) const override
bool is_looplevel_param() const override
void set(const LoopLevel &value) override
void set_from_string(const std::string &new_value_string) override
std::string get_default_value() const override
GeneratorParam_String(const std::string &name, const std::string &value)
std::string get_c_type() const override
void set_from_string(const std::string &new_value_string) override
std::string get_default_value() const override
std::string call_to_string(const std::string &v) const override
bool is_synthetic_param() const override
std::string call_to_string(const std::string &v) const override
void set_from_string(const std::string &new_value_string) override
friend class GeneratorParamInfo
std::string get_default_value() const override
std::string get_c_type() const override
void set_from_string(const std::string &new_value_string) override
GeneratorParam_Target(const std::string &name, const T &value)
std::string get_c_type() const override
std::string get_default_value() const override
std::string call_to_string(const std::string &v) const override
std::string get_type_decls() const override
std::string get_c_type() const override
std::string call_to_string(const std::string &v) const override
std::string get_default_value() const override
GeneratorParam_Type(const std::string &name, const T &value)
void check_value_readable() const
virtual bool is_synthetic_param() const
GeneratorParamBase(GeneratorParamBase &&)=delete
friend class GeneratorBase
virtual std::string call_to_string(const std::string &v) const =0
void fail_wrong_type(const char *type)
virtual ~GeneratorParamBase()
virtual std::string get_type_decls() const
GeneratorParamBase(const std::string &name)
virtual std::string get_default_value() const =0
void set(const std::string &new_value)
GeneratorParamBase(const GeneratorParamBase &)=delete
virtual std::string get_c_type() const =0
virtual bool is_looplevel_param() const
virtual void set_from_string(const std::string &value_string)=0
void check_value_writable() const
GeneratorParamBase & operator=(GeneratorParamBase &&)=delete
const std::string & name() const
friend class GeneratorParamInfo
GeneratorParamBase & operator=(const GeneratorParamBase &)=delete
void set(const char *new_value)
void set(const std::string &new_value)
GeneratorParamImpl(const std::string &name, const T &value)
virtual void set_impl(const T &new_value)
const std::vector< Internal::GeneratorInputBase * > & inputs() const
friend class GeneratorBase
const std::vector< Internal::GeneratorParamBase * > & generator_params() const
GeneratorParamInfo(GeneratorBase *generator, size_t size)
const std::vector< Internal::GeneratorOutputBase * > & outputs() const
GeneratorRegistry(const GeneratorRegistry &)=delete
static AbstractGeneratorPtr create(const std::string &name, const Halide::GeneratorContext &context)
GeneratorRegistry & operator=(GeneratorRegistry &&that)=delete
GeneratorRegistry(GeneratorRegistry &&that)=delete
GeneratorRegistry & operator=(const GeneratorRegistry &)=delete
static void register_factory(const std::string &name, GeneratorFactory generator_factory)
static std::vector< std::string > enumerate()
static void unregister_factory(const std::string &name)
RegisterGenerator(const char *registered_name, GeneratorFactory generator_factory)
Target get_target() const
std::shared_ptr< AbstractGenerator > generator
Realization realize(Args &&...args)
StubOutputBufferBase(const Func &f, const std::shared_ptr< AbstractGenerator > &generator)
Realization realize(std::vector< int32_t > sizes)
StubOutputBuffer is the placeholder that a Stub uses when it requires a Buffer for an output (rather ...
StubOutputBuffer()=default
static std::vector< StubOutputBuffer< T > > to_output_buffers(const std::vector< Func > &v, const std::shared_ptr< AbstractGenerator > &gen)
friend class GeneratorOutput_Buffer
A reference to a site in a Halide statement at the top of the body of a particular for loop.
static LoopLevel root()
Construct a special LoopLevel value which represents the location outside of all for loops.
static LoopLevel inlined()
Construct a special LoopLevel value that implies that a function should be inlined away.
void set(const LoopLevel &other)
Mutate our contents to match the contents of 'other'.
Halide::GeneratorParam< T > GeneratorParam
Halide::MemoryType MemoryType
static Type Bool(int lanes=1)
Halide::ImageParam ImageParam
Halide::ExternFuncArgument ExternFuncArgument
static Expr cast(Halide::Type t, Expr e)
Halide::GeneratorContext GeneratorContext
Halide::NameMangling NameMangling
Halide::TailStrategy TailStrategy
static Type UInt(int bits, int lanes=1)
Halide::LoopLevel LoopLevel
Halide::EvictionKey EvictionKey
Halide::Partition Partition
static Type Int(int bits, int lanes=1)
static Type Float(int bits, int lanes=1)
Halide::PrefetchBoundStrategy PrefetchBoundStrategy
Halide::Buffer< T, D > Buffer
Halide::Pipeline Pipeline
A handle on the output buffer of a pipeline.
A scalar parameter to a halide pipeline.
A reference-counted handle to a parameter to a halide pipeline.
void set_default_value(const Expr &e)
Get and set the default values for scalar parameters.
int dimensions() const
Get the dimensionality of this parameter.
void set_max_value(const Expr &e)
void set_buffer(const Buffer< void > &b)
If the parameter is a buffer parameter, set its current value.
void set_min_value(const Expr &e)
Get and set constraints for scalar parameters.
void set_estimate(Expr e)
Type type() const
Get the type of this parameter.
A class representing a Halide pipeline.
A multi-dimensional domain over which to iterate.
A reduction variable represents a single dimension of a reduction domain (RDom).
A Realization is a vector of references to existing Buffer objects.
A single definition of a Func.
Create a small array of Exprs for defining and calling functions with multiple outputs.
A Halide variable, to be used when defining functions.
auto max_forward(const Other &a, const GeneratorParam< T > &b) -> decltype(max(a,(T) b))
auto min_forward(const Other &a, const GeneratorParam< T > &b) -> decltype(min(a,(T) b))
typename select_type< cond< has_static_halide_type_method< TBase >::value, GeneratorInput_Buffer< T > >, cond< std::is_same< TBase, Func >::value, GeneratorInput_Func< T > >, cond< std::is_arithmetic< TBase >::value, GeneratorInput_Arithmetic< T > >, cond< std::is_scalar< TBase >::value, GeneratorInput_Scalar< T > >, cond< std::is_same< TBase, Expr >::value, GeneratorInput_DynamicScalar< T > > >::type GeneratorInputImplBase
int generate_filter_main(int argc, char **argv)
generate_filter_main() is a convenient wrapper for GeneratorRegistry::create() + compile_to_files(); ...
std::string halide_type_to_enum_string(const Type &t)
ConstantInterval min(const ConstantInterval &a, const ConstantInterval &b)
std::vector< Expr > parameter_constraints(const Parameter &p)
Expr make_const(Type t, int64_t val)
Construct an immediate of the given type from any numeric C++ type.
typename select_type< cond< has_static_halide_type_method< TBase >::value, GeneratorOutput_Buffer< T > >, cond< std::is_same< TBase, Func >::value, GeneratorOutput_Func< T > >, cond< std::is_arithmetic< TBase >::value, GeneratorOutput_Arithmetic< T > > >::type GeneratorOutputImplBase
std::string halide_type_to_c_source(const Type &t)
std::function< AbstractGeneratorPtr(const GeneratorContext &context)> GeneratorFactory
ConstantInterval max(const ConstantInterval &a, const ConstantInterval &b)
HALIDE_NO_USER_CODE_INLINE std::string enum_to_string(const std::map< std::string, T > &enum_map, const T &t)
std::vector< Type > parse_halide_type_list(const std::string &types)
std::string halide_type_to_c_type(const Type &t)
std::string print_loop_nest(const std::vector< Function > &output_funcs)
Emit some simple pseudocode that shows the structure of the loop nest specified by this pipeline's sc...
void execute_generator(const ExecuteGeneratorArgs &args)
Execute a Generator for AOT compilation – this provides the implementation of the command-line Genera...
std::unique_ptr< AbstractGenerator > AbstractGeneratorPtr
HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector< Expr > &args)
const GeneratorFactoryProvider & get_registered_generators()
Return a GeneratorFactoryProvider that knows about all the currently-registered C++ Generators.
typename select_type< cond< std::is_same< T, Target >::value, GeneratorParam_Target< T > >, cond< std::is_same< T, LoopLevel >::value, GeneratorParam_LoopLevel >, cond< std::is_same< T, std::string >::value, GeneratorParam_String< T > >, cond< std::is_same< T, Type >::value, GeneratorParam_Type< T > >, cond< std::is_same< T, bool >::value, GeneratorParam_Bool< T > >, cond< std::is_arithmetic< T >::value, GeneratorParam_Arithmetic< T > >, cond< std::is_enum< T >::value, GeneratorParam_Enum< T > > >::type GeneratorParamImplBase
T parse_scalar(const std::string &value)
const std::map< std::string, Halide::Type > & get_halide_type_enum_map()
T enum_from_string(const std::map< std::string, T > &enum_map, const std::string &s)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
auto operator>=(const Other &a, const GeneratorParam< T > &b) -> decltype(a >=(T) b)
Greater than or equal comparison between GeneratorParam<T> and any type that supports operator>= with...
Target get_host_target()
Return the target corresponding to the host machine.
Type UInt(int bits, int lanes=1)
Constructing an unsigned integer type.
Expr reinterpret(Type t, Expr e)
Reinterpret the bits of one value as another type.
Type Float(int bits, int lanes=1)
Construct a floating-point type.
std::function< std::unique_ptr< Internal::CompilerLogger >(const std::string &fn_name, const Target &target)> CompilerLoggerFactory
auto operator==(const Other &a, const GeneratorParam< T > &b) -> decltype(a==(T) b)
Equality comparison between GeneratorParam<T> and any type that supports operator== with T.
auto operator<(const Other &a, const GeneratorParam< T > &b) -> decltype(a<(T) b)
Less than comparison between GeneratorParam<T> and any type that supports operator< with T.
Type type_of()
Construct the halide equivalent of a C type.
auto operator*(const Other &a, const GeneratorParam< T > &b) -> decltype(a *(T) b)
Multiplication between GeneratorParam<T> and any type that supports operator* with T.
auto operator||(const Other &a, const GeneratorParam< T > &b) -> decltype(a||(T) b)
Logical or between between GeneratorParam<T> and any type that supports operator|| with T.
PrefetchBoundStrategy
Different ways to handle accesses outside the original extents in a prefetch.
auto operator-(const Other &a, const GeneratorParam< T > &b) -> decltype(a -(T) b)
Subtraction between GeneratorParam<T> and any type that supports operator- with T.
auto operator!(const GeneratorParam< T > &a) -> decltype(!(T) a)
Not operator for GeneratorParam.
TailStrategy
Different ways to handle a tail case in a split when the factor does not provably divide the extent.
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
auto operator+(const Other &a, const GeneratorParam< T > &b) -> decltype(a+(T) b)
Addition between GeneratorParam<T> and any type that supports operator+ with T.
Callable create_callable_from_generator(const GeneratorContext &context, const std::string &name, const GeneratorParamsMap &generator_params={})
Create a Generator from the currently-registered Generators, use it to create a Callable.
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
auto operator&&(const Other &a, const GeneratorParam< T > &b) -> decltype(a &&(T) b)
Logical and between between GeneratorParam<T> and any type that supports operator&& with T.
auto operator%(const Other &a, const GeneratorParam< T > &b) -> decltype(a %(T) b)
Modulo between GeneratorParam<T> and any type that supports operator% with T.
NameMangling
An enum to specify calling convention for extern stages.
@ Default
Match whatever is specified in the Target.
Target get_jit_target_from_environment()
Return the target that Halide will use for jit-compilation.
std::map< std::string, std::string > GeneratorParamsMap
auto operator<=(const Other &a, const GeneratorParam< T > &b) -> decltype(a<=(T) b)
Less than or equal comparison between GeneratorParam<T> and any type that supports operator<= with T.
Target get_target_from_environment()
Return the target that Halide will use.
auto operator>(const Other &a, const GeneratorParam< T > &b) -> decltype(a >(T) b)
Greater than comparison between GeneratorParam<T> and any type that supports operator> with T.
auto operator!=(const Other &a, const GeneratorParam< T > &b) -> decltype(a !=(T) b)
Inequality comparison between between GeneratorParam<T> and any type that supports operator!...
Internal::ConstantInterval cast(Type t, const Internal::ConstantInterval &a)
Cast operators for ConstantIntervals.
Type Bool(int lanes=1)
Construct a boolean type.
std::vector< Range > Region
A multi-dimensional box.
auto operator/(const Other &a, const GeneratorParam< T > &b) -> decltype(a/(T) b)
Division between GeneratorParam<T> and any type that supports operator/ with T.
Expr max(const FuncRef &a, const FuncRef &b)
MemoryType
An enum describing different address spaces to be used with Func::store_in.
Partition
Different ways to handle loops with a potentially optimizable boundary conditions.
unsigned __INT64_TYPE__ uint64_t
signed __INT64_TYPE__ int64_t
signed __INT32_TYPE__ int32_t
unsigned __INT8_TYPE__ uint8_t
unsigned __INT16_TYPE__ uint16_t
unsigned __INT32_TYPE__ uint32_t
signed __INT16_TYPE__ int16_t
signed __INT8_TYPE__ int8_t
Special the Autoscheduler to be used (if any), along with arbitrary additional arguments specific to ...
A fragment of Halide syntax.
HALIDE_ALWAYS_INLINE Type type() const
Get the type of this expression node.
An argument to an extern-defined Func.
static TO2 value(const FROM &from)
The Dim struct represents one loop in the schedule's representation of a loop nest.
ExecuteGeneratorArgs is the set of arguments to execute_generator().
CompilerLoggerFactory compiler_logger_factory
std::string function_name
std::string file_base_name
CreateGeneratorFn create_generator
std::string generator_name
std::set< OutputFileType > output_types
std::vector< std::string > suffixes
std::vector< Target > targets
GeneratorParamsMap generator_params
std::function< AbstractGeneratorPtr(const std::string &name, const GeneratorContext &context)> CreateGeneratorFn
static constexpr bool value
typename std::conditional< First::value, typename First::type, void >::type type
A struct representing a target machine and os to generate code for.
Types in the halide type system.