Skip to content
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

refactor: move random number generator into collisions #65

Merged
merged 1 commit into from
May 8, 2024
Merged
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
18 changes: 7 additions & 11 deletions libs/runcleo/runcleo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Author: Clara Bayley (CB)
* Additional Contributors: Tobias Kölling (TK)
* -----
* Last Modified: Friday 19th April 2024
* Last Modified: Wednesday 8th May 2024
* Modified By: CB
* -----
* License: BSD 3-Clause "New" or "Revised" License
Expand All @@ -27,7 +27,6 @@
#include <Kokkos_Random.hpp>
#include <concepts>
#include <iostream>
#include <random>
#include <stdexcept>
#include <string>

Expand Down Expand Up @@ -116,11 +115,10 @@ class RunCLEO {
* @param t_end End time for timestepping.
* @param gbxs DualView of gridboxes.
* @param totsupers View of all superdroplets (both in and out of bounds of domain).
* @param genpool Random number generator pool.
* @return 0 on success.
*/
int timestep_cleo(const unsigned int t_end, const dualview_gbx gbxs, const viewd_supers totsupers,
GenRandomPool genpool) const {
int timestep_cleo(const unsigned int t_end, const dualview_gbx gbxs,
const viewd_supers totsupers) const {
std::cout << "\n--- timestepping ---\n";

unsigned int t_mdl(0);
Expand All @@ -132,7 +130,7 @@ class RunCLEO {
coupldyn_step(t_mdl, t_next);

/* advance SDM (optionally concurrent to dynamics solver) */
sdm_step(t_mdl, t_next, gbxs, totsupers, genpool);
sdm_step(t_mdl, t_next, gbxs, totsupers);

/* proceed to next step (in general involves coupling) */
t_mdl = proceed_to_next_step(t_next, gbxs);
Expand Down Expand Up @@ -217,12 +215,11 @@ class RunCLEO {
* @param t_next Next timestep of the coupled model.
* @param gbxs DualView of gridboxes.
* @param totsupers View of all superdrops (both in and out of bounds of domain).
* @param genpool Random number generator pool.
*/
void sdm_step(const unsigned int t_mdl, unsigned int t_next, dualview_gbx gbxs,
const viewd_supers totsupers, GenRandomPool genpool) const {
const viewd_supers totsupers) const {
gbxs.sync_device(); // get device up to date with host
sdm.run_step(t_mdl, t_next, gbxs.view_device(), totsupers, genpool);
sdm.run_step(t_mdl, t_next, gbxs.view_device(), totsupers);
gbxs.modify_device(); // mark device view of gbxs as modified
}

Expand Down Expand Up @@ -297,13 +294,12 @@ class RunCLEO {
// create runtime objects
viewd_supers totsupers(create_supers(initconds.initsupers));
dualview_gbx gbxs(create_gbxs(sdm.gbxmaps, initconds.initgbxs, totsupers));
GenRandomPool genpool(std::random_device {}());

// prepare CLEO for timestepping
prepare_to_timestep(gbxs);

// do timestepping from t=0 to t=t_end
timestep_cleo(t_end, gbxs, totsupers, genpool);
timestep_cleo(t_end, gbxs, totsupers);

return 0;
}
Expand Down
16 changes: 7 additions & 9 deletions libs/runcleo/sdmmethods.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Author: Clara Bayley (CB)
* Additional Contributors: Tobias Kölling (TK)
* -----
* Last Modified: Friday 19th April 2024
* Last Modified: Wednesday 8th May 2024
* Modified By: CB
* -----
* License: BSD 3-Clause "New" or "Revised" License
Expand Down Expand Up @@ -126,10 +126,9 @@ class SDMMethods {
* @param t_sdm Current timestep for SDM.
* @param t_next Next timestep for SDM.
* @param d_gbxs View of gridboxes on device.
* @param genpool Random number generator pool.
*/
void operator()(const unsigned int t_sdm, const unsigned int t_next, const viewd_gbx d_gbxs,
GenRandomPool genpool) const {
void operator()(const unsigned int t_sdm, const unsigned int t_next,
const viewd_gbx d_gbxs) const {
// TODO(all) use scratch space for parallel region?
const size_t ngbxs(d_gbxs.extent(0));
Kokkos::parallel_for(
Expand All @@ -139,7 +138,7 @@ class SDMMethods {

auto supers(d_gbxs(ii).supersingbx());
for (unsigned int subt = t_sdm; subt < t_next; subt = microphys.next_step(subt)) {
supers = microphys.run_step(team_member, subt, supers, d_gbxs(ii).state, genpool);
supers = microphys.run_step(team_member, subt, supers, d_gbxs(ii).state);
}
});
}
Expand Down Expand Up @@ -214,16 +213,15 @@ class SDMMethods {
* @param t_mdl_next Next timestep of the coupled model.
* @param d_gbxs View of gridboxes on device.
* @param totsupers View of all superdrops (both in and out of bounds of domain).
* @param genpool Random number generator pool.
*/
void run_step(const unsigned int t_mdl, const unsigned int t_mdl_next, viewd_gbx d_gbxs,
const viewd_supers totsupers, GenRandomPool genpool) const {
const viewd_supers totsupers) const {
unsigned int t_sdm(t_mdl);
while (t_sdm < t_mdl_next) {
const auto t_sdm_next = next_sdmstep(t_sdm, t_mdl_next);

superdrops_movement(t_sdm, d_gbxs, totsupers); // on host and device
sdm_microphysics(t_sdm, t_sdm_next, d_gbxs, genpool); // on device
superdrops_movement(t_sdm, d_gbxs, totsupers); // on host and device
sdm_microphysics(t_sdm, t_sdm_next, d_gbxs); // on device

t_sdm = t_sdm_next;
}
Expand Down
29 changes: 12 additions & 17 deletions libs/superdrops/collisions/collisions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Author: Clara Bayley (CB)
* Additional Contributors:
* -----
* Last Modified: Sunday 21st April 2024
* Last Modified: Wednesday 8th May 2024
* Modified By: CB
* -----
* License: BSD 3-Clause "New" or "Revised" License
Expand All @@ -25,6 +25,7 @@
#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include <concepts>
#include <random>

#include "../../cleoconstants.hpp"
#include "../kokkosaliases_sd.hpp"
Expand Down Expand Up @@ -79,6 +80,7 @@ struct DoCollisions {
const double DELT; /**< time interval [s] over which probability of collision is calculated. */
const Probability probability; /**< Probability object for calculating collision probabilities. */
const EnactCollision enact_collision; /**< Enactment object for enacting collision events. */
const GenRandomPool genpool; /**< Kokkos thread-safe random number generator pool.*/

/**
* @brief Scaled probability of collision for a pair of super-droplets.
Expand Down Expand Up @@ -132,13 +134,12 @@ struct DoCollisions {
*
* @param dropA The first superdroplet.
* @param dropB The second superdroplet.
* @param genpool The random number generator pool.
* @param scale_p The scaling factor.
* @param VOLUME The volume.
* @return True if the collision event results in null superdrops with xi=0), otherwise false.
*/
KOKKOS_INLINE_FUNCTION bool collide_superdroplet_pair(Superdrop &dropA, Superdrop &dropB,
GenRandomPool genpool, const double scale_p,
const double scale_p,
const double VOLUME) const {
/* 1. assign references to each superdrop in pair
that will collide such that (drop1.xi) >= (drop2.xi) */
Expand Down Expand Up @@ -176,12 +177,10 @@ struct DoCollisions {
* @param team_member The Kokkos team member.
* @param supers The randomly shuffled view of super-droplets.
* @param volume The volume in which to calculate the probability of collisions.
* @param genpool The random number generator pool.
* @return The number of null (xi=0) superdrops.
*/
KOKKOS_INLINE_FUNCTION size_t collide_supers(const TeamMember &team_member,
subviewd_supers supers, const double volume,
GenRandomPool genpool) const {
subviewd_supers supers, const double volume) const {
const auto nsupers = static_cast<size_t>(supers.extent(0));
const auto npairs = size_t{nsupers / 2}; // no. pairs of superdrops (=floor() for nsupers > 0)
const auto scale_p = double{nsupers * (nsupers - 1.0) / (2.0 * npairs)};
Expand All @@ -193,7 +192,7 @@ struct DoCollisions {
[&, this](const size_t jj, size_t &nnull) {
const auto kk = size_t{jj * 2};
const auto isnull =
collide_superdroplet_pair(supers(kk), supers(kk + 1), genpool, scale_p, VOLUME);
collide_superdroplet_pair(supers(kk), supers(kk + 1), scale_p, VOLUME);
nnull += static_cast<size_t>(isnull);
},
totnnull);
Expand All @@ -212,19 +211,17 @@ struct DoCollisions {
* @param team_member The Kokkos team member.
* @param supers The view of super-droplets.
* @param volume The volume in which to calculate the probability of collisions.
* @param genpool The random number generator pool.
* @return The updated superdroplets.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers do_collisions(const TeamMember &team_member,
subviewd_supers supers, const double volume,
GenRandomPool genpool) const {
subviewd_supers supers,
const double volume) const {
/* Randomly shuffle order of superdroplet objects
in supers in order to generate random pairs */
supers = one_shuffle_supers(team_member, supers, genpool);

/* collide all randomly generated pairs of SDs */
size_t nnull(
collide_supers(team_member, supers, volume, genpool)); // number of null superdrops
size_t nnull(collide_supers(team_member, supers, volume)); // number of null superdrops

return is_null_supers(supers, nnull);
}
Expand All @@ -242,7 +239,7 @@ struct DoCollisions {
* @param x The enactment object for enacting collision events.
*/
DoCollisions(const double DELT, Probability p, EnactCollision x)
: DELT(DELT), probability(p), enact_collision(x) {}
: DELT(DELT), probability(p), enact_collision(x), genpool(std::random_device {}()) {}

/**
* @brief Operator used as an "adaptor" for using collisions as the MicrophysicsFunction type for
Expand All @@ -258,14 +255,12 @@ struct DoCollisions {
* @param subt The sub-time step.
* @param supers The superdroplets.
* @param state The state.
* @param genpool The random number generator pool.
* @return The updated superdroplets.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers operator()(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
const State &state,
GenRandomPool genpool) const {
return do_collisions(team_member, supers, state.get_volume(), genpool);
const State &state) const {
return do_collisions(team_member, supers, state.get_volume());
}
};

Expand Down
5 changes: 2 additions & 3 deletions libs/superdrops/condensation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Author: Clara Bayley (CB)
* Additional Contributors: Shin-ichiro Shima (SiS)
* -----
* Last Modified: Wednesday 17th April 2024
* Last Modified: Wednesday 8th May 2024
* Modified By: CB
* -----
* License: BSD 3-Clause "New" or "Revised" License
Expand Down Expand Up @@ -165,12 +165,11 @@ struct DoCondensation {
* @param subt The microphysics time step.
* @param supers The view of super-droplets.
* @param state The State.
* @param genpool The Kokkos thread-safe random number generator pool.
* @return The updated view super-droplets.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers operator()(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
State &state, GenRandomPool genpool) const {
State &state) const {
do_condensation(team_member, supers, state);
return supers;
}
Expand Down
36 changes: 16 additions & 20 deletions libs/superdrops/microphysicalprocess.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Author: Clara Bayley (CB)
* Additional Contributors: Tobias Kölling (TK)
* -----
* Last Modified: Monday 12th February 2024
* Last Modified: Wednesday 8th May 2024
* Modified By: CB
* -----
* License: BSD 3-Clause "New" or "Revised" License
Expand All @@ -23,10 +23,9 @@
#ifndef LIBS_SUPERDROPS_MICROPHYSICALPROCESS_HPP_
#define LIBS_SUPERDROPS_MICROPHYSICALPROCESS_HPP_

#include <concepts>

#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include <concepts>

#include "../cleoconstants.hpp"
#include "./kokkosaliases_sd.hpp"
Expand All @@ -44,10 +43,10 @@
*/
template <typename P>
concept MicrophysicalProcess = requires(P p, const TeamMember &tm, const unsigned int t,
subviewd_supers supers, State &state, GenRandomPool gp) {
subviewd_supers supers, State &state) {
{ p.next_step(t) } -> std::convertible_to<unsigned int>;
{ p.on_step(t) } -> std::same_as<bool>;
{ p.run_step(tm, t, supers, state, gp) } -> std::convertible_to<subviewd_supers>;
{ p.run_step(tm, t, supers, state) } -> std::convertible_to<subviewd_supers>;
};

/**
Expand All @@ -64,8 +63,8 @@ concept MicrophysicalProcess = requires(P p, const TeamMember &tm, const unsigne
template <MicrophysicalProcess Microphys1, MicrophysicalProcess Microphys2>
struct CombinedMicrophysicalProcess {
private:
Microphys1 a; /**< The first instance of type of MicrophysicalProcess. */
Microphys2 b; /**< The second instance of type of MicrophysicalProcess. */
Microphys1 a; /**< The first instance of type of MicrophysicalProcess. */
Microphys2 b; /**< The second instance of type of MicrophysicalProcess. */

public:
/**
Expand Down Expand Up @@ -106,14 +105,13 @@ struct CombinedMicrophysicalProcess {
* @param subt The current time step.
* @param supers The view of super-droplets.
* @param state The state of the system / volume.
* @param genpool The Kokkos thread-safe random number generator pool.
* @return The updated view of super-droplets after the process.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers run_step(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
State &state, GenRandomPool genpool) const {
supers = a.run_step(team_member, subt, supers, state, genpool);
supers = b.run_step(team_member, subt, supers, state, genpool);
State &state) const {
supers = a.run_step(team_member, subt, supers, state);
supers = b.run_step(team_member, subt, supers, state);
return supers;
}
};
Expand Down Expand Up @@ -167,12 +165,11 @@ struct NullMicrophysicalProcess {
* @param subt The current time step.
* @param supers The view of super-droplets.
* @param state The state of the system.
* @param genpool The random number generator pool.
* @return The unchanged view of super-droplets.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers run_step(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
State &state, GenRandomPool genpool) const {
State &state) const {
return supers;
}
};
Expand All @@ -187,8 +184,8 @@ struct NullMicrophysicalProcess {
*/
template <typename F>
concept MicrophysicsFunc = requires(F f, const TeamMember &tm, const unsigned int subt,
subviewd_supers supers, State &state, GenRandomPool gp) {
{ f(tm, subt, supers, state, gp) } -> std::convertible_to<subviewd_supers>;
subviewd_supers supers, State &state) {
{ f(tm, subt, supers, state) } -> std::convertible_to<subviewd_supers>;
};

/**
Expand All @@ -203,8 +200,8 @@ concept MicrophysicsFunc = requires(F f, const TeamMember &tm, const unsigned in
template <MicrophysicsFunc F>
struct ConstTstepMicrophysics {
private:
unsigned int interval; /**< The constant time step between calls to microphysics. */
F do_microphysics; /**< Function-like microphysics is type of MicrophysicsFunc*/
unsigned int interval; /**< The constant time step between calls to microphysics. */
F do_microphysics; /**< Function-like microphysics is type of MicrophysicsFunc*/

public:
/**
Expand Down Expand Up @@ -244,14 +241,13 @@ struct ConstTstepMicrophysics {
* @param subt The current time step.
* @param supers The view of super-droplets.
* @param state The state of the system / volume.
* @param genpool The Kokkos thread-safe random number generator pool.
* @return The updated view of super-droplets after the process.
*/
KOKKOS_INLINE_FUNCTION subviewd_supers run_step(const TeamMember &team_member,
const unsigned int subt, subviewd_supers supers,
State &state, GenRandomPool genpool) const {
State &state) const {
if (on_step(subt)) {
supers = do_microphysics(team_member, subt, supers, state, genpool);
supers = do_microphysics(team_member, subt, supers, state);
}

return supers;
Expand Down
4 changes: 2 additions & 2 deletions libs/superdrops/urbg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Author: Clara Bayley (CB)
* Additional Contributors:
* -----
* Last Modified: Tuesday 9th April 2024
* Last Modified: Wednesday 8th May 2024
* Modified By: CB
* -----
* License: BSD 3-Clause "New" or "Revised" License
Expand Down Expand Up @@ -132,7 +132,7 @@ KOKKOS_INLINE_FUNCTION viewd_supers shuffle_supers(const viewd_supers supers,
*/
KOKKOS_INLINE_FUNCTION viewd_supers one_shuffle_supers(const TeamMember& team_member,
const viewd_supers supers,
GenRandomPool genpool) {
const GenRandomPool genpool) {
Kokkos::single(Kokkos::PerTeam(team_member), [&]() {
URBG<ExecSpace> urbg{genpool.get_state()};
shuffle_supers(supers, urbg);
Expand Down
Loading