LocalTensorField - Rank-Local Host-Memory Tensor Fields
This module provides LocalTensorField[D,R,L,T], which represents the portion of a distributed TensorField that resides in host memory on the current MPI rank. It is created by down-casting a global tensor via newLocalTensorField.
The data pointer points directly into Global Arrays memory obtained via NGA_Access. Any writes through data immediately modify the underlying GA — no explicit copy-back is needed. Because the GA has ghost-padded strides, a precomputed siteOffsets lookup table maps each lexicographic site index to its flat offset in the padded memory so that data[siteOffsets[site] + e] reaches element e of the given site.
Key operations:
- Construction: newLocalTensorField obtains a direct pointer to rank-local GA memory and precomputes siteOffsets
- Element access: [] / []= for per-element and per-site reads and writes
- Arithmetic: site-level +, -, *, compound +=, -= on vector and matrix payloads
- Copy / zero: copy, zero for bulk operations
- Norm: norm2 computes the local Euclidean norm
Example
var field = lat.newTensorField([3, 3]): Complex64 var local = field.newLocalTensorField() for n in all 0..<local.numSites(): var site = local.getSite(n) site[0, 0] = 1.0 # writes go directly to GA — no flush required
Types
HostStorage[T] = ptr UncheckedArray[T]
LocalTensorField[D; R; L; T] = object lattice*: L localGrid*: array[D, int] shape*: array[R, int] when isComplex32(T): data*: HostStorage[float32] elif isComplex64(T): data*: HostStorage[float64] else: data*: HostStorage[T] hasPadding*: bool siteOffsets*: seq[int] ## precomputed flat offset for each lex site ## real elements per site (product(shape) * complexFactor) ## product of localGrid
-
Local tensor field on host memory
Represents a local tensor field on host memory defined on a lattice with specified dimensions and data type.
The data pointer points directly into GA memory via NGA_Access. Writes through data immediately modify the underlying Global Array. Because GA inner dimensions have ghost padding, a siteOffsets lookup table maps lexicographic site index → flat offset in padded memory: data[siteOffsets[site] + e] reaches element e of that site.
Procs
proc `[]`[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: LocalTensorField[D, R, L, T]; idx: int): T {.inline.}
- Element access by flat index
proc `[]=`[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: var LocalTensorField[D, R, L, T]; idx: int; value: T) {.inline.}
- Element assignment by flat index
proc `[]=`[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: var LocalTensorField[D, R, L, T]; site: int; value: LocalAddResult[D, R, L, T]) {.inline.}
- Site-level addition/subtraction: localn = localAn + localBn
proc `[]=`[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: var LocalTensorField[D, R, L, T]; site: int; value: LocalMulResult[D, R, L, T]) {.inline.}
- Site-level matrix multiplication: localn = localAn * localBn
proc `[]=`[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: var LocalTensorField[D, R, L, T]; site: int; value: LocalScalarAddResult[D, R, L, T]) {.inline.}
- Site-level scalar add: localn = localAn + scalar
proc `[]=`[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: var LocalTensorField[D, R, L, T]; site: int; value: LocalScalarMulResult[D, R, L, T]) {.inline.}
- Site-level scalar multiply: localn = scalar * localAn
proc `[]=`[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: var LocalTensorField[D, R, L, T]; site: int; value: LocalSiteProxy[D, R, L, T]) {.inline.}
- Copy a site from one proxy to another
proc getSite[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: LocalTensorField[D, R, L, T]; site: int): LocalSiteProxy[D, R, L, T] {. inline.}
- Get a site proxy for the given site index (for "for all" loops)
proc newLocalTensorField[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: TensorField[D, R, L, T]; padded: bool = false): LocalTensorField[D, R, L, T]
-
Create a new local tensor field from a global tensor field
Obtains a direct pointer into rank-local GA memory via NGA_Access and precomputes a siteOffsets lookup table that maps each lexicographic site index to its flat offset in the padded GA memory. Writes through data immediately modify the GA — no explicit copy-back is needed.
proc numElements[D: static[int]; R: static[int]; L: Lattice[D]; T]( view: LocalTensorField[D, R, L, T]): int {.inline.}
- Returns the total number of elements (sites * elements per site)
proc numGlobalSites[D: static[int]; R: static[int]; L: Lattice[D]; T]( view: LocalTensorField[D, R, L, T]): int {.inline.}
- Returns the total number of lattice sites in the tensor field view
proc numSites[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: LocalTensorField[D, R, L, T]): int {.inline.}
- Returns the number of sites (for use with "for all" loops)
proc tensorElementsPerSite[D: static[int]; R: static[int]; L: Lattice[D]; T]( tensor: LocalTensorField[D, R, L, T]): int {.inline.}
- Returns the number of tensor elements per site