diff --git a/python_bindings/src/halide/CMakeLists.txt b/python_bindings/src/halide/CMakeLists.txt index c0f48f569eb1..df3d8fe8bbfb 100644 --- a/python_bindings/src/halide/CMakeLists.txt +++ b/python_bindings/src/halide/CMakeLists.txt @@ -20,6 +20,7 @@ set(native_sources PyLoopLevel.cpp PyModule.cpp PyParam.cpp + PyParameter.cpp PyPipeline.cpp PyRDom.cpp PyStage.cpp diff --git a/python_bindings/src/halide/halide_/PyGenerator.cpp b/python_bindings/src/halide/halide_/PyGenerator.cpp index 2651f513d0fc..2ec427f7c7df 100644 --- a/python_bindings/src/halide/halide_/PyGenerator.cpp +++ b/python_bindings/src/halide/halide_/PyGenerator.cpp @@ -11,9 +11,9 @@ using Halide::Internal::AbstractGenerator; using Halide::Internal::AbstractGeneratorPtr; using Halide::Internal::GeneratorFactoryProvider; using ArgInfo = Halide::Internal::AbstractGenerator::ArgInfo; +using Halide::Parameter; using Halide::Internal::ArgInfoDirection; using Halide::Internal::ArgInfoKind; -using Halide::Internal::Parameter; template std::map dict_to_map(const py::dict &dict) { diff --git a/python_bindings/src/halide/halide_/PyHalide.cpp b/python_bindings/src/halide/halide_/PyHalide.cpp index 5b0926f8c8ab..750ee6cc092f 100644 --- a/python_bindings/src/halide/halide_/PyHalide.cpp +++ b/python_bindings/src/halide/halide_/PyHalide.cpp @@ -18,6 +18,7 @@ #include "PyLambda.h" #include "PyModule.h" #include "PyParam.h" +#include "PyParameter.h" #include "PyPipeline.h" #include "PyRDom.h" #include "PyTarget.h" @@ -61,6 +62,7 @@ PYBIND11_MODULE(HALIDE_PYBIND_MODULE_NAME, m) { define_lambda(m); define_operators(m); define_param(m); + define_parameter(m); define_image_param(m); define_type(m); define_derivative(m); diff --git a/python_bindings/src/halide/halide_/PyParam.cpp b/python_bindings/src/halide/halide_/PyParam.cpp index 31319fffd4ee..ac5c13d45d35 100644 --- a/python_bindings/src/halide/halide_/PyParam.cpp +++ b/python_bindings/src/halide/halide_/PyParam.cpp @@ -6,8 +6,6 @@ namespace Halide { namespace PythonBindings { -using Halide::Internal::Parameter; - namespace { template @@ -40,29 +38,6 @@ void add_param_methods(py::class_> ¶m_class) { } // namespace void define_param(py::module &m) { - // This is a "just-enough" wrapper around Parameter to let us pass it back - // and forth between Py and C++. It deliberately exposes very few methods, - // and we should keep it that way. - auto parameter_class = - py::class_(m, "InternalParameter") - .def(py::init(), py::arg("p")) - .def("defined", &Parameter::defined) - .def("type", &Parameter::type) - .def("dimensions", &Parameter::dimensions) - .def("_to_argument", [](const Parameter &p) -> Argument { - return Argument(p.name(), - p.is_buffer() ? Argument::InputBuffer : Argument::InputScalar, - p.type(), - p.dimensions(), - p.get_argument_estimates()); - }) - .def("__repr__", [](const Parameter &p) -> std::string { - std::ostringstream o; - // Don't leak any info but the name into the repr string. - o << ""; - return o.str(); - }); - auto param_class = py::class_>(m, "Param") .def(py::init(), py::arg("type")) diff --git a/python_bindings/src/halide/halide_/PyParameter.cpp b/python_bindings/src/halide/halide_/PyParameter.cpp new file mode 100644 index 000000000000..87da6610a691 --- /dev/null +++ b/python_bindings/src/halide/halide_/PyParameter.cpp @@ -0,0 +1,106 @@ +#include "PyParameter.h" + +#include "PyType.h" + +namespace Halide { +namespace PythonBindings { + +namespace { + +template +void add_scalar_methods(py::class_ ¶meter_class) { + parameter_class + .def("scalar", &Parameter::scalar) + .def( + "set_scalar", [](Parameter ¶meter, TYPE value) -> void { + parameter.set_scalar(value); + }, + py::arg("value")); +} + +} // namespace + +void define_parameter(py::module &m) { + // Disambiguate some ambigious methods + void (Parameter::*set_scalar_method)(const Type &t, halide_scalar_value_t val) = &Parameter::set_scalar; + + auto parameter_class = + py::class_(m, "Parameter") + .def(py::init<>()) + .def(py::init(), py::arg("p")) + .def(py::init()) + .def(py::init()) + .def(py::init &, int, const std::vector &, + MemoryType>()) + .def(py::init()) + .def("_to_argument", [](const Parameter &p) -> Argument { + return Argument(p.name(), + p.is_buffer() ? Argument::InputBuffer : Argument::InputScalar, + p.type(), + p.dimensions(), + p.get_argument_estimates()); + }) + .def("__repr__", [](const Parameter &p) -> std::string { + std::ostringstream o; + o << ""; + return o.str(); + }) + .def("type", &Parameter::type) + .def("dimensions", &Parameter::dimensions) + .def("name", &Parameter::name) + .def("is_buffer", &Parameter::is_buffer) + .def("scalar_expr", &Parameter::scalar_expr) + .def("set_scalar", set_scalar_method, py::arg("value_type"), py::arg("value")) + .def("buffer", &Parameter::buffer) + .def("set_buffer", &Parameter::set_buffer, py::arg("buffer")) + .def("same_as", &Parameter::same_as, py::arg("other")) + .def("defined", &Parameter::defined) + .def("set_min_constraint", &Parameter::set_min_constraint, py::arg("dim"), py::arg("expr")) + .def("set_extent_constraint", &Parameter::set_extent_constraint, py::arg("dim"), py::arg("expr")) + .def("set_stride_constraint", &Parameter::set_stride_constraint, py::arg("dim"), py::arg("expr")) + .def("set_min_constraint_estimate", &Parameter::set_min_constraint_estimate, py::arg("dim"), py::arg("expr")) + .def("set_extent_constraint_estimate", &Parameter::set_extent_constraint_estimate, py::arg("dim"), py::arg("expr")) + .def("set_host_alignment", &Parameter::set_host_alignment, py::arg("bytes")) + .def("min_constraint", &Parameter::min_constraint, py::arg("dim")) + .def("extent_constraint", &Parameter::extent_constraint, py::arg("dim")) + .def("stride_constraint", &Parameter::stride_constraint, py::arg("dim")) + .def("min_constraint_estimate", &Parameter::min_constraint_estimate, py::arg("dim")) + .def("extent_constraint_estimate", &Parameter::extent_constraint_estimate, py::arg("dim")) + .def("host_alignment", &Parameter::host_alignment) + .def("buffer_constraints", &Parameter::buffer_constraints) + .def("set_min_value", &Parameter::set_min_value, py::arg("expr")) + .def("min_value", &Parameter::min_value) + .def("set_max_value", &Parameter::set_max_value, py::arg("expr")) + .def("max_value", &Parameter::max_value) + .def("set_estimate", &Parameter::set_estimate, py::arg("expr")) + .def("estimate", &Parameter::estimate) + .def("set_default_value", &Parameter::set_default_value, py::arg("expr")) + .def("default_value", &Parameter::default_value) + .def("get_argument_estimates", &Parameter::get_argument_estimates) + .def("store_in", &Parameter::store_in, py::arg("memory_type")) + .def("memory_type", &Parameter::memory_type); + + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); + add_scalar_methods(parameter_class); +} + +} // namespace PythonBindings +} // namespace Halide diff --git a/python_bindings/src/halide/halide_/PyParameter.h b/python_bindings/src/halide/halide_/PyParameter.h new file mode 100644 index 000000000000..49f84743a9d9 --- /dev/null +++ b/python_bindings/src/halide/halide_/PyParameter.h @@ -0,0 +1,14 @@ +#ifndef HALIDE_PYTHON_BINDINGS_PYPARAMETER_H +#define HALIDE_PYTHON_BINDINGS_PYPARAMETER_H + +#include "PyHalide.h" + +namespace Halide { +namespace PythonBindings { + +void define_parameter(py::module &m); + +} // namespace PythonBindings +} // namespace Halide + +#endif // HALIDE_PYTHON_BINDINGS_PYPARAMETER_H diff --git a/python_bindings/stub/PyStubImpl.cpp b/python_bindings/stub/PyStubImpl.cpp index 4ca47edaa800..474f45c5e8c8 100644 --- a/python_bindings/stub/PyStubImpl.cpp +++ b/python_bindings/stub/PyStubImpl.cpp @@ -19,7 +19,6 @@ namespace py = pybind11; namespace Halide { namespace PythonBindings { -using Parameter = Internal::Parameter; using ArgInfoKind = Internal::ArgInfoKind; using ArgInfo = Internal::AbstractGenerator::ArgInfo; using GeneratorFactory = Internal::GeneratorFactory; diff --git a/src/AbstractGenerator.cpp b/src/AbstractGenerator.cpp index 41fbe8fa892d..d94232e55b61 100644 --- a/src/AbstractGenerator.cpp +++ b/src/AbstractGenerator.cpp @@ -8,7 +8,7 @@ namespace Internal { namespace { -Argument to_argument(const Internal::Parameter ¶m) { +Argument to_argument(const Parameter ¶m) { return Argument(param.name(), param.is_buffer() ? Argument::InputBuffer : Argument::InputScalar, param.type(), diff --git a/src/Deserialization.cpp b/src/Deserialization.cpp index d40c3d746893..c56badf7b887 100644 --- a/src/Deserialization.cpp +++ b/src/Deserialization.cpp @@ -1365,12 +1365,12 @@ Pipeline Deserializer::deserialize(std::istream &in) { } // namespace Internal -Pipeline deserialize_pipeline(const std::string &filename, const std::map &external_params) { +Pipeline deserialize_pipeline(const std::string &filename, const std::map &external_params) { Internal::Deserializer deserializer(external_params); return deserializer.deserialize(filename); } -Pipeline deserialize_pipeline(std::istream &in, const std::map &external_params) { +Pipeline deserialize_pipeline(std::istream &in, const std::map &external_params) { Internal::Deserializer deserializer(external_params); return deserializer.deserialize(in); } @@ -1381,12 +1381,12 @@ Pipeline deserialize_pipeline(std::istream &in, const std::map &external_params) { +Pipeline deserialize_pipeline(const std::string &filename, const std::map &external_params) { user_error << "Deserialization is not supported in this build of Halide; try rebuilding with WITH_SERIALIZATION=ON."; return Pipeline(); } -Pipeline deserialize_pipeline(std::istream &in, const std::map &external_params) { +Pipeline deserialize_pipeline(std::istream &in, const std::map &external_params) { user_error << "Deserialization is not supported in this build of Halide; try rebuilding with WITH_SERIALIZATION=ON."; return Pipeline(); } diff --git a/src/Deserialization.h b/src/Deserialization.h index 4ef48b60bdb7..b4c1f7fe369d 100644 --- a/src/Deserialization.h +++ b/src/Deserialization.h @@ -13,9 +13,9 @@ namespace Halide { * external_params is an optional map, all parameters in the map * will be treated as external parameters so won't be deserialized. */ -Pipeline deserialize_pipeline(const std::string &filename, const std::map &external_params); +Pipeline deserialize_pipeline(const std::string &filename, const std::map &external_params); -Pipeline deserialize_pipeline(std::istream &in, const std::map &external_params); +Pipeline deserialize_pipeline(std::istream &in, const std::map &external_params); } // namespace Halide diff --git a/src/Dimension.cpp b/src/Dimension.cpp index 4cb80a836a99..bb152d60c85f 100644 --- a/src/Dimension.cpp +++ b/src/Dimension.cpp @@ -7,7 +7,7 @@ namespace Halide { namespace Internal { -Dimension::Dimension(const Internal::Parameter &p, int d, Func f) +Dimension::Dimension(const Parameter &p, int d, Func f) : param(p), d(d), f(std::move(f)) { user_assert(param.defined()) << "Can't access the dimensions of an undefined Parameter\n"; diff --git a/src/Dimension.h b/src/Dimension.h index 629511f1341c..c386181248e1 100644 --- a/src/Dimension.h +++ b/src/Dimension.h @@ -84,9 +84,9 @@ class Dimension { friend class ::Halide::OutputImageParam; /** Construct a Dimension representing dimension d of some - * Internal::Parameter p. Only friends may construct + * Parameter p. Only friends may construct * these. */ - Dimension(const Internal::Parameter &p, int d, Func f); + Dimension(const Parameter &p, int d, Func f); Parameter param; int d; diff --git a/src/ExternFuncArgument.h b/src/ExternFuncArgument.h index ae0e476f360a..1c604818de20 100644 --- a/src/ExternFuncArgument.h +++ b/src/ExternFuncArgument.h @@ -24,7 +24,7 @@ struct ExternFuncArgument { Internal::FunctionPtr func; Buffer<> buffer; Expr expr; - Internal::Parameter image_param; + Parameter image_param; ExternFuncArgument(Internal::FunctionPtr f) : arg_type(FuncArg), func(std::move(f)) { @@ -44,7 +44,7 @@ struct ExternFuncArgument { : arg_type(ExprArg), expr(e) { } - ExternFuncArgument(const Internal::Parameter &p) + ExternFuncArgument(const Parameter &p) : arg_type(ImageParamArg), image_param(p) { // Scalar params come in via the Expr constructor. internal_assert(p.is_buffer()); diff --git a/src/Func.cpp b/src/Func.cpp index 170671fda478..121233aed7a5 100644 --- a/src/Func.cpp +++ b/src/Func.cpp @@ -1932,7 +1932,7 @@ Stage &Stage::prefetch(const Func &f, const VarOrRVar &at, const VarOrRVar &from return *this; } -Stage &Stage::prefetch(const Internal::Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset, PrefetchBoundStrategy strategy) { +Stage &Stage::prefetch(const Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset, PrefetchBoundStrategy strategy) { definition.schedule().touched() = true; PrefetchDirective prefetch = {param.name(), at.name(), from.name(), std::move(offset), strategy, param}; definition.schedule().prefetches().push_back(prefetch); @@ -2629,7 +2629,7 @@ Func &Func::prefetch(const Func &f, const VarOrRVar &at, const VarOrRVar &from, return *this; } -Func &Func::prefetch(const Internal::Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset, PrefetchBoundStrategy strategy) { +Func &Func::prefetch(const Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset, PrefetchBoundStrategy strategy) { invalidate_cache(); Stage(func, func.definition(), 0).prefetch(param, at, from, std::move(offset), strategy); return *this; diff --git a/src/Func.h b/src/Func.h index f38e113c6cbc..0a9c9eba4fe1 100644 --- a/src/Func.h +++ b/src/Func.h @@ -442,7 +442,7 @@ class Stage { Stage &prefetch(const Func &f, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, PrefetchBoundStrategy strategy = PrefetchBoundStrategy::GuardWithIf); - Stage &prefetch(const Internal::Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, + Stage &prefetch(const Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, PrefetchBoundStrategy strategy = PrefetchBoundStrategy::GuardWithIf); template Stage &prefetch(const T &image, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, @@ -1982,7 +1982,7 @@ class Func { // @{ Func &prefetch(const Func &f, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, PrefetchBoundStrategy strategy = PrefetchBoundStrategy::GuardWithIf); - Func &prefetch(const Internal::Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, + Func &prefetch(const Parameter ¶m, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, PrefetchBoundStrategy strategy = PrefetchBoundStrategy::GuardWithIf); template Func &prefetch(const T &image, const VarOrRVar &at, const VarOrRVar &from, Expr offset = 1, diff --git a/src/Function.h b/src/Function.h index 807335834266..66b62a01f66b 100644 --- a/src/Function.h +++ b/src/Function.h @@ -17,8 +17,8 @@ namespace Halide { struct ExternFuncArgument; +class Parameter; class Tuple; - class Var; /** An enum to specify calling convention for extern stages. */ @@ -31,7 +31,6 @@ enum class NameMangling { namespace Internal { struct Call; -class Parameter; /** A reference-counted handle to Halide's internal representation of * a function. Similar to a front-end Func object, but with no diff --git a/src/Generator.cpp b/src/Generator.cpp index 67a132a4d4d9..7637df5774e9 100644 --- a/src/Generator.cpp +++ b/src/Generator.cpp @@ -1645,7 +1645,7 @@ bool GeneratorBase::emit_hlpipe(const std::string &hlpipe_file_path) { debug(1) << "Applying autoscheduler " << asp.name << " to Generator " << name() << " ...\n"; auto_schedule_results = pipeline.apply_autoscheduler(context.target(), asp); } - std::map params; // FIXME: Remove when API allows this to be optional + std::map params; // FIXME: Remove when API allows this to be optional serialize_pipeline(pipeline, hlpipe_file_path, params); return true; #else diff --git a/src/ImageParam.cpp b/src/ImageParam.cpp index ca1b5d3922ac..7e72ff2ab47b 100644 --- a/src/ImageParam.cpp +++ b/src/ImageParam.cpp @@ -6,7 +6,7 @@ namespace Halide { ImageParam::ImageParam(Type t, int d) : OutputImageParam( - Internal::Parameter(t, true, d, Internal::make_entity_name(this, "Halide:.*:ImageParam", 'p')), + Parameter(t, true, d, Internal::make_entity_name(this, "Halide:.*:ImageParam", 'p')), Argument::InputBuffer, Func()) { // We must call create_func() after the super-ctor has completed. @@ -15,7 +15,7 @@ ImageParam::ImageParam(Type t, int d) ImageParam::ImageParam(Type t, int d, const std::string &n) : OutputImageParam( - Internal::Parameter(t, true, d, n), + Parameter(t, true, d, n), Argument::InputBuffer, Func()) { // We must call create_func() after the super-ctor has completed. diff --git a/src/ImageParam.h b/src/ImageParam.h index d294b731df2f..dd9ac6b2820d 100644 --- a/src/ImageParam.h +++ b/src/ImageParam.h @@ -25,7 +25,7 @@ class ImageParam : public OutputImageParam { friend class ::Halide::Internal::GeneratorInput_Buffer; // Only for use of Generator - ImageParam(const Internal::Parameter &p, Func f) + ImageParam(const Parameter &p, Func f) : OutputImageParam(p, Argument::InputBuffer, std::move(f)) { } diff --git a/src/Memoization.cpp b/src/Memoization.cpp index ba259a46c76e..d07914591cc5 100644 --- a/src/Memoization.cpp +++ b/src/Memoization.cpp @@ -30,9 +30,9 @@ class FindParameterDependencies : public IRGraphVisitor { for (const auto &extern_arg : extern_args) { if (extern_arg.is_buffer()) { // Function with an extern definition - record(Halide::Internal::Parameter(extern_arg.buffer.type(), true, - extern_arg.buffer.dimensions(), - extern_arg.buffer.name())); + record(Halide::Parameter(extern_arg.buffer.type(), true, + extern_arg.buffer.dimensions(), + extern_arg.buffer.name())); } else if (extern_arg.is_image_param()) { record(extern_arg.image_param); } diff --git a/src/OutputImageParam.cpp b/src/OutputImageParam.cpp index 0a668c3395a9..63e31e8c1e0e 100644 --- a/src/OutputImageParam.cpp +++ b/src/OutputImageParam.cpp @@ -7,7 +7,7 @@ namespace Halide { using Internal::Dimension; -OutputImageParam::OutputImageParam(const Internal::Parameter &p, Argument::Kind k, Func f) +OutputImageParam::OutputImageParam(const Parameter &p, Argument::Kind k, Func f) : param(p), kind(k), func(std::move(f)) { } @@ -79,7 +79,7 @@ Expr OutputImageParam::channels() const { return dim(2).extent(); } -Internal::Parameter OutputImageParam::parameter() const { +Parameter OutputImageParam::parameter() const { return param; } diff --git a/src/OutputImageParam.h b/src/OutputImageParam.h index c5b6b30371c7..378f21e74d54 100644 --- a/src/OutputImageParam.h +++ b/src/OutputImageParam.h @@ -21,7 +21,7 @@ class OutputImageParam { friend class Func; /** A reference-counted handle on the internal parameter object */ - Internal::Parameter param; + Parameter param; /** Is this an input or an output? OutputImageParam is the base class for both. */ Argument::Kind kind = Argument::InputScalar; @@ -37,7 +37,7 @@ class OutputImageParam { bool *placeholder_seen) const; /** Construct an OutputImageParam that wraps an Internal Parameter object. */ - OutputImageParam(const Internal::Parameter &p, Argument::Kind k, Func f); + OutputImageParam(const Parameter &p, Argument::Kind k, Func f); public: /** Construct a null image parameter handle. */ @@ -99,7 +99,7 @@ class OutputImageParam { Expr channels() const; /** Get at the internal parameter object representing this ImageParam. */ - Internal::Parameter parameter() const; + Parameter parameter() const; /** Construct the appropriate argument matching this parameter, * for the purpose of generating the right type signature when diff --git a/src/Param.h b/src/Param.h index 03fb58bef6aa..a8e8864059c7 100644 --- a/src/Param.h +++ b/src/Param.h @@ -21,7 +21,7 @@ namespace Halide { template class Param { /** A reference-counted handle on the internal parameter object */ - Internal::Parameter param; + Parameter param; // This is a deliberately non-existent type that allows us to compile Param<> // but provide less-confusing error messages if you attempt to call get<> or set<> @@ -314,11 +314,11 @@ class Param { param.get_argument_estimates()); } - const Internal::Parameter ¶meter() const { + const Parameter ¶meter() const { return param; } - Internal::Parameter ¶meter() { + Parameter ¶meter() { return param; } }; @@ -328,7 +328,7 @@ class Param { * (e.g. to pass the user context to an extern function written in C). */ inline Expr user_context_value() { return Internal::Variable::make(Handle(), "__user_context", - Internal::Parameter(Handle(), false, 0, "__user_context")); + Parameter(Handle(), false, 0, "__user_context")); } } // namespace Halide diff --git a/src/Parameter.cpp b/src/Parameter.cpp index d0fa297b6fbf..1155d5468f30 100644 --- a/src/Parameter.cpp +++ b/src/Parameter.cpp @@ -44,6 +44,8 @@ void destroy(const ParameterContents *p) { delete p; } +} // namespace Internal + void Parameter::check_defined() const { user_assert(defined()) << "Parameter is undefined\n"; } @@ -71,19 +73,19 @@ void Parameter::check_type(const Type &t) const { } Parameter::Parameter(const Type &t, bool is_buffer, int d) - : contents(new ParameterContents(t, is_buffer, d, unique_name('p'))) { + : contents(new Internal::ParameterContents(t, is_buffer, d, Internal::unique_name('p'))) { internal_assert(is_buffer || d == 0) << "Scalar parameters should be zero-dimensional"; } Parameter::Parameter(const Type &t, bool is_buffer, int d, const std::string &name) - : contents(new ParameterContents(t, is_buffer, d, name)) { + : contents(new Internal::ParameterContents(t, is_buffer, d, name)) { internal_assert(is_buffer || d == 0) << "Scalar parameters should be zero-dimensional"; } Parameter::Parameter(const Type &t, bool is_buffer, int dimensions, const std::string &name, const Buffer &buffer, int host_alignment, const std::vector &buffer_constraints, MemoryType memory_type) - : contents(new ParameterContents(t, is_buffer, dimensions, name)) { + : contents(new Internal::ParameterContents(t, is_buffer, dimensions, name)) { contents->buffer = buffer; contents->host_alignment = host_alignment; contents->buffer_constraints = buffer_constraints; @@ -93,7 +95,7 @@ Parameter::Parameter(const Type &t, bool is_buffer, int dimensions, const std::s Parameter::Parameter(const Type &t, bool is_buffer, int dimensions, const std::string &name, uint64_t data, const Expr &scalar_default, const Expr &scalar_min, const Expr &scalar_max, const Expr &scalar_estimate) - : contents(new ParameterContents(t, is_buffer, dimensions, name)) { + : contents(new Internal::ParameterContents(t, is_buffer, dimensions, name)) { contents->data = data; contents->scalar_default = scalar_default; contents->scalar_min = scalar_min; @@ -151,7 +153,7 @@ Expr Parameter::scalar_expr() const { } else if (t.is_uint()) { switch (t.bits()) { case 1: - return make_bool(scalar()); + return Internal::make_bool(scalar()); case 8: return Expr(scalar()); case 16: @@ -220,6 +222,8 @@ bool Parameter::defined() const { // parameter itself, to avoid creating a reference count cycle and causing a // leak. Note that it's still possible to create a cycle by having two different // Parameters each have constraints that reference the other. +namespace Internal { + Expr remove_self_references(const Parameter &p, const Expr &e) { class RemoveSelfReferences : public IRMutator { using IRMutator::visit; @@ -251,8 +255,8 @@ Expr restore_self_references(const Parameter &p, const Expr &e) { if (!var->image.defined() && !var->param.defined() && !var->reduction_domain.defined() && - starts_with(var->name, p.name() + ".")) { - return Variable::make(var->type, var->name, p); + Internal::starts_with(var->name, p.name() + ".")) { + return Internal::Variable::make(var->type, var->name, p); } return var; } @@ -266,34 +270,36 @@ Expr restore_self_references(const Parameter &p, const Expr &e) { return mutator.mutate(e); } +} // namespace Internal + void Parameter::set_min_constraint(int dim, const Expr &e) { check_is_buffer(); check_dim_ok(dim); - contents->buffer_constraints[dim].min = remove_self_references(*this, e); + contents->buffer_constraints[dim].min = Internal::remove_self_references(*this, e); } void Parameter::set_extent_constraint(int dim, const Expr &e) { check_is_buffer(); check_dim_ok(dim); - contents->buffer_constraints[dim].extent = remove_self_references(*this, e); + contents->buffer_constraints[dim].extent = Internal::remove_self_references(*this, e); } void Parameter::set_stride_constraint(int dim, const Expr &e) { check_is_buffer(); check_dim_ok(dim); - contents->buffer_constraints[dim].stride = remove_self_references(*this, e); + contents->buffer_constraints[dim].stride = Internal::remove_self_references(*this, e); } void Parameter::set_min_constraint_estimate(int dim, const Expr &min) { check_is_buffer(); check_dim_ok(dim); - contents->buffer_constraints[dim].min_estimate = remove_self_references(*this, min); + contents->buffer_constraints[dim].min_estimate = Internal::remove_self_references(*this, min); } void Parameter::set_extent_constraint_estimate(int dim, const Expr &extent) { check_is_buffer(); check_dim_ok(dim); - contents->buffer_constraints[dim].extent_estimate = remove_self_references(*this, extent); + contents->buffer_constraints[dim].extent_estimate = Internal::remove_self_references(*this, extent); } void Parameter::set_host_alignment(int bytes) { @@ -304,31 +310,31 @@ void Parameter::set_host_alignment(int bytes) { Expr Parameter::min_constraint(int dim) const { check_is_buffer(); check_dim_ok(dim); - return restore_self_references(*this, contents->buffer_constraints[dim].min); + return Internal::restore_self_references(*this, contents->buffer_constraints[dim].min); } Expr Parameter::extent_constraint(int dim) const { check_is_buffer(); check_dim_ok(dim); - return restore_self_references(*this, contents->buffer_constraints[dim].extent); + return Internal::restore_self_references(*this, contents->buffer_constraints[dim].extent); } Expr Parameter::stride_constraint(int dim) const { check_is_buffer(); check_dim_ok(dim); - return restore_self_references(*this, contents->buffer_constraints[dim].stride); + return Internal::restore_self_references(*this, contents->buffer_constraints[dim].stride); } Expr Parameter::min_constraint_estimate(int dim) const { check_is_buffer(); check_dim_ok(dim); - return restore_self_references(*this, contents->buffer_constraints[dim].min_estimate); + return Internal::restore_self_references(*this, contents->buffer_constraints[dim].min_estimate); } Expr Parameter::extent_constraint_estimate(int dim) const { check_is_buffer(); check_dim_ok(dim); - return restore_self_references(*this, contents->buffer_constraints[dim].extent_estimate); + return Internal::restore_self_references(*this, contents->buffer_constraints[dim].extent_estimate); } int Parameter::host_alignment() const { @@ -431,6 +437,18 @@ ArgumentEstimates Parameter::get_argument_estimates() const { return argument_estimates; } +void Parameter::store_in(MemoryType memory_type) { + check_is_buffer(); + contents->memory_type = memory_type; +} + +MemoryType Parameter::memory_type() const { + // check_is_buffer(); + return contents->memory_type; +} + +namespace Internal { + void check_call_arg_types(const std::string &name, std::vector *args, int dims) { user_assert(args->size() == (size_t)dims) << args->size() << "-argument call to \"" @@ -451,15 +469,5 @@ void check_call_arg_types(const std::string &name, std::vector *args, int } } -void Parameter::store_in(MemoryType memory_type) { - check_is_buffer(); - contents->memory_type = memory_type; -} - -MemoryType Parameter::memory_type() const { - // check_is_buffer(); - return contents->memory_type; -} - } // namespace Internal } // namespace Halide diff --git a/src/Parameter.h b/src/Parameter.h index 6ce9916abce7..712380c2576e 100644 --- a/src/Parameter.h +++ b/src/Parameter.h @@ -19,15 +19,19 @@ struct Expr; struct Type; enum class MemoryType; -namespace Internal { - -struct ParameterContents; - struct BufferConstraint { Expr min, extent, stride; Expr min_estimate, extent_estimate; }; +namespace Internal { +#ifdef WITH_SERIALIZATION +class Serializer; +#endif +struct ParameterContents; + +} // namespace Internal + /** A reference-counted handle to a parameter to a halide * pipeline. May be a scalar parameter or a buffer */ class Parameter { @@ -38,7 +42,24 @@ class Parameter { void check_type(const Type &t) const; protected: - IntrusivePtr contents; + Internal::IntrusivePtr contents; + +#ifdef WITH_SERIALIZATION + friend class Internal::Serializer; //< for scalar_raw_value() +#endif + friend class Pipeline; //< for scalar_address() + + /** Get the raw currently-bound buffer. null if unbound */ + const halide_buffer_t *raw_buffer() const; + + /** Get the pointer to the current value of the scalar + * parameter. For a given parameter, this address will never + * change. Only relevant when jitting. */ + void *scalar_address() const; + + /** Get the raw data of the current value of the scalar + * parameter. Only relevant when serializing. */ + uint64_t scalar_raw_value() const; public: /** Construct a new undefined handle */ @@ -117,22 +138,10 @@ class Parameter { * bound buffer. Only relevant when jitting */ Buffer buffer() const; - /** Get the raw currently-bound buffer. null if unbound */ - const halide_buffer_t *raw_buffer() const; - /** If the parameter is a buffer parameter, set its current * value. Only relevant when jitting */ void set_buffer(const Buffer &b); - /** Get the pointer to the current value of the scalar - * parameter. For a given parameter, this address will never - * change. Only relevant when jitting. */ - void *scalar_address() const; - - /** Get the raw data of the current value of the scalar - * parameter. Only relevant when serializing. */ - uint64_t scalar_raw_value() const; - /** Tests if this handle is the same as another handle */ bool same_as(const Parameter &other) const; @@ -193,6 +202,8 @@ class Parameter { MemoryType memory_type() const; }; +namespace Internal { + /** Validate arguments to a call to a func, image or imageparam. */ void check_call_arg_types(const std::string &name, std::vector *args, int dims); diff --git a/src/Serialization.cpp b/src/Serialization.cpp index c2cde6818884..cc9daa9fe325 100644 --- a/src/Serialization.cpp +++ b/src/Serialization.cpp @@ -40,7 +40,7 @@ class Serializer { // A lookup table for finding parameters via their names, // used for preventing the same parameter being serialized multiple times - std::map parameters_in_pipeline; + std::map parameters_in_pipeline; // A lookup table for finding buffers via their names, // used for preventing the same buffer being serialized multiple times @@ -1464,7 +1464,7 @@ void Serializer::serialize(const Pipeline &pipeline, const std::string &filename } // namespace Internal -void serialize_pipeline(const Pipeline &pipeline, const std::string &filename, std::map ¶ms) { +void serialize_pipeline(const Pipeline &pipeline, const std::string &filename, std::map ¶ms) { Internal::Serializer serializer; serializer.serialize(pipeline, filename); params = serializer.get_external_parameters(); @@ -1476,7 +1476,7 @@ void serialize_pipeline(const Pipeline &pipeline, const std::string &filename, s namespace Halide { -void serialize_pipeline(const Pipeline &pipeline, const std::string &filename, std::map ¶ms) { +void serialize_pipeline(const Pipeline &pipeline, const std::string &filename, std::map ¶ms) { user_error << "Serialization is not supported in this build of Halide; try rebuilding with WITH_SERIALIZATION=ON."; } diff --git a/src/Serialization.h b/src/Serialization.h index 85d2c86dae47..ebbcee484147 100644 --- a/src/Serialization.h +++ b/src/Serialization.h @@ -5,7 +5,7 @@ namespace Halide { -void serialize_pipeline(const Pipeline &pipeline, const std::string &filename, std::map ¶ms); +void serialize_pipeline(const Pipeline &pipeline, const std::string &filename, std::map ¶ms); } // namespace Halide