sf.training.trainer.map_trainer¶
- mrmustard.training.trainer.map_trainer(trainer=<function train_device>, tasks=1, pbar=True, unblock=False, num_cpus=None, **kwargs)[source]¶
Maps multiple training tasks across multiple workers using ray.
In practice, the most common use case is to ignore the keywords trainer (as it defaults to
train_device()
), pbar, unblock, etc. and just concentrate on tasks and **kwargs which passes arguments to the wrapper functions that contain the task execution logic, as well as theOptimizer
and itsOptimizer.minimize()
.For example, with the default trainer
train_device()
, two user-defined functions are used for wrapping up user logic:A device_factory (optional) that wraps around the logic for making circuits/states to be optimized; it is expected to return a single, or list of, :class:`Circuit`(s).
A cost_fn (required) that takes the circuits made and additional keyword arguments and returns a backprop-able scalar cost.
Refer to the kwargs section below for more available options.
- Parameters:
trainer (callable) – The function containing the training loop to be distributed, whose fixed arguments are to be passed by **kwargs and task-specific arguments iterated through tasks. Provide only when custom evaluation/training logic is needed. Defaults to
train_device()
.tasks (Union[int, Sequence, Mapping]) – Number of repeats or collection of task-specific training config arguments feeding into
train_device()
. Refer to kwargs below for the available options. Defaults to 1 which runs trainer exactly once.pbar (bool) – Whether to show a progress bar, available only in blocking mode (i.e. unblock==False). Defaults to True.
unblock (bool) – Whether to unblock the process and returns a getter function returning the available results. Defaults to False.
num_cpus (int) – Number of cpu workers to initialize ray. Defaults to the number of virtual cores.
kwargs –
Additional arguments containing fixed training config kwargs feeding into trainer. For the default trainer
train_device()
, available options are:- cost_fn (callable):
The optimized cost function to be distributed. It’s expected to accept the output of device_factory as *args as well as user-defined **kwargs, and returns a scalar cost. Its user-defined **kwargs will be passed from this function’s **kwargs which must include all its required arguments.
- device_factory (callable):
Function that (partially) takes kwargs and returns a device, or list/dict of devices. If None, cost_fn will be assumed to take no positional argument (for example, when device-making is contained in cost_fn). Defaults to None.
- metric_fns (Union[Sequence[callable], Mapping[callable], callable]):
Optional collection of functions that takes the output of device_factory after optimization and returns arbitrary evaluation/information.
- return_kwargs (bool):
Whether to include input config kwargs in the output dict. Defualts to True.
- skip_opt (bool):
Whether to skip the optimization and directly calculate cost.
- tag (str):
Optional label of the training task associated with the kwargs to be included in the output dict.
any kwargs to cost_fn: exluding the output of device_factory.
any kwargs to device_factory: e.g. x, r, theta, etc.
any kwargs to Optimizer: e.g. euclidean_lr.
any kwargs to Optimizer.minimize: excluding cost_fn and by_optimizing, e.g. max_steps.
- Returns
- Union[List, Dict]: The collection of results from each training task. Returns
a list if tasks is provided as an int or a list; or
a dict with the same keys if tasks is provided as a dict.
Examples:¶
from mrmustard.lab import Vacuum, Dgate, Ggate, Gaussian from mrmustard.physics import fidelity from mrmustard.training.trainer import map_trainer def make_circ(x=0.): return Ggate(num_modes=1, symplectic_trainable=True) >> Dgate(x=x, x_trainable=True, y_trainable=True) def cost_fn(circ=make_circ(0.1), y_targ=0.): target = Gaussian(1) >> Dgate(-1.5, y_targ) s = Vacuum(1) >> circ return -fidelity(s, target) # Use case 0: Calculate the cost of a randomly initialized circuit 5 times without optimizing it. results_0 = map_trainer( cost_fn=cost_fn, tasks=5, ) # Use case 1: Run circuit optimization 5 times on randomly initialized circuits. results_1 = map_trainer( cost_fn=cost_fn, device_factory=make_circ, tasks=5, max_steps=50, symplectic_lr=0.05, ) # Use case 2: Run 2 sets of circuit optimization with custom parameters passed as list. results_2 = map_trainer( cost_fn=cost_fn, device_factory=make_circ, tasks=[ {'x': 0.1, 'euclidean_lr': 0.005, 'max_steps': 50}, {'x': -0.7, 'euclidean_lr': 0.1, 'max_steps': 2}, ], y_targ=0.35, symplectic_lr=0.05, AUTOCUTOFF_MAX_CUTOFF=7, ) # Use case 3: Run 2 sets of circuit optimization with custom parameters passed as dict with extra metric functions for evaluating the final optimized circuit. results_3 = map_trainer( cost_fn=cost_fn, device_factory=make_circ, tasks={ 'my-job': {'x': 0.1, 'euclidean_lr': 0.005, 'max_steps': 50}, 'my-other-job': {'x': -0.7, 'euclidean_lr': 0.1, 'max_steps': 2}, }, y_targ=0.35, symplectic_lr=0.05, metric_fns={ 'is_gaussian': lambda c: c.is_gaussian, 'foo': lambda _: 17. },
)