Skip to content

Commit 1b15275

Browse files
committed
docs(plan): the dpcpp correction took three attempts, and the second broke every consumer
The regression was not visible from the payload: `sycl-ls` reported the GPU in attempts two and three alike. What differed was whether a CONSUMER of the payload still worked, and only rebuilding the example showed it. A non-empty DT_RUNPATH on a payload library switches off the inherited DT_RPATH of whatever loaded it, so the CUDA adapter stopped seeing the artifact's own farm. Also records compat.sycl-runtime 2026.09.07, which moves the driver hop from the user's manifest into the adapter: which back end the SYCL runtime dlopens is the runtime's business, not the project's.
1 parent 8092724 commit 1b15275

1 file changed

Lines changed: 34 additions & 5 deletions

File tree

.agents/docs/2026-09-05-heterogeneous-build-ecosystem-design-v2.md

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,8 @@ replaced by one that measures something: the same content named `.cpp` is still
510510
compiled as C++ and does not reach the build program -- a test naming only
511511
`.sycl` would pass on a table that had started classifying by content.
512512

513-
**A dpcpp repair, found by trying to use the payload.** Five of its programs --
513+
**A dpcpp repair that took three attempts, and the third is the shape.** Five
514+
of its programs --
514515
`sycl-ls`, `sycl-prof`, `sycl-trace`, `sycl-sanitize`, `syclbin-dump` -- ship
515516
with neither DT_RPATH nor DT_RUNPATH and could not start once installed. The
516517
`[cuda:gpu] NVIDIA CUDA BACKEND` recorded in that recipe's own comment had been
@@ -522,10 +523,27 @@ measured with LD_LIBRARY_PATH set. Two attempts were needed:
522523
naming four sonames with no provider in the index. The check was describing a
523524
real regression: the sealed payload enumerated no platforms where the
524525
unsealed one had found the GPU.
525-
* `elfpatch.set_rpath` on BOTH halves is the answer. bin/ alone leaves
526-
`sycl-ls` starting and reporting nothing, because the Unified Runtime loader
527-
dlopens its adapters by absolute path and each one then fails on
528-
`libumf.so.1`, which is inside this same payload.
526+
* `elfpatch.set_rpath` on BOTH halves made `sycl-ls` work and made every
527+
CONSUMER worse, which appeared only when an mcpp artifact reached the payload
528+
through a runtime adapter: a non-empty DT_RUNPATH on a payload library
529+
switches OFF the inherited DT_RPATH of whatever loaded it, so
530+
`libur_adapter_cuda.so.0` stopped seeing the artifact's own farm and failed
531+
first on `libcuda.so.1` and then on `libnvidia-ml.so.1`. Every consumer would
532+
have had to re-farm the payload's entire external closure.
533+
* `patchelf --force-rpath` on the PROGRAMS and nothing on the libraries is the
534+
answer, and it is one tag rather than two paths: DT_RUNPATH is honoured for
535+
an object's own DT_NEEDED and not for a dlopen beneath it, DT_RPATH for both
536+
at any depth. The programs' RPATH therefore serves their adapters too, while
537+
the libraries keep inheriting from whoever loads them. `elfpatch` cannot
538+
express this -- `set_rpath` writes RUNPATH and `patch_elf_loader_rpath` also
539+
swaps the interpreter -- so the recipe calls patchelf directly with
540+
`xim:patchelf` as a build dep, which is what godot.lua and libglvnd.lua do
541+
for the same documented reason.
542+
543+
⭐ The regression was not visible from the payload. `sycl-ls` reported the GPU
544+
in all three attempts from the second onward; what differed was whether a
545+
CONSUMER of the payload still worked, and only building the example again
546+
showed it.
529547

530548
**The SYCL link needs `-l:libstdc++.so.6`, not `-lstdc++`.** clang's driver
531549
treats `-lstdc++` as a selector for the C++ standard library and rewrites it to
@@ -542,6 +560,15 @@ entries were added by a failure rather than by design: the dlopen chain
542560
deliberately does not farm, and `libz.so.1` -- which only CI found, because
543561
this machine had zlib installed for unrelated reasons.
544562

563+
Its 2026.09.07 version moves one more thing across the boundary. A SYCL
564+
artifact using the CUDA back end had to declare `compat:cuda-runtime` beside
565+
it, because the adapter reaches `libcuda.so.1` through the artifact's own path.
566+
That is a true statement about the implementation and a poor one to put in a
567+
user's manifest: which back end the SYCL runtime dlopens is the runtime's
568+
business. The adapter now declares the sentinel and links the same versioned
569+
soname `compat.cuda-runtime` links, so a project that writes SYCL declares one
570+
compat entry and no CUDA at all.
571+
545572
**Five pull requests across three repositories, not three.** The dependency
546573
order is a cycle if each repository takes one: the plugin collection's CI needs
547574
the released engine AND the index adapter, while the engine's examples need the
@@ -558,3 +585,5 @@ mcpp-plugins, then mcpp-index (descriptor), then mcpp (examples).
558585
| 2026-09-06 | N1's second criterion replaced | above |
559586
| 2026-09-06 | `compat.sycl-runtime` added to the index row | the runtime closure check refuses the artifact without it |
560587
| 2026-09-06 | the round is five PRs, not three | the release order is a cycle otherwise |
588+
| 2026-09-06 | dpcpp corrected a second time (xim #769) | the first correction fixed the payload's own programs and broke every consumer of it; the regression was invisible from the payload |
589+
| 2026-09-06 | `compat.sycl-runtime` 2026.09.07 (mcpp-index #355) | a SYCL project should not have to declare CUDA; the adapter owns the hop its runtime needs |

0 commit comments

Comments
 (0)