Skip to content

Misc Develop and Tiebreaker Work #185

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

Merged
merged 18 commits into from
Jul 11, 2022
Merged

Misc Develop and Tiebreaker Work #185

merged 18 commits into from
Jul 11, 2022

Conversation

nmcglo
Copy link
Member

@nmcglo nmcglo commented Jul 11, 2022

This brings in the functionality of the tiebreaker work which introduces a separate set of PRNG streams on each LP that are not to be called directly or used by the user/model. These RNG streams create values that are embedded into the ROSS event structure so that upon receipt, if the virtual time of the received event ties with any other event, their ordering can be determined by these embedded RNG values.

This tiebreaking method boils down to a fair 50:50 coin flip for the ordering of any two simultaneous events.

This mechanism has been extended to also support tiebreaking of zero-offset events as well as user-defined priorities which are given precedent in the event ordering ruleset.

e.g. Given any two events, their ordering is determined by the following cascading rules:

  1. Their virtual timestamp
  2. Their user defined priority
  3. Their ith random tiebreaker value
  4. Their ith+1 random tiebreaker value (and so on -- these values are only needed to determine ordering of two simultaneous zero-offset events

The RNG stream seeds for the model and the core (tiebreaker) are individually set at runtime via CLA.

gonsie and others added 18 commits September 29, 2020 13:04
Release 7.2.1 -> Develop
develop and master should now be even
This commit adds a separate array of RNG streams on each LP that aren't
to be utilized by developed models. These separate RNG streams can be
utilized to leverage the deterministic RNG nature that ROSS can manage
toward other goals of the ROSS engine itself.

Notable example use for this: Deterministic Tiebreaking
Deterministic Tiebreaking can be implemented by creating a random value
at the creation of an event, this value is encoded into the ROSS event
struct and is utilized to break any event ties (same destination LP at
same time). Because this separate RNG is only accessed by ROSS, it can
be rolled back if the event becomes RC'd or cancelled. Because of
determinism, any ordering as a result of this tiebreaker will be
consistent across simulation runs regardless of event delivery order
or stragglers. If a regular model-accessed LP RNG was used for this
purpose, the tiebreaking sequence would be subject to interference.
This commit adds the functionality of the deterministic tiebreaker
mentioned in an earlier commit which added the core ROSS engine
exclusive RNGs.

The deterministic tiebreaker itself is rather simple. When an event
is created, a random value is generated from a ROSS core RNG stream.
When that event is RC'd or cancelled, that random value is also
reversed. Because this stream is only utilized by said tiebreaking
mechanism, the ordering of tiebreaking values created by the stream
is deterministic across simulations. When comparing two events
received by an LP at the same timestamp, the determining factor
in which is processed first will be decided - deterministically -
by the tiebreaker value.

While the concept itself is simple, and implementing the tiebreaker
into the event struct is similarly simple. Getting this tiebreaker
to work with the concept of GVT is not.

A better way to think about this tiebreaking mechanism is to think
of it as making sure that there are actually no such thing as event
ties. This paradigm shift means that determining "when" GVT happens
is no longer a single TW_STIME value. There is now an event signature
struct which contains a timestamp and a tiebreaker value. This
signature is all that is necessary for determining ordering of two
events in the simulation. Thus the time of the last GVT is no longer
just the single dimensional virtual timestamp, but it also includes
a tiebreaker which divides events that happen at the same primary
timestamp as GVT but with their own tiebreaker values which will be
deterministically separated as "before GVT" and "after GVT".

Thus, rollbacks now also no longer go back to a single timestamp
value in time, but to a two dimensional timestamp value consisting
of the primary timestamp and an event tiebreaker.

As complex as this system is, it does have its benefits:
1) Comparing events for Splay and AVL trees to determine ordering
require fewer comparisons and thus less compute time spent.
2) If primary timestamp ties are numerous in a model, rolling back
of one event at said timestamp will no longer require rolling back
all events with the same timestamp, only those whose tiebreaker values
determine that they happen "after" the event that prompted the
rollback.
3) Event ties are statistically impossible to force. Because the
tiebreaker value is generated using its own independent RNG stream
with an extremely long period, two events at the same primary
timestamp ALSO generating an identical random value is nearly
impossible. This also means that model developers will no longer
have to generate their own small noise to add onto their event
timestamps to prevent event ties, significantly improving the
administrative code complexity - reducing the likelihood that
a developer will forget to roll back an RNG from noise and
plunge their entire model into non-determinism.

This feature has been walled off behind a CMAKE Define Variable:
USE_RAND_TIEBREAKER. Set this value to ON during CMAKE ROSS
configuration and all code enabling the tiebreaking value
generation and the timestamp-to-time-signature paradigm shift
will be switched on by pre-processor #ifdef's.
- Changing faulty use of memset for a "for" loop instead
- Removing unused temporal variable
Tiny fixes on tiebreaking code to make compiler happy
This PR brings in tiebreaker work to develop.

Adds a separate array of RNG streams on each LP that aren't
to be utilized by developed models. These separate RNG streams can be
utilized to leverage the deterministic RNG nature that ROSS can manage
toward other goals of the ROSS engine itself.

Notable example use for this: Deterministic Tiebreaking
Deterministic Tiebreaking can be implemented by creating a random value
at the creation of an event, this value is encoded into the ROSS event
struct and is utilized to break any event ties (same destination LP at
same time). Because this separate RNG is only accessed by ROSS, it can
be rolled back if the event becomes RC'd or cancelled. Because of
determinism, any ordering as a result of this tiebreaker will be
consistent across simulation runs regardless of event delivery order
or stragglers. If a regular model-accessed LP RNG was used for this
purpose, the tiebreaking sequence would be subject to interference.

Also included: 

Capability for zero-offset event unbiased tiebreaking
User defined event priorities for tiebreaking (primary tie-breaker, then random tiebreaker used to break subsequent ties)
@nmcglo
Copy link
Member Author

nmcglo commented Jul 11, 2022

Temporarily allowing repo admins to bypass CI checks as the travis configuration is broken.

@nmcglo nmcglo merged commit 9948f6f into master Jul 11, 2022
@nmcglo
Copy link
Member Author

nmcglo commented Jul 11, 2022

CI bypass re-disabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants