[翻译]CURAND Libaray--Host API--(2)

2.3 返回值

所有的CURAND host端的函数返回值都是curandStatus_t.如果调用没有错误,则返回成功,即返回值为CURAND_STATUS_SUCCESS.如果发生了错误,返回值会依据错误的不同而不同。因为cuda允许内核函数异步的调用cpu端的代码,因此返回的错误,有可能是在调用函数库时发生的,而非CURAND内核函数,此时,返回值是CURAND_STATUS_PREEXISTING.

2.4 触发函数

curandStatus_t curandGenerate(curandGenerator_t generator, unsigned int *outputPtr, size_t num)

curandGenerate() 函数用来生成伪随机或者真随机数序列。包括 XORWOW、MRG32k3a,MTGP32,and SOBOL32,每个元素都是32位unsigned int型的每位都是随机产生的。对于SOBOL64触发器来说,产生的是每一位随机产生的64位的unsigned long long型随机数。

curandStatus_t curandGenerateUniform(curandGenerator_t generator,  float *outputPtr, size_t num)

curandGenerateUniform() 函数用来产生0.0-1.0间的服从均匀分布(uniformly distributed)的浮点型随机数,其中0不包含0.0,包含1.0。

curandStatus_t curandGenerateNormal(curandGenerator_t generator, float *outputPtr, size_t n, float mean, float stddev)

curandGenerateNormal()函数通过指定的方法和输出目标来产生服从正态分布(normally distributed)的浮点型随机数。

curandStatus_t curandGenerateLogNormal(curandGenerator_t generator, float *outputPtr, size_t n, float mean, float stddev)

curandGenerateLogNormal()函数通过指定的方法和输出目标产生服从对数正态分布(log-normaly distributed)的浮点数。

curandStatus_t curandGeneratePoisson(curandGenerator_t generator, unsigned int *outputPtr, size_t n, double lambda)

curandGeneratePoision()函数通过指定的lamda产生基于泊松分布(possion distributed)的随机数。

curandStatus_tcurandGenerateUniformDouble(curandGenerator_t generator, double *outputPtr, size_t num)

curandGenerateUniformDouble()函数产生双精度的均匀分布的随机数。

curandStatus_tcurandGenerateNormalDouble(curandGenerator_t generator, double *outputPtr, size_t n, double mean, double stddev)

curandGenerateNormalDouble()触发器通过指定的方法和标准输出对象产生基于正态分布的双精度随机数。双精度的随机数只能在计算能力在1.3以上或者host端产生。

curandStatus_t curandGenerateLogNormalDouble(curandGenerator_t generator,double *outputPtr, size_t n, double mean, double stddev)

curandGernerateLogNormalDouble()通过指定的方法和输出对象产生基于正态分布的对数正态分布双精度随机数。

只有多维度的触发器才能产生真随机数。(大概是这个意思,For quasirandom generation,the number of results returned must be a multiple of the dimension of the generator)

生成函数能够被同一个触发器多次调用,来产生连续的结果块。对于伪随机数触发器,多次调用size大小的随机数,相当于一次调用产生n*size大小的随机数。对于真随机数触发器,由于内存的空间排序问题,多次短的调用,与一次长调用产生的结果并不相同;然而,产生的n维动态数组确实相同的。

双精度的随机数只能在计算能力1.3以上的设备或是host端产生。

2.5 Host API Example

/*

 * This program uses the host CURAND API to generate 100 

 * pseudorandom floats.

 */

#include <stdio.h>

#include <stdlib.h>

#include <cuda.h>

#include <curand.h>

 

#define CUDA_CALL(x) do { if((x)!=cudaSuccess) { \

    printf("Error at %s:%d\n",__FILE__,__LINE__);\

    return EXIT_FAILURE;}} while(0)

#define CURAND_CALL(x) do { if((x)!=CURAND_STATUS_SUCCESS) { \

    printf("Error at %s:%d\n",__FILE__,__LINE__);\

    return EXIT_FAILURE;}} while(0)

 

int main(int argc, char *argv[])

{

    size_t n = 100;

    size_t i;

    curandGenerator_t gen;

float *devData, *hostData;

 

    /* Allocate n floats on host */

    hostData = (float *)calloc(n, sizeof(float));

 

    /* Allocate n floats on device */

    CUDA_CALL(cudaMalloc((void **)&devData, n*sizeof(float)));

 

    /* Create pseudo-random number generator */

    CURAND_CALL(curandCreateGenerator(&gen, 

                CURAND_RNG_PSEUDO_DEFAULT));

    

    /* Set seed */

    CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 

                1234ULL));

 

    /* Generate n floats on device */

    CURAND_CALL(curandGenerateUniform(gen, devData, n));

 

    /* Copy device memory to host */

    CUDA_CALL(cudaMemcpy(hostData, devData, n * sizeof(float),

        cudaMemcpyDeviceToHost));

 

    /* Show result */

    for(i = 0; i < n; i++) {

        printf("%1.4f ", hostData[i]);

    }

    printf("\n");

 

    /* Cleanup */

    CURAND_CALL(curandDestroyGenerator(gen));

    CUDA_CALL(cudaFree(devData));

    free(hostData);    

    return EXIT_SUCCESS;

}

通常通过CURAND库产生的随机数规模越大,产生的性能越好。对于多次调用产生小规模的随机数来说,尽可能少的调用随机函数库而产生大量的随机数来使用,更有效率。比如一次产生n*size大小规模的随机数,然后分n次使用,要比n次调用,每次产生size高效。XORWOW是默认的伪随机数触发器,通过默认的排序,首次调用可能要花费一些时间来启动,后来的调用就不需要这步了。为了避免启动时间,可以使用CURAND_ORDERING_PSEUDO_SEEDED排序。

MTGP32 mersenne Twister算法与线程和块数目紧密联系。MTGP32的产生结果通常是一个通过特定的参数集产生的指定顺序的256个大小的样例,每64个块使用不同的参数集并且每256个线程产生整体中的一个样例。因此使用MTGP32产生16384个样品是最高效的。(这一块有待研究)。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏进击的程序猿

seq2seq模型之raw_rnn

本文是seq2seq模型的第二篇,主要是通过raw_rnn来实现seq2seq模型。 github地址是:https://github.com/zhuanxu...

31720
来自专栏青玉伏案

算法与数据结构(五) 普利姆与克鲁斯卡尔的最小生成树(Swift版)

上篇博客我们聊了图的物理存储结构邻接矩阵和邻接链表,然后在此基础上给出了图的深度优先搜索和广度优先搜索。本篇博客就在上一篇博客的基础上进行延伸,也是关于图的。今...

31170
来自专栏tkokof 的技术,小趣及杂念

一种稀疏矩阵的实现方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tkokof1/article/details/828...

20410
来自专栏人工智能LeadAI

Python 设计模式初探

本文章是在阅读精通Python设计模式(中文版)(https://book.douban.com/subject/26829015/),以及阅读 Mask R-...

36560
来自专栏人工智能LeadAI

TensorFlow应用实战 | TensorFlow基础知识

hw = tf.constant("Hello World! Mtianyan love TensorFlow!")

18140
来自专栏漫漫深度学习路

tensorflow自定义op:梯度

tensorflow自定义op,梯度 tensorflow 是 自动微分的,但是如果你不给它定义微分方程的话,它啥也干不了 在使用 tensorflow 的时...

79370
来自专栏图形学与OpenGL

机械版CG 实验4 裁剪

了解二维图形裁剪的原理(点的裁剪、直线的裁剪、多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法。

18710
来自专栏深度学习之tensorflow实战篇

R语言函数的含义与用法,实现过程解读

R的源起 R是S语言的一种实现。S语言是由 AT&T贝尔实验室开发的一种用来进行数据探索、统计分析、作图的解释型语言。最初S语言的实现版本主要是S-PLUS。S...

483120
来自专栏专知

【附源码】TensorFlow动态图(Eager模式)的那些神坑

导读:TensorFlow的动态图(Eager模式)为TensorFlow提供了Pythonic的API,让开发者可以像使用PyTorch一样使用TensorF...

12320
来自专栏数据结构与算法

五校联考模拟赛Day2T2矩阵(容斥原理)

设$f[i][j]$表示到了第$i$行,已经有$j$列被染黑,然后暴力转移上一行有几个黑格子

10010

扫码关注云+社区

领取腾讯云代金券