File size: 12,702 Bytes
e488ce7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#!/usr/bin/env python3
"""Unit test for H3 Temporal Insert, the node that does the time-smear retime
in LATENT space: expand the video latent onto the dilated token grid,
interpolate the inserted token-times, freeze the originals with a mask.

  python tests/test_temporal_insert.py
      Synthetic, no GPU, no models. comfy.nested_tensor is stubbed.

What it checks:

  1. THE T2a MAP, row for row against the probe's worked example
     (ComfyUI-ModelCatalog benchmarks/scripts/tinterp/token_map.csv, the
     124f clip with hold 2 on world frames 85..118): 124 -> 158 frames,
     37 -> 47 tokens, and the exact interpolation weights - smear token 26
     is w=0.400 between base tokens 25 and 26. The map is PORTED from that
     harness, so this test is what stops it drifting.
  2. THE EXACTNESS INVARIANT. Every token-time whose target lands on a base
     token centre (all the copied originals, and inserted singletons aligned
     to base 17-multiples) is a BIT-COPY of that base token: maxabs 0.0, not
     "close". T2a measured corr 1.0 there and the node must not do worse.
  3. LEGAL-SNAP PARITY with H3TimeSmear on three hold maps, including one
     that needs a tail pad: same dilated length, same snapped hold map, so
     the pixel and latent routes can never disagree about the grid.
  4. MASK CORRECTNESS: inserted token-times 1, originals 0, nothing partial,
     full spatial extent, and the mask rides on the samples output (that is
     how it reaches the sampler) as well as on its own output.
  5. NOISE MODE fills only the inserted tokens, leaves the copies verbatim,
     and is reproducible from noise_seed.
  6. NESTED AV: the audio component comes through bit-exact and by
     reference; a plain video latent gets a zero audio track sized for the
     DILATED length.
  7. THE REPORT names the lengths, the token counts, the split, the
     17-multiple alignment rule and the audio caveat.

Exit code 0 = pass.
"""
import importlib.util
import os
import sys
import types

import torch

HERE = os.path.dirname(os.path.abspath(__file__))

# The node builds real comfy NestedTensors; stub the module so the test needs
# nothing but torch. Same duck type comfy's has (unbind() / .is_nested).
if "comfy.nested_tensor" not in sys.modules:
    class _StubNested:
        def __init__(self, tensors):
            self.tensors = list(tensors)
            self.is_nested = True

        def unbind(self):
            return self.tensors

    _pkg = sys.modules.setdefault("comfy", types.ModuleType("comfy"))
    _mod = types.ModuleType("comfy.nested_tensor")
    _mod.NestedTensor = _StubNested
    _pkg.nested_tensor = _mod
    sys.modules["comfy.nested_tensor"] = _mod

spec = importlib.util.spec_from_file_location(
    "mainodes_motion", os.path.join(os.path.dirname(HERE), "motion.py"))
motion = importlib.util.module_from_spec(spec)
spec.loader.exec_module(motion)

FAILS = []

# The T2a probe's retime: 124 world frames, hold 2 on frames 85..118 (34
# frames, starting on a 17-multiple). 158 = 17*9+5 is legal, no tail pad.
# NOTE: this map has the end-jump shape (a rate-1 tail behind a rate-2
# span), so every call below passes expand_to_end=False: the T2a probe's
# worked example is what this suite pins, and the toggle would rewrite it.
# The toggle itself is pinned by tests/test_expand_to_end.py.
T2A_HOLDS = [1] * 85 + [2] * 34 + [1] * 5
T2A_MAP = json_map = '{"holds": %s, "world_len": 124}' % T2A_HOLDS

# (token, target_base_time, lo, hi, w_hi) straight out of token_map.csv.
T2A_ROWS = [
    (1, 2.5, 0, 1, 1.0),      # identity region: lands on base token 1's centre
    (25, 85.0, 24, 25, 1.0),  # the hold's first frame, still an exact anchor
    (26, 86.0, 25, 26, 0.400),   # THE worked example
    (27, 88.0, 26, 27, 0.125),
    (28, 90.0, 26, 27, 0.625),
]
# tokens whose target lands exactly on a base token centre -> bit-copies
T2A_EXACT = list(range(26)) + [35, 45, 46]


def check(name, ok, detail=""):
    print(("  PASS  " if ok else "  FAIL  ") + name + ("  " + detail if detail else ""))
    if not ok:
        FAILS.append(name)


def base_latent(t=37, h=6, w=10, seed=7):
    torch.manual_seed(seed)
    return {"samples": torch.randn(1, 24, t, h, w)}


def main():
    node = motion.H3TemporalInsert()

    # ---- 1. the T2a map
    holds, dil, t_base, t_dil, plan = motion.temporal_insert_map(T2A_HOLDS)
    check("T2a retime: 124f -> 158f dilated", dil == 158, str(dil))
    check("T2a token grid: 37 -> 47 tokens",
          (t_base, t_dil) == (37, 47), f"{t_base} -> {t_dil}")
    check("no tail pad needed (158 = 17*9+5), hold map unchanged",
          holds == T2A_HOLDS and sum(holds) == 158, f"sum={sum(holds)}")
    for tok, t, lo, hi, w in T2A_ROWS:
        pt, plo, phi, pw, pex = plan[tok]
        if pex >= 0:                      # exact hits are recorded as a copy
            plo, phi, pw = pex - 1, pex, 1.0
        ok = (pt == t and (plo, phi) == (lo, hi) and abs(pw - w) < 1e-12)
        check(f"token {tok}: base time {t}, lerp {lo}/{hi} w={w}", ok,
              f"got t={pt} {plo}/{phi} w={pw!r}")
    check("smear token 26's weight is EXACTLY 0.400 (the csv's row)",
          plan[26][3] == 0.4, repr(plan[26][3]))
    check("the exact-hit set matches the probe's",
          [n for n, p in enumerate(plan) if p[4] >= 0] == T2A_EXACT,
          str([n for n, p in enumerate(plan) if p[4] >= 0]))
    check("18 of the 47 token-times are inserted, 29 copied",
          len([p for p in plan if p[4] < 0]) == 18 and len(T2A_EXACT) == 29,
          f"{len([p for p in plan if p[4] < 0])} inserted")

    # ---- 2 + 4. run the node: bit-copies and mask
    lat = base_latent()
    v0 = lat["samples"]
    out, mask_out, used, rep = node.insert(samples=lat, hold_map=T2A_MAP,
                                           init_mode="lerp",
                                           expand_to_end=False)
    ov, oa = out["samples"].unbind()
    mv, ma = out["noise_mask"].unbind()
    check("the video latent is expanded along t only",
          tuple(ov.shape) == (1, 24, 47, 6, 10), str(tuple(ov.shape)))
    worst = max(float((ov[:, :, n] - v0[:, :, plan[n][4]]).abs().max())
                for n in T2A_EXACT)
    check("EXACTNESS: every exact-hit token is a BIT-COPY of its base token",
          worst == 0.0, f"maxabs over {len(T2A_EXACT)} tokens = {worst!r}")
    ins = [n for n, p in enumerate(plan) if p[4] < 0]
    n26 = (0.6 * v0[:, :, 25] + 0.4 * v0[:, :, 26])
    check("an inserted token is the plain lerp of its bracketing base tokens",
          float((ov[:, :, 26] - n26).abs().max()) < 1e-6,
          f"maxabs {float((ov[:, :, 26] - n26).abs().max()):.3e}")
    check("mask shape is (1,1,t_dil,h,w)", tuple(mv.shape) == (1, 1, 47, 6, 10),
          str(tuple(mv.shape)))
    check("inserted token-times are marked 1 (regenerate)",
          all(float(mv[:, :, n].min()) == 1.0 for n in ins), f"{len(ins)} tokens")
    check("original token-times are marked 0 (frozen)",
          all(float(mv[:, :, n].max()) == 0.0 for n in T2A_EXACT))
    check("the mask is hard everywhere (no partial cells)",
          bool(((mv == 0) | (mv == 1)).all()))
    check("the audio half of the mask is all ones",
          bool((ma == 1).all()) and ma.shape[1:] == oa.shape[1:],
          str(tuple(ma.shape)))
    check("the mask rides on the samples output (this is how it reaches "
          "the sampler)", out["noise_mask"] is mask_out["samples"])
    check("the input latent is not mutated",
          tuple(lat["samples"].shape) == (1, 24, 37, 6, 10) and
          torch.equal(lat["samples"], v0))

    # ---- 3. legal-snap parity with H3TimeSmear
    smear = motion.H3TimeSmear()
    import json as _json
    cases = [("T2a map (no pad)", T2A_HOLDS),
             ("uniform x2 on 39f (pad)", [2] * 39),
             ("adaptive burst on 90f (pad)",
              [1] * 20 + [3] * 12 + [2] * 8 + [1] * 50)]
    for name, hm in cases:
        n = len(hm)
        img = torch.zeros(n, 4, 4, 3)
        _, used_smear, length_smear, _ = smear.smear(
            images=img, dilation=1, expand_to_end=False,
            hold_map=_json.dumps({"holds": hm, "world_len": n}))
        h2, dil2, tb2, td2, _p = motion.temporal_insert_map(hm)
        s = _json.loads(used_smear)
        check(f"snap parity, {name}",
              s["holds"] == h2 and int(length_smear) == dil2 and
              s["world_len"] == n,
              f"smear {length_smear}f last hold {s['holds'][-1]} | "
              f"insert {dil2}f last hold {h2[-1]} -> {td2} tokens")

    # ---- 5. noise mode
    lat2 = base_latent()
    nout, _nm, _u, nrep = node.insert(samples=lat2, hold_map=T2A_MAP,
                                      init_mode="noise", noise_seed=11,
                                      expand_to_end=False)
    nv = nout["samples"].unbind()[0]
    worst_n = max(float((nv[:, :, n] - v0[:, :, plan[n][4]]).abs().max())
                  for n in T2A_EXACT)
    check("noise mode still bit-copies the originals", worst_n == 0.0,
          f"maxabs {worst_n!r}")
    check("noise mode fills the inserted tokens with unit noise",
          abs(float(nv[:, :, ins].std()) - 1.0) < 0.05 and
          not torch.equal(nv[:, :, 26], ov[:, :, 26]),
          f"std {float(nv[:, :, ins].std()):.4f}")
    again, _, _, _ = node.insert(samples=base_latent(), hold_map=T2A_MAP,
                                 init_mode="noise", noise_seed=11,
                                 expand_to_end=False)
    check("noise mode is reproducible from noise_seed",
          torch.equal(again["samples"].unbind()[0], nv))
    diff, _, _, _ = node.insert(samples=base_latent(), hold_map=T2A_MAP,
                                init_mode="noise", noise_seed=12,
                                expand_to_end=False)
    check("...and a different seed gives a different init",
          not torch.equal(diff["samples"].unbind()[0], nv))

    # ---- 6. audio: nested passthrough vs plain input
    torch.manual_seed(5)
    audio_in = torch.randn(1, 32, 2, 207)          # 124f clip's audio latent
    audio_ref = audio_in.clone()
    Nested = sys.modules["comfy.nested_tensor"].NestedTensor
    av = {"samples": Nested([base_latent()["samples"], audio_in])}
    aout, _am, _au, arep = node.insert(samples=av, hold_map=T2A_MAP,
                                       expand_to_end=False)
    av_v, av_a = aout["samples"].unbind()
    check("nested AV: the audio comes out bit-exact",
          torch.equal(av_a, audio_ref) and tuple(av_a.shape) == (1, 32, 2, 207),
          str(tuple(av_a.shape)))
    check("nested AV: the audio is passed by reference, not copied",
          av_a is audio_in)
    check("nested AV: the video is still expanded", av_v.shape[2] == 47)
    check("nested AV: the audio mask matches the audio it guards",
          tuple(aout["noise_mask"].unbind()[1].shape) == (1, 32, 2, 207))
    check("a plain video latent gets a ZERO audio track on the DILATED clock",
          tuple(oa.shape) == (1, 32, 2, motion._audio_latent_t(158)) and
          bool((oa == 0).all()),
          f"{tuple(oa.shape)} vs base clock {motion._audio_latent_t(124)}")

    # ---- 7. hold_map passthrough + report
    u = _json.loads(used)
    check("hold_map passes through in H3TimeSmear's format, already snapped",
          u["holds"] == holds and u["world_len"] == 124,
          f"world_len {u['world_len']}, {len(u['holds'])} holds")
    check("the passthrough map drives H3TrueClock to the dilated token count",
          len(motion.true_clock_spans(u["holds"])) == 47,
          str(len(motion.true_clock_spans(u["holds"]))))
    for frag in ("world 124f -> dilated 158f", "t_lat 37 -> 47 tokens",
                 "copied verbatim (mask 0, frozen): 29 token-times [0-25,35,45-46]",
                 "inserted (mask 1, regenerate): 18 token-times [26-34,36-44]",
                 "T2a rule 1", "all on 17-multiples", "AUDIO CAVEAT",
                 "sigma >= ~0.5"):
        check(f"report says {frag!r}", frag in rep)
    check("the report flags an OFF-anchor hold span",
          "OFF the 17-multiple phase" in node.insert(
              samples=base_latent(), expand_to_end=False,
              hold_map=_json.dumps({"holds": [1] * 80 + [2] * 39 + [1] * 5,
                                    "world_len": 124}))[3])
    check("the nested-AV report states the audio is on the BASE clock",
          "audio passed through untouched" in arep and
          "BASE clip's clock" in arep)
    print("\n--- report (T2a map, lerp)\n" + rep)

    print()
    if FAILS:
        print(f"FAILED: {len(FAILS)} check(s): " + ", ".join(FAILS))
        return 1
    print("all checks passed")
    return 0


if __name__ == "__main__":
    sys.exit(main())