Skip to content

removing rnd reuse logic (disabled by default) #1642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 32 additions & 40 deletions PySDM/dynamics/collisions/collision.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@
from PySDM.dynamics.collisions.breakup_efficiencies import ConstEb
from PySDM.dynamics.collisions.breakup_fragmentations import AlwaysN
from PySDM.dynamics.collisions.coalescence_efficiencies import ConstEc
from PySDM.dynamics.impl.random_generator_optimizer import RandomGeneratorOptimizer
from PySDM.dynamics.impl.random_generator_optimizer_nopair import (
RandomGeneratorOptimizerNoPair,
)
from PySDM.physics import si
from PySDM.dynamics.impl import register_dynamic

Expand All @@ -47,7 +43,6 @@ def __init__(
breakup_efficiency,
fragmentation_function,
croupier=None,
optimized_random=False,
substeps: int = DEFAULTS.substeps,
adaptive: bool = DEFAULTS.adaptive,
dt_coal_range=DEFAULTS.dt_coal_range,
Expand All @@ -68,14 +63,15 @@ def __init__(
self.compute_breakup_efficiency = breakup_efficiency
self.compute_number_of_fragments = fragmentation_function

self.rnd_opt_frag = None
self.rnd_opt_coll = None
self.rnd_opt_proc = None
self.optimised_random = None
self.rnd = None
self.rand = None
self.rand_frag = None
self.rand_coll = None
self.rand_proc = None
self.rand_pairs = None

assert dt_coal_range[0] > 0
self.croupier = croupier
self.optimized_random = optimized_random
self.__substeps = substeps
self.adaptive = adaptive
self.stats_n_substep = None
Expand All @@ -100,24 +96,26 @@ def __init__(

def register(self, builder):
self.particulator = builder.particulator
rnd_args = {
"optimized_random": self.optimized_random,
"dt_min": self.dt_coal_range[0],
"seed": builder.formulae.seed,
}
self.rnd_opt_coll = RandomGeneratorOptimizer(**rnd_args)

empty_args_dropwise = {"shape": self.particulator.n_sd, "dtype": float}
empty_args_pairwise = {"shape": self.particulator.n_sd // 2, "dtype": float}
empty_args_cellwise = {"shape": self.particulator.mesh.n_cell, "dtype": float}

self.rnd = self.particulator.Random(
self.particulator.n_sd, builder.formulae.seed
)
self.rand = self.particulator.Storage.empty(**empty_args_pairwise)
self.rand_pairs = self.particulator.Storage.empty(**empty_args_dropwise)
if self.enable_breakup:
self.rnd_opt_proc = RandomGeneratorOptimizerNoPair(**rnd_args)
self.rnd_opt_frag = RandomGeneratorOptimizerNoPair(**rnd_args)
self.rand_proc = self.particulator.Storage.empty(**empty_args_pairwise)
self.rand_frag = self.particulator.Storage.empty(**empty_args_pairwise)

if self.particulator.n_sd < 2:
raise ValueError("No one to collide with!")
if self.dt_coal_range[1] > self.particulator.dt:
self.dt_coal_range = (self.dt_coal_range[0], self.particulator.dt)
assert self.dt_coal_range[0] <= self.dt_coal_range[1]

empty_args_pairwise = {"shape": self.particulator.n_sd // 2, "dtype": float}
empty_args_cellwise = {"shape": self.particulator.mesh.n_cell, "dtype": float}
self.kernel_temp = self.particulator.PairwiseStorage.empty(
**empty_args_pairwise
)
Expand All @@ -135,7 +133,6 @@ def register(self, builder):
self.stats_dt_min = self.particulator.Storage.empty(**empty_args_cellwise)
self.stats_dt_min[:] = np.nan

self.rnd_opt_coll.register(builder)
self.collision_kernel.register(builder)

if self.croupier is None:
Expand All @@ -161,8 +158,6 @@ def register(self, builder):
self.Eb_temp = self.particulator.PairwiseStorage.empty(
**empty_args_pairwise
)
self.rnd_opt_proc.register(builder)
self.rnd_opt_frag.register(builder)
self.compute_coalescence_efficiency.register(builder)
self.compute_breakup_efficiency.register(builder)
self.compute_number_of_fragments.register(builder)
Expand All @@ -188,40 +183,41 @@ def __call__(self):

self.particulator.attributes.reset_working_length()
self.particulator.attributes.reset_cell_idx()
self.rnd_opt_coll.reset()
if self.enable_breakup:
self.rnd_opt_proc.reset()
self.rnd_opt_frag.reset()

def step(self):
pairs_rand, rand = self.rnd_opt_coll.get_random_arrays()
self.rand_pairs.urand(self.rnd)
self.rand.urand(self.rnd)

self.toss_candidate_pairs_and_sort_within_pair_by_multiplicity(
self.is_first_in_pair, pairs_rand
self.is_first_in_pair, self.rand_pairs
)

prob = self.gamma
self.compute_probabilities_of_collision(self.is_first_in_pair, out=prob)

if self.enable_breakup:
proc_rand = self.rnd_opt_proc.get_random_arrays()
rand_frag = self.rnd_opt_frag.get_random_arrays()
self.rand_proc.urand(self.rnd)
self.rand_frag.urand(self.rnd)
self.compute_coalescence_efficiency(self.Ec_temp, self.is_first_in_pair)
self.compute_breakup_efficiency(self.Eb_temp, self.is_first_in_pair)
self.compute_number_of_fragments(
self.n_fragment, self.fragment_mass, rand_frag, self.is_first_in_pair
self.n_fragment,
self.fragment_mass,
self.rand_frag,
self.is_first_in_pair,
)
else:
proc_rand = None

self.compute_gamma(
prob=prob, rand=rand, is_first_in_pair=self.is_first_in_pair, out=self.gamma
prob=prob,
rand=self.rand,
is_first_in_pair=self.is_first_in_pair,
out=self.gamma,
)

self.particulator.collision_coalescence_breakup(
enable_breakup=self.enable_breakup,
gamma=self.gamma,
rand=proc_rand,
rand=self.rand_proc,
Ec=self.Ec_temp,
Eb=self.Eb_temp,
fragment_mass=self.fragment_mass,
Expand Down Expand Up @@ -298,7 +294,6 @@ def __init__(
collision_kernel,
coalescence_efficiency=ConstEc(Ec=1),
croupier=None,
optimized_random=False,
substeps: int = DEFAULTS.substeps,
adaptive: bool = DEFAULTS.adaptive,
dt_coal_range=DEFAULTS.dt_coal_range,
Expand All @@ -311,7 +306,6 @@ def __init__(
breakup_efficiency=breakup_efficiency,
fragmentation_function=fragmentation_function,
croupier=croupier,
optimized_random=optimized_random,
substeps=substeps,
adaptive=adaptive,
dt_coal_range=dt_coal_range,
Expand All @@ -327,7 +321,6 @@ def __init__(
collision_kernel,
fragmentation_function,
croupier=None,
optimized_random=False,
substeps: int = DEFAULTS.substeps,
adaptive: bool = DEFAULTS.adaptive,
dt_coal_range=DEFAULTS.dt_coal_range,
Expand All @@ -341,7 +334,6 @@ def __init__(
breakup_efficiency=breakup_efficiency,
fragmentation_function=fragmentation_function,
croupier=croupier,
optimized_random=optimized_random,
substeps=substeps,
adaptive=adaptive,
dt_coal_range=dt_coal_range,
Expand Down
48 changes: 0 additions & 48 deletions PySDM/dynamics/impl/random_generator_optimizer.py

This file was deleted.

40 changes: 0 additions & 40 deletions PySDM/dynamics/impl/random_generator_optimizer_nopair.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def __init__(self, formulae: Formulae):

self.coalescence_adaptive = True
self.coalescence_dt_coal_range = collisions.collision.DEFAULTS.dt_coal_range
self.coalescence_optimized_random = True
self.coalescence_substeps = 1
self.kernel = Geometric(collection_efficiency=1)
self.coalescence_efficiency = ConstEc(Ec=1.0)
Expand Down
1 change: 0 additions & 1 deletion examples/PySDM_examples/utils/kinematic_2d/gui_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ def __init__(self, settings):
self.kernel = settings.kernel
self.spectrum_per_mass_of_dry_air = settings.spectrum_per_mass_of_dry_air
self.coalescence_dt_coal_range = settings.coalescence_dt_coal_range
self.coalescence_optimized_random = settings.coalescence_optimized_random
self.coalescence_substeps = settings.coalescence_substeps
self.freezing_inp_frac = settings.freezing_inp_frac
self.coalescence_efficiency = settings.coalescence_efficiency
Expand Down
2 changes: 0 additions & 2 deletions examples/PySDM_examples/utils/kinematic_2d/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ def reinit(self, products=None):
adaptive=self.settings.coalescence_adaptive,
dt_coal_range=self.settings.coalescence_dt_coal_range,
substeps=self.settings.coalescence_substeps,
optimized_random=self.settings.coalescence_optimized_random,
)
)
elif (
Expand All @@ -130,7 +129,6 @@ def reinit(self, products=None):
adaptive=self.settings.coalescence_adaptive,
dt_coal_range=self.settings.coalescence_dt_coal_range,
substeps=self.settings.coalescence_substeps,
optimized_random=self.settings.coalescence_optimized_random,
)
)
assert not (
Expand Down
3 changes: 1 addition & 2 deletions tests/unit_tests/dynamics/collisions/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,12 @@ def insert_zeros(array):


def get_dummy_particulator_and_coalescence(
backend, n_length, optimized_random=False, environment=None, substeps=1
backend, n_length, environment=None, substeps=1
):
particulator = DummyParticulator(backend, n_sd=n_length)
particulator.environment = environment or Box(dv=1, dt=DEFAULTS.dt_coal_range[1])
coalescence = Coalescence(
collision_kernel=StubKernel(particulator.backend),
optimized_random=optimized_random,
substeps=substeps,
adaptive=False,
)
Expand Down
54 changes: 0 additions & 54 deletions tests/unit_tests/dynamics/collisions/test_sdm_single_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import numpy as np
import pytest

from PySDM.backends import ThrustRTC
from PySDM.backends.impl_common.index import make_Index
from PySDM.backends.impl_common.indexed_storage import make_IndexedStorage
from PySDM.backends.impl_common.pair_indicator import make_PairIndicator
Expand Down Expand Up @@ -256,56 +255,3 @@ def expected(p, r):

# Assert
assert expected(p, r) == prob_arr.to_ndarray()[0]

@staticmethod
@pytest.mark.parametrize(
"optimized_random",
(pytest.param(True, id="optimized"), pytest.param(False, id="non-optimized")),
)
@pytest.mark.parametrize(
"adaptive",
(pytest.param(True, id="adaptive_dt"), pytest.param(False, id="const_dt")),
)
def test_rnd_reuse(backend_class, optimized_random, adaptive):
if backend_class is ThrustRTC:
pytest.skip("# TODO #330")

# Arrange
n_sd = 256
n = np.random.randint(1, 64, size=n_sd)
v = np.random.uniform(size=n_sd)
n_substeps = 5

particles, sut = get_dummy_particulator_and_coalescence(
backend_class,
n_sd,
optimized_random=optimized_random,
substeps=n_substeps,
)
attributes = {"multiplicity": n, "volume": v}
particles.build(attributes)

class CountingRandom(
backend_class.Random
): # pylint: disable=too-few-public-methods
calls = 0

def __call__(self, storage):
CountingRandom.calls += 1
super().__call__(storage)

sut.rnd_opt_coll.rnd = CountingRandom(n_sd, seed=44)
sut.stats_n_substep[:] = n_substeps
sut.adaptive = adaptive

# Act
sut()

# Assert
if sut.rnd_opt_coll.optimized_random:
assert CountingRandom.calls == 2
else:
if adaptive:
assert 2 <= CountingRandom.calls <= 2 * n_substeps
else:
assert CountingRandom.calls == 2 * n_substeps
Loading