20#ifndef MLIR_EXECUTIONENGINE_SPARSETENSOR_FILE_H
21#define MLIR_EXECUTIONENGINE_SPARSETENSOR_FILE_H
46template <
typename V,
bool IsPattern>
47inline std::enable_if_t<!is_complex<V>::value, V>
readValue(
char **linePtr) {
51 if constexpr (IsPattern)
53 return strtod(*linePtr, linePtr);
59template <
typename V,
bool IsPattern>
60inline std::enable_if_t<is_complex<V>::value, V>
readValue(
char **linePtr) {
65 if constexpr (IsPattern)
67 double re = strtod(*linePtr, linePtr);
68 double im = strtod(*linePtr, linePtr);
106 assert(filename &&
"Received nullptr for filename");
117 const uint64_t *dimShape,
124 "Tensor element type %d not compatible with values in file %s\n",
125 static_cast<int>(valTp), filename);
159 assert(
isValid() &&
"Attempt to isPattern() before readHeader()");
166 assert(
isValid() &&
"Attempt to isSymmetric() before readHeader()");
173 assert(
isValid() &&
"Attempt to getRank() before readHeader()");
180 assert(
isValid() &&
"Attempt to getNSE() before readHeader()");
192 assert(d <
getRank() &&
"Dimension out of bounds");
203 template <
typename P,
typename C,
typename V>
206 const LevelType *lvlTypes,
const uint64_t *dim2lvl,
207 const uint64_t *lvl2dim) {
208 const uint64_t dimRank =
getRank();
209 MapRef map(dimRank, lvlRank, dim2lvl, lvl2dim);
210 auto *lvlCOO = readCOO<V>(map, lvlSizes);
212 dimRank,
getDimSizes(), lvlRank, lvlSizes, lvlTypes, dim2lvl, lvl2dim,
221 template <
typename C,
typename V>
222 bool readToBuffers(uint64_t lvlRank,
const uint64_t *dim2lvl,
223 const uint64_t *lvl2dim, C *lvlCoordinates, V *values);
232 template <
typename C>
233 char *readCoords(C *dimCoords) {
236 char *linePtr = line;
237 for (uint64_t dimRank =
getRank(), d = 0; d < dimRank; ++d) {
239 uint64_t c = strtoul(linePtr, &linePtr, 10);
241 dimCoords[d] =
static_cast<C
>(c - 1);
247 template <
typename V>
248 SparseTensorCOO<V> *readCOO(
const MapRef &map,
const uint64_t *lvlSizes);
252 template <
typename V,
bool IsPattern>
253 void readCOOLoop(
const MapRef &map, SparseTensorCOO<V> *coo);
258 template <
typename C,
typename V,
bool IsPattern>
259 bool readToBuffersLoop(
const MapRef &map, C *lvlCoordinates, V *values);
262 void readMMEHeader();
268 void readExtFROSTTHeader();
270 static constexpr int kColWidth = 1025;
271 const char *
const filename;
272 FILE *file =
nullptr;
274 bool isSymmetric_ =
false;
276 char line[kColWidth];
287 const uint64_t *lvlSizes) {
288 assert(
isValid() &&
"Attempt to readCOO() before readHeader()");
290 auto *coo =
new SparseTensorCOO<V>(map.getLvlRank(), lvlSizes,
getNSE());
293 readCOOLoop<V, true>(map, coo);
295 readCOOLoop<V, false>(map, coo);
301template <
typename V,
bool IsPattern>
302void SparseTensorReader::readCOOLoop(
const MapRef &map,
304 const uint64_t dimRank = map.getDimRank();
305 const uint64_t lvlRank = map.getLvlRank();
307 std::vector<uint64_t> dimCoords(dimRank);
308 std::vector<uint64_t> lvlCoords(lvlRank);
309 for (uint64_t k = 0, nse =
getNSE(); k < nse; k++) {
310 char *linePtr = readCoords(dimCoords.data());
312 map.pushforward(dimCoords.data(), lvlCoords.data());
313 coo->add(lvlCoords, value);
317template <
typename C,
typename V>
319 const uint64_t *dim2lvl,
320 const uint64_t *lvl2dim,
321 C *lvlCoordinates, V *values) {
322 assert(
isValid() &&
"Attempt to readCOO() before readHeader()");
325 isPattern() ? readToBuffersLoop<C, V, true>(map, lvlCoordinates, values)
326 : readToBuffersLoop<C, V, false>(map, lvlCoordinates, values);
331template <
typename C,
typename V,
bool IsPattern>
332bool SparseTensorReader::readToBuffersLoop(
const MapRef &map, C *lvlCoordinates,
336 const uint64_t nse =
getNSE();
338 std::vector<C> dimCoords(dimRank);
339 bool isSorted =
false;
341 const auto readNextElement = [&]() {
342 linePtr = readCoords<C>(dimCoords.data());
348 C *prevLvlCoords = lvlCoordinates - lvlRank;
349 for (uint64_t l = 0; l < lvlRank; ++l) {
350 if (prevLvlCoords[l] != lvlCoordinates[l]) {
351 if (prevLvlCoords[l] > lvlCoordinates[l])
357 lvlCoordinates += lvlRank;
362 for (uint64_t n = 1; n < nse; ++n)
A class for capturing the sparse tensor type map with a compact encoding.
void pushforward(const T *in, T *out) const
uint64_t getLvlRank() const
uint64_t getDimRank() const
A memory-resident sparse tensor in coordinate-scheme representation (a collection of Elements).
void assertMatchesShape(uint64_t rank, const uint64_t *shape) const
Asserts the shape subsumes the actual dimension sizes.
bool isPattern() const
Gets the MME "pattern" property setting.
void closeFile()
Closes the file.
SparseTensorStorage< P, C, V > * readSparseTensor(uint64_t lvlRank, const uint64_t *lvlSizes, const LevelType *lvlTypes, const uint64_t *dim2lvl, const uint64_t *lvl2dim)
Allocates a new sparse-tensor storage object with the given encoding, initializes it by reading all t...
uint64_t getDimSize(uint64_t d) const
Safely gets the size of the given dimension.
SparseTensorReader(const SparseTensorReader &)=delete
void readHeader()
Reads and parses the file's header.
bool canReadAs(PrimaryType valTy) const
Checks if the file's ValueKind can be converted into the given tensor PrimaryType.
uint64_t getNSE() const
Gets the number of stored elements.
bool isValid() const
Checks if a header has been successfully read.
ValueKind getValueKind() const
Returns the stored value kind.
const uint64_t * getDimSizes() const
Gets the dimension-sizes array.
bool readToBuffers(uint64_t lvlRank, const uint64_t *dim2lvl, const uint64_t *lvl2dim, C *lvlCoordinates, V *values)
Reads the COO tensor from the file, stores the coordinates and values to the given buffers,...
bool isSymmetric() const
Gets the MME "symmetric" property setting.
SparseTensorReader & operator=(const SparseTensorReader &)=delete
uint64_t getRank() const
Gets the dimension-rank of the tensor.
static SparseTensorReader * create(const char *filename, uint64_t dimRank, const uint64_t *dimShape, PrimaryType valTp)
Factory method to allocate a new reader, open the file, read the header, and validate that the actual...
SparseTensorReader(const char *filename)
void openFile()
Opens the file for reading.
A memory-resident sparse tensor using a storage scheme based on per-level sparse/dense annotations.
static SparseTensorStorage< P, C, V > * newFromCOO(uint64_t dimRank, const uint64_t *dimSizes, uint64_t lvlRank, const uint64_t *lvlSizes, const LevelType *lvlTypes, const uint64_t *dim2lvl, const uint64_t *lvl2dim, SparseTensorCOO< V > *lvlCOO)
Allocates a new sparse tensor and initializes it from the given COO.
This file contains the declaration of the mlir::NonFloatComplex type and mlir::Complex type alias.
std::enable_if_t<!is_complex< V >::value, V > readValue(char **linePtr)
Returns an element-value of non-complex type.
PrimaryType
Encoding of the elemental type, for "overloading" @newSparseTensor.
Include the generated interface declarations.
This enum defines all the sparse representations supportable by the SparseTensor dialect.