Repository navigation
[SYCL] Avoid runtime registration for empty device pre-link outputs - #23545
vishalshetagar wants to merge 6 commits into
Conversation
When -fsycl-link has no device images or only empty images, emit the required output object without references to __sycl_register_lib or __sycl_unregister_lib. This allows a host linker to link host-only and kernel-free configurations without the SYCL runtime. Handle empty images in both offload wrappers, omit empty modules from post-link image tables, and generate an empty object when the new driver has no device-link outputs. Preserve registration for nonempty images and NativeCPU placeholders. Extend existing regression tests for empty and mixed images, host-only inputs, and empty modules through both post-link implementations. Fixes intel#23528
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
Give the non-RDC wrapper and linker-wrapper command tests a kernel so post-link processing retains an image. Empty sources now correctly omit images and registration, so they cannot exercise image sections or the missing-ocloc diagnostic. Disable integration-header inclusion to keep these standalone fixtures independent of installed SYCL headers and host C++ libraries. Extend the non-RDC test to check that empty ELF and COFF objects contain no embedded device image or SYCL registration references. Reproduced both original failures with the PR's CI-built compiler. The updated tests pass, along with the surrounding SYCL driver, wrapper, and post-link tests: 294 passed, 3 expected failures, 15 unsupported, and no unexpected failures.
|
@vishalshetagar Looks like the PR needs to be merged with HEAD since there are merge conflicts, could you take a look? Thanks |
…mpty-images # Conflicts: # clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-sycl.cpp # clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
…mpty-images # Conflicts: # clang/test/Driver/sycl-nordc-wrapper-object.cpp # clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Keep the SYCL image group when post-link removes every image. Emit a container with one empty image only when the combined group is empty, so the host compilation still has its required input and omits runtime registration. Mixed target groups retain only their nonempty images. Extend the existing image test for empty tool/library post-link paths, ELF and COFF host wrapping, and mixed targets. Give the no-RDC section fixture a real kernel because its checks require a nonempty image. Validated with 139 focused lit tests, Linux host linking for both drivers, 12 ELF/COFF wrapper checks, and native Windows linking/execution of eight executables and eight DLLs plus two nonempty failure controls.
|
Thanks @sarnex I’ve merged the latest upstream sycl branch and resolved the conflicts. Retesting caught an empty-image issue with the updated non-RDC flow, which I fixed in the follow-up commit. All 139 focused regression tests passed, along with Linux and native Windows linking checks. The changes are pushed and the PR description is updated. |
|
@sarnex Could you please rerun all jobs for the Windows workflow? The latest retry failed downloading sycl_windows_default. The build succeeded on October 23, but the toolchain artifact has a three-day retention period, so the November 2 retry needs a fresh build. Thanks! |
|
Done, you can ignore the Windows Arc failure, it's not related to this change |
|
Ping @intel/dpcpp-tools-reviewers @intel/dpcpp-clang-driver-reviewers for review, thanks! |
mdtoguchi
left a comment
There was a problem hiding this comment.
An end-to-end test would be good (sycl/test-e2e) that covers this scenario.
Also, please clean up the commit message and detail what the full scope of the changes are without all of the testing result information.
| const ArgList &Args, bool IsEmbeddedIR = false) { | ||
| StringRef Target = Args.getLastArgValue(OPT_triple_EQ); | ||
| if (Target.empty()) | ||
| if (Target.empty() && !SplitModules.empty()) |
There was a problem hiding this comment.
This relaxes the -triple check. Could the empty case get a small dedicated helper (emit an empty wrapper object for the host triple), so this check stays strict for everyone else?
| return SYCLImagesOrErr.takeError(); | ||
|
|
||
| std::scoped_lock<decltype(ImageMtx)> Guard(ImageMtx); | ||
| auto &SYCLImages = Images[OFK_SYCL]; |
There was a problem hiding this comment.
A comment explaining the need for this would be good to have, as it isn't clear that the potential empty Input would be used at L3196
| return BinOrErr.takeError(); | ||
| MemoryBuffer *Bin = *BinOrErr; | ||
| HasNonEmptyImage |= | ||
| Bin->getBufferSize() != 0 || Triple(Img.Tgt).isNativeCPU(); |
There was a problem hiding this comment.
Is the NativeCPU exception here tested? Would be good to make sure that the empty native_cpu image produces the needed info.
| SYCLWrappingOptions Options) { | ||
| if (llvm::all_of(Images, [](const SYCLImage &Image) { | ||
| return Image.Image->getBufferSize() == 0 && | ||
| Image.Target != "native_cpu"; |
There was a problem hiding this comment.
Maybe use Triple(Image.Target).isNativeCPU() for consistency with clang-offload-wrapper.
| } | ||
| addTableRow(*Table, CopyTriple); | ||
| if (!MD.getModule().global_values().empty() || | ||
| !MD.getModule().getModuleInlineAsm().empty()) |
There was a problem hiding this comment.
We are only adding the as long as we aren't empty, looks like we can exit early if this condition isn't met as opposed to only exiting right before we have already generated the info.
Exercise host-only and kernel-free device pre-linking with both offload drivers, then link and run the results without the SYCL runtime. Cover empty non-RDC compilation as well, and disable automatic SYCL library dependencies in Windows objects. Emit the empty host wrapper object through a dedicated helper so normal wrapping retains strict device-triple validation. Explain why the empty SYCL image group must survive post-link filtering for fatbin-only output. Use Triple::isNativeCPU consistently when deciding whether an empty image still needs registration. Check NativeCPU entry tables and registration with both wrappers for ELF and COFF hosts. Return before writing unused post-link files for empty modules, and check that only the empty image table is produced.
|
@mdtoguchi Thanks for the review. Addressed all five inline suggestions in b64f560 and added an E2E test covering host-only and kernel-free pre-linking, plus empty non-RDC compilation, with both drivers. The test links and runs without the SYCL runtime. I also cleaned up the PR description, which will become the squash commit message, to describe the full scope without the testing results. Could you please take another look? |
cf7a486 to
b64f560
Compare
tahonermann
left a comment
There was a problem hiding this comment.
Thank you for working on this @vishalshetagar!
I don't see anything that looks like it should require review from the CFE team, so I'll go ahead and approve from that perspective. The test coverage looks good to me, but I'm not very familiar with the scenarios to be tested, so that might not mean much.
I don't understand why an exception is needed for native CPU, but I'm not sure how important that is either. Ideally, I would expect the SYCL RT symbol references to be omitted if the TU defines no kernels for native CPU too. But perhaps that is something we can come back to if it is found to be an issue.
|
@tahonermann Thanks for the review and approval! NativeCPU can use an empty image payload while representing kernels through a table of host function pointers, so an empty payload alone doesn’t mean there are no kernels to register. The exception preserves registration for that case. I agree that a NativeCPU TU with no kernels should ideally avoid the runtime references too. The current exception is conservative; we can follow up on distinguishing that case using the kernel entries. |
-fsycl-linkcurrently introduces SYCL runtime registration references even when its inputs contain no device images or only empty images. This prevents host-only and kernel-free configurations from linking with a host linker unless they also link the SYCL runtime.Make both offload driver paths produce the required output without references to
__sycl_register_libor__sycl_unregister_libwhen there is nothing to register. Both offload wrappers skip registration for empty image sets, and both post-link implementations omit empty modules. The post-link tool returns before writing unused IR, property, or symbol files.When device pre-linking has no device inputs, a dedicated helper emits an empty object for the host triple while keeping device-triple validation strict in the normal wrapping path. For non-RDC compilation, retain the SYCL image group after post-link filtering and emit a placeholder container only when the combined group is empty, so host compilation still receives its required input. Preserve registration and metadata for nonempty images, mixed image sets, and NativeCPU placeholders.
Add an end-to-end test covering host-only pre-linking, kernel-free SYCL pre-linking, and empty non-RDC compilation with both drivers, followed by host linking and execution without the SYCL runtime. Extend compiler regressions for empty and mixed images, ELF/COFF output, NativeCPU entry tables and registration, and empty post-link output. Give fixtures that require nonempty device images real kernels.
Fixes #23528.