-convert-executor-to-llvm

Lower the ``executor`` dialect to direct calls into the Catalyst executor runtime.

Replaces each executor.* op with the corresponding __catalyst__executor__* runtime entry point:

  • executor.open -> session = __catalyst__executor__open(addr)

  • executor.send_binary -> __catalyst__executor__send_binary(session, path, format)

  • executor.launch -> __catalyst__executor__launch(session, "_catalyst_pyface_<callee>", ...)

  • executor.call -> __catalyst__executor__call_wrapper(session, sym, ...) + __catalyst__executor__free_result

  • executor.close -> __catalyst__executor__close(session)

-dispatch-executor-targets

Ship cross-compiled ``catalyst.target`` modules to an executor.

For every nested builtin.module carrying a catalyst.dispatch attribute and a catalyst.object_file path, the pass:

  1. Injects executor.open into setup() (once per unique address) and executor.send_binary into setup() (once per module).

  2. Rewrites every host-side catalyst.launch_kernel targeting that module into an executor.launch carrying the executor address, the entry callee, and the object-file path.

  3. Erases the nested module from the host after its catalyst.launch_kernels are rewritten.

Session teardown is handled by the runtime, which closes every open session at process exit, so no explicit close op is emitted.

The pass is a no-op when no catalyst.dispatch modules are present.

-lower-runtime-dispatch

_Lower dispatched catalyst.runtime_call ops to executor.call._

Rewrites every catalyst.runtime_call carrying a dispatch attribute into an executor.call on that executor, marshalling the operands into the executor’s flat wire layout on the way:

  • a scalar or ptr operand becomes a one-element tensor of its declared width,

  • a str from c_strings becomes a NUL-padded fixed-width constant tensor,

  • the declared result and each out buffer become results, the result first.

An empty dispatch binds to the program’s single executor, taken from the catalyst.dispatch attribute of the nested target modules.

The pass runs before bufferization so the executor.call it emits is bufferized into its destination-passing form by one-shot bufferize.