Named clusters
A dask task executor runs the tasks on a dask cluster. The module
gain.dask.named_cluster builds the dask client of that cluster from a
named cluster or from one cluster definition. A cluster definition holds
the type, the params and the worker count that build one dask
cluster. A named cluster is a cluster definition stored under a name.
This page describes the Python side of the named clusters.
Creating a dask client from a named cluster
setup_client() takes the name of a named
cluster and a worker count. It returns the dask client and the cluster
definition that built it:
from gain.dask.named_cluster import setup_client
client, cluster_definition = setup_client("local", number_of_workers=4)
None as the name selects the named cluster in
gain_named_cluster.default. None as the worker count keeps the
number_of_workers of the cluster definition.
setup_client_from_config() takes one cluster
definition mapping, with type, params and a worker count. It needs
no named cluster file. The cluster definition below starts two workers
that are threads of the current process, with no dashboard:
# Two workers that are threads of this process, with no dashboard.
LOW_COST_CLUSTER: dict[str, Any] = {
"type": "local",
"number_of_workers": 2,
"params": {"processes": False, "dashboard_address": None},
}
client, _ = setup_client_from_config(LOW_COST_CLUSTER)
setup_client_from_config works on its own copy of the mapping that it
gets. The mapping stays unchanged, so one cluster definition builds many
clients.
The lifecycle
Give the client to a DaskExecutor.
The task executor owns the client from then on. When the task executor
closes, it shuts down the client and its cluster. Do not use the client
after that.
Where the line falls
The named cluster file, the four types local, sge, slurm and
manual, and the options -N and -c are the user side. The user
page Named clusters describes them, and the user page
Running in parallel describes the task graph options. This page
describes only the two functions that build a dask client.
A running example, part 4
Part 1, on the page Graphs, builds a graph that counts the N
bases of a reference genome. Part 2, on the page Task executors,
runs it from Python, and part 3, on the page Running from a CLI,
runs it from a command line. Part 4 runs it on a dask cluster.
The first run builds a dask client from the cluster definition above and
gives it to a DaskExecutor. The with block closes the task
executor, so the client is closed after the run:
def run_on_a_dask_client(resource: GenomicResource, client: Client) -> int:
"""Count the ``N`` bases of the genome on the cluster of ``client``."""
graph, _ = build_n_count_graph(resource)
# The task executor owns the client. Closing it shuts down the cluster.
with DaskExecutor(client) as executor:
results = list(task_graph_run_with_results(graph, executor))
total: int = results[-1]
return total
The second run uses the script of part 3. -N local selects the named
cluster local, and the script builds the client with setup_client:
count_n --grr-directory grr -R genome -N local -d task-status
A dask run prints logs that change from run to run, so the page shows no
output. After the run, the record of the summary task sum_n in the
task status directory task-status holds the sum.
API
setup_client and setup_client_from_config are defined in the
module gain.dask.named_cluster.
|
Create a dask client for a named cluster. |
|
Create a dask client from one cluster definition. |
- setup_client(cluster_name: str | None = None, number_of_workers: int | None = None) tuple[Client, dict[str, Any]][source]
Create a dask client for a named cluster.
- Parameters:
cluster_name – The name of a named cluster under
gain_named_cluster.clusters.Noneselects the named cluster ingain_named_cluster.default.number_of_workers – The number of workers.
Nonekeeps the number in the cluster definition.
- Returns:
The dask client and a copy of the cluster definition that built it.
- Return type:
tuple[Client, dict[str, Any]]
- Raises:
ValueError – When
gain_named_cluster.clustersis not a mapping from names to cluster definitions, when a cluster definition holds anamekey, or when no named cluster has the namecluster_name. Also whensetup_client_from_config()refuses the cluster definition.
Notes
The function does not change the cluster definition in the dask config. Two calls for the same named cluster build two clients with the same settings.
- setup_client_from_config(cluster_config: dict[str, Any], *, number_of_workers: int | None = None) tuple[Client, dict[str, Any]][source]
Create a dask client from one cluster definition.
- Parameters:
cluster_config – A cluster definition: a mapping with the keys
type,paramsand, optionally,number_of_workersoradapt_params.typeislocal,sge,slurmormanual.paramsholds the arguments of the dask cluster class. Formanual,paramsholds theaddressof a running dask scheduler.number_of_workers – The number of workers. A number here wins over the
number_of_workersof the cluster definition.Nonekeeps the number of the cluster definition. When the cluster definition has nonumber_of_workers, the deprecatednumber_of_threadskey gives the number. When no key gives a number, the cluster adapts byadapt_params, if the cluster definition has that key.
- Returns:
The dask client and a copy of
cluster_config. The copy is equal tocluster_config. It is not the same object.- Return type:
tuple[Client, dict[str, Any]]
- Raises:
ValueError – When
typeis not a known cluster type, or when amanualcluster definition has noaddressunderparams.
Notes
For the
localtype, each worker runs one thread. Whenparamsholdsthreads_per_worker, the function logs a warning, also for the value 1, and uses 1. Forsgeandslurm, the jobqueue parameterscoresandprocessesinparamsset the threads of a worker.The function works on its own copy of
cluster_configand does not change the mapping that it gets. Two calls with the same mapping build two clients with the same settings.