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."
296 for (
const auto &key_value : enum_map) {
297 if (t == key_value.second) {
298 return key_value.first;
301 user_error <<
"Enumeration value not found.\n";
307 auto it = enum_map.find(s);
308 user_assert(it != enum_map.end()) <<
"Enumeration value not found: " << s <<
"\n";
344 template<
bool B,
typename T>
350 template<
typename First,
typename... Rest>
351 struct select_type : std::conditional<First::value, typename First::type, typename select_type<Rest...>::type> {};
353 template<
typename First>
354 struct select_type<First> {
using type =
typename std::conditional<First::value, typename First::type, void>::type; };
364 inline const std::string &
name()
const {
376 #define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE) \
377 virtual void set(const TYPE &new_value) = 0;
395 #undef HALIDE_GENERATOR_PARAM_TYPED_SETTER
398 void set(
const std::string &new_value) {
401 void set(
const char *new_value) {
436 const std::string name_;
453 template<
typename FROM,
typename TO>
455 template<typename TO2 = TO, typename std::enable_if<!std::is_same<TO2, bool>::value>::type * =
nullptr>
456 inline static TO2
value(
const FROM &from) {
457 return static_cast<TO2
>(from);
460 template<typename TO2 = TO, typename std::enable_if<std::is_same<TO2, bool>::value>::type * =
nullptr>
461 inline static TO2
value(
const FROM &from) {
481 return this->
value();
488 #define HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE) \
489 void set(const TYPE &new_value) override { \
490 typed_setter_impl<TYPE>(new_value, #TYPE); \
509 #undef HALIDE_GENERATOR_PARAM_TYPED_SETTER
512 void set(
const std::string &new_value) {
528 template<
typename FROM,
typename std::enable_if<
529 !std::is_convertible<FROM, T>::value>
::type * =
nullptr>
535 template<
typename FROM,
typename std::enable_if<
536 std::is_same<FROM, T>::value>
::type * =
nullptr>
543 template<
typename FROM,
typename std::enable_if<
544 !std::is_same<FROM, T>::value &&
545 std::is_convertible<FROM, T>::value &&
546 std::is_convertible<T, FROM>::value>
::type * =
nullptr>
551 if (value2 !=
value) {
558 template<
typename FROM,
typename std::enable_if<
559 !std::is_same<FROM, T>::value &&
560 std::is_convertible<FROM, T>::value &&
561 !std::is_convertible<T, FROM>::value>
::type * =
nullptr>
585 return this->
value().to_string();
589 std::ostringstream oss;
590 oss << v <<
".to_string()";
611 return this->
value().to_string();
615 std::ostringstream oss;
616 oss << v <<
".to_string()";
621 return "MachineParams";
654 if (new_value_string ==
"root") {
656 }
else if (new_value_string ==
"inlined") {
659 user_error <<
"Unable to parse " << this->
name() <<
": " << new_value_string;
676 return "LoopLevel::inlined()";
678 return "LoopLevel::root()";
687 return std::string();
704 const T &min = std::numeric_limits<T>::lowest(),
712 user_assert(new_value >= min && new_value <= max) <<
"Value out of range: " << new_value;
717 std::istringstream iss(new_value_string);
722 if (
sizeof(T) ==
sizeof(
char) && !std::is_same<T, bool>::value) {
729 user_assert(!iss.fail() && iss.get() == EOF) <<
"Unable to parse: " << new_value_string;
734 std::ostringstream oss;
735 oss << this->
value();
736 if (std::is_same<T, float>::value) {
739 if (oss.str().find(
'.') == std::string::npos) {
748 std::ostringstream oss;
749 oss <<
"std::to_string(" << v <<
")";
754 std::ostringstream oss;
755 if (std::is_same<T, float>::value) {
757 }
else if (std::is_same<T, double>::value) {
759 }
else if (std::is_integral<T>::value) {
760 if (std::is_unsigned<T>::value) {
763 oss <<
"int" << (
sizeof(T) * 8) <<
"_t";
784 if (new_value_string ==
"true" || new_value_string ==
"True") {
786 }
else if (new_value_string ==
"false" || new_value_string ==
"False") {
789 user_assert(
false) <<
"Unable to parse bool: " << new_value_string;
795 return this->
value() ?
"true" :
"false";
799 std::ostringstream oss;
800 oss <<
"std::string((" << v <<
") ? \"true\" : \"false\")";
819 template<typename T2 = T, typename std::enable_if<!std::is_same<T2, Type>::value>
::type * =
nullptr>
825 auto it = enum_map.find(new_value_string);
826 user_assert(it != enum_map.end()) <<
"Enumeration value not found: " << new_value_string;
831 return "Enum_" + this->
name() +
"_map().at(" + v +
")";
835 return "Enum_" + this->
name();
843 std::ostringstream oss;
844 oss <<
"enum class Enum_" << this->
name() <<
" {\n";
845 for (
auto key_value : enum_map) {
846 oss <<
" " << key_value.first <<
",\n";
853 oss <<
"inline HALIDE_NO_USER_CODE_INLINE const std::map<Enum_" << this->
name() <<
", std::string>& Enum_" << this->
name() <<
"_map() {\n";
854 oss <<
" static const std::map<Enum_" << this->
name() <<
", std::string> m = {\n";
855 for (
auto key_value : enum_map) {
856 oss <<
" { Enum_" << this->
name() <<
"::" << key_value.first <<
", \"" << key_value.first <<
"\"},\n";
859 oss <<
" return m;\n";
865 const std::map<std::string, T> enum_map;
876 return "Halide::Internal::halide_type_to_enum_string(" + v +
")";
899 this->
set(new_value_string);
903 return "\"" + this->
value() +
"\"";
911 return "std::string";
963 template<typename T2 = T, typename std::enable_if<!std::is_same<T2, std::string>::value>::type * =
nullptr>
972 GeneratorParam(
const std::string &name,
const T &value,
const std::map<std::string, T> &enum_map)
984 template<
typename Other,
typename T>
988 template<
typename Other,
typename T>
997 template<
typename Other,
typename T>
1001 template<
typename Other,
typename T>
1010 template<
typename Other,
typename T>
1014 template<
typename Other,
typename T>
1023 template<
typename Other,
typename T>
1027 template<
typename Other,
typename T>
1036 template<
typename Other,
typename T>
1040 template<
typename Other,
typename T>
1049 template<
typename Other,
typename T>
1053 template<
typename Other,
typename T>
1062 template<
typename Other,
typename T>
1066 template<
typename Other,
typename T>
1075 template<
typename Other,
typename T>
1079 template<
typename Other,
typename T>
1088 template<
typename Other,
typename T>
1092 template<
typename Other,
typename T>
1101 template<
typename Other,
typename T>
1105 template<
typename Other,
typename T>
1114 template<
typename Other,
typename T>
1118 template<
typename Other,
typename T>
1127 template<
typename Other,
typename T>
1131 template<
typename Other,
typename T>
1135 template<
typename T>
1137 return (T)a && (T)b;
1144 template<
typename Other,
typename T>
1148 template<
typename Other,
typename T>
1152 template<
typename T>
1154 return (T)a || (T)b;
1162 namespace Internal {
1163 namespace GeneratorMinMax {
1168 template<
typename Other,
typename T>
1170 return min(a, (T)b);
1172 template<
typename Other,
typename T>
1174 return min((T)a, b);
1177 template<
typename Other,
typename T>
1179 return max(a, (T)b);
1181 template<
typename Other,
typename T>
1183 return max((T)a, b);
1192 template<
typename Other,
typename T>
1196 template<
typename Other,
typename T>
1205 template<
typename Other,
typename T>
1209 template<
typename Other,
typename T>
1216 template<
typename T>
1221 namespace Internal {
1223 template<
typename T2>
1224 class GeneratorInput_Buffer;
1242 template<
typename T2>
1256 template<
typename T2,
int D2>
1272 template<
typename T2,
int D2>
1274 : parameter_(parameter_from_buffer(b)) {
1292 template<
typename... Args>
1298 template<
typename Dst>
1317 template<
typename T =
void>
1319 template<
typename T2>
1343 template<
typename T2>
1345 : kind_(
IOKind::
Buffer), parameter_(b.parameter_), func_(), expr_() {
1351 : kind_(
IOKind::
Scalar), parameter_(), func_(), expr_(e) {
1422 const std::string &
name,
1424 const std::vector<Type> &
types,
1457 template<
typename ElemType>
1467 template<
typename T>
1478 inline const std::vector<Expr> &GIOBase::get_values<Expr>()
const {
1483 inline const std::vector<Func> &GIOBase::get_values<Func>()
const {
1490 const std::string &
name,
1492 const std::vector<Type> &t,
1528 template<
typename T,
typename ValueType>
1531 using TBase =
typename std::remove_all_extents<T>::type;
1534 return std::is_array<T>::value;
1537 template<
typename T2 = T,
typename std::enable_if<
1539 !std::is_array<T2>::value>
::type * =
nullptr>
1544 template<
typename T2 = T,
typename std::enable_if<
1546 std::is_array<T2>::value && std::rank<T2>::value == 1 && (std::extent<T2, 0>::value > 0)>::
type * =
nullptr>
1551 template<
typename T2 = T,
typename std::enable_if<
1553 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>
::type * =
nullptr>
1559 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1562 return get_values<ValueType>().size();
1565 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1568 return get_values<ValueType>()[i];
1571 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1572 const ValueType &
at(
size_t i)
const {
1574 return get_values<ValueType>().at(i);
1577 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1578 typename std::vector<ValueType>::const_iterator
begin()
const {
1580 return get_values<ValueType>().begin();
1583 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1584 typename std::vector<ValueType>::const_iterator
end()
const {
1586 return get_values<ValueType>().end();
1598 #define HALIDE_FORWARD_METHOD(Class, Method) \
1599 template<typename... Args> \
1600 inline auto Method(Args &&...args)->typename std::remove_reference<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))>::type { \
1601 return this->template as<Class>().Method(std::forward<Args>(args)...); \
1604 #define HALIDE_FORWARD_METHOD_CONST(Class, Method) \
1605 template<typename... Args> \
1606 inline auto Method(Args &&...args) const-> \
1607 typename std::remove_reference<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))>::type { \
1608 this->check_gio_access(); \
1609 return this->template as<Class>().Method(std::forward<Args>(args)...); \
1612 template<
typename T>
1620 friend class ::Halide::Func;
1621 friend class ::Halide::Stage;
1624 if (TBase::has_static_halide_type) {
1625 return "Halide::Internal::StubInputBuffer<" +
1629 return "Halide::Internal::StubInputBuffer<>";
1633 template<
typename T2>
1641 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
1642 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
1647 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Input<Buffer<T>> if T is void or omitted.");
1648 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Input<Buffer<T, D>> if D is -1 or omitted.");
1653 static_assert(!TBase::has_static_halide_type,
"You can only specify a Type argument for Input<Buffer<T>> if T is void or omitted.");
1658 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
1660 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Input<Buffer<T, D>> if D is -1 or omitted.");
1663 template<
typename... Args>
1666 return Func(*
this)(std::forward<Args>(args)...);
1671 return Func(*
this)(std::move(args));
1674 template<
typename T2>
1676 user_assert(!this->
is_array()) <<
"Cannot assign an array type to a non-array type for Input " << this->
name();
1682 return this->
funcs().at(0);
1709 return Func(*this).
in(other);
1714 return Func(*this).
in(others);
1719 user_assert(!this->
is_array()) <<
"Cannot convert an Input<Buffer<>[]> to an ImageParam; use an explicit subscript operator: " << this->
name();
1723 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1729 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1735 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1741 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1742 typename std::vector<ImageParam>::const_iterator
begin()
const {
1743 user_error <<
"Input<Buffer<>>::begin() is not supported.";
1747 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
1748 typename std::vector<ImageParam>::const_iterator
end()
const {
1749 user_error <<
"Input<Buffer<>>::end() is not supported.";
1773 template<
typename T>
1785 template<
typename T2>
1829 template<
typename... Args>
1832 return this->
funcs().at(0)(std::forward<Args>(args)...);
1837 return this->
funcs().at(0)(args);
1842 return this->
funcs().at(0);
1869 return Func(*this).
in(other);
1874 return Func(*this).
in(others);
1895 template<
typename T>
1900 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");
1910 user_assert(!std::is_array<T>::value) <<
"Input<Expr[]> is not allowed";
1917 return this->
exprs().at(0);
1935 template<
typename T>
1959 template<typename TBase2 = TBase, typename std::enable_if<!std::is_pointer<TBase2>::value>
::type * =
nullptr>
1961 return cast<TBase>(
Expr(value));
1964 template<typename TBase2 = TBase, typename std::enable_if<std::is_pointer<TBase2>::value>
::type * =
nullptr>
1966 user_assert(value == 0) <<
"Zero is the only legal default value for Inputs which are pointer types.\n";
1980 const std::string &
name)
1985 const std::string &
name,
1994 return this->
exprs().at(0);
2004 template<typename T2 = T, typename std::enable_if<std::is_pointer<T2>::value>
::type * =
nullptr>
2007 user_assert(value ==
nullptr) <<
"nullptr is the only valid estimate for Input<PointerType>";
2014 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value && !std::is_pointer<T2>::value>
::type * =
nullptr>
2018 if (std::is_same<T2, bool>::value) {
2026 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2030 if (std::is_same<T2, bool>::value) {
2037 template<
typename T>
2050 if (!std::is_same<TBase, bool>::value) {
2073 const std::string &
name)
2078 const std::string &
name,
2091 const std::string &
name,
2102 template<
typename T2,
typename =
void>
2105 template<
typename T2>
2108 template<typename T, typename TBase = typename std::remove_all_extents<T>::type>
2119 template<
typename T>
2146 : Super(name, def) {
2150 : Super(array_size, name, def) {
2155 : Super(name, def,
min,
max) {
2160 : Super(array_size, name, def,
min,
max) {
2164 : Super(name, t, d) {
2177 : Super(array_size, name, t, d) {
2181 : Super(array_size, name, t) {
2187 : Super(array_size, name, d) {
2191 : Super(array_size, name) {
2195 namespace Internal {
2199 template<typename T2, typename std::enable_if<std::is_same<T2, Func>::value>
::type * =
nullptr>
2201 static_assert(std::is_same<T2, Func>::value,
"Only Func allowed here");
2204 user_assert(
funcs_.size() == 1) <<
"Use [] to access individual Funcs in Output<Func[]>";
2266 #undef HALIDE_OUTPUT_FORWARD
2267 #undef HALIDE_OUTPUT_FORWARD_CONST
2271 const std::string &
name,
2273 const std::vector<Type> &t,
2278 const std::vector<Type> &t,
2301 template<
typename T>
2304 using TBase =
typename std::remove_all_extents<T>::type;
2308 return std::is_array<T>::value;
2311 template<
typename T2 = T,
typename std::enable_if<
2313 !std::is_array<T2>::value>
::type * =
nullptr>
2318 template<
typename T2 = T,
typename std::enable_if<
2320 std::is_array<T2>::value && std::rank<T2>::value == 1 && (std::extent<T2, 0>::value > 0)>::
type * =
nullptr>
2325 template<
typename T2 = T,
typename std::enable_if<
2327 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>
::type * =
nullptr>
2333 template<
typename... Args,
typename T2 = T,
typename std::enable_if<!std::is_array<T2>::value>
::type * =
nullptr>
2336 return get_values<ValueType>().at(0)(std::forward<Args>(args)...);
2339 template<typename ExprOrVar, typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>
::type * =
nullptr>
2342 return get_values<ValueType>().at(0)(args);
2345 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>
::type * =
nullptr>
2348 return get_values<ValueType>().at(0);
2351 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>
::type * =
nullptr>
2354 return get_values<ValueType>().at(0);
2357 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2360 return get_values<ValueType>().size();
2363 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2366 return get_values<ValueType>()[i];
2369 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2372 return get_values<ValueType>().at(i);
2375 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2376 typename std::vector<ValueType>::const_iterator
begin()
const {
2378 return get_values<ValueType>().begin();
2381 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2382 typename std::vector<ValueType>::const_iterator
end()
const {
2384 return get_values<ValueType>().end();
2387 template<
typename T2 = T,
typename std::enable_if<
2389 std::is_array<T2>::value && std::rank<T2>::value == 1 && std::extent<T2, 0>::value == 0>
::type * =
nullptr>
2396 template<
typename T>
2407 const auto &my_types = this->
types();
2409 <<
"Cannot assign Func \"" << f.
name()
2410 <<
"\" to Output \"" << this->
name() <<
"\"\n"
2411 <<
"Output " << this->
name()
2412 <<
" is declared to have " << my_types.size() <<
" tuple elements"
2413 <<
" but Func " << f.
name()
2414 <<
" has " << f.
output_types().size() <<
" tuple elements.\n";
2415 for (
size_t i = 0; i < my_types.size(); i++) {
2417 <<
"Cannot assign Func \"" << f.
name()
2418 <<
"\" to Output \"" << this->
name() <<
"\"\n"
2419 << (my_types.size() > 1 ?
"In tuple element " + std::to_string(i) +
", " :
"")
2420 <<
"Output " << this->
name()
2421 <<
" has declared type " << my_types[i]
2422 <<
" but Func " << f.
name()
2428 <<
"Cannot assign Func \"" << f.
name()
2429 <<
"\" to Output \"" << this->
name() <<
"\"\n"
2430 <<
"Output " << this->
name()
2431 <<
" has declared dimensionality " << this->
dims()
2432 <<
" but Func " << f.
name()
2433 <<
" has dimensionality " << f.
dimensions() <<
"\n";
2446 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2447 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
2454 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.");
2455 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2461 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.");
2466 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2469 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2474 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2475 TBase::has_static_dimensions ? TBase::static_dimensions() : -1) {
2482 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.");
2483 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2489 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.");
2494 TBase::has_static_halide_type ? std::vector<
Type>{TBase::static_halide_type()} : std::vector<Type>{},
2497 static_assert(!TBase::has_static_dimensions,
"You can only specify a dimension argument for Output<Buffer<T, D>> if D is -1 or omitted.");
2501 if (TBase::has_static_halide_type) {
2502 return "Halide::Internal::StubOutputBuffer<" +
2506 return "Halide::Internal::StubOutputBuffer<>";
2510 template<typename T2, typename std::enable_if<!std::is_same<T2, Func>::value>
::type * =
nullptr>
2522 template<
typename T2,
int D2>
2528 <<
"Cannot assign to the Output \"" << this->
name()
2529 <<
"\": the expression is not convertible to the same Buffer type and/or dimensions.\n";
2533 <<
"Output " << this->
name() <<
" should have type=" << this->
type() <<
" but saw type=" <<
Type(buffer.
type()) <<
"\n";
2537 <<
"Output " << this->
name() <<
" should have dim=" << this->
dims() <<
" but saw dim=" << buffer.dimensions() <<
"\n";
2542 this->
funcs_.at(0)(_) = buffer(_);
2550 template<
typename T2>
2553 assign_from_func(stub_output_buffer.
f);
2562 assign_from_func(f);
2568 user_assert(!this->
is_array()) <<
"Cannot convert an Output<Buffer<>[]> to an ImageParam; use an explicit subscript operator: " << this->
name();
2570 return this->
funcs_.at(0).output_buffer();
2576 user_assert(!this->
is_array()) <<
"Cannot call set_estimates() on an array Output; use an explicit subscript operator: " << this->
name();
2578 this->
funcs_.at(0).set_estimates(estimates);
2582 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2585 return this->
template get_values<Func>()[i];
2589 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>
::type * =
nullptr>
2592 return this->
template get_values<Func>()[i];
2613 template<
typename T>
2620 return this->funcs_.at(i);
2648 template<typename T2 = T, typename std::enable_if<!std::is_array<T2>::value>::type * =
nullptr>
2650 this->check_gio_access();
2651 this->check_value_writable();
2655 get_assignable_func_ref(0) = f;
2660 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2662 this->check_gio_access();
2663 this->check_value_writable();
2664 return get_assignable_func_ref(i);
2668 template<typename T2 = T, typename std::enable_if<std::is_array<T2>::value>::type * =
nullptr>
2670 this->check_gio_access();
2671 return Super::operator[](i);
2675 this->check_gio_access();
2677 for (
Func &f : this->funcs_) {
2678 f.set_estimate(var,
min, extent);
2684 this->check_gio_access();
2686 for (
Func &f : this->funcs_) {
2687 f.set_estimates(estimates);
2693 template<
typename T>
2710 template<typename T, typename TBase = typename std::remove_all_extents<T>::type>
2719 template<
typename T>
2740 : Super(array_size, name) {
2748 : Super(name, {t}) {
2756 : Super(name, {t}, d) {
2760 : Super(name, t, d) {
2764 : Super(array_size, name, d) {
2768 : Super(array_size, name, {t}) {
2771 explicit GeneratorOutput(
size_t array_size,
const std::string &name,
const std::vector<Type> &t)
2772 : Super(array_size, name, t) {
2776 : Super(array_size, name, {t}, d) {
2779 explicit GeneratorOutput(
size_t array_size,
const std::string &name,
const std::vector<Type> &t,
int d)
2780 : Super(array_size, name, t, d) {
2786 template<
typename T2,
int D2>
2788 Super::operator=(buffer);
2792 template<
typename T2>
2794 Super::operator=(stub_output_buffer);
2799 Super::operator=(f);
2804 namespace Internal {
2806 template<
typename T>
2808 std::istringstream iss(value);
2811 user_assert(!iss.fail() && iss.get() == EOF) <<
"Unable to parse: " << value;
2823 template<
typename T>
2829 if (!error_msg.empty()) {
2832 set_from_string_impl<T>(new_value_string);
2837 return std::string();
2842 return std::string();
2847 return std::string();
2857 static std::unique_ptr<Internal::GeneratorParamBase> make(
2859 const std::string &generator_name,
2860 const std::string &gpname,
2864 std::string error_msg = defined ?
"Cannot set the GeneratorParam " + gpname +
" for " + generator_name +
" because the value is explicitly specified in the C++ source." :
"";
2865 return std::unique_ptr<GeneratorParam_Synthetic<T>>(
2873 template<typename T2 = T, typename std::enable_if<std::is_same<T2, ::Halide::Type>::value>
::type * =
nullptr>
2874 void set_from_string_impl(
const std::string &new_value_string) {
2879 template<typename T2 = T, typename std::enable_if<std::is_integral<T2>::value>
::type * =
nullptr>
2880 void set_from_string_impl(
const std::string &new_value_string) {
2882 gio.
dims_ = parse_scalar<T2>(new_value_string);
2884 gio.
array_size_ = parse_scalar<T2>(new_value_string);
2892 const std::string error_msg;
2895 class GeneratorStub;
2941 bool auto_schedule =
false,
2954 return auto_schedule_;
2957 return machine_params_;
2960 template<
typename T>
2962 return T::create(*
this);
2964 template<
typename T,
typename... Args>
2965 inline std::unique_ptr<T>
apply(
const Args &...args)
const {
2966 auto t = this->create<T>();
2973 bool auto_schedule_ =
false;
2975 std::shared_ptr<ExternsMap> externs_map_;
2976 std::shared_ptr<Internal::ValueTracker> value_tracker_;
2981 std::shared_ptr<ExternsMap> externs_map,
2982 std::shared_ptr<Internal::ValueTracker> value_tracker);
3008 template<
typename T>
3010 return Halide::cast<T>(e);
3015 template<
typename T>
3017 template<
typename T = void,
int D = -1>
3019 template<
typename T>
3035 namespace Internal {
3037 template<
typename... Args>
3043 template<
typename T,
typename... Args>
3045 static const bool value = !std::is_convertible<T, Realization>::value &&
NoRealizations<Args...>::value;
3073 std::set<std::string> names;
3076 std::vector<Internal::GeneratorParamBase *> filter_generator_params;
3079 std::vector<Internal::GeneratorInputBase *> filter_inputs;
3082 std::vector<Internal::GeneratorOutputBase *> filter_outputs;
3087 std::vector<std::unique_ptr<Internal::GeneratorParamBase>> owned_synthetic_params;
3090 std::vector<std::unique_ptr<Internal::GIOBase>> owned_extras;
3098 return filter_generator_params;
3100 const std::vector<Internal::GeneratorInputBase *> &
inputs()
const {
3101 return filter_inputs;
3103 const std::vector<Internal::GeneratorOutputBase *> &
outputs()
const {
3104 return filter_outputs;
3122 template<
typename data_t>
3160 template<
typename... Args>
3165 <<
"Expected exactly " << pi.
inputs().size()
3166 <<
" inputs but got " <<
sizeof...(args) <<
"\n";
3167 set_inputs_vector(build_inputs(std::forward_as_tuple<const Args &...>(args...), std::make_index_sequence<
sizeof...(Args)>{}));
3171 this->check_scheduled(
"realize");
3177 template<
typename... Args,
typename std::enable_if<
NoRealizations<Args...>::value>::type * =
nullptr>
3179 this->check_scheduled(
"realize");
3184 this->check_scheduled(
"realize");
3188 #ifdef HALIDE_ALLOW_GENERATOR_BUILD_METHOD
3204 template<
typename T,
3205 typename std::enable_if<std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3209 p->generator =
this;
3210 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3211 param_info_ptr->filter_inputs.push_back(p);
3216 template<
typename T,
3217 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3219 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 .");
3220 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.");
3223 p->generator =
this;
3224 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3225 param_info_ptr->filter_inputs.push_back(p);
3230 template<
typename T,
3231 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3233 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.");
3234 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.");
3237 p->generator =
this;
3238 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3239 param_info_ptr->filter_inputs.push_back(p);
3244 template<
typename T,
3245 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3247 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.");
3248 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.");
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);
3257 template<
typename T,
3258 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3262 p->generator =
this;
3263 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3264 param_info_ptr->filter_inputs.push_back(p);
3268 template<
typename T,
3269 typename std::enable_if<std::is_same<T, Expr>::value>::type * =
nullptr>
3273 p->generator =
this;
3275 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3276 param_info_ptr->filter_inputs.push_back(p);
3281 template<
typename T,
3282 typename std::enable_if<std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3286 p->generator =
this;
3287 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3288 param_info_ptr->filter_outputs.push_back(p);
3293 template<
typename T,
3294 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3296 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 .");
3297 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.");
3300 p->generator =
this;
3301 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3302 param_info_ptr->filter_outputs.push_back(p);
3307 template<
typename T,
3308 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3310 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.");
3311 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.");
3314 p->generator =
this;
3315 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3316 param_info_ptr->filter_outputs.push_back(p);
3321 template<
typename T,
3322 typename std::enable_if<!std::is_arithmetic<T>::value && !std::is_same<T, Halide::Func>::value>::type * =
nullptr>
3324 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.");
3325 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.");
3328 p->generator =
this;
3329 param_info_ptr->owned_extras.push_back(std::unique_ptr<Internal::GIOBase>(p));
3330 param_info_ptr->filter_outputs.push_back(p);
3334 template<
typename... Args>
3367 template<
typename T>
3370 template<
typename T>
3389 #ifdef HALIDE_ALLOW_GENERATOR_BUILD_METHOD
3453 std::shared_ptr<GeneratorContext::ExternsMap> externs_map;
3454 std::shared_ptr<Internal::ValueTracker> value_tracker;
3458 std::unique_ptr<GeneratorParamInfo> param_info_ptr;
3460 bool inputs_set{
false};
3461 std::string generator_registered_name, generator_stub_name;
3469 void check_scheduled(
const char *m)
const;
3471 void build_params(
bool force =
false);
3484 std::vector<Func> get_outputs(
const std::string &n);
3486 void set_inputs_vector(
const std::vector<std::vector<StubInput>> &inputs);
3496 template<
typename T,
int Dims>
3497 std::vector<StubInput> build_input(
size_t i,
const Buffer<T, Dims> &arg) {
3498 auto *in = param_info().
inputs().at(i);
3499 check_input_is_singular(in);
3500 const auto k = in->kind();
3508 f(Halide::_) = arg(Halide::_);
3521 template<
typename T,
int Dims>
3522 std::vector<StubInput> build_input(
size_t i,
const GeneratorInput<Buffer<T, Dims>> &arg) {
3523 auto *in = param_info().
inputs().at(i);
3524 check_input_is_singular(in);
3525 const auto k = in->kind();
3527 StubInputBuffer<> sib = arg;
3541 std::vector<StubInput> build_input(
size_t i,
const Func &arg) {
3542 auto *in = param_info().
inputs().at(i);
3544 check_input_is_singular(in);
3551 std::vector<StubInput> build_input(
size_t i,
const std::vector<Func> &arg) {
3552 auto *in = param_info().
inputs().at(i);
3554 check_input_is_array(in);
3556 std::vector<StubInput> siv;
3557 siv.reserve(arg.size());
3558 for (
const auto &f : arg) {
3559 siv.emplace_back(f);
3565 std::vector<StubInput> build_input(
size_t i,
const Expr &arg) {
3566 auto *in = param_info().
inputs().at(i);
3568 check_input_is_singular(in);
3574 std::vector<StubInput> build_input(
size_t i,
const std::vector<Expr> &arg) {
3575 auto *in = param_info().
inputs().at(i);
3577 check_input_is_array(in);
3578 std::vector<StubInput> siv;
3579 siv.reserve(arg.size());
3580 for (
const auto &value : arg) {
3581 siv.emplace_back(value);
3588 template<
typename T,
3589 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3590 std::vector<StubInput> build_input(
size_t i,
const T &arg) {
3591 auto *in = param_info().
inputs().at(i);
3593 check_input_is_singular(in);
3601 template<
typename T,
3602 typename std::enable_if<std::is_arithmetic<T>::value>::type * =
nullptr>
3603 std::vector<StubInput> build_input(
size_t i,
const std::vector<T> &arg) {
3604 auto *in = param_info().
inputs().at(i);
3606 check_input_is_array(in);
3607 std::vector<StubInput> siv;
3608 siv.reserve(arg.size());
3609 for (
const auto &value : arg) {
3613 siv.emplace_back(e);
3618 template<
typename... Args,
size_t... Indices>
3619 std::vector<std::vector<StubInput>> build_inputs(
const std::tuple<const Args &...> &t, std::index_sequence<Indices...>) {
3620 return {build_input(Indices, std::get<Indices>(t))...};
3637 static std::unique_ptr<GeneratorBase>
create(
const std::string &name,
3641 using GeneratorFactoryMap = std::map<const std::string, GeneratorFactory>;
3643 GeneratorFactoryMap factories;
3671 auto g = std::make_unique<T>();
3672 g->init_from_context(
context);
3678 const std::string ®istered_name,
3679 const std::string &stub_name) {
3681 g->set_generator_names(registered_name, stub_name);
3685 template<
typename... Args>
3687 #ifdef HALIDE_ALLOW_GENERATOR_BUILD_METHOD
3692 static_assert(has_generate_method<T>::value,
"apply() is not supported for old-style Generators.");
3701 template<
typename T2>
3706 template<
typename T2,
typename... Args>
3707 inline std::unique_ptr<T2>
apply(
const Args &...args)
const {
3708 auto t = this->create<T2>();
3717 struct type_sink {
typedef void type; };
3719 template<
typename T2,
typename =
void>
3720 struct has_configure_method : std::false_type {};
3722 template<
typename T2>
3723 struct has_configure_method<T2, typename type_sink<decltype(std::declval<T2>().configure())>::type> : std::true_type {};
3725 template<
typename T2,
typename =
void>
3726 struct has_generate_method : std::false_type {};
3728 template<
typename T2>
3729 struct has_generate_method<T2, typename type_sink<decltype(std::declval<T2>().generate())>::type> : std::true_type {};
3731 template<
typename T2,
typename =
void>
3732 struct has_schedule_method : std::false_type {};
3734 template<
typename T2>
3735 struct has_schedule_method<T2, typename type_sink<decltype(std::declval<T2>().
schedule())>::type> : std::true_type {};
3737 #ifdef HALIDE_ALLOW_GENERATOR_BUILD_METHOD
3747 template<
typename T2 = T,
3748 typename std::enable_if<!has_generate_method<T2>::value>::type * =
nullptr>
3749 HALIDE_ATTRIBUTE_DEPRECATED(
"The build() method is deprecated for Halide Generators and will be removed entirely in future versions of Halide. Please use a generate() method with Output<> members instead.")
3750 Pipeline build_pipeline_impl(
double) {
3751 static_assert(!has_configure_method<T2>::value,
"The configure() method is ignored if you define a build() method; use generate() instead.");
3752 static_assert(!has_schedule_method<T2>::value,
"The schedule() method is ignored if you define a build() method; use generate() instead.");
3754 user_warning <<
"The build() method is deprecated for Halide Generators and will be removed entirely in future versions of Halide. "
3755 <<
"Please use a generate() method with Output<> members instead.\n";
3763 template<
typename T2 = T,
3764 typename = decltype(std::declval<T2>().generate())>
3765 Pipeline build_pipeline_impl(
int) {
3771 ((T *)
this)->call_generate_impl(0);
3772 ((T *)
this)->call_schedule_impl(0, 0);
3779 void call_configure_impl(
double,
double) {
3786 template<
typename T2 = T,
3787 typename = decltype(std::declval<T2>().generate())>
3788 void call_configure_impl(
double,
int) {
3791 static_assert(!has_configure_method<T2>::value,
"Did not expect a configure method here.");
3795 template<
typename T2 = T,
3796 typename = decltype(std::declval<T2>().generate()),
3797 typename = decltype(std::declval<T2>().configure())>
3798 void call_configure_impl(
int,
int) {
3800 static_assert(std::is_void<decltype(t->configure())>::value,
"configure() must return void");
3809 void call_generate_impl(
double) {
3813 template<
typename T2 = T,
3814 typename = decltype(std::declval<T2>().generate())>
3815 void call_generate_impl(
int) {
3817 static_assert(std::is_void<decltype(t->generate())>::value,
"generate() must return void");
3826 void call_schedule_impl(
double,
double) {
3830 template<
typename T2 = T,
3831 typename = decltype(std::declval<T2>().generate())>
3832 void call_schedule_impl(
double,
int) {
3838 template<
typename T2 = T,
3839 typename = decltype(std::declval<T2>().generate()),
3840 typename = decltype(std::declval<T2>().
schedule())>
3841 void call_schedule_impl(
int,
int) {
3843 static_assert(std::is_void<decltype(t->schedule())>::value,
"schedule() must return void");
3856 t->call_generate_impl();
3857 t->call_schedule_impl();
3861 void call_configure_impl() {
3863 if constexpr (has_configure_method<T>::value) {
3865 static_assert(std::is_void<decltype(t->configure())>::value,
"configure() must return void");
3871 void call_generate_impl() {
3873 static_assert(has_generate_method<T>::value,
"Expected a generate() method here.");
3875 static_assert(std::is_void<decltype(t->generate())>::value,
"generate() must return void");
3880 void call_schedule_impl() {
3882 if constexpr (has_schedule_method<T>::value) {
3884 static_assert(std::is_void<decltype(t->schedule())>::value,
"schedule() must return void");
3892 #ifdef HALIDE_ALLOW_GENERATOR_BUILD_METHOD
3894 return this->build_pipeline_impl(0);
3898 this->call_configure_impl(0, 0);
3902 this->call_generate_impl(0);
3906 this->call_schedule_impl(0, 0);
3910 return this->build_pipeline_impl();
3914 this->call_configure_impl();
3918 this->call_generate_impl();
3922 this->call_schedule_impl();
3928 friend class ::Halide::GeneratorContext;
3952 const std::vector<std::vector<Internal::StubInput>> &inputs);
3954 const std::vector<std::vector<Internal::StubInput>> &inputs);
3961 template<
typename T2>
3964 std::vector<T2> result;
3979 template<
typename T =
void>
3984 template<
typename T>
3986 std::vector<StubInput> r;
3987 std::copy(v.begin(), v.end(), std::back_inserter(r));
4007 struct halide_global_ns;
4010 #define _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) \
4011 namespace halide_register_generator { \
4012 struct halide_global_ns; \
4013 namespace GEN_REGISTRY_NAME##_ns { \
4014 std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context); \
4015 std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context) { \
4016 using GenType = std::remove_pointer<decltype(new GEN_CLASS_NAME)>::type; \
4017 return GenType::create(context, #GEN_REGISTRY_NAME, #FULLY_QUALIFIED_STUB_NAME); \
4020 static auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
4022 static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \
4023 "HALIDE_REGISTER_GENERATOR must be used at global scope");
4025 #define _HALIDE_REGISTER_GENERATOR2(GEN_CLASS_NAME, GEN_REGISTRY_NAME) \
4026 _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, GEN_REGISTRY_NAME)
4028 #define _HALIDE_REGISTER_GENERATOR3(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) \
4029 _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME)
4034 #define __HALIDE_REGISTER_ARGCOUNT_IMPL(_1, _2, _3, COUNT, ...) \
4037 #define _HALIDE_REGISTER_ARGCOUNT_IMPL(ARGS) \
4038 __HALIDE_REGISTER_ARGCOUNT_IMPL ARGS
4040 #define _HALIDE_REGISTER_ARGCOUNT(...) \
4041 _HALIDE_REGISTER_ARGCOUNT_IMPL((__VA_ARGS__, 3, 2, 1, 0))
4043 #define ___HALIDE_REGISTER_CHOOSER(COUNT) \
4044 _HALIDE_REGISTER_GENERATOR##COUNT
4046 #define __HALIDE_REGISTER_CHOOSER(COUNT) \
4047 ___HALIDE_REGISTER_CHOOSER(COUNT)
4049 #define _HALIDE_REGISTER_CHOOSER(COUNT) \
4050 __HALIDE_REGISTER_CHOOSER(COUNT)
4052 #define _HALIDE_REGISTER_GENERATOR_PASTE(A, B) \
4055 #define HALIDE_REGISTER_GENERATOR(...) \
4056 _HALIDE_REGISTER_GENERATOR_PASTE(_HALIDE_REGISTER_CHOOSER(_HALIDE_REGISTER_ARGCOUNT(__VA_ARGS__)), (__VA_ARGS__))
4072 #define HALIDE_REGISTER_GENERATOR_ALIAS(GEN_REGISTRY_NAME, ORIGINAL_REGISTRY_NAME, ...) \
4073 namespace halide_register_generator { \
4074 struct halide_global_ns; \
4075 namespace ORIGINAL_REGISTRY_NAME##_ns { \
4076 std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context); \
4078 namespace GEN_REGISTRY_NAME##_ns { \
4079 std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context); \
4080 std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context) { \
4081 auto g = ORIGINAL_REGISTRY_NAME##_ns::factory(context); \
4082 g->set_generator_param_values(__VA_ARGS__); \
4086 static auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
4088 static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \
4089 "HALIDE_REGISTER_GENERATOR_ALIAS must be used at global scope");
#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.
Defines methods for introspecting in C++.
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
A Halide::Buffer is a named shared reference to a Halide::Runtime::Buffer.
bool defined() const
Check if this Buffer refers to an existing Buffer.
const std::string & name() const
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.
Realization realize(std::vector< int32_t > sizes={}, const Target &target=Target(), const ParamMap ¶m_map=ParamMap::empty_map())
Evaluate this function over some rectangular domain and return the resulting buffer or buffers.
const std::string & name() const
The name of this function, either given during construction, or automatically generated.
const std::vector< Type > & output_types() const
Get the types of the outputs of this Func.
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...
std::map< std::string, ExternalCode > ExternsMap
std::unique_ptr< T > apply(const Args &...args) const
const MachineParams & get_machine_params() const
GeneratorContext & operator=(const GeneratorContext &)=default
const Target & get_target() const
GeneratorContext & operator=(GeneratorContext &&)=default
std::unique_ptr< T > create() const
bool get_auto_schedule() const
GeneratorContext(const Target &t, bool auto_schedule=false, const MachineParams &machine_params=MachineParams::generic())
GeneratorContext()=default
GeneratorContext(const GeneratorContext &)=default
GeneratorContext(GeneratorContext &&)=default
void call_generate() override
Generator(Generator &&that)=delete
void call_schedule() override
std::unique_ptr< T2 > create() 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)
static std::unique_ptr< T > create(const Halide::GeneratorContext &context, const std::string ®istered_name, const std::string &stub_name)
void call_configure() override
std::unique_ptr< T2 > apply(const Args &...args) const
Pipeline build_pipeline() override
Generator(const Generator &)=delete
GeneratorOutput< T > & operator=(Buffer< T2, D2 > &buffer)
typename Super::TBase TBase
GeneratorOutput(const std::string &name)
GeneratorOutput(const std::string &name, const std::vector< Type > &t, int d)
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=(const Internal::StubOutputBuffer< T2 > &stub_output_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.
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...
size_t array_size() const
const std::vector< Func > & funcs() const
GIOBase & operator=(const GIOBase &)=delete
void check_matching_dims(int d) const
GIOBase(size_t array_size, const std::string &name, IOKind kind, const std::vector< Type > &types, int dims)
bool array_size_defined() const
virtual const char * input_or_output() const =0
bool dims_defined() const
GIOBase & operator=(GIOBase &&)=delete
std::vector< Type > types_
const std::vector< ElemType > & get_values() const
void check_matching_types(const std::vector< Type > &t) const
const std::vector< Type > & types() 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
const std::vector< Expr > & exprs() const
GIOBase(GIOBase &&)=delete
void check_gio_access() const
void set_dimensions(int dims)
void set_array_size(int size)
std::vector< Func > funcs_
const std::string & name() const
bool types_defined() const
virtual bool is_array() const
virtual void verify_internals()
virtual ~GIOBase()=default
std::vector< Expr > exprs_
void set_type(const Type &type)
GeneratorBase * generator
void ensure_configure_has_been_called()
virtual void call_schedule()=0
GeneratorParam< Target > target
GeneratorInput< T > * add_input(const std::string &name, const Type &t, int dimensions)
GeneratorBase(size_t size, const void *introspection_helper)
HALIDE_NO_USER_CODE_INLINE void add_requirement(Expr condition, Args &&...args)
GeneratorInput< T > * add_input(const std::string &name)
Realization realize(Args &&...args)
Module build_module(const std::string &function_name="", LinkageType linkage_type=LinkageType::ExternalPlusMetadata)
GeneratorBase(const GeneratorBase &)=delete
void init_from_context(const Halide::GeneratorContext &context)
virtual void call_generate()=0
GeneratorInput< T > * add_input(const std::string &name, const Type &type)
int natural_vector_size() const
Given a data type, return an estimate of the "natural" vector size for that data type when compiling ...
GeneratorInput< T > * add_input(const std::string &name, int dimensions)
Target get_target() const
GeneratorParam< bool > auto_schedule
void check_exact_phase(Phase expected_phase) const
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)
std::shared_ptr< GeneratorContext::ExternsMap > get_externs_map() const
Generators can register ExternalCode objects onto themselves.
bool get_auto_schedule() const
GeneratorOutput< T > * add_output(const std::string &name, const Type &t, int dimensions)
Module build_gradient_module(const std::string &function_name)
Build a module that is suitable for using for gradient descent calculation in TensorFlow or PyTorch.
virtual void call_configure()=0
GeneratorBase(GeneratorBase &&that)=delete
GeneratorOutput< T > * add_output(const std::string &name)
MachineParams get_machine_params() const
GeneratorBase & operator=(const GeneratorBase &)=delete
GeneratorOutput< T > * add_output(const std::string &name, int dimensions)
GeneratorContext context() const
void emit_cpp_stub(const std::string &stub_file_path)
virtual Pipeline build_pipeline()=0
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_generator_param_values(const GeneratorParamsMap ¶ms)
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 track_parameter_values(bool include_outputs)
void advance_phase(Phase new_phase)
GeneratorParam< MachineParams > machine_params
GeneratorBase & operator=(GeneratorBase &&that)=delete
GeneratorOutput_Arithmetic(const std::string &name)
GeneratorOutput_Arithmetic(size_t array_size, const std::string &name)
GeneratorOutput_Buffer(const std::string &name, int d)
GeneratorOutput_Buffer(size_t array_size, const std::string &name)
GeneratorOutput_Buffer(size_t array_size, const std::string &name, const std::vector< Type > &t, int d)
GeneratorOutput_Buffer< T > & set_estimates(const Region &estimates)
GeneratorOutput_Buffer(const std::string &name)
GeneratorOutput_Buffer< T > & operator=(const Func &f)
HALIDE_NO_USER_CODE_INLINE std::string get_c_type() const override
GeneratorOutput_Buffer< T > & operator=(const StubOutputBuffer< T2 > &stub_output_buffer)
const Func & operator[](size_t i) const
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)
HALIDE_NO_USER_CODE_INLINE GeneratorOutput_Buffer< T > & operator=(Buffer< T2, D2 > &buffer)
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)
GeneratorOutput_Func< T > & set_estimate(const Var &var, const Expr &min, const Expr &extent)
GeneratorOutput_Func(const std::string &name)
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< T > & set_estimates(const Region &estimates)
Func & operator[](size_t i)
GeneratorOutput_Func(const std::string &name, int d)
GeneratorOutput_Func< T > & operator=(const Func &f)
const Func & operator[](size_t i) const
GeneratorOutput_Func(const std::string &name, const std::vector< Type > &t)
~GeneratorOutputBase() override
GeneratorOutputBase(size_t array_size, const std::string &name, IOKind kind, const std::vector< Type > &t, int d)
Forward schedule-related methods to the underlying Func.
GeneratorOutputBase(const std::string &name, IOKind kind, const std::vector< Type > &t, int d)
virtual std::string get_c_type() const
HALIDE_NO_USER_CODE_INLINE T2 as() const
const char * input_or_output() const override
void check_value_writable() const override
GeneratorOutputImpl(const std::string &name, IOKind kind, const std::vector< Type > &t, int d)
std::vector< ValueType >::const_iterator begin() const
const ValueType & at(size_t i) const
const ValueType & operator[](size_t i) const
bool is_array() const override
std::vector< ValueType >::const_iterator end() const
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
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_MachineParams(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
void set_from_string(const std::string &new_value_string) 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
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)
const std::string & name() const
void check_value_readable() const
virtual bool is_synthetic_param() const
GeneratorParamBase(GeneratorParamBase &&)=delete
GeneratorParamBase & operator=(const GeneratorParamBase &)=delete
virtual std::string call_to_string(const std::string &v) const =0
void fail_wrong_type(const char *type)
GeneratorParamBase & operator=(GeneratorParamBase &&)=delete
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
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::GeneratorParamBase * > & generator_params() const
const std::vector< Internal::GeneratorInputBase * > & inputs() const
GeneratorParamInfo(GeneratorBase *generator, size_t size)
const std::vector< Internal::GeneratorOutputBase * > & outputs() const
GeneratorRegistry & operator=(const GeneratorRegistry &)=delete
GeneratorRegistry(const GeneratorRegistry &)=delete
static std::unique_ptr< GeneratorBase > create(const std::string &name, const Halide::GeneratorContext &context)
GeneratorRegistry(GeneratorRegistry &&that)=delete
GeneratorRegistry & operator=(GeneratorRegistry &&that)=delete
static std::vector< std::string > enumerate()
static void register_factory(const std::string &name, GeneratorFactory generator_factory)
static void unregister_factory(const std::string &name)
static std::vector< StubInput > to_stub_input_vector(const Expr &e)
std::vector< std::vector< Func > > generate(const GeneratorParamsMap &generator_params, const std::vector< std::vector< Internal::StubInput >> &inputs)
GeneratorStub(const GeneratorContext &context, const GeneratorFactory &generator_factory, const GeneratorParamsMap &generator_params, const std::vector< std::vector< Internal::StubInput >> &inputs)
std::vector< Func > get_outputs(const std::string &n) const
static std::vector< StubInput > to_stub_input_vector(const Func &f)
std::shared_ptr< GeneratorBase > generator
GeneratorStub(const GeneratorContext &context, const GeneratorFactory &generator_factory)
static std::vector< StubInput > to_stub_input_vector(const StubInputBuffer< T > &b)
std::vector< T2 > get_output_buffers(const std::string &n) const
static std::vector< StubInput > to_stub_input_vector(const std::vector< T > &v)
A reference-counted handle to a parameter to a halide pipeline.
void set_estimate(Expr e)
void set_buffer(const Buffer< void > &b)
If the parameter is a buffer parameter, set its current value.
HALIDE_NO_USER_CODE_INLINE void set_scalar(T val)
If the parameter is a scalar parameter, set its current value.
void set_default_value(const Expr &e)
Get and set the default values for scalar parameters.
Type type() const
Get the type of this parameter.
void set_min_value(const Expr &e)
Get and set constraints for scalar parameters.
int dimensions() const
Get the dimensionality of this parameter.
void set_max_value(const Expr &e)
RegisterGenerator(const char *registered_name, GeneratorFactory generator_factory)
Target get_target() const
Realization realize(Args &&...args)
StubOutputBufferBase(const Func &f, const std::shared_ptr< GeneratorBase > &generator)
std::shared_ptr< GeneratorBase > generator
void check_scheduled(const char *m) const
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
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'.
static Type Bool(int lanes=1)
static Expr cast(Halide::Type t, Expr e)
static Type UInt(int bits, int lanes=1)
static Type Int(int bits, int lanes=1)
static Type Float(int bits, int lanes=1)
Halide::Pipeline Pipeline
A handle on the output buffer of a pipeline.
A scalar parameter to a halide pipeline.
A class representing a Halide pipeline.
void add_requirement(const Expr &condition, std::vector< Expr > &error)
Add a top-level precondition to the generated pipeline, expressed as a boolean Expr.
void trace_pipeline()
Generate begin_pipeline and end_pipeline tracing calls for this pipeline.
Realization realize(std::vector< int32_t > sizes={}, const Target &target=Target(), const ParamMap ¶m_map=ParamMap::empty_map())
See Func::realize.
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))
const void * get_introspection_helper()
Return the address of a global with type T *.
std::string halide_type_to_enum_string(const Type &t)
typename select_type< cond< std::is_same< T, Target >::value, GeneratorParam_Target< T > >, cond< std::is_same< T, MachineParams >::value, GeneratorParam_MachineParams< 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
Expr make_const(Type t, int64_t val)
Construct an immediate of the given type from any numeric C++ type.
std::string halide_type_to_c_source(const Type &t)
std::function< std::unique_ptr< GeneratorBase >(const GeneratorContext &)> GeneratorFactory
std::vector< Type > parse_halide_type_list(const std::string &types)
HALIDE_NO_USER_CODE_INLINE std::string enum_to_string(const std::map< std::string, T > &enum_map, const T &t)
std::map< std::string, StringOrLoopLevel > GeneratorParamsMap
std::string halide_type_to_c_type(const Type &t)
std::vector< Expr > parameter_constraints(const Parameter &p)
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...
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
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, std::ostream &cerr)
generate_filter_main() is a convenient wrapper for GeneratorRegistry::create() + compile_to_files(); ...
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.
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.
LinkageType
Type of linkage a function in a lowered Halide module can have.
@ ExternalPlusMetadata
Visible externally. Argument metadata and an argv wrapper are also generated.
@ Internal
Not visible externally, similar to 'static' linkage in C.
class HALIDE_ATTRIBUTE_DEPRECATED("Use OutputFileType instead of Output") Output
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.
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 min(const GeneratorParam< T > &a, const Other &b) -> decltype(Internal::GeneratorMinMax::min_forward(a, b))
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.
Expr cast(Expr a)
Cast an expression to the halide type corresponding to the C++ type 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.
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.
Target get_jit_target_from_environment()
Return the target that Halide will use for jit-compilation.
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!...
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)
auto max(const GeneratorParam< T > &a, const Other &b) -> decltype(Internal::GeneratorMinMax::max_forward(a, b))
MemoryType
An enum describing different address spaces to be used with Func::store_in.
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
A fragment of Halide syntax.
An argument to an extern-defined Func.
static TO2 value(const FROM &from)
std::vector< std::string > inputs
std::vector< std::string > outputs
std::vector< std::string > generator_params
HALIDE_ALWAYS_INLINE bool defined() const
StringOrLoopLevel(const LoopLevel &loop_level)
StringOrLoopLevel(const std::string &s)
StringOrLoopLevel(const char *s)
StringOrLoopLevel()=default
static constexpr bool value
typename std::conditional< First::value, typename First::type, void >::type type
A struct representing the machine parameters to generate the auto-scheduled code for.
static MachineParams generic()
Default machine parameters for generic CPU architecture.
A struct representing a target machine and os to generate code for.
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 ...
Types in the halide type system.