File: GB_select_bitmap.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 (176 lines) | stat: -rw-r--r-- 6,597 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
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
//------------------------------------------------------------------------------
// GB_select_bitmap:  select entries from a bitmap or full matrix
//------------------------------------------------------------------------------

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

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

#include "select/GB_select.h"
#include "jitifyer/GB_stringify.h"
#ifndef GBCOMPACT
#include "FactoryKernels/GB_sel__include.h"
#endif

#define GB_FREE_ALL         \
    GB_phybix_free (C) ;

GrB_Info GB_select_bitmap
(
    GrB_Matrix C,               // output matrix, static header
    const bool C_iso,           // if true, C is iso
    const GrB_IndexUnaryOp op,
    const bool flipij,          // if true, flip i and j for user operator
    GrB_Matrix A,               // input matrix
    const int64_t ithunk,       // (int64_t) Thunk, if Thunk is NULL
    const GB_void *restrict athunk,     // (A->type) Thunk
    const GB_void *restrict ythunk,     // (op->ytype) Thunk
    GB_Werk Werk
)
{

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

    GrB_Info info ;
    ASSERT_MATRIX_OK (A, "A for bitmap selector", GB0) ;
    ASSERT_INDEXUNARYOP_OK (op, "idxunop for bitmap selector", GB0) ;
    ASSERT (GB_IS_BITMAP (A) || GB_IS_FULL (A)) ;
    GB_Opcode opcode = op->opcode ;
    ASSERT (opcode != GB_NONZOMBIE_idxunop_code) ;
    ASSERT (C != NULL && (C->header_size == 0 || GBNSTATIC)) ;

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

    int64_t anz = GB_nnz_held (A) ;
    const size_t asize = A->type->size ;
    const GB_Type_code acode = A->type->code ;

    //--------------------------------------------------------------------------
    // allocate C
    //--------------------------------------------------------------------------

    // C->b and C->x are malloc'd, not calloc'd
    GB_OK (GB_new_bix (&C, // always bitmap, existing header
        A->type, A->vlen, A->vdim, GB_ph_calloc, true,
        GxB_BITMAP, false, A->hyper_switch, -1, anz, true, C_iso,
        /* OK: */ false, false, false)) ;

    ASSERT (GxB_BITMAP == GB_sparsity (C)) ;

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

    int nthreads_max = GB_Context_nthreads_max ( ) ;
    double chunk = GB_Context_chunk ( ) ;
    int nthreads = GB_nthreads (anz, chunk, nthreads_max) ;

    //--------------------------------------------------------------------------
    // copy values of A into C
    //--------------------------------------------------------------------------

    // C and A have the same type, since C is the T matrix from GB_select,
    // not the final user's C matrix.  In the future A could be typecasted
    // into C in the JIT kernel.

    if (C_iso)
    { 
        // Cx [0] = Ax [0] or (A->type) thunk
        GB_select_iso (C->x, opcode, athunk, A->x, asize) ;
    }
    else
    { 
        // Cx [0:anz-1] = Ax [0:anz-1]
        // Fixme for CUDA: do this on the GPU if appropriate
        GB_memcpy (C->x, A->x, anz * asize, nthreads) ;
    }

    //--------------------------------------------------------------------------
    // bitmap selector kernel
    //--------------------------------------------------------------------------

    info = GrB_NO_VALUE ;

    #if defined ( GRAPHBLAS_HAS_CUDA )
    if (GB_cuda_select_branch (A, op))
    {
        info = GB_cuda_select_bitmap (C, A, flipij, ythunk, op) ;
    }
    #endif

    if (info == GrB_NO_VALUE)
    {
        if (GB_IS_INDEXUNARYOP_CODE_POSITIONAL (opcode))
        { 

            //------------------------------------------------------------------
            // bitmap selector for positional ops
            //------------------------------------------------------------------

            info = GB_select_positional_bitmap (C, A, ithunk, op, nthreads) ;
        }
        else
        { 

            //------------------------------------------------------------------
            // bitmap selector for VALUE* and user-defined ops
            //------------------------------------------------------------------

            #ifndef GBCOMPACT
            GB_IF_FACTORY_KERNELS_ENABLED
            { 

                //--------------------------------------------------------------
                // via the factory kernel 
                //--------------------------------------------------------------

                #define GB_selbit(opname,aname) \
                    GB (_sel_bitmap_ ## opname ## aname)
                #define GB_SEL_WORKER(opname,aname)                            \
                {                                                              \
                    info = GB_selbit (opname, aname) (C, A, ythunk, nthreads) ;\
                }                                                              \
                break ;

                #include "select/factory/GB_select_entry_factory.c"
            }
            #endif

            //------------------------------------------------------------------
            // via the JIT or PreJIT kernel
            //------------------------------------------------------------------

            if (info == GrB_NO_VALUE)
            { 
                info = GB_select_bitmap_jit (C, A, flipij, ythunk, op,
                    nthreads) ;
            }

            //------------------------------------------------------------------
            // via the generic kernel 
            //------------------------------------------------------------------

            if (info == GrB_NO_VALUE)
            { 
                GBURBLE ("(generic select) ") ;
                info = GB_select_generic_bitmap (C, A, flipij, ythunk, op,
                    nthreads) ;
            }
        }
    }

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

    GB_OK (info) ;  // check for out-of-memory, or other error
    C->magic = GB_MAGIC ;
    ASSERT_MATRIX_OK (C, "C from bitmap selector", GB0) ;
    return (GrB_SUCCESS) ;
}