1 #ifndef HALIDE_GENERATOR_H_ 2 #define HALIDE_GENERATOR_H_ 262 #include <functional> 270 #include <type_traits> 281 #if !(__cplusplus >= 201703L || _MSVC_LANG >= 201703L) 282 #error "Halide requires C++17 or later; please upgrade your compiler." 287 class GeneratorContext;
299 for (
const auto &key_value : enum_map) {
300 if (t == key_value.second) {
301 return key_value.first;
304 user_error <<
"Enumeration value not found.\n";
310 auto it = enum_map.find(s);
311 user_assert(it != enum_map.end()) <<
"Enumeration value not found: " << s <<
"\n";
338 virtual std::vector<std::string>
enumerate()
const = 0;
380 template<
bool B,
typename T>
386 template<
typename First,
typename... Rest>
387 struct select_type : std::conditional<First::value, typename First::type, typename select_type<Rest...>::type> {};
389 template<
typename First>
391 using type =
typename std::conditional<First::value, typename First::type, void>::type;
401 inline const std::string &
name()
const {
413 #define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE) \ 414 virtual void set(const TYPE &new_value) = 0; 432 #undef HALIDE_GENERATOR_PARAM_TYPED_SETTER 435 void set(
const std::string &new_value) {
438 void set(
const char *new_value) {
453 virtual std::string
call_to_string(
const std::string &v)
const = 0;
473 const std::string name_;
490 template<
typename FROM,
typename TO>
492 template<typename TO2 = TO, typename std::enable_if<!std::is_same<TO2, bool>::value>::type * =
nullptr>
493 inline static TO2
value(
const FROM &from) {
494 return static_cast<TO2
>(from);
497 template<typename TO2 = TO, typename std::enable_if<std::is_same<TO2, bool>::value>::type * =
nullptr>
498 inline static TO2
value(
const FROM &from) {
518 return this->
value();
525 #define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE) \ 526 void set(const TYPE &new_value) override { \ 527 typed_setter_impl<TYPE>(new_value, #TYPE); \ 546 #undef HALIDE_GENERATOR_PARAM_TYPED_SETTER 549 void set(
const std::string &new_value) {
565 template<
typename FROM,
typename std::enable_if<
566 !std::is_convertible<FROM, T>::value>
::type * =
nullptr>
572 template<
typename FROM,
typename std::enable_if<
573 std::is_same<FROM, T>::value>
::type * =
nullptr>
580 template<
typename FROM,
typename std::enable_if<
581 !std::is_same<FROM, T>::value &&
582 std::is_convertible<FROM, T>::value &&
583 std::is_convertible<T, FROM>::value>
::type * =
nullptr>
588 if (value2 !=
value) {
595 template<
typename FROM,
typename std::enable_if<
596 !std::is_same<FROM, T>::value &&
597 std::is_convertible<FROM, T>::value &&
598 !std::is_convertible<T, FROM>::value>
::type * =
nullptr>
618 this->
set(
Target(new_value_string));
622 return this->
value().to_string();
626 std::ostringstream oss;
627 oss << v <<
".to_string()";
648 bool try_set(
const std::string &key,
const std::string &
value);
680 if (new_value_string ==
"root") {
682 }
else if (new_value_string ==
"inlined") {
685 user_error <<
"Unable to parse " << this->
name() <<
": " << new_value_string;
702 return "LoopLevel::inlined()";
704 return "LoopLevel::root()";
713 return std::string();
730 const T &min = std::numeric_limits<T>::lowest(),
738 user_assert(new_value >= min && new_value <= max) <<
"Value out of range: " << new_value;
743 std::istringstream iss(new_value_string);
748 if (
sizeof(T) ==
sizeof(
char) && !std::is_same<T, bool>::value) {
755 user_assert(!iss.fail() && iss.get() == EOF) <<
"Unable to parse: " << new_value_string;
760 std::ostringstream oss;
761 oss << this->
value();
762 if (std::is_same<T, float>::value) {
765 if (oss.str().find(
'.') == std::string::npos) {
774 std::ostringstream oss;
775 oss <<
"std::to_string(" << v <<
")";
780 std::ostringstream oss;
781 if (std::is_same<T, float>::value) {
783 }
else if (std::is_same<T, double>::value) {
785 }
else if (std::is_integral<T>::value) {
786 if (std::is_unsigned<T>::value) {
789 oss <<
"int" << (
sizeof(T) * 8) <<
"_t";
810 if (new_value_string ==
"true" || new_value_string ==
"True") {
812 }
else if (new_value_string ==
"false" || new_value_string ==
"False") {
815 user_assert(
false) <<
"Unable to parse bool: " << new_value_string;
821 return this->
value() ?
"true" :
"false";
825 std::ostringstream oss;
826 oss <<
"std::string((" << v <<
") ? \"true\" : \"false\")";
845 template<typename T2 = T, typename std::enable_if<!std::is_same<T2, Type>::value>
::type * =
nullptr>
846 void set(
const T &e) {
851 auto it = enum_map.find(new_value_string);
852 user_assert(it != enum_map.end()) <<
"Enumeration value not found: " << new_value_string;
857 return "Enum_" + this->
name() +
"_map().at(" + v +
")";
861 return "Enum_" + this->
name();
869 std::ostringstream oss;
870 oss <<
"enum class Enum_" << this->
name() <<
" {\n";
871 for (
auto key_value : enum_map) {
872 oss <<
" " << key_value.first <<
",\n";
879 oss <<
"inline HALIDE_NO_USER_CODE_INLINE const std::map<Enum_" << this->
name() <<
", std::string>& Enum_" << this->
name() <<
"_map() {\n";
880 oss <<
" static const std::map<Enum_" << this->
name() <<
", std::string> m = {\n";
881 for (
auto key_value : enum_map) {
882 oss <<
" { Enum_" << this->
name() <<
"::" << key_value.first <<
", \"" << key_value.first <<
"\"},\n";
885 oss <<
" return m;\n";
891 const std::map<std::string, T> enum_map;
902 return "Halide::Internal::halide_type_to_enum_string(" + v +
")";
925 this->
set(new_value_string);
929 return "\"" + this->
value() +
"\"";
937 return "std::string";
943 typename select_type<
992 template<typename T2 = T, typename std::enable_if<!std::is_same<T2, std::string>::value>::type * =
nullptr>
1001 GeneratorParam(
const std::string &name,
const T &value,
const std::map<std::string, T> &enum_map)
1013 template<
typename Other,
typename T>
1017 template<
typename Other,
typename T>
1026 template<
typename Other,
typename T>
1030 template<
typename Other,
typename T>
1039 template<
typename Other,
typename T>
1043 template<
typename Other,
typename T>
1052 template<
typename Other,
typename T>
1056 template<
typename Other,
typename T>
1065 template<
typename Other,
typename T>
1069 template<
typename Other,
typename T>
1078 template<
typename Other,
typename T>
1082 template<
typename Other,
typename T>
1091 template<
typename Other,
typename T>
1092 auto operator<(const Other &a, const GeneratorParam<T> &b) -> decltype(a < (T)b) {
1095 template<
typename Other,
typename T>
1096 auto operator<(const GeneratorParam<T> &a,
const Other &b) -> decltype((T)a < b) {
1104 template<
typename Other,
typename T>
1108 template<
typename Other,
typename T>
1117 template<
typename Other,
typename T>
1118 auto operator<=(const Other &a, const GeneratorParam<T> &b) -> decltype(a <= (T)b) {
1121 template<
typename Other,
typename T>
1122 auto operator<=(const GeneratorParam<T> &a,
const Other &b) -> decltype((T)a <= b) {
1130 template<
typename Other,
typename T>
1134 template<
typename Other,
typename T>
1143 template<
typename Other,
typename T>
1147 template<
typename Other,
typename T>
1156 template<
typename Other,
typename T>
1160 template<
typename Other,
typename T>
1164 template<
typename T>
1166 return (T)a && (T)b;
1173 template<
typename Other,
typename T>
1177 template<
typename Other,
typename T>
1181 template<
typename T>
1183 return (T)a || (T)b;
1191 namespace Internal {
1192 namespace GeneratorMinMax {
1197 template<
typename Other,
typename T>
1199 return min(a, (T)b);
1201 template<
typename Other,
typename T>
1203 return min((T)a, b);
1206 template<
typename Other,
typename T>
1208 return max(a, (T)b);
1210 template<
typename Other,
typename T>
1212 return max((T)a, b);
1221 template<
typename Other,
typename T>
1225 template<
typename Other,
typename T>
1234 template<
typename Other,
typename T>
1238 template<
typename Other,
typename T>
1245 template<
typename T>
1250 namespace Internal {
1252 template<
typename T2>
1267 template<
typename T2>
1269 template<
typename T2,
int D2>
1283 template<
typename T2,
int D2>
1299 template<
typename T2,
int D2>
1301 : parameter_(parameter_from_buffer(b)) {
1304 template<
typename T2>
1306 return {t.parameter_};
1309 template<
typename T2>
1311 std::vector<Parameter> r;
1312 r.reserve(v.size());
1313 for (
const auto &s : v) {
1314 r.push_back(s.parameter_);
1320 class AbstractGenerator;
1335 template<
typename... Args>
1340 template<
typename Dst>
1358 template<
typename T =
void>
1360 template<
typename T2>
1370 const std::shared_ptr<AbstractGenerator> &gen) {
1371 std::vector<StubOutputBuffer<T>> result;
1372 for (
const Func &
f : v) {
1392 template<
typename T2>
1459 const std::string &
name()
const;
1463 const std::vector<Type> &
gio_types()
const;
1469 const std::vector<Func> &
funcs()
const;
1470 const std::vector<Expr> &
exprs()
const;
1473 const std::string &
name,
1475 const std::vector<Type> &types,
1508 template<
typename ElemType>
1509 const std::vector<ElemType> &
get_values()
const;
1518 template<
typename T>
1530 inline const std::vector<Expr> &GIOBase::get_values<Expr>()
const {
1535 inline const std::vector<Func> &GIOBase::get_values<Func>()
const {
1542 const std::string &
name,
1544 const std::vector<Type> &t,
1557 void set_inputs(
const std::vector<StubInput> &inputs);
1581 template<
typename T,
typename ValueType>
1584 using TBase =
typename std::remove_all_extents<T>::type;
1587 return std::is_array<T>::value;
1590 template<
typename T2 = T,
typename std::enable_if<
1592 !std::is_array<T2>::value>::type * =
nullptr>
1597 template<
typename T2 = T,
typename std::enable_if<
1599 std::is_array<T2>::value && std::rank<T2>::value == 1 && (std::extent<T2, 0>::value > 0)>::type * =
nullptr>
1604 template<
typename T2 = T,
typename std::enable_if<
1606 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>::type * =
nullptr>
1612 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1615 return get_values<ValueType>().
size();
1618 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1621 return get_values<ValueType>()[i];
1624 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1625 const ValueType &
at(
size_t i)
const {
1627 return get_values<ValueType>().
at(i);
1630 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1631 typename std::vector<ValueType>::const_iterator
begin()
const {
1633 return get_values<ValueType>().
begin();
1636 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1637 typename std::vector<ValueType>::const_iterator
end()
const {
1639 return get_values<ValueType>().
end();
1651 #define HALIDE_FORWARD_METHOD(Class, Method) \ 1652 template<typename... Args> \ 1653 inline auto Method(Args &&...args)->typename std::remove_reference<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))>::type { \ 1654 return this->template as<Class>().Method(std::forward<Args>(args)...); \ 1657 #define HALIDE_FORWARD_METHOD_CONST(Class, Method) \ 1658 template<typename... Args> \ 1659 inline auto Method(Args &&...args) const-> \ 1660 typename std::remove_reference<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))>::type { \ 1661 this->check_gio_access(); \ 1662 return this->template as<Class>().Method(std::forward<Args>(args)...); \ 1665 template<
typename T>
1666 class GeneratorInput_Buffer :
public GeneratorInputImpl<T, Func> {
1668 using Super = GeneratorInputImpl<T, Func>;
1673 friend class ::Halide::Func;
1674 friend class ::Halide::Stage;
1677 if (TBase::has_static_halide_type) {
1678 return "Halide::Internal::StubInputBuffer<" +
1682 return "Halide::Internal::StubInputBuffer<>";
1686 template<
typename T2>
1694 TBase::has_static_halide_type ?
std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
1695 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
1700 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Input<Buffer<T>> if T is void or omitted.");
1701 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Input<Buffer<T, D>> if D is -1 or omitted.");
1706 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Input<Buffer<T>> if T is void or omitted.");
1711 TBase::has_static_halide_type ?
std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
1713 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Input<Buffer<T, D>> if D is -1 or omitted.");
1716 template<
typename... Args>
1719 return Func(*
this)(std::forward<Args>(args)...);
1724 return Func(*
this)(std::move(args));
1727 template<
typename T2>
1729 user_assert(!this->
is_array()) <<
"Cannot assign an array type to a non-array type for Input " << this->
name();
1735 return this->
funcs().at(0);
1762 return Func(*this).
in(other);
1767 return Func(*this).
in(others);
1772 user_assert(!this->
is_array()) <<
"Cannot convert an Input<Buffer<>[]> to an ImageParam; use an explicit subscript operator: " << this->
name();
1776 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1782 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1788 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1794 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1795 typename std::vector<ImageParam>::const_iterator
begin()
const {
1796 user_error <<
"Input<Buffer<>>::begin() is not supported.";
1800 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
1801 typename std::vector<ImageParam>::const_iterator
end()
const {
1802 user_error <<
"Input<Buffer<>>::end() is not supported.";
1827 template<
typename T>
1839 template<
typename T2>
1883 template<
typename... Args>
1886 return this->
funcs().at(0)(std::forward<Args>(args)...);
1891 return this->
funcs().at(0)(args);
1896 return this->
funcs().at(0);
1923 return Func(*this).
in(other);
1928 return Func(*this).
in(others);
1951 template<
typename T>
1956 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");
1966 user_assert(!std::is_array<T>::value) <<
"Input<Expr[]> is not allowed";
1973 return this->
exprs().at(0);
1995 template<
typename T>
2020 template<typename TBase2 = TBase, typename std::enable_if<!std::is_pointer<TBase2>::value>
::type * =
nullptr>
2022 return cast<TBase>(
Expr(value));
2025 template<typename TBase2 = TBase, typename std::enable_if<std::is_pointer<TBase2>::value>
::type * =
nullptr>
2027 user_assert(value == 0) <<
"Zero is the only legal default value for Inputs which are pointer types.\n";
2041 const std::string &
name)
2046 const std::string &
name,
2055 return this->
exprs().at(0);
2065 template<typename T2 = T, typename std::enable_if<std::is_pointer<T2>::value>
::type * =
nullptr>
2068 user_assert(value ==
nullptr) <<
"nullptr is the only valid estimate for Input<PointerType>";
2075 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value && !std::is_pointer<T2>::value>
::type * =
nullptr>
2079 if (std::is_same<T2, bool>::value) {
2087 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2091 if (std::is_same<T2, bool>::value) {
2102 template<
typename T>
2115 if (!std::is_same<TBase, bool>::value) {
2138 const std::string &
name)
2143 const std::string &
name,
2156 const std::string &
name,
2169 template<
typename T2,
typename =
void>
2172 template<
typename T2>
2175 template<typename T, typename TBase = typename std::remove_all_extents<T>::type>
2186 template<
typename T>
2213 : Super(name, def) {
2217 : Super(array_size, name, def) {
2222 : Super(name, def,
min,
max) {
2227 : Super(array_size, name, def,
min,
max) {
2231 : Super(name, t, d) {
2244 : Super(array_size, name, t, d) {
2248 : Super(array_size, name, t) {
2254 : Super(array_size, name, d) {
2258 : Super(array_size, name) {
2262 namespace Internal {
2266 template<typename T2, typename std::enable_if<std::is_same<T2, Func>::value>::type * =
nullptr>
2268 static_assert(std::is_same<T2, Func>::value,
"Only Func allowed here");
2272 user_assert(
funcs_.size() == 1) <<
"Use [] to access individual Funcs in Output<Func[]>";
2342 #undef HALIDE_OUTPUT_FORWARD 2343 #undef HALIDE_OUTPUT_FORWARD_CONST 2347 const std::string &
name,
2349 const std::vector<Type> &t,
2354 const std::vector<Type> &t,
2361 void resize(
size_t size);
2377 template<
typename T>
2380 using TBase =
typename std::remove_all_extents<T>::type;
2384 return std::is_array<T>::value;
2387 template<
typename T2 = T,
typename std::enable_if<
2389 !std::is_array<T2>::value>::type * =
nullptr>
2394 template<
typename T2 = T,
typename std::enable_if<
2396 std::is_array<T2>::value && std::rank<T2>::value == 1 && (std::extent<T2, 0>::value > 0)>::type * =
nullptr>
2401 template<
typename T2 = T,
typename std::enable_if<
2403 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>::type * =
nullptr>
2409 template<
typename... Args,
typename T2 = T,
typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2412 return get_values<ValueType>().
at(0)(std::forward<Args>(args)...);
2415 template<typename ExprOrVar, typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2418 return get_values<ValueType>().
at(0)(args);
2421 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2424 return get_values<ValueType>().
at(0);
2427 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2430 return get_values<ValueType>().
at(0);
2433 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2436 return get_values<ValueType>().
size();
2439 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2442 return get_values<ValueType>()[i];
2445 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2448 return get_values<ValueType>().
at(i);
2451 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2452 typename std::vector<ValueType>::const_iterator
begin()
const {
2454 return get_values<ValueType>().
begin();
2457 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2458 typename std::vector<ValueType>::const_iterator
end()
const {
2460 return get_values<ValueType>().
end();
2463 template<
typename T2 = T,
typename std::enable_if<
2465 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>::type * =
nullptr>
2472 template<
typename T>
2483 const auto &my_types = this->
gio_types();
2485 <<
"Cannot assign Func \"" << f.
name()
2486 <<
"\" to Output \"" << this->
name() <<
"\"\n" 2487 <<
"Output " << this->
name()
2488 <<
" is declared to have " << my_types.size() <<
" tuple elements" 2489 <<
" but Func " << f.
name()
2490 <<
" has " << f.
types().size() <<
" tuple elements.\n";
2491 for (
size_t i = 0; i < my_types.size(); i++) {
2493 <<
"Cannot assign Func \"" << f.
name()
2494 <<
"\" to Output \"" << this->
name() <<
"\"\n" 2495 << (my_types.size() > 1 ?
"In tuple element " + std::to_string(i) +
", " :
"")
2496 <<
"Output " << this->
name()
2497 <<
" has declared type " << my_types[i]
2498 <<
" but Func " << f.
name()
2499 <<
" has type " << f.
types().at(i) <<
"\n";
2504 <<
"Cannot assign Func \"" << f.
name()
2505 <<
"\" to Output \"" << this->
name() <<
"\"\n" 2506 <<
"Output " << this->
name()
2507 <<
" has declared dimensionality " << this->
dims()
2508 <<
" but Func " << f.
name()
2509 <<
" has dimensionality " << f.
dimensions() <<
"\n";
2522 TBase::has_static_halide_type ?
std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2523 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
2530 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.");
2531 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2537 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.");
2542 TBase::has_static_halide_type ?
std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2545 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2550 TBase::has_static_halide_type ?
std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2551 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
2558 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.");
2559 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2565 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.");
2570 TBase::has_static_halide_type ?
std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2573 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2577 if (TBase::has_static_halide_type) {
2578 return "Halide::Internal::StubOutputBuffer<" +
2582 return "Halide::Internal::StubOutputBuffer<>";
2586 template<typename T2, typename std::enable_if<!std::is_same<T2, Func>::value>::type * =
nullptr>
2598 template<
typename T2,
int D2>
2604 <<
"Cannot assign to the Output \"" << this->
name()
2605 <<
"\": the expression is not convertible to the same Buffer type and/or dimensions.\n";
2609 <<
"Output " << this->
name() <<
" should have type=" << this->
gio_type() <<
" but saw type=" <<
Type(buffer.
type()) <<
"\n";
2613 <<
"Output " << this->
name() <<
" should have dim=" << this->
dims() <<
" but saw dim=" << buffer.dimensions() <<
"\n";
2618 this->
funcs_.at(0)(_) = buffer(_);
2626 template<
typename T2>
2629 assign_from_func(stub_output_buffer.
f);
2638 assign_from_func(f);
2644 user_assert(!this->
is_array()) <<
"Cannot convert an Output<Buffer<>[]> to an ImageParam; use an explicit subscript operator: " << this->
name();
2646 return this->
funcs_.at(0).output_buffer();
2652 user_assert(!this->
is_array()) <<
"Cannot call set_estimates() on an array Output; use an explicit subscript operator: " << this->
name();
2654 this->
funcs_.at(0).set_estimates(estimates);
2658 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2661 return this->
template get_values<Func>()[i];
2665 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2668 return this->
template get_values<Func>()[i];
2689 template<
typename T>
2696 return this->funcs_.at(i);
2724 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2726 this->check_gio_access();
2727 this->check_value_writable();
2731 get_assignable_func_ref(0) = f;
2736 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2738 this->check_gio_access();
2739 this->check_value_writable();
2740 return get_assignable_func_ref(i);
2744 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2746 this->check_gio_access();
2747 return Super::operator[](i);
2751 this->check_gio_access();
2753 for (
Func &f : this->funcs_) {
2754 f.set_estimate(var,
min, extent);
2760 this->check_gio_access();
2762 for (
Func &f : this->funcs_) {
2763 f.set_estimates(estimates);
2769 template<
typename T>
2786 template<typename T, typename TBase = typename std::remove_all_extents<T>::type>
2788 typename select_type<
2795 template<
typename T>
2816 : Super(array_size, name) {
2824 : Super(name, {t}) {
2832 : Super(name, {t}, d) {
2836 : Super(name, t, d) {
2840 : Super(array_size, name, d) {
2844 : Super(array_size, name, {t}) {
2847 explicit GeneratorOutput(
size_t array_size,
const std::string &name,
const std::vector<Type> &t)
2848 : Super(array_size, name, t) {
2852 : Super(array_size, name, {t}, d) {
2855 explicit GeneratorOutput(
size_t array_size,
const std::string &name,
const std::vector<Type> &t,
int d)
2856 : Super(array_size, name, t, d) {
2862 template<
typename T2,
int D2>
2864 Super::operator=(buffer);
2868 template<
typename T2>
2870 Super::operator=(stub_output_buffer);
2875 Super::operator=(f);
2880 namespace Internal {
2882 template<
typename T>
2884 std::istringstream iss(value);
2887 user_assert(!iss.fail() && iss.get() == EOF) <<
"Unable to parse: " << value;
2899 template<
typename T>
2905 if (!error_msg.empty()) {
2908 set_from_string_impl<T>(new_value_string);
2913 return std::string();
2918 return std::string();
2923 return std::string();
2933 static std::unique_ptr<Internal::GeneratorParamBase> make(
2935 const std::string &generator_name,
2936 const std::string &gpname,
2940 std::string error_msg = defined ?
"Cannot set the GeneratorParam " + gpname +
" for " + generator_name +
" because the value is explicitly specified in the C++ source." :
"";
2941 return std::unique_ptr<GeneratorParam_Synthetic<T>>(
2949 template<typename T2 = T, typename std::enable_if<std::is_same<T2, ::Halide::Type>::value>
::type * =
nullptr>
2950 void set_from_string_impl(
const std::string &new_value_string) {
2955 template<typename T2 = T, typename std::enable_if<std::is_integral<T2>::value>
::type * =
nullptr>
2956 void set_from_string_impl(
const std::string &new_value_string) {
2958 gio.
dims_ = parse_scalar<T2>(new_value_string);
2960 gio.
array_size_ = parse_scalar<T2>(new_value_string);
2968 const std::string error_msg;
3026 return autoscheduler_params_;
3034 template<
typename T>
3036 return T::create(*
this);
3038 template<
typename T,
typename... Args>
3039 inline std::unique_ptr<T>
apply(
const Args &...args)
const {
3040 auto t = this->create<T>();
3074 template<
typename T>
3076 return Halide::cast<T>(e);
3081 template<
typename T>
3083 template<
typename T = void,
int D = -1>
3085 template<
typename T>
3101 namespace Internal {
3103 template<
typename... Args>
3109 template<
typename T,
typename... Args>
3111 static const bool value = !std::is_convertible<T, Realization>::value &&
NoRealizations<Args...>::value;
3120 std::set<std::string> names;
3123 std::vector<Internal::GeneratorParamBase *> filter_generator_params;
3126 std::vector<Internal::GeneratorInputBase *> filter_inputs;
3129 std::vector<Internal::GeneratorOutputBase *> filter_outputs;
3134 std::vector<std::unique_ptr<Internal::GeneratorParamBase>> owned_synthetic_params;
3137 std::vector<std::unique_ptr<Internal::GIOBase>> owned_extras;
3145 return filter_generator_params;
3147 const std::vector<Internal::GeneratorInputBase *> &
inputs()
const {
3148 return filter_inputs;
3150 const std::vector<Internal::GeneratorOutputBase *> &
outputs()
const {
3151 return filter_outputs;
3167 template<
typename data_t>
3182 template<
typename... Args>
3187 <<
"Expected exactly " << pi.
inputs().size()
3188 <<
" inputs but got " <<
sizeof...(args) <<
"\n";
3189 set_inputs_vector(build_inputs(std::forward_as_tuple<const Args &...>(args...), std::make_index_sequence<
sizeof...(Args)>{}));
3193 this->check_scheduled(
"realize");
3199 template<
typename... Args,
typename std::enable_if<
NoRealizations<Args...>::value>::type * =
nullptr>
3201 this->check_scheduled(
"realize");
3206 this->check_scheduled(
"realize");
3217 template<
typename T,
3218 typename std::enable_if<std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3222 p->generator =
this;
3223 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3224 param_info_ptr->filter_inputs.push_back(p);
3229 template<
typename T,
3230 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3232 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 .");
3233 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.");
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 not void.");
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.");
3250 p->generator =
this;
3251 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3252 param_info_ptr->filter_inputs.push_back(p);
3257 template<
typename T,
3258 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3260 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.");
3261 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.");
3264 p->generator =
this;
3265 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3266 param_info_ptr->filter_inputs.push_back(p);
3270 template<
typename T,
3271 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3275 p->generator =
this;
3276 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3277 param_info_ptr->filter_inputs.push_back(p);
3281 template<
typename T,
3282 typename std::enable_if<std::is_same<T, Expr>::value>::type * =
nullptr>
3286 p->generator =
this;
3288 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3289 param_info_ptr->filter_inputs.push_back(p);
3294 template<
typename T,
3295 typename std::enable_if<std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3299 p->generator =
this;
3300 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3301 param_info_ptr->filter_outputs.push_back(p);
3306 template<
typename T,
3307 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3309 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 .");
3310 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.");
3313 p->generator =
this;
3314 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3315 param_info_ptr->filter_outputs.push_back(p);
3320 template<
typename T,
3321 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3323 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.");
3324 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.");
3327 p->generator =
this;
3328 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3329 param_info_ptr->filter_outputs.push_back(p);
3334 template<
typename T,
3335 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3337 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.");
3338 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.");
3341 p->generator =
this;
3342 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3343 param_info_ptr->filter_outputs.push_back(p);
3349 template<
typename... Args,
3352 std::vector<Expr> collected_args;
3362 GeneratorBase(
size_t size,
const void *introspection_helper);
3363 void set_generator_names(
const std::string ®istered_name,
const std::string &stub_name);
3435 template<
typename T>
3438 template<
typename T>
3494 std::unique_ptr<GeneratorParamInfo> param_info_ptr;
3496 std::string generator_registered_name, generator_stub_name;
3499 struct Requirement {
3501 std::vector<Expr> error_args;
3503 std::vector<Requirement> requirements;
3508 template<
typename T>
3509 T *find_by_name(
const std::string &
name,
const std::vector<T *> &v) {
3511 if (t->name() ==
name) {
3518 Internal::GeneratorInputBase *find_input_by_name(
const std::string &
name);
3519 Internal::GeneratorOutputBase *find_output_by_name(
const std::string &
name);
3521 void check_scheduled(
const char *m)
const;
3523 void build_params(
bool force =
false);
3528 void get_host_target();
3529 void get_jit_target_from_environment();
3530 void get_target_from_environment();
3532 void set_inputs_vector(
const std::vector<std::vector<StubInput>> &inputs);
3534 static void check_input_is_singular(Internal::GeneratorInputBase *in);
3535 static void check_input_is_array(Internal::GeneratorInputBase *in);
3542 template<
typename T,
int Dims>
3543 std::vector<StubInput> build_input(
size_t i,
const Buffer<T, Dims> &arg) {
3544 auto *in = param_info().
inputs().at(i);
3545 check_input_is_singular(in);
3546 const auto k = in->kind();
3549 StubInputBuffer<> sib(b);
3554 f(Halide::_) = arg(Halide::_);
3567 template<
typename T,
int Dims>
3568 std::vector<StubInput> build_input(
size_t i,
const GeneratorInput<Buffer<T, Dims>> &arg) {
3569 auto *in = param_info().
inputs().at(i);
3570 check_input_is_singular(in);
3571 const auto k = in->kind();
3573 StubInputBuffer<> sib = arg;
3587 std::vector<StubInput> build_input(
size_t i,
const Func &arg) {
3588 auto *in = param_info().
inputs().at(i);
3590 check_input_is_singular(in);
3597 std::vector<StubInput> build_input(
size_t i,
const std::vector<Func> &arg) {
3598 auto *in = param_info().
inputs().at(i);
3600 check_input_is_array(in);
3602 std::vector<StubInput> siv;
3603 siv.reserve(arg.size());
3604 for (
const auto &f : arg) {
3605 siv.emplace_back(f);
3611 std::vector<StubInput> build_input(
size_t i,
const Expr &arg) {
3612 auto *in = param_info().
inputs().at(i);
3614 check_input_is_singular(in);
3620 std::vector<StubInput> build_input(
size_t i,
const std::vector<Expr> &arg) {
3621 auto *in = param_info().
inputs().at(i);
3623 check_input_is_array(in);
3624 std::vector<StubInput> siv;
3625 siv.reserve(arg.size());
3626 for (
const auto &value : arg) {
3627 siv.emplace_back(value);
3634 template<
typename T,
3635 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3636 std::vector<StubInput> build_input(
size_t i,
const T &arg) {
3637 auto *in = param_info().
inputs().at(i);
3639 check_input_is_singular(in);
3647 template<
typename T,
3648 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3649 std::vector<StubInput> build_input(
size_t i,
const std::vector<T> &arg) {
3650 auto *in = param_info().
inputs().at(i);
3652 check_input_is_array(in);
3653 std::vector<StubInput> siv;
3654 siv.reserve(arg.size());
3655 for (
const auto &value : arg) {
3659 siv.emplace_back(e);
3664 template<
typename... Args,
size_t... Indices>
3665 std::vector<std::vector<StubInput>> build_inputs(
const std::tuple<const Args &...> &t, std::index_sequence<Indices...>) {
3666 return {build_input(Indices, std::get<Indices>(t))...};
3671 template<
typename T>
3672 static void get_arguments(std::vector<AbstractGenerator::ArgInfo> &args,
ArgInfoDirection dir,
const T &t) {
3674 args.push_back({e->name(),
3677 e->gio_types_defined() ? e->gio_types() : std::vector<Type>{},
3678 e->dims_defined() ? e->dims() : 0});
3684 std::string
name()
override;
3686 std::vector<ArgInfo>
arginfos()
override;
3698 void bind_input(
const std::string &
name,
const std::vector<Parameter> &v)
override;
3699 void bind_input(
const std::string &
name,
const std::vector<Func> &v)
override;
3700 void bind_input(
const std::string &
name,
const std::vector<Expr> &v)
override;
3702 bool emit_cpp_stub(
const std::string &stub_file_path)
override;
3703 bool emit_hlpipe(
const std::string &hlpipe_file_path)
override;
3715 static std::vector<std::string>
enumerate();
3722 using GeneratorFactoryMap = std::map<const std::string, GeneratorFactory>;
3724 GeneratorFactoryMap factories;
3752 auto g = std::make_unique<T>();
3753 g->init_from_context(
context);
3759 const std::string ®istered_name,
3760 const std::string &stub_name) {
3762 g->set_generator_names(registered_name, stub_name);
3766 template<
typename... Args>
3774 template<
typename T2>
3779 template<
typename T2,
typename... Args>
3780 inline std::unique_ptr<T2>
apply(
const Args &...args)
const {
3781 auto t = this->create<T2>();
3794 template<
typename T2,
typename =
void>
3795 struct has_configure_method : std::false_type {};
3797 template<
typename T2>
3798 struct has_configure_method<T2, typename type_sink<decltype(
std::declval<T2>().configure())>::type> : std::true_type {};
3800 template<
typename T2,
typename =
void>
3801 struct has_generate_method : std::false_type {};
3803 template<
typename T2>
3804 struct has_generate_method<T2, typename type_sink<decltype(
std::declval<T2>().generate())>::type> : std::true_type {};
3806 template<
typename T2,
typename =
void>
3807 struct has_schedule_method : std::false_type {};
3809 template<
typename T2>
3810 struct has_schedule_method<T2, typename type_sink<decltype(
std::declval<T2>().
schedule())>::type> : std::true_type {};
3819 t->call_generate_impl();
3820 t->call_schedule_impl();
3824 void call_configure_impl() {
3826 if constexpr (has_configure_method<T>::value) {
3828 static_assert(std::is_void<decltype(t->configure())>::value,
"configure() must return void");
3834 void call_generate_impl() {
3836 static_assert(has_generate_method<T>::value,
"Expected a generate() method here.");
3838 static_assert(std::is_void<decltype(t->generate())>::value,
"generate() must return void");
3843 void call_schedule_impl() {
3845 if constexpr (has_schedule_method<T>::value) {
3847 static_assert(std::is_void<decltype(t->schedule())>::value,
"schedule() must return void");
3856 return this->build_pipeline_impl();
3860 this->call_configure_impl();
3864 this->call_generate_impl();
3868 this->call_schedule_impl();
3874 friend class ::Halide::GeneratorContext;
3944 using CreateGeneratorFn = std::function<AbstractGeneratorPtr(const std::string &name, const GeneratorContext &context)>;
3977 const std::string &name,
3980 const std::string &name,
3990 struct halide_global_ns;
3993 #define _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) \ 3994 namespace halide_register_generator { \ 3995 struct halide_global_ns; \ 3996 namespace GEN_REGISTRY_NAME##_ns { \ 3997 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \ 3998 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context) { \ 3999 using GenType = std::remove_pointer<decltype(new GEN_CLASS_NAME)>::type; \ 4000 return GenType::create(context, #GEN_REGISTRY_NAME, #FULLY_QUALIFIED_STUB_NAME); \ 4004 auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \ 4007 static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \ 4008 "HALIDE_REGISTER_GENERATOR must be used at global scope"); 4010 #define _HALIDE_REGISTER_GENERATOR2(GEN_CLASS_NAME, GEN_REGISTRY_NAME) \ 4011 _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, GEN_REGISTRY_NAME) 4013 #define _HALIDE_REGISTER_GENERATOR3(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) \ 4014 _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) 4019 #define __HALIDE_REGISTER_ARGCOUNT_IMPL(_1, _2, _3, COUNT, ...) \ 4022 #define _HALIDE_REGISTER_ARGCOUNT_IMPL(ARGS) \ 4023 __HALIDE_REGISTER_ARGCOUNT_IMPL ARGS 4025 #define _HALIDE_REGISTER_ARGCOUNT(...) \ 4026 _HALIDE_REGISTER_ARGCOUNT_IMPL((__VA_ARGS__, 3, 2, 1, 0)) 4028 #define ___HALIDE_REGISTER_CHOOSER(COUNT) \ 4029 _HALIDE_REGISTER_GENERATOR##COUNT 4031 #define __HALIDE_REGISTER_CHOOSER(COUNT) \ 4032 ___HALIDE_REGISTER_CHOOSER(COUNT) 4034 #define _HALIDE_REGISTER_CHOOSER(COUNT) \ 4035 __HALIDE_REGISTER_CHOOSER(COUNT) 4037 #define _HALIDE_REGISTER_GENERATOR_PASTE(A, B) \ 4040 #define HALIDE_REGISTER_GENERATOR(...) \ 4041 _HALIDE_REGISTER_GENERATOR_PASTE(_HALIDE_REGISTER_CHOOSER(_HALIDE_REGISTER_ARGCOUNT(__VA_ARGS__)), (__VA_ARGS__)) 4057 #define HALIDE_REGISTER_GENERATOR_ALIAS(GEN_REGISTRY_NAME, ORIGINAL_REGISTRY_NAME, ...) \ 4058 namespace halide_register_generator { \ 4059 struct halide_global_ns; \ 4060 namespace ORIGINAL_REGISTRY_NAME##_ns { \ 4061 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \ 4063 namespace GEN_REGISTRY_NAME##_ns { \ 4064 std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context) { \ 4065 auto g = ORIGINAL_REGISTRY_NAME##_ns::factory(context); \ 4066 const Halide::GeneratorParamsMap m = __VA_ARGS__; \ 4067 g->set_generatorparam_values(m); \ 4072 auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \ 4075 static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \ 4076 "HALIDE_REGISTER_GENERATOR_ALIAS must be used at global scope"); 4081 #define HALIDE_GENERATOR_PYSTUB(GEN_REGISTRY_NAME, MODULE_NAME) \ 4082 static_assert(PY_MAJOR_VERSION >= 3, "Python bindings for Halide require Python 3+"); \ 4083 extern "C" PyObject *_halide_pystub_impl(const char *module_name, const Halide::Internal::GeneratorFactory &factory); \ 4084 namespace halide_register_generator::GEN_REGISTRY_NAME##_ns { \ 4085 extern std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \ 4087 extern "C" HALIDE_EXPORT_SYMBOL PyObject *PyInit_##MODULE_NAME() { \ 4088 const auto factory = halide_register_generator::GEN_REGISTRY_NAME##_ns::factory; \ 4089 return _halide_pystub_impl(#MODULE_NAME, factory); \ 4092 #endif // HALIDE_GENERATOR_H_
GeneratorOutput(const std::string &name, const Type &t, int d)
std::vector< Range > Region
A multi-dimensional box.
std::vector< Func > output_func(const std::string &name) override
Given the name of an output, return the Func(s) for that output.
std::vector< Type > parse_halide_type_list(const std::string &types)
enum Halide::Internal::ExecuteGeneratorArgs::BuildMode build_mode
Create a small array of Exprs for defining and calling functions with multiple outputs.
GeneratorOutput_Arithmetic(const std::string &name)
void set_inputs(const Args &...args)
set_inputs is a variadic wrapper around set_inputs_vector, which makes usage much simpler in many cas...
void set_type(const Type &type)
Expr max(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
const std::vector< Func > & funcs() const
GeneratorOutput< T > & operator=(Buffer< T2, D2 > &buffer)
GeneratorOutput(const std::string &name, const std::vector< Type > &t)
#define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE)
std::string get_c_type() const override
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...
Func & operator[](size_t i)
A reference to a site in a Halide statement at the top of the body of a particular for loop...
void set_dimensions(int dims)
GeneratorOutput_Func(const std::string &name, const std::vector< Type > &t)
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...
static constexpr bool value
GeneratorContext is a class that is used when using Generators (or Stubs) directly; it is used to all...
A fragment of Halide syntax.
virtual void call_configure()=0
StubOutputBuffer is the placeholder that a Stub uses when it requires a Buffer for an output (rather ...
std::string get_c_type() const override
HALIDE_NO_USER_CODE_INLINE T2 as() const
std::string get_default_value() const override
A class representing a Halide pipeline.
void check_value_writable() const
GeneratorOutput_Func(size_t array_size, const std::string &name, const std::vector< Type > &t, int d)
void set_generatorparam_value(const std::string &name, const std::string &value) override
Set the value for a specific GeneratorParam for an AbstractGenerator instance.
const Func & operator[](size_t i) const
std::vector< std::string > suffixes
virtual bool is_looplevel_param() const
GeneratorOutput_Buffer(size_t array_size, const std::string &name, int d)
GeneratorBase * generator
void call_schedule() override
virtual void check_value_writable() const =0
static Type Int(int bits, int lanes=1)
Generator & operator=(const Generator &)=delete
GeneratorOutput(size_t array_size, const std::string &name, const Type &t, int d)
GeneratorOutput_Arithmetic(size_t array_size, const std::string &name)
std::vector< Expr > exprs_
Func in(const Func &f)
Creates and returns a new identity Func that wraps this Func.
StubOutputBuffer()=default
GeneratorContext()=default
HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector< Expr > &args)
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
A Realization is a vector of references to existing Buffer objects.
GeneratorOutput_Func< T > & set_estimate(const Var &var, const Expr &min, const Expr &extent)
std::string call_to_string(const std::string &v) const override
const std::vector< Type > & types() const
Get the type(s) of the outputs of this Func.
auto max(const GeneratorParam< T > &a, const Other &b) -> decltype(Internal::GeneratorMinMax::max_forward(a, b))
Compute the maximum value between GeneratorParam<T> and any type that supports max with T...
int dimensions() const
The dimensionality (number of arguments) of this function.
const std::string & name() const
Partition
Different ways to handle loops with a potentially optimizable boundary conditions.
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!= with T...
void execute_generator(const ExecuteGeneratorArgs &args)
Execute a Generator for AOT compilation – this provides the implementation of the command-line Gene...
void set_from_string(const std::string &new_value_string) override
GIOBase is the base class for all GeneratorInput<> and GeneratorOutput<> instantiations; it is not pa...
GeneratorParam_Enum(const std::string &name, const T &value, const std::map< std::string, T > &enum_map)
GeneratorContext context() const override
Return the Target and autoscheduler info that this Generator was created with.
~GeneratorBase() override
Func operator[](size_t i)
void set(const LoopLevel &other)
Mutate our contents to match the contents of 'other'.
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...
GeneratorParam_AutoSchedulerParams()
TailStrategy
Different ways to handle a tail case in a split when the factor does not provably divide the extent...
GIOBase(size_t array_size, const std::string &name, ArgInfoKind kind, const std::vector< Type > &types, int dims)
GeneratorOutput(const char *name)
GeneratorContext with_target(const Target &t) const
GeneratorOutput_Buffer(const std::string &name, const std::vector< Type > &t, int d)
std::string name() override
Return the name of this Generator.
A struct representing a target machine and os to generate code for.
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
std::function< AbstractGeneratorPtr(const GeneratorContext &context)> GeneratorFactory
Halide::LoopLevel LoopLevel
std::string call_to_string(const std::string &v) const override
A reference-counted handle to a parameter to a halide pipeline.
void set_buffer(const Buffer< void > &b)
If the parameter is a buffer parameter, set its current value.
#define internal_assert(c)
virtual bool is_synthetic_param() const
virtual std::string get_default_value() const =0
Defines methods for introspecting in C++.
std::string get_default_value() const override
A Halide variable, to be used when defining functions.
Target get_target() const
GeneratorOutput(const std::string &name, const std::vector< Type > &t, int d)
GeneratorFactoryProvider provides a way to customize the Generators that are visible to generate_filt...
GeneratorInput< T > * add_input(const std::string &name)
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...
static TO2 value(const FROM &from)
bool defined() const
Does this function have at least a pure definition.
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())
auto min(const GeneratorParam< T > &a, const Other &b) -> decltype(Internal::GeneratorMinMax::min_forward(a, b))
Compute minimum between GeneratorParam<T> and any type that supports min with T.
signed __INT8_TYPE__ int8_t
void set_estimate(Expr e)
Get and set constraints for scalar parameters.
std::string array_name(size_t i) const
AbstractGenerator is an ABC that defines the API a Generator must provide to work with the existing G...
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.
GeneratorOutput(size_t array_size, const std::string &name)
std::unique_ptr< T > apply(const Args &...args) const
A fragment of front-end syntax of the form f(x, y, z), where x, y, z are Vars or Exprs.
Realization realize(Args &&...args)
GeneratorOutput(size_t array_size, const std::string &name, const std::vector< Type > &t, int d)
GeneratorParamsMap generator_params
GeneratorOutput(size_t array_size, const std::string &name, int d)
const Func & operator[](size_t i) const
void add_requirement(const Expr &condition, const std::vector< Expr > &error_args)
Expr cast(Expr a)
Cast an expression to the halide type corresponding to the C++ type T.
void set_max_value(const Expr &e)
Get and set constraints for scalar parameters.
friend class StubOutputBufferBase
GeneratorOutput_Buffer(const std::string &name)
GeneratorOutput< T > * add_output(const std::string &name)
virtual std::string call_to_string(const std::string &v) const =0
This file defines the class FunctionDAG, which is our representation of a Halide pipeline, and contains methods to using Halide's bounds tools to query properties of it.
virtual void call_generate()=0
virtual void verify_internals()
std::string function_name
friend class GeneratorOutputBase
GeneratorOutput_Buffer(const std::string &name, const std::vector< Type > &t)
virtual void set_impl(const T &new_value)
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...
std::string get_default_value() const override
T parse_scalar(const std::string &value)
RegisterGenerator(const char *registered_name, GeneratorFactory generator_factory)
std::set< OutputFileType > output_types
unsigned __INT8_TYPE__ uint8_t
Defines the structure that describes a Halide target.
static void register_factory(const std::string &name, GeneratorFactory generator_factory)
GeneratorOutput_Func(const std::string &name, const std::vector< Type > &t, int d)
void set_from_string(const std::string &new_value_string) override
CreateGeneratorFn create_generator
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...
typename std::remove_all_extents< T >::type TBase
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.
HALIDE_NO_USER_CODE_INLINE std::string get_c_type() const override
Forward schedule-related methods to the underlying Func.
GeneratorOutput_Buffer< T > & set_estimates(const Region &estimates)
void check_matching_array_size(size_t size) const
bool using_autoscheduler() const
std::vector< ValueType >::const_iterator begin() const
Defines Func - the front-end handle on a halide function, and related classes.
std::shared_ptr< AbstractGenerator > generator
HALIDE_NO_USER_CODE_INLINE std::string enum_to_string(const std::map< std::string, T > &enum_map, const T &t)
friend class GeneratorParamBase
virtual std::string get_c_type() const
Forward schedule-related methods to the underlying Func.
std::string get_c_type() const override
const void * get_introspection_helper()
Return the address of a global with type T *.
const std::vector< Internal::GeneratorParamBase * > & generator_params() const
virtual std::string get_c_type() const =0
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 ...
const char * input_or_output() const override
Forward schedule-related methods to the underlying Func.
void resize(size_t size)
Forward schedule-related methods to the underlying Func.
GeneratorOutput< T > * add_output(const std::string &name, const Type &t, int dimensions)
typename std::conditional< First::value, typename First::type, void >::type type
std::unique_ptr< T2 > apply(const Args &...args) const
void set_from_string(const std::string &new_value_string) override
std::string halide_type_to_c_source(const Type &t)
const std::vector< ElemType > & get_values() const
Realization realize(std::vector< int32_t > sizes)
const std::vector< Internal::GeneratorOutputBase * > & outputs() const
const std::string & name() const
void check_gio_access() const
GeneratorParamBase(const std::string &name)
std::string get_default_value() const override
GeneratorParam_LoopLevel(const std::string &name, const LoopLevel &value)
std::map< std::string, std::string > GeneratorParamsMap
void set_from_string(const std::string &new_value_string) override
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...
HALIDE_ALWAYS_INLINE Type type() const
Get the type of this expression node.
GeneratorBase(size_t size, const void *introspection_helper)
GeneratorOutput_Buffer(const std::string &name, int d)
std::string call_to_string(const std::string &v) const override
std::string call_to_string(const std::string &v) const override
GeneratorParam(const std::string &name, const std::string &value)
GeneratorOutput_Buffer< T > & operator=(const Func &f)
HALIDE_NO_USER_CODE_INLINE T2 as() const
bool dims_defined() const
friend class GeneratorParamInfo
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
static void unregister_factory(const std::string &name)
static LoopLevel root()
Construct a special LoopLevel value which represents the location outside of all for loops...
GeneratorOutput_Func< T > & operator=(const Func &f)
void check_matching_dims(int d) const
Halide::GeneratorContext GeneratorContext
typename Super::TBase TBase
friend class StubEmitter
Forward schedule-related methods to the underlying Func.
std::vector< Func > funcs_
GeneratorOutput< T > * add_output(const std::string &name, int dimensions)
Expr make_const(Type t, int64_t val)
Construct an immediate of the given type from any numeric C++ type.
std::unique_ptr< T > create() const
const ValueType & at(size_t i) const
std::vector< Target > targets
void apply(const Args &...args)
GeneratorOutput_Buffer(size_t array_size, const std::string &name)
GeneratorInput< T > * add_input(const std::string &name, const Type &type)
std::string get_c_type() const override
friend class GeneratorStub
A handle on the output buffer of a pipeline.
void set_from_string(const std::string &new_value_string) override
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
const GeneratorFactoryProvider & get_registered_generators()
Return a GeneratorFactoryProvider that knows about all the currently-registered C++ Generators...
void ensure_configure_has_been_called()
GeneratorInput< T > * add_input(const std::string &name, int dimensions)
std::string halide_type_to_enum_string(const Type &t)
void fail_wrong_type(const char *type)
static std::vector< StubOutputBuffer< T > > to_output_buffers(const std::vector< Func > &v, const std::shared_ptr< AbstractGenerator > &gen)
void set_min_value(const Expr &e)
Get and set constraints for scalar parameters.
unsigned __INT32_TYPE__ uint32_t
std::string call_to_string(const std::string &v) const override
std::string get_default_value() const override
GeneratorParam_String(const std::string &name, const std::string &value)
auto min_forward(const Other &a, const GeneratorParam< T > &b) -> decltype(min(a,(T) b))
void check_min_phase(Phase expected_phase) const
const ValueType & operator[](size_t i) const
virtual ~GIOBase()=default
virtual std::string get_type_decls() const
#define HALIDE_NO_USER_CODE_INLINE
std::string call_to_string(const std::string &v) const override
Not visible externally, similar to 'static' linkage in C.
Target get_target() const
void set_array_size(int size)
Expr reinterpret(Type t, Expr e)
Reinterpret the bits of one value as another type.
int dimensions() const
Get the dimensionality of this parameter.
bool allow_out_of_order_inputs_and_outputs() const override
By default, a Generator must declare all Inputs before all Outputs.
Provides a single global registry of Generators, GeneratorParams, and Params indexed by this pointer...
const std::string & name() const
The name of this function, either given during construction, or automatically generated.
void init_internals()
Forward schedule-related methods to the underlying Func.
signed __INT64_TYPE__ int64_t
std::string halide_type_to_c_type(const Type &t)
void advance_phase(Phase new_phase)
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.
static std::unique_ptr< T > create(const Halide::GeneratorContext &context, const std::string ®istered_name, const std::string &stub_name)
Type Bool(int lanes=1)
Construct a boolean type.
void set_from_string(const std::string &new_value_string) override
GeneratorParam_Bool(const std::string &name, const T &value)
std::string file_base_name
const std::vector< Internal::GeneratorInputBase * > & inputs() const
auto operator!(const GeneratorParam< T > &a) -> decltype(!(T) a)
Not operator for GeneratorParam.
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.
GeneratorOutput_Func(const std::string &name, int d)
auto max_forward(const Other &a, const GeneratorParam< T > &b) -> decltype(max(a,(T) b))
int natural_vector_size(const Halide::Type &t) const
Given a data type, return an estimate of the "natural" vector size for that data type when compiling ...
GeneratorParamBase & operator=(const GeneratorParamBase &)=delete
int natural_vector_size() const
Given a data type, return an estimate of the "natural" vector size for that data type when compiling ...
static std::vector< std::string > enumerate()
FuncRef operator()(Args &&...args) const
bool emit_cpp_stub(const std::string &stub_file_path) override
Emit a Generator Stub (.stub.h) file to the given path.
Special the Autoscheduler to be used (if any), along with arbitrary additional arguments specific to ...
GeneratorOutput< T > & operator=(const Func &f)
GeneratorOutput(const std::string &name)
PrefetchBoundStrategy
Different ways to handle accesses outside the original extents in a prefetch.
ExecuteGeneratorArgs is the set of arguments to execute_generator().
enum Halide::Internal::GeneratorBase::Phase Created
#define HALIDE_ALWAYS_INLINE
bool is_array() const override
std::function< AbstractGeneratorPtr(const std::string &name, const GeneratorContext &context)> CreateGeneratorFn
GeneratorOutput(const std::string &name, int d)
HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...error_args)
std::unique_ptr< T2 > create() const
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 ...
static LoopLevel inlined()
Construct a special LoopLevel value that implies that a function should be inlined away...
Realization realize(std::vector< int32_t > sizes={}, const Target &target=Target())
See Func::realize.
std::string get_default_value() const override
GeneratorOutput(const std::string &name, const Type &t)
void check_matching_types(const std::vector< Type > &t) const
void call_generate() override
HALIDE_NO_USER_CODE_INLINE GeneratorOutput_Buffer< T > & operator=(Buffer< T2, D2 > &buffer)
std::vector< Parameter > input_parameter(const std::string &name) override
Given the name of an input, return the Parameter(s) for that input.
const std::vector< Type > & gio_types() const
void trace_pipeline()
Generate begin_pipeline and end_pipeline tracing calls for this pipeline.
GeneratorOutput_Buffer(size_t array_size, const std::string &name, const std::vector< Type > &t, int d)
const std::map< std::string, Halide::Type > & get_halide_type_enum_map()
void set_default_value(const Expr &e)
Get and set the default values for scalar parameters.
std::string call_to_string(const std::string &v) const override
GeneratorParam_Type(const std::string &name, const T &value)
static Type Float(int bits, int lanes=1)
GeneratorFactoryProvider()=default
Type UInt(int bits, int lanes=1)
Constructing an unsigned integer type.
A reference-counted handle to Halide's internal representation of a function.
GeneratorParamImpl(const std::string &name, const T &value)
std::string get_default_value() const override
bool is_synthetic_param() const override
std::vector< Expr > parameter_constraints(const Parameter &p)
Realization realize(std::vector< int32_t > sizes)
An Image parameter to a halide pipeline.
unsigned __INT16_TYPE__ uint16_t
An argument to an extern-defined Func.
Types in the halide type system.
Pipeline build_pipeline() override
Build and return the Pipeline for this AbstractGenerator.
CompilerLoggerFactory compiler_logger_factory
GeneratorParam(const std::string &name, const T &value)
#define HALIDE_FORWARD_METHOD(Class, Method)
std::string get_default_value() const override
void call_configure() override
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.
GeneratorOutput_Func(const std::string &name)
GeneratorParam_Target(const std::string &name, const T &value)
NameMangling
An enum to specify calling convention for extern stages.
std::string call_to_string(const std::string &v) const override
void set_from_string(const std::string &new_value_string) override
std::string call_to_string(const std::string &v) const override
std::string get_default_value() const override
virtual void set_from_string(const std::string &value_string)=0
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.
GeneratorContext & operator=(const GeneratorContext &)=default
void realize(Realization r)
void check_exact_phase(Phase expected_phase) const
GeneratorOutput_Func< T > & set_estimates(const Region &estimates)
std::vector< ArgInfo > arginfos() override
Return a list of all the ArgInfos for this generator.
virtual void call_schedule()=0
GeneratorOutputBase(size_t array_size, const std::string &name, ArgInfoKind kind, const std::vector< Type > &t, int d)
Forward schedule-related methods to the underlying Func.
GeneratorParam(const std::string &name, const T &value, const std::map< std::string, T > &enum_map)
Halide::Pipeline Pipeline
Helper class for identifying purpose of an Expr passed to memoize.
std::string get_c_type() const override
HALIDE_ALWAYS_INLINE bool defined() const
GeneratorParam is a templated class that can be used to modify the behavior of the Generator at code-...
virtual bool is_array() const
GeneratorBase & operator=(const GeneratorBase &)=delete
GeneratorOutput< T > & operator=(const Internal::StubOutputBuffer< T2 > &stub_output_buffer)
A single definition of a Func.
T enum_from_string(const std::map< std::string, T > &enum_map, const std::string &s)
std::string generator_name
GeneratorParam_AutoSchedulerParams autoscheduler_
const AutoschedulerParams & autoscheduler_params() const
GeneratorOutputImpl(const std::string &name, ArgInfoKind kind, const std::vector< Type > &t, int d)
A reduction variable represents a single dimension of a reduction domain (RDom).
GeneratorOutput(size_t array_size, const std::string &name, const Type &t)
A multi-dimensional domain over which to iterate.
std::string get_type_decls() const override
virtual ~GeneratorParamBase()
bool defined() const
Check if this Buffer refers to an existing Buffer.
A scalar parameter to a halide pipeline.
int generate_filter_main(int argc, char **argv)
generate_filter_main() is a convenient wrapper for GeneratorRegistry::create() + compile_to_files(); ...
bool emit_hlpipe(const std::string &hlpipe_file_path) override
Emit a Serialized Halide Pipeline (.hlpipe) file to the given path.
GeneratorRegistry & operator=(const GeneratorRegistry &)=delete
std::string get_c_type() const override
~GeneratorOutputBase() override
Forward schedule-related methods to the underlying Func.
Realization realize(Args &&...args)
Classes for declaring image parameters to halide pipelines.
GeneratorParam(const std::string &name, const T &value, const T &min, const T &max)
GeneratorOutput_Buffer< T > & operator=(const StubOutputBuffer< T2 > &stub_output_buffer)
void set_from_string(const std::string &new_value_string) override
static Type Bool(int lanes=1)
static Expr cast(Halide::Type t, Expr e)
static Type UInt(int bits, int lanes=1)
unsigned __INT64_TYPE__ uint64_t
FuncRef operator()(std::vector< ExprOrVar > args) const
GeneratorOutput(size_t array_size, const std::string &name, const std::vector< Type > &t)
const std::vector< Expr > & exprs() const
GeneratorInput< T > * add_input(const std::string &name, const Type &t, int dimensions)
virtual const char * input_or_output() const =0
virtual std::vector< std::string > enumerate() const =0
Return a list of all registered Generators that are available for use with the create() method...
std::string get_c_type() const override
void check_value_writable() const override
Forward schedule-related methods to the underlying Func.
std::function< std::unique_ptr< Internal::CompilerLogger >(const std::string &fn_name, const Target &target)> CompilerLoggerFactory
GIOBase & operator=(const GIOBase &)=delete
bool gio_types_defined() const
std::string get_c_type() const override
size_t array_size() const
const Target & target() const
friend class GeneratorInputBase
Type type() const
Get the type of this parameter.
static AbstractGeneratorPtr create(const std::string &name, const Halide::GeneratorContext &context)
void set_impl(const T &new_value) override
signed __INT32_TYPE__ int32_t
bool is_looplevel_param() const override
GeneratorOutput_Buffer(size_t array_size, const std::string &name, const std::vector< Type > &t)
GeneratorParam< Target > target
void set_generator_names(const std::string ®istered_name, const std::string &stub_name)
void check_value_readable() const
#define HALIDE_FORWARD_METHOD_CONST(Class, Method)
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
virtual void init_from_context(const Halide::GeneratorContext &context)
std::unique_ptr< AbstractGenerator > AbstractGeneratorPtr
Type type() const
Does the same thing as the equivalent Halide::Runtime::Buffer method.
Realization realize(std::vector< int32_t > sizes={}, const Target &target=Target())
Evaluate this function over some rectangular domain and return the resulting buffer or buffers...
signed __INT16_TYPE__ int16_t
bool array_size_defined() const
GeneratorParamInfo(GeneratorBase *generator, size_t size)
virtual ~GeneratorFactoryProvider()=default
std::vector< ValueType >::const_iterator end() const
std::vector< Type > types_
std::string get_type_decls() const override
GeneratorFactoryProvider & operator=(const GeneratorFactoryProvider &)=delete
static std::unique_ptr< T > create(const Halide::GeneratorContext &context)
Type Float(int bits, int lanes=1)
Construct a floating-point type.
std::string get_c_type() const override
MemoryType
An enum describing different address spaces to be used with Func::store_in.