Skip to content

[SYCL][Driver] Add option to specify the location of ocloc - #22912

Open
mdtoguchi wants to merge 16 commits into
intel:syclfrom
mdtoguchi:ocloc-location
Open

[SYCL][Driver] Add option to specify the location of ocloc#22912
mdtoguchi wants to merge 16 commits into
intel:syclfrom
mdtoguchi:ocloc-location

Conversation

@mdtoguchi

@mdtoguchi mdtoguchi commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

The ocloc tool used for ahead of time compilation targeting Intel GPUs is
acquired externally, so it is not guaranteed to be placed in the PATH.
Add --ocloc-path=dir, allowing a user to specify the directory in which
ocloc resides. The user provided location always wins over any ocloc that
is otherwise visible via the program paths or the PATH environment
variable.

The option is honored for both the old and the new offloading model

  • Old model: the driver's Intel GPU backend compile job (SYCL.cpp) and
    the ocloc help emitted for -fsycl-help=gen.
  • New model: forwarded to clang-linker-wrapper, and to clang-sycl-linker
    for the --sycl-link path. Both tools also accept --ocloc-path=
    directly for standalone use.

Some new offload model tests within sycl-offload-jit.cpp will fail when
the corresponding device libraries are not built.  In those cases, the
test needs to pick up the internal variants so the driver does not error
due to not finding any.
The ocloc tool used for ahead of time compilation targeting Intel GPUs is
acquired externally, so it is not guaranteed to be placed in the PATH.
Add --ocloc-path=<dir>, allowing a user to specify the directory in which
ocloc resides.  The user provided location always wins over any ocloc that
is otherwise visible via the program paths or the PATH environment
variable.

The option is honored for both the old and the new offloading model:

 - Old model: the driver's Intel GPU backend compile job (SYCL.cpp) and
   the ocloc help emitted for -fsycl-help=gen.
 - New model: forwarded to clang-linker-wrapper, and to clang-sycl-linker
   for the --sycl-link path.  Both tools also accept --ocloc-path=
   directly for standalone use.
@mdtoguchi mdtoguchi changed the title Ocloc location [SYCL][Driver] Add option to specify the location of ocloc Aug 10, 2026
@mdtoguchi
mdtoguchi marked this pull request as ready for review August 11, 2026 01:11
@mdtoguchi
mdtoguchi requested review from a team as code owners August 11, 2026 01:11

@tahonermann tahonermann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks ok to me. I'd like to see more comments explaining what happens if ocloc is not at the specified path or not found elsewhere.

It's unfortunate that the logic for finding the right path is repeated in so many places, but that is a pre-existing issue that probably isn't easy to fix.

The help text for each of the three cases of the new option differs for each, but not in a meaningful way as far as I can tell. I suggest consolidating to one phrasing.

Comment thread clang/include/clang/Options/Options.td Outdated
Comment thread clang/lib/Driver/ToolChains/SYCL.h Outdated
Comment on lines +85 to +88
// Returns the full path of the ocloc tool to be used for AOT compilation. A
// user provided --ocloc-path= is honored above all other lookup locations.
const char *getOclocPath(Compilation &C, const ToolChain &TC,
const llvm::opt::ArgList &Args);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when ocloc is not found? Is a null pointer returned? Is a diagnostic issued? It would be helpful for the comment to state what should happen.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not found, the fallback is just the tool name with no path information. I'll update the comment.

Comment thread clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td Outdated
Comment thread clang/tools/clang-sycl-linker/SYCLLinkOpts.td Outdated

@YuriPlyakhin YuriPlyakhin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to submit it upstream first?

Comment thread clang/lib/Driver/Driver.cpp Outdated
@mdtoguchi

Copy link
Copy Markdown
Contributor Author

Does it make sense to submit it upstream first?

Probably not - the only tool where ocloc is even mentioned is the clang-sycl-linker. All other locations, no AOT behavior is available. This probably makes more sense to upstream when more AOT functionality is available.

Comment thread clang/lib/Driver/ToolChains/SYCL.h Outdated
Comment thread clang/lib/Driver/ToolChains/SYCL.cpp
}

/// Locate the 'ocloc' tool used for Intel GPU AOT compilation.
Expected<std::string> findOcloc(const ArgList &Args) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation in ClangLinkerWrapper.cpp and ClangSYCLLinker.cpp - near-identical, but differ in some subtle things:

  1. The two copies check DryRun on opposite sides of the findProgramByName call. In the wrapper, a --dry-run in an environment where ocloc does exist in the given directory hits the filesystem and returns the resolved path; in clang-sycl-linker it never does.
  2. Diagnostic capitalization is different (Unable to find vs unable to find).

Could you please align implementations?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aligned here: d27f11d

@YuriPlyakhin YuriPlyakhin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: can we use -B instead of introducing new per-tool option?

Comment thread clang/lib/Driver/Driver.cpp Outdated
SmallString<128> ExecPath;
// A user provided --ocloc-path= overrides the usual tool lookup for ocloc.
if (Arg *A = C.getArgs().getLastArg(options::OPT_ocloc_path_EQ);
A && std::get<1>(HA) == "ocloc") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit
std::get<1>(HA) is now repeated three times in five lines - a bit difficult to read the code.
Could you please consider a small named struct ({Triple, ToolName, HelpFlag, ExtraArg}) instead of tuple (std::tuple<llvm::Triple, StringRef, StringRef, StringRef>)? Maybe you can do a small NFC PR with this refactoring as a prerequisite to this PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into restructuring this for readability. Current changes at least clean up the std::get<1>(HA) usage.

Comment thread clang/lib/Driver/Driver.cpp Outdated
C.getDefaultToolChain().GetProgramPath(std::get<1>(HA).data()));
SmallString<128> ExecPath;
// A user provided --ocloc-path= overrides the usual tool lookup for ocloc.
if (Arg *A = C.getArgs().getLastArg(options::OPT_ocloc_path_EQ);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getLastArg(OPT_ocloc_path_EQ) is re-queried on every loop iteration for every tool, please, consider hoisting it above the loop or maybe change the order of conditions, to first check if the tool is ocloc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should no longer be an issue with the change to use a common ocloc location query.

def cuda_path_EQ : Joined<["--"], "cuda-path=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<dir>">,
HelpText<"Set the system CUDA path">;
def ocloc_path_EQ : Joined<["--"], "ocloc-path=">,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, update documentation for both: clang-linker-wrapper and clang-sycl-linker to document new options (also driver maybe?)
ClangLinkerWrapper.rst
ClangSYCLLinker.rst
sycl/doc/UsersManual.md

Also Options WG???

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation additions here: cb367d5

Options WG can be queried, but is currently more geared towards xmain and new options that require additional scrutiny. If this new option naming is somewhat controversial, a proposal can be submitted.

Fixes a few items from review
 - Improved error handling with -fsycl-help=gen
 - Make getOclocPath a static helper
 - make --ocloc-path= usage consistent when no value provided
@mdtoguchi

Copy link
Copy Markdown
Contributor Author

Question: can we use -B instead of introducing new per-tool option?

Use of -B<dir> already works (when using the old model), but it is a general application and impacts all GetProgramPath lookups. There is already precedence of using a specific option for the specific tool to locate.

@mdtoguchi
mdtoguchi requested a review from a team as a code owner August 14, 2026 00:08

@sarnex sarnex left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly lgtm, just some minor questions

// Forward the user provided location for ocloc.
if (Arg *A = Args.getLastArg(options::OPT_ocloc_path_EQ))
CmdArgs.push_back(
Args.MakeArgString(Twine("--ocloc-path=") + A->getValue()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have a test where the path contains spaces just to make sure we don't get any nonsense

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add here: dc8860f

// An empty --ocloc-path= is rejected here for consistent usage for areas
// that consume it.
if (A->getOption().matches(options::OPT_ocloc_path_EQ) &&
A->containsValue("")) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this fail if the path contains a space?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only checking for no argument and doesn't care if the string itself is malformed or contains a space.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah sorry i misread the code thanks

Comment thread clang/lib/Driver/Driver.cpp Outdated
}
// Run the Tool.
llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs);
if (llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs) < 0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably a nit:
the doc for ExecuteAndWait says

Returns
    an integer result code indicating the status of the program. A zero or positive value indicates the result code of the program. -1 indicates failure to execute -2 indicates a crash during execution or timeout 

So it will definitely return something < 0 if it failed to run/crash, but I think it will be positive if it ran but ocloc returns non-zero. Do we want to throw the error in that case or is that case handled elsewhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will update to cover all non-zero. The call here is just for emitting tool help information

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool thx

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed here: 1a47a4b

@sarnex sarnex left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Comment thread clang/lib/Driver/Driver.cpp Outdated
}
// Run the Tool.
llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs);
if (!llvm::sys::ExecuteAndWait(ToolBinary.get(), ToolArgs))

@sarnex sarnex Aug 14, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i might be overthinking this but we only want to go into the if if the result is not exacltly 0 right? either < 0 or >0 we want to error right?, if so i dont think this condition does that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I think my brain is fried.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@sarnex sarnex left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx

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.

4 participants