1 //------------------------------------------------------------------------------
2 // GB_bitmap_select_template: C=select(A,thunk) if A is bitmap or full
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 // Ab and Cb can be aliased, if A is bitmap and the selection is done in-place.
11 // Ax and Cx are not aliased.
12 
13 // TODO: If done in-place, Cx can be passed as NULL.  Then if A is not bitmap,
14 // C->b needs to be allocated, but not C->x.
15 
16 // the following macro is awkward but currently needed for the user_select op:
17 #undef  GBI
18 #define GBI(Ai,p,avlen) i
19 
20 {
21     int8_t *Ab = A->b ;
22     GB_ATYPE *restrict Ax = (GB_ATYPE *) A->x ;
23     const int64_t avlen = A->vlen ;
24     const int64_t avdim = A->vdim ;
25     const size_t asize = A->type->size ;
26     const int64_t anz = avlen * avdim ;
27     int64_t pA, cnvals = 0 ;
28     #pragma omp parallel for num_threads(nthreads) schedule(static) \
29         reduction(+:cnvals)
30     for (pA = 0 ; pA < anz ; pA++)
31     {
32         int64_t i = pA % avlen ;
33         int64_t j = pA / avlen ;
34         #if defined ( GB_ENTRY_SELECTOR )
35             // test the existence and value of A(i,j)
36             int8_t cb = GBB (Ab, pA) && GB_TEST_VALUE_OF_ENTRY (pA) ;
37         #else
38             // test the existence and position of A(i,j)
39             #if defined ( GB_TRIL_SELECTOR )
40             int8_t cb = GBB (Ab, pA) && (j-i <= ithunk) ;
41             #elif defined ( GB_TRIU_SELECTOR )
42             int8_t cb = GBB (Ab, pA) && (j-i >= ithunk) ;
43             #elif defined ( GB_DIAG_SELECTOR )
44             int8_t cb = GBB (Ab, pA) && (j-i == ithunk) ;
45             #elif defined ( GB_OFFDIAG_SELECTOR )
46             int8_t cb = GBB (Ab, pA) && (j-i != ithunk) ;
47             #else
48             ASSERT (GB_DEAD_CODE) ;
49             #endif
50         #endif
51         Cb [pA] = cb ;
52         cnvals += cb ;
53         // if (Cx != NULL)
54         {
55             // Cx [pA] = Ax [pA]
56             GB_SELECT_ENTRY (Cx, pA, Ax, pA) ;
57         }
58     }
59     (*cnvals_handle)= cnvals ;
60 }
61 
62