Функции генерации случайных чисел rand, randi, и randn вести себя по-разному при параллельных расчетах по сравнению с клиентом MATLAB ®. Можно изменить поведение генераторов случайных чисел на параллельных рабочих или на клиенте для генерации воспроизводимых потоков случайных чисел .
По умолчанию клиент MATLAB и работники MATLAB используют разные генераторы случайных чисел, даже если работники являются частью локального кластера на той же машине, что и клиент. В таблице ниже приведены параметры по умолчанию для клиента и работников:
| Генератор | Семя | Обычное преобразование | |
|---|---|---|---|
| Клиент | 'Twister' или 'mt19937ar' | 0 | 'Ziggurat' |
| Работник (локальный или удаленный) | 'Threefry' или 'Threefry4x64_20' | 0 | 'Inversion' |
Дополнительные сведения о доступных генераторах и нормальных преобразованиях см. в разделе Выбор генератора случайных чисел. Каждый работник в кластере извлекает случайные числа из независимого потока со свойствами в таблице. По умолчанию случайные числа, сгенерированные для каждого работника в parfor циклы отличаются друг от друга и от случайных чисел, генерируемых на клиенте.
Примечание
Если на работнике имеется графический процессор, к потокам случайных чисел на графическом процессоре применяются различные настройки. Дополнительные сведения см. в разделе Потоки случайных чисел на графическом процессоре.
Если необходимо создать один и тот же поток чисел в клиенте и работниках, можно настроить один на соответствие другому. Алгоритм генератора и начальное число можно задать с помощью rng.
Например, можно запустить сценарий в качестве пакетного задания на работнике и использовать тот же генератор или последовательность, что и клиент. Предположим, что вы начинаете с файла сценария с именем randScript1.m который содержит строку:
R = rand(1,4);
Этот сценарий можно запустить в клиенте, а затем в качестве пакетного задания на работнике. Обратите внимание, что сгенерированные по умолчанию последовательности случайных чисел в результатах отличаются.
randScript1; % In client
R
R =
0.8147 0.9058 0.1270 0.9134
parallel.defaultClusterProfile('local') c = parcluster(); j = batch(c,'randScript1'); % On worker wait(j);load(j); R
R =
0.1349 0.6744 0.9301 0.5332Для идентичных результатов можно настроить клиента и работника на использование одного и того же генератора и начального значения. Вот, файл randScript2.m содержит следующий код:
rng(1,'Threefry');
R = rand(1,4);Теперь запустите новый сценарий в клиенте и на работнике:
randScript2; % In client
R
R =
0.1404 0.8197 0.1073 0.4131j = batch(c,'randScript2'); % On worker wait(j); load(j); R
R =
0.1404 0.8197 0.1073 0.4131По умолчанию каждый работник в кластере, работающий над одним и тем же заданием, имеет независимый поток случайных чисел. Если rand, randi, или randn вызываются параллельно, каждый работник производит уникальную последовательность случайных чисел.
Примечание
Поскольку rng('shuffle') инициирует генератор случайных чисел на основе текущего времени, не используйте эту команду, чтобы задать поток случайных чисел для различных работников, если вы хотите обеспечить независимые потоки. Это особенно верно, когда команда отправляется нескольким работникам одновременно, например, внутри parfor, spmdили коммуникационное задание. Для независимых потоков на рабочих используется поведение по умолчанию; или если этого недостаточно для ваших потребностей, рассмотрите возможность использования уникального подпотока на каждом работнике с помощью RandStream.
В этом примере используются два работника в параллельном пуле, чтобы показать, что они генерируют уникальные последовательности случайных чисел.
p = parpool(2); spmd R = rand(1,4); % Different on each worker end R{1},R{2}
ans =
0.1349 0.6744 0.9301 0.5332
ans =
0.6383 0.5195 0.1398 0.6509
delete(p)
Если необходимо, чтобы все работники генерировали одну и ту же последовательность чисел, можно задать для каждого работника одни и те же настройки генератора:
p = parpool(2); spmd rng(0,'Philox'); % Default seed 0. R = rand(1,4); % Same on all workers end R{1},R{2}
ans =
0.3655 0.6975 0.1789 0.4549
ans =
0.3655 0.6975 0.1789 0.4549delete(p)
Если необходимо управлять случайными числами в каждой итерации parfor-loop, см. раздел Повтор случайных чисел в цикле parfor-Loops.
При работе с обычно распределенными случайными числами с помощью randn функция, вы можете использовать те же методы, что и выше, используя RandStream установка типа генератора, начального значения и нормального алгоритма преобразования для каждого работника и клиента.
Например, предположим, что файл randScript3.m содержит код:
stream = RandStream('Threefry','Seed',0,'NormalTransform','Inversion'); RandStream.setGlobalStream(stream); R = randn(1,7)
batch или spmd) для получения одинаковой последовательности случайных чисел:R =
-0.3479 0.1057 0.3969 0.6544 -1.8228 0.9587 0.5360