Skip to content

Scaling with Dask

Experimental integration. Dask evaluation is an optional third-party integration and is outside the VAMOS 1.0 stable compatibility surface. Its behavior and integration details may change in a minor release while the distributed execution contract is hardened.

VAMOS can distribute expensive objective-function evaluations through an active Dask Client. The maintained user path is the public optimize(...) API with eval_strategy="dask"; user code does not need to import VAMOS evaluation backend internals.

Installation

Install VAMOS with the optional distributed-compute dependencies:

pip install "vamos-optimization[compute]"

For a local editable checkout, the equivalent developer command is pip install -e ".[compute]".

Quick Start

Create the Dask client first, then ask VAMOS to use the experimental Dask strategy. VAMOS discovers the active client and does not own or close it.

from dask.distributed import Client, LocalCluster

from vamos import make_problem_selection, optimize
from vamos.algorithms import NSGAIIConfig

problem = make_problem_selection("zdt1", n_var=30).instantiate()
algo_cfg = NSGAIIConfig.default(pop_size=100, n_var=problem.n_var)

with LocalCluster(
    n_workers=4,
    threads_per_worker=1,
    dashboard_address=None,
) as cluster:
    with Client(cluster):
        result = optimize(
            problem,
            algorithm="nsgaii",
            algorithm_config=algo_cfg,
            max_evaluations=10_000,
            seed=42,
            engine="numpy",
            eval_strategy="dask",
        )

Connecting to an Existing Cluster

The same public path works with an existing scheduler. The Client context is responsible for its own lifecycle.

from dask.distributed import Client

from vamos import make_problem_selection, optimize
from vamos.algorithms import NSGAIIConfig

problem = make_problem_selection("zdt1", n_var=30).instantiate()
algo_cfg = NSGAIIConfig.default(pop_size=100, n_var=problem.n_var)

with Client("tcp://scheduler.example.com:8786"):
    result = optimize(
        problem,
        algorithm="nsgaii",
        algorithm_config=algo_cfg,
        max_evaluations=50_000,
        seed=42,
        engine="numpy",
        eval_strategy="dask",
    )

Failure Behavior

The maintained public Dask path does not silently fall back to serial execution. If no active Dask client is available, or the scheduler cannot be used, the run fails explicitly. This prevents a distributed benchmark from quietly producing serial timings.

Create or connect a Client before calling optimize(..., eval_strategy="dask"). If Dask is not installed, install the compute extra shown above.

Kubernetes Deployment

# dask-cluster.yaml
apiVersion: kubernetes.dask.org/v1
kind: DaskCluster
metadata:
  name: vamos-cluster
spec:
  worker:
    replicas: 10
    resources:
      limits:
        memory: "4Gi"
        cpu: "2"

After connecting a Client to the cluster scheduler, use the same eval_strategy="dask" call shown above.

When to Use Distributed Evaluation

Scenario Recommended
Cheap objectives (<1 ms) No
Medium objectives (10-100 ms) Maybe; benchmark first
Expensive objectives (>1 s) Yes
Large populations with expensive evaluations Yes

Dask adds scheduling and serialization overhead. Measure end-to-end wall time on the actual objective function rather than assuming more workers will improve a cheap workload.

Complete Example

See examples/distributed/dask_cluster.py for an executable experimental example.

# Local comparison
python examples/distributed/dask_cluster.py --compare

# Existing scheduler
python examples/distributed/dask_cluster.py --scheduler tcp://scheduler.example.com:8786