//===- Storage.h - TACO-flavored sparse tensor representation ---*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contains definitions for the following classes: // // * `SparseTensorStorageBase` // * `SparseTensorStorage<P, C, V>` // //===----------------------------------------------------------------------===// #ifndef MLIR_EXECUTIONENGINE_SPARSETENSOR_STORAGE_H #define MLIR_EXECUTIONENGINE_SPARSETENSOR_STORAGE_H #include "mlir/Dialect/SparseTensor/IR/Enums.h" #include "mlir/ExecutionEngine/Float16bits.h" #include "mlir/ExecutionEngine/SparseTensor/ArithmeticUtils.h" #include "mlir/ExecutionEngine/SparseTensor/COO.h" #include "mlir/ExecutionEngine/SparseTensor/MapRef.h" namespace mlir { namespace sparse_tensor { //===----------------------------------------------------------------------===// // // SparseTensorStorage Classes // //===----------------------------------------------------------------------===// /// Abstract base class for `SparseTensorStorage<P,C,V>`. This class /// takes responsibility for all the `<P,C,V>`-independent aspects /// of the tensor (e.g., sizes, sparsity, mapping). In addition, /// we use function overloading to implement "partial" method /// specialization, which the C-API relies on to catch type errors /// arising from our use of opaque pointers. /// /// Because this class forms a bridge between the denotational semantics /// of "tensors" and the operational semantics of how we store and /// compute with them, it also distinguishes between two different /// coordinate spaces (and their associated rank, sizes, etc). /// Denotationally, we have the *dimensions* of the tensor represented /// by this object. Operationally, we have the *levels* of the storage /// representation itself. /// /// The *size* of an axis is the cardinality of possible coordinate /// values along that axis (regardless of which coordinates have stored /// element values). As such, each size must be non-zero since if any /// axis has size-zero then the whole tensor would have trivial storage /// (since there are no possible coordinates). Thus we use the plural /// term *sizes* for a collection of non-zero cardinalities, and use /// this term whenever referring to run-time cardinalities. Whereas we /// use the term *shape* for a collection of compile-time cardinalities, /// where zero is used to indicate cardinalities which are dynamic (i.e., /// unknown/unspecified at compile-time). At run-time, these dynamic /// cardinalities will be inferred from or checked against sizes otherwise /// specified. Thus, dynamic cardinalities always have an "immutable but /// unknown" value; so the term "dynamic" should not be taken to indicate /// run-time mutability. class SparseTensorStorageBase { … }; /// A memory-resident sparse tensor using a storage scheme based on /// per-level sparse/dense annotations. This data structure provides /// a bufferized form of a sparse tensor type. In contrast to generating /// setup methods for each differently annotated sparse tensor, this /// method provides a convenient "one-size-fits-all" solution that simply /// takes an input tensor and annotations to implement all required setup /// in a general manner. template <typename P, typename C, typename V> class SparseTensorStorage final : public SparseTensorStorageBase { … }; //===----------------------------------------------------------------------===// // // SparseTensorStorage Factories // //===----------------------------------------------------------------------===// template <typename P, typename C, typename V> SparseTensorStorage<P, C, V> *SparseTensorStorage<P, C, V>::newEmpty( 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) { … } template <typename P, typename C, typename V> SparseTensorStorage<P, C, V> *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) { … } template <typename P, typename C, typename V> SparseTensorStorage<P, C, V> *SparseTensorStorage<P, C, V>::newFromBuffers( 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, uint64_t srcRank, const intptr_t *buffers) { … } //===----------------------------------------------------------------------===// // // SparseTensorStorage Constructors // //===----------------------------------------------------------------------===// template <typename P, typename C, typename V> SparseTensorStorage<P, C, V>::SparseTensorStorage( 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) : … { … } template <typename P, typename C, typename V> SparseTensorStorage<P, C, V>::SparseTensorStorage( 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, const intptr_t *lvlBufs) : … { … } } // namespace sparse_tensor } // namespace mlir #endif // MLIR_EXECUTIONENGINE_SPARSETENSOR_STORAGE_H