Skip to main content

seed_for_name

Function seed_for_name 

pub fn seed_for_name(base: u64, name: &str) -> u64
Expand description

Derives the seed of one named parameter from a base seed.

The algorithm hashes the name with FNV-1a and absorbs it through the same SplitMix64 finalizer seed_for uses:

h = mix(base ^ GOLDEN_GAMMA)
h = mix(h ^ (fnv1a(name.as_bytes()) + GOLDEN_GAMMA))

(the addition wraps).

§Why this exists

This is what makes a sampled value depend on (sampler seed, parameter name) and on nothing else — in particular not on the order parameters are drawn in, nor on which other parameters the search space happens to contain. Drawing sequentially from one per-trial RNG would key every value on its position instead, with three consequences this function avoids:

  • adding, removing or reordering a parameter would resample every other parameter of every trial, silently invalidating a study’s history;
  • Sampler::sample_relative and sample_independent could not agree on a value, because one knows the joint space and the other does not;
  • the value of a parameter would depend on how much of the space the sampler happened to be asked for.

base is normally TrialMeta::sampler_seed, which is itself seed_for(study_seed, trial_number, Stream::Sampler). The two functions therefore compose into “a parameter’s randomness is a pure function of (study seed, trial number, parameter name)”.

use atune_core::seed::seed_for_name;

// Pure in both arguments…
assert_eq!(seed_for_name(7, "lr"), seed_for_name(7, "lr"));
// …and separating in both.
assert_ne!(seed_for_name(7, "lr"), seed_for_name(7, "batch"));
assert_ne!(seed_for_name(7, "lr"), seed_for_name(8, "lr"));

§Stability

The output values are frozen exactly as seed_for’s are: they are golden-tested by value, and changing them is a breaking change. See the module documentation.