August 14, 2026 · 22 min read

SNN Timesteps T Explained

T is a conversion and inference budget. This page shows how to choose 8 vs 16 vs 32 with NeuroCUDA for accuracy, latency, and energy without copying the ResNet tutorial's T=32 line as if it were a law of physics.

NeuroCUDA treats SNN timesteps T as a budget you sweep for accuracy, latency, and energy. Install with pip install neurocuda from https://github.com/Krishnav1/neurocuda (MIT). Call snn, meta = neurocuda.convert(model, calib_loader), compile, then evaluate T=8, T=16, and T=32 and pick. GPU wall time is not Loihi energy.

TL;DR

Sweep SNN timesteps T at 8, 16, and 32 on your checkpoint. Convert (or finetune) at each T, then evaluate at that T. T=32 is the published ResNet-18/CIFAR-10 protocol (SNN 94.61% ± 0.14% vs ANN 95.56%). N-MNIST often works with fewer steps because events already live in time. Pick the smallest T that meets the accuracy floor. GPU milliseconds are not Loihi millijoules. Paper: technical report.

This page vs nearby pages: this URL is how to choose T=8 vs 16 vs 32. ResNet-18 SNN conversion uses T=32 as the published CIFAR protocol, not as a universal constant. N-MNIST SNN conversion is the event-dataset HowTo. Accuracy drop lists low T as one of four bugs. QCFS ANN to SNN explains the scale that T spends. Google should index this page for the T tradeoff, not as a clone of the ResNet tutorial.

SNN timesteps T tradeoff of 8, 16, and 32 with NeuroCUDA

People copy timesteps=32 from a ResNet gist and then either overspend latency on a three-layer event CNN or undersample a residual net and blame spiking networks. Both mistakes come from treating T as a brand instead of a budget. This article is the budget. NeuroCUDA is the compiler: pip install neurocuda, source at github.com/Krishnav1/neurocuda, method in the PDF report. The convert HowTo stays at convert PyTorch to SNN. The install HowTo stays at pip install neurocuda guide. Stay here when the question is which T to run.

A converted SNN is not a ReLU network with a funny activation. It is a dynamical system that sees the same sample for T discrete steps. Each step, weighted input is added to a membrane, a threshold is tested, and a spike may fire. The number of those steps is SNN timesteps T. If T is too small, late layers never see enough spikes to reconstruct the ReLU they replaced. If T is larger than the task needs, you pay sequential latency and you may pay energy, depending on the machine. The machine matters. That last sentence is the rest of this page in miniature.

What SNN timesteps T actually count

T is not "how neuromorphic the model is." It is a clock. On a software backend (GPU or CPU), NeuroCUDA unrolls integrate-and-fire dynamics for T steps per sample. On a neuromorphic chip, T is a window in which events may arrive and membranes may cross threshold. Those two clocks are related by the neuron model. They are not related by a joule conversion factor you can invent in a blog.

In ANN-to-SNN conversion the same T usually appears in three places, and they should match:

  1. Calibration. QCFS maps a ReLU value onto a spike count that can be realized in T steps. The method explainer is QCFS ANN to SNN.
  2. Fine-tune. BPTT unrolls T steps so surrogate gradients see the same window you will use at test.
  3. Inference. Evaluate presents each test sample for T steps and reads out a decision (spike counts, membrane, or a last-step logit, depending on the compiled graph).

If you calibrate and finetune at T=32 and then evaluate at T=8, you are scoring a different object than the one you converted. That experiment is allowed. Calling it "the NeuroCUDA ResNet number" is not. The published CIFAR row is T=32. The published N-MNIST row is a different dataset. Quote the protocol with the number, the way reproduce NeuroCUDA results does.

T also shows up in memory. BPTT stores intermediates across the unroll. A Colab T4 and a lab A100 feel different at T=32 even when the method is identical. That is a hardware constraint on the sweep, documented on NeuroCUDA Google Colab, not a reason to skip the sweep.

Rate coding: T is a bin budget

Rate coding is the conversion default you should assume unless you have evidence of a temporal code. A ReLU activation of size x is supposed to look like "about k spikes in T steps." The finest grain you can represent without tricks is 1/T. At T=8, two neighboring rates differ by 12.5 percentage points of the maximum spike count. At T=16 that grain is 6.25 points. At T=32 it is about 3.1 points. That is why people reach for larger T on hard image tasks: they are buying resolution in the rate, not buying a mystical extra of "spiking-ness."

QCFS exists because unbounded ReLU and a finite spike budget do not match. Clip admits that T cannot emit 50 spikes in 8 steps. Floor turns the remaining range into bins. Shift keeps those bins from being biased low. The scale (lambda, per channel) is learned so each feature map uses the bins it actually needs. None of that removes T from the problem. It makes T spendable. If you want the method, open the QCFS page. If you want the spend, stay here.

Rate coding also explains a failure mode that looks like "SNNs need huge T." If thresholds are frozen at 1.0, the bins are in the wrong place no matter how large T is. That is the QCFS threshold not learning bug. If BatchNorm is still live after IF replace, the affine that used to sit on continuous activations now sits on spike counts, and raising T will not put the mean back. That is the folding page: batchnorm folding SNN. Sweep T after those two are healthy. Sweeping T first is how people burn a night and write a false limitation.

A second coding family uses time-to-first-spike or other temporal codes. Those codes can in principle decide before T expires. Conversion from a static ReLU CNN is not automatically that family. NeuroCUDA's published path is QCFS then IF then BPTT. Do not advertise a temporal-code latency number unless you measured time-to-decision on that path. This page's T is the window length of the converted IF network.

Membrane integration and network depth

Rate bins are the first half of T. The second half is travel time. An integrate-and-fire unit adds input, compares to threshold, and (on spike) resets. The next layer cannot fire until it receives spikes. In a deep stack, information is a wave. If the wave has not reached the classifier when you stop the clock, the readout is noise or a bias toward classes that fire early for the wrong reason.

Skip connections change the wave, they do not remove it. A residual add is a merge of two streams that must both have had enough time to produce spikes, or one branch is silent and the add is a different function than the ANN. That is why residual conversion is a compiler problem (see the ResNet-18 SNN conversion tutorial) and a T problem at the same time. The tutorial's job is skip-connection execution and the 94.61% protocol. This page's job is why that protocol chose a long enough window rather than T=8 by default.

Shallow nets need less travel time. A three-layer N-MNIST CNN has a short path from sensor-like input to logits. Spikes do not have to climb eighteen residual blocks. Event frames already vary over time, so the membrane is not starting from a DC current that must be integrated from zero every sample. Those two facts, not a marketing preference for "low latency SNNs," are why N-MNIST conversions often look healthy at smaller T than CIFAR ResNets.

Leaky IF versus IF also changes the integration story. QCFS is matching a static ReLU, which has no leak. NeuroCUDA's conversion target is IF. Adding a leak and then complaining that T=8 is "not enough" is mixing neuron models. You can study LIF after conversion. Do not attribute a LIF-plus-T=8 number to the published IF table in paper.pdf.

Reset policy is not T, but it interacts with T. If membrane state is not reset between independent samples, residual charge from sample A votes on sample B. Accuracy then looks like chance, and raising T can make it worse by integrating more garbage. Check reset before you double T. The checklist lives on SNN accuracy drop after conversion.

How SNN timesteps T trade accuracy, latency, and energy

The three-way tradeoff is real. The units are easy to mix up. Keep them separate or the sweep is theater.

Accuracy

Accuracy is test-set classification against the ANN baseline on the same loader. Published software-backend numbers, and only those numbers:

SetupANNSNNT in the claim
N-MNIST, 3-layer CNN99.70%99.88% ± 0.02%Event path; not CIFAR T=32
ResNet-18 / CIFAR-1095.56% ± 0.11%94.61% ± 0.14%T=32 software backend

Those figures come from the technical report. They are GPU/CPU software-backend results. They are not SpiNNaker on-chip accuracy. They are not Loihi silicon. If your sweep at T=8 on ResNet-18 is 20 points below 94.61%, you have a measurement, not a contradiction of the paper, unless you used the paper's T.

Latency

Latency for a converted IF network is, to first order, T sequential membrane updates plus the cost of the weighted sums at each step. On a GPU the weighted sums are dense kernels. Wall-clock latency then scales with T more or less linearly if kernels are similar, plus a constant for data load. That GPU wall clock is a valid latency number for GPU deployment. It is not a neuromorphic latency number. Time-to-first-correct-class can be smaller than T if you read out early; conversion does not give you that for free. If you stop at step 12 of a T=32 network, say so.

Energy

Energy is where papers get dishonest. On an event-driven chip, energy tracks synaptic events: spikes times fan-out, inside a window of length T. Sparsity (fraction of neuron-timesteps without a spike) is a proxy, not a joule. NeuroCUDA reports roughly 93.7% sparsity on ResNet-18/CIFAR-10 on the software backend. That number does not become millijoules until someone measures a chip. On a GPU, energy tracks dense FLOPs and memory traffic. A sparse spike tensor that still launches a dense conv still pays the dense conv. GPU time is not Loihi energy. Loihi 2 in this stack is an IF-neuron simulator, not Intel silicon. SpiNNaker-1 confirmation is EBRAINS jobs #420148 and #420186, a 2-neuron smoke test, not ResNet-on-chip. If you need those labels in a citation, use cite NeuroCUDA.

Field context for CUDA simulators versus this compiler is neuromorphic CUDA. FPGA C++ generation is a proof of concept, not a bitstream, on NeuroCUDA FPGA HLS. Akida status is honest non-claims on NeuroCUDA Akida. None of those pages turns a T sweep on a GPU into a chip energy table.

Why N-MNIST often uses fewer steps than CIFAR ResNet

This is the comparison people skip when they paste T=32 everywhere. N-MNIST is neuromorphic MNIST recorded with a DVS camera: asynchronous polarity events on a 34×34 sensor. It is not RGB CIFAR. It is not static MNIST pixels. The HowTo is N-MNIST SNN conversion. Three structural facts cut the T the network needs:

  1. The input is already spikes (or spike-like tensors). Conversion is not starting from a photograph that must be turned into a DC current and integrated from silence. Temporal contrast is in the data. The membrane sees change early.
  2. The published CNN is shallow. Three layers. Travel time is short. Residual merge timing is not the bottleneck.
  3. The decision is easy relative to CIFAR-10. Digit classes on event MNIST leave more accuracy headroom. The SNN can even sit slightly above the ANN (99.88% vs 99.70%) on the software backend. That is a published result, not a reason to claim SNNs always beat ANNs.

CIFAR-10 plus ResNet-18 is the opposite shape. Static 32×32 color images, presented as constant input over T. Eighteen-layer residual graph. Ten object classes with real visual overlap. Rate-code reconstruction has to be fine, and the spike wave has to finish. T=32 is the documented operating point that sits next to 94.61%. It is not "because ResNet uses 32" as a tribal rule. It is because that protocol was the one measured. If you run T=8 on that graph, you are asking a deep residual IF network to reconstruct ReLUs with eight bins and a short travel window. Maybe it works on your seed. Maybe it collapses. Measure. Do not cite 94.61% next to a T=8 run.

Event cameras in robotics add a third shape: variable-rate streams, ROS2, reset between unrelated frames. That is not this page's HowTo. See neuromorphic CUDA for the CUDA map and keep T honest there too: a bag-file demo does not inherit CIFAR T.

Sweep T, evaluate, pick

The HowTo is empirical. Install, convert at each candidate T, evaluate at that T, pick the smallest T that meets the constraint you actually have (accuracy floor, latency cap, or a measured energy budget on a named device).

pip install neurocuda
# optional backends:
pip install neurocuda[all]

Load the same ANN you will convert. Keep the ANN checkpoint. You need it as the regression baseline at every T.

import time
import torch
import neurocuda

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.eval()
model.to(device)

ann_acc = neurocuda.evaluate(model, test_loader, device=device)
print(f"ANN baseline: {ann_acc:.2%}")

rows = []
for T in (8, 16, 32):
    snn, meta = neurocuda.convert(
        model,
        calib_loader,
        timesteps=T,
        device=device,
    )
    neurocuda.compile(snn, target="gpu")
    t0 = time.perf_counter()
    snn_acc = neurocuda.evaluate(snn, test_loader, device=device)
    gpu_s = time.perf_counter() - t0
    sparsity = neurocuda.measure_sparsity(snn, test_loader, device=device)
    rows.append((T, snn_acc, gpu_s, sparsity))
    print(f"T={T}: acc={snn_acc:.2%}  gpu_s={gpu_s:.2f}  sparsity={sparsity:.1%}")

# Pick: smallest T whose accuracy is within your allowed gap of ann_acc.
# gpu_s is GPU wall time. It is not Loihi energy.

convert() runs QCFS calibration, BatchNorm folding, IF replace, and BPTT finetune. That is why each T gets its own convert. A cheaper diagnostic (raise T only at eval, no finetune) can tell you "undersampled," but it is not the number you publish as the T=8 model. If you already converted at T=32 and want extra BPTT at another T, that is a finetune experiment: say so. The default API path remains snn, meta = neurocuda.convert(model, calib_loader) then neurocuda.compile.

Folding belongs before IF replace at every T. If you are inspecting the ANN graph yourself, call neurocuda.fold_batchnorm and confirm BatchNorm keys are gone. Details are the sibling post, not a second theory hub: batchnorm folding SNN.

How to pick after the table exists:

  1. Fix an accuracy floor relative to the ANN, for example "within 1.5 points" or "not below 90%." The floor is yours. The published ResNet gap is 0.95 points at T=32. Do not invent a new CIFAR mean in this article.
  2. Among T values that clear the floor, take the smallest. That is the latency-aware pick for a sequential IF window.
  3. If none clear the floor, debug reset, folding, and lambda before you jump to T=64. Chance-level accuracy is almost never "need T=256."
  4. If you have a real energy log on a named chip, use it. If you have GPU joules from nvidia-smi, label them GPU joules. If you have neither, stop at sparsity and wall time.

Reproducible containers for CI sweeps belong on neurocuda docker. Notebook sweeps belong on Colab with Drive checkpoints. Local CUDA wheels belong on the pip guide. Do not merge those environments into one T number without naming the machine.

What not to claim

Write these on a sticky note before you put T in a slide:

Sweep T=8, 16, 32. Convert at T, evaluate at T. Quote T next to accuracy. GPU milliseconds are not Loihi millijoules. A 2-neuron SpiNNaker job is not ResNet energy.

Theory without a vendor page is /ann-to-snn. This URL will not clone it. Conversion tools compared stay on their own post. Training from scratch is NeuroCUDA vs SpikingJelly, which uses T as a training unroll, a different job.

Worked decision patterns (not new accuracy rows)

These patterns use only published numbers plus the logic of the sweep. They do not add a fictional ImageNet score.

You need the published ResNet figure

Use T=32, CIFAR-10, the documented seeds, the residual executor. Follow the ResNet tutorial and the reproduce page. Your sweep can still include 8 and 16 as diagnostics. The number you put next to "NeuroCUDA ResNet-18" is the T=32 software-backend result: 94.61% ± 0.14% vs ANN 95.56%.

You have N-MNIST or another event set

Start the sweep at 8 and 16. Compare to the ANN on the same event tensors. The published SNN is 99.88% ± 0.02% vs ANN 99.70%. If T=8 already sits on that plateau, spending T=32 is latency you are not buying. If T=8 is chance, check prep_nmnist tensors before you assume you need ResNet-sized T.

You have a latency cap of N steps

Convert at T=N (and maybe at 2N as a diagnostic). If accuracy misses the floor, the fix may be calibration or folding, not secretly running T=2N at deploy. Deploy T must match convert T unless you measured early readout.

You want an energy story

Measure on the device you name. Until then, report sparsity and GPU wall time as GPU wall time. Point readers at the Loihi-versus-GPU energy write-up for modeled vs measured language. Do not paste that language onto a T=8 Colab cell.

Runnable sweep you can paste

Minimal path from a trained ReLU module. Replace loaders with yours. CIFAR normalize constants belong on CIFAR; N-MNIST uses examples/prep_nmnist.py in the repo.

import copy
import neurocuda

def sweep_timesteps(model, calib_loader, test_loader, ts=(8, 16, 32)):
    model = copy.deepcopy(model).eval()
    out = []
    for T in ts:
        snn, meta = neurocuda.convert(model, calib_loader, timesteps=T)
        neurocuda.compile(snn, target="gpu")
        acc = neurocuda.evaluate(snn, test_loader)
        out.append({"T": T, "acc": acc, "meta": meta})
    return out

# pick: min T with acc >= floor
def pick_T(rows, floor):
    ok = [r for r in rows if r["acc"] >= floor]
    return min(ok, key=lambda r: r["T"]) if ok else None

That is the whole product loop: sweep, evaluate, pick. Citation for the compiler: Krishna Santosh Varma, QuantaraCore Technologies LLP, MIT, github.com/Krishnav1/neurocuda.

Cluster map so T does not cannibalize other URLs

Use this page for the tradeoff. Use the others for their jobs:

Primary sources

  1. NeuroCUDA technical report, quantaracore.in/neurocuda/paper.pdf
  2. NeuroCUDA source, github.com/Krishnav1/neurocuda (MIT)
  3. Product hub, quantaracore.in/neurocuda
  4. Bu et al., QCFS, ICLR 2023 (scale that T spends)
  5. ResNet-18 protocol page, ResNet-18 SNN conversion tutorial

Frequently asked questions

What are SNN timesteps T?

SNN timesteps T is the discrete window over which an integrate-and-fire network presents an input, integrates membrane potential, and emits spikes. In NeuroCUDA conversion it is also the protocol length used during QCFS calibration and BPTT finetune. T is a budget, not a slogan.

Should I use T=8, T=16, or T=32?

Sweep those three values on your model and data. T=32 is the published NeuroCUDA protocol for ResNet-18 on CIFAR-10 (94.61% ± 0.14% SNN vs 95.56% ANN). N-MNIST often needs fewer steps because the input is already events and the CNN is shallow. Pick the smallest T that meets your accuracy floor.

How do I sweep SNN timesteps T in NeuroCUDA?

Install with pip install neurocuda. For each T in {8, 16, 32} call snn, meta = neurocuda.convert(model, calib_loader) with that timesteps setting, then compile and evaluate. Convert at T, evaluate at T. Do not convert at 32 and score at 8 and call it the same model.

Why does N-MNIST often use fewer steps than a CIFAR ResNet?

N-MNIST is event-camera data with polarity events already in time. A 3-layer CNN is shallow, so spikes do not have to climb 18 residual blocks. CIFAR-10 frames are static; conversion presents them as constant current over T. Residual depth plus rate-code reconstruction is why the published ResNet protocol uses T=32.

Is GPU wall time the same as Loihi energy?

No. GPU time is dense kernel time on a CUDA device. Loihi 2 in NeuroCUDA is an IF-neuron simulator, not Intel silicon. Do not convert milliseconds on a GPU into millijoules on Loihi. SpiNNaker jobs #420148 and #420186 are a 2-neuron smoke test, not ResNet-on-chip energy.

Does raising T always raise accuracy?

Often, until the rate code has enough bins and membranes have time to cross threshold through depth. After that, extra T spends latency. If accuracy is still chance at T=32, the bug is usually reset, unfolded BatchNorm, or frozen QCFS thresholds, not a missing T=128.

Can I convert once at T=32 and evaluate at T=8?

That is a different experiment. convert() calibrates and BPTT-finetunes at the T you pass. Evaluating a T=32 network in an 8-step window under-samples a model that was not trained for that window. For a fair pick, convert (or at least finetune) at each candidate T.

What published accuracies attach to which T?

ResNet-18 CIFAR-10 SNN 94.61% ± 0.14% vs ANN 95.56% is the T=32 software-backend result. N-MNIST SNN 99.88% ± 0.02% vs ANN 99.70% is a different dataset and a shallow CNN. Quote T with the number. Source: paper.pdf.

Does sparsity replace an energy measurement?

No. Sparsity is the fraction of neuron-timesteps without a spike. It is a useful proxy for event-driven chips. A GPU still runs dense matmuls. Measure energy on the device you name, or do not name a joule.

Where is the NeuroCUDA source for this HowTo?

https://github.com/Krishnav1/neurocuda, MIT license. Author Krishna Santosh Varma, QuantaraCore Technologies LLP. Hub: /neurocuda. Install: pip install neurocuda.

Next: pip install neurocuda · sweep T=8, 16, 32 · Product page · PDF report · Fold BatchNorm before IF