|
- package gpudemod
-
- import "testing"
-
- func TestStreamingExtractGPUExecUsesSafeDefaultMode(t *testing.T) {
- r := &BatchRunner{eng: &Engine{sampleRate: 4000000}, streamState: make(map[int64]*ExtractStreamState)}
- job := StreamingExtractJob{
- SignalID: 1,
- OffsetHz: 12500,
- Bandwidth: 20000,
- OutRate: 200000,
- NumTaps: 65,
- ConfigHash: 777,
- }
- res, err := r.StreamingExtractGPUExec(makeDeterministicIQ(2048), []StreamingExtractJob{job})
- if err != nil {
- t.Fatalf("expected safe default execution path, got error: %v", err)
- }
- if len(res) != 1 {
- t.Fatalf("expected 1 result, got %d", len(res))
- }
- if res[0].Rate != job.OutRate {
- t.Fatalf("expected output rate %d, got %d", job.OutRate, res[0].Rate)
- }
- if res[0].NOut <= 0 {
- t.Fatalf("expected streaming output samples")
- }
- }
-
- func TestStreamingGPUExecMatchesCPUOracleAcrossChunkPatterns(t *testing.T) {
- job := StreamingExtractJob{
- SignalID: 1,
- OffsetHz: 12500,
- Bandwidth: 20000,
- OutRate: 200000,
- NumTaps: 65,
- ConfigHash: 777,
- }
- t.Run("DeterministicIQ", func(t *testing.T) {
- r := &BatchRunner{eng: &Engine{sampleRate: 4000000}, streamState: make(map[int64]*ExtractStreamState)}
- steps := makeStreamingValidationSteps(
- makeDeterministicIQ(1500),
- []int{0, 1, 2, 17, 63, 64, 65, 129, 511},
- []StreamingExtractJob{job},
- )
- runStreamingExecSequenceAgainstOracle(t, r, steps, 1e-5, 1e-9)
- })
- t.Run("ToneNoiseIQ", func(t *testing.T) {
- r := &BatchRunner{eng: &Engine{sampleRate: 4000000}, streamState: make(map[int64]*ExtractStreamState)}
- steps := makeStreamingValidationSteps(
- makeToneNoiseIQ(4096, 0.023),
- []int{7, 20, 3, 63, 64, 65, 777},
- []StreamingExtractJob{job},
- )
- runStreamingExecSequenceAgainstOracle(t, r, steps, 1e-5, 1e-9)
- })
- }
-
- func TestStreamingGPUExecLifecycleMatchesCPUOracle(t *testing.T) {
- r := &BatchRunner{
- eng: &Engine{sampleRate: 4000000},
- streamState: make(map[int64]*ExtractStreamState),
- nativeState: make(map[int64]*nativeStreamingSignalState),
- }
- baseA := StreamingExtractJob{
- SignalID: 11,
- OffsetHz: 12500,
- Bandwidth: 20000,
- OutRate: 200000,
- NumTaps: 65,
- ConfigHash: 1001,
- }
- baseB := StreamingExtractJob{
- SignalID: 22,
- OffsetHz: -18750,
- Bandwidth: 16000,
- OutRate: 100000,
- NumTaps: 33,
- ConfigHash: 2002,
- }
- steps := []streamingValidationStep{
- {
- name: "prime_both_signals",
- iq: makeDeterministicIQ(512),
- jobs: []StreamingExtractJob{baseA, baseB},
- },
- {
- name: "config_reset_with_zero_new",
- iq: nil,
- jobs: []StreamingExtractJob{{SignalID: baseA.SignalID, OffsetHz: baseA.OffsetHz, Bandwidth: baseA.Bandwidth, OutRate: baseA.OutRate, NumTaps: baseA.NumTaps, ConfigHash: baseA.ConfigHash + 1}, baseB},
- },
- {
- name: "signal_b_disappears",
- iq: makeToneNoiseIQ(96, 0.041),
- jobs: []StreamingExtractJob{baseA},
- },
- {
- name: "signal_b_reappears_fresh",
- iq: makeDeterministicIQ(160),
- jobs: []StreamingExtractJob{baseA, baseB},
- },
- {
- name: "small_history_boundary_chunk",
- iq: makeToneNoiseIQ(65, 0.017),
- jobs: []StreamingExtractJob{baseA, baseB},
- },
- }
- runStreamingExecSequenceAgainstOracle(t, r, steps, 1e-5, 1e-9)
- if _, ok := r.nativeState[baseB.SignalID]; ok {
- t.Fatalf("expected safe host-oracle path to keep native state inactive while gate is off")
- }
- }
|