Ihre ursprüngliche Annahme, dass Sie reikna.cbrng.CBRNG
verwenden müssen, ist richtig. Es scheint, es bietet eine Vielzahl von sources of pseudo randomness - basierend auf Counter-basierte Zufallszahlengeneratoren - und distributions, die verwirrend sein können. Es bietet auch shortcuts zum Erstellen von Zufallszahlengeneratoren mit gegebener Verteilung.
from reikna.core import Type
from reikna.cbrng import CBRNG
from reikna.cluda import any_api
import numpy as np
# Get any supported API for this system, or an exception
_api = any_api()
# The global CLUDA Thread, wrapping context, shared by all
# reikna_norm_rng's
_thr = _api.Thread.create()
def reikna_norm_rng(seed, rows, cols, mean, std,
dtype=np.float32,
generators_dim=1):
"""
A do-all generator function for creating a new Computation
returning a stream of pseudorandom number arrays.
"""
# The Type of the output array
randoms_arr = Type(dtype, (rows, cols))
# Shortcut for creating a Sampler for normally distributed
# random numbers
rng = CBRNG.normal_bm(randoms_arr=randoms_arr,
generators_dim=generators_dim,
sampler_kwds=dict(mean=mean, std=std),
# Reikna expects a positive integer. This is a
# quick and *dirty* solution.
seed=abs(hash(seed)))
compiled_comp = rng.compile(_thr)
# RNG "state"
counters = _thr.to_device(rng.create_counters())
# Output array
randoms = _thr.empty_like(compiled_comp.parameter.randoms)
while True:
compiled_comp(counters, randoms)
yield randoms.get()
Um es in Aktion Add zu sehen:
if __name__ == '__main__':
seed1 = '123'
seed2 = 'asd'
rows, cols = 100, 3
mu, sd = 0, 1
# This will create a new RNG, take 1 result and throw the RNG away
r1 = next(reikna_norm_rng(seed1, rows, cols, mu, sd))
r2 = next(reikna_norm_rng(seed2, rows, cols, mu, sd))
r3 = next(reikna_norm_rng(seed1, rows, cols, mu, sd))
r4 = next(reikna_norm_rng(seed2, rows, cols, mu, sd))
err1 = r1 - r3
err2 = r2 - r4
print("all(err1 == 0):", np.all(err1 == 0))
print("all(err2 == 0):", np.all(err2 == 0))
Ich möchte auch sicherstellen, dass randoms die beiden unterschiedlichen Samen keine Korrelation haben generiert.
Dies hängt von der Qualität der Implementierung ab. Hier ist, wie zwei Sätze von Zahlen mit Samen und geplottet:
rng1 = reikna_norm_rng(0, 100, 10000, 0, 1)
rng2 = reikna_norm_rng(1, 100, 10000, 0, 1)
A = next(rng1)
B = next(rng2)
A_r = A.ravel()
B_r = B.ravel()
for i in range(0, A_r.size, 1000):
plot(A_r[i:i+1000], B_r[i:i+1000], 'b.')
Haftungsausschluss
Dies ist mein erster Lauf in mit reikna. Der obige Code kann Ressourcen nicht rechtzeitig freigeben und/oder wie ein Sieb auslaufen. Es verwendet eine globale Thread
, die möglicherweise nicht das ist, was Sie in einer größeren Anwendung möchten.
PS
np.random.seed(seed)
np.random.normal(0, 1, (100, 3))
produziert auch Arrays von normalverteilten Zufallszahlen mit Form (100, 3), obwohl es nicht die GPU zu verwenden ist.
Ich weiß nicht viel über Reikna, aber jedes Mal, wenn Sie eine zufällige Sache generieren, wird es nicht anders sein? Warum brauchen Sie err1 und err3 als 0? –
@Sagar https://en.wikipedia.org/wiki/Pseudorandom_number_generator, Seeding Kontrollen gegeben "zufällige" Zahlen, die vollständig deterministisch sind. Wiederholbare "zufällige" Zahlen zu haben, kann beim Testen usw. sehr nützlich sein. –
Danke @Ilja wird durchgehen. –