1 //------------------------------------------------------------------------------
2 // GB_split_bitmap: split a bitmap matrix into an array of matrices
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 #define GB_FREE_ALL \
11 GB_Matrix_free (&C) ;
12
13 #include "GB_split.h"
14
GB_split_bitmap(GrB_Matrix * Tiles,const GrB_Index m,const GrB_Index n,const int64_t * restrict Tile_rows,const int64_t * restrict Tile_cols,const GrB_Matrix A,GB_Context Context)15 GrB_Info GB_split_bitmap // split a bitmap matrix
16 (
17 GrB_Matrix *Tiles, // 2D row-major array of size m-by-n
18 const GrB_Index m,
19 const GrB_Index n,
20 const int64_t *restrict Tile_rows, // size m+1
21 const int64_t *restrict Tile_cols, // size n+1
22 const GrB_Matrix A, // input matrix
23 GB_Context Context
24 )
25 {
26
27 //--------------------------------------------------------------------------
28 // get inputs
29 //--------------------------------------------------------------------------
30
31 GrB_Info info ;
32 ASSERT (GB_IS_BITMAP (A)) ;
33 GrB_Matrix C = NULL ;
34
35 int sparsity_control = A->sparsity ;
36 float hyper_switch = A->hyper_switch ;
37 bool csc = A->is_csc ;
38 GrB_Type atype = A->type ;
39 int64_t avlen = A->vlen ;
40 int64_t avdim = A->vdim ;
41 size_t asize = atype->size ;
42 const int8_t *restrict Ab = A->b ;
43
44 GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
45
46 int64_t nouter = csc ? n : m ;
47 int64_t ninner = csc ? m : n ;
48
49 const int64_t *Tile_vdim = csc ? Tile_cols : Tile_rows ;
50 const int64_t *Tile_vlen = csc ? Tile_rows : Tile_cols ;
51
52 //--------------------------------------------------------------------------
53 // split A into tiles
54 //--------------------------------------------------------------------------
55
56 for (int64_t outer = 0 ; outer < nouter ; outer++)
57 {
58
59 const int64_t avstart = Tile_vdim [outer] ;
60 const int64_t avend = Tile_vdim [outer+1] ;
61
62 for (int64_t inner = 0 ; inner < ninner ; inner++)
63 {
64
65 //------------------------------------------------------------------
66 // allocate the tile C
67 //------------------------------------------------------------------
68
69 // The tile appears in vectors avstart:avend-1 of A, and indices
70 // aistart:aiend-1.
71
72 const int64_t aistart = Tile_vlen [inner] ;
73 const int64_t aiend = Tile_vlen [inner+1] ;
74 const int64_t cvdim = avend - avstart ;
75 const int64_t cvlen = aiend - aistart ;
76 int64_t cnzmax = cvdim * cvlen ;
77
78 C = NULL ;
79 GB_OK (GB_new_bix (&C, false, // new header
80 atype, cvlen, cvdim, GB_Ap_null, csc, GxB_BITMAP, false,
81 hyper_switch, 0, cnzmax, true, Context)) ;
82 int8_t *restrict Cb = C->b ;
83 C->sparsity = sparsity_control ;
84 C->hyper_switch = hyper_switch ;
85 int C_nthreads = GB_nthreads (cnzmax, chunk, nthreads_max) ;
86 int64_t cnz = 0 ;
87
88 //------------------------------------------------------------------
89 // copy the tile from A into C
90 //------------------------------------------------------------------
91
92 bool done = false ;
93
94 #ifndef GBCOMPACT
95 {
96 // no typecasting needed
97 switch (asize)
98 {
99 #define GB_COPY(pC,pA) Cx [pC] = Ax [pA]
100
101 case 1 : // uint8, int8, bool, or 1-byte user-defined
102 #define GB_CTYPE uint8_t
103 #include "GB_split_bitmap_template.c"
104 break ;
105
106 case 2 : // uint16, int16, or 2-byte user-defined
107 #define GB_CTYPE uint16_t
108 #include "GB_split_bitmap_template.c"
109 break ;
110
111 case 4 : // uint32, int32, float, or 4-byte user-defined
112 #define GB_CTYPE uint32_t
113 #include "GB_split_bitmap_template.c"
114 break ;
115
116 case 8 : // uint64, int64, double, float complex,
117 // or 8-byte user defined
118 #define GB_CTYPE uint64_t
119 #include "GB_split_bitmap_template.c"
120 break ;
121
122 case 16 : // double complex or 16-byte user-defined
123 #define GB_CTYPE uint64_t
124 #undef GB_COPY
125 #define GB_COPY(pC,pA) \
126 Cx [2*pC ] = Ax [2*pA ] ; \
127 Cx [2*pC+1] = Ax [2*pA+1] ;
128 #include "GB_split_bitmap_template.c"
129 break ;
130
131 default:;
132 }
133 }
134 #endif
135
136 if (!done)
137 {
138 // user-defined types
139 #define GB_CTYPE GB_void
140 #undef GB_COPY
141 #define GB_COPY(pC,pA) \
142 memcpy (Cx + (pC)*asize, Ax + (pA)*asize, asize) ;
143 #include "GB_split_bitmap_template.c"
144 }
145
146 //------------------------------------------------------------------
147 // conform the tile and save it in the Tiles array
148 //------------------------------------------------------------------
149
150 C->magic = GB_MAGIC ;
151 C->nvals = cnz ;
152 ASSERT_MATRIX_OK (C, "C for GB_split", GB0) ;
153 GB_OK (GB_conform (C, Context)) ;
154 if (csc)
155 {
156 GB_TILE (Tiles, inner, outer) = C ;
157 }
158 else
159 {
160 GB_TILE (Tiles, outer, inner) = C ;
161 }
162 C = NULL ;
163 }
164 }
165
166 return (GrB_SUCCESS) ;
167 }
168
169