1 //------------------------------------------------------------------------------
2 // GB_convert_full_to_sparse: convert a matrix from full to sparse
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 #include "GB.h"
11 
GB_convert_full_to_sparse(GrB_Matrix A,GB_Context Context)12 GrB_Info GB_convert_full_to_sparse      // convert matrix from full to sparse
13 (
14     GrB_Matrix A,               // matrix to convert from full to sparse
15     GB_Context Context
16 )
17 {
18 
19     //--------------------------------------------------------------------------
20     // check inputs
21     //--------------------------------------------------------------------------
22 
23     ASSERT_MATRIX_OK (A, "A converting full to sparse", GB0) ;
24     ASSERT (GB_IS_FULL (A) || A->nzmax == 0) ;
25     ASSERT (!GB_IS_BITMAP (A)) ;
26     ASSERT (!GB_IS_SPARSE (A)) ;
27     ASSERT (!GB_IS_HYPERSPARSE (A)) ;
28     ASSERT (!GB_ZOMBIES (A)) ;
29     ASSERT (!GB_JUMBLED (A)) ;
30     ASSERT (!GB_PENDING (A)) ;
31     GBURBLE ("(full to sparse) ") ;
32 
33     //--------------------------------------------------------------------------
34     // allocate A->p and A->i
35     //--------------------------------------------------------------------------
36 
37     int64_t avdim = A->vdim ;
38     int64_t avlen = A->vlen ;
39     int64_t anz = avdim * avlen ;
40     ASSERT (GB_Index_multiply (&anz, avdim, avlen) == true) ;
41 
42     int64_t *restrict Ap = NULL ; size_t Ap_size = 0 ;
43     int64_t *restrict Ai = NULL ; size_t Ai_size = 0 ;
44 
45     Ap = GB_MALLOC (avdim+1, int64_t, &Ap_size) ;
46     Ai = GB_MALLOC (anz, int64_t, &Ai_size) ;
47 
48     if (Ap == NULL || Ai == NULL)
49     {
50         // out of memory
51         GB_FREE (&Ap, Ap_size) ;
52         GB_FREE (&Ai, Ai_size) ;
53         return (GrB_OUT_OF_MEMORY) ;
54     }
55 
56     A->p = Ap ; A->p_size = Ap_size ;
57     A->i = Ai ; A->i_size = Ai_size ;
58     A->plen = avdim ;
59     A->nvec = avdim ;
60     A->nvec_nonempty = (avlen == 0) ? 0 : avdim ;
61 
62     //--------------------------------------------------------------------------
63     // determine the number of threads to use
64     //--------------------------------------------------------------------------
65 
66     GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
67     int nthreads = GB_nthreads (anz, chunk, nthreads_max) ;
68 
69     //--------------------------------------------------------------------------
70     // fill the A->p and A->i pattern
71     //--------------------------------------------------------------------------
72 
73     int64_t k ;
74     #pragma omp parallel for num_threads(nthreads) schedule(static)
75     for (k = 0 ; k <= avdim ; k++)
76     {
77         Ap [k] = k * avlen ;
78     }
79 
80     int64_t p ;
81     #pragma omp parallel for num_threads(nthreads) schedule(static)
82     for (p = 0 ; p < anz ; p++)
83     {
84         Ai [p] = p % avlen ;
85     }
86 
87     //--------------------------------------------------------------------------
88     // return result
89     //--------------------------------------------------------------------------
90 
91     ASSERT_MATRIX_OK (A, "A converted from full to sparse", GB0) ;
92     ASSERT (GB_IS_SPARSE (A)) ;
93     ASSERT (!GB_ZOMBIES (A)) ;
94     ASSERT (!GB_JUMBLED (A)) ;
95     ASSERT (!GB_PENDING (A)) ;
96     return (GrB_SUCCESS) ;
97 }
98 
99