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