C# Wrapper-Methods for CuRand functions defined in curand.h
示例#1
0
        /// <summary>
        /// Get scramble constants that can be used for quasirandom number generation.
        /// <para/>
        /// The array contains constants for many dimensions. Each dimension
        /// has a single ulong constant.
        /// </summary>
        /// <returns></returns>
        public static ulong[] GetScrambleConstants64()
        {
            IntPtr       ptr;
            CurandStatus status = CudaRandNativeMethods.curandGetScrambleConstants64(out ptr);

            Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGetScrambleConstants64", status));
            if (status != CurandStatus.Success)
            {
                throw new CudaRandException(status);
            }

            //Marshall.Copy cannot directly copy to an ulong[] array.
            //So first copy to long[] and then to ulong[]...
            long[]  consts_long  = new long[MaxDimensions];
            ulong[] consts_ulong = new ulong[MaxDimensions];

            //Copy unmanaged array (ptr) to managed array of long[]:
            Marshal.Copy(ptr, consts_long, 0, MaxDimensions);

            //Pin ulong[] array to get IntPtr and copy data again.
            GCHandle handle = GCHandle.Alloc(consts_ulong, GCHandleType.Pinned);

            Marshal.Copy(consts_long, 0, handle.AddrOfPinnedObject(), MaxDimensions);
            handle.Free();

            return(consts_ulong);
        }
示例#2
0
 /// <summary>
 /// Use generator to generate num double results into the device memory at
 /// outputPtr.  The device memory must have been previously allocated and be
 /// large enough to hold all the results.  Launches are done with the stream
 /// set using curandSetStream(), or the null stream if no stream has been set.
 /// <para/>
 /// Results are 64-bit floating point values with log-normal distribution based on
 /// an associated normal distribution with mean mean and standard deviation stddev.
 /// <para/>
 /// Normally distributed results are generated from pseudorandom generators
 /// with a Box-Muller transform, and so require num to be even.
 /// Quasirandom generators use an inverse cumulative distribution
 /// function to preserve dimensionality.
 /// The normally distributed results are transformed into log-normal distribution.
 /// <para/>
 /// There may be slight numerical differences between results generated
 /// on the GPU with generators created with ::curandCreateGenerator()
 /// and results calculated on the CPU with generators created with
 /// ::curandCreateGeneratorHost().  These differences arise because of
 /// differences in results for transcendental functions.  In addition,
 /// future versions of CURAND may use newer versions of the CUDA math
 /// library, so different versions of CURAND may give slightly different
 /// numerical values.
 /// </summary>
 /// <param name="output">CudaDeviceVariable</param>
 /// <param name="mean"></param>
 /// <param name="stddev"></param>
 public void GenerateLogNormal(CudaDeviceVariable <double> output, double mean, double stddev)
 {
     _status = CudaRandNativeMethods.curandGenerateLogNormalDouble(_generator, output.DevicePointer, output.Size, mean, stddev);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGenerateLogNormalDouble", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#3
0
 /// <summary>
 /// Use generator to generate num double results into the device memory at
 /// outputPtr.  The device memory must have been previously allocated and be
 /// large enough to hold all the results.  Launches are done with the stream
 /// set using curandSetStream(), or the null stream if no stream has been set.
 /// <para/>
 /// Results are 64-bit floating point values with log-normal distribution based on
 /// an associated normal distribution with mean mean and standard deviation stddev.
 /// <para/>
 /// Normally distributed results are generated from pseudorandom generators
 /// with a Box-Muller transform, and so require num to be even.
 /// Quasirandom generators use an inverse cumulative distribution
 /// function to preserve dimensionality.
 /// The normally distributed results are transformed into log-normal distribution.
 /// <para/>
 /// There may be slight numerical differences between results generated
 /// on the GPU with generators created with ::curandCreateGenerator()
 /// and results calculated on the CPU with generators created with
 /// ::curandCreateGeneratorHost().  These differences arise because of
 /// differences in results for transcendental functions.  In addition,
 /// future versions of CURAND may use newer versions of the CUDA math
 /// library, so different versions of CURAND may give slightly different
 /// numerical values.
 /// </summary>
 /// <param name="output">CudaDeviceVariable</param>
 /// <param name="mean"></param>
 /// <param name="stddev"></param>
 public void GenerateLogNormal(double[] output, double mean, double stddev)
 {
     _status = CudaRandNativeMethods.curandGenerateLogNormalDouble(_generator, output, output.LongLength, mean, stddev);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGenerateLogNormalDouble", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#4
0
 /// <summary>
 /// Use generator to generate num float results into the device memory at
 /// outputPtr. The device memory must have been previously allocated and be
 /// large enough to hold all the results. Launches are done with the stream
 /// set using SetStream(), or the null stream if no stream has been set.
 /// <para/>
 /// Results are 32-bit floating point values between 0.0f and 1.0f,
 /// excluding 0.0f and including 1.0f.
 /// </summary>
 /// <param name="output">CudaDeviceVariable</param>
 public void GenerateUniform(CudaDeviceVariable <float> output)
 {
     _status = CudaRandNativeMethods.curandGenerateUniform(_generator, output.DevicePointer, output.Size);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGenerateUniform", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#5
0
 /// <summary>
 /// Set the number of dimensions to be generated by the quasirandom number generator.
 /// <para/>
 /// Legal values for dimensions are 1 to 20000.
 /// </summary>
 /// <param name="dimensions">Legal values for dimensions are 1 to 20000.</param>
 public void SetQuasiRandomGeneratorDimensions(uint dimensions)
 {
     _status = CudaRandNativeMethods.curandSetQuasiRandomGeneratorDimensions(_generator, dimensions);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandSetQuasiRandomGeneratorDimensions", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#6
0
 /// <summary>
 /// Use generator to generate num float results into the device memory at
 /// outputPtr. The device memory must have been previously allocated and be
 /// large enough to hold all the results. Launches are done with the stream
 /// set using SetStream(), or the null stream if no stream has been set.
 /// <para/>
 /// Results are 32-bit floating point values between 0.0f and 1.0f,
 /// excluding 0.0f and including 1.0f.
 /// </summary>
 /// <param name="output">DevicePtr of type float*</param>
 /// <param name="size">Number of random elements to create</param>
 public void GenerateUniform32(CUdeviceptr output, SizeT size)
 {
     _status = CudaRandNativeMethods.curandGenerateUniform(_generator, output, size);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGenerateUniform", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#7
0
 /// <summary>
 /// Set the absolute offset of the pseudo or quasirandom number generator.
 /// <para/>
 /// All values of offset are valid.  The offset position is absolute, not
 /// relative to the current position in the sequence.
 /// </summary>
 /// <param name="offset">All values of offset are valid.</param>
 public void SetOffset(ulong offset)
 {
     _status = CudaRandNativeMethods.curandSetGeneratorOffset(_generator, offset);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandSetGeneratorOffset", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#8
0
 /// <summary>
 /// Set the seed value of the pseudorandom number generator.<para/>
 /// All values of seed are valid.  Different seeds will produce different sequences.
 /// Different seeds will often not be statistically correlated with each other,
 /// but some pairs of seed values may generate sequences which are statistically correlated.
 /// </summary>
 /// <param name="seed">All values of seed are valid.</param>
 public void SetPseudoRandomGeneratorSeed(ulong seed)
 {
     _status = CudaRandNativeMethods.curandSetPseudoRandomGeneratorSeed(_generator, seed);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandSetPseudoRandomGeneratorSeed", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#9
0
 /// <summary>
 /// Set the current stream for CURAND kernel launches.  All library functions
 /// will use this stream until set again.
 /// </summary>
 /// <param name="stream"></param>
 public void SetStream(CUstream stream)
 {
     _status = CudaRandNativeMethods.curandSetStream(_generator, stream);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandSetStream", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#10
0
 /// <summary>
 /// Generate the starting state of the generator.  This function is
 /// automatically called by generation functions such as
 /// Generate(CudaDeviceVariable) and GenerateUniform(CudaDeviceVariable).
 /// It can be called manually for performance testing reasons to separate
 /// timings for starting state generation and random number generation.
 /// </summary>
 public void GenerateSeeds()
 {
     _status = CudaRandNativeMethods.curandGenerateSeeds(_generator);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGenerateSeeds", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#11
0
 /// <summary>
 /// Use generator to generate num double results into the device memory at
 /// outputPtr.  The device memory must have been previously allocated and be
 /// large enough to hold all the results.  Launches are done with the stream
 /// set using curandSetStream(), or the null stream if no stream has been set.
 /// <para/>
 /// Results are 64-bit floating point values with log-normal distribution based on
 /// an associated normal distribution with mean mean and standard deviation stddev.
 /// <para/>
 /// Normally distributed results are generated from pseudorandom generators
 /// with a Box-Muller transform, and so require num to be even.
 /// Quasirandom generators use an inverse cumulative distribution
 /// function to preserve dimensionality.
 /// The normally distributed results are transformed into log-normal distribution.
 /// <para/>
 /// There may be slight numerical differences between results generated
 /// on the GPU with generators created with ::curandCreateGenerator()
 /// and results calculated on the CPU with generators created with
 /// ::curandCreateGeneratorHost().  These differences arise because of
 /// differences in results for transcendental functions.  In addition,
 /// future versions of CURAND may use newer versions of the CUDA math
 /// library, so different versions of CURAND may give slightly different
 /// numerical values.
 /// </summary>
 /// <param name="output">DevicePtr of type double*</param>
 /// <param name="size">Number of random elements to create</param>
 /// <param name="mean"></param>
 /// <param name="stddev"></param>
 public void GenerateLogNormal64(CUdeviceptr output, SizeT size, float mean, float stddev)
 {
     _status = CudaRandNativeMethods.curandGenerateLogNormalDouble(_generator, output, size, mean, stddev);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGenerateLogNormalDouble", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#12
0
 /// <summary>
 /// Use generator to generate num float results into the device memory at
 /// outputPtr. The device memory must have been previously allocated and be
 /// large enough to hold all the results. Launches are done with the stream
 /// set using SetStream(), or the null stream if no stream has been set.
 /// <para/>
 /// Results are 32-bit floating point values between 0.0f and 1.0f,
 /// excluding 0.0f and including 1.0f.
 /// </summary>
 /// <param name="output">CudaDeviceVariable</param>
 public void GenerateUniform(float[] output)
 {
     _status = CudaRandNativeMethods.curandGenerateUniform(_generator, output, output.LongLength);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGenerateUniform", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#13
0
 /// <summary>
 /// Generate Poisson-distributed unsigned ints.<para/>
 /// Use <c>generator</c> to generate <c>num</c> unsigned int results into the device memory at
 /// <c>outputPtr</c>.  The device memory must have been previously allocated and be
 /// large enough to hold all the results.  Launches are done with the stream
 /// set using <c>curandSetStream()</c>, or the null stream if no stream has been set.
 /// Results are 32-bit unsigned int point values with poisson distribution based on
 /// an associated poisson distribution with lambda <c>lambda</c>.
 /// </summary>
 /// <param name="generator">Generator to use</param>
 /// <param name="output">Pointer to host memory to store CPU-generated results</param>
 public void Generate(CudaRandHost generator, uint[] output)
 {
     _status = CudaRandNativeMethods.curandGeneratePoisson(generator.Generator, output, output.Length, _lambda);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGeneratePoisson", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#14
0
 /// <summary>
 /// Generate Poisson-distributed unsigned ints.<para/>
 /// Use <c>generator</c> to generate <c>num</c> unsigned int results into the device memory at
 /// <c>outputPtr</c>.  The device memory must have been previously allocated and be
 /// large enough to hold all the results.  Launches are done with the stream
 /// set using <c>curandSetStream()</c>, or the null stream if no stream has been set.
 /// Results are 32-bit unsigned int point values with poisson distribution based on
 /// an associated poisson distribution with lambda <c>lambda</c>.
 /// </summary>
 /// <param name="generator">Generator to use</param>
 /// <param name="output">Pointer to device memory to store CUDA-generated results</param>
 public void Generate(CudaRandDevice generator, CudaDeviceVariable <uint> output)
 {
     _status = CudaRandNativeMethods.curandGeneratePoisson(generator.Generator, output.DevicePointer, output.Size, _lambda);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGeneratePoisson", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#15
0
 /// <summary>
 /// Creates a new random number generator of type Type
 /// </summary>
 /// <param name="Type">Generator type</param>
 public CudaRandDevice(GeneratorType Type)
 {
     _generator = new CurandGenerator();
     _status    = CudaRandNativeMethods.curandCreateGenerator(ref _generator, Type);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandCreateGenerator", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#16
0
 /// <summary>
 /// Creates a new poisson distribution.<para/>
 /// Construct histogram array for poisson distribution.<para/>
 /// Construct histogram array for poisson distribution with lambda <c>lambda</c>.
 /// For lambda greater than 2000 optimization with normal distribution is used.
 /// </summary>
 /// <param name="lambda">lambda for poisson distribution</param>
 public PoissonDistribution(double lambda)
 {
     _distributions = new DiscreteDistribution();
     _lambda        = lambda;
     _status        = CudaRandNativeMethods.curandCreatePoissonDistribution(lambda, ref _distributions);
     Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandCreatePoissonDistribution", _status));
     if (_status != CurandStatus.Success)
     {
         throw new CudaRandException(_status);
     }
 }
示例#17
0
 /// <summary>
 /// For IDisposable
 /// </summary>
 /// <param name="fDisposing"></param>
 protected virtual void Dispose(bool fDisposing)
 {
     if (fDisposing && !disposed)
     {
         _status = CudaRandNativeMethods.curandDestroyDistribution(_distributions);
         Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandDestroyDistribution", _status));
         disposed = true;
     }
     if (!fDisposing && !disposed)
     {
         Debug.WriteLine(String.Format("CudaRand not-disposed warning: {0}", this.GetType()));
     }
 }
示例#18
0
        /// <summary>
        /// Returns the version number of the dynamically linked CURAND library.
        /// </summary>
        public static Version GetVersion()
        {
            int          version = 0;
            CurandStatus _status = CudaRandNativeMethods.curandGetVersion(ref version);

            Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGetVersion", _status));
            if (_status != CurandStatus.Success)
            {
                throw new CudaRandException(_status);
            }

            return(new Version((int)version / 1000, (int)version % 100));
        }
示例#19
0
        /// <summary>
        /// Get an array of direction vectors that can be used for quasirandom number generation.
        /// <para/>
        /// The array contains vectors for many dimensions. Each dimension
        /// has 64 vectors. Each individual vector is an unsigned long long.
        /// <para/>
        /// Legal values for set are:
        /// - <see cref="DirectionVectorSet.JoeKuo6_64"/> (20,000 dimensions)
        /// - <see cref="DirectionVectorSet.ScrambledJoeKuo6_64"/> (20,000 dimensions)
        /// </summary>
        /// <param name="set"></param>
        /// <returns></returns>
        public static DirectionVectors64[] GetDirectionVectors64(DirectionVectorSet set)
        {
            IntPtr       ptr;
            CurandStatus status = CudaRandNativeMethods.curandGetDirectionVectors64(out ptr, set);

            Debug.WriteLine(String.Format("{0:G}, {1}: {2}", DateTime.Now, "curandGetDirectionVectors64", status));
            if (status != CurandStatus.Success)
            {
                throw new CudaRandException(status);
            }

            DirectionVectors64[] vec = new DirectionVectors64[MaxDimensions];

            for (int i = 0; i < MaxDimensions; i++)
            {
                vec[i] = (DirectionVectors64)Marshal.PtrToStructure(new IntPtr(ptr.ToInt64() + i * 64 * Marshal.SizeOf(typeof(ulong))), typeof(DirectionVectors64));
            }

            return(vec);
        }