File: GB_split.c

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 506; asm: 369; python: 125; awk: 10
file content (137 lines) | stat: -rw-r--r-- 4,367 bytes parent folder | download | duplicates (3)
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
//------------------------------------------------------------------------------
// GB_split: split a matrix into an array of matrices
//------------------------------------------------------------------------------

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

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

#define GB_FREE_WORKSPACE                   \
    GB_WERK_POP (Tile_cols, int64_t) ;      \
    GB_WERK_POP (Tile_rows, int64_t) ;

#define GB_FREE_ALL                         \
    GB_FREE_WORKSPACE ;                     \
    for (int64_t k = 0 ; k < m*n ; k++)     \
    {                                       \
        GB_Matrix_free (&(Tiles [k])) ;     \
    }

#include "GB_split.h"

GrB_Info GB_split                   // split a matrix
(
    GrB_Matrix *Tiles,              // 2D row-major array of size m-by-n
    const GrB_Index m,
    const GrB_Index n,
    const GrB_Index *Tile_nrows,    // array of size m
    const GrB_Index *Tile_ncols,    // array of size n
    const GrB_Matrix A,             // input matrix
    GB_Context Context
)
{

    //--------------------------------------------------------------------------
    // allocate workspace
    //--------------------------------------------------------------------------

    // set all Tiles to NULL
    GrB_Info info ;
    ASSERT (Tiles != NULL) ;
    memset (Tiles, 0, m * n * sizeof (GrB_Matrix)) ;

    GB_WERK_DECLARE (Tile_rows, int64_t) ;
    GB_WERK_DECLARE (Tile_cols, int64_t) ;
    GB_WERK_PUSH (Tile_rows, m+1, int64_t) ;
    GB_WERK_PUSH (Tile_cols, n+1, int64_t) ;
    if (Tile_rows == NULL || Tile_cols == NULL)
    { 
        // out of memory
        GB_FREE_ALL ;
        return (GrB_OUT_OF_MEMORY) ;
    }

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

    ASSERT_MATRIX_OK (A, "A input for GB_split", GB0) ;
    GB_MATRIX_WAIT (A) ;
    if (A->iso)
    { 
        GBURBLE ("(iso split) ") ;
    }

    //--------------------------------------------------------------------------
    // check the sizes of each tile
    //--------------------------------------------------------------------------

    int64_t nrows = GB_NROWS (A) ;
    int64_t ncols = GB_NCOLS (A) ;

    int64_t s = 0 ;
    for (int64_t i = 0 ; i < m ; i++)
    {
        GrB_Index tile_nrows = Tile_nrows [i] ;     // # of rows in Tile{i,:}
        if (tile_nrows < 0 || tile_nrows > nrows)
        { 
            return (GrB_DIMENSION_MISMATCH) ;
        }
        Tile_rows [i] = s ;                         // cumulative sum
        s += tile_nrows ;
    }
    if (s != nrows)
    { 
        return (GrB_DIMENSION_MISMATCH) ;
    }
    Tile_rows [m] = nrows ;

    s = 0 ;
    for (int64_t j = 0 ; j < n ; j++)
    {
        GrB_Index tile_ncols = Tile_ncols [j] ;     // # of cols in Tile{:,j}
        if (tile_ncols < 0 || tile_ncols > ncols)
        { 
            return (GrB_DIMENSION_MISMATCH) ;
        }
        Tile_cols [j] = s ;                         // cumulative sum
        s += tile_ncols ;
    }
    if (s != ncols)
    { 
        return (GrB_DIMENSION_MISMATCH) ;
    }
    Tile_cols [n] = ncols ;

    //--------------------------------------------------------------------------
    // Tiles = split (A)
    //--------------------------------------------------------------------------

    if (GB_is_dense (A))
    { 
        // A is full
        GBURBLE ("(full split) ") ;
        GB_OK (GB_split_full (Tiles, m, n, Tile_rows, Tile_cols, A, Context)) ;
    }
    else if (GB_IS_BITMAP (A))
    { 
        // A is bitmap
        GBURBLE ("(bitmap split) ") ;
        GB_OK (GB_split_bitmap (Tiles, m, n, Tile_rows, Tile_cols, A, Context));
    }
    else
    { 
        // A is sparse/hypersparse, each Tile has the same sparsity as A
        GBURBLE ("(sparse/hyper split) ") ;
        GB_OK (GB_split_sparse (Tiles, m, n, Tile_rows, Tile_cols, A, Context));
    }

    //--------------------------------------------------------------------------
    // free workspace and return result
    //--------------------------------------------------------------------------

    GB_FREE_WORKSPACE ;
    return (GrB_SUCCESS) ;
}