feat: initial release
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package io
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"sourcedock.dev/petrbalvin/tensor/internal/core"
|
||||
)
|
||||
|
||||
// The boolean fixture bool_enum.h5 under testdata/h5 was written by
|
||||
// hand against the HDF5 1.8 specification, in the shape the reference
|
||||
// library writes for an old-style group with a symbol table, and it
|
||||
// validates against the reference library's own tools: h5dump reads
|
||||
// the dataset back as an H5T_ENUM over H5T_STD_U8LE with the members
|
||||
// FALSE = 0 and TRUE = 1 and the values TRUE, FALSE, TRUE, TRUE,
|
||||
// FALSE. Its layout deliberately differs from what this package's
|
||||
// writer produces: the messages of the dataset's object header sit in
|
||||
// the order datatype, fill value, dataspace, layout, the dataspace
|
||||
// carries no maximum dimensions and the fill value message declares a
|
||||
// defined zero fill, so the pins below prove the reader's tolerance of
|
||||
// a foreign layout rather than a round trip of its own bytes.
|
||||
|
||||
// TestLoadHDF5ForeignBoolFixture pins the read side: the hand-crafted
|
||||
// boolean enumeration of a foreign layout lands the dataset "flags"
|
||||
// with the core Bool dtype and the values the reference library reads
|
||||
// from the same bytes.
|
||||
func TestLoadHDF5ForeignBoolFixture(t *testing.T) {
|
||||
sets, err := LoadHDF5(h5Fixture(t, "bool_enum.h5"))
|
||||
if err != nil {
|
||||
t.Fatalf("LoadHDF5: %v", err)
|
||||
}
|
||||
if len(sets) != 1 {
|
||||
t.Fatalf("datasets = %d, want 1", len(sets))
|
||||
}
|
||||
d := sets[0]
|
||||
if d.Path != "/flags" {
|
||||
t.Fatalf("path = %q, want /flags", d.Path)
|
||||
}
|
||||
if s := d.Shape; len(s) != 1 || s[0] != 5 {
|
||||
t.Fatalf("shape = %v, want [5]", s)
|
||||
}
|
||||
if dt := d.Values.Dtype(); dt != core.Bool {
|
||||
t.Fatalf("dtype = %s, want bool", dt)
|
||||
}
|
||||
want := []bool{true, false, true, true, false}
|
||||
if got := d.Values.RawBools()[:5]; !slices.Equal(got, want) {
|
||||
t.Fatalf("values = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSaveHDF5BoolConvention pins the write side against the same
|
||||
// logical values: SaveHDF5 stores them through the boolean enumeration
|
||||
// convention and LoadHDF5 reads them back identically. The pin holds
|
||||
// the two-sided agreement on the convention, not a byte match with the
|
||||
// foreign fixture, whose layout the writer need not reproduce.
|
||||
func TestSaveHDF5BoolConvention(t *testing.T) {
|
||||
want := []bool{true, false, true, true, false}
|
||||
values, err := core.FromBools(want, 5)
|
||||
if err != nil {
|
||||
t.Fatalf("FromBools: %v", err)
|
||||
}
|
||||
path := filepath.Join(t.TempDir(), "bool_convention.h5")
|
||||
if err := SaveHDF5(path, []HDF5Dataset{{Path: "/flags", Shape: []int{5}, Values: values}}, nil); err != nil {
|
||||
t.Fatalf("SaveHDF5: %v", err)
|
||||
}
|
||||
sets, err := LoadHDF5(path)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadHDF5: %v", err)
|
||||
}
|
||||
if len(sets) != 1 {
|
||||
t.Fatalf("datasets = %d, want 1", len(sets))
|
||||
}
|
||||
d := sets[0]
|
||||
if d.Path != "/flags" {
|
||||
t.Fatalf("path = %q, want /flags", d.Path)
|
||||
}
|
||||
if s := d.Shape; len(s) != 1 || s[0] != 5 {
|
||||
t.Fatalf("shape = %v, want [5]", s)
|
||||
}
|
||||
if dt := d.Values.Dtype(); dt != core.Bool {
|
||||
t.Fatalf("dtype = %s, want bool", dt)
|
||||
}
|
||||
if got := d.Values.RawBools()[:5]; !slices.Equal(got, want) {
|
||||
t.Fatalf("values = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user