Python 3.x numpy实现自定义RNG

Python 3.x numpy实现自定义RNG,python-3.x,numpy,random,Python 3.x,Numpy,Random,出于一致性原因,我正试图让numpy使用我自己的RNG in实现。根据我从numpy文档中找到的一些文档,我的理解是,我需要提供一个自定义的BitGenerator类,该类实现random\u raw方法,然后使用np.random.Generator初始化,所以我尝试了以下方法: import numpy as np class TestBitGenerator(np.random.BitGenerator): def __init__(self): super().__init

出于一致性原因,我正试图让numpy使用我自己的RNG in实现。根据我从numpy文档中找到的一些文档,我的理解是,我需要提供一个自定义的BitGenerator类,该类实现
random\u raw
方法,然后使用
np.random.Generator
初始化,所以我尝试了以下方法:

import numpy as np

class TestBitGenerator(np.random.BitGenerator):
  def __init__(self):
    super().__init__(0)
    self.counter = 0
  def random_raw(self, size=None):
    self.counter += 1
    if size is None:
      return self.counter
    return np.full(n, self.counter)  

mc_adapter = TestBitGenerator() 
npgen = np.random.Generator(mc_adapter)

print(npgen.random())
这将导致一个segfault:

$ python bitgen.py 
Segmentation fault (core dumped)
我假设我在这里遗漏了什么(来自TestBitGenerator?),有人能给我指出正确的方向吗

我尝试不将np.random.BitGenerator子类化,但得到了不同的错误:
对象没有属性“capsule”

我使用numpy 1.19.2和python 3.8.2进行了一些挖掘,生成器的构造函数如下所示:

    def __init__(self, bit_generator):
        self._bit_generator = bit_generator

        capsule = bit_generator.capsule
        cdef const char *name = "BitGenerator"
        if not PyCapsule_IsValid(capsule, name):
            raise ValueError("Invalid bit generator. The bit generator must "
                             "be instantiated.")
        self._bitgen = (<bitgen_t *> PyCapsule_GetPointer(capsule, name))[0]
        self.lock = bit_generator.lock
因此,据我所知,
BitGenerator
的任何实现似乎都必须在cython中完成,任何试图在纯python(可能还有pybind11)中实现的尝试都不会奏效(?)


由于我不熟悉cython以及它是否/如何与pybind11共存,现在我只想确保我的每一个(并行)进程显式地调用np.random.Generator,并确定使用numpy RNG种子,这样它就独立于我自己的RNG蒸汽。

实际上,如果使用库
RandomGen
包装它,您就可以用纯python完成它(这是当前
np.random.Generator
的孵化器)。因此,有一个
UserBitGenerator
只允许您使用python:


遗憾的是,这没有出现在
numpy
(或者如果是,我还没有找到它…。

如果是出于一致性的原因,为什么不将种子设置为一致的值?这似乎与解释我的确切需求无关,因为它很复杂。我有一些C++代码(包括我的RNG),通过pybd11访问python,我在MPI上运行,我需要控制每个进程是如何被播种的,每个进程应该(理想地)使用一个从C++和Python层访问的单个随机流。如果你在代码中找到了限制,Nopy.Road。您可能希望在以下位置提交问题:。此外,NumPy文档中还提供了一个演示多线程随机生成工作原理的示例,以防您没有看到:
struct bitgen:
    void *state
    npy_uint64 (*next_uint64)(void *st) nogil
    uint32_t (*next_uint32)(void *st) nogil
    double (*next_double)(void *st) nogil
    npy_uint64 (*next_raw)(void *st) nogil

ctypedef bitgen bitgen_t