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