1 //------------------------------------------------------------------------------
2 // GB_masker_phase1: find # of entries in R = masker (C,M,Z)
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 // GB_masker_phase1 counts the number of entries in each vector of R, for R =
11 // masker (C,M,Z), and then does a cumulative sum to find Cp.  GB_masker_phase1
12 // is preceded by GB_add_phase0, which finds the non-empty vectors of R.  This
13 // phase is done entirely in parallel.
14 
15 // R, M, C, and Z can be standard sparse or hypersparse, as determined by
16 // GB_add_phase0.  All cases of the mask M are handled: present and not
17 // complemented, and present and complemented.  The mask is always present for
18 // R=masker(C,M,Z).
19 
20 // Rp is either freed by phase2, or transplanted into R.
21 
22 #include "GB_mask.h"
23 #include "GB_unused.h"
24 
GB_masker_phase1(int64_t ** Rp_handle,size_t * Rp_size_handle,int64_t * Rnvec_nonempty,GB_task_struct * restrict TaskList,const int R_ntasks,const int R_nthreads,const int64_t Rnvec,const int64_t * restrict Rh,const int64_t * restrict R_to_M,const int64_t * restrict R_to_C,const int64_t * restrict R_to_Z,const GrB_Matrix M,const bool Mask_comp,const bool Mask_struct,const GrB_Matrix C,const GrB_Matrix Z,GB_Context Context)25 GrB_Info GB_masker_phase1           // count nnz in each R(:,j)
26 (
27     // computed by phase1:
28     int64_t **Rp_handle,            // output of size Rnvec+1
29     size_t *Rp_size_handle,
30     int64_t *Rnvec_nonempty,        // # of non-empty vectors in R
31     // tasks from phase1a:
32     GB_task_struct *restrict TaskList,       // array of structs
33     const int R_ntasks,               // # of tasks
34     const int R_nthreads,             // # of threads to use
35     // analysis from phase0:
36     const int64_t Rnvec,
37     const int64_t *restrict Rh,
38     const int64_t *restrict R_to_M,
39     const int64_t *restrict R_to_C,
40     const int64_t *restrict R_to_Z,
41     // original input:
42     const GrB_Matrix M,             // required mask
43     const bool Mask_comp,           // if true, then M is complemented
44     const bool Mask_struct,         // if true, use the only structure of M
45     const GrB_Matrix C,
46     const GrB_Matrix Z,
47     GB_Context Context
48 )
49 {
50 
51     //--------------------------------------------------------------------------
52     // check inputs
53     //--------------------------------------------------------------------------
54 
55     ASSERT (Rp_handle != NULL) ;
56     ASSERT (Rp_size_handle != NULL) ;
57     ASSERT (Rnvec_nonempty != NULL) ;
58 
59     ASSERT_MATRIX_OK (M, "M for mask phase1", GB0) ;
60     ASSERT (!GB_ZOMBIES (M)) ;
61     ASSERT (!GB_JUMBLED (M)) ;
62     ASSERT (!GB_PENDING (M)) ;
63 
64     ASSERT_MATRIX_OK (C, "C for mask phase1", GB0) ;
65     ASSERT (!GB_ZOMBIES (C)) ;
66     ASSERT (!GB_JUMBLED (C)) ;
67     ASSERT (!GB_PENDING (C)) ;
68 
69     ASSERT_MATRIX_OK (Z, "Z for mask phase1", GB0) ;
70     ASSERT (!GB_ZOMBIES (Z)) ;
71     ASSERT (!GB_JUMBLED (Z)) ;
72     ASSERT (!GB_PENDING (Z)) ;
73 
74     ASSERT (!GB_IS_BITMAP (C)) ;    // not used if C is bitmap
75 
76     ASSERT (C->vdim == Z->vdim && C->vlen == Z->vlen) ;
77     ASSERT (C->vdim == M->vdim && C->vlen == M->vlen) ;
78 
79     int64_t *restrict Rp = NULL ; size_t Rp_size = 0 ;
80     (*Rp_handle) = NULL ;
81 
82     //--------------------------------------------------------------------------
83     // allocate the result
84     //--------------------------------------------------------------------------
85 
86     Rp = GB_CALLOC (GB_IMAX (2, Rnvec+1), int64_t, &Rp_size) ;
87     if (Rp == NULL)
88     {
89         // out of memory
90         return (GrB_OUT_OF_MEMORY) ;
91     }
92 
93     //--------------------------------------------------------------------------
94     // count the entries in each vector of R
95     //--------------------------------------------------------------------------
96 
97     #define GB_PHASE_1_OF_2
98     #include "GB_masker_template.c"
99 
100     //--------------------------------------------------------------------------
101     // cumulative sum of Rp and fine tasks in TaskList
102     //--------------------------------------------------------------------------
103 
104     GB_task_cumsum (Rp, Rnvec, Rnvec_nonempty, TaskList, R_ntasks, R_nthreads,
105         Context) ;
106 
107     //--------------------------------------------------------------------------
108     // return the result
109     //--------------------------------------------------------------------------
110 
111     (*Rp_handle) = Rp ;
112     (*Rp_size_handle) = Rp_size ;
113     return (GrB_SUCCESS) ;
114 }
115 
116