| # Multiple Modules / Pipelines |
| |
| IREE programs can be composed of multiple modules and calls can be made between |
| them even if the modules are implemented manually (C/C++/python/etc) or |
| generated by the compiler (VMFB/emitc). Modules have a user-specified load |
| order and can only reference modules loaded prior. Each module can contain |
| global state that is scoped to the VM context that loaded them to allow for |
| multiple copies of a program to be loaded in a single hosting process. |
| |
| This sample contains two modules produced by the compiler |
| ([`module_a.mlir`](./module_a.mlir) and [`module_b.mlir`](./module_b.mlir)) that |
| export some basic functions and a pipeline module implemented for both |
| synchronous ([`pipeline_sync.mlir`](./pipeline_sync.mlir)) and asynchronous |
| execution ([`pipeline_async.mlir`](./pipeline_async.mlir)) that calls into the |
| modules. This shows how common/reusable portions of programs can be factored |
| into multiple components and complex stateful pipelines can be easily authored |
| that use those components. |
| |
| ## Instructions (synchronous) |
| |
| 1. Compile each module to .vmfb files: |
| |
| ``` |
| iree-compile \ |
| --iree-hal-target-backends=vmvx \ |
| module_a.mlir -o=module_a_sync.vmfb |
| iree-compile \ |
| --iree-hal-target-backends=vmvx \ |
| module_b.mlir -o=module_b_sync.vmfb |
| iree-compile \ |
| --iree-hal-target-backends=vmvx \ |
| pipeline_sync.mlir -o=pipeline_sync.vmfb |
| ``` |
| |
| 2. Run the program by passing in the modules in load order (dependencies first): |
| |
| ``` |
| iree-run-module \ |
| --device=local-sync \ |
| --module=module_a_sync.vmfb \ |
| --module=module_b_sync.vmfb \ |
| --module=pipeline_sync.vmfb \ |
| --function=run \ |
| --input=4096xf32=-2.0 |
| ``` |
| |
| ## Instructions (asynchronous) |
| |
| The compilation portion is the same as above just with the addition of the flag |
| telling the compiler to make the modules export functions with async support. |
| It's possible to have modules that contain a mix of synchronous and asynchronous |
| exports and calls if desired. `iree-run-module` and other IREE tooling |
| automatically detects asynchronous calls and handles adding the wait and signal |
| fences while applications directly using IREE APIs for execution will need to |
| add the fences themselves. |
| |
| 1. Compile each module to .vmfb files with the `async-external` ABI model: |
| |
| ``` |
| iree-compile \ |
| --iree-execution-model=async-external \ |
| --iree-hal-target-backends=vmvx \ |
| module_a.mlir -o=module_a_async.vmfb |
| iree-compile \ |
| --iree-execution-model=async-external \ |
| --iree-hal-target-backends=vmvx \ |
| module_b.mlir -o=module_b_async.vmfb |
| iree-compile \ |
| --iree-execution-model=async-external \ |
| --iree-hal-target-backends=vmvx \ |
| pipeline_async.mlir -o=pipeline_async.vmfb |
| ``` |
| |
| 2. Run the program by passing in the modules in load order (dependencies first): |
| |
| ``` |
| iree-run-module \ |
| --device=local-sync \ |
| --module=module_a_async.vmfb \ |
| --module=module_b_async.vmfb \ |
| --module=pipeline_async.vmfb \ |
| --function=run \ |
| --input=4096xf32=-2.0 |
| ``` |