File: GB_clear.c

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 506; asm: 369; python: 125; awk: 10
file content (140 lines) | stat: -rw-r--r-- 5,086 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//------------------------------------------------------------------------------
// GB_clear: clears the content of a matrix
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// All content of A is freed (or removed if shallow) and new A->p and A->h
// content is created.  This puts the matrix A in the same initialized state it
// had after GrB_Matrix_new (&A, ...), with A->magic == GB_MAGIC to denote a
// valid, initialized matrix, with nnz(A) equal to zero.  The dimensions, type,
// and CSR/CSC format are unchanged.  The hypersparsity of the newly empty
// matrix A is determined by the A->hyper_switch for the matrix.  The matrix is
// valid.

// However, if this method runs out of memory, and the A->p and A->h structure
// cannot be recreated, then all content of the matrix is freed or removed, and
// the matrix A is left in an invalid state (A->magic == GB_MAGIC2).  Only the
// header is left.

// A is first converted to sparse or hypersparse, and then conformed via
// GB_conform.  If A->sparsity_control disables the sparse and hypersparse
// structures, A is converted bitmap instead.

#include "GB.h"

GrB_Info GB_clear           // clear a matrix, type and dimensions unchanged
(
    GrB_Matrix A,           // matrix to clear
    GB_Context Context
)
{

    //--------------------------------------------------------------------------
    // check inputs
    //--------------------------------------------------------------------------

    ASSERT (A != NULL) ;
    ASSERT (A->magic == GB_MAGIC || A->magic == GB_MAGIC2) ;

    // zombies and pending tuples have no effect; about to delete them anyway
    ASSERT (GB_ZOMBIES_OK (A)) ;
    ASSERT (GB_JUMBLED_OK (A)) ;
    ASSERT (GB_PENDING_OK (A)) ;

    //--------------------------------------------------------------------------
    // clear the content of A if bitmap
    //--------------------------------------------------------------------------

    GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
    int sparsity_control = GB_sparsity_control (A->sparsity_control, A->vdim) ;
    if (((sparsity_control & (GxB_SPARSE + GxB_HYPERSPARSE)) == 0)
        && GB_IS_BITMAP (A))
    { 
        // A should remain bitmap
        GB_memset (A->b, 0, GB_nnz_held (A), nthreads_max) ;
        A->nvals = 0 ;
        A->magic = GB_MAGIC ;
        return (GrB_SUCCESS) ;
    }

    //--------------------------------------------------------------------------
    // clear the content of A
    //--------------------------------------------------------------------------

    // free all content
    GB_phybix_free (A) ;

    // no more zombies or pending tuples
    ASSERT (!GB_ZOMBIES (A)) ;
    ASSERT (!GB_JUMBLED (A)) ;
    ASSERT (!GB_PENDING (A)) ;

    //--------------------------------------------------------------------------
    // allocate new A->p and A->h components
    //--------------------------------------------------------------------------

    // By default, an empty matrix with n > 1 vectors is held in hypersparse
    // form.  A GrB_Matrix with n <= 1, or a GrB_Vector (with n == 1) is always
    // non-hypersparse.  If A->hyper_switch is negative, A will be always be
    // non-hypersparse.

    if (GB_convert_hyper_to_sparse_test (A->hyper_switch, 0, A->vdim))
    {

        //----------------------------------------------------------------------
        // A is sparse
        //----------------------------------------------------------------------

        int64_t plen = A->vdim ;
        A->nvec = plen ;
        A->plen = plen ;
        A->p = GB_MALLOC (plen+1, int64_t, &(A->p_size)) ;
        ASSERT (A->h == NULL) ;
        if (A->p == NULL)
        { 
            // out of memory
            GB_phybix_free (A) ;
            return (GrB_OUT_OF_MEMORY) ;
        }
        GB_memset (A->p, 0, (plen+1) * sizeof (int64_t), nthreads_max) ;

    }
    else
    {

        //----------------------------------------------------------------------
        // A is hypersparse
        //----------------------------------------------------------------------

        int64_t plen = GB_IMIN (1, A->vdim) ;
        A->nvec = 0 ;
        A->plen = plen ;
        A->p = GB_MALLOC (plen+1, int64_t, &(A->p_size)) ;
        A->h = GB_MALLOC (plen  , int64_t, &(A->h_size)) ;
        if (A->p == NULL || A->h == NULL)
        { 
            // out of memory
            GB_phybix_free (A) ;
            return (GrB_OUT_OF_MEMORY) ;
        }
        A->p [0] = 0 ;
        if (plen > 0)
        { 
            A->p [1] = 0 ;
            A->h [0] = 0 ;
        }
    }

    A->magic = GB_MAGIC ;

    //--------------------------------------------------------------------------
    // conform A to its desired sparsity 
    //--------------------------------------------------------------------------

    return (GB_conform (A, Context)) ;
}