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