Управляйте потоками случайных чисел на рабочих

Функции генерации случайных чисел 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

См. также

|

Похожие темы