next up previous
Next: The Sequential Algorithm Up: Sparse Matrix Solver Previous: Sparse Matrix Solver

The Hierarchical Data Structure

An implicit hierarchical data structure has been developed to efficiently store and retrieve data for a non-symmetric block-diagonal-bordered sparse matrix. This data structure is static, consequently, the locations of all fillin must be determined before memory is allocated for the data structures. In addition, due to the static nature of the data structure, explicit pointers to subsequent data locations can be used in order to reduce indexing overhead. Row and column location indicators are explicitly stored as are pointers to subsequent values in columns and rows that are required when updating values in the matrix. This sparse matrix research has considered real-time applications, so the use of additional memory in the data structures is traded for reduced indexing overhead. Modern distributed memory multi-processors can be purchased with substantial amounts of random access memory at each node, so this research examines data structures that are designed to optimize processing speed at the cost of increased memory usage when compared to other compressed storage formats. We compare the memory requirements for these data structures to the memory requirements for the more conventional compressed data structures below.

The hierarchical data structure is composed of eight separate parts that implicitly store a block-diagonal-bordered sparse matrix. The hierarchical nature of these structures store only non-zero values, especially in the borders where entire rows or columns may be zero. Eight separate C language structures are employed to store the data in a manner that can efficiently be accessed with minimal indexing overhead. Static vectors of each structure type are used to store the block-diagonal-bordered sparse matrix. Figure 12 graphically illustrates the hierarchical nature of the data structure, where the eight separate C structure elements presented in that figure are:

  1. block identifier,
  2. matrix diagonal element,
  3. non-zero value in a lower triangular matrix diagonal block (arranged by rows),
  4. non-zero value in a upper triangular matrix diagonal block (arranged by columns),
  5. non-zero row in the lower border,
  6. non-zero column in the upper border,
  7. non-zero value in the lower border (arranged by rows),
  8. non-zero value in the upper border (arranged by columns).

 
Figure 12: The Hierarchical Data Structure 

At the top of the hierarchical data structure is the information on the storage locations of independent blocks, the last block, and the lower and upper borders. The next layer in the data structure hierarchy are the matrix diagonal and the identifiers of non-zero border rows and columns. Data values on the original matrix diagonal are stored in the diagonal portion of the data structure, however, most of the remaining information stored along with each diagonal element are pointers so that data in related columns or rows can be rapidly accessed.

Data in the strictly lower triangular portion of the matrix is stored by rows; likewise, data in the strictly upper triangular portion of the matrix is stored by columns. This data storage scheme minimizes the effort to find non-zero --- pairs used to modify by consecutively storing values in lower triangular rows and upper triangular columns. However, Crout's algorithm requires access to the next non-zero value in the same column or row for lower/upper triangular matrices, so pointers are used to permit direct access to those values without requiring searching for the data as is required in compressed storage formats. This data structure provides the benefits of a doubly linked data structure in order to minimize indexing overhead. The data pertaining to any diagonal element has pointers to the first non-zero element in the lower triangular row and upper triangular column. There are also pointers to the next non-zero value in the lower triangular column and the upper triangular row. This data structure trades memory utilization for speed by storing all row and column indicators with a non-zero value. In addition, the combination of adjacent storage of non-zero row and column values and the explicit storage of row and column identifiers, greatly simplify the forward reduction and backward substitution steps.

The remaining portions of the hierarchical data structure efficiently store the non-zero values in the borders. Because entire lower border rows or upper border columns may be sparse in a block, two layers are required to store this data in an efficient manner. The next level in this portion of the hierarchy, stores the location of the first non-zero value in the row or column. The corresponding row and column identifiers can be found by referencing the structure that the pointer references. The non-zero values in the lower and upper borders are stored with the same format as data in the diagonal blocks. A complete listing of the elements in the data structure is presented in appendix A.

Conventional compressed data formats require less storage than this data structure; however, two reasons exist that justify the use of additional memory: large available memories are available with state-of-the-art distributed-memory multi-processors and these algorithms have been designed with the expressed intention to support real-time applications. The compressed data format requires

bytes to store the A matrix implicitly. Likewise, the hierarchical data structure used in this implementation requires

bytes to store the same matrix implicitly.

 where: ¯

is the storage requirements in bytes for the compressed data structure.

is the storage requirements in bytes for the hierarchical data structure.

is the length if a floating point data type.

is the length if an integer data type.

is the number of non-zero values in the matrix.

n is the order of the matrix.

is the number of independent blocks.

is the number of non-zero row and column segments in the borders.

For double precision floating point representations of the actual data values and single word integer representations of all pointers, the hierarchical data structure takes approximately twice the data storage of the compressed data structure. By doubling the storage, there is a significant decrease in indexing overhead, especially considering that to find a value in a row or column, the average search will be one-half the average number of values in the row or column. Given that this costly search must be performed for nearly every non-zero value in the matrix, substantial indexing overhead is required when using the implicit compressed storage format.

Nevertheless, there is nothing in the nature of block-diagonal-bordered form matrices that limits the use of modified compressed data structures that simply use the hierarchical nature of this data structure to identify independent blocks with compressed data structures substituted throughout the remainder of the data structure. However, the data structure is closely tied to the implementation of the block-diagonal-bordered sparse matrix algorithms and modifying the data structures would require changes in the code used to identify values to be used in updates of matrix values.

While the general Crout factorization algorithm permits partial pivoting [13], this static hierarchical data structure assumes that no pivoting is required to maintain numerical stability in the calculations. Traditional numerical pivoting can be difficult in a general sparse matrix due to the sparsity structure and concerns for fillin, so considerations are made to relax the normal numerical pivoting rules in Markowitz pivoting when the matrix is neither positive definite nor diagonally dominate [5]. Block-diagonal-bordered sparse matrices offer the potential for an additional relaxed pivoting rule that limits pivoting choices to within a diagonal matrix block. Numerical pivoting choices could be further limited to a small neighborhood of an equation when sparse matrices are ordered into recursive block-diagonal-bordered form. For the present research, it is assumed that numerical pivoting will not be required, because the matrices for our applications will be diagonally dominate if not positive definite.



next up previous
Next: The Sequential Algorithm Up: Sparse Matrix Solver Previous: Sparse Matrix Solver



David P. Koester
Sun Oct 22 16:27:33 EDT 1995