help with using multiple rng's in C

Hey all,

I am trying to use igraph as a threaded application (I have compiled it in thread-safe mode), together with random number generators. From the docs I gathered that for reproducibility I need a RNG for each thread but I must still be missing something there. I have the following Minimal-Not-Working-Example:

#include <igraph.h>
#include <igraph_random.h>

int main() {

    igraph_rng_t* firstrng;
    igraph_rng_init(firstrng, &igraph_rngtype_mt19937);

    igraph_rng_t* secondrng;
    igraph_rng_init(secondrng, &igraph_rngtype_mt19937);

    igraph_rng_destroy(firstrng);
    igraph_rng_destroy(secondrng);

    return 0;
}

which gives me a segfault. However, the following snippet does work:

#include <igraph.h>
#include <igraph_random.h>

int main() {

    igraph_rng_t* firstrng;
    igraph_rng_init(firstrng, &igraph_rngtype_mt19937);

    igraph_rng_destroy(firstrng);

    return 0;
}

I am quite lost - the solution must be simple but I’m not getting it. Igraph works perfectly fine otherwise on my machine. I’d be grateful for any help! (I am seeding my RNGs, just cut it out for this example).

Why the crash?

This is not necessary. You only ever need to include igraph.h

This is a pointer, but what is it pointing to? It is not initialized to any meaningful value, so you end up trying to access arbitrary memory locations, leading to a crash.

You need a variable to store the RNG data. This should be of type igraph_rng_t. Then you will be passing pointers to this variable to RNG functions. So:

igraph_rng_t firstrng;
igraph_rng_init(&firstrng, &igraph_rngtype_mt19937);
igraph_rng_destroy(firstrng);

Using igraph from multiple threads

Each thread will need to have its own RNG, i.e. you will need an igraph_rng_t which lives in that thread.

You can achieve this for example by declaring a thread-local igraph_rng_t variable, initializing it once from each thread, then using it from those thread. The variable must be initialized on thread startup.

What you show in the example is two RNG state variables, both in the main thread. This is not what you would normally do.

Thank you!! The pointer was a leftover artefact from when i used igraph_default_rng, oops. I knew it had to be simple :smiley:
Do you have any idea why it works when I only try to initialize one rng? That had me stumped but maybe I just got lucky there.

I think I’m doing the threading correctly, I just removed it all so it didnt distract from the problem I was having. Thank you either way!

Indeed, the lack of crash was just luck, but it was not truly working properly. It was overwriting memory it shouldn’t.

1 Like