Commit 3e25316
feat: Implement resource requirements for components (#194)
# Summary
Adds resource specification support for components to enable Ray actor
resource allocation and Tuner placement group optimization. Resources
can be declared as class attributes on Component definitions
(recommended) or overridden at instantiation time.
# Changes
**Core Schema**
- Added `Resource` Pydantic class in `plugboard_schemas.component` with
fields: `cpu`, `gpu`, `memory` (integer bytes), `resources` (custom
dict)
- Supports full SI prefix notation:
- Decimal SI: `n`, `u`, `m`, `k`, `M`, `G`, `T`, `P`, `E` (e.g.,
`"250m"` → 0.25, `"5k"` → 5000)
- Binary: `Ki`, `Mi`, `Gi`, `Ti`, `Pi`, `Ei` (e.g., `"10Mi"` →
10,485,760 bytes)
- Default: `cpu=0.001`, others zero
- Implements `to_ray_options()` for Ray actor configuration
- Memory stored as integer bytes for precision
**Component Integration**
- Added `resources` class attribute to `Component` for declaring default
resource requirements
- Extended `Component.__init__()` with optional `resources` parameter to
override class-level defaults
- Updated `ComponentArgsDict`, `ComponentArgsSpec` for YAML support
- Resources auto-exported and reconstructed from configuration
- Each component instance creates an instance-scoped copy of resources
**Ray Execution**
- Modified `RayProcess._create_component_actor()` to apply resource
requirements via `ray.remote(**ray_options)`
- Falls back to default `Resource()` when unspecified
- Import statements organized at top of file
**Tuner Optimization**
- Added `Tuner._calculate_placement_bundles()` to aggregate component
resources
- Creates `PlacementGroupFactory` with tuner overhead (0.5 CPU) +
component bundle
- Import statements organized at top of file
**Documentation**
- Updated `Component` class docstring to document the `resources` class
attribute
- Added `Component.__init__()` docstring explaining resource parameter
behavior
- Added comprehensive section in
`docs/examples/tutorials/running-in-parallel.md` explaining both
approaches:
- Class-level resource declaration (recommended)
- Constructor override for flexibility
- Python and YAML examples demonstrating both resource specification
approaches
**Usage Examples**
Class-level declaration (recommended):
```python
from plugboard.component import Component
from plugboard.schemas import Resource
class CPUIntensiveTask(Component):
io = IO(inputs=["x"], outputs=["y"])
resources = Resource(cpu=2.0) # Declare at class level
async def step(self) -> None:
# Your logic here
pass
# Uses class-level resources
component = CPUIntensiveTask(name="my-task")
```
Constructor override:
```python
# Override class-level resources when needed
component = CPUIntensiveTask(
name="my-task",
resources=Resource(cpu=4.0) # Override to 4 CPUs
)
```
YAML config:
```yaml
components:
- type: my.CPUIntensiveTask
args:
name: my-task
# Optionally override class-level resources
resources:
cpu: 4.0
memory: "512Mi"
```
**Tests**
- Unit tests: Resource parsing with all SI prefixes, validation, Ray
conversion
- Integration tests: Component/ProcessSpec/Tuner scenarios, class-level
resource declaration
- Manual verification (full test suite requires Ray dependencies)
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>feat: Implement resource requirements for
components</issue_title>
> <issue_description>### Summary
>
> Users would like to be able to specify custom resource requirements on
`Component` objects. These can be passed to Ray when a `RayProcess` is
used or a `Tuner` object is run.
>
> Requirements:
> * Must be able to specify `Resource` requirements for `cpu`, `gpu`,
`memory`, `resources`. These should be defined as a Pydantic class in
`plugboard_schemas`.
> * Must be able to specify resources as a numerical value, or as a
string (to be validated by Pydantic), e.g. `250m` for 0.25 or `10Mi` for
1024 * 1024 * 10. `resources` should be a dictionary of string key,
numerical value pairs.
> * Must be able to convert these requirements to their Ray equivalents,
see
https://docs.ray.io/en/latest/ray-core/api/doc/ray.actor.ActorClass.options.html,
i.e. `cpu = "250m"` gets converted to `num_cpus=0.25`.
> * Must be able to pass a `Resource` to a `Component` when
instantiating it. This will require changes to the `Component` and its
schema, so that we can specify resource requirements in YAML config.
> * The default requirement should be `{"cpu": 0.001}`, to be used if
the user does not provide anything.
> * Resource requirements should be passed to the actor options in
`RayProcess`.
> * They should be used in the resource placement group inside `Tuner`.
>
> ### Example
>
> _No response_
>
> ### Alternatives
>
> _No response_</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #193
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com>
Co-authored-by: Toby Coleman <toby@tobycoleman.com>
Co-authored-by: Chris Knight <chrisk314@gmail.com>
Co-authored-by: chrisk314 <2366658+chrisk314@users.noreply.github.com>1 parent 229a08f commit 3e25316
17 files changed
Lines changed: 850 additions & 23 deletions
File tree
- .github/workflows
- docs
- api/schemas
- examples/tutorials
- examples/tutorials/004_using_ray
- plugboard-schemas/plugboard_schemas
- plugboard
- component
- process
- schemas
- tune
- tests
- integration
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
78 | | - | |
| 78 | + | |
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
116 | | - | |
| 116 | + | |
117 | 117 | | |
118 | 118 | | |
119 | 119 | | |
| |||
157 | 157 | | |
158 | 158 | | |
159 | 159 | | |
160 | | - | |
| 160 | + | |
161 | 161 | | |
162 | 162 | | |
163 | 163 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
116 | 117 | | |
117 | 118 | | |
118 | 119 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| 80 | + | |
80 | 81 | | |
81 | 82 | | |
82 | 83 | | |
| |||
0 commit comments