Porting code that uses random numbers

dobbelstenen

When we port software to the GPU or FPGA, testability is very important. A part of making the code testable, is getting its functionality fully under control. And you guessed already that run-time generated random numbers takes good attention.

In a selection of past projects random numbers were generated on every run. Statistically the simulations were more correct, but it is impossible to make 100% sure the ported code is functionally correct. This is because there are two variations introduced: one due to the numbers being different and one due to differences in code and hardware.

Even if the combined error-variations are within the given limits, the two code-bases can have unnoticed, different functionality. On top of that, it is hard to have further optimisations under control, as that can lower the precision.

When porting, the stochastic correctness of the simulations is less important. Predictable outcomes should be leading during the port.

Below are some tips we gave to these customers, and I hope they’re useful for you. If you have code to be ported, these preparations make the process quicker and more correct.

If you want to know more about the correctness of RNGs themselves, we discussed earlier this year that generating good random numbers on GPUs is not obvious.

Getting in control of the RNG

What we need is a range of random numbers, which is the same every time. This sounds very bad for production-level code, but it’s perfect for porting.

Random numbers from a file

This is the easiest way, as test-cases can be created and retested with 100% certainty. What you need to do is to isolate the function that makes the random numbers, then write them to a file with a unique name. Second create a function that reads the file, and is called in case a specific parameter with a filename is given.

In most cases this simple method suffices, and test-cases can then be fully automated.

Controlled Quasirandom Number Generation

When loading and saving files are not an option, you can also make use of fully-predictable Quasirandom Number Generators. This is especially handy when each thread needs to process one or a few random numbers.

In most cases it needs to be fully checked via the file-method afterwards, but it can help in more convenient testing during development.

A tip of the iceberg?

The above information is a bit of experience which helped us porting code faster, which seems so obvious when you read it.

When you let us do a full code review and analysis, getting full control is an important objective – RNGs is one of the problems we tackle, but one we more often encounter. Would you like to hear more about how we can help you get in control of very performant code, feel free to contact us via email or phone.