diff --git a/src/AbstractGenerator.cpp b/src/AbstractGenerator.cpp index f6229d4cbf7d..cdcc80c4800a 100644 --- a/src/AbstractGenerator.cpp +++ b/src/AbstractGenerator.cpp @@ -41,9 +41,11 @@ Module AbstractGenerator::build_module(const std::string &function_name) { } Module result = pipeline.compile_to_module(filter_arguments, function_name, context.target(), linkage_type); +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE for (const auto &map_entry : external_code_map()) { result.append(map_entry.second); } +#endif for (const auto &a : arg_infos) { if (a.dir != ArgInfoDirection::Output) { @@ -221,8 +223,10 @@ Module AbstractGenerator::build_gradient_module(const std::string &function_name } Module result = grad_pipeline.compile_to_module(gradient_inputs, function_name, context.target(), linkage_type); +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE user_assert(external_code_map().empty()) << "Building a gradient-descent module for a Generator with ExternalCode is not supported.\n"; +#endif result.set_auto_scheduler_results(auto_schedule_results); return result; diff --git a/src/AbstractGenerator.h b/src/AbstractGenerator.h index 48cd80e4e0ff..28dc9335b0f3 100644 --- a/src/AbstractGenerator.h +++ b/src/AbstractGenerator.h @@ -30,7 +30,9 @@ enum class ArgInfoKind { Scalar, enum class ArgInfoDirection { Input, Output }; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE using ExternsMap = std::map; +#endif /** * AbstractGenerator is an ABC that defines the API a Generator must provide @@ -151,12 +153,14 @@ class AbstractGenerator { */ virtual std::vector output_func(const std::string &name) = 0; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE /** Return the ExternsMap for the Generator, if any. * * CALL-AFTER: build_pipeline() * CALL-BEFORE: n/a */ virtual ExternsMap external_code_map() = 0; +#endif /** Rebind a specified Input to refer to the given piece of IR, replacing the * default ImageParam / Param in place for that Input. Basic type-checking is diff --git a/src/CodeGen_C.cpp b/src/CodeGen_C.cpp index d1e7b816ac81..e9ab248757fa 100644 --- a/src/CodeGen_C.cpp +++ b/src/CodeGen_C.cpp @@ -1751,6 +1751,7 @@ void CodeGen_C::compile(const Module &input) { stream << "\n"; if (!is_header_or_extern_decl()) { +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE // Emit any external-code blobs that are C++. for (const ExternalCode &code_blob : input.external_code()) { if (code_blob.is_c_plus_plus_source()) { @@ -1762,6 +1763,7 @@ void CodeGen_C::compile(const Module &input) { stream << "\n"; } } +#endif add_vector_typedefs(type_info.vector_types_used); diff --git a/src/CodeGen_LLVM.cpp b/src/CodeGen_LLVM.cpp index c893a74b0ef4..60b53f60b1f8 100644 --- a/src/CodeGen_LLVM.cpp +++ b/src/CodeGen_LLVM.cpp @@ -338,6 +338,7 @@ void CodeGen_LLVM::init_module() { module = get_initial_module_for_target(target, context); } +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE void CodeGen_LLVM::add_external_code(const Module &halide_module) { for (const ExternalCode &code_blob : halide_module.external_code()) { if (code_blob.is_for_cpu_target(get_target())) { @@ -345,6 +346,7 @@ void CodeGen_LLVM::add_external_code(const Module &halide_module) { } } } +#endif CodeGen_LLVM::~CodeGen_LLVM() { delete builder; @@ -503,7 +505,9 @@ std::unique_ptr CodeGen_LLVM::compile(const Module &input) { internal_assert(module && context && builder) << "The CodeGen_LLVM subclass should have made an initial module before calling CodeGen_LLVM::compile\n"; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE add_external_code(input); +#endif // Generate the code for this module. debug(1) << "Generating llvm bitcode...\n"; diff --git a/src/CodeGen_LLVM.h b/src/CodeGen_LLVM.h index 0e5abf35f9de..da31f5a1cd19 100644 --- a/src/CodeGen_LLVM.h +++ b/src/CodeGen_LLVM.h @@ -177,8 +177,10 @@ class CodeGen_LLVM : public IRVisitor { * multiple related modules (e.g. multiple device kernels). */ virtual void init_module(); +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE /** Add external_code entries to llvm module. */ void add_external_code(const Module &halide_module); +#endif /** Run all of llvm's optimization passes on the module. */ void optimize_module(); diff --git a/src/ExternalCode.h b/src/ExternalCode.h index 7e75eabc9e53..8de876afc394 100644 --- a/src/ExternalCode.h +++ b/src/ExternalCode.h @@ -1,6 +1,8 @@ #ifndef HALIDE_EXTERNAL_CODE_H #define HALIDE_EXTERNAL_CODE_H +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE + #include #include "Expr.h" @@ -131,4 +133,10 @@ class ExternalCode { } // namespace Halide +#else + +#error "ExternalCode is deprecated in Halide 15 and will be removed in Halide 16" + +#endif // HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE + #endif diff --git a/src/Generator.cpp b/src/Generator.cpp index c77e35bbf5f2..d0254c3206bf 100644 --- a/src/Generator.cpp +++ b/src/Generator.cpp @@ -19,6 +19,7 @@ namespace Halide { +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE GeneratorContext::GeneratorContext(const Target &target, bool auto_schedule, const MachineParams &machine_params, @@ -28,18 +29,27 @@ GeneratorContext::GeneratorContext(const Target &target, machine_params_(machine_params), externs_map_(std::move(externs_map)) { } +#endif GeneratorContext::GeneratorContext(const Target &target, bool auto_schedule, const MachineParams &machine_params) - : GeneratorContext(target, - auto_schedule, - machine_params, - std::make_shared()) { + : target_(target), + auto_schedule_(auto_schedule), + machine_params_(machine_params) +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE + , + externs_map_(std::make_shared()) +#endif +{ } GeneratorContext GeneratorContext::with_target(const Target &t) const { +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE return GeneratorContext(t, auto_schedule_, machine_params_, externs_map_); +#else + return GeneratorContext(t, auto_schedule_, machine_params_); +#endif } namespace Internal { @@ -1292,7 +1302,11 @@ GeneratorOutputBase *GeneratorBase::find_output_by_name(const std::string &name) } GeneratorContext GeneratorBase::context() const { +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE return GeneratorContext(target, auto_schedule, machine_params, externs_map); +#else + return GeneratorContext(target, auto_schedule, machine_params); +#endif } void GeneratorBase::init_from_context(const Halide::GeneratorContext &context) { @@ -1300,7 +1314,9 @@ void GeneratorBase::init_from_context(const Halide::GeneratorContext &context) { auto_schedule.set(context.auto_schedule_); machine_params.set(context.machine_params_); +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE externs_map = context.externs_map_; +#endif // pre-emptively build our param_info now internal_assert(param_info_ptr == nullptr); @@ -1534,10 +1550,12 @@ std::vector GeneratorBase::output_func(const std::string &n) { return output->funcs(); } +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE ExternsMap GeneratorBase::external_code_map() { // get_externs_map() returns a std::shared_ptr return *get_externs_map(); } +#endif void GeneratorBase::bind_input(const std::string &name, const std::vector &v) { ensure_configure_has_been_called(); diff --git a/src/Generator.h b/src/Generator.h index 96ca0086e393..e5f254e82b36 100644 --- a/src/Generator.h +++ b/src/Generator.h @@ -272,7 +272,9 @@ #include #include "AbstractGenerator.h" +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE #include "ExternalCode.h" +#endif #include "Func.h" #include "ImageParam.h" #include "Introspection.h" @@ -3028,7 +3030,9 @@ class GeneratorContext { public: friend class Internal::GeneratorBase; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE using ExternsMap = std::map; +#endif explicit GeneratorContext(const Target &t, bool auto_schedule = false, @@ -3083,12 +3087,16 @@ class GeneratorContext { Target target_; bool auto_schedule_ = false; MachineParams machine_params_ = MachineParams::generic(); +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE std::shared_ptr externs_map_; +#endif +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE GeneratorContext(const Target &target, bool auto_schedule, const MachineParams &machine_params, std::shared_ptr externs_map); +#endif }; class NamesInterface { @@ -3514,6 +3522,8 @@ class GeneratorBase : public NamesInterface, public AbstractGenerator { MachineParams get_machine_params() const { return machine_params; } + +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE /** Generators can register ExternalCode objects onto * themselves. The Generator infrastructure will arrange to have * this ExternalCode appended to the Module that is finally @@ -3532,6 +3542,11 @@ class GeneratorBase : public NamesInterface, public AbstractGenerator { std::shared_ptr get_externs_map() const { return externs_map; } +#else + /** ExternalCode objects in Generator are deprecated in Halide 15 and will + * be removed in Halide 16. You may continue to use them in Halide 15 + * by defining HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE when building Halide. */ +#endif // These must remain here for legacy code that access the fields directly. GeneratorParam target{"target", Target()}; @@ -3548,7 +3563,9 @@ class GeneratorBase : public NamesInterface, public AbstractGenerator { friend class StubOutputBufferBase; const size_t size; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE std::shared_ptr externs_map; +#endif // Lazily-allocated-and-inited struct with info about our various Params. // Do not access directly: use the param_info() getter. @@ -3746,7 +3763,9 @@ class GeneratorBase : public NamesInterface, public AbstractGenerator { std::vector input_parameter(const std::string &name) override; std::vector output_func(const std::string &name) override; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE ExternsMap external_code_map() override; +#endif // This is overridden in the concrete Generator<> subclass. // Pipeline build_pipeline() override; diff --git a/src/Module.cpp b/src/Module.cpp index 6c0c820f8876..aae1064bd65c 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -329,7 +329,9 @@ struct ModuleContents { std::vector> buffers; std::vector functions; std::vector submodules; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE std::vector external_code; +#endif MetadataNameMap metadata_name_map; bool any_strict_float{false}; std::unique_ptr auto_scheduler_results; @@ -415,9 +417,11 @@ const std::vector &Module::submodules() const { return contents->submodules; } +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE const std::vector &Module::external_code() const { return contents->external_code; } +#endif Internal::LoweredFunc Module::get_function_by_name(const std::string &name) const { for (const auto &f : functions()) { @@ -441,9 +445,11 @@ void Module::append(const Module &module) { contents->submodules.push_back(module); } +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE void Module::append(const ExternalCode &external_code) { contents->external_code.push_back(external_code); } +#endif Module link_modules(const std::string &name, const std::vector &modules) { Module output(name, modules.front().target()); @@ -511,12 +517,15 @@ Module Module::resolve_submodules() const { for (const auto &buf : buffers()) { lowered_module.append(buf); } +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE for (const auto &ec : external_code()) { lowered_module.append(ec); } +#endif for (const auto &m : submodules()) { Module copy(m.resolve_submodules()); +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE // Propagate external code blocks. for (const auto &ec : external_code()) { // TODO(zalman): Is this the right thing to do? @@ -531,6 +540,7 @@ Module Module::resolve_submodules() const { copy.append(ec); } } +#endif auto buf = copy.compile_to_buffer(); lowered_module.append(buf); diff --git a/src/Module.h b/src/Module.h index 38394811f3f7..99ccd19065b6 100644 --- a/src/Module.h +++ b/src/Module.h @@ -13,7 +13,9 @@ #include "Argument.h" #include "Expr.h" +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE #include "ExternalCode.h" +#endif #include "Function.h" // for NameMangling #include "ModulusRemainder.h" @@ -161,7 +163,9 @@ class Module { const std::vector &functions() const; std::vector &functions(); const std::vector &submodules() const; +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE const std::vector &external_code() const; +#endif // @} /** Return the function with the given name. If no such function @@ -173,7 +177,9 @@ class Module { void append(const Buffer &buffer); void append(const Internal::LoweredFunc &function); void append(const Module &module); +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE void append(const ExternalCode &external_code); +#endif // @} /** Compile a halide Module to variety of outputs, depending on diff --git a/src/Pipeline.h b/src/Pipeline.h index a432404baf1b..15e19652c107 100644 --- a/src/Pipeline.h +++ b/src/Pipeline.h @@ -12,7 +12,9 @@ #include #include +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE #include "ExternalCode.h" +#endif #include "IROperator.h" #include "IntrusivePtr.h" #include "JITModule.h" diff --git a/test/correctness/CMakeLists.txt b/test/correctness/CMakeLists.txt index c61023593271..1aee6cecdd0d 100644 --- a/test/correctness/CMakeLists.txt +++ b/test/correctness/CMakeLists.txt @@ -95,7 +95,6 @@ tests(GROUPS correctness extern_reorder_storage.cpp extern_sort.cpp extern_stage_on_device.cpp - external_code.cpp failed_unroll.cpp fast_trigonometric.cpp fibonacci.cpp diff --git a/test/correctness/external_code.cpp b/test/correctness/external_code.cpp deleted file mode 100644 index 87f8bcfa1437..000000000000 --- a/test/correctness/external_code.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "Halide.h" -#include "halide_test_dirs.h" - -#include -#include - -#include -#include - -using namespace Halide; - -int main(int argc, char **argv) { - if (get_jit_target_from_environment().arch == Target::WebAssembly) { - printf("[SKIP] Skipping test for WebAssembly as it does not support ExternalCode::bitcode_wrapper().\n"); - return 0; - } - - Var x("x"), y("y"); - Func f("f"); - - f(x, y) = 42; - - Target target = get_jit_target_from_environment(); - - std::string bitcode_file = Internal::get_test_tmp_dir() + "extern.bc"; - f.compile_to_bitcode(bitcode_file, {}, "extern", target); - - std::vector bitcode; - std::ifstream bitcode_stream(bitcode_file, std::ios::in | std::ios::binary); - bitcode_stream.seekg(0, std::ios::end); - bitcode.resize(bitcode_stream.tellg()); - bitcode_stream.seekg(0, std::ios::beg); - bitcode_stream.read(reinterpret_cast(&bitcode[0]), bitcode.size()); - - ExternalCode external_code = - ExternalCode::bitcode_wrapper(target, bitcode, "extern"); - - Func f_extern; - f_extern.define_extern("extern", {}, type_of(), 2); - - Func result; - result(x, y) = f_extern(x, y); - - Module module = result.compile_to_module({}, "forty_two", target); - - module.append(external_code); - - auto forty_two = module.get_function_by_name("forty_two"); - - Internal::JITModule jit_module(module, forty_two, {}); - - auto main_function = (int (*)(halide_buffer_t * buf)) jit_module.main_function(); - Buffer buf(16, 16); - - int ret_code = main_function(buf.raw_buffer()); - - assert(ret_code == 0); - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - assert(buf(i, j) == 42); - } - } - - printf("Success!\n"); - return 0; -} diff --git a/test/generator/CMakeLists.txt b/test/generator/CMakeLists.txt index 89f01b1a2701..e6f82c285641 100644 --- a/test/generator/CMakeLists.txt +++ b/test/generator/CMakeLists.txt @@ -64,41 +64,6 @@ function(halide_define_aot_test NAME) endif () endfunction() -## -# Define a nontrivial dependency for external_code.generator -## - -# external_code_extern.cpp -set(EXTERNAL_CPP "${CMAKE_CURRENT_SOURCE_DIR}/external_code_extern.cpp") - -set(EC32 "external_code_extern_bitcode_32") -add_custom_command(OUTPUT "${EC32}.bc" - COMMAND clang -O3 -c -m32 -target le32-unknown-nacl-unknown -emit-llvm "$" -o "${EC32}.bc" - DEPENDS "${EXTERNAL_CPP}" - VERBATIM) -add_custom_command(OUTPUT "${EC32}.cpp" - COMMAND binary2cpp external_code_extern_bitcode_32 < "${EC32}.bc" > "${EC32}.cpp" - DEPENDS "${EC32}.bc" binary2cpp - VERBATIM) - -set(EC64 "external_code_extern_bitcode_64") -add_custom_command(OUTPUT "${EC64}.bc" - COMMAND clang -O3 -c -m64 -target le64-unknown-unknown-unknown -emit-llvm "$" -o "${EC64}.bc" - DEPENDS "${EXTERNAL_CPP}" binary2cpp - VERBATIM) -add_custom_command(OUTPUT "${EC64}.cpp" - COMMAND binary2cpp external_code_extern_bitcode_64 < "${EC64}.bc" > "${EC64}.cpp" - DEPENDS "${EC64}.bc" binary2cpp - VERBATIM) - -set(ECCPP "external_code_extern_cpp_source") -add_custom_command(OUTPUT "${ECCPP}.cpp" - COMMAND binary2cpp external_code_extern_cpp_source < "$" > "${ECCPP}.cpp" - DEPENDS "${EXTERNAL_CPP}" binary2cpp - VERBATIM) - -add_library(external_code_generator_deps OBJECT "${EC32}.cpp" "${EC64}.cpp" "${ECCPP}.cpp") - ## # Some tests are not available when compiling for WASM. ## @@ -259,10 +224,6 @@ halide_define_aot_test(example halide_define_aot_test(extern_output GROUPS multithreaded) -# external_code_aottest.cpp -# external_code_generator.cpp -halide_define_aot_test(external_code GEN_DEPS external_code_generator_deps) - # float16_t_aottest.cpp # float16_t_generator.cpp halide_define_aot_test(float16_t) diff --git a/test/generator/abstractgeneratortest_generator.cpp b/test/generator/abstractgeneratortest_generator.cpp index 0c7da6fa985b..cedf16d58dd3 100644 --- a/test/generator/abstractgeneratortest_generator.cpp +++ b/test/generator/abstractgeneratortest_generator.cpp @@ -115,10 +115,12 @@ class AbstractGeneratorTest : public AbstractGenerator { return {}; } +#ifdef HALIDE_ALLOW_GENERATOR_EXTERNAL_CODE ExternsMap external_code_map() override { // none return {}; } +#endif void bind_input(const std::string &name, const std::vector &v) override { _halide_user_assert(false) << "OOPS"; diff --git a/test/generator/external_code_aottest.cpp b/test/generator/external_code_aottest.cpp deleted file mode 100644 index cd03f04b2692..000000000000 --- a/test/generator/external_code_aottest.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "HalideBuffer.h" -#include "HalideRuntime.h" - -#include -#include -#include -#include - -#include "external_code.h" - -using namespace std; -using namespace Halide::Runtime; - -int main() { - Buffer buf(10, 10); - - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 10; j++) { - buf(i, j) = i * 65536 + j * 256; - } - } - - Buffer out(10, 10); - int ret_code = external_code(buf.raw_buffer(), out.raw_buffer()); - - assert(ret_code == 0); - - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 10; j++) { - assert(out(i, j) == i * 65536 + j * 256 + 42); - } - } - printf("Success!\n"); - return 0; -} diff --git a/test/generator/external_code_extern.cpp b/test/generator/external_code_extern.cpp deleted file mode 100644 index e1915f3d3f0c..000000000000 --- a/test/generator/external_code_extern.cpp +++ /dev/null @@ -1,3 +0,0 @@ -extern "C" float gen_extern_tester(float in) { - return in + 42; -} diff --git a/test/generator/external_code_generator.cpp b/test/generator/external_code_generator.cpp deleted file mode 100644 index 49c5f4ce06f3..000000000000 --- a/test/generator/external_code_generator.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "Halide.h" - -extern "C" unsigned char external_code_extern_bitcode_32[]; -extern "C" int external_code_extern_bitcode_32_length; -extern "C" unsigned char external_code_extern_bitcode_64[]; -extern "C" int external_code_extern_bitcode_64_length; -extern "C" unsigned char external_code_extern_cpp_source[]; -extern "C" int external_code_extern_cpp_source_length; - -namespace { - -class ExternalCode : public Halide::Generator { -public: - GeneratorParam external_code_is_bitcode{"external_code_is_bitcode", true}; - Input> input{"input"}; - Output> output{"output"}; - HalidePureExtern_1(float, gen_extern_tester, float); - - void generate() { - Var x("x"), y("y"); - Func f("f"); - - unsigned char *code; - int code_length; - const char *name = "org.halide-lang.extern_code_extern"; - if (external_code_is_bitcode) { - Target target = get_target(); - if (target.bits == 64) { - code = external_code_extern_bitcode_64; - code_length = external_code_extern_bitcode_64_length; - } else { - code = external_code_extern_bitcode_32; - code_length = external_code_extern_bitcode_32_length; - } - std::vector code_vector(code, code + code_length); - get_externs_map()->insert({name, - Halide::ExternalCode::bitcode_wrapper(target, code_vector, name)}); - } else { - code = external_code_extern_cpp_source; - code_length = external_code_extern_cpp_source_length; - std::vector code_vector(code, code + code_length); - get_externs_map()->insert({name, - Halide::ExternalCode::c_plus_plus_code_wrapper(code_vector, name)}); - } - - output(x, y) = gen_extern_tester(cast(input(x, y))); - } - - void schedule() { - } -}; - -} // namespace - -HALIDE_REGISTER_GENERATOR(ExternalCode, external_code)