File: GB_mex_band.c

package info (click to toggle)
suitesparse 1%3A7.11.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 258,172 kB
  • sloc: ansic: 1,153,566; cpp: 48,145; makefile: 4,997; fortran: 2,087; java: 1,826; sh: 1,113; ruby: 725; python: 676; asm: 371; sed: 166; awk: 44
file content (151 lines) | stat: -rw-r--r-- 4,618 bytes parent folder | download
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
144
145
146
147
148
149
150
151
//------------------------------------------------------------------------------
// GB_mex_band: C = tril (triu (A,lo), hi), or with A'
//------------------------------------------------------------------------------

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

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

// Apply a select operator to a matrix

#include "GB_mex.h"

#define USAGE "C = GB_mex_band (A, lo, hi, atranspose)"

#define FREE_ALL                        \
{                                       \
    GrB_Scalar_free_(&Thunk) ;          \
    GrB_Matrix_free_(&C) ;              \
    GrB_Matrix_free_(&A) ;              \
    GrB_Scalar_free_(&Thunk_type) ;     \
    GrB_IndexUnaryOp_free_(&op) ;       \
    GrB_Descriptor_free_(&desc) ;       \
    GB_mx_put_global (true) ;           \
}

#define OK(method)                                      \
{                                                       \
    info = method ;                                     \
    if (info != GrB_SUCCESS)                            \
    {                                                   \
        FREE_ALL ;                                      \
        mexErrMsgTxt ("GraphBLAS failed") ;             \
    }                                                   \
}

 typedef struct { int64_t lo ; int64_t hi ; } gb_LoHi_type ; 

#define LOHI_DEFN                                       \
"typedef struct { int64_t lo ; int64_t hi ; } gb_LoHi_type ;"

void gb_LoHi_band (bool *z, /* x is unused: */ const void *x,
    uint64_t i, uint64_t j, const gb_LoHi_type *thunk) ;

void gb_LoHi_band (bool *z, /* x is unused: */ const void *x,
    uint64_t i, uint64_t j, const gb_LoHi_type *thunk)
{
    int64_t i2 = (int64_t) i ;
    int64_t j2 = (int64_t) j ;
    (*z) = ((thunk->lo <= (j2-i2)) && ((j2-i2) <= thunk->hi)) ;
}

void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{

    bool malloc_debug = GB_mx_get_global (true) ;
    GrB_Matrix C = NULL ;
    GrB_Matrix A = NULL ;
    GrB_IndexUnaryOp op = NULL ;
    GrB_Info info ;
    GrB_Descriptor desc = NULL ;
    GrB_Scalar Thunk = NULL ;
    GrB_Type Thunk_type = NULL ;

    #define GET_DEEP_COPY ;
    #define FREE_DEEP_COPY ;

    // check inputs
    if (nargout > 1 || nargin < 3 || nargin > 4)
    {
        mexErrMsgTxt ("Usage: " USAGE) ;
    }

    // get A (shallow copy)
    A = GB_mx_mxArray_to_Matrix (pargin [0], "A input", false, true) ;
    if (A == NULL)
    {
        FREE_ALL ;
        mexErrMsgTxt ("A failed") ;
    }

    // create the Thunk
    gb_LoHi_type bandwidth  ;
    OK (GxB_Type_new (&Thunk_type, sizeof (gb_LoHi_type),
        "gb_LoHi_type", LOHI_DEFN)) ;

    // get lo and hi
    bandwidth.lo = (int64_t) mxGetScalar (pargin [1]) ;
    bandwidth.hi = (int64_t) mxGetScalar (pargin [2]) ;

    OK (GrB_Scalar_new (&Thunk, Thunk_type)) ;
    OK (GrB_Scalar_setElement_UDT (Thunk, (void *) &bandwidth)) ;
    OK (GrB_Scalar_wait_(Thunk, GrB_MATERIALIZE)) ;

    // get atranspose
    bool atranspose = false ;
    if (nargin > 3) atranspose = (bool) mxGetScalar (pargin [3]) ;
    if (atranspose)
    {
        OK (GrB_Descriptor_new (&desc)) ;
        OK (GxB_Desc_set (desc, GrB_INP0, GrB_TRAN)) ;
    }

    // create operator
    // use the user-defined operator, from the gb_LoHi_band function.
    // This operator cannot be JIT'd because it doesn't have a name or defn.
    METHOD (GrB_IndexUnaryOp_new (&op, (GxB_index_unary_function) gb_LoHi_band,
        GrB_BOOL, GrB_FP64, Thunk_type)) ;

    uint64_t nrows, ncols ;
    GrB_Matrix_nrows (&nrows, A) ;
    GrB_Matrix_ncols (&ncols, A) ;
    if (bandwidth.lo == 0 && bandwidth.hi == 0 && nrows == 10 && ncols == 10)
    {
        GxB_IndexUnaryOp_fprint (op, "lohi_op", 3, NULL) ;
    }

    // create result matrix C
    if (atranspose)
    {
        OK (GrB_Matrix_new (&C, GrB_FP64, A->vdim, A->vlen)) ;
    }
    else
    {
        OK (GrB_Matrix_new (&C, GrB_FP64, A->vlen, A->vdim)) ;
    }

    // C<Mask> = accum(C,op(A))
    if (GB_NCOLS (C) == 1 && !atranspose)
    {
        // this is just to test the Vector version
        OK (GrB_Vector_select_Scalar ((GrB_Vector) C, NULL, NULL, op,
            (GrB_Vector) A, Thunk, NULL)) ;
    }
    else
    {
        OK (GrB_Matrix_select_Scalar (C, NULL, NULL, op, A, Thunk, desc)) ;
    }

    // return C as a sparse matrix and free the GraphBLAS C
    pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C output", false) ;

    FREE_ALL ;
}