Skip to content
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
34 changes: 25 additions & 9 deletions src/libPMacc/include/mpi/SeedPerRank.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2014 Axel Huebl
* Copyright 2014-2015 Axel Huebl, Alexander Grund
*
* This file is part of libPMacc.
*
Expand All @@ -24,14 +24,16 @@

#include "types.h"
#include "Environment.hpp"
#include "algorithms/reverseBits.hpp"
#include <limits>

namespace PMacc
{
namespace mpi
{
/** Calculate a Seed per Rank
*
* This functor derives a unqiue seed for each MPI rank (or GPU) from
* This functor derives a unique seed for each MPI rank (or GPU) from
* a given global seed in a deterministic manner.
*
* \tparam T_DIM Dimensionality of the simulation (1-3 D)
Expand All @@ -42,22 +44,36 @@ namespace mpi
/** Functor implementation
*
* This method provides a guaranteed unique number per MPI rank
* (or GPU). When a (only locally unique) localShift parameter is used
* (or GPU). When a (only locally unique) localSeed parameter is used
* it is furthermore guaranteed that this number does not collide
* with an other seed.
*
* \param seed initial seed to vary two identical simulations
* \param localShift e.g. a unique species id
* \param localSeed Initial seed to vary two identical simulations
* can have been xor'ed with e.g. a unique species id
* to get an unique seed per species
* \return uint32_t seed
*/
uint32_t
operator()( uint32_t seed, uint32_t localShift = 0 )
operator()( uint32_t localSeed )
{
PMACC_AUTO(&gc, PMacc::Environment<T_DIM>::get().GridController());

seed ^= gc.getGlobalSize( ) * localShift +
gc.getGlobalRank( );
return seed;
uint32_t rank = gc.getGlobalRank( );
/* We put the rank into the upper bits to allow values which start
* from zero (e.g. cellIdxs, time steps) to be used as additional seed contributors
* Those would then write to the lower bits leaving the upper bits alone
* which still results in globally unique seeds
*/
uint32_t globalUniqueSeed = reverseBits(rank);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think to remember that we discuss this:

uint32_t rank = gc.getGlobalRank( );
rank ^= localShift; // still unique because it is only a rank mixing operation
rank ^=seed; // an other mixing
unt32_t globalUniqueSeed = reverseBits(rank);
seed = globalUniqueSeed;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really? I thought we agreed on just reversing the rank and xor the localShift. If localShift is a globally constant value of whatever size it doesn't matter though if it is also reversed. Not reversing it and assuming localshift to be small we'd get some more bits set. Only problem would be, if localshift is also counted (e.g. 1 increasing value per species) then XORing this before the reversing would be better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I agree with that.

/* localSeed often contains a counted number, so we rotate it by some bits to not "destroy"
* the counted rank that is already there. Also it is not reversed to get a different pattern
*/
localSeed = (localSeed << 16) | (localSeed >> (sizeof(uint32_t) * CHAR_BIT - 16));
globalUniqueSeed ^= localSeed;
/* For any globally constant localSeed globalUniqueSeed is now guaranteed
* to be globally unique
*/
return globalUniqueSeed;
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2015 Rene Widera
* Copyright 2015 Rene Widera, Alexander Grund
*
* This file is part of PIConGPU.
*
Expand Down Expand Up @@ -51,8 +51,10 @@ struct RandomPositionImpl

GlobalSeed globalSeed;
mpi::SeedPerRank<simDim> seedPerRank;
seed = seedPerRank(globalSeed(), PMacc::traits::GetUniqueTypeId<FrameType, uint32_t>::uid());
seed ^= POSITION_SEED ^ currentStep;
seed = globalSeed() ^
PMacc::traits::GetUniqueTypeId<FrameType, uint32_t>::uid() ^
POSITION_SEED;
seed = seedPerRank(seed) ^ currentStep;

const SubGrid<simDim>& subGrid = Environment<simDim>::get().SubGrid();
localCells = subGrid.getLocalDomain().size;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Copyright 2013-2014 Axel Huebl, Heiko Burau, Rene Widera
* Copyright 2013-2015 Axel Huebl, Heiko Burau, Rene Widera,
* Alexander Grund
*
* This file is part of PIConGPU.
*
Expand Down Expand Up @@ -54,8 +55,10 @@ struct TemperatureImpl : private T_ValueFunctor

GlobalSeed globalSeed;
mpi::SeedPerRank<simDim> seedPerRank;
seed = seedPerRank(globalSeed(), PMacc::traits::GetUniqueTypeId<FrameType, uint32_t>::uid());
seed ^= TEMPERATURE_SEED;
seed = globalSeed() ^
PMacc::traits::GetUniqueTypeId<FrameType, uint32_t>::uid() ^
TEMPERATURE_SEED;
seed = seedPerRank(seed) ^ currentStep;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can now be used at each time step, pls add the currentStep xor, too.

const SubGrid<simDim>& subGrid = Environment<simDim>::get().SubGrid();
localCells = subGrid.getLocalDomain().size;
Expand Down
7 changes: 5 additions & 2 deletions src/picongpu/include/particles/startPosition/RandomImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ struct RandomImpl
typedef typename SpeciesType::FrameType FrameType;

mpi::SeedPerRank<simDim> seedPerRank;
seed = seedPerRank(GlobalSeed()(), PMacc::traits::GetUniqueTypeId<FrameType, uint32_t>::uid());
seed ^= POSITION_SEED;
GlobalSeed globalSeed;
seed = globalSeed() ^
PMacc::traits::GetUniqueTypeId<FrameType, uint32_t>::uid() ^
POSITION_SEED;
seed = seedPerRank(seed) ^ currentStep;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add the currentStep xor (can also be, in principle, now be used at each time step; example: redistribution of particles for each step)

const uint32_t numSlides = MovingWindow::getInstance( ).getSlideCounter( currentStep );
const SubGrid<simDim>& subGrid = Environment<simDim>::get().SubGrid();
Expand Down