Site tensor types for lattice field theory
These types represent tensors at a single lattice site with compile-time known dimensions. They are designed for use with OpenCL kernel generation, where operations are translated to inline C code.
Types
LocalAddResult[D; R; L; T] = object proxyA*, proxyB*: LocalSiteProxy[D, R, L, T] isSubtraction*: bool
- Result of local tensor addition/subtraction
LocalMulResult[D; R; L; T] = object proxyA*, proxyB*: LocalSiteProxy[D, R, L, T]
- Result of local tensor multiplication
LocalScalarAddResult[D; R; L; T] = object proxy*: LocalSiteProxy[D, R, L, T] scalar*: T
- Result of local tensor + scalar
LocalScalarMulResult[D; R; L; T] = object proxy*: LocalSiteProxy[D, R, L, T] scalar*: T
- Result of local scalar * tensor
LocalSiteProxy[D; R; L; T] = object hostPtr*: pointer siteOffset*: int shape*: array[R, int] elemsPerSite*: int
- Proxy type returned by LocalTensorField for "for all" loops Provides CPU-only access to tensor sites without GPU acceleration
Mat[N; M; T] = object data*: array[N * M, T]
- A matrix with compile-time known dimensions N x M and element type T Storage is row-major: datai * M + j = element at row i, column j
MatAddResult[L; T] = object proxyA*, proxyB*: TensorSiteProxy[L, T] isSubtraction*: bool when UseOpenMP: computedA*, computedB*: seq[T] hasComputedA*, hasComputedB*: bool
- Result of matrix addition/subtraction: mat1n +/- mat2n
MatMulResult[L; T] = object proxyA*, proxyB*: TensorSiteProxy[L, T] when UseOpenMP: computed*: seq[T] hasComputed*: bool
- Result of matrix-matrix multiplication: mat1n * mat2n
MatVecResult[L; T] = object proxyMat*, proxyVec*: TensorSiteProxy[L, T]
- Result of matrix-vector multiplication: matn * vecn
RuntimeSiteData[T] = object data*: seq[T] shape*: seq[int] rank*: int
- Holds actual data for a site tensor - used for CPU fallback with printing
ScalarAddResult[L; T] = object proxy*: TensorSiteProxy[L, T] scalar*: T
- Result of scalar addition: scalar + matn or matn + scalar
ScalarMulResult[L; T] = object proxy*: TensorSiteProxy[L, T] scalar*: T
- Result of scalar multiplication: scalar * matn or matn * scalar
TensorElementProxy[L; T] = object view*: pointer site*: int indices*: array[4, int] numIndices*: int when UseOpenMP: hostPtr*: pointer shape*: seq[int] elemsPerSite*: int
- Proxy type returned by TensorSiteProxy - represents single element at site Used for element-level read/write: mViewn = value
TensorSiteProxy[L; T] = object view*: pointer site*: int runtimeData*: RuntimeSiteData[T] when UseOpenMP: hostPtr*: pointer shape*: seq[int] elemsPerSite*: int hasSimdLayout*: bool simdLayoutPtr*: pointer nSitesInner*: int
- Proxy type returned by TensorFieldView - represents site tensor at index Operations on this proxy generate appropriate OpenCL kernel code Also supports runtime use for printing: stores actual tensor data when accessed
Vec[N; T] = object data*: array[N, T]
- A vector with compile-time known size N and element type T Storage is a flat array of N elements
VecAddResult[L; T] = object proxyA*, proxyB*: TensorSiteProxy[L, T] isSubtraction*: bool when UseOpenMP: computedA*, computedB*: seq[T] hasComputedA*, hasComputedB*: bool
- Result of vector addition/subtraction: vec1n +/- vec2n
Procs
proc `$`[D: static[int]; R: static[int]; L, T](proxy: LocalSiteProxy[D, R, L, T]): string
- Format LocalSiteProxy tensor for printing Scalar: just the value Vector: row format x, y, z Matrix: grid format with Unicode box drawing
proc `$`[L, T](proxy: TensorSiteProxy[L, T]): string
- Convert site tensor to string for debugging. Works both in OpenCL kernels (via macro) and at runtime (via stored data).
proc `$`[T](data: RuntimeSiteData[T]): string
- Format a site tensor nicely for printing Scalar: just the value Vector: column format x, y, z Matrix: grid format
proc `*`[D: static[int]; R: static[int]; L, T](a, b: LocalSiteProxy[D, R, L, T]): LocalMulResult[ D, R, L, T] {.inline.}
proc `*`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; scalar: T): LocalScalarMulResult[D, R, L, T] {.inline.}
proc `*`[D: static[int]; R: static[int]; L, T](scalar: T; proxy: LocalSiteProxy[D, R, L, T]): LocalScalarMulResult[D, R, L, T] {. inline.}
proc `*`[L, T](a, b: TensorSiteProxy[L, T]): MatMulResult[L, T]
proc `*`[L, T](proxy: TensorSiteProxy[L, T]; scalar: T): ScalarMulResult[L, T]
proc `*`[L, T](res: MatAddResult[L, T]; scalar: T): ScalarMulResult[L, T]
proc `*`[L, T](res: MatMulResult[L, T]; scalar: T): ScalarMulResult[L, T]
proc `*`[L, T](scalar: T; proxy: TensorSiteProxy[L, T]): ScalarMulResult[L, T]
proc `*`[L, T](scalar: T; res: MatAddResult[L, T]): ScalarMulResult[L, T]
proc `*`[L, T](scalar: T; res: MatMulResult[L, T]): ScalarMulResult[L, T]
proc `*`[N: static[int]; K: static[int]; M: static[int]; T](a: Mat[N, K, T]; b: Mat[K, M, T]): Mat[N, M, T] {.inline.}
- Matrix-matrix multiplication: (N x K) * (K x M) -> (N x M) Ci,j = sum_k Ai,k * Bk,j
proc `*`[N: static[int]; M: static[int]; T](a: T; m: Mat[N, M, T]): Mat[N, M, T] {. inline.}
- Scalar-matrix multiplication
proc `*`[N: static[int]; M: static[int]; T](m: Mat[N, M, T]; a: T): Mat[N, M, T] {. inline.}
- Matrix-scalar multiplication
proc `+`[D: static[int]; R: static[int]; L, T](a, b: LocalSiteProxy[D, R, L, T]): LocalAddResult[ D, R, L, T] {.inline.}
proc `+`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; scalar: T): LocalScalarAddResult[D, R, L, T] {.inline.}
proc `+`[D: static[int]; R: static[int]; L, T](scalar: T; proxy: LocalSiteProxy[D, R, L, T]): LocalScalarAddResult[D, R, L, T] {. inline.}
proc `+`[L, T](a, b: MatAddResult[L, T]): MatAddResult[L, T]
proc `+`[L, T](a, b: MatMulResult[L, T]): MatAddResult[L, T]
proc `+`[L, T](a, b: TensorSiteProxy[L, T]): MatAddResult[L, T]
proc `+`[L, T](a: MatAddResult[L, T]; b: MatMulResult[L, T]): MatAddResult[L, T]
proc `+`[L, T](a: MatAddResult[L, T]; b: TensorSiteProxy[L, T]): MatAddResult[L, T]
proc `+`[L, T](a: MatMulResult[L, T]; b: MatAddResult[L, T]): MatAddResult[L, T]
proc `+`[L, T](a: MatMulResult[L, T]; b: TensorSiteProxy[L, T]): MatAddResult[L, T]
proc `+`[L, T](a: TensorSiteProxy[L, T]; b: MatAddResult[L, T]): MatAddResult[L, T]
proc `+`[L, T](a: TensorSiteProxy[L, T]; b: MatMulResult[L, T]): MatAddResult[L, T]
proc `+`[L, T](proxy: TensorSiteProxy[L, T]; scalar: T): ScalarAddResult[L, T]
proc `+`[L, T](scalar: T; proxy: TensorSiteProxy[L, T]): ScalarAddResult[L, T]
proc `-`[D: static[int]; R: static[int]; L, T](a, b: LocalSiteProxy[D, R, L, T]): LocalAddResult[ D, R, L, T] {.inline.}
proc `-`[L, T](a, b: MatAddResult[L, T]): MatAddResult[L, T]
proc `-`[L, T](a, b: MatMulResult[L, T]): MatAddResult[L, T]
proc `-`[L, T](a, b: TensorSiteProxy[L, T]): MatAddResult[L, T]
proc `-`[L, T](a: MatAddResult[L, T]; b: MatMulResult[L, T]): MatAddResult[L, T]
proc `-`[L, T](a: MatAddResult[L, T]; b: TensorSiteProxy[L, T]): MatAddResult[L, T]
proc `-`[L, T](a: MatMulResult[L, T]; b: MatAddResult[L, T]): MatAddResult[L, T]
proc `-`[L, T](a: MatMulResult[L, T]; b: TensorSiteProxy[L, T]): MatAddResult[L, T]
proc `-`[L, T](a: TensorSiteProxy[L, T]; b: MatAddResult[L, T]): MatAddResult[L, T]
proc `-`[L, T](a: TensorSiteProxy[L, T]; b: MatMulResult[L, T]): MatAddResult[L, T]
proc `[]`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; i, j, k: int): T {.inline.}
- 3D tensor element read: localn
proc `[]`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; i, j: int): T {.inline.}
- Matrix element read: localn
proc `[]`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; i: int): T {.inline.}
- Vector element read: localn
proc `[]`[L, T](proxy: TensorSiteProxy[L, T]; i, j, k: int): TensorElementProxy[ L, T]
proc `[]`[L, T](proxy: TensorSiteProxy[L, T]; i, j: int): TensorElementProxy[L, T]
proc `[]`[L, T](proxy: TensorSiteProxy[L, T]; i: int): TensorElementProxy[L, T]
proc `[]=`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; i, j, k: int; value: T) {.inline.}
- 3D tensor element write: localn = value
proc `[]=`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; i, j: int; value: T) {.inline.}
- Matrix element write: localn = value
proc `[]=`[D: static[int]; R: static[int]; L, T]( proxy: LocalSiteProxy[D, R, L, T]; i: int; value: T) {.inline.}
- Vector element write: localn = value
proc `[]=`[L, T](proxy: TensorSiteProxy[L, T]; i, j, k: int; value: T)
proc `[]=`[L, T](proxy: TensorSiteProxy[L, T]; i, j: int; value: T)
proc `[]=`[L, T](proxy: TensorSiteProxy[L, T]; i: int; value: T)
Templates
template elementType[N: static[int]; M: static[int]; T]( m: typedesc[Mat[N, M, T]]): typedesc
- Get the element type of a Mat
template elementType[N: static[int]; T](v: typedesc[Vec[N, T]]): typedesc
- Get the element type of a Vec
template isMat(T: typedesc): bool
- Check if type is a Mat
template isSiteTensor(T: typedesc): bool
- Check if type is a site tensor (Vec or Mat)
template isVec(T: typedesc): bool
- Check if type is a Vec
template numElements[N: static[int]; M: static[int]; T]( m: typedesc[Mat[N, M, T]]): int
- Get the number of elements in a Mat
template numElements[N: static[int]; T](v: typedesc[Vec[N, T]]): int
- Get the number of elements in a Vec
template storageType(T: typedesc): typedesc
- Get the underlying storage type for a site tensor or scalar For scalars, returns T. For Vec/Mat, returns the element type.