diff --git a/python_bindings/src/halide/halide_/PyImageParam.cpp b/python_bindings/src/halide/halide_/PyImageParam.cpp index 15985070f134..e410a386e809 100644 --- a/python_bindings/src/halide/halide_/PyImageParam.cpp +++ b/python_bindings/src/halide/halide_/PyImageParam.cpp @@ -44,12 +44,13 @@ void define_image_param(py::module &m) { .def("__repr__", [](const OutputImageParam &im) -> std::string { std::ostringstream o; - o << ""; return o.str(); @@ -79,12 +80,13 @@ void define_image_param(py::module &m) { .def("__repr__", [](const ImageParam &im) -> std::string { std::ostringstream o; - o << ""; return o.str(); diff --git a/python_bindings/src/halide/halide_/PyPipeline.cpp b/python_bindings/src/halide/halide_/PyPipeline.cpp index b636de6b9461..35ee2e85e902 100644 --- a/python_bindings/src/halide/halide_/PyPipeline.cpp +++ b/python_bindings/src/halide/halide_/PyPipeline.cpp @@ -277,13 +277,19 @@ void define_pipeline(py::module &m) { .def("__repr__", [](const Pipeline &p) -> std::string { std::ostringstream o; - o << ""; + o << ">"; return o.str(); // }); diff --git a/python_bindings/test/correctness/basics.py b/python_bindings/test/correctness/basics.py index c7d1cc4f8533..d8c88c839848 100644 --- a/python_bindings/test/correctness/basics.py +++ b/python_bindings/test/correctness/basics.py @@ -523,7 +523,6 @@ def test_unevaluated_funcref(): g = hl.Func("g") g[x] = 2 - print("------------------------") f = hl.Func("f") f[hl._] += g[hl._] assert list(f.realize([1])) == [2] @@ -582,6 +581,23 @@ def test_implicit_update_by_float(): assert f.realize([1])[0] == 0.5 +def test_print_ir(): + im = hl.ImageParam() + assert str(im) == "" + + im = hl.OutputImageParam() + assert str(im) == "" + + im = hl.ImageParam(hl.UInt(16), 2, "input") + assert str(im) == "" + + r = hl.RDom() + assert str(r) == "" + + p = hl.Pipeline() + assert str(p) == "" + + if __name__ == "__main__": test_compiletime_error() test_runtime_error() @@ -605,3 +621,4 @@ def test_implicit_update_by_float(): test_unevaluated_funcref() test_implicit_update_by_int() test_implicit_update_by_float() + test_print_ir() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 62aac6030602..557466c0d7e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -469,7 +469,9 @@ set(LICENSE_PATH "${Halide_SOURCE_DIR}/LICENSE.txt") set(headers "$") add_custom_command(OUTPUT "${HALIDE_H}" COMMAND ${CMAKE_COMMAND} -E make_directory "$" - COMMAND build_halide_h "$" "${headers}" > "$" + COMMAND build_halide_h "$" "${headers}" > "$.tmp" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "$.tmp" "$" + COMMAND ${CMAKE_COMMAND} -E rm "$.tmp" DEPENDS build_halide_h "${LICENSE_PATH}" "${headers}" WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" COMMAND_EXPAND_LISTS diff --git a/src/Func.cpp b/src/Func.cpp index 07f8dc41a90a..986c05a16318 100644 --- a/src/Func.cpp +++ b/src/Func.cpp @@ -85,6 +85,8 @@ Func::Func(const Expr &e) Func::Func(Function f) : func(std::move(f)) { + internal_assert(func.get_contents().defined()) + << "Can't construct Func from undefined Function"; } const string &Func::name() const { diff --git a/src/Func.h b/src/Func.h index dad266a49230..a28c099464a8 100644 --- a/src/Func.h +++ b/src/Func.h @@ -756,7 +756,7 @@ class Func { * not contain free variables). */ explicit Func(const Expr &e); - /** Construct a new Func to wrap an existing, already-define + /** Construct a new Func to wrap an existing, already-defined * Function object. */ explicit Func(Internal::Function f); diff --git a/test/error/CMakeLists.txt b/test/error/CMakeLists.txt index 5272b2717de7..d8bb0494b974 100644 --- a/test/error/CMakeLists.txt +++ b/test/error/CMakeLists.txt @@ -23,6 +23,7 @@ tests(GROUPS error bad_ring_buffer.cpp bad_extern_split.cpp bad_fold.cpp + bad_func_object.cpp bad_host_alignment.cpp bad_hoist_storage.cpp bad_partition_always.cpp diff --git a/test/error/bad_func_object.cpp b/test/error/bad_func_object.cpp new file mode 100644 index 000000000000..ad0f09ec8226 --- /dev/null +++ b/test/error/bad_func_object.cpp @@ -0,0 +1,23 @@ +#include "Halide.h" +using namespace Halide; + +int main() { +#ifdef HALIDE_WITH_EXCEPTIONS + try { +#endif + const Internal::Function func{}; + const Func f{func}; // internal_assert + + std::cout << f.name() << "\n"; // segfaults without above assert +#ifdef HALIDE_WITH_EXCEPTIONS + } catch (const InternalError &e) { + // The harness rejects internal errors as they should typically not be + // _expected_. However, we are directly testing a constructor invariant + // check here, so an internal error is both expected and appropriate. + throw std::runtime_error(e.what()); + } +#endif + + printf("Success!\n"); + return 0; +}