Skip to content

BitLogic Documentation

BitLogic is a modular PyTorch library for differentiable Look-Up Table (LUT) neural networks, built for research and for efficient FPGA deployment.

2026 rewrite — design inspired by torchlogix

BitLogic was rewritten from the ground up to follow the design philosophy of torchlogix by Lino Gerlach et al. — a minimal, torch.nn-native API composed with nn.Sequential. The GroupSum head, the binarization-as-module encoder pattern, and the train/eval mode-switching discipline all come directly from torchlogix. Our warp parametrization implements Gerlach's own WARP-LUTs paper. Full credit is in the README Acknowledgments.

BitLogic Architecture

What's in the box

BitLogic is intentionally small. The public API is a torch.nn-native stack of three things:

  • Encoders — turn continuous data into bits. Two implementations: Thermometer and DistributiveThermometer.
  • Layers — one class, LogicDense, composed of a parametrization (what the LUT is) and connections (which inputs feed each neuron).
  • Heads — reduce layer outputs to task-specific shapes. GroupSum is the default popcount head; GroupedDSP adds a tanh-bounded learnable k×k weight matrix with signed integer quantization at eval time.

Under the hood, LogicDense forwards by gathering lut_rank inputs per neuron via its connection module, then contracting them through the chosen parametrization. The whole model is a plain torch.nn.Sequential.

A ten-line network

import torch
from bitlogic import DistributiveThermometer, LogicDense, GroupSum

enc = DistributiveThermometer(num_bits=8).fit(train_samples)   # (N, 1, 28, 28)

model = torch.nn.Sequential(
    enc,
    torch.nn.Flatten(),
    LogicDense(6272, 64000,
               parametrization="light", lut_rank=4,
               connections="learnable", num_candidates=8),
    LogicDense(64000, 64000,
               parametrization="light", lut_rank=4,
               connections="learnable", num_candidates=8),
    GroupSum(k=10, tau=150),
)

See Quick Start for a complete end-to-end MNIST example.

Choosing a parametrization

Parametrizations are picked by name ("light", "warp", "linear", "polylut", "neurallut", "dwn", "difflogic"). Each implements a different inductive bias over the truth table:

Name What it is Supports lut_rank Notes
light Kronecker-indicator basis 2, 4, 6 Good default. Soft / hard / Gumbel sampling.
warp Walsh–Hadamard basis 2, 4, 6 Fast, smooth.
linear Affine + sigmoid any ≥ 2 Simplest baseline.
polylut Monomial basis (degree D) any ≥ 2 Structured pruning style.
neurallut Tiny MLP per neuron any ≥ 2 No residual init.
dwn Binarized input + EFD gradient 2, 4, 6 Direct LUT lookup.
difflogic Softmax over 16 Boolean ops 2 only Differentiable logic gates.

Full reference: Parametrizations.

Choosing a connection pattern

Kind Trainable? Typical use
fixed no Sparse, random routing (the LogicNets / DLGN default).
learnable yes Per-slot candidate pool with softmax + straight-through argmax. Set num_candidates=-1 to open it up to every input (dense; expensive, exact).

Full reference: Connections.

Getting started

  1. Installation — set up BitLogic with uv.
  2. Quick Start — build and train a LUT network on MNIST.
  3. Examples — runnable MNIST quickstart that matches the Quick Start guide.

Guides

  • Contributing — dev loop, branching, versioning, CI.
  • Examples — the runnable MNIST quickstart.
  • HDL Export — SystemVerilog emit + Yosys NAND2-GE flow.

API Reference


BitLogic © 2025–2026 Simon Jonas Bührer, Andreas Plesner, Till Aczel — ETH Zurich, Distributed Computing Group.