Automatic execution groups select an execution platform for each toolchain type. In other words, one target can have multiple execution platforms without defining execution groups.
Quick summary
Automatic execution groups are closely connected to toolchains. If you are using
toolchains, you need to set them on the affected actions (actions which use an
executable or a tool from a toolchain) by adding toolchain
parameter. For
example:
ctx.actions.run(
...,
executable = ctx.toolchain['@bazel_tools//tools/jdk:toolchain_type'].tool,
...,
toolchain = '@bazel_tools//tools/jdk:toolchain_type',
)
If the action does not use a tool or executable from a toolchain, and Blaze
doesn't detect that (the error is raised), you can set
toolchain = None
.
If you need to use multiple toolchains on a single execution platform (an action uses executable or tools from two or more toolchains), you need to manually define exec_groups (check When should I use a custom exec_group? section).
History
Before AEGs, the execution platform was selected on a rule level. For example:
my_rule = rule(
_impl,
toolchains = ['//tools:toolchain_type_1', '//tools:toolchain_type_2'],
)
Rule my_rule
registers two toolchain types. This means that the Toolchain
Resolution used
to find an execution platform which supports both toolchain types. The selected
execution platform was used for each registered action inside the rule, unless
specified differently with exec_groups.
In other words, all actions inside the rule used to have a single execution
platform even if they used tools from different toolchains (execution platform
is selected for each target). This resulted in failures when there was no
execution platform supporting all toolchains.
Current state
With AEGs, the execution platform is selected for each toolchain type. The
implementation function of the earlier example, my_rule
, would look like:
def _impl(ctx):
ctx.actions.run(
mnemonic = "First action",
executable = ctx.toolchain['//tools:toolchain_type_1'].tool,
toolchain = '//tools:toolchain_type_1',
)
ctx.actions.run(
mnemonic = "Second action",
executable = ctx.toolchain['//tools:toolchain_type_2'].tool,
toolchain = '//tools:toolchain_type_2',
)
This rule creates two actions, the First action
which uses executable from a
//tools:toolchain_type_1
and the Second action
which uses executable from a
//tools:toolchain_type_2
. Before AEGs, both of these actions would be executed
on a single execution platform which supports both toolchain types. With AEGs,
by adding the toolchain
parameter inside the actions, each action executes on
the execution platform that provides the toolchain. The actions may be executed
on different execution platforms.
The same is effective with ctx.actions.run_shell where toolchain
parameter should be added when tools
are from a toolchain.
Difference between custom exec groups and automatic exec groups
As the name suggests, AEGs are exec groups created automatically for each toolchain type registered on a rule. There is no need to manually specify them, unlike the "classic" exec groups.
When should I use a custom exec_group?
Custom exec_groups are needed only in case where multiple toolchains need to execute on a single execution platform. In all other cases there's no need to define custom exec_groups. For example:
def _impl(ctx):
ctx.actions.run(
...,
executable = ctx.toolchain['//tools:toolchain_type_1'].tool,
tools = [ctx.toolchain['//tools:toolchain_type_2'].tool],
exec_group = 'two_toolchains',
)
my_rule = rule(
_impl,
exec_groups = {
"two_toolchains": exec_group(
toolchains = ['//tools:toolchain_type_1', '//tools:toolchain_type_2'],
),
}
)
Migration of AEGs
Internally in google3, Blaze is already using AEGs. Externally for Bazel, migration is in the process. Some rules are already using this feature (e.g. Java and C++ rules).
Which Bazel versions support this migration?
AEGs are fully supported from Bazel 7.
How to enable AEGs?
Set --incompatible_auto_exec_groups
to true. More information about the flag
on the GitHub issue.
How to enable AEGs inside a particular rule?
Set the _use_auto_exec_groups
attribute on a rule.
my_rule = rule(
_impl,
attrs = {
"_use_auto_exec_groups": attr.bool(default = True),
}
)
This enables AEGs only in my_rule
and its actions start using the new logic
when selecting the execution platform. Incompatible flag is overridden with this
attribute.
How to disable AEGs in case of an error?
Set --incompatible_auto_exec_groups
to false to completely disable AEGs in
your project (flag's GitHub issue), or disable a particular rule
by setting _use_auto_exec_groups
attribute to False
(more details about the attribute).
Error messages while migrating to AEGs
Couldn't identify if tools are from implicit dependencies or a toolchain. Please set the toolchain parameter. If you're not using a toolchain, set it to 'None'.
- In this case you get a stack of calls before the error happened and you can
clearly see which exact action needs the toolchain parameter. Check which
toolchain is used for the action and set it with the toolchain param. If no
toolchain is used inside the action for tools or executable, set it to
None
.
Action declared for non-existent toolchain '[toolchain_type]'.
- This means that you've set the toolchain parameter on the action but didn't
register it on the rule. Register the toolchain or set
None
inside the action.
Additional material
For more information, check design document: Automatic exec groups for toolchains.