1 //------------------------------------------------------------------------------
2 // GB_extract_vector_list: extract vector indices for all entries in 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 // Constructs a list of vector indices for each entry in a matrix. Creates
11 // the output J for GB_extractTuples, and I for GB_transpose when the qsort
12 // method is used.
13
14 // TODO: use #include "GB_positional_op_ijp.c" here
15
16 #include "GB_ek_slice.h"
17
18 #define GB_FREE_ALL \
19 { \
20 GB_WERK_POP (A_ek_slicing, int64_t) ; \
21 }
22
GB_extract_vector_list(int64_t * restrict J,const GrB_Matrix A,GB_Context Context)23 GrB_Info GB_extract_vector_list // extract vector list from a matrix
24 (
25 // output:
26 int64_t *restrict J, // size nnz(A) or more
27 // input:
28 const GrB_Matrix A,
29 GB_Context Context
30 )
31 {
32
33 //--------------------------------------------------------------------------
34 // check inputs
35 //--------------------------------------------------------------------------
36
37 ASSERT (J != NULL) ;
38 ASSERT (A != NULL) ;
39 ASSERT (GB_JUMBLED_OK (A)) ; // pattern not accessed
40 ASSERT (GB_ZOMBIES_OK (A)) ; // pattern not accessed
41 ASSERT (!GB_IS_BITMAP (A)) ;
42
43 //--------------------------------------------------------------------------
44 // get A
45 //--------------------------------------------------------------------------
46
47 const int64_t *restrict Ap = A->p ;
48 const int64_t *restrict Ah = A->h ;
49 const int64_t avlen = A->vlen ;
50
51 //--------------------------------------------------------------------------
52 // determine the max number of threads to use
53 //--------------------------------------------------------------------------
54
55 GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
56
57 //--------------------------------------------------------------------------
58 // slice the entries for each task
59 //--------------------------------------------------------------------------
60
61 GB_WERK_DECLARE (A_ek_slicing, int64_t) ;
62 int A_ntasks, A_nthreads ;
63 GB_SLICE_MATRIX (A, 2, chunk) ;
64
65 //--------------------------------------------------------------------------
66 // extract the vector index for each entry
67 //--------------------------------------------------------------------------
68
69 int tid ;
70 #pragma omp parallel for num_threads(A_nthreads) schedule(dynamic,1)
71 for (tid = 0 ; tid < A_ntasks ; tid++)
72 {
73
74 // if kfirst > klast then task tid does no work at all
75 int64_t kfirst = kfirst_Aslice [tid] ;
76 int64_t klast = klast_Aslice [tid] ;
77
78 for (int64_t k = kfirst ; k <= klast ; k++)
79 {
80
81 //------------------------------------------------------------------
82 // find the part of A(:,k) to be operated on by this task
83 //------------------------------------------------------------------
84
85 int64_t j = GBH (Ah, k) ;
86 int64_t pA_start, pA_end ;
87 GB_get_pA (&pA_start, &pA_end, tid, k,
88 kfirst, klast, pstart_Aslice, Ap, avlen) ;
89
90 //------------------------------------------------------------------
91 // extract vector indices of A(:,j)
92 //------------------------------------------------------------------
93
94 for (int64_t p = pA_start ; p < pA_end ; p++)
95 {
96 J [p] = j ;
97 }
98 }
99 }
100
101 //--------------------------------------------------------------------------
102 // free workspace and return result
103 //--------------------------------------------------------------------------
104
105 GB_FREE_ALL ;
106 return (GrB_SUCCESS) ;
107 }
108
109