Функции генерации случайных чисел rand
, randi
, и randn
вести себя по-разному для параллельных вычислений по сравнению с MATLAB® клиент. Можно изменить поведение генераторов случайных чисел на параллельных рабочих местах или на клиенте, чтобы сгенерировать воспроизводимые потоки случайных чисел.
По умолчанию клиент MATLAB и работники MATLAB используют различные генераторы случайных чисел, даже если работники являются частью локального кластера на том же компьютере, что и клиент. В приведенной ниже таблице приведены настройки по умолчанию для клиента и работников:
Генератор | Seed | Нормальное Преобразование | |
---|---|---|---|
Клиент | 'Twister' или 'mt19937ar' | 0 | 'Ziggurat' |
Рабочий (локальный или удаленный) | 'Threefry' или 'Threefry4x64_20' | 0 | 'Inversion' |
Для получения дополнительной информации о доступных генераторах и нормальных преобразованиях см. Раздел «Выбор генератора случайных чисел». Каждый рабочий процесс в кластере рисует случайные числа из независимого потока со свойствами в таблице. По умолчанию случайные числа, сгенерированные для каждого работника в parfor
цикл отличается друг от друга и от случайных чисел, сгенерированных на клиенте.
Примечание
Если у вас есть графический процессор в рабочем режиме, другие настройки применяются к потокам случайных чисел на графическом процессоре. Для получения дополнительной информации смотрите Потоки случайных чисел на графическом процессоре.
Если необходимо сгенерировать один и тот же поток чисел в клиенте и работниках, можно задать один, чтобы соответствовать другому. Можно задать алгоритм генератора и seed, используя 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
Для идентичных результатов можно задать клиент и рабочий, чтобы использовать один и тот же генератор и seed. Вот, файл randScript2.m
содержит следующий код:
rng(1,'Threefry');
R = rand(1,4);
Теперь запустите новый скрипт в клиенте и на рабочем:
randScript2; % In client
R
R = 0.1404 0.8197 0.1073 0.4131
j = 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.4549
delete(p)
Если вам нужно управлять случайными числами при каждой итерации parfor
-loop, см. «Повторение случайных чисел в циклах parfor».
Если вы работаете с нормально распределенными случайными числами, используя randn
функция, вы можете использовать те же методы, что и выше, используя RandStream
чтобы задать тип генератора, seed и нормальный алгоритм преобразования для каждого работника и клиента.
Например, предположим, что файл 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