File: GB_all_entries_are_iso.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (139 lines) | stat: -rw-r--r-- 5,598 bytes parent folder | download | duplicates (2)
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
//------------------------------------------------------------------------------
// GB_all_entries_are_iso: check if all entries in a matrix are identical
//------------------------------------------------------------------------------

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

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

// Returns true if all entries in A are the same, and A can then be converted
// to iso if currently non-iso.  Returns false if A is bitmap, has any zombies,
// or has or pending tuples, since these are more costly to check.

// User-defined types of sizes 1, 2, 4, 8, and 16 bytes can be tested by using
// the built-in uint* types of those sizes.  Different sizes cannot be checked
// with a JIT since "a == b" is not defined in C11 if a and b are structs.
// Instead, memcmp (a, b, sizeof (type)) is used instead.

#include "GB.h"

bool GB_all_entries_are_iso // return true if A is iso, false otherwise
(
    const GrB_Matrix A      // matrix to test if all entries are the same
)
{

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

    if (A == NULL || GB_nnz (A) == 0 || GB_nnz_held (A) == 0)
    { 
        // empty matrices cannot be iso
        return (false) ;
    }
    else if (A->iso)
    { 
        // nothing to do; A is already iso
        return (true) ;
    }
    else if (GB_PENDING (A) || GB_ZOMBIES (A) || GB_IS_BITMAP (A))
    { 
        // Non-iso matrices with pending work are assumed to be non-iso.
        // Bitmap matrices and matrices with zombies could be checked, but
        // finding the first entry is tedious so this is skipped.  Matrices
        // with pending work could be finished first, but this is costly so it
        // is skipped.
        return (false) ;
    }

    ASSERT (!GB_ZOMBIES (A)) ;
    ASSERT (GB_JUMBLED_OK (A)) ;
    ASSERT (!GB_PENDING (A)) ;
    ASSERT (!GB_IS_BITMAP (A)) ;
    ASSERT_MATRIX_OK (A, "A input for GB_all_entries_are_iso", GB0) ;

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

    int64_t asize = A->type->size ;
    int64_t anz = GB_nnz_held (A) ;

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

    int nthreads = 0, ntasks = 0 ;
    int nthreads_max = GB_Context_nthreads_max ( ) ;
    double chunk = GB_Context_chunk ( ) ;
    nthreads = GB_nthreads (anz, chunk, nthreads_max) ;
    ntasks = (nthreads == 1) ? 1 : (64 * nthreads) ;
    ntasks = GB_IMIN (ntasks, anz) ;
    ntasks = GB_IMAX (ntasks, 1) ;

    //--------------------------------------------------------------------------
    // check if A is iso: built-in types and user-defined with sizes 1,2,4,8,16
    //--------------------------------------------------------------------------

    #define GB_GET_FIRST_VALUE(atype_t, a, Ax)                      \
        const atype_t a = Ax [0]
    #define GB_COMPARE_WITH_FIRST_VALUE(my_iso, a, Ax, p)           \
        my_iso = my_iso & (a == Ax [p])

    bool iso = true ;       // A is iso until proven otherwise

    switch (asize)
    {
        case GB_1BYTE : // uint8, int8, bool, or 1-byte user
            #define GB_A_TYPE uint8_t
            #include "iso/factory/GB_all_entries_are_iso_template.c"
            break ;

        case GB_2BYTE : // uint16, int16, or 2-byte user
            #define GB_A_TYPE uint16_t
            #include "iso/factory/GB_all_entries_are_iso_template.c"
            break ;

        case GB_4BYTE : // uint32, int32, float, or 4-byte user
            #define GB_A_TYPE uint32_t
            #include "iso/factory/GB_all_entries_are_iso_template.c"
            break ;

        case GB_8BYTE : // uint64, int64, double, float complex,
                        // or 8-byte user defined
            #define GB_A_TYPE uint64_t
            #include "iso/factory/GB_all_entries_are_iso_template.c"
            break ;

        case GB_16BYTE : // double complex or 16-byte user
            #define GB_A_TYPE uint64_t
            #undef  GB_GET_FIRST_VALUE
            #define GB_GET_FIRST_VALUE(atype_t, a, Ax)              \
                const atype_t a ## 0 = Ax [0] ;                     \
                const atype_t a ## 1 = Ax [1] ;
            #undef  GB_COMPARE_WITH_FIRST_VALUE
            #define GB_COMPARE_WITH_FIRST_VALUE(my_iso, a, Ax, p)   \
                my_iso = my_iso & (a ## 0 == Ax [2*(p)  ])          \
                                & (a ## 1 == Ax [2*(p)+1])
            #include "iso/factory/GB_all_entries_are_iso_template.c"
            break ;

        default : // with user-defined types of any size

            #define GB_A_TYPE GB_void
            #undef  GB_GET_FIRST_VALUE
            #define GB_GET_FIRST_VALUE(atype_t, a, Ax)              \
                GB_void a [GB_VLA(asize)] ;                         \
                memcpy (a, Ax, asize) ;
            #undef  GB_COMPARE_WITH_FIRST_VALUE
            #define GB_COMPARE_WITH_FIRST_VALUE(my_iso, a, Ax, p)   \
                my_iso = my_iso & (memcmp (a, Ax + (p)*asize, asize) == 0)
            #include "iso/factory/GB_all_entries_are_iso_template.c"
            break ;
    }

    return (iso) ;
}