qlat_utils.types — Element Type Descriptors and Buffer Protocol Support¶
Source: qlat-utils/qlat_utils/types.pyx
Note: Update this document when updating the source file.
Outline¶
Overview¶
types defines the Python-level type descriptors for the fundamental data types used in lattice QCD calculations. It provides:
Buffer— a Cython-level implementation of the Python buffer protocol (__getbuffer__/__releasebuffer__) that allows C++ memory to be exposed as NumPy-compatible buffers without copying.ElemTypeclass hierarchy — a family of descriptor classes, each encoding the shape, itemsize, format string, and byte-size of a specific C++ lattice type (e.g.,ColorMatrix,WilsonMatrix,ComplexD,RealD, etc.).
These types serve as metadata bridges between C++ field storage and Python’s buffer/NumPy ecosystem.
Python access:
import qlat_utils as q
Buffer Class¶
cdef class Buffer:
def __cinit__(self, object obj=None, int ndim=1, int itemsize=1,
char* fmt=NULL, char* buf=NULL)
A Cython extension type that implements the Python buffer protocol. Instances are not typically created directly by users; they are used internally by field types to expose their data as buffer-compatible objects.
Constructor Parameters¶
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Parent object that owns the memory. Its |
|
|
|
Number of dimensions |
|
|
|
Size in bytes of a single element |
|
|
|
Format string for the buffer protocol (e.g. |
|
|
|
Pointer to the raw memory |
Internal Methods¶
Method |
Description |
|---|---|
|
Populate a |
|
Set the size of dimension |
|
Compute C-contiguous strides from the current shape |
|
Return total byte length ( |
Buffer Protocol¶
Buffer implements __getbuffer__ and __releasebuffer__, making it compatible with memoryview, np.asarray(), and any Python API that accepts the buffer protocol. When the buffer is released, the parent object’s release_buffer() method is called.
ElemType Hierarchy¶
ElemType is the base class for all element type descriptors. Each subclass encodes the metadata for a specific C++ lattice data type.
class ElemType:
name = ""
All subclasses provide the following class-level attributes:
Attribute |
Type |
Description |
|---|---|---|
|
|
Human-readable type name |
|
|
Total byte size of the C++ type |
All subclasses also provide the following Python-accessible static methods (wrappers around the internal cdef methods):
Method |
Return Type |
Description |
|---|---|---|
|
|
Buffer protocol format string (e.g., |
|
|
Byte size of one scalar element |
|
|
Number of dimensions |
|
|
Dimension sizes |
|
|
Total byte size of the type |
Matrix Types¶
These types represent 2D matrix structures used in lattice QCD calculations. All use ComplexD (complex double, 'Zd') as their scalar element type, so an item occupies 16 bytes.
ElemTypeColorMatrix¶
3×3 complex color matrix. Used for SU(3) gauge links.
Property |
Value |
|---|---|
|
|
|
|
|
|
|
16 bytes |
|
144 bytes |
ElemTypeWilsonMatrix¶
12×12 complex Wilson (Dirac-spinor × color) matrix.
Property |
Value |
|---|---|
|
|
|
|
|
|
|
16 bytes |
|
2304 bytes |
ElemTypeNonRelWilsonMatrix¶
6×6 complex non-relativistic Wilson matrix.
Property |
Value |
|---|---|
|
|
|
|
|
|
|
16 bytes |
|
576 bytes |
ElemTypeIsospinMatrix¶
2×2 complex isospin matrix.
Property |
Value |
|---|---|
|
|
|
|
|
|
|
16 bytes |
|
64 bytes |
ElemTypeSpinMatrix¶
4×4 complex Dirac spin matrix.
Property |
Value |
|---|---|
|
|
|
|
|
|
|
16 bytes |
|
256 bytes |
ElemTypeWilsonVector¶
12-component complex Wilson vector (Dirac spin × color).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
16 bytes |
|
192 bytes |
Scalar Types¶
These types represent scalar (0-dimensional) primitive types.
ElemTypeComplexD¶
Complex double precision (std::complex<double>).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
16 bytes |
ElemTypeComplexF¶
Complex single precision (std::complex<float>).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
8 bytes |
ElemTypeRealD¶
Double precision real (double).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
8 bytes |
ElemTypeRealF¶
Single precision real (float).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
4 bytes |
ElemTypeLong¶
64-bit signed integer (Long).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
8 bytes |
ElemTypeInt¶
32-bit signed integer (int).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
4 bytes |
ElemTypeChar¶
Signed character (char).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
1 byte |
ElemTypeInt64t¶
64-bit signed integer (int64_t).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
8 bytes |
ElemTypeInt32t¶
32-bit signed integer (int32_t).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
4 bytes |
ElemTypeInt8t¶
8-bit signed integer (int8_t).
Property |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
1 byte |
Type Properties Reference¶
Note: The tables below document the full type metadata.
nameandsizeof_mare class attributes.py_format(),py_itemsize(),py_ndim(),py_shape(), andpy_size()are Python-accessible static methods (wrappers around internalcdefmethods).
Matrix Types Summary¶
Type |
Name |
Shape |
Item Format |
Element Size |
Total Size |
|---|---|---|---|---|---|
|
|
|
|
16 B |
144 B |
|
|
|
|
16 B |
2304 B |
|
|
|
|
16 B |
576 B |
|
|
|
|
16 B |
64 B |
|
|
|
|
16 B |
256 B |
|
|
|
|
16 B |
192 B |
Scalar Types Summary¶
Type |
Name |
Format |
Size |
|---|---|---|---|
|
|
|
16 B |
|
|
|
8 B |
|
|
|
8 B |
|
|
|
4 B |
|
|
|
8 B |
|
|
|
4 B |
|
|
|
1 B |
|
|
|
8 B |
|
|
|
4 B |
|
|
|
1 B |
Examples¶
Querying Type Metadata¶
import qlat_utils as q
from qlat_utils.types import ElemTypeColorMatrix, ElemTypeWilsonMatrix, ElemTypeRealD
# ColorMatrix: 3x3 complex double, total size 144 bytes
print(ElemTypeColorMatrix.name) # "ColorMatrix"
print(ElemTypeColorMatrix.sizeof_m) # 144
# WilsonMatrix: 12x12 complex double
print(ElemTypeWilsonMatrix.name) # "WilsonMatrix"
print(ElemTypeWilsonMatrix.sizeof_m) # 2304
# Scalar type
print(ElemTypeRealD.name) # "RealD"
print(ElemTypeRealD.sizeof_m) # 8
Buffer Protocol Usage¶
The Buffer class is used internally by field types. A typical pattern:
import numpy as np
import qlat_utils as q
from qlat_utils.types import Buffer, ElemTypeComplexD
# Buffer is typically created internally by field objects.
# When a field exposes its data via the buffer protocol,
# NumPy can access it without copying:
# arr = np.asarray(field_buffer)
# The parent object controls memory lifetime via release_buffer().
Using ElemType for Array Construction¶
import numpy as np
from qlat_utils.types import ElemTypeColorMatrix
# Construct a zero-filled array matching the ColorMatrix layout
# ColorMatrix is 3x3 complex double (sizeof_m = 144 bytes)
shape = (3, 3)
dtype = np.complex128 # matches 'Zd' format
mat = np.zeros(shape, dtype=dtype)
print(mat.nbytes) # 144, matches ElemTypeColorMatrix.sizeof_m
Querying Type Properties via Python-Accessible Methods¶
All ElemType subclasses expose py_format(), py_itemsize(), py_ndim(),
py_shape(), and py_size() as static methods callable from Python:
from qlat_utils.types import ElemTypeColorMatrix, ElemTypeWilsonMatrix
from qlat_utils.types import ElemTypeComplexD, ElemTypeRealD, ElemTypeLong
# ColorMatrix: 3x3 complex double
assert ElemTypeColorMatrix.py_ndim() == 2
assert ElemTypeColorMatrix.py_shape() == (3, 3)
assert ElemTypeColorMatrix.py_itemsize() == 16
assert ElemTypeColorMatrix.py_size() == 144
assert ElemTypeColorMatrix.py_format() == 'Zd'
# WilsonMatrix: 12x12 complex double
assert ElemTypeWilsonMatrix.py_ndim() == 2
assert ElemTypeWilsonMatrix.py_shape() == (12, 12)
assert ElemTypeWilsonMatrix.py_itemsize() == 16
assert ElemTypeWilsonMatrix.py_size() == 2304
# Scalar types have ndim == 0 and empty shape
assert ElemTypeComplexD.py_ndim() == 0
assert ElemTypeComplexD.py_shape() == ()
assert ElemTypeComplexD.py_itemsize() == 16
assert ElemTypeComplexD.py_size() == 16
assert ElemTypeRealD.py_ndim() == 0
assert ElemTypeRealD.py_format() == 'd'
assert ElemTypeRealD.py_itemsize() == 8
assert ElemTypeLong.py_ndim() == 0
assert ElemTypeLong.py_format() == 'q'
assert ElemTypeLong.py_itemsize() == 8
Building a NumPy Array from Type Metadata¶
Use the Python-accessible methods to programmatically construct arrays whose layout matches a given ElemType, without hardcoding shape or dtype:
import numpy as np
from qlat_utils.types import ElemTypeSpinMatrix, ElemTypeWilsonVector
fmt_to_dtype = {
'Zd': np.complex128,
'Zf': np.complex64,
'd': np.float64,
'f': np.float32,
'q': np.int64,
'i': np.int32,
'b': np.int8,
}
def make_array(elem_type, count):
dtype = fmt_to_dtype[elem_type.py_format()]
shape = (count,) + elem_type.py_shape()
return np.zeros(shape, dtype=dtype)
# 10 SpinMatrix elements: shape (10, 4, 4), dtype complex128
arr = make_array(ElemTypeSpinMatrix, 10)
assert arr.shape == (10, 4, 4)
assert arr.dtype == np.complex128
assert arr.nbytes == 10 * ElemTypeSpinMatrix.py_size()
# 5 WilsonVector elements: shape (5, 12), dtype complex128
vec = make_array(ElemTypeWilsonVector, 5)
assert vec.shape == (5, 12)
assert vec.nbytes == 5 * ElemTypeWilsonVector.py_size()
Iterating Over All ElemType Subclasses¶
import numpy as np
from qlat_utils.types import (
ElemTypeColorMatrix, ElemTypeWilsonMatrix, ElemTypeNonRelWilsonMatrix,
ElemTypeIsospinMatrix, ElemTypeSpinMatrix, ElemTypeWilsonVector,
ElemTypeComplexD, ElemTypeComplexF, ElemTypeRealD, ElemTypeRealF,
ElemTypeLong, ElemTypeInt, ElemTypeChar, ElemTypeInt64t,
ElemTypeInt32t, ElemTypeInt8t,
)
all_types = [
ElemTypeColorMatrix, ElemTypeWilsonMatrix, ElemTypeNonRelWilsonMatrix,
ElemTypeIsospinMatrix, ElemTypeSpinMatrix, ElemTypeWilsonVector,
ElemTypeComplexD, ElemTypeComplexF, ElemTypeRealD, ElemTypeRealF,
ElemTypeLong, ElemTypeInt, ElemTypeChar, ElemTypeInt64t,
ElemTypeInt32t, ElemTypeInt8t,
]
for t in all_types:
assert t.py_size() == t.sizeof_m, f"{t.name}: py_size()={t.py_size()} != sizeof_m={t.sizeof_m}"
if t.py_ndim() > 0:
expected = t.py_itemsize() * int(np.prod(t.py_shape()))
else:
expected = t.py_itemsize()
assert t.py_size() == expected, f"{t.name}: py_size()={t.py_size()} != expected={expected}"
Verifying Consistency Between Properties¶
import numpy as np
from qlat_utils.types import (
ElemTypeColorMatrix, ElemTypeWilsonMatrix, ElemTypeNonRelWilsonMatrix,
ElemTypeIsospinMatrix, ElemTypeSpinMatrix, ElemTypeWilsonVector,
ElemTypeComplexD, ElemTypeComplexF, ElemTypeRealD, ElemTypeRealF,
ElemTypeLong, ElemTypeInt, ElemTypeChar, ElemTypeInt64t,
ElemTypeInt32t, ElemTypeInt8t,
)
all_types = [
ElemTypeColorMatrix, ElemTypeWilsonMatrix, ElemTypeNonRelWilsonMatrix,
ElemTypeIsospinMatrix, ElemTypeSpinMatrix, ElemTypeWilsonVector,
ElemTypeComplexD, ElemTypeComplexF, ElemTypeRealD, ElemTypeRealF,
ElemTypeLong, ElemTypeInt, ElemTypeChar, ElemTypeInt64t,
ElemTypeInt32t, ElemTypeInt8t,
]
for t in all_types:
assert t.py_size() == t.sizeof_m, f"{t.name}: py_size()={t.py_size()} != sizeof_m={t.sizeof_m}"
if t.py_ndim() > 0:
expected = t.py_itemsize() * int(np.prod(t.py_shape()))
else:
expected = t.py_itemsize()
assert t.py_size() == expected, f"{t.name}: py_size()={t.py_size()} != expected={expected}"
assert isinstance(t.name, str) and len(t.name) > 0
assert isinstance(t.py_ndim(), int) and t.py_ndim() >= 0
assert isinstance(t.py_shape(), tuple)
assert isinstance(t.py_itemsize(), int) and t.py_itemsize() > 0
assert isinstance(t.py_size(), int) and t.py_size() > 0
assert isinstance(t.py_format(), str) and len(t.py_format()) > 0