Wideband autonomous SDR analysis engine forked from sdr-visual-suite
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

113 строки
3.3KB

  1. package gpudemod
  2. import "testing"
  3. func TestStreamingExtractGPUExecUsesSafeDefaultMode(t *testing.T) {
  4. r := &BatchRunner{eng: &Engine{sampleRate: 4000000}, streamState: make(map[int64]*ExtractStreamState)}
  5. job := StreamingExtractJob{
  6. SignalID: 1,
  7. OffsetHz: 12500,
  8. Bandwidth: 20000,
  9. OutRate: 200000,
  10. NumTaps: 65,
  11. ConfigHash: 777,
  12. }
  13. res, err := r.StreamingExtractGPUExec(makeDeterministicIQ(2048), []StreamingExtractJob{job})
  14. if err != nil {
  15. t.Fatalf("expected safe default execution path, got error: %v", err)
  16. }
  17. if len(res) != 1 {
  18. t.Fatalf("expected 1 result, got %d", len(res))
  19. }
  20. if res[0].Rate != job.OutRate {
  21. t.Fatalf("expected output rate %d, got %d", job.OutRate, res[0].Rate)
  22. }
  23. if res[0].NOut <= 0 {
  24. t.Fatalf("expected streaming output samples")
  25. }
  26. }
  27. func TestStreamingGPUExecMatchesCPUOracleAcrossChunkPatterns(t *testing.T) {
  28. job := StreamingExtractJob{
  29. SignalID: 1,
  30. OffsetHz: 12500,
  31. Bandwidth: 20000,
  32. OutRate: 200000,
  33. NumTaps: 65,
  34. ConfigHash: 777,
  35. }
  36. t.Run("DeterministicIQ", func(t *testing.T) {
  37. r := &BatchRunner{eng: &Engine{sampleRate: 4000000}, streamState: make(map[int64]*ExtractStreamState)}
  38. steps := makeStreamingValidationSteps(
  39. makeDeterministicIQ(1500),
  40. []int{0, 1, 2, 17, 63, 64, 65, 129, 511},
  41. []StreamingExtractJob{job},
  42. )
  43. runStreamingExecSequenceAgainstOracle(t, r, steps, 1e-5, 1e-9)
  44. })
  45. t.Run("ToneNoiseIQ", func(t *testing.T) {
  46. r := &BatchRunner{eng: &Engine{sampleRate: 4000000}, streamState: make(map[int64]*ExtractStreamState)}
  47. steps := makeStreamingValidationSteps(
  48. makeToneNoiseIQ(4096, 0.023),
  49. []int{7, 20, 3, 63, 64, 65, 777},
  50. []StreamingExtractJob{job},
  51. )
  52. runStreamingExecSequenceAgainstOracle(t, r, steps, 1e-5, 1e-9)
  53. })
  54. }
  55. func TestStreamingGPUExecLifecycleMatchesCPUOracle(t *testing.T) {
  56. r := &BatchRunner{
  57. eng: &Engine{sampleRate: 4000000},
  58. streamState: make(map[int64]*ExtractStreamState),
  59. nativeState: make(map[int64]*nativeStreamingSignalState),
  60. }
  61. baseA := StreamingExtractJob{
  62. SignalID: 11,
  63. OffsetHz: 12500,
  64. Bandwidth: 20000,
  65. OutRate: 200000,
  66. NumTaps: 65,
  67. ConfigHash: 1001,
  68. }
  69. baseB := StreamingExtractJob{
  70. SignalID: 22,
  71. OffsetHz: -18750,
  72. Bandwidth: 16000,
  73. OutRate: 100000,
  74. NumTaps: 33,
  75. ConfigHash: 2002,
  76. }
  77. steps := []streamingValidationStep{
  78. {
  79. name: "prime_both_signals",
  80. iq: makeDeterministicIQ(512),
  81. jobs: []StreamingExtractJob{baseA, baseB},
  82. },
  83. {
  84. name: "config_reset_with_zero_new",
  85. iq: nil,
  86. jobs: []StreamingExtractJob{{SignalID: baseA.SignalID, OffsetHz: baseA.OffsetHz, Bandwidth: baseA.Bandwidth, OutRate: baseA.OutRate, NumTaps: baseA.NumTaps, ConfigHash: baseA.ConfigHash + 1}, baseB},
  87. },
  88. {
  89. name: "signal_b_disappears",
  90. iq: makeToneNoiseIQ(96, 0.041),
  91. jobs: []StreamingExtractJob{baseA},
  92. },
  93. {
  94. name: "signal_b_reappears_fresh",
  95. iq: makeDeterministicIQ(160),
  96. jobs: []StreamingExtractJob{baseA, baseB},
  97. },
  98. {
  99. name: "small_history_boundary_chunk",
  100. iq: makeToneNoiseIQ(65, 0.017),
  101. jobs: []StreamingExtractJob{baseA, baseB},
  102. },
  103. }
  104. runStreamingExecSequenceAgainstOracle(t, r, steps, 1e-5, 1e-9)
  105. if _, ok := r.nativeState[baseB.SignalID]; ok {
  106. t.Fatalf("expected safe host-oracle path to keep native state inactive while gate is off")
  107. }
  108. }