1 //------------------------------------------------------------------------------
2 // GB_subassign_zombie: C(I,J)<!,repl> = empty ; using S
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 // Method 00: C(I,J)<!,repl> = empty ; using S
11 
12 // M:           NULL
13 // Mask_comp:   true
14 // C_replace:   true
15 // accum:       any (present or not; result is the same)
16 // A:           any (scalar or matrix; result is the same)
17 // S:           constructed
18 
19 // C: not bitmap
20 
21 #include "GB_subassign_methods.h"
22 
23 #undef  GB_FREE_ALL
24 #define GB_FREE_ALL GB_phbix_free (S) ;
25 
GB_subassign_zombie(GrB_Matrix C,const GrB_Index * I,const int64_t ni,const int64_t nI,const int Ikind,const int64_t Icolon[3],const GrB_Index * J,const int64_t nj,const int64_t nJ,const int Jkind,const int64_t Jcolon[3],GB_Context Context)26 GrB_Info GB_subassign_zombie
27 (
28     GrB_Matrix C,
29     // input:
30     const GrB_Index *I,
31     const int64_t ni,
32     const int64_t nI,
33     const int Ikind,
34     const int64_t Icolon [3],
35     const GrB_Index *J,
36     const int64_t nj,
37     const int64_t nJ,
38     const int Jkind,
39     const int64_t Jcolon [3],
40     GB_Context Context
41 )
42 {
43 
44     //--------------------------------------------------------------------------
45     // check inputs
46     //--------------------------------------------------------------------------
47 
48     ASSERT (!GB_IS_BITMAP (C)) ; ASSERT (!GB_IS_FULL (C)) ;
49 
50     //--------------------------------------------------------------------------
51     // S = C(I,J)
52     //--------------------------------------------------------------------------
53 
54     GrB_Info info ;
55     struct GB_Matrix_opaque S_header ;
56     GrB_Matrix S = GB_clear_static_header (&S_header) ;
57     GB_OK (GB_subassign_symbolic (S, C, I, ni, J, nj, false, Context)) ;
58     ASSERT (GB_JUMBLED_OK (S)) ;        // S can be returned as jumbled
59 
60     //--------------------------------------------------------------------------
61     // get inputs
62     //--------------------------------------------------------------------------
63 
64     const int64_t *restrict Sx = (int64_t *) S->x ;
65     int64_t *restrict Ci = C->i ;
66 
67     //--------------------------------------------------------------------------
68     // Method 00: C(I,J)<!,repl> = empty ; using S
69     //--------------------------------------------------------------------------
70 
71     // Time: Optimal, O(nnz(S)), assuming S has already been constructed.
72 
73     //--------------------------------------------------------------------------
74     // Parallel: all entries in S can be processed entirely in parallel.
75     //--------------------------------------------------------------------------
76 
77     // All entries in C(I,J) are deleted.  The result does not depend on A or
78     // the scalar.
79 
80     int64_t snz = GB_NNZ (S) ;
81 
82     GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
83     int nthreads = GB_nthreads (snz, chunk, nthreads_max) ;
84 
85     int64_t nzombies = C->nzombies ;
86 
87     int64_t pS ;
88     #pragma omp parallel for num_threads(nthreads) schedule(static) \
89         reduction(+:nzombies)
90     for (pS = 0 ; pS < snz ; pS++)
91     {
92         // S (inew,jnew) is a pointer back into C (I(inew), J(jnew))
93         int64_t pC = Sx [pS] ;
94         int64_t i = Ci [pC] ;
95         // ----[X A 0] or [X . 0]-----------------------------------------------
96         // action: ( X ): still a zombie
97         // ----[C A 0] or [C . 0]-----------------------------------------------
98         // action: C_repl: ( delete ): becomes a zombie
99         if (!GB_IS_ZOMBIE (i))
100         {
101             nzombies++ ;
102             Ci [pC] = GB_FLIP (i) ;
103         }
104     }
105 
106     //--------------------------------------------------------------------------
107     // free workspace and return result
108     //--------------------------------------------------------------------------
109 
110     C->nzombies = nzombies ;
111     GB_FREE_ALL ;
112     return (GrB_SUCCESS) ;
113 }
114 
115