muRAND 开发者指南
muRAND 是基于 MUSA 开发的高效伪随机数和准随机数生成器,适用于蒙特卡洛模拟、深度学习初始化、随机算法等场景。
概述
什么是 muRAND
muRAND(Pseudo-Random and Quasi-Random Numbers based on MUSA,随机数生成库)提供基于 MUSA 的随机数生成接口,支持在 MTGPU 上生成伪随机数和准随机数,适用于蒙特卡洛模拟、模型初始化和随机采样等场景。
关键特性
- 支持多种伪随机数和准随机数生成器。
- 支持均匀分布、正态分布和泊松分布等常用分布。
- 可与 MUSA stream 配合,实现设备侧随机数生成和异步数据传输。
- 适用于批量随机数生成和高吞吐模拟任务。
支持的生成器类型
| 生成器 | 说明 | 应用场景 |
|---|---|---|
| MURAND_RNG_PSEUDO_MTGP32 | Mersenne Twister for GPU | 通用伪随机数 |
| MURAND_RNG_PSEUDO_PHILOX4_32_10 | Philox4x32 10 轮 | 高质量伪随机数 |
| MURAND_RNG_QUASI_SOBOL32 | Sobol 准随机数 | 蒙特卡洛积分 |
支持的分布
- 均匀分布 (Uniform):
murandGenerateUniform() - 正态分布 (Gaussian/Normal):
murandGenerateNormal() - 泊松分布 (Poisson):
murandGeneratePoisson()
快速开始
生成均匀分布随机数
#include <musa_runtime.h>
#include <murand.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int rand_n = 128; // 生成 128 个随机数
int seed = 777; // 随机种子
// 创建 stream
musaStream_t stream;
musaStreamCreateWithFlags(&stream, musaStreamNonBlocking);
// 分配设备内存
float *d_Rand;
musaMalloc((void **)&d_Rand, rand_n * sizeof(float));
// 创建随机数生成器
murandGenerator_t prngGPU;
murandCreateGenerator(&prngGPU, MURAND_RNG_PSEUDO_MTGP32);
murandSetStream(prngGPU, stream);
murandSetPseudoRandomGeneratorSeed(prngGPU, seed);
// 分配主机 pinned 内存
float *h_RandGPU;
musaMallocHost(&h_RandGPU, rand_n * sizeof(float));
printf("Generating random numbers on GPU...\n");
// 生成均匀分布随机数 [0, 1)
murandGenerateUniform(prngGPU, (float *)d_Rand, rand_n);
// 复制结果回主机
printf("Reading back the results...\n");
musaMemcpyAsync(h_RandGPU, d_Rand, rand_n * sizeof(float),
musaMemcpyDeviceToHost, stream);
musaDeviceSynchronize();
// 打印结果
for(int i = 0; i < rand_n; i++) {
printf("r[%d] = %f\n", i, h_RandGPU[i]);
}
// 释放资源
murandDestroyGenerator(prngGPU);
musaStreamDestroy(stream);
musaFree(d_Rand);
musaFreeHost(h_RandGPU);
return EXIT_SUCCESS;
}
编译和运行
# 使用 mcc 编译
mcc -x musa rand_example.cpp \
-L/usr/local/musa/lib \
-I/usr/local/musa/include \
-lmurand -lmusart \
-o rand_example
# 运行
./rand_example