Cross-compile target modules and dispatch to executor#3033
Conversation
Assisted by: Claude code
|
Hello. You may have forgotten to update the changelog!
|
maliasadi
left a comment
There was a problem hiding this comment.
Thanks @mehrdad2m! Will you fix the build issues on this PR or on the base branch/PR?
| -DLLVM_TARGETS_TO_BUILD="${LLVM_TARGETS_TO_BUILD}" \ | ||
| -DLLVM_ENABLE_PROJECTS="$(LLVM_PROJECTS)" \ | ||
| -DLLVM_ENABLE_ASSERTIONS=ON \ |
There was a problem hiding this comment.
this is consistent with other places:
| -DLLVM_TARGETS_TO_BUILD="${LLVM_TARGETS_TO_BUILD}" \ | |
| -DLLVM_ENABLE_PROJECTS="$(LLVM_PROJECTS)" \ | |
| -DLLVM_ENABLE_ASSERTIONS=ON \ | |
| -DLLVM_TARGETS_TO_BUILD=${LLVM_TARGETS_TO_BUILD} \ | |
| -DLLVM_ENABLE_PROJECTS=$(LLVM_PROJECTS) \ | |
| -DLLVM_ENABLE_ASSERTIONS=ON \ |
There was a problem hiding this comment.
This was added to allow multiple targets/project to be parsed correctly. e.g. without the quotation, cmake can not parse DLLVM_TARGETS_TO_BUILD=X86;AArch64 correctly. Let me know if you know a cleaner way to achieve this.
| // CHECK: executor.send_binary("ADDR:PORT", "/tmp/target_compute.o") | ||
| // CHECK-NOT: executor.send_binary |
There was a problem hiding this comment.
What do CHECK and CHECK-NOT executor.send_binary check?
There was a problem hiding this comment.
This was added to ensure we only send the binary once even if we have multiple launch_kernels on the same object file. I'll add a comment to clarify that
|
|
||
| 1. Injects `executor.open` into `setup()` (once per unique address) and `executor.send_binary` | ||
| into `setup()` (once per module). | ||
| 2. Replaces every host-side `func.call` to the module's entry functions with a |
There was a problem hiding this comment.
What's the strategy to replace host func.call with executor.launch? What does filter the host-side func.calls which need to run on the host from those need to be handled with executor?
There was a problem hiding this comment.
Ah good catch. This docstring is outdated. I updated it in 2aafda2. the func.calls are unaffected by this pass. It only acts on nested modules with catalyst.dispatch attribute.
|
|
||
| // Open a session (once per address), ship the object recorded in | ||
| // `catalyst.object_file`, and rewrite each host-side func.call into a `executor.launch`. | ||
| LogicalResult dispatchViaOrcExecutor(ModuleOp host, ModuleOp nested, |
There was a problem hiding this comment.
What does this function do? 🤔
There was a problem hiding this comment.
It handles one dispatch module which involves opening the session, shipping the object, and rewriting that module's launch_kernels into executor.launch. I just noticed though that the name carries an implementation detail it shouldn't, I renamed it to dispatchTargetModule. 350665b
| dumpLLVMIR(*llvmModule, kernelDir, name.str() + ".ll"); | ||
| } | ||
| std::string objPath = | ||
| emitObjectFile(std::move(llvmModule), name, kernelDir, *targetMachine); |
There was a problem hiding this comment.
Could you add a guard before the compile loop to fix the object-file name collision issue? as it generates {workspace}/{name}/{name}.o and for two targets with the same sym name, this will silently fail.
There was a problem hiding this comment.
Good catch! Although having two targets with the same sym name would not be a valid IR to begin with, we default to "unnamed" for modules with no name and that could trigger this issue. I added a guard e22b237
| let summary = "Apply the passes scheduled with the transform dialect."; | ||
| } | ||
|
|
||
| def CrossCompileTargetsPass : Pass<"cross-compile-targets", "mlir::ModuleOp"> { |
Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Co-authored-by: Ali Asadi <10773383+maliasadi@users.noreply.github.com>
Context:
This PR adds a compile path that turns a catalyst.target-tagged QNode into a standalone object and either statically links it (local) or ships it to a remote executor.
Description of the Change:
cross-compile-targetspass which lowers eachcatalyst.targetnested module and emits a standalone .o. Then it records the path ascatalyst.object_file, and reduce the module to external declarations. Local targets are also recorded for static linking.dispatch-executor-targetspass which ships the remote binaries and rewrites their host calls intoexecutor.launch.Benefits:
Possible Drawbacks:
Related GitHub Issues: