Function seed_for_name
pub fn seed_for_name(base: u64, name: &str) -> u64Expand 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_relativeandsample_independentcould 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.