1 //------------------------------------------------------------------------------
2 // GB_assign_zombie2: delete all entries in C(i,:) for GB_assign
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 // C(i,:)<!> = anything: GrB_Row_assign or GrB_Col_assign with an empty
11 // complemented mask requires all entries in C(i,:) to be deleted.
12 // C must be sparse or hypersparse.
13 
14 #include "GB_assign.h"
15 #include "GB_assign_zombie.h"
16 
GB_assign_zombie2(GrB_Matrix C,const int64_t i,GB_Context Context)17 void GB_assign_zombie2
18 (
19     GrB_Matrix C,
20     const int64_t i,
21     GB_Context Context
22 )
23 {
24 
25     //--------------------------------------------------------------------------
26     // check inputs
27     //--------------------------------------------------------------------------
28 
29     ASSERT (!GB_IS_FULL (C)) ;
30     ASSERT (!GB_IS_BITMAP (C)) ;
31     ASSERT (GB_ZOMBIES_OK (C)) ;
32     ASSERT (!GB_JUMBLED (C)) ;      // binary search is used
33     ASSERT (!GB_PENDING (C)) ;
34 
35     //--------------------------------------------------------------------------
36     // get C
37     //--------------------------------------------------------------------------
38 
39     const int64_t *restrict Cp = C->p ;
40     int64_t *restrict Ci = C->i ;
41     const int64_t Cnvec = C->nvec ;
42     int64_t nzombies = C->nzombies ;
43     const int64_t zorig = nzombies ;
44 
45     //--------------------------------------------------------------------------
46     // determine the number of threads to use
47     //--------------------------------------------------------------------------
48 
49     GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
50     int nthreads = GB_nthreads (Cnvec, chunk, nthreads_max) ;
51     int ntasks = (nthreads == 1) ? 1 : (64 * nthreads) ;
52 
53     //--------------------------------------------------------------------------
54     // C(i,:) = empty
55     //--------------------------------------------------------------------------
56 
57     int taskid ;
58     #pragma omp parallel for num_threads(nthreads) schedule(dynamic,1) \
59         reduction(+:nzombies)
60     for (taskid = 0 ; taskid < ntasks ; taskid++)
61     {
62         int64_t kfirst, klast ;
63         GB_PARTITION (kfirst, klast, Cnvec, taskid, ntasks) ;
64         for (int64_t k = kfirst ; k < klast ; k++)
65         {
66 
67             //------------------------------------------------------------------
68             // find C(i,j)
69             //------------------------------------------------------------------
70 
71             int64_t pC = Cp [k] ;
72             int64_t pC_end = Cp [k+1] ;
73             int64_t pright = pC_end - 1 ;
74             bool found, is_zombie ;
75             GB_BINARY_SEARCH_ZOMBIE (i, Ci, pC, pright, found, zorig,
76                 is_zombie) ;
77 
78             //------------------------------------------------------------------
79             // if found and not a zombie, mark it as a zombie
80             //------------------------------------------------------------------
81 
82             if (found && !is_zombie)
83             {
84                 ASSERT (i == Ci [pC]) ;
85                 nzombies++ ;
86                 Ci [pC] = GB_FLIP (i) ;
87             }
88         }
89     }
90 
91     //--------------------------------------------------------------------------
92     // return result
93     //--------------------------------------------------------------------------
94 
95     C->nzombies = nzombies ;
96 }
97 
98