По умолчанию функции генерации случайных чисел rand, randi, и randn использовать различные настройки генератора для вычислений на GPU по сравнению с CPU. Можно изменить поведение генераторов случайных чисел, чтобы генерировать воспроизводимые последовательности случайных чисел на GPU и CPU.
В таблице ниже приведены параметры по умолчанию для графического процессора и ЦП для клиентских и рабочих сеансов MATLAB ® :
| Генератор | Семя | Обычное преобразование | |
|---|---|---|---|
| Центральный процессор клиента | 'Twister' или 'mt19937ar' | 0 | 'Ziggurat' |
| Рабочий ЦП | 'Threefry' или 'Threefry4x64_20' | 0 | 'Inversion' |
| Графический процессор (на клиенте или работнике) | 'Threefry' или 'Threefry4x64_20' | 0 | 'BoxMuller' |
В большинстве случаев не имеет значения, что генератор случайных чисел по умолчанию на GPU не совпадает с генераторами по умолчанию на клиентском или рабочем CPU. Однако если требуется воспроизвести одни и те же результаты как на GPU, так и на CPU, можно соответствующим образом настроить генераторы.
В новой сессии MATLAB MATLAB генерирует различные последовательности случайных чисел на CPU и GPU.
Rc = rand(1,4)
Rc =
0.8147 0.9058 0.1270 0.9134Rg = rand(1,4,'gpuArray')
Rg =
0.3640 0.5421 0.6543 0.7436Если необходимо создать одну и ту же последовательность случайных чисел как на GPU, так и на CPU, можно установить соответствующие настройки генератора.
На GPU доступны три алгоритма генератора случайных чисел: 'Threefry', 'Philox', и 'CombRecursive'. Все они поддерживаются ЦП. В следующей таблице перечислены алгоритмы для этих генераторов и их свойства.
| Ключевое слово | Генератор | Поддержка нескольких потоков и субпотоков | Приблизительный период с полной точностью |
|---|---|---|---|
'Threefry' или 'Threefry4x64_20' | Три генератора 4x64 с 20 патронами | Да | 2514 (2256 потоков длиной 2258) |
'Philox' или 'Philox4x32_10' | Генератор Philox 4x32 с 10 патронами | Да | 2193 (264 потока длиной 2129) |
'CombRecursive' или 'mrg32k3a' | Комбинированный множественный рекурсивный генератор | Да | 2191 (263 потока длиной 2127) |
Вы можете использовать rng и gpurng для установки алгоритма генератора и начального значения на CPU и GPU соответственно.
sc = rng(1,'Threefry');
Rc = rand(1,4)Rc = 0.1404 0.8197 0.1073 0.4131
sg = gpurng(1,'Threefry'); Rg = rand(1,4,'gpuArray')
Rg =
0.1404 0.8197 0.1073 0.4131rand и randi теперь генерируйте одни и те же последовательности случайных чисел на клиентском CPU и GPU.
Параллельный рабочий CPU использует тот же тип генератора случайных чисел по умолчанию и начальное значение, что и клиентский GPU и рабочий GPU, если он имеет его. Графический процессор и ЦП не используют один и тот же поток. По умолчанию rand и randi создать одну и ту же последовательность номеров на GPU и рабочем CPU.
Настройки отличаются от настроек на клиентском ЦП. Дополнительные сведения см. в разделе Управление потоками случайных чисел на рабочих
Если необходимо создать различные случайные числа для каждого работника, можно изменить настройки генератора. В этом примере каждый работник создает одну и ту же последовательность на своем GPU и CPU, но на каждом работнике создаются разные последовательности.
p = parpool(2); spmd rng(labindex,'Threefry'); Rc = rand(1,4) gpurng(labindex,'Threefry'); Rg = rand(1,4,'gpuArray') end delete(p)
Для нормально распределенных случайных чисел, созданных с помощью randn функция MATLAB дает различные результаты на клиентском CPU, рабочем CPU и GPU. Преобразование однородных случайных чисел в нормально распределенные случайные числа управляется NormalTransform установка. Управлять этим можно с помощью графического процессора parallel.gpu.RandStream.
На клиентском ЦП значение по умолчанию 'NormalTransform' параметр имеет значение 'Ziggurat'. Для рабочего ЦП по умолчанию установлено значение 'Inversion'.
Если не указано иное, код графического процессора использует 'BoxMuller' преобразование для 'Threefry' и 'Philox' генераторы и 'Inversion' преобразование для 'CombRecursive' генератор.
Вы можете установить одни и те же генераторы и преобразования на CPU и GPU, чтобы получить то же самое randn последовательности. Единственным преобразованием, поддерживаемым как на CPU, так и на GPU, является 'Inversion' преобразование.
sc = RandStream('Threefry','NormalTransform','Inversion','Seed',1); RandStream.setGlobalStream(sc) sg = parallel.gpu.RandStream('Threefry','NormalTransform','Inversion','Seed',1); parallel.gpu.RandStream.setGlobalStream(sg); Rc = randn(1,4)
Rc = -1.0783 0.9144 -1.2412 -0.2196
Rg = randn(1,4,'gpuArray')
Rg = -1.0783 0.9144 -1.2412 -0.2196
gpurng | parallel.gpu.RandStream | RandStream | rng