File: GB_conform.c

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 506; asm: 369; python: 125; awk: 10
file content (389 lines) | stat: -rw-r--r-- 13,753 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
//------------------------------------------------------------------------------
// GB_conform: conform any matrix to its desired sparsity structure
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// On input, the matrix has any one of four sparsity structures: hypersparse,
// sparse, bitmap, or full.  A bitmap or full matrix never has pending work.  A
// sparse or hypersparse matrix may have pending work (zombies, jumbled, and/or
// pending tuples).  The pending work is not finished unless the matrix is
// converted to bitmap or full.  If this method fails, the matrix is cleared
// of all entries.

#include "GB.h"

#define GB_FREE_ALL ;

//------------------------------------------------------------------------------
// GB_conform_hyper_or_bitmap: ensure a matrix is either hypersparse or bitmap
//------------------------------------------------------------------------------

static inline GrB_Info GB_conform_hyper_or_bitmap
(
    bool is_hyper, bool is_sparse, bool is_bitmap, bool is_full,
    GrB_Matrix A, GB_Context Context
)
{
    GrB_Info info ;
    if (is_full || ((is_hyper || is_sparse) &&
        GB_convert_sparse_to_bitmap_test (A->bitmap_switch,
            GB_nnz (A), A->vlen, A->vdim)))
    { 
        // if full or sparse/hypersparse with many entries: to bitmap
        GB_OK (GB_convert_any_to_bitmap (A, Context)) ;
    }
    else if (is_sparse || (is_bitmap &&
        GB_convert_bitmap_to_sparse_test (A->bitmap_switch,
            GB_nnz (A), A->vlen, A->vdim)))
    { 
        // if sparse or bitmap with few entries: to hypersparse
        GB_OK (GB_convert_any_to_hyper (A, Context)) ;
    }
    return (GrB_SUCCESS) ;
}

//------------------------------------------------------------------------------
// GB_conform_sparse_or_bitmap: ensure a matrix is either sparse or bitmap
//------------------------------------------------------------------------------

static inline GrB_Info GB_conform_sparse_or_bitmap
(
    bool is_hyper, bool is_sparse, bool is_bitmap, bool is_full,
    GrB_Matrix A, GB_Context Context
)
{
    GrB_Info info ;
    if (is_full || ((is_hyper || is_sparse) &&
        GB_convert_sparse_to_bitmap_test (A->bitmap_switch,
            GB_nnz (A), A->vlen, A->vdim)))
    { 
        // if full or sparse/hypersparse with many entries: to bitmap
        GB_OK (GB_convert_any_to_bitmap (A, Context)) ;
    }
    else if (is_hyper || (is_bitmap &&
        GB_convert_bitmap_to_sparse_test (A->bitmap_switch,
            GB_nnz (A), A->vlen, A->vdim)))
    { 
        // if hypersparse or bitmap with few entries: to sparse
        GB_OK (GB_convert_any_to_sparse (A, Context)) ;
    }
    return (GrB_SUCCESS) ;
}

//------------------------------------------------------------------------------
// GB_conform_hyper_sparse_or_bitmap: ensure matrix is hyper, sparse, or bitmap
//------------------------------------------------------------------------------

static inline GrB_Info GB_conform_hyper_sparse_or_bitmap
(
    bool is_hyper, bool is_sparse, bool is_bitmap, bool is_full,
    GrB_Matrix A, GB_Context Context
)
{
    GrB_Info info ;
    if (is_full || ((is_hyper || is_sparse) &&
        GB_convert_sparse_to_bitmap_test (A->bitmap_switch,
            GB_nnz (A), A->vlen, A->vdim)))
    { 
        // if full or sparse/hypersparse with many entries: to bitmap
        GB_OK (GB_convert_any_to_bitmap (A, Context)) ;
    }
    else if (is_bitmap)
    {
        if (GB_convert_bitmap_to_sparse_test (A->bitmap_switch,
            GB_nnz (A), A->vlen, A->vdim))
        { 
            // if bitmap with few entries: to sparse
            GB_OK (GB_convert_bitmap_to_sparse (A, Context)) ;
            // conform between sparse and hypersparse
            GB_OK (GB_conform_hyper (A, Context)) ;
        }
    }
    else // is_hyper || is_sparse
    { 
        // conform between sparse and hypersparse
        GB_OK (GB_conform_hyper (A, Context)) ;
    }
    return (GrB_SUCCESS) ;
}

//------------------------------------------------------------------------------
// GB_conform
//------------------------------------------------------------------------------

GrB_Info GB_conform     // conform a matrix to its desired sparsity structure
(
    GrB_Matrix A,       // matrix to conform
    GB_Context Context
)
{

    //--------------------------------------------------------------------------
    // check inputs
    //--------------------------------------------------------------------------

    GrB_Info info ;
    ASSERT_MATRIX_OK (A, "A to conform", GB0) ;
    ASSERT (GB_ZOMBIES_OK (A)) ;
    ASSERT (GB_JUMBLED_OK (A)) ;
    ASSERT (GB_PENDING_OK (A)) ;
    bool is_hyper = GB_IS_HYPERSPARSE (A) ;
    bool is_sparse = GB_IS_SPARSE (A) ;
    bool is_full = GB_IS_FULL (A) ;
    bool is_bitmap = GB_IS_BITMAP (A) ;
    bool as_if_full = GB_as_if_full (A) ;
    if (A->nvec_nonempty < 0)
    { 
        A->nvec_nonempty = GB_nvec_nonempty (A, Context) ;
    }

    //--------------------------------------------------------------------------
    // select the sparsity structure
    //--------------------------------------------------------------------------

    switch (GB_sparsity_control (A->sparsity_control, A->vdim))
    {

        //----------------------------------------------------------------------
        // (1) always hypersparse
        //----------------------------------------------------------------------

        case GxB_HYPERSPARSE : 

            GB_OK (GB_convert_any_to_hyper (A, Context)) ;
            break ;

        //----------------------------------------------------------------------
        // (2) always sparse
        //----------------------------------------------------------------------

        case GxB_SPARSE : 

            GB_OK (GB_convert_any_to_sparse (A, Context)) ;
            break ;

        //----------------------------------------------------------------------
        // (3) sparse or hypersparse
        //----------------------------------------------------------------------

        case GxB_HYPERSPARSE + GxB_SPARSE : 

            if (is_full || is_bitmap)
            { 
                // if full or bitmap: to sparse
                GB_OK (GB_convert_any_to_sparse (A, Context)) ;
            }
            // conform between sparse and hypersparse
            GB_OK (GB_conform_hyper (A, Context)) ;
            break ;

        //----------------------------------------------------------------------
        // (4) always bitmap
        //----------------------------------------------------------------------

        case GxB_BITMAP : 

            GB_OK (GB_convert_any_to_bitmap (A, Context)) ;
            break ;

        //----------------------------------------------------------------------
        // (5) hypersparse or bitmap
        //----------------------------------------------------------------------

        case GxB_HYPERSPARSE + GxB_BITMAP : 

            // ensure the matrix is hypersparse or bitmap
            GB_OK (GB_conform_hyper_or_bitmap (is_hyper, is_sparse, is_bitmap,
                is_full, A, Context)) ;
            break ;

        //----------------------------------------------------------------------
        // (6) sparse or bitmap
        //----------------------------------------------------------------------

        case GxB_SPARSE + GxB_BITMAP : 

            // ensure the matrix is sparse or bitmap
            GB_OK (GB_conform_sparse_or_bitmap (is_hyper, is_sparse, is_bitmap,
                is_full, A, Context)) ;
            break ;

        //----------------------------------------------------------------------
        // (7) hypersparse, sparse, or bitmap
        //----------------------------------------------------------------------

        case GxB_HYPERSPARSE + GxB_SPARSE + GxB_BITMAP : 

            // ensure the matrix is hypersparse, sparse, or bitmap
            GB_OK (GB_conform_hyper_sparse_or_bitmap (is_hyper, is_sparse,
                is_bitmap, is_full, A, Context)) ;
            break ;

        //----------------------------------------------------------------------
        // (8): full
        //----------------------------------------------------------------------

        case GxB_FULL : 

            if (as_if_full)
            { 
                // if full or all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else
            { 
                // otherwise: to bitmap
                GB_OK (GB_convert_any_to_bitmap (A, Context)) ;
            }
            break ;

        //----------------------------------------------------------------------
        // (9) hypersparse or full
        //----------------------------------------------------------------------

        case GxB_HYPERSPARSE + GxB_FULL : 

            if (as_if_full)
            { 
                // if all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else
            { 
                // otherwise: to hypersparse
                GB_OK (GB_convert_any_to_hyper (A, Context)) ;
            }
            break ;

        //----------------------------------------------------------------------
        // (10) sparse or full
        //----------------------------------------------------------------------

        case GxB_SPARSE + GxB_FULL :  

            if (as_if_full)
            { 
                // if full or all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else
            { 
                // otherwise: to sparse
                GB_OK (GB_convert_any_to_sparse (A, Context)) ;
            }
            break ;

        //----------------------------------------------------------------------
        // (11) hypersparse, sparse, or full
        //----------------------------------------------------------------------

        case GxB_HYPERSPARSE + GxB_SPARSE + GxB_FULL : 

            if (as_if_full)
            { 
                // if full or all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else if (is_bitmap)
            { 
                // if bitmap: to sparse
                GB_OK (GB_convert_bitmap_to_sparse (A, Context)) ;
                // conform between sparse and hypersparse
                GB_OK (GB_conform_hyper (A, Context)) ;
            }
            else
            { 
                // conform between sparse and hypersparse
                GB_OK (GB_conform_hyper (A, Context)) ;
            }
            break ;

        //----------------------------------------------------------------------
        // (12): bitmap or full
        //----------------------------------------------------------------------

        case GxB_BITMAP + GxB_FULL : 

            if (as_if_full)
            { 
                // if full or all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else
            { 
                // otherwise: to bitmap
                GB_OK (GB_convert_any_to_bitmap (A, Context)) ;
            }
            break ;

        //----------------------------------------------------------------------
        // (13) hypersparse, bitmap, or full
        //----------------------------------------------------------------------

        case GxB_HYPERSPARSE + GxB_BITMAP + GxB_FULL : 

            if (as_if_full)
            { 
                // if full or all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else
            { 
                // ensure the matrix is hypersparse or bitmap
                GB_OK (GB_conform_hyper_or_bitmap (is_hyper, is_sparse,
                    is_bitmap, is_full, A, Context)) ;
            }
            break ;

        //----------------------------------------------------------------------
        // (14) sparse, bitmap, or full
        //----------------------------------------------------------------------

        case GxB_SPARSE + GxB_BITMAP + GxB_FULL : 

            if (as_if_full)
            { 
                // if full or all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else
            { 
                // ensure the matrix is sparse or bitmap
                GB_OK (GB_conform_sparse_or_bitmap (is_hyper, is_sparse,
                    is_bitmap, is_full, A, Context)) ;
            }
            break ;

        //----------------------------------------------------------------------
        // (15) hypersparse, sparse, bitmap, or full
        //----------------------------------------------------------------------

        default:
        case GxB_HYPERSPARSE + GxB_SPARSE + GxB_BITMAP + GxB_FULL : 

            if (as_if_full)
            { 
                // if full or all entries present: to full
                GB_convert_any_to_full (A) ;
            }
            else
            { 
                // ensure the matrix is hypersparse, sparse, or bitmap
                GB_OK (GB_conform_hyper_sparse_or_bitmap (is_hyper, is_sparse,
                    is_bitmap, is_full, A, Context)) ;
            }
            break ;
    }

    //--------------------------------------------------------------------------
    // return result
    //--------------------------------------------------------------------------

    ASSERT_MATRIX_OK (A, "A conformed", GB0) ;
    return (GrB_SUCCESS) ;
}