<?xml-model href='http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng' schematypens='http://relaxng.org/ns/structure/1.0'?><TEI xmlns="http://www.tei-c.org/ns/1.0">
	<teiHeader>
		<fileDesc>
			<titleStmt><title level='a'>Bit-GraphBLAS: Bit-Level Optimizations of Matrix-Centric Graph Processing on GPU</title></titleStmt>
			<publicationStmt>
				<publisher></publisher>
				<date>05/01/2022</date>
			</publicationStmt>
			<sourceDesc>
				<bibl> 
					<idno type="par_id">10379217</idno>
					<idno type="doi">10.1109/IPDPS53621.2022.00056</idno>
					<title level='j'>36th IEEE International Parallel &amp; Distributed Processing Symposium</title>
<idno></idno>
<biblScope unit="volume"></biblScope>
<biblScope unit="issue"></biblScope>					

					<author>Jou-An Chen</author><author>Hsin-Hsuan Sung</author><author>Xipeng Shen</author><author>Nathan Tallent</author><author>Kevin Barker</author><author>Ang Li</author>
				</bibl>
			</sourceDesc>
		</fileDesc>
		<profileDesc>
			<abstract><ab><![CDATA[In a general graph data structure like an adjacency matrix, when edges are homogeneous, the connectivity of two nodes can be sufficiently represented using a single bit. This insight has, however, not yet been adequately exploited by the existing matrix-centric graph processing frameworks. This work fills the void by systematically exploring the bit-level representation of graphs and the corresponding optimizations to the graph operations. It proposes a two-level representation named Bit-Block Compressed Sparse Row (B2SR) and presents a series of optimizations to the graph operations on B2SR by leveraging the intrinsics of modern GPUs. Evaluations on NVIDIA Pascal and Volta GPUs show that the optimizations bring up to 40⇥ and 6555⇥ for essential GraphBLAS kernels SpMV and SpGEMM, respectively, making GraphBLAS-based BFS accelerate up to 433⇥, SSSP, PR, and CC up to 35⇥, and TC up to 52⇥.]]></ab></abstract>
		</profileDesc>
	</teiHeader>
	<text><body xmlns="http://www.tei-c.org/ns/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">
<div xmlns="http://www.tei-c.org/ns/1.0"><head>I. INTRODUCTION</head><p>Despite drawing great attention recently <ref type="bibr">[1]</ref>- <ref type="bibr">[11]</ref>, accelerating graph analytics on GPUs remains challenging in that: (i) graphs are often irregular in connectivity, causing warp divergence, memory non-coalescing, and low arithmetic intensity; (ii) graphs are often large, many of which cannot directly fit into the caches, shared memory, or even the DRAM of GPUs. To address these challenges, the matrix-centric approach has been proposed and increasingly employed by GPU-based graph frameworks <ref type="bibr">[3]</ref>, <ref type="bibr">[4]</ref>, <ref type="bibr">[12]</ref>, <ref type="bibr">[13]</ref>. Unlike traditional graphcentric frameworks that go through relevant nodes or edges iteratively, this approach employs sparse storage formats-such as compressed sparse column (CSC) or compressed sparse row (CSR)-to represent the adjacency matrix of a graph and then uses highly optimized linear algebra kernels (sparse matrix-vector and matrix-matrix multiplications, SpMV and SpGEMM) on the sparse formats for computation.</p><p>Although GraphBLAS has shown improved performance over traditional approaches in handling large graphs, there is still considerable potential to tap into. This work aims to unlock the potential by exploiting bit-level representations and optimizations on GPUs. The underlying observation is that for a large class of graphs (homogeneous graphs), a single bit is sufficient for indicating the adjacency relation of two vertices in a graph (1: adjacent, 0: not adjacent). Given that many graph algorithms center around computations upon adjacency matrices, using a bit-level representation can potentially reduce storage usage and improve computation efficiency.</p><p>Bit representations (bitmaps, bitvectors) have been used in vertex-based graph frameworks <ref type="bibr">[14]</ref>- <ref type="bibr">[16]</ref> for representing frontiers (i.e., active nodes); bit-level optimizations have, however, not yet been systematically explored in matrixbased graph frameworks. Existing GraphBLAS <ref type="bibr">[17]</ref>, <ref type="bibr">[18]</ref> frameworks typically build on existing linear algebra libraries, which offer no bit-level representations of matrices or bit-level implementations of linear algebra functions.</p><p>This work answers three key research questions. RQ-1: What storage format should be used for a binary adjacency matrix?</p><p>Unlike the Boolean data structures (frontiers) in graphcentric frameworks, for matrix-based graph frameworks, the binary data structure in focus is the entire adjacency matrix, which sits at the center of the linear algebra operations in GraphBLAS. Systematic studies are needed for manipulating it; simply representing it as a bitmap cannot tap into the full potential of space savings by accommodating many unnecessary zeros; that also causes difficulties for the graph operations to leverage the highly tuned matrix-based libraries.</p><p>Based on the properties of adjacency matrices and various tradeoffs, we design a storage format, namely Bit-Block Compressed Sparse Row (B2SR). B2SR is inspired by the Block Compressed Sparse Row (BSR) format <ref type="bibr">[19]</ref>. It takes a twolevel structure: The upper level is similar to BSR's upper level, using a sparse format to represent the locations of non-zero blocks (or called submatrices); the lower level differs from BSR in that it represents each non-zero block as a dense bit matrix-that is, each element in the block becomes one bit in the representation. The representation allows it to efficiently harvest the hardware computation capability at the low level and at the same time leverage the (regional) sparsity at the high level. Balancing the space savings and the indexing overhead lays the foundation for tapping into the potential of sparse binary matrices.</p><p>RQ-2: How to efficiently compute on the new representation?</p><p>We propose several new algorithms to implement the critical linear algebra kernels (SpMV and SpGEMM) for manipulating sparse matrices represented in B2SR. The design carefully tailors the kernel implementations around the efficient low-level bit-manipulation intrinsics on GPUs. It exploits the new optimizations and hardware-specific capability brought by the latest GPUs. These kernels lay the foundation for efficient manipulations of sparse binary matrices for graph analytics.</p><p>RQ-3: What are the performance implications? We evaluate the B2SR-based SpMV and SpGEMM on 521 binary matrices and five graph algorithms. The benefits are significant. B2SR provides up to 32&#8677; space savings. On two generations of GPUs (NVIDIA's Pascal and Volta), we observe 40&#8677; and 6555&#8677; maximum speedups over the stateof-the-art sparse linear algebra libraries cuSPARSE <ref type="bibr">[20]</ref> and GraphBLAST <ref type="bibr">[4]</ref>. On graph algorithms, it offers up to 433&#8677; acceleration on Breadth-first-search (BFS), 55&#8677; on Single-Source-Shortest-Path (SSSP), 28&#8677; on PageRank (PR), 69&#8677; on Connected Component (CC) algorithms, and 52&#8677; on Triangle Counting (TC) algorithm over GraphBLAST <ref type="bibr">[4]</ref>, a GPU graph processing framework with state-of-the-art performance. As is well known <ref type="bibr">[21]</ref>- <ref type="bibr">[23]</ref>, no sparse format fits all matrices. So despite the effectiveness of B2SR, there are matrices that fit other sparse formats better. We provide a brief discussion and a simple sampling approach to assisting users in applying B2SR.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>II. BACKGROUND AND RELATED WORK</head><p>Graph programming frameworks are based on either graphcentric abstraction (vertex-or edge-centric) <ref type="bibr">[1]</ref>, <ref type="bibr">[24]</ref>- <ref type="bibr">[28]</ref> or matrix abstraction. For the performance advantages and direct leverage of advances in high-performance linear algebra libraries, matrix abstraction has received increasing interest in recent years. GraphBLAS <ref type="bibr">[17]</ref>, <ref type="bibr">[18]</ref> is the mathematical core of matrix-based graph frameworks. It models graph traversal as operations on semi-rings. Frameworks that implement the standard include nvGraph <ref type="bibr">[12]</ref>, cuGraph <ref type="bibr">[29]</ref>, SuiteSparse <ref type="bibr">[13]</ref>, GraphBLAS template library (GBTL) <ref type="bibr">[3]</ref>, GraphBLAST <ref type="bibr">[4]</ref>, and so on. Among them, GraphBLAST <ref type="bibr">[4]</ref> represents state of the art, achieving high performance on GPU by exploiting input and output sparsity <ref type="bibr">[30]</ref> and enhanced load balance by exploiting the memory access patterns of sparse matrix multiplication.</p><p>These frameworks are mainly built under the same line of unified graph construct-using CSC or CSR to establish floating-point element space and perform matrix operations with underlying linear algebra libraries. They have not exploited bit-level optimizations. Even though in the sparse linear algebra libraries, bitmaps or bitvectors may be used to index the non-zero elements in a sparse matrix <ref type="bibr">[31]</ref>- <ref type="bibr">[33]</ref>, those libraries fundamentally assume that the sparse matrices are general rather than binary matrices. They hence leave an immense performance potential untapped (as our comparison in Section VI shows).</p><p>In graph-centric frameworks (e.g., GraphMat <ref type="bibr">[14]</ref>, Graphlt <ref type="bibr">[15]</ref>, SpbLA <ref type="bibr">[16]</ref>), there are some Boolean data structures (e.g., frontiers or active nodes), which are sometimes represented in bitmaps or bitvectors. Some works <ref type="bibr">[34]</ref>- <ref type="bibr">[36]</ref> exploit binary encoding or compression to achieve storage reduction and algorithm acceleration. For matrix-centric graph frameworks, the binary data structure in focus is the entire adjacency matrix, which sits at the center of the linear algebra operations in GraphBLAS-simply representing it as a bitmap leaves not only lots of potential 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 nRows = 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 nCols = 16 nTileRow = 2 0 1 2 1.00 1.00 1.00 1.00 1.00 1.00 1.00</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Compressed Sparse Row (CSR)</head><p>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 for space savings but also causes difficulties for the graph operations to leverage the highly tuned matrix-based libraries. Therefore, systematic studies are needed for manipulating it. Bit-manipulation primitives have been used in enhancing the performance of deep neural networks (DNNs) on GPUs <ref type="bibr">[37]</ref>- <ref type="bibr">[39]</ref>, ASICs, and FPGAs <ref type="bibr">[40]</ref>- <ref type="bibr">[42]</ref>. They are about dense binary operations, so they cannot efficiently handle sparse ops as those in graph processing. The irregularity of sparse matrices and accesses makes the issue more complex.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>III. REPRESENTATION: B2SR</head><p>This section presents B2SR, the format we have designed for representing an adjacency matrix. Figure <ref type="figure">1</ref> illustrates the design. The principle we followed is that the representation should reduce the space cost as much as possible and at the same time facilitate the acceleration of the core graph operations. Drawing on the inspiration of BSR, we create the two-level representation of B2SR. The top-level takes advantage of well-proven effective sparse formats (CSR or CSC) to represent non-empty blocks. The bottom-level treats each non-empty block as a dense block and packs its elements into a bit representation. The combination of sparse formats and bit representation minimizes space usage, while the blocklevel dense bit format preserves low-level regularity, making efficient computation possible. We will explain the format in detail.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>A. Bit-tile Indexing System</head><p>Since adjacency matrices are all square, it is natural to have the number of tile rows (nTileRow) set as nRows+tileDim 1 tileDim , where tileDim is the dimension (or bit-width) of the tile (e.g., <ref type="bibr">4,</ref><ref type="bibr">8,</ref><ref type="bibr">16,</ref><ref type="bibr">32)</ref>. The number of non-empty bit-tiles can then be inferred from the nonzeros' coordinates of the sparse matrices. In our implementation, we use cuSPARSE's cusparseXcsr2bsrNnz() API to obtain the number of non-empty tiles from the CSR format. We utilize indexing arrays to record the coordination of the non-empty bytealigned bit-tiles. The proposed format comprises three arrays:</p><p>&#8226; Tile row indices (TileRowPtr): an integer array with the size of the number of tile-rows. It records the bittiles' row indices. It is an accumulated array with the i-th element recording the sum of total non-empty bittiles counting from the first tile row to the (i-1)-th row. Therefore, T ileRowP tr[i+1] T ileRowP tr[i] suggests the number of non-empty bit-tiles in the i-th tile-row.  Table <ref type="table">I</ref>: Binarized packing format. &#8226; Tile column indices (TileColInd): an integer array with the size equal to the number of non-empty bit-tiles. This array is for recording the tile column indices in the tile coordination system. &#8226; Bit-tiles storage (BitTiles): a bit-packing type (unsigned char, unsigned short, unsigned int, or unsigned long long int) array with a size equal to the tileDim&#8677;numofTiles (number of non-empty bit-tiles). It stores the binarized non-empty bit-tiles' layout in the order of their tile column indices. The proposed format has several merits: (1) It allows simpler transpose of the sparse matrix. By transforming the TileRowPtr and TileColInd from CSR to CSC, the sparse matrix is transposed. (BitTiles do not require transpose since we default the mxv() and mxm() algorithm to access the content of a tile always in row-by-row order.) We use cuSPARSE's cusparseScsr2csc() API to enable this function in our implementation. <ref type="bibr">(2)</ref> The format has a better data accessing locality for SpGEMM and SpMV when computing in tile-row by tile-row order; Since the storage format is similar to CSR, we can use existing optimization on CSR-based algorithms to spearhead the linear algebra kernels in use. <ref type="bibr">(3)</ref> In BitTiles, the format provides storage-saving compared to CSR. The proposed format carries extra zeros than CSR and COO, which store only the nonzeros. Nevertheless, with the binarized packing yielding up to 32&#8677; space-saving per tile, most sparse matrices can still benefit from storage compression, especially when configured in small tile size.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>B. Bit Packing</head><p>Figure <ref type="figure">2</ref> presents the column-major and row-major packing of a bit-tile. We adopt column-major packing as default when converting CSR to B2SR. The transpose of B2SR tiles can be achieved by storing the additional row-major layouts. To figure out the proper byte-addressable data types to carry bits in proximity, we explore the packing granularity from 8-bit to 32-bit (reference Table <ref type="table">I</ref>). Additionally, we use half of the space in an unsigned char to allow 4-bit (nibble) packing, which further reduces half in one dimension to carry unnecessary zero when the matrix is extremely sparse. The packing result yields four variants of B2SR format: B2SR-4 (for 4&#8677;4 tile size), B2SR-8 (for 8&#8677;8 tile size), B2SR-16 (for 16&#8677;16 tile size), and B2SR-32 (for 32&#8677;32 tile size). Generally, the space-saving depends on how the adjacency matrix is initially being stored. State-of-the-art GPU graph frameworks mostly use float to carry the elements, so our bit-packing can generally provide up to 32&#8677; storage savings per square tile; for frameworks that use double to carry the elements, the bit-packing results in up to 64&#8677; savings in space. This indicates an ability to store 32&#8677; or 64&#8677; larger graphs using the same amount of space. This also brings a potential reduction in required data accessing bandwidth during computation to enable higher throughput.</p><p>Bit-packing overhead To transform CSR to B2SR, we parallelize each tile-row's encoding procedure for the large graph. For the 4, 8, 16, or 32 continuous elements in CSR's RowPtr, we use cusparseXcsr2bsrNnz() and cusparseScsr2bsr() to obtain tile-row index and fullprecision tiles along a tile-row. Next, column-major or rowmajor bit-packing kernels are applied to process each tile's encoding. The routine's overall cost is about 3 to 34 ms. In practical applications, a graph can be reused by many users; even within one execution, a graph is often used repeatedly (e.g., for iterative processing). So despite format conversion may be needed, such a one-time cost can be greatly amortized in these conditions.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>C. Sampling Profile and Tile Size Configuration</head><p>While the proposed method provides storage compression and performance gains in BLAS operators, it is evident that not all graph matrices are suitable for converting to Bit-GraphBLAS binarized format. For example, graph matrices with randomly distributed connections (nonzeros) or relatively dense patterns may not necessarily benefit from this format. When each bit tile does not capture enough nonzeros, we can have many empty bit-rows in tiles after bit packing. Converting the matrices from CSR to B2SR is not ideal since it expands the total amounts of storage. In addition, it adds additional per-thread workloads (OPS) compared to CSR's BLAS kernels in terms of operators. We observe that the tile size selection trade-off can be considerably different in various matrix patterns. Figure <ref type="figure">3a</ref> shows that when the tile size equals 4&#8677;4, there are less than 30% non-empty tiles; when the tile size equals 32&#8677;32, non-empty tiles reach more than 80% for some matrices. The reason is that although increasing tile size can decrease the number of non-empty tiles, the reduction is often less than 4&#8677; (the times of per tile size increment), causing the ratio of non-empty tiles to increase ultimately. We find that despite the increment, the total B2SR byte size can sometimes decrease because of the  reduction in the number of tiles and indexing arrays. For instance, in matrix mycielskian12, we have CSR storage at 3.12 (MB), B2SR-4 at 675.70 (KB), B2SR-8 at 361.46 (KB), B2SR-16 at 358.89 (KB), and B2SR-32 at 429.89 (KB). The total byte size of the format does not monotonically increase as tile size increases. From the other angle, Figure <ref type="figure">3b</ref> presents the reduction in the average occupancy of nonzeros in the non-empty tiles. The percentage of actual nonzeros in tiles can drop from 20% to less than 5% as the tile dimension differs. If the bit-tile is too large, the computation may waste processing too many tiles; if the bit-tile is too small, the indexing array may carry more unit workloads. Therefore, to fully utilize the double benefits (compression and computation efficiency) of Bit-GraphBLAS, graph users can first identify the potential benefits offline through our sampling profile method. In this way, when tackling extensive graphs or cumbersome, repetitive graph computations, users can experience worthy time and labor cost saving with only one-time format conversion to B2SR. The sampling works as in Algorithm 1. The user first specifies the number of rows to sample as N for N &#63743; N umOf Rows (sampling more rows can accurately capture matrix characteristics but induces more significant overheads). We then have N random indices as the random index set S &#10003; [0, 1, 2, ..., N]. Algorithm 1 Sampling Profile Scheme 1: for i in S do 2:</p><p>The sampling result provides a rough estimation of the compression rate of Bit-GraphBLAS on B2SR-4 to B2SR-32. Users can select the affordable compression rate and tile size configuration.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>IV. BIT OPERATIONS AND BLAS KERNELS DESIGN</head><p>This subsection discusses the code patterns and scheme designs that leverage the proposed storage format. Our imple- We briefly introduce the GPU bit operation intrinsics that will be used in this work, with respect to the BSTC bitblock abstraction <ref type="bibr">[37]</ref>: (1) __popc(): The population count function is for efficient bit-accumulation across a singe bit-row. CUDA supports population count along a 32-bit unsigned int. Paired with the logical AND operation, it can perform bit-dotproduct for two 32-bit bit-rows. ( <ref type="formula">2</ref>) __shfl_sync(): This intrinsic is for exchanging the bit-row across the lanes of a warp. For BMM, it facilitates a faster bit-dot-product between a bit-row and multiple bit-columns. ( <ref type="formula">3</ref>) __ballot_sync(): This warp-vote intrinsic returns a 32-bit unsigned integer whose N-th bit indicates a predicate setting by the N-th thread of a warp (assuming all threads are active). This is essentially equal to transposing a bit-column to a bit-row. Since bits are indexed from right to left in the bit-row packing, the function is equivalent to a 90 clockwise transposition to a bit-row. ( <ref type="formula">4</ref>) __brev(): This intrinsic is used in bit-packing. Together with __ballot_sync(), this function rotates a bit-column 90 anti-clockwise into a bit-row.</p><p>The kernels of matrix-centric graph computing are matrixvector and matrix-matrix computations. Table <ref type="table">II</ref> and III list the core schemes we have implemented. They correspond to the different scenarios of the inputs and outputs (binary "1-bit" or full precision "32-bit"). We use two of the schemes to explain our implementations:</p><p>Listing 1. As an example scheme of Binarized Sparse Matrix Multiply Vector (BMV), Listing 1 shows the code of bmv_bin_bin_full() in 32&#8677;32 tile size. The function demonstrates the bit multiplication between the binarized bittiles and the binarized vector. The result is a full-precision vector. The computation is as follows:</p><p>Before computation, the sparse matrix is packed into the hierarchical storage format -the vector is binarized into the column-major order with 32 consecutive elements compacted as an unsigned int. This allows the bit-columns to be fetched according to the same indexing system and enables fast bitdot-product with each bit-row in the bit-tiles. The A variable is a bit-row in a tile, and the B variable is the binarized vector. The output array C is a vector in full precision. In each warp of the thread block, the number of bit-tiles to be computed is indicated by the TileRowptr. In each iteration, the bit-tile and the 32-binarized vector perform bit-matrixvector-product using bit-wise AND and __popc(). Each lane Listing 2. As an example of Binarized Sparse Matrix Multiply Binarized Sparse Matrix (BMM), Listing 2 shows the code of bmm_bin_bin_sum() for B2SR-32. The A and B variables are the two bit-vector in tiles of the input sparse matrices. The output C is a single variable in full precision, summing up the nonzeros (1s) of the resulting bit matrix. In each warp of the thread block, the number of bittiles in A's tile row is indicated by the TileRowptr of A. In the outer "for" loop, the TileColInd of each bit-tile is used to retrieve the corresponding tile rows and bit-tiles of these tile-rows. The inner "for" loop performs the bit-tile-matrixmatrix-multiplication, where __shfl_sync() is used to retrieve the B's bit-vectors in each lane. The temporary result of each bit-vector in B is accumulated in separate registers for avoiding race conditions. Finally, the content in the 32 registers is summed up. The sum is atomically added to a single destination element in C.</p><p>Allowing efficient full-precision vector load In BMV and BMM, the bit-tiles in a tile-row are handled in a warp of 32 threads, following the warp-consolidation model <ref type="bibr">[43]</ref>. By default, each of the thread blocks contains only one warp. So up to 64 thread blocks can be freely scheduled by a single SM scheduler. This works fine when kernels are computing in a binarized vector or matrix. However, in bmv_bin_full_full(), when engaging a full-precision vector as the multiplier, the one-warp-per-thread-block design impedes the flexibility to preload the common vector portions for the neighboring tile rows into shared memory. Thus, we implement the kernel scheme with 32 warps processing consecutive 32 tile-rows in a thread block. This further enhances the spatial locality of the computation workload. Figure <ref type="figure">4</ref> shows the thread mapping for B2SR-32, B2SR-16, B2SR-8, B2SR-4. The execution latency is generally shorter when 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 &#8230; 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 &#8230; 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 cooperatively loading 128 bytes (equal to the cache line size of GPUs in our experiment) of binarized tiles from global memory. At the same time, the corresponding number of fullprecision subvectors have to be loaded for multiplication. We set the thread block to contain 1024 threads to load the vectors into shared memory before multiplication. Bit-vectors on tilerow with the same column index can share the preload vectors from shared memory.</p><p>V. GRAPH ALGORITHMS This section explains how graph programs can be implemented upon the core operations.</p><p>Matrix-centric graph computing models graph traversals as operations on semirings <ref type="bibr">[44]</ref>. As shown in Table <ref type="table">IV</ref> our implementation can support the key semiring domain operations when performing vxm(), mxv(), mxm(). After the adjacency matrix is in B2SR, it remains binary throughout all operations. The vectors representing the frontier nodes are all in dense format. They can be either binarized for binary semiring or full-precision (float, unsigned, bool, etc.) for the non-binary domains to support a variety of graph algorithms. We also implement efficient masking schemes for both BMV and BMM: bmv_bin_bin_bin_masked(), bmv_bin_bin_full_masked(), bmv_bin_full_ full_masked(), and bmm_bin_bin_sum_masked().</p><p>We next use two graph algorithms to illustrate how to utilize these kernel backends when writing graph algorithms.</p><p>Breadth-First-Search (BFS) Breadth-first-search uses boolean semiring. In each iteration, the vxm() performs onedegree edge traversal to all the connected vertices. A mask of visited vertices is applied at the end to filter out the visited results. We introduce bmv_bin_bin_bin_masked() to enable this. GraphBLAST uses early exit to eliminate the masked element operations in their masked vxm(). Yet, a similar strategy does not apply to our case. In our implementation, the consecutive rows in a tile row are operated in the same warp. Early exit causes a performance penalty because of warp divergence. Therefore, in the bmv_bin_bin_bin_masked() kernel, the bitmask is applied right before the output store, having bit-wise AND with the negation of visited vertex vector (indicates unvisited vertices).</p><p>Single-Source Shortest-Path (SSSP) We implement the algorithm with delta-stepping SSSP <ref type="bibr">[8]</ref> as in Graph-BLAST. SSSP utilizes tropical min-plus semiring. The intermediate vectors are reduced by minimum operation. bmv_bin_full_full() maintains the multiplier vector in full-precision, allowing it to carry minimum distance values. To realize the relaxation, we set an extra condition in the bmv_bin_full_full() such that the 0s in the adjacency matrix are identified as infinite (1), indicating unreachable. Only 0s along the diagonal are treated as actual zeros, which we omit their self-connectivity. Within a warp, a thread reduces all non-zero full-precision values along the multiplier vector by Min() (for B2SR-32). In B2SR-4, B2SR-8, and B2SR-16, since we use more than one thread to process the values along the multiplier vector, atomicMin() is applied to avoid race conditions.</p><p>PageRank (PR) PR uses arithmetic semiring. In each iteration, the page rank vector is multiplied by the column stochastic adjacency matrix. The column stochastic adjacency matrix is the adjacency matrix with each out-vertex connectivity divided by the vertex's out-degree. Since the page rank vector is in full-precision, we use bmv_bin_full_full() with an auxiliary vector v_out_degree to accommodate each vertex's out-degree. For each 1 on the matrix, the corresponding value on the page rank vector is divided by its out-degree on v_out_degree. Eventually, the intermediate vector is summed up with add operation to the output, indicating the weighted sum. Likewise, B2SR- process the workload along the vector cooperatively.</p><p>Connected Component (CC) We follow the CC implementation in GraphBLAST, which is based on the FastSV linear-algebraic connected component alogrithm <ref type="bibr">[45]</ref>, <ref type="bibr">[46]</ref>. Similar to SSSP, CC uses tropical min-plus semiring. We adopt bmv_bin_full_full() since the frontier vector should be in full-precision. The mxv() is achieved by reducing the nonzero full-precision values along the intemediate vector using Min() and atomicMin().</p><p>Triangle Counting (TC) We implement TC as in Graph-BLAST, following Azas and Buluc's <ref type="bibr">[47]</ref> and Wolf's <ref type="bibr">[48]</ref>. The TC uses arithmetic semiring. It is achieved by multiplying the lower triangle of the adjacency matrix (L) with the transpose of itself (L T ) and then applying (L) as the mask to generate the output matrix. Ultimately, the non-zeros is summed up into one full-precision value; therefore, we fuse the reduction sum kernel with mxm() and directly perform atomicAdd() to global sum once a bitmap subroutine finishes. Since both input matrices and mask matrix can be sufficiently represented in binary format, so we realize the kernel through bmm_bin_bin_sum_masked().</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>VI. EVALUATION</head></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>A. Experiment Configuration</head><p>Dataset We use all 521 binary square matrices in the SuiteSparse Matrix Collection <ref type="bibr">[13]</ref>. The set of matrices contains the number of rows and columns ranging from 2 to 214,005,017 and the number of nonzeros from 2 to 11,588,725,964. To better summarize the similarity between the matrices with higher or lower performance in the evaluation, we further  classify the matrices into six categories based on their patterns in Table <ref type="table">V</ref>. GPU Environments We evaluate the proposed format and computation core functions on two NVIDIA GPU architectures, including Pascal and Volta. With the compute capability 6.0 and 7.0 configured, respectively, how the proposed format adapts to each hardware-specific variance is worth seeing. Table <ref type="table">VI</ref> shows the configured SM information and memory hierarchy size of the two GPU architectures in the evaluation. We use CUDA version 10.0 across all our evaluations.</p><p>Algorithm Parameters The optimization setup of Graph-BLAST's algorithms is based on the default running script provided in their GitHub repository <ref type="bibr">[49]</ref>. BFS is with earlyexit, structure-only, and operand reuse enabled. PR is limited to a maximum iteration of 10. The alpha parameter is set to 0.85, and pdfilon is set to 1e 9. The runtime for all algorithms is measured by the average of 5 runs.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>B. Storage Efficiency</head><p>B2SR brings significant storage savings for large sparse matrices. We show the compression ratio of the 521 binary graph matrices with respect to the default 32-bit floating-point CSR. The compression ratio thus is defined as: B2SR size CSR size . A lower value indicates a better compression rate. The compression ratio depends mainly on the nonzero distribution of the binary matrices. Figure <ref type="figure">5a</ref> shows the compression ratio on the x-axis and the histogram recording the number of matrices using the four B2SR formats on the y-axis. In Figure <ref type="figure">5b</ref>, the y-axis shows the number of matrices that belong to their: (1) optimal size (colored in blue): the least storage size required among the four B2SR formats of a matrix. (2) compressed size (colored in green): the B2SR format can provide a compression ratio &lt; 100% for a matrix. For optimal, 162 matrices appear at B2SR-4, 291 matrices at B2SR-8, 26 matrices at B2SR-16, and 12 matrices at B2SR-32. For compressed, 491 matrices can have a compression ratio &lt; 100% on B2SR-4, 421 on B2SR-8, 329 on B2SR-16, and 263 on B2SR-32.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>C. Overview of the Performance Gains</head><p>There are multiple factors that contributed to the significant speedups B2SR has achieved. In addition to the gains by using native bit-level intrinsics such as __popc(), we have observed that more performance is from the reduced memory transactions and enhanced data locality. For example, for the matrix mycielskian8, by using B2SR, the number of global memory load transactions reduces by 4&#8677; from 6630 to 1826, while the L1 cache hit-rate increases by 24% from 65.63% to 81.83%. We also observed different sweet areas for different B2SR tile sizes-such as, the smaller tile sizes (e.g., 4, 8) draw better L1 hit rates while the larger tile sizes (e.g., 32, 64) favor coalesced memory access-and also the impact from the profiles of individual graphs. In the next two sections, we describe the performance evaluation of the linear algebra kernels (BMV and BMM) and the five graph algorithms, respectively.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>D. Linear Algebra Kernels</head><p>In this subsection, we evaluate the basic arithmetic cores BMV and BMM in terms of different schemes. We evaluate the speedups of the kernels over cuS-PARSE's SpMV (cusparseScsrmv()) and SpGEMM (cusparseScsrgemm()) with CSR in 32-bit floating-point nonzero storage. We compare the performance of each kernel scheme on B2SR-4, B2SR-8, B2SR-16, and B2SR-32. In Figure <ref type="figure">6</ref> and 7, the y-axis is the average speedups (of 5 runs) over cuSPARSE and the x-axis is the nonzero density of the matrices which is defined as # of nonzeros # of elements . A higher nonzero density (more to the right in the figure) implies a denser matrix while a lower one (more to the left) implies a sparser matrix.</p><p>BMV In BMV, we implement three schemes as the basic SpMV kernels (see Table <ref type="table">II</ref>). We evaluate the performance of bmv_bin_bin_bin(), bmv_bin_bin_full(), bmv_bin_full_full() and compare it with cuSPARSE's cusparseScsrmv(). bmv_bin_bin_bin()'s performance is shown in Figure <ref type="figure">6a</ref> and<ref type="figure">7a</ref>. Although the arithmetic capability of this scheme is limited to only binary operations, it allows a minimal memory footprint by keeping all value storage in binarized format. On GTX1080, bmv_bin_bin_bin() achieves an average speedup of 2.41&#8677; in B2SR-4, 2.74&#8677; in B2SR-8, 2.91&#8677; in B2SR-16, and 2.85&#8677; in B2SR-32. The max speedup over baseline is 40.47&#8677; that appears at matrix ins2 with B2SR-32. On Titan V, bmv_bin_bin_bin() achieves an average speedup of 2.04&#8677; in B2SR-4, 2.17&#8677; in B2SR-8, 2.18&#8677; in B2SR-16, and 2.26&#8677; in B2SR-32. The max speedup over baseline is 25.16&#8677; that appears at matrix ins2 with B2SR-32.</p><p>In bmv_bin_bin_full(), the vector input is binarized with the same tile dimension of the binary adjacency matrix. Compared to bmv_bin_full_full(), it requires less vector load bandwidth per matrix-vector multiplication. The inner product of each bit-row is done by bit-wise AND and population count of the resulting bit-row. In the 521 binary matrices, the runtime speedup of bmv_bin_bin_full() over cuSPARSE's full-precision CSR SpMV is shown in Figure <ref type="figure">6b</ref> and 7b. On GTX1080, bmv_bin_bin_full() achieves an average speedup of 2.06&#8677; in B2SR-4, 2.36&#8677; in B2SR-8, 2.22&#8677; in B2SR-16, and 2.97&#8677; in B2SR-32. The    For bmv_bin_full_full(), the performance is present in Figure <ref type="figure">6c</ref> and<ref type="figure">7c</ref>. Unlike bmv_bin_bin_full(), the average performance gain decreases when enlarged the tile size. On GTX1080, it achieves an average speedup of 2.06&#8677; in B2SR-4, 1.92&#8677; in B2SR-8, 1.43&#8677; in B2SR-16, and  <ref type="table">III</ref>). Figure <ref type="figure">6d</ref> and 7d presents the performance of the BMM kernel compared to cuSPARSE's cusparseScsrgemm(). On GTX1080, it achieves an average speedup of 33.96&#8677; in B2SR-4, 27.84&#8677; in B2SR-8, 17.81&#8677; in B2SR-16, and 10.22&#8677; in B2SR-32. The maximum speedup is 6555&#8677; that happens at matrix ins2 with B2SR-4. On Titan V, the performance gain is moderate compared to GTX1080. We accounts the reason for cuSPARSE's APIs have better performance gain on Volta than Pascal, while our implementation perform similar or evenly slightly poor on Volta than on Pascal. bmm_bin_bin_sum() on Titan V achieves an average speedup of 5.34&#8677; in B2SR-4, 3.65&#8677; in B2SR-8, 9.03&#8677; in B2SR-16, and 12.25&#8677; in B2SR-32. Interestingly, the most significant speedup is 3243&#8677; also happens at matrix ins2 but with B2SR-32 instead of B2SR-4 as on GTX1080.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>E. Graph Algorithms</head><p>We compare the implemented B2SR-based Bit-GraphBLAS algorithms with GraphBLAST <ref type="bibr">[4]</ref>, a state-of-the-art GPUbased GraphBLAS framework. GraphBLAST switches between sparse and dense vector/matrix computation depending on sparsity degree across algorithm interactions with optimized CUDA kernels. For the GraphBLAST configuration, we use the same environment (e.g., CUDA Runtime 9.1) as indicated on the Github repository <ref type="bibr">[49]</ref>. The graph algorithms are implemented following the GraphBLAS convention. For iteration-based algorithms, such as BFS, SSSP, PR, and CC, each iteration contains a frontier vector that performs a matrixvector multiplication with the adjacency matrix and several element-wise scalar operations. They are used to update the frontier vector for indicating neighbor aggregation in each iteration, through the mathematical semi-ring operation. The number of iterations depends on when the algorithm is converged at runtime.</p><p>Since matrix-vector multiplication is the major performance concern per iteration (&gt;80% of the workload), in Bit-GraphBLAS, our major goal is to improve the efficiency of SpMV through our B2SR based BMV kernel. Table <ref type="table">VII</ref> and VIII list the algorithm and kernel execution latency in ms for the proposed Bit-GraphBLAS with respect to GraphBLAST. As can be seen, under both conditions, Bit-GraphBLAS achieves considerable speedups through B2SR and the strong bit computation capability of modern GPUs.</p><p>For Bit-GraphBLAS, in the 521 binary matrices dataset, the patterns with better performance fall into three main categories: diagonal, block, and stripe (reference the classification in Table <ref type="table">V</ref>). The performance of matrices from the three categories are shown in Table VII and VIII. In the subset of matrices, delaunay n14, se, and debr are stripe patterns; Erdos02, mycielskian9, EX3, net25, and myciel-skian10 are block patterns; ash292, netz4504 dual, minnesota, jagmesh6, uk, whitaker3 dual, rajat07, 3dtube are diagonal patterns. In the algorithm evaluation, BFS relies on the kernel bmv_bin_bin_bin_masked() with boolean semiring. On Pascal, diagonal pattern matrices can achieve up to 433&#8677; acceleration in the whole algorithm and 1414&#8677; in kernel; On Volta, it achieves up to 349&#8677; speedup to GraphBLAST in algorithm and 1344&#8677; in kernel. Matrices in stripe and block generally perform a moderate speedup from 2&#8677; to 7&#8677; on both GPU architectures. Other three SpMV-based algorithms (SSSP, PR, and CC) are fulfilled by bmv_bin_full_full() with relaxation and extension (details are described in Section V). They mainly achieve a acceleration over GraphBLAST with no more than 20&#8677; algorithm-wise and 40&#8677; kernel-wise.</p><p>In Table <ref type="table">IX</ref>, we demonstrate the performance improvement of TC algorithm, which is essentially a one-time execution of the bmm_bin_sum_masked() kernel. On both Pascal and Volta, we still have diagonal patterns with the best performance. It can achieve up to 52&#8677; on Pascal and 27&#8677; on Volta GPUs.</p><p>It is noteworthy that the same matrix can often find lower GraphBLAST runtime on Volta than on Pascal. A similar effect can be found in both kernel and algorithm evaluations. For example, the 3dtube runs 151.89 (ms) on Pascal but only 79.49 (ms) on Volta. Nevertheless, Bit-GraphBLAS can have a larger or similar runtime on Volta than on Pascal GPUs. We have a 0.04 (ms) increase in runtime for the 3dtube case. We attribute the effect to that Volta has updated the warp execution model and eliminated implicit warp synchronous. This poses a little performance slowdown of binary intrinsics like __shfl_sync() and __ballot_sync() compared to the non-synchronizing __shfl() and __ballot() in Pascal GPUs.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>VII. DISCUSSION</head><p>Limitations of Bit-GraphBLAS: As Bit-GraphBLAS relies on the bit-operation and bit-data, it only directly applies to homogeneous graphs (i.e., the adjacency matrix is a binary matrix). Throughout the SuiteSparse data collection, we have observed that &#8672;20% of graphs are homogeneous that can directly benefit from Bit-GraphBLAS. These graphs cover a wide range of domains including mathematics, power-grid, physics, electronics, material science, economics, thermal, fluid dynamics, etc. Additionally, as the weights for many heterogeneous graphs can be expressed by integers or fixedpoints (e.g., through normalization), similar to the recent effort decomposing a quantized-neural-network into several concurrent binary-neural-networks for acceleration <ref type="bibr">[39]</ref>, Bit-GraphBLAS can also be extended to support heterogeneous graphs with short bit-width. We set this as future work.</p><p>Platform Portability: Although in the evaluation we showcase Bit-GraphBLAS on NVIDIA GPUs due to hardware availability, the bit intrinsics that Bit-GraphBLAS relies on, such as popc(), shfl(), ballot(), and brev() are also available (despite using different names) in other GPUs and CPUs (like AMD's GPU and X86 CPUs). Therefore, we did not see significant challenges in supporting Bit-GraphBLAS on alternative hardware platforms (e.g., AMD GPUs through HIPIFY <ref type="bibr">[50]</ref>).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>VIII. CONCLUSION</head><p>We present Bit-GraphBLAS, a linear algebra-based graph framework that utilizes a Bit-Block Compressed Sparse Row (B2SR) format and bit manipulation primitives on GPUs to enable dense bit-operations on bit tiles within large sparse adjacency matrices. We explore different tile size configurations from 4&#8677;4 to 32&#8677;32, and suitable bit-packing types. We implement BMV and BMM schemes to support parse kernel operations and demonstrate their effectiveness on graph algorithms by reducing memory footprint. The result shows significant performance gain over full-CSR-based GPU graph frameworks. In sum, the novel storage format and algorithms compress the graphs' storage and accelerate the linear algebra kernels SpMV and SpGEMM through finer-grained bit-wise parallelism.</p></div></body>
		</text>
</TEI>
