1 //------------------------------------------------------------------------------
2 // GB_export: export a matrix or vector
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 // No conversion is done, and the matrix is exported in its current sparsity
11 // structure and by-row/by-col format.
12 
13 #include "GB_export.h"
14 
GB_export(GrB_Matrix * A,GrB_Type * type,GrB_Index * vlen,GrB_Index * vdim,bool is_sparse_vector,GrB_Index ** Ap,GrB_Index * Ap_size,GrB_Index ** Ah,GrB_Index * Ah_size,int8_t ** Ab,GrB_Index * Ab_size,GrB_Index ** Ai,GrB_Index * Ai_size,void ** Ax,GrB_Index * Ax_size,GrB_Index * nvals,bool * jumbled,GrB_Index * nvec,int * sparsity,bool * is_csc,bool * is_uniform,GB_Context Context)15 GrB_Info GB_export      // export a matrix in any format
16 (
17     GrB_Matrix *A,      // handle of matrix to export and free
18     GrB_Type *type,     // type of matrix to export
19     GrB_Index *vlen,    // vector length
20     GrB_Index *vdim,    // vector dimension
21     bool is_sparse_vector,      // true if A is a sparse GrB_Vector
22 
23     // the 5 arrays:
24     GrB_Index **Ap,     // pointers
25     GrB_Index *Ap_size, // size of Ap in bytes
26 
27     GrB_Index **Ah,     // vector indices
28     GrB_Index *Ah_size, // size of Ah in bytes
29 
30     int8_t **Ab,        // bitmap
31     GrB_Index *Ab_size, // size of Ab in bytes
32 
33     GrB_Index **Ai,     // indices
34     GrB_Index *Ai_size, // size of Ai in bytes
35 
36     void **Ax,          // values
37     GrB_Index *Ax_size, // size of Ax in bytes
38 
39     // additional information for specific formats:
40     GrB_Index *nvals,   // # of entries for bitmap format.
41     bool *jumbled,      // if true, sparse/hypersparse may be jumbled.
42     GrB_Index *nvec,    // size of Ah for hypersparse format.
43 
44     // information for all formats:
45     int *sparsity,      // hypersparse, sparse, bitmap, or full
46     bool *is_csc,       // if true then matrix is by-column, else by-row
47     bool *is_uniform,   // if true then A has uniform values and only one
48                         // entry is returned in Ax, regardless of nvals(A).
49                         // TODO::: uniform valued matrices not yet supported
50     GB_Context Context
51 )
52 {
53 
54     //--------------------------------------------------------------------------
55     // check inputs
56     //--------------------------------------------------------------------------
57 
58     ASSERT (A != NULL) ;
59     GB_RETURN_IF_NULL_OR_FAULTY (*A) ;
60     ASSERT_MATRIX_OK (*A, "A to export", GB0) ;
61     ASSERT (!GB_ZOMBIES (*A)) ;
62     ASSERT (GB_JUMBLED_OK (*A)) ;
63     ASSERT (!GB_PENDING (*A)) ;
64 
65     GB_RETURN_IF_NULL (type) ;
66     GB_RETURN_IF_NULL (vlen) ;
67     GB_RETURN_IF_NULL (vdim) ;
68     GB_RETURN_IF_NULL (Ax) ;
69     GB_RETURN_IF_NULL (Ax_size) ;
70 
71     int s = GB_sparsity (*A) ;
72 
73     switch (s)
74     {
75         case GxB_HYPERSPARSE :
76             GB_RETURN_IF_NULL (nvec) ;
77             GB_RETURN_IF_NULL (Ah) ; GB_RETURN_IF_NULL (Ah_size) ;
78 
79         case GxB_SPARSE :
80             if (is_sparse_vector)
81             {
82                 GB_RETURN_IF_NULL (nvals) ;
83             }
84             else
85             {
86                 GB_RETURN_IF_NULL (Ap) ; GB_RETURN_IF_NULL (Ap_size) ;
87             }
88             GB_RETURN_IF_NULL (Ai) ; GB_RETURN_IF_NULL (Ai_size) ;
89             break ;
90 
91         case GxB_BITMAP :
92             GB_RETURN_IF_NULL (nvals) ;
93             GB_RETURN_IF_NULL (Ab) ; GB_RETURN_IF_NULL (Ab_size) ;
94 
95         case GxB_FULL :
96             break ;
97 
98         default: ;
99     }
100 
101     //--------------------------------------------------------------------------
102     // export the matrix
103     //--------------------------------------------------------------------------
104 
105     (*type) = (*A)->type ;
106     (*vlen) = (*A)->vlen ;
107     (*vdim) = (*A)->vdim ;
108 
109     // export A->x
110     #ifdef GB_DEBUG
111     GB_Global_memtable_remove ((*A)->x) ;
112     #endif
113     (*Ax) = (*A)->x ; (*A)->x = NULL ;
114     (*Ax_size) = (*A)->x_size ;
115 
116     switch (s)
117     {
118         case GxB_HYPERSPARSE :
119             (*nvec) = (*A)->nvec ;
120 
121             // export A->h
122             #ifdef GB_DEBUG
123             GB_Global_memtable_remove ((*A)->h) ;
124             #endif
125             (*Ah) = (GrB_Index *) ((*A)->h) ; (*A)->h = NULL ;
126             (*Ah_size) = (*A)->h_size ;
127 
128         case GxB_SPARSE :
129             if (jumbled != NULL)
130             {
131                 (*jumbled) = (*A)->jumbled ;
132             }
133 
134             // export A->p, unless A is a sparse vector in CSC format
135             if (is_sparse_vector)
136             {
137                 (*nvals) = (*A)->p [1] ;
138             }
139             else
140             {
141                 #ifdef GB_DEBUG
142                 GB_Global_memtable_remove ((*A)->p) ;
143                 #endif
144                 (*Ap) = (GrB_Index *) ((*A)->p) ; (*A)->p = NULL ;
145                 (*Ap_size) = (*A)->p_size ;
146             }
147 
148             // export A->i
149             #ifdef GB_DEBUG
150             GB_Global_memtable_remove ((*A)->i) ;
151             #endif
152             (*Ai) = (GrB_Index *) ((*A)->i) ; (*A)->i = NULL ;
153             (*Ai_size) = (*A)->i_size ;
154             break ;
155 
156         case GxB_BITMAP :
157             (*nvals) = (*A)->nvals ;
158 
159             // export A->b
160             #ifdef GB_DEBUG
161             GB_Global_memtable_remove ((*A)->b) ;
162             #endif
163             (*Ab) = (*A)->b ; (*A)->b = NULL ;
164             (*Ab_size) = (*A)->b_size ;
165 
166         case GxB_FULL :
167 
168         default: ;
169     }
170 
171     if (sparsity != NULL)
172     {
173         (*sparsity) = s ;
174     }
175     if (is_csc != NULL)
176     {
177         (*is_csc) = (*A)->is_csc ;
178     }
179     if (is_uniform != NULL)
180     {
181         (*is_uniform) = false ;     // TODO::: uniform-valued matrices
182     }
183 
184     //--------------------------------------------------------------------------
185     // free the GrB_Matrix
186     //--------------------------------------------------------------------------
187 
188     // frees the header of A, and A->p if A is a sparse GrB_Vector
189     GB_Matrix_free (A) ;
190     ASSERT ((*A) == NULL) ;
191     return (GrB_SUCCESS) ;
192 }
193 
194