File: GB_unjumble.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 (153 lines) | stat: -rw-r--r-- 5,249 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
//------------------------------------------------------------------------------
// GB_unjumble: unjumble the vectors of a matrix
//------------------------------------------------------------------------------

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

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

#include "GB_sort.h"

GrB_Info GB_unjumble        // unjumble a matrix
(
    GrB_Matrix A,           // matrix to unjumble
    GB_Context Context
)
{

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

    ASSERT_MATRIX_OK (A, "A to unjumble", GB0) ;
    ASSERT (!GB_ZOMBIES (A)) ;      // zombies must be killed first
    ASSERT (GB_PENDING_OK (A)) ;    // pending tuples are not modified

    if (A->nvec_nonempty < 0)
    { 
        A->nvec_nonempty = GB_nvec_nonempty (A, Context) ;
    }

    if (!A->jumbled)
    { 
        // nothing to do
        return (GrB_SUCCESS) ;
    }

    // full and bitmap matrices are never jumbled 
    ASSERT (!GB_IS_FULL (A)) ;
    ASSERT (!GB_IS_BITMAP (A)) ;
    ASSERT (GB_IS_SPARSE (A) || GB_IS_HYPERSPARSE (A)) ;

    //--------------------------------------------------------------------------
    // get A
    //--------------------------------------------------------------------------

    const int64_t anvec = A->nvec ;
    const int64_t anz = GB_nnz (A) ;
    const int64_t *restrict Ap = A->p ;
    int64_t *restrict Ai = A->i ;
    const size_t asize = (A->iso) ? 0 : A->type->size ;

    //--------------------------------------------------------------------------
    // determine the number of threads to use
    //--------------------------------------------------------------------------

    GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
    int nthreads = GB_nthreads (anz + anvec, chunk, nthreads_max) ;
    int ntasks = (nthreads == 1) ? 1 : (32 * nthreads) ;
    ntasks = GB_IMIN (ntasks, anvec) ;
    ntasks = GB_IMAX (ntasks, 1) ;

    //--------------------------------------------------------------------------
    // slice the work
    //--------------------------------------------------------------------------

    GB_WERK_DECLARE (A_slice, int64_t) ;
    GB_WERK_PUSH (A_slice, ntasks + 1, int64_t) ;
    if (A_slice == NULL)
    { 
        // out of memory
        return (GrB_OUT_OF_MEMORY) ;
    }
    GB_pslice (A_slice, Ap, anvec, ntasks, false) ;

    //--------------------------------------------------------------------------
    // sort the vectors
    //--------------------------------------------------------------------------

    switch (asize)
    {
        case 0 : // iso matrices of any type; only sort the pattern
            #define GB_QSORT \
                GB_qsort_1 (Ai+pA_start, aknz) ;
            #include "GB_unjumbled_template.c"
            break ;

        case GB_1BYTE : // bool, uint8, int8, and user defined types of size 1
        {
            uint8_t *Ax = (uint8_t *) A->x ;
            #define GB_QSORT \
                GB_qsort_1b_size1 (Ai+pA_start, Ax+pA_start, aknz) ;
            #include "GB_unjumbled_template.c"
        }
        break ;

        case GB_2BYTE : // uint16, int16, and user-defined types of size 2
        {
            uint16_t *Ax = (uint16_t *) A->x ;
            #define GB_QSORT \
                GB_qsort_1b_size2 (Ai+pA_start, Ax+pA_start, aknz) ;
            #include "GB_unjumbled_template.c"
        }
        break ;

        case GB_4BYTE : // uint32, int32, float, and 4-byte user
        {
            uint32_t *Ax = (uint32_t *) A->x ;
            #define GB_QSORT \
                GB_qsort_1b_size4 (Ai+pA_start, Ax+pA_start, aknz) ;
            #include "GB_unjumbled_template.c"
        }
        break ;

        case GB_8BYTE : // uint64, int64, double, float complex, and 8-byte user
        {
            uint64_t *Ax = (uint64_t *) A->x ;
            #define GB_QSORT \
                GB_qsort_1b_size8 (Ai+pA_start, Ax+pA_start, aknz) ;
            #include "GB_unjumbled_template.c"
        }
        break ;

        case GB_16BYTE : // double complex, and user-defined types of size 16
        {
            GB_blob16 *Ax = (GB_blob16 *) A->x ;
            #define GB_QSORT \
                GB_qsort_1b_size16 (Ai+pA_start, Ax+pA_start, aknz) ;
            #include "GB_unjumbled_template.c"
        }
        break ;

        default : // user-defined types of arbitrary size
        {
            GB_void *Ax = (GB_void *) A->x ;
            #define GB_QSORT \
                GB_qsort_1b (Ai+pA_start, Ax+pA_start*asize, asize, aknz) ;
            #include "GB_unjumbled_template.c"
        }
        break ;
    }

    //--------------------------------------------------------------------------
    // free workspace and return result
    //--------------------------------------------------------------------------

    GB_WERK_POP (A_slice, int64_t) ;
    A->jumbled = false ;        // A has been unjumbled
    ASSERT_MATRIX_OK (A, "A unjumbled", GB0) ;
    ASSERT (A->nvec_nonempty >= 0)
    return (GrB_SUCCESS) ;
}