# Customize a Strategy Builder
## A Closer Look into Strategy
In AutoDist, a `Strategy` is a representation
instructing AutoDist to transform a single-node computational graph into
a distributed one.
For more technical details,
one can refer to the [definition page](../proto_docgen.md)
of the `Strategy` Protocol Buffer message.
Below is an intuitive example of a strategy for a computational graph
with two variables `W:0` and `b:0`. Each variable is assigned
with a corresponding configured synchronizer within the
[node_config](../proto_docgen.html#autodist.proto.Strategy.Node)
section;
while the [graph_config](../proto_docgen.html#autodist.proto.Strategy.GraphConfig)
in the below example configures the data-parallel `replicas` of the whole graph.
```
node_config {
var_name: "W:0"
PSSynchronizer {
reduction_destinations: "localhost:CPU:0"
sync: true
}
}
node_config {
var_name: "b:0"
AllReduceSynchronizer {
chunk_size: 128
}
}
graph_config {
replicas:
[
"10.21.1.24:GPU:0",
"10.21.1.24:GPU:1",
"10.21.1.25:GPU:0",
"10.21.1.25:GPU:1"
]
}
```
## Build a Strategy
If you understand the strategy representation above, you can create your own
customized `StrategyBuilder`
just like the [built-in ones](choose-strategy.md).
The customized strategy builder needs to follow the
[StrategyBuilder](../../api/api/autodist.strategy.base.html#autodist.strategy.base.StrategyBuilder)
abstraction,
with a required interface `build`,
which takes a [GraphItem](../../api/autodist.graph_item)
and a
[ResourceSpec](../../api/autodist.resource_spec)
and returns a
[Strategy](../../api/api/autodist.strategy.base.html#autodist.strategy.base.Strategy)
.
```python
def build(self, graph_item: GraphItem, resource_spec: ResourceSpec) -> Strategy:
```
* Create a strategy representation wrapper object.
```python
from autodist.strategy.base import Strategy
strategy = Strategy()
```
* Set configurations for the whole graph. For example, you can utilize the `resource_spec` properties to list
all GPU devices for your data parallelism.
```python
strategy.graph_config.replicas.extend([k for k, v in resource_spec.gpu_devices])
```
* Before configuring nodes, for example, you can utilize the `graph_item` methods to list
all variables that you want to configure or utilize the `resource_spec` properties to
prepare for where to put the variable states.
```python
variables = graph_item.trainable_var_op_to_var.values()
reduction_devices = [k for k, _ in resource_spec.cpu_devices][0:1]
```
* Set configurations for variable nodes. Besides the below example,
there are various choices of configurations listed here
[strategy_pb2.Strategy.Node](../proto_docgen.html#autodist.proto.Strategy.Node)
section.
```python
from autodist.proto import strategy_pb2
node_config = []
for var in variables:
node = strategy_pb2.Strategy.Node()
node.var_name = var.name
node.PSSynchronizer.reduction_destinations.extend(reduction_devices)
node.PSSynchronizer.local_replication = False
node.PSSynchronizer.sync = True
node.PSSynchronizer.staleness = 2
node_config.append(node)
strategy.node_config.extend(node_config)
```
Congratulations! You have successfully created your first `StrategyBuilder`. AutoDist is flexible, allowing developers
to create different types of strategies based on the configuration spaces, and also for auto-learning a strategy.
For more developments on strategies, you could refer to other [built-in strategy builders](../../api/autodist.strategy)
or our development reference to invent your own [kernels](../../api/autodist.kernel).