Moving existing custom_module sample to custom_module/basic/.
diff --git a/samples/custom_module/CMakeLists.txt b/samples/custom_module/CMakeLists.txt index dbfb002..1e70c9d 100644 --- a/samples/custom_module/CMakeLists.txt +++ b/samples/custom_module/CMakeLists.txt
@@ -4,27 +4,4 @@ # See https://llvm.org/LICENSE.txt for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -set(_NAME "iree_samples_custom_module_run") -add_executable(${_NAME} "") -target_sources(${_NAME} - PRIVATE - main.c - module.cc - module.h -) - -set_target_properties(${_NAME} PROPERTIES OUTPUT_NAME "custom-module-run") - -# TODO(benvanik): make iree_status_annotate_f always available as a function -# instead of defining it empty? otherwise optimized builds of the runtime won't -# export it but external libraries may pull it in. -target_compile_options(${_NAME} PRIVATE ${IREE_DEFAULT_COPTS}) - -target_link_libraries(${_NAME} - iree_base_base - iree_base_internal_file_io - iree_vm_vm - iree_vm_bytecode_module -) - -add_subdirectory(test) +iree_add_all_subdirs()
diff --git a/samples/custom_module/README.md b/samples/custom_module/README.md index bece021..5b603ed 100644 --- a/samples/custom_module/README.md +++ b/samples/custom_module/README.md
@@ -1,261 +1,15 @@ -# "Custom Module" sample +# "Custom Module" samples -This sample shows how to +These samples demonstrate how to extend IREE with custom host code that can be +called from compiled modules. All modules regardless of type can call into each +other to allow for arbitrary module configurations. -1. Create a custom module in C++ that can be used with the IREE runtime -2. Author an MLIR input that uses a custom module including a custom type -3. Compile that program to an IREE VM bytecode module -4. Load the compiled program using a low-level VM interface -5. Call exported functions on the loaded program to exercise the custom module +## Basic sample -The custom module is declared in [`module.h`](./module.h), implemented using a -C++ module wrapper layer in [`module.cc`](./module.cc), and called by example in -[`main.c`](./main.c). +[samples/custom_module/basic/](/samples/custom_module/basic/README.md) shows how +to add a basic C++ custom module and use many of the more advanced features of +the module system. -This document uses terminology that can be found in the documentation of -[IREE's execution model](https://github.com/iree-org/iree/blob/main/docs/developers/design_docs/execution_model.md). -See [IREE's extensibility mechanisms](https://iree-org.github.io/iree/extensions/) -documentation for more information specific to extenting IREE and -alternative approaches to doing so. - -## Background - -IREE's VM is used to dynamically link modules of various types together at -runtime (C, C++, IREE's VM bytecode, etc). Via this mechanism any number of -modules containing exported functions and types that can be used across modules -can extend IREE's base functionality. In most IREE programs the HAL module is -used to provide a hardware abstraction layer for execution and both the HAL -module itself and the types it exposes (`!hal.buffer`, `!hal.executable`, etc) -are implemented using this mechanism. - -## Instructions - -1. Build or install the `iree-compile` binary: - - ``` - python -m pip install iree-compiler - ``` - - [See here](https://iree-org.github.io/iree/getting-started/) - for general instructions on installing the compiler. - -3. Compile the [example module](./test/example.mlir) to a .vmfb file: - - ``` - # This simple sample doesn't use tensors and can be compiled in host-only - # mode to avoid the need for the HAL. - iree-compile --iree-execution-model=host-only samples/custom_module/test/example.mlir -o=/tmp/example.vmfb - ``` - -3. Build the `iree_samples_custom_module_run` CMake target : - - ``` - cmake -B ../iree-build/ -DCMAKE_BUILD_TYPE=RelWithDebInfo . \ - -DCMAKE_C_FLAGS=-DIREE_VM_EXECUTION_TRACING_FORCE_ENABLE=1 - cmake --build ../iree-build/ --target iree_samples_custom_module_run - ``` - (here we force runtime execution tracing for demonstration purposes) - - [See here](https://iree-org.github.io/iree/building-from-source/getting-started/) - for general instructions on building using CMake. - -4. Run the example program to call the main function: - - ``` - ../iree-build/samples/custom_module/custom-module-run \ - /tmp/example.vmfb example.main - ``` - -## Defining Custom Modules in C++ - -Modules are exposed to applications and the IREE VM via the `iree_vm_module_t` -interface. IREE canonically uses C headers to expose module and type functions -but the implementation of the module can be anything the user is able to work -with (C, C++, rust, etc). - -A C++ wrapper is provided to ease implementation when minimal code size and overhead is not a focus and provides easy definition of exports and marshaling -of types. Utilities such as `iree::Status` and `iree::vm::ref<T>` add safety for -managing reference counted resources and can be used within the modules. - -General flow: - -1. Expose module via a C API ([`module.h`](./module.h)): - -```c -// Ideally all allocations performed by the module should use |allocator|. -// The returned module in |out_module| should have a ref count of 1 to transfer -// ownership to the caller. -iree_status_t iree_table_module_create(iree_allocator_t allocator, - iree_vm_module_t** out_module); -``` - -2. Implement the module using C/C++/etc ([`module.cc`](./module.cc)): - -Modules have two parts: a shared module and instantiated state. - -The `iree::vm::NativeModule` helper is used to handle the shared module -declaration and acts as a factory for per-context instantiated state and the -methods exported by the module: - -```c++ -// Any mutable state stored on the module may be accessed from multiple threads -// if the module is instantiated in multiple contexts and must be thread-safe. -struct TableModule final : public vm::NativeModule<TableModuleState> { - // Each time the module is instantiated this will be called to allocate the - // context-specific state. The returned state must only be thread-compatible - // as invocations within a context will not be made from multiple threads but - // the thread on which they are made may change over time; this means no TLS! - StatusOr<std::unique_ptr<TableModuleState>> CreateState( - iree_allocator_t allocator) override; -}; -``` - -The module implementation is done on the state object so that methods may use -`this` to access context-local state: - -```c++ -struct TableModuleState final { - // Local to the context the module was instantiated in and thread-compatible. - std::unordered_map<std::string, std::string> mutable_state; - - // Exported functions must return Status or StatusOr. Failures will result in - // program termination and will be propagated up to the top-level invoker. - // If a module wants to provide non-fatal errors it can return results to the - // program: here we return a 0/1 indicating whether the key was found as well - // as the result or null. - // - // MLIR declaration: - // func.func private @table.lookup(!util.buffer) -> (i1, !util.buffer) - StatusOr<std::tuple<int32_t, vm::ref<iree_vm_buffer_t>>> Lookup( - const vm::ref<iree_vm_buffer_t> key); -}; -``` - -Finally the exported methods are registered and marshaling code is expanded: - -```c++ -static const vm::NativeFunction<TableModuleState> kTableModuleFunctions[] = { - vm::MakeNativeFunction("lookup", &TableModuleState::Lookup), -}; -extern "C" iree_status_t iree_table_module_create( - iree_allocator_t allocator, iree_vm_module_t** out_module) { - auto module = std::make_unique<TableModule>( - "table", /*version=*/0, allocator, - iree::span<const vm::NativeFunction<CustomModuleState>> - (kTableModuleFunctions)); - *out_module = module.release()->interface(); - return iree_ok_status(); -} -``` - -## Registering Custom Modules at Runtime - -Once a custom module is defined it needs to be provided to any context that it -is going to be used in. Each context may have its own unique mix of modules and -it's the hosting application's responsibility to inject the available modules. -See [`main.c`](./main.c) for an example showing the entire end-to-end lifetime -of loading a compiled bytecode module and providing a custom module for runtime -dynamic linking. - -Since modules themselves can be reused across contexts it can be a way of -creating shared caches (requires thread-safety!) that span contexts while the -module state is context specific and isolated. - -Import resolution happens in reverse registration order: the most recently -registered modules override previous ones. This combined with optional imports -allows overriding behavior and version compatibility shims (though there is -still some trickiness involved). - -```c -// Ensure custom types are registered before loading modules that use them. -// This only needs to be done once per instance. -IREE_CHECK_OK(iree_custom_module_register_types(instance)); - -// Create the custom module that can be reused across contexts. -iree_vm_module_t* custom_module = NULL; -IREE_CHECK_OK(iree_custom_module_create(instance, allocator, &custom_module)); - -// Create the context for this invocation reusing the loaded modules. -// Contexts hold isolated state and can be reused for multiple calls. -// Note that the module order matters: the input user module is dependent on -// the custom module. -iree_vm_module_t* modules[] = {custom_module, bytecode_module}; -iree_vm_context_t* context = NULL; -IREE_CHECK_OK(iree_vm_context_create_with_modules( - instance, IREE_VM_CONTEXT_FLAG_NONE, IREE_ARRAYSIZE(modules), modules, - allocator, &context)); -``` - -## Calling Custom Modules from Compiled Programs - -The IREE compiler allows for external functions that are resolved at runtime -using the [MLIR `func` dialect](https://mlir.llvm.org/docs/Dialects/Func/). Some -optional attributes are used to allow for customization where required but in -many cases no additional IREE-specific work is required in the compiled program. -A few advanced features of the VM FFI are not currently exposed via this -mechanism such as variadic arguments and tuples but the advantage is that users -need not customize the IREE compiler in order to use their modules. - -Prior to passing input programs to the IREE compiler users can insert the -imported functions as external -[`func.func`](https://mlir.llvm.org/docs/Dialects/Func/#funcfunc-mlirfuncfuncop) -ops and calls to those functions using -[`func.call`](https://mlir.llvm.org/docs/Dialects/Func/#funccall-mlirfunccallop): - -```mlir -// An external function declaration. -// `custom` is the runtime module and `string.create` is the exported method. -// This call uses both IREE types (`!util.buffer`) and custom ones not known to -// the compiler but available at runtime (`!custom.string`). -func.func private @custom.string.create(!util.buffer) -> !custom.string -``` - -```mlir -// Call the imported function. -%buffer = util.buffer.constant : !util.buffer = "hello world!" -%result = func.call @custom.string.create(%buffer) : (!util.buffer) -> !custom.string -``` - -Users with custom dialects and ops can use -[MLIR's dialect conversion](https://mlir.llvm.org/docs/DialectConversion/) -framework to rewrite their custom ops to this form and perform additional -marshaling logic. For example, the above could have started as this program -before the user ran their dialect conversion and passed it in to `iree-compile`: - -```mlir -%result = custom.string.create "hello world!" : !custom.string -``` - -See this samples [`example.mlir`](./test/example.mlir) for examples of features -such as signature specification and optional import fallback support. - -### Interoperating with the HAL - -Currently only HAL types with synchronous behavior are supported in custom -modules but deeper integration with the HAL is planned. -This means that today all custom module operations are executed on the host and -synchronous with other host behavior. Future extensions will allow for custom -device-specific command buffer operations and asynchronous scheduling that fit -within the -[IREE execution model](https://github.com/iree-org/iree/blob/main/docs/developers/design_docs/execution_model.md). - -The same ABI mechanisms used to call in to IREE with HAL resources can be used -to call in to custom modules: - -```mlir -// Perform work on tensors using tensor dialects. This will run using IREE's -// asynchronous execution model. -%src = call @produce_tensor() : () -> tensor<?x3xf32> - -// Make the custom call synchronously on the host. The call can use the -// `iree_hal_buffer_view_t` APIs to access the metadata and contents and -// allocate a new buffer view to return to the program. -%dst = func.call @custom.process(%src) : (tensor<?x3xf32>) -> tensor<3x?xi32> - -// Continue using the tensor as normal. -call @consume_tensor(%dst) : (tensor<3x?xi32>) -> () -``` - -Future extensions will allow for `!hal.fence` and `!hal.buffer` to be used to -allow for chaining asynchronous submissions and assign storage for in-place -operations. +* C++ VM wrappers for defining modules and using reference types +* Weak imports/fallback functions +* Custom types exposed to the compiler
diff --git a/samples/custom_module/basic/CMakeLists.txt b/samples/custom_module/basic/CMakeLists.txt new file mode 100644 index 0000000..ab87cf4 --- /dev/null +++ b/samples/custom_module/basic/CMakeLists.txt
@@ -0,0 +1,30 @@ +# Copyright 2022 The IREE Authors +# +# Licensed under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set(_NAME "iree_samples_custom_module_basic_run") +add_executable(${_NAME} "") +target_sources(${_NAME} + PRIVATE + main.c + module.cc + module.h +) + +set_target_properties(${_NAME} PROPERTIES OUTPUT_NAME "custom-module-basic-run") + +# TODO(benvanik): make iree_status_annotate_f always available as a function +# instead of defining it empty? otherwise optimized builds of the runtime won't +# export it but external libraries may pull it in. +target_compile_options(${_NAME} PRIVATE ${IREE_DEFAULT_COPTS}) + +target_link_libraries(${_NAME} + iree_base_base + iree_base_internal_file_io + iree_vm_vm + iree_vm_bytecode_module +) + +add_subdirectory(test)
diff --git a/samples/custom_module/basic/Makefile b/samples/custom_module/basic/Makefile new file mode 100644 index 0000000..9a0a630 --- /dev/null +++ b/samples/custom_module/basic/Makefile
@@ -0,0 +1,51 @@ +# Copyright 2022 The IREE Authors +# +# Licensed under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This is an example showing a basic makefile that links in the IREE runtime by +# way of the unified static library. It's recommended that IREE is added as a +# subproject and cmake is used to add the dependencies (as in the CMakeLists.txt +# in this directory) but when using other build systems this is easier to adapt. +# +# Configure the runtime: +# cmake -GNinja -B ../iree-build-runtime/ . \ +# -DCMAKE_BUILD_TYPE=MinSizeRel \ +# -DIREE_SIZE_OPTIMIZED=ON +# Build the runtime: +# cmake --build ../iree-build-runtime/ --target iree_runtime_unified +# Make this binary: +# make custom-module-run-min RUNTIME_BUILD_DIR=../iree-build-runtime/ +# +# Note that if IREE_SIZE_OPTIMIZED is used to build the runtime then the +# -DNDEBUG and -DIREE_STATUS_MODE=0 are required on any binaries using it. + +RUNTIME_SRC_DIR ?= ../../runtime/src/ +RUNTIME_BUILD_DIR ?= ../../../iree-build/ + +SRC_FILES := module.h module.cc main.c +INCLUDE_DIRS := ${RUNTIME_SRC_DIR} +INCLUDE_FLAGS := $(addprefix -I,${INCLUDE_DIRS}) +LIBRARY_DIRS := \ + ${RUNTIME_BUILD_DIR}/build_tools/third_party/flatcc/ \ + ${RUNTIME_BUILD_DIR}/runtime/src/iree/runtime/ +LINK_LIBRARIES := \ + iree_runtime_unified \ + flatcc_parsing +LIBRARY_FLAGS := $(addprefix -L,${LIBRARY_DIRS}) $(addprefix -l,${LINK_LIBRARIES}) +CXX_FLAGS := -flto ${INCLUDE_FLAGS} ${LIBRARY_FLAGS} +MIN_FLAGS := \ + -s \ + -Os \ + -DNDEBUG \ + -DIREE_STATUS_MODE=0 + +all: custom-module-run custom-module-run-min +clean: + rm -f custom-module-run custom-module-run-min + +custom-module-run: ${SRC_FILES} + ${CXX} ${SRC_FILES} ${CXX_FLAGS} -o $@ +custom-module-run-min: ${SRC_FILES} + ${CXX} ${SRC_FILES} ${CXX_FLAGS} ${MIN_FLAGS} -o $@
diff --git a/samples/custom_module/basic/README.md b/samples/custom_module/basic/README.md new file mode 100644 index 0000000..77d6c28 --- /dev/null +++ b/samples/custom_module/basic/README.md
@@ -0,0 +1,231 @@ +# Basic custom module sample + +This sample shows how to + +1. Create a custom module in C++ that can be used with the IREE runtime +2. Author an MLIR input that uses a custom module including a custom type +3. Compile that program to an IREE VM bytecode module +4. Load the compiled program using a low-level VM interface +5. Call exported functions on the loaded program to exercise the custom module + +The custom module is declared in [`module.h`](./module.h), implemented using a +C++ module wrapper layer in [`module.cc`](./module.cc), and called by example in +[`main.c`](./main.c). + +This document uses terminology that can be found in the documentation of +[IREE's execution model](https://github.com/iree-org/iree/blob/main/docs/developers/design_docs/execution_model.md). +See [IREE's extensibility mechanisms](https://iree-org.github.io/iree/extensions/) +documentation for more information specific to extenting IREE and +alternative approaches to doing so. + +## Background + +IREE's VM is used to dynamically link modules of various types together at +runtime (C, C++, IREE's VM bytecode, etc). Via this mechanism any number of +modules containing exported functions and types that can be used across modules +can extend IREE's base functionality. In most IREE programs the HAL module is +used to provide a hardware abstraction layer for execution and both the HAL +module itself and the types it exposes (`!hal.buffer`, `!hal.executable`, etc) +are implemented using this mechanism. + +## Instructions + +1. Build or install the `iree-compile` binary: + + ``` + python -m pip install iree-compiler + ``` + + [See here](https://iree-org.github.io/iree/getting-started/) + for general instructions on installing the compiler. + +3. Compile the [example module](./test/example.mlir) to a .vmfb file: + + ``` + # This simple sample doesn't use tensors and can be compiled in host-only + # mode to avoid the need for the HAL. + iree-compile --iree-execution-model=host-only samples/custom_module/basic/test/example.mlir -o=/tmp/example.vmfb + ``` + +3. Build the `iree_samples_custom_module_run` CMake target : + + ``` + cmake -B ../iree-build/ -DCMAKE_BUILD_TYPE=RelWithDebInfo . \ + -DCMAKE_C_FLAGS=-DIREE_VM_EXECUTION_TRACING_FORCE_ENABLE=1 + cmake --build ../iree-build/ --target iree_samples_custom_module_basic_run + ``` + (here we force runtime execution tracing for demonstration purposes) + + [See here](https://iree-org.github.io/iree/building-from-source/getting-started/) + for general instructions on building using CMake. + +4. Run the example program to call the main function: + + ``` + ../iree-build/samples/custom_module/basic/custom-module-basic-run \ + /tmp/example.vmfb example.main + ``` + +## Defining Custom Modules in C++ + +Modules are exposed to applications and the IREE VM via the `iree_vm_module_t` +interface. IREE canonically uses C headers to expose module and type functions +but the implementation of the module can be anything the user is able to work +with (C, C++, rust, etc). + +A C++ wrapper is provided to ease implementation when minimal code size and overhead is not a focus and provides easy definition of exports and marshaling +of types. Utilities such as `iree::Status` and `iree::vm::ref<T>` add safety for +managing reference counted resources and can be used within the modules. + +General flow: + +1. Expose module via a C API ([`module.h`](./module.h)): + +```c +// Ideally all allocations performed by the module should use |allocator|. +// The returned module in |out_module| should have a ref count of 1 to transfer +// ownership to the caller. +iree_status_t iree_table_module_create(iree_allocator_t allocator, + iree_vm_module_t** out_module); +``` + +2. Implement the module using C/C++/etc ([`module.cc`](./module.cc)): + +Modules have two parts: a shared module and instantiated state. + +The `iree::vm::NativeModule` helper is used to handle the shared module +declaration and acts as a factory for per-context instantiated state and the +methods exported by the module: + +```c++ +// Any mutable state stored on the module may be accessed from multiple threads +// if the module is instantiated in multiple contexts and must be thread-safe. +struct TableModule final : public vm::NativeModule<TableModuleState> { + // Each time the module is instantiated this will be called to allocate the + // context-specific state. The returned state must only be thread-compatible + // as invocations within a context will not be made from multiple threads but + // the thread on which they are made may change over time; this means no TLS! + StatusOr<std::unique_ptr<TableModuleState>> CreateState( + iree_allocator_t allocator) override; +}; +``` + +The module implementation is done on the state object so that methods may use +`this` to access context-local state: + +```c++ +struct TableModuleState final { + // Local to the context the module was instantiated in and thread-compatible. + std::unordered_map<std::string, std::string> mutable_state; + + // Exported functions must return Status or StatusOr. Failures will result in + // program termination and will be propagated up to the top-level invoker. + // If a module wants to provide non-fatal errors it can return results to the + // program: here we return a 0/1 indicating whether the key was found as well + // as the result or null. + // + // MLIR declaration: + // func.func private @table.lookup(!util.buffer) -> (i1, !util.buffer) + StatusOr<std::tuple<int32_t, vm::ref<iree_vm_buffer_t>>> Lookup( + const vm::ref<iree_vm_buffer_t> key); +}; +``` + +Finally the exported methods are registered and marshaling code is expanded: + +```c++ +static const vm::NativeFunction<TableModuleState> kTableModuleFunctions[] = { + vm::MakeNativeFunction("lookup", &TableModuleState::Lookup), +}; +extern "C" iree_status_t iree_table_module_create( + iree_allocator_t allocator, iree_vm_module_t** out_module) { + auto module = std::make_unique<TableModule>( + "table", /*version=*/0, allocator, + iree::span<const vm::NativeFunction<CustomModuleState>> + (kTableModuleFunctions)); + *out_module = module.release()->interface(); + return iree_ok_status(); +} +``` + +## Registering Custom Modules at Runtime + +Once a custom module is defined it needs to be provided to any context that it +is going to be used in. Each context may have its own unique mix of modules and +it's the hosting application's responsibility to inject the available modules. +See [`main.c`](./main.c) for an example showing the entire end-to-end lifetime +of loading a compiled bytecode module and providing a custom module for runtime +dynamic linking. + +Since modules themselves can be reused across contexts it can be a way of +creating shared caches (requires thread-safety!) that span contexts while the +module state is context specific and isolated. + +Import resolution happens in reverse registration order: the most recently +registered modules override previous ones. This combined with optional imports +allows overriding behavior and version compatibility shims (though there is +still some trickiness involved). + +```c +// Ensure custom types are registered before loading modules that use them. +// This only needs to be done once per instance. +IREE_CHECK_OK(iree_basic_custom_module_register_types(instance)); + +// Create the custom module that can be reused across contexts. +iree_vm_module_t* custom_module = NULL; +IREE_CHECK_OK(iree_basic_custom_module_create(instance, allocator, + &custom_module)); + +// Create the context for this invocation reusing the loaded modules. +// Contexts hold isolated state and can be reused for multiple calls. +// Note that the module order matters: the input user module is dependent on +// the custom module. +iree_vm_module_t* modules[] = {custom_module, bytecode_module}; +iree_vm_context_t* context = NULL; +IREE_CHECK_OK(iree_vm_context_create_with_modules( + instance, IREE_VM_CONTEXT_FLAG_NONE, IREE_ARRAYSIZE(modules), modules, + allocator, &context)); +``` + +## Calling Custom Modules from Compiled Programs + +The IREE compiler allows for external functions that are resolved at runtime +using the [MLIR `func` dialect](https://mlir.llvm.org/docs/Dialects/Func/). Some +optional attributes are used to allow for customization where required but in +many cases no additional IREE-specific work is required in the compiled program. +A few advanced features of the VM FFI are not currently exposed via this +mechanism such as variadic arguments and tuples but the advantage is that users +need not customize the IREE compiler in order to use their modules. + +Prior to passing input programs to the IREE compiler users can insert the +imported functions as external +[`func.func`](https://mlir.llvm.org/docs/Dialects/Func/#funcfunc-mlirfuncfuncop) +ops and calls to those functions using +[`func.call`](https://mlir.llvm.org/docs/Dialects/Func/#funccall-mlirfunccallop): + +```mlir +// An external function declaration. +// `custom` is the runtime module and `string.create` is the exported method. +// This call uses both IREE types (`!util.buffer`) and custom ones not known to +// the compiler but available at runtime (`!custom.string`). +func.func private @custom.string.create(!util.buffer) -> !custom.string +``` + +```mlir +// Call the imported function. +%buffer = util.buffer.constant : !util.buffer = "hello world!" +%result = func.call @custom.string.create(%buffer) : (!util.buffer) -> !custom.string +``` + +Users with custom dialects and ops can use +[MLIR's dialect conversion](https://mlir.llvm.org/docs/DialectConversion/) +framework to rewrite their custom ops to this form and perform additional +marshaling logic. For example, the above could have started as this program +before the user ran their dialect conversion and passed it in to `iree-compile`: + +```mlir +%result = custom.string.create "hello world!" : !custom.string +``` + +See this samples [`example.mlir`](./test/example.mlir) for examples of features +such as signature specification and optional import fallback support.
diff --git a/samples/custom_module/main.c b/samples/custom_module/basic/main.c similarity index 92% rename from samples/custom_module/main.c rename to samples/custom_module/basic/main.c index bf72aa0..7585033 100644 --- a/samples/custom_module/main.c +++ b/samples/custom_module/basic/main.c
@@ -29,10 +29,11 @@ // solar flares, etc). int main(int argc, char** argv) { if (argc != 3) { - fprintf(stderr, - "Usage:\n" - " custom-module-run - <entry.point> # read from stdin\n" - " custom-module-run </path/to/say_hello.vmfb> <entry.point>\n"); + fprintf( + stderr, + "Usage:\n" + " custom-module-basic-run - <entry.point> # read from stdin\n" + " custom-module-basic-run </path/to/say_hello.vmfb> <entry.point>\n"); fprintf(stderr, " (See the README for this sample for details)\n "); return -1; } @@ -48,11 +49,12 @@ // Ensure custom types are registered before loading modules that use them. // This only needs to be done once. - IREE_CHECK_OK(iree_custom_module_register_types(instance)); + IREE_CHECK_OK(iree_custom_module_basic_register_types(instance)); // Create the custom module that can be reused across contexts. iree_vm_module_t* custom_module = NULL; - IREE_CHECK_OK(iree_custom_module_create(instance, allocator, &custom_module)); + IREE_CHECK_OK( + iree_custom_module_basic_create(instance, allocator, &custom_module)); // Load the module from stdin or a file on disk. // Applications can ship and load modules however they want (such as mapping
diff --git a/samples/custom_module/module.cc b/samples/custom_module/basic/module.cc similarity index 98% rename from samples/custom_module/module.cc rename to samples/custom_module/basic/module.cc index 36fd997..6ba12d8 100644 --- a/samples/custom_module/module.cc +++ b/samples/custom_module/basic/module.cc
@@ -67,7 +67,7 @@ iree_allocator_free(string->allocator, ptr); } -extern "C" iree_status_t iree_custom_module_register_types( +extern "C" iree_status_t iree_custom_module_basic_register_types( iree_vm_instance_t* instance) { if (iree_custom_string_descriptor.type) { return iree_ok_status(); // Already registered. @@ -184,7 +184,7 @@ // Note that while we are using C++ bindings internally we still expose the // module as a C instance. This hides the details of our implementation. -extern "C" iree_status_t iree_custom_module_create( +extern "C" iree_status_t iree_custom_module_basic_create( iree_vm_instance_t* instance, iree_allocator_t allocator, iree_vm_module_t** out_module) { IREE_ASSERT_ARGUMENT(out_module);
diff --git a/samples/custom_module/module.h b/samples/custom_module/basic/module.h similarity index 76% rename from samples/custom_module/module.h rename to samples/custom_module/basic/module.h index 8fdc5c0..c786f6b 100644 --- a/samples/custom_module/module.h +++ b/samples/custom_module/basic/module.h
@@ -4,8 +4,8 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#ifndef IREE_SAMPLES_CUSTOM_MODULE_MODULE_H_ -#define IREE_SAMPLES_CUSTOM_MODULE_MODULE_H_ +#ifndef IREE_SAMPLES_CUSTOM_MODULE_BASIC_MODULE_H_ +#define IREE_SAMPLES_CUSTOM_MODULE_BASIC_MODULE_H_ #include <stdint.h> @@ -31,19 +31,20 @@ iree_custom_string_t** out_string); // Registers types provided by the custom module. -iree_status_t iree_custom_module_register_types(iree_vm_instance_t* instance); +iree_status_t iree_custom_module_basic_register_types( + iree_vm_instance_t* instance); // Creates a native custom module that can be reused in multiple contexts. // The module itself may hold state that can be shared by all instantiated // copies but it will require the module to provide synchronization; usually // it's safer to just treat the module as immutable and keep state within the // instantiated module states instead. -iree_status_t iree_custom_module_create(iree_vm_instance_t* instance, - iree_allocator_t allocator, - iree_vm_module_t** out_module); +iree_status_t iree_custom_module_basic_create(iree_vm_instance_t* instance, + iree_allocator_t allocator, + iree_vm_module_t** out_module); #ifdef __cplusplus } // extern "C" #endif // __cplusplus -#endif // IREE_SAMPLES_CUSTOM_MODULE_MODULE_H_ +#endif // IREE_SAMPLES_CUSTOM_MODULE_BASIC_MODULE_H_
diff --git a/samples/custom_module/test/CMakeLists.txt b/samples/custom_module/basic/test/CMakeLists.txt similarity index 89% rename from samples/custom_module/test/CMakeLists.txt rename to samples/custom_module/basic/test/CMakeLists.txt index a6e86ce..ad7361a 100644 --- a/samples/custom_module/test/CMakeLists.txt +++ b/samples/custom_module/basic/test/CMakeLists.txt
@@ -12,7 +12,7 @@ TOOLS FileCheck iree-compile - iree_samples_custom_module_run + iree_samples_custom_module_basic_run LABELS "hostonly" )
diff --git a/samples/custom_module/test/example.mlir b/samples/custom_module/basic/test/example.mlir similarity index 98% rename from samples/custom_module/test/example.mlir rename to samples/custom_module/basic/test/example.mlir index 07aa11f..c3a4a26 100644 --- a/samples/custom_module/test/example.mlir +++ b/samples/custom_module/basic/test/example.mlir
@@ -1,4 +1,4 @@ -// RUN: iree-compile %s --iree-execution-model=host-only | custom-module-run - example.main | FileCheck %s +// RUN: iree-compile %s --iree-execution-model=host-only | custom-module-basic-run - example.main | FileCheck %s module @example { //===--------------------------------------------------------------------===//