Skip to content

Parallel

distribute(simulation_fn, spaces, n_cores=None, shuffle=False)

Distribute a function over a list of parameters in parallel.

Parameters:

Name Type Description Default
simulation_fn Callable

function to be distributed

required
spaces list[list[float]]

list of lists of parameters

required
n_cores int

number of cores to use.

None

Returns:

Type Description

tuple index (int): Index of the parameters in the spaces list, multiple dims. simulation_fn output (any): The output of the simulation function. index - index of the parameters in the spaces list, multiple dims.

Source code in cmtj/utils/parallel.py
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
def distribute(
    simulation_fn: Callable,
    spaces: list[list[float]],
    n_cores: int = None,
    shuffle: bool = False,
):
    """
    Distribute a function over a list of parameters in parallel.
    :param simulation_fn: function to be distributed
    :param spaces: list of lists of parameters
    :param n_cores: number of cores to use.
    :returns: tuple
        index (int): Index of the parameters in the spaces list, multiple dims.
        simulation_fn output (any): The output of the simulation function.
        index - index of the parameters in the spaces list, multiple dims.
    """
    spaces = [np.asarray(space) for space in spaces]

    def _get_index(values):
        return [np.argwhere(space == values[i]).ravel()[0] for i, space in enumerate(spaces)]

    iterables = list(product(*spaces))
    indexes = [_get_index(val) for val in iterables]
    # shuffle the indexes
    if shuffle:
        index_reshuffle = np.arange(len(indexes))
        np.random.shuffle(index_reshuffle)
        # reorder the indexes
        iterables = np.asarray(iterables)[index_reshuffle].tolist()
        indexes = np.asarray(indexes)[index_reshuffle].tolist()

    def func_wrapper(iterable):
        return iterable, simulation_fn(*iterable)

    with Pool(processes=n_cores) as pool:
        for result in tqdm(pool.imap_unordered(func_wrapper, iterables), total=len(iterables)):
            iterable, output = result
            indx = indexes[iterables.index(iterable)]
            yield indx, output

parallel_vsd_sb_model(simulation_fn, frequencies, Hvecs, layers, J1=None, J2=None, iDMI=None, n_cores=None)

Parallelise the VSD SB model.

Parameters:

Name Type Description Default
simulation_fn Callable

function to be distributed. This function must take a tuple of arguments, where the first argument is the frequency, then Hvectors, the list of layers and finally the list of J1 and J2 values.

required
frequencies list[float]

list of frequencies

required
Hvecs list[list[float]]

list of Hvectors in cartesian coordinates

required
layers list[LayerDynamic]

list of layers

required
J1 list[float]

list of J1 values

None
J2 list[float]

list of J2 values

None
n_cores int

number of cores to use.

None

Returns:

Type Description

list of simulation_fn outputs for each frequency

Source code in cmtj/utils/parallel.py
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
def parallel_vsd_sb_model(
    simulation_fn: Callable,
    frequencies: list[float],
    Hvecs: list[list[float]],
    layers: list[LayerDynamic],
    J1: list[float] = None,
    J2: list[float] = None,
    iDMI: list[float] = None,
    n_cores: int = None,
):
    """
    Parallelise the VSD SB model.
    :param simulation_fn: function to be distributed.
        This function must take a tuple of arguments, where the first argument is the
        frequency, then Hvectors, the list of layers and finally the list of J1 and J2 values.
    :param frequencies: list of frequencies
    :param Hvecs: list of Hvectors in cartesian coordinates
    :param layers: list of layers
    :param J1: list of J1 values
    :param J2: list of J2 values
    :param n_cores: number of cores to use.
    :returns: list of simulation_fn outputs for each frequency
    """
    if J1 is None:
        J1 = [0] * (len(layers) - 1)
    if J2 is None:
        J2 = [0] * (len(layers) - 1)
    if iDMI is None:
        iDMI = [0] * (len(layers) - 1)
    args = [(f, Hvecs, *layers, J1, J2, iDMI) for f in frequencies]
    with Pool(processes=n_cores) as pool:
        return list(tqdm(pool.imap(simulation_fn, args), total=len(frequencies)))