0

I want to generate random values in a parallel context with cython. I have some cpp code and I don't know how to convert it in cython (or import it from a cpp file)

My cpp code is :

#include <random>
static std::random_device rand_device;
static std::mt19937 rnd_gen(rand_device());
static std::uniform_real_distribution<> rnd_unif(0, 1);

What I suppose is to define a cpp file with these lines of code but what can I write in the cython file to import it and use it?

I saw the canonical-way-to-generate-random-numbers-in-cython coming from a similar question, but that generates alway the same number

Coming from there I need to do a setup like this:

from distutils.core import setup
from Cython.Build import cythonize
import numpy

setup(
    name="cyvmc",
    version="1.0",
    packages=["cyvmc"],
    ext_modules=cythonize(["cyvmc/*.pyx"]),
    include_dirs=[numpy.get_include()],
)

This setup will find the cpp file: am I correct ?

After that I don't know how to import cpp file for the cython usage I'm not familiar with c++. Do I need to create a rand.h if I only use this 4 lines of code

slideWXY
  • 1,121
  • 8
  • 9
  • Hint: Starting from Cython 3.x, the C++ STL's `` is already available in Cython, see [here](https://github.com/cython/cython/blob/master/Cython/Includes/libcpp/random.pxd). I'll write an detailed answer later. – joni Aug 19 '22 at 12:40
  • I appreciate your help. I tried to do some code based on rand.pyx but that's not conclusive – slideWXY Aug 19 '22 at 15:21

1 Answers1

2

As mentioned in the comments, starting with Cython 3.0.0a11, the C++ STL <random> is already wrapped and part of the cython module libcpp.random. You only need to update your Cython version, i.e. pip3 install cython==3.0.0a11.

Here's a minimal working example.pyx:

# distutils: language = c++

from libcpp.random cimport random_device, mt19937, uniform_real_distribution

def foo():
    cdef random_device dev
    cdef mt19937 rnd_gen = mt19937(dev())
    cdef uniform_real_distribution[double] rnd_unif = uniform_real_distribution[double](0, 1)
    
    # create one random_value
    return rnd_unif(rnd_gen)

You don't need to include any header files in your setup.py then. Just install it as a regular *.pyx file.

joni
  • 6,840
  • 2
  • 13
  • 20
  • Thanks joni, but when I want only rnd_gen() what is the max of this value ? – slideWXY Aug 22 '22 at 08:38
  • @slideWXY Not really sure what you're asking, but you can access the maximum value potentially generated by the random-number engine `rnd_gen` just by `rnd_gen.max()`. See the cppreference and the Cython wrapper [here](https://github.com/cython/cython/blob/master/Cython/Includes/libcpp/random.pxd). – joni Aug 22 '22 at 09:12
  • That's because my code needs to have a random_generation and a random_uniform generator – slideWXY Aug 22 '22 at 09:57
  • if you use distutils: language = c++ , put it in a separate file otherwise you will have an error – slideWXY Aug 23 '22 at 14:04