This project is read-only.

Random Numbers and Branching

Dec 17, 2011 at 8:03 PM

I have two questions I'm hoping get some help on...

#1 What's the best way to get a random number while running on the GPU?

I'm generating a lot of different small random numbers, lets say many random Colors(but not limited too). So typically in C# I would write...

Random rnd = new Random();
Color clr = new Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255));

Now I have my color. But I'm going to generate many colors and other random positions and I do not know how many I'm going to generate before running on the GPU. So the "ray_serialize" example doesn't apply for me because its generating all the random numbers before its passed onto the GPU.

Any ideas? I looked at using Cudafy.Rand Cudafy.Maths.RAND, but I'm lost as to how to use them any samples?

#2 While on the GPU can I branch another set of sub calculations?

This is similar to the previous problem, as I'm running on the GPU iterating over N instances, and those instances have different requirements each for X instances. Lets use the simple example of testing a bunch of strings for numeric consistency. Regularly you could write...

string[] strings = new string[] { "120490""90848214987""9038WW2409823""B7A" };
bool[] validation = new bool[strings.Length];
for (int i = 0; i < strings.Length; i++)
{
    bool isValid = true;
    for (int j = 0; j < strings[i].Length; j++) {
        if (!Char.IsNumber(strings[i][j]))
        {
            isValid = false;
            break;
        }
    }
    validation[i] = isValid;
}

Keep in mind this example you do know the max length of the strings for the second loop, so on the GPU for this example you could call gpu.Launch(strings.length, stringMaxLength) but ignore that because the code I'm running on the GPU would have to do the calculation of how many times to loop for the second loop because it's actually generating sub content of the "strings" per say.

Would it be as simple as passing the "gpu" variable to the first instance and then spawn as necessary, or should it be done a different way?

Thanks for any help!

Dec 18, 2011 at 7:01 PM

Hi,

1) Take a look at the units tests: CURANDHostTests.cs.  It is also recommended to look through the CUDA documentation.  You will have it in the CUDA SDK folder.

2) Porting such code will need to workaround the limited support for Strings in CUDA device code.  Best look at StringTests.cs in Cudafy.Host.UnitTests.  Branching (or divergence) of threads in a block can give a performance hit, so as always with CUDA programming you'd need to monitor timings.  Not totally sure I follow what you're trying.  In any case you can't pass a gpu variable into device functions.

Nick

Dec 28, 2011 at 3:35 AM

Nick,

I tried using the code you suggested for random numbers, and it turns out that nvidia decided to change the filename of the curand_____.dll on my computer it is...

    internal class CURANDDriver64 : ICURANDDriver
    {
        //public const string DLL_NAME = "curand64_40_17";
        public const string DLL_NAME = "curand64_41_21";

and

    internal class CURANDDriver32 : ICURANDDriver
    {
        //public const string DLL_NAME = "curand32_40_17";
        public const string DLL_NAME = "curand32_41_21";

That appears to be working for me so far... trying to work through some other issues right now before I fully check.

-xer

 


Dec 28, 2011 at 10:23 AM

Hi there,

We do not support CUDA 4.1 until it is officially released.  Within a week or so of 4.1 becoming official we'll update, test and release.  In the mean time you can of course do what you have done or if you want to work with the Cudafy.NET.dll binary then you can rename the relevant CUDA dlls (and also rename the old ones). This could be a recipe for general bad news if you are not careful.

Nick