Skip to content

rudraditya21/lattice

Lattice Programming Language

Lattice icon

Lattice is a small scientific computing language aimed at reproducible numerics and statistical workflows. It ships a REPL and embeddable library with:

  • Arithmetic expressions with identifiers, unary minus, calls, assignments, and blocks.
  • Control flow via if/else statements, nested blocks, while loops, for loops, and break/continue.
  • Strict typing with optional annotations and a numeric tower (ints, floats, complex, decimals, rationals) plus tensors.
  • GPU backends: OpenCL, CUDA, HIP, and Metal with BLAS/MPS/CLBlast matmul and dense add/sub paths when available (kernels are used for non-BLAS ops only).
  • Built-in constants pi, e, gamma, inf and math helpers pow, gcd, lcm, abs, sign, mod, floor, ceil, round, clamp, min, max, sum, mean, var, std, transpose, matmul, conv2d, max_pool2d, fft1d.
  • Typed constructors/casts: int(), float(), complex(), decimal(), rational(), tensor(), tensor_values(), tensor_sparse_csr(), tensor_sparse_coo(), tensor_ragged(), to_dense(), to_sparse_csr(), to_sparse_coo(). The project is organized with headers in include/ and sources in src/.

Layout

  • include/ – public headers (lexer/, parser/, runtime/, repl/, builtin/, util/)
  • src/ – implementation (lexer/, parser/, runtime/, repl/, builtin/, main.cpp)
  • tests/ – modular tests under tests/{lexer,parser,runtime,builtin,util,repl} with shared helpers at tests/test_util.* and entry in tests/main.cpp
  • CMakeLists.txt – build configuration
  • .clang-format – formatting rules
  • .gitignore – repository hygiene

Build

cmake -S . -B build
cmake --build build

Run REPL

./build/lattice

Example session (typed values, complex/tensors):

lattice> x = 3
3
lattice> x + 2
5
lattice> complex(1, -2)
1+-2i
lattice> t = tensor(2, 2, 1)
tensor[dense][2x2]<f64>
lattice> tensor_values((1,2,3))
tensor[dense][3]<i32>
lattice> tensor_values(((1,2),(3,4)))
tensor[dense][2x2]<i32>
lattice> matmul(tensor_values(((1,2),(3,4))), tensor_values(((1,),(1,))))
tensor[dense][2x1]<f64>
lattice> var(tensor_values((1,3)))
1
lattice> fft1d(tensor_values((1,0,1,0)))
(tensor[dense][4]<f64>, tensor[dense][4]<f64>)
lattice> exit

GPU Backend (experimental)

LATTICE_BACKEND=auto ./build/lattice
LATTICE_BACKEND=cuda ./build/lattice
LATTICE_BACKEND=hip ./build/lattice
LATTICE_BACKEND=metal ./build/lattice
LATTICE_BACKEND=opencl ./build/lattice
LATTICE_GPU_SMOKE_TEST=1 ctest --test-dir build -R lattice_tests

Benchmarks

Microbenchmarks are available via ./build/lattice_bench. For R vs Lattice matmul comparisons, see benchmarks/scripts/compare_r_lattice_matmul.sh.

Matmul (1024x1024x1024, f64)

Host: macOS (Intel Core i5 2.4 GHz, Intel Iris Plus Graphics 655).

Command:

./build/lattice_bench --backend cpu --ops matmul --matmul-size 1024 --warmup 1 --iters 2

Results:

Tool/Backend Latency (s) Bandwidth (GB/s) GFLOP/s Notes
R (base %*%) 0.0185 N/A 116.080 Median over 2 iterations, warmup 1.
Lattice CPU 0.0146 1.72778 147.437 Same parameters as above.
Lattice Metal N/A N/A N/A Metal backend unavailable on this host (fell back to OpenCL CPU device).

Tensor Ops and Shapes

  • Creation:
    • Dense: tensor(d0, d1, ..., fill) for row-major dense; tensor_values((1,2,3)) for 1D; nested tuples for nD (e.g., tensor_values(((1,2),(3,4)))). Square-bracket list literals are not supported; tuples are the only literal collection.
    • Sparse: tensor_sparse_csr((rows, cols), indptr_tuple, indices_tuple, values_tuple), tensor_sparse_coo((rows, cols), rows_tuple, cols_tuple, values_tuple).
    • Ragged: tensor_ragged(row_splits_tuple, values_tuple).
    • Conversion: to_dense, to_sparse_csr, to_sparse_coo.
  • Elementwise ops: + - * / support dense⊕dense (broadcast), dense⊕sparse (densifies sparse), sparse⊕sparse (same format/shape), ragged⊕ragged (matching row_splits). Other mixes error with guidance.
  • Reductions: sum, mean, var, std reduce all elements; missing sparse entries count as zero; ragged reduces flat values. Results are cast to the tensor element dtype.
  • Linear algebra: matmul (2D only, requires BLAS/MPS/CLBlast) and transpose (2D only) on dense tensors; sparse inputs are densified first. More ops (solve/QR/LU/SVD) are not implemented yet.
  • Convolution/pooling: conv2d(input2d, kernel2d) with valid padding only; max_pool2d(input2d, kh, kw) with integer kernel sizes, no stride/dilation options yet.
  • FFT: fft1d returns a tuple (real_tensor, imag_tensor); implementation is naive O(n^2) and dense-only.

Control Flow

  • if/else: if (condition) { expr_or_stmt } else { other_stmt }. Conditions must be bool.
  • Comparisons: ==, !=, >, <, >=, <= yield booleans (true/false).
  • Boolean literals: true, false; arithmetic on bools is allowed (1/0) but control-flow requires bool.
  • while: while (condition) body. Condition re-evaluated each iteration.
  • for: for (init; condition; increment) body. Any of the three clauses may be empty (e.g., for (; cond; )).
  • break / continue: only valid inside loops; continue skips to the next iteration; break exits the nearest loop. At the REPL top level they print an error.
  • Blocks: { stmt1; stmt2; ... } with optional semicolons after statements.
  • Functions: func name(param1, param2) { ... } defines a function; return expr; exits with a value. Without return, the last statement value is used if present, otherwise 0. Functions may carry type annotations on params/returns; annotated boundaries are enforced, unannotated code remains dynamic.

Types and Promotion

  • Numeric tower: i8/i16/i32/i64/u8/u16/u32/u64, f16/bfloat16/f32/f64, complex64/complex128, decimal, rational, bool.
  • Aggregates: tensor (dense/sparse CSR/COO/ragged) with shape/row-major strides and element dtype (default f64), tuples, records, strings.
  • Constructors/casts: int, float, complex, decimal, rational, tensor, tensor_values, sparse/ragged tensor constructors, to_dense, to_sparse_*.
  • Promotion: complex > float > int; signed/unsigned width-aware; decimal↔decimal and rational↔rational only; tensor ops promote element dtype; implicit narrowing is rejected (use cast/constructors).
  • Math builtins enforce dtype expectations (e.g., gcd/lcm require integers, abs handles complex/decimal/rational, pow supports complex).

Tests

cmake --build build
ctest --test-dir build

Tests exercise parsing and evaluation (arithmetic, identifiers, constants, builtins, and error paths).

Formatting

Use clang-format with the provided configuration:

find include src CUDA HIP OpenCL Metal \( -name '*.h' -o -name '*.hpp' -o -name '*.hh' -o -name '*.hxx' -o -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.cxx' -o -name '*.mm' -o -name '*.cu' -o -name '*.hip' -o -name '*.cl' -o -name '*.metal' \) -print0 | xargs -0 clang-format -i

About

Lattice Programming Language

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors