File: GB_ek_slice.c

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (143 lines) | stat: -rw-r--r-- 5,467 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
141
142
143
//------------------------------------------------------------------------------
// GB_ek_slice: slice the entries and vectors of a matrix
//------------------------------------------------------------------------------

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

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

// Slice the entries of a matrix or vector into A_ntasks slices.

// The function is called GB_ek_slice because it first partitions the e entries
// into chunks of identical sizes, and then finds the first and last vector
// (k) for each chunk.

// Task t does entries pstart_slice [t] to pstart_slice [t+1]-1 inclusive and
// vectors kfirst_slice [t] to klast_slice [t].  The first and last vectors
// may be shared with prior slices and subsequent slices.

// On input, A_ntasks is the # of tasks requested.

// A can have any sparsity structure (sparse, hyper, bitmap, or full).
// A may be jumbled.

#include "GB.h"
#include "slice/include/GB_search_for_vector.h"

//------------------------------------------------------------------------------
// GB_ek_slice_search: find the first and last vectors in a slice
//------------------------------------------------------------------------------

#define GB_ek_slice_search_TYPE   GB_ek_slice_search_32
#define GB_search_for_vector_TYPE GB_search_for_vector_32
#include "slice/factory/GB_ek_slice_search_template.c"

#define GB_ek_slice_search_TYPE   GB_ek_slice_search_64
#define GB_search_for_vector_TYPE GB_search_for_vector_64
#include "slice/factory/GB_ek_slice_search_template.c"

//------------------------------------------------------------------------------
// GB_ek_slice: slice the entries and vectors of a matrix
//------------------------------------------------------------------------------

//  void GB_ek_slice                    // slice a matrix
//  (
//      // output:
//      int64_t *restrict A_ek_slicing, // size 3*A_ntasks+1
//      // input:
//      GrB_Matrix A,                   // matrix to slice
//      int A_ntasks                    // # of tasks
//  ) ;

GB_CALLBACK_EK_SLICE_PROTO (GB_ek_slice)
{

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

    ASSERT (A_ek_slicing != NULL) ;
    ASSERT (A_ntasks >= 1) ;

    //--------------------------------------------------------------------------
    // get A
    //--------------------------------------------------------------------------

    ASSERT (GB_JUMBLED_OK (A)) ;    // pattern of A is not accessed

    int64_t anvec = A->nvec ;
    int64_t avlen = A->vlen ;
    int64_t anz = GB_nnz_held (A) ;
    const void *Ap = A->p ;         // NULL if bitmap or full
    bool Ap_is_32 = A->p_is_32 ;

    //--------------------------------------------------------------------------
    // allocate result
    //--------------------------------------------------------------------------

    // kfirst_slice and klast_slice are size A_ntasks.
    // pstart_slice is size A_ntasks+1

    int64_t *restrict kfirst_slice = A_ek_slicing ;
    int64_t *restrict klast_slice  = A_ek_slicing + A_ntasks ;
    int64_t *restrict pstart_slice = A_ek_slicing + A_ntasks * 2 ;

    //--------------------------------------------------------------------------
    // quick return for empty matrices
    //--------------------------------------------------------------------------

    if (anz == 0)
    { 
        // construct a single empty task
        ASSERT (A_ntasks == 1) ;
        pstart_slice [0] = 0 ;
        pstart_slice [1] = 0 ;
        kfirst_slice [0] = -1 ;
        klast_slice  [0] = -2 ;
        return ;
    }

    //--------------------------------------------------------------------------
    // find the first and last entries in each slice
    //--------------------------------------------------------------------------

    // FUTURE: this can be done in parallel if there are many tasks
    GB_e_slice (pstart_slice, anz, A_ntasks) ;

    //--------------------------------------------------------------------------
    // find the first and last vectors in each slice
    //--------------------------------------------------------------------------

    // The first vector of the slice is the kth vector of A if
    // pstart_slice [taskid] is in the range Ap [k]...A[k+1]-1, and this
    // is vector is k = kfirst_slice [taskid].

    // The last vector of the slice is the kth vector of A if
    // pstart_slice [taskid+1]-1 is in the range Ap [k]...A[k+1]-1, and this
    // is vector is k = klast_slice [taskid].

    // FUTURE: this can be done in parallel if there are many tasks
    if (Ap_is_32)
    {
        for (int taskid = 0 ; taskid < A_ntasks ; taskid++)
        { 
            // using GB_search_for_vector_32 (...):
            GB_ek_slice_search_32 (taskid, A_ntasks, pstart_slice, Ap,
                anvec, avlen, kfirst_slice, klast_slice) ;
        }
    }
    else
    {
        for (int taskid = 0 ; taskid < A_ntasks ; taskid++)
        { 
            // using GB_search_for_vector_64 (...):
            GB_ek_slice_search_64 (taskid, A_ntasks, pstart_slice, Ap,
                anvec, avlen, kfirst_slice, klast_slice) ;
        }
    }

    ASSERT (kfirst_slice [0] == 0) ;
    ASSERT (klast_slice  [A_ntasks-1] == anvec-1) ;
}