io/tensorio

Search:
Group by:

TensorField I/O facilities for reading/writing distributed tensor fields

This module provides I/O operations for TensorField types, handling the conversion between file formats (LIME/SciDAC/QIO) and distributed GlobalArray storage via LocalTensorField intermediaries.

Key features:

  • Read LIME/SciDAC/QIO files into TensorField objects
  • Write TensorField objects to LIME/SciDAC/QIO files
  • Handle parallel I/O with proper site ordering (rank 0 does file I/O)
  • Support for both real and complex tensor data

Example usage:

import io/tensorfield
import tensor/[globaltensor, localtensor]
import lattice

let lattice = newSimpleCubicLattice([16, 16, 16, 32])
var gaugeField = lattice.newTensorField([4, 3, 3]): Complex64

# Read from file
readTensorField(gaugeField, "config.lime")

# Write to file
writeTensorField(gaugeField, "output.lime", "<info>My config</info>")

Types

TensorFieldReader = ref object
  fileInfo*: SciDACFileInfo
  recordInfo*: SciDACRecordInfo
  storedChecksum*: SciDACChecksum
  computedChecksum*: SciDACChecksum
  hasChecksum*: bool
Reader for TensorField data from LIME/SciDAC/QIO files
TensorFieldWriter = ref object
  fileInfo*: SciDACFileInfo
Writer for TensorField data to LIME/SciDAC/QIO files

Procs

proc close(reader: TensorFieldReader) {....raises: [IOError, OSError],
                                        tags: [WriteIOEffect], forbids: [].}
Close the reader
proc close(writer: TensorFieldWriter): LimeStatus {....raises: [IOError, OSError],
    tags: [WriteIOEffect], forbids: [].}
Close the writer
proc colors(reader: TensorFieldReader): int {....raises: [], tags: [], forbids: [].}
Get number of colors (e.g., 3 for SU(3))
proc datacount(reader: TensorFieldReader): int {....raises: [], tags: [],
    forbids: [].}
Get data count (number of tensor elements per site)
proc dims(reader: TensorFieldReader): seq[int] {....raises: [], tags: [],
    forbids: [].}
Get lattice dimensions from file
proc globalLexCoords[D: static[int]](index: int; dims: array[D, int]): array[D,
    int]
Convert global lexicographic index to coordinates
proc globalLexIndex[D: static[int]](coords: array[D, int]; dims: array[D, int]): int
Convert lattice coordinates to global lexicographic index. QIO order: x + Lx * (y + Ly * (z + Lz * t))
proc loadBinaryData(reader: TensorFieldReader; validate: bool = true) {.
    ...raises: [IOError, OSError, ValueError, Exception, XmlError],
    tags: [ReadIOEffect, RootEffect, WriteIOEffect], forbids: [].}
Load binary data from the file (call before reading into TensorField) If validate is true and checksum doesn't match, raises IOError
proc newTensorFieldReader(filename: string): TensorFieldReader {.
    ...raises: [IOError, OSError, ValueError, Exception, XmlError],
    tags: [ReadIOEffect, RootEffect, WriteIOEffect], forbids: [].}
Open a file for reading tensor field data
proc newTensorFieldWriter[D: static[int]](filename: string; dims: array[D, int]): TensorFieldWriter
Create a new writer for tensor field data
proc precision(reader: TensorFieldReader): SciDACPrecision {....raises: [],
    tags: [], forbids: [].}
Get the precision of the data in the file
proc printFileInfo(reader: TensorFieldReader) {....raises: [], tags: [],
    forbids: [].}
Print file metadata in a nice format
proc printRecordInfo(reader: TensorFieldReader) {....raises: [], tags: [],
    forbids: [].}
Print record metadata in a nice format
proc readGaugeField[D: static[int]; L: Lattice[D]](
    gaugeField: var array[4, TensorField[D, 2, L, Complex64]]; filename: string;
    swapBytes: bool = true)

Read a gauge configuration into an array of 4 TensorFields with shape 3, 3

The gauge field has 4 link matrices per site (one per direction), each being a 3x3 complex SU(3) matrix stored as a separate TensorField.

Parameters: gaugeField: Array of 4 TensorFields, each with shape 3, 3 filename: Path to the input file swapBytes: Whether to swap bytes for endianness (default: true)

proc readGaugeFieldToTensor[D: static[int]; L: Lattice[D]](
    tensor: var TensorField[D, 3, L, Complex64]; filename: string)

Read a gauge configuration into a TensorField with shape 4, 3, 3

The gauge field has 4 link matrices per site (one per direction), each being a 3x3 complex SU(3) matrix.

proc readPropagatorToTensor[D: static[int]; L: Lattice[D]](
    tensor: var TensorField[D, 4, L, Complex64]; filename: string)

Read a propagator field into a TensorField with shape 4, 3, 4, 3

The propagator has spin (4) and color (3) indices for both source and sink.

proc readTensorField[D: static[int]; R: static[int]; L: Lattice[D]; T](
    tensor: var TensorField[D, R, L, T]; filename: string;
    swapBytes: bool = true)

Read tensor field data from a LIME/SciDAC/QIO file

The file data is read by rank 0 and distributed to all ranks via the GlobalArray. Each rank receives the portion of data it owns.

Parameters: tensor: The TensorField to read data into (must be pre-allocated) filename: Path to the input file swapBytes: Whether to swap bytes for endianness (default: true for big-endian files)

proc spins(reader: TensorFieldReader): int {....raises: [], tags: [], forbids: [].}
Get number of spin components (0 for gauge, 4 for fermions)
proc typesize(reader: TensorFieldReader): int {....raises: [], tags: [],
    forbids: [].}
Get type size (number of real values per site element)
proc writeGaugeField[D: static[int]; L: Lattice[D]](
    gaugeField: array[4, TensorField[D, 2, L, Complex64]]; filename: string;
    userXml: string = ""): LimeStatus

Write a gauge configuration from an array of 4 TensorFields to file

Parameters: gaugeField: Array of 4 TensorFields, each with shape 3, 3 filename: Path to the output file userXml: Optional user metadata XML

proc writeGaugeFieldFromTensor[D: static[int]; L: Lattice[D]](
    tensor: TensorField[D, 3, L, Complex64]; filename: string;
    userXml: string = ""): LimeStatus
Write a gauge configuration from a TensorField to file
proc writePropagatorFromTensor[D: static[int]; L: Lattice[D]](
    tensor: TensorField[D, 4, L, Complex64]; filename: string;
    userXml: string = ""): LimeStatus
Write a propagator field from a TensorField to file
proc writeTensorField[D: static[int]; R: static[int]; L: Lattice[D]; T](
    tensor: TensorField[D, R, L, T]; filename: string; userXml: string = "";
    colors: int = 3; spins: int = 0): LimeStatus

Write tensor field data to a LIME/SciDAC/QIO file

The distributed TensorField data is gathered to rank 0 using GlobalArrays broadcast mechanism (in reverse - we gather). Rank 0 writes the file.

Parameters: tensor: The TensorField to write filename: Path to the output file userXml: Optional user metadata XML colors: Number of colors (default 3 for SU(3)) spins: Number of spin components (0 for gauge, 4 for fermions)

Returns: LimeStatus indicating success or failure