1 //------------------------------------------------------------------------------
2 // GB_clear: clears the content of a matrix
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 // All content of A is freed (or removed if shallow) and new A->p and A->h
11 // content is created. This puts the matrix A in the same initialized state it
12 // had after GrB_Matrix_new (&A, ...), with A->magic == GB_MAGIC to denote a
13 // valid, initialized matrix, with nnz(A) equal to zero. The dimensions, type,
14 // and CSR/CSC format are unchanged. The hypersparsity of the newly empty
15 // matrix A is determined by the A->hyper_switch for the matrix. The matrix is
16 // valid.
17
18 // However, if this method runs out of memory, and the A->p and A->h structure
19 // cannot be recreated, then all content of the matrix is freed or removed, and
20 // the matrix A is left in an invalid state (A->magic == GB_MAGIC2). Only the
21 // header is left.
22
23 // A is first converted to sparse or hypersparse, and then conformed via
24 // GB_conform. If A->sparsity disables the sparse and hypersparse structures,
25 // A is converted bitmap instead.
26
27 #include "GB.h"
28
GB_clear(GrB_Matrix A,GB_Context Context)29 GrB_Info GB_clear // clear a matrix, type and dimensions unchanged
30 (
31 GrB_Matrix A, // matrix to clear
32 GB_Context Context
33 )
34 {
35
36 //--------------------------------------------------------------------------
37 // check inputs
38 //--------------------------------------------------------------------------
39
40 ASSERT (A != NULL) ;
41 ASSERT (A->magic == GB_MAGIC || A->magic == GB_MAGIC2) ;
42
43 // zombies and pending tuples have no effect; about to delete them anyway
44 ASSERT (GB_ZOMBIES_OK (A)) ;
45 ASSERT (GB_JUMBLED_OK (A)) ;
46 ASSERT (GB_PENDING_OK (A)) ;
47
48 //--------------------------------------------------------------------------
49 // clear the content of A if bitmap
50 //--------------------------------------------------------------------------
51
52 GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
53 int sparsity = GB_sparsity_control (A->sparsity, A->vdim) ;
54 if (((sparsity & (GxB_SPARSE + GxB_HYPERSPARSE)) == 0) && GB_IS_BITMAP (A))
55 {
56 // A should remain bitmap
57 GB_memset (A->b, 0, GB_NNZ_HELD (A), nthreads_max) ;
58 A->nvals = 0 ;
59 A->magic = GB_MAGIC ;
60 return (GrB_SUCCESS) ;
61 }
62
63 //--------------------------------------------------------------------------
64 // clear the content of A
65 //--------------------------------------------------------------------------
66
67 // free all content
68 GB_phbix_free (A) ;
69
70 // no more zombies or pending tuples
71 ASSERT (!GB_ZOMBIES (A)) ;
72 ASSERT (!GB_JUMBLED (A)) ;
73 ASSERT (!GB_PENDING (A)) ;
74
75 //--------------------------------------------------------------------------
76 // allocate new A->p and A->h components
77 //--------------------------------------------------------------------------
78
79 // By default, an empty matrix with n > 1 vectors is held in hypersparse
80 // form. A GrB_Matrix with n <= 1, or a GrB_Vector (with n == 1) is always
81 // non-hypersparse. If A->hyper_switch is negative, A will be always be
82 // non-hypersparse.
83
84 if (GB_convert_hyper_to_sparse_test (A->hyper_switch, 0, A->vdim))
85 {
86
87 //----------------------------------------------------------------------
88 // A is sparse
89 //----------------------------------------------------------------------
90
91 int64_t plen = A->vdim ;
92 A->nvec = plen ;
93 A->plen = plen ;
94 A->p = GB_MALLOC (plen+1, int64_t, &(A->p_size)) ;
95 ASSERT (A->h == NULL) ;
96 if (A->p == NULL)
97 {
98 // out of memory
99 GB_phbix_free (A) ;
100 return (GrB_OUT_OF_MEMORY) ;
101 }
102 GB_memset (A->p, 0, (plen+1) * sizeof (int64_t), nthreads_max) ;
103
104 }
105 else
106 {
107
108 //----------------------------------------------------------------------
109 // A is hypersparse
110 //----------------------------------------------------------------------
111
112 int64_t plen = GB_IMIN (1, A->vdim) ;
113 A->nvec = 0 ;
114 A->plen = plen ;
115 A->p = GB_MALLOC (plen+1, int64_t, &(A->p_size)) ;
116 A->h = GB_MALLOC (plen , int64_t, &(A->h_size)) ;
117 if (A->p == NULL || A->h == NULL)
118 {
119 // out of memory
120 GB_phbix_free (A) ;
121 return (GrB_OUT_OF_MEMORY) ;
122 }
123 A->p [0] = 0 ;
124 if (plen > 0)
125 {
126 A->p [1] = 0 ;
127 A->h [0] = 0 ;
128 }
129 }
130
131 A->magic = GB_MAGIC ;
132
133 //--------------------------------------------------------------------------
134 // conform A to its desired sparsity
135 //--------------------------------------------------------------------------
136
137 return (GB_conform (A, Context)) ;
138 }
139
140