| --- |
| layout: documentation |
| title: Execution groups |
| --- |
| |
| # Execution groups |
| |
| |
| Execution groups allow for multiple execution platforms within a single target. |
| Each execution group has its own [toolchain](toolchains.md) dependencies and |
| performs its own [toolchain resolution](toolchains.md#toolchain-resolution). |
| |
| ## Current status |
| |
| This feature is implemented but experimental. In order to use, you must set the |
| flag `--experimental_exec_group=true`. |
| |
| ## Background |
| |
| Execution groups allow the rule author to define sets of actions, each with a |
| potentially different execution platform. Multiple execution platforms can allow |
| actions to execution differently, for example compiling an iOS app on a remote |
| (linux) worker and then linking/code signing on a local mac worker. |
| |
| Being able to define groups of actions also helps alleviate the usage of action |
| mnemonics as a proxy for specifying actions. Mnemonics are not guaranteed to be |
| unique and can only reference a single action. This is especially helpful in |
| allocating extra resources to specific memory and processing intensive actions |
| like linking in c++ builds without over-allocating to less demanding tasks. |
| |
| ## Defining execution groups |
| |
| During rule definition, rule authors can declare a set of execution groups. On |
| each execution group, the rule author can specify everything needed to select |
| an execution platform for that execution group, namely any constraints via |
| `exec_compatible_with` and toolchain types via `toolchain`. If an execution group |
| is created as empty (no specified toolchains or constraints) it will |
| automatically inherit these |
| [parameters](https://docs.bazel.build/versions/master/skylark/lib/globals.html#rule) |
| from the rule to which the group is attached. |
| |
| TODO(juliexxia): link to exec_group method docs when they get released in bazel. |
| |
| ```python |
| # foo.bzl |
| my_rule = rule( |
| _impl, |
| exec_groups = { |
| “link”: exec_group( |
| exec_compatible_with = [ "@platforms//os:linux" ] |
| toolchains = ["//foo:toolchain_type"], |
| |
| ), |
| “test”: exec_group( |
| toolchains = ["//foo_tools:toolchain_type"], |
| ), |
| }, |
| attrs = { |
| "_compiler": attr.label(cfg = config.exec("link")) |
| }, |
| ) |
| ``` |
| |
| In the code snippet above, you can see that tool dependencies can also specify |
| transition for an exec group using the |
| [`cfg`](https://docs.bazel.build/versions/master/skylark/lib/attr.html#label) |
| attribute param and the |
| [`config`](https://docs.bazel.build/versions/master/skylark/lib/config.html) |
| module. The module exposes an `exec` function which takes a single string |
| parameter which is the name of the exec group for which the dependency should be |
| built. |
| |
| ## Accessing execution groups |
| |
| In the rule implementation, you can declare that actions should be run on the |
| execution platform of an execution group. You can do this by using the `exec_group` |
| param of action generating methods, specifically [`ctx.actions.run`] |
| (https://docs.bazel.build/versions/master/skylark/lib/actions.html#run) and |
| [`ctx.actions.run_shell`](https://docs.bazel.build/versions/master/skylark/lib/actions.html#run_shell). |
| |
| ```python |
| # foo.bzl |
| def _impl(ctx): |
| ctx.actions.run( |
| inputs = [ctx.attr._some_tool, ctx.srcs[0]] |
| exec_group = "compile", |
| # ... |
| ) |
| ``` |
| |
| Rule authors will also be able to access the [resolved toolchains] |
| (toolchains.md#toolchain-resolution) of execution groups, similarly to how you |
| can access the resolved toolchain of a target: |
| |
| ```python |
| # foo.bzl |
| def _impl(ctx): |
| foo_info = ctx.exec_groups["link"].toolchains["//foo:toolchain_type"].fooinfo |
| ctx.actions.run( |
| inputs = [foo_info, ctx.srcs[0]] |
| exec_group = "link", |
| # ... |
| ) |
| ``` |
| |
| Note: If an action uses a toolchain from an execution group, but doesn't specify |
| that execution group in the action declaration, that may potentially cause |
| issues. A mismatch like this may not immediately cause failures, but is a latent |
| problem. |
| |
| ## Using execution groups to set execution properties |
| |
| Execution groups are integrated with the |
| [`exec_properties`](be/common-definitions.html#common-attributes) |
| attribute that exists on every rule and allows the target writer to specify a |
| string dict of properties that is then passed to the execution machinery. For |
| example, if you wanted to set some property, say memory, for the target and give |
| certain actions a higher memory allocation, you would write an `exec_properties` |
| entry with an execution-group-augmented key, e.g.: |
| |
| ```python |
| # BUILD |
| my_rule( |
| name = 'my_target', |
| exec_properties = { |
| 'mem': '12g', |
| 'link.mem': '16g' |
| } |
| … |
| ) |
| ``` |
| |
| All actions with `exec_group = "link"` would see the exec properties |
| dictionary as `{"mem": "16g"}`. As you see here, execution-group-level |
| settings override target-level settings. |
| |