Input/Output Module¶
Printing to the Terminal¶
You can print the content of a Matrix, CSR Matrix, Vector and Sparse Vector to the terminal in a similar way as other built-in datatypes: with the operator<<
and std:cout
or std::err
.
Alternatively, you can use the fmt::print()
, std::format()
and similar routines from the {fmt} library. This provides more control over how the entries of the container are displayed. See the Format Syntax Guide for all the format options.
Matrix<int> mat = {{11, 12, 13}, {21, 22, 23}, {31, 32, 33}};
std::cout << "Matrix: " << mat << std::endl;
Vector<double> vec = {1.2, 4.5, 7.6};
fmt::print("Vector:\n{:>+9.3f}\n", vec);
CSRMatrix<int> csr_mat(4, 4, 5);
csr_mat.insert(0, 1, 12);
csr_mat.insert(0, 3, 14);
csr_mat.insert(1, 1, 22);
csr_mat.insert(2, 2, 33);
csr_mat.insert(3, 1, 42);
fmt::print("CSR Matrix:\n{:^#10x}\n", csr_mat);
SparseVector<int> sparse_vec(10, 3);
sparse_vec.insert(2, 3);
sparse_vec.insert(5, 6);
sparse_vec.insert(9, 10);
fmt::print("Sparse Vector:\n{}\n", sparse_vec);
Output:
Matrix:
[[ 11 12 13 ]
[ 21 22 23 ]
[ 31 32 33 ]]
Vector:
[ +1.200
+4.500
+7.600 ]
CSR Matrix:
( 0 , 1 ) 0xc
( 0 , 3 ) 0xe
( 1 , 1 ) 0x16
( 2 , 2 ) 0x21
( 3 , 1 ) 0x2a
Sparse Vector:
(2) 3
(5) 6
(9) 10
If the object is large, not all entries will be printed into the terminal. You can control the number of rows, columns and nonzeros that will be displayed by setting the following global print options:
mocca::io::print_options::nrows = 10; // Default: 5
mocca::io::print_options::ncols = 20; // Default: 5
mocca::io::print_options::nonzeros = 100; // Default: 5
For displaying all entries, you can use the kAllEntries
constant.
Importing and Exporting Data to Files¶
MTX Files¶
*Matrix Market Matrix Format* (MTX) was created by the U.S. National Institute of Standards and Technology (NIST) for facilitating the exchange of matrix data over the web. It consists of a header containing the information about the matrix, followed by its dimensions and its entries:
%%MatrixMarket matrix <matrix format> <data type> <symmetry>
% <comments>
% ...
<matrix parameters>
<entry 1>
<entry 2>
...
<entry n>
The MTX specification defines two matrix formats:
coordinate: A file format suitable for representing sparse matrices. Only nonzero entries are provided, and the coordinates of each nonzero entry are given explicitly.
array: A file format suitable for representing dense matrices. This format assumes that the entries in the matrix follow the Column-Major scheme.
Both matrix formats supports four different data types — pattern
(i.e., all nonzero entries are equal to 1
), integer
, real
or complex
— and symmetry structures — general
, symmetric
, skew-symmetric
and Hermitian
. If the matrix is symmetric, the file only contains the lower triangular part of the matrix (i.e., the entries on or below the main diagonal), reducing the file size. MOCCA only supports general
and symmetric
matrices.
If the coordinate format is used, the matrix parameters are <rows> <columns> <nonzeros>
and each nonzero entry is stored as a triplet: <row> <column> <value>
. If pattern
is specified, only the position of the nonzeros entries is provided (i.e., <row> <column>
). The nonzero entries do not need to be sorted. If the array format is used, the matrix parameters are <rows> <columns>
and the values of entries are stored using a Column-Major scheme.
Comments can be included between the header and the matrix parameters and must begin with the %
symbol.
MTX files in the coordinate format can be imported using the read_sparse_mtx()
method, while files in the array format, be with the read_dense_mtx()
method.
// Initialize csr_mat directly from the file
mocca::CSRMatrix<double> csr_mat = mocca::io::read_sparse_mtx<double>("csr_matrix.mtx");
// Create the matrix and then fill_sorted_by_col it with the contents of the file
mocca::Matrix<float> mat;
mocca::io::read_dense_mtx("mat.mtx", mat);
Likewise, the data in the Matrix and CSR Matrix can be exported to an MTX file in their corresponding formats by calling write_mtx()
.
HDF5 Files¶
The Hierarchical Data Format version 5 (HDF5) is an open-source file format that supports large, complex, heterogeneous data. HDF5 uses a “file directory” like structure that allows you to organize data within the file in many different structured ways, as you might do with files on your computer.
MOCCA provides a high-level interface as well as a simple C++ interface for creating, writing and reading an HDF5 File Properties and api_io_hdf5_group. All MOCCA objects are compressed and chunked by default.
The following code creates an HDF5 File test.h5
, then writes a 5x5 matrix A
as mat
to the file, vector v
as a vector to group G1
and u
as u
to the “root” group. A similar procedure can be done for reading HDF5 files.
Matrix<int> A(5, 5);
Vector<double> v(200), u(100);
//...//
io::hdf5::File file("test.h5");
io::write_hdf5(file, "mat", A, "G1/vec", v);
file.root().write("u", u);
Warning
When using (Parallel) HDF5 together with MPI I/O, all HDF5 files, groups, datasets, etc. must be closed before calling MPI_FINALIZE
! Note that this is done automatically when exiting the scope.
TXT Files¶
MOCCA also supports a simpler file format: a plain text file containing a header with the matrix/vector dimensions followed by the entries in the object separated by either spaces or newlines. The entries are organized in a Row-Major format. Currently, TXT files can only store Vector or Matrix objects. Below is an example of a file for a 3x5 dense matrix stored in a TXT file:
3 5
11 12 13 14 15
21 22 23 24 25
31 32 33 34 34
For a dense vector of 4 entries, the file can be simplified to:
4
10.1
209
0.114
498
The data from TXT files can be imported through the read_mat_txt()
and read_vec_txt()
. Likewise, the data from Vector and Matrix objects can be written to a file in this format by calling write_txt()
.