32-bit FNV-1a digest of the container’s live state.
Folds the schema string, then the element count as an explicit
int64, then every field’s live slice in declaration order. Two runs
that reach identical state therefore produce identical digests, on any
supported compiler and in both default_int builds, which is what
makes this usable to validate a checkpoint.
Changing any single element of any single field changes the digest.
See pic_array_hash for how -0.0 and NaN are canonicalised.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(particle_soa_t), | intent(in) | :: | this |
Container to fingerprint. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(array_hash_t), | private | :: | hasher | ||||
| integer(kind=default_int), | private | :: | n |
function particle_soa_state_hash(this) result(digest) !! 32-bit FNV-1a digest of the container's live state. !! !! Folds the schema string, then the element count as an explicit !! `int64`, then every field's live slice in declaration order. Two runs !! that reach identical state therefore produce identical digests, on any !! supported compiler and in both `default_int` builds, which is what !! makes this usable to validate a checkpoint. !! !! Changing any single element of any single field changes the digest. !! See `pic_array_hash` for how -0.0 and NaN are canonicalised. class(particle_soa_t), intent(in) :: this !! Container to fingerprint. integer(int32) :: digest type(array_hash_t) :: hasher integer(default_int) :: n n = this%extent%used call soa_hash_begin(hasher, PARTICLE_SOA_SCHEMA, n) call soa_hash_field(hasher, this%id, n) call soa_hash_field(hasher, this%x, n) call soa_hash_field(hasher, this%y, n) call soa_hash_field(hasher, this%z, n) call soa_hash_field(hasher, this%mass, n) call soa_hash_field(hasher, this%active, n) digest = hasher%digest() end function particle_soa_state_hash