Skip to content

fix: make BiFManager builtin-index hash independent of the C++ standard library#417

Open
TsaiGaggery wants to merge 1 commit into
intel:masterfrom
TsaiGaggery:fix/bifmanager-stdlib-independent-hash
Open

fix: make BiFManager builtin-index hash independent of the C++ standard library#417
TsaiGaggery wants to merge 1 commit into
intel:masterfrom
TsaiGaggery:fix/bifmanager-stdlib-independent-hash

Conversation

@TsaiGaggery

Copy link
Copy Markdown

Problem

BiFManagerCommon::getHash() uses std::hash<std::string>, whose result is
implementation-defined and differs across C++ standard libraries. BiFManager-bin
bakes the hashes of builtin names into the generated OCLBiFImpl.h as
case <hash>ULL: labels at build time, and BiFManagerHandler::GetDepList
recomputes getHash() for each referenced function at run time to find its section.

When the host BiFManager-bin and the libigc runtime are linked against
different standard libraries -- the usual situation when cross-compiling IGC for
Android (a libstdc++ host tool generating the header while libigc is built with
libc++) -- the generated case labels and the runtime lookups disagree for every
name. The switch always falls through to {-1}, findAllBuiltins() collects
nothing, LinkBiF() links no built-in bodies, and every __spirv_* reference is
reported undefined reference to ... -> backend compiler failure
(CL_BUILD_PROGRAM_FAILURE). Native single-stdlib builds are unaffected, which is why
this only surfaces in heterogeneous-stdlib / cross builds.

Fix

Use a fixed 64-bit FNV-1a hash so the generated labels and the runtime lookups always
agree regardless of the C++ standard library. getHash() is defined once in
BiFManagerCommon and compiled into both the host tool and the runtime.

Validation

Reproduced cross-compiling IGC (LLVM 17.0.6) for Android x86_64: host BiFManager-bin
linked against libstdc++, libigc.so against libc++. Before this patch, ocloc compile
of any kernel using a builtin failed with
undefined reference to _Z33__spirv_BuiltInGlobalInvocationIdi. Binary proof: the
libstdc++ hash of that symbol appeared as an immediate inside libigc.so while the
libc++ value the runtime actually computes appeared 0 times. After this patch the
FNV-1a value matches on both sides, findAllBuiltins collects the builtins, ocloc
reports Build succeeded., and OpenVINO GPU inference runs end to end.

…rd library

BiFManagerCommon::getHash() used std::hash<std::string>, whose value is
implementation-defined and differs across C++ standard libraries. BiFManager-bin
bakes the hashes of builtin names into OCLBiFImpl.h as `case <hash>ULL:` labels at
build time, and BiFManagerHandler::GetDepList recomputes getHash() for each
referenced function at run time to find its section.

When the host BiFManager-bin and the libigc runtime are linked against different
standard libraries (e.g. a libstdc++ host tool generating the header while libigc
is built with libc++, the usual situation when cross-compiling IGC for Android),
the generated case labels and the runtime lookups disagree for every name. The
switch always falls through to {-1}, findAllBuiltins() collects nothing, LinkBiF()
links no built-in bodies, and every __spirv_* reference is reported "undefined
reference to ..." -> backend compiler failure (CL_BUILD_PROGRAM_FAILURE). Native
single-stdlib builds are unaffected, which is why this only surfaces in
heterogeneous-stdlib / cross builds.

Use a fixed 64-bit FNV-1a hash so the generated labels and the runtime lookups
always agree regardless of the standard library. getHash() is defined once in
BiFManagerCommon and compiled into both the host tool and the runtime, so a single
definition keeps them consistent.

Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant