File: gbsize.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 (145 lines) | stat: -rw-r--r-- 4,984 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
144
145
//------------------------------------------------------------------------------
// gbsize: dimension and type of a GraphBLAS or built-in matrix
//------------------------------------------------------------------------------

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

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

// The input may be either a GraphBLAS matrix struct or a standard built-in
// matrix.  Note that the output may be int64, to accomodate huge hypersparse
// matrices.  Also returns the type of the matrix.

// Usage:

// [m, n, type] = gbsize (X)

#include "gb_interface.h"

#define USAGE "usage: [m n type] = gbsize (X)"

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

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

    gb_usage (nargin == 1 && nargout <= 4, USAGE) ;

    //--------------------------------------------------------------------------
    // get the # of rows and columns of a GraphBLAS or built-in matrix
    //--------------------------------------------------------------------------

    GrB_Index nrows, ncols ;
    int typecode = -1 ;

    if (mxIsStruct (pargin [0]))
    { 

        //----------------------------------------------------------------------
        // get the size of a GraphBLAS matrix
        //----------------------------------------------------------------------

        // get the type
        mxArray *mx_type = mxGetField (pargin [0], 0, "GraphBLASv7_3") ;
        if (mx_type == NULL)
        {
            // check if it is a GraphBLASv5_1 struct
            mx_type = mxGetField (pargin [0], 0, "GraphBLASv5_1") ;
        }
        if (mx_type == NULL)
        {
            // check if it is a GraphBLASv5 struct
            mx_type = mxGetField (pargin [0], 0, "GraphBLASv5") ;
        }
        if (mx_type == NULL)
        {
            // check if it is a GraphBLASv4 struct
            mx_type = mxGetField (pargin [0], 0, "GraphBLASv4") ;
        }
        if (mx_type == NULL)
        {
            // check if it is a GraphBLASv3 struct
            mx_type = mxGetField (pargin [0], 0, "GraphBLAS") ;
        }
        CHECK_ERROR (mx_type == NULL, "invalid GraphBLAS struct") ;

        // get the scalar info
        mxArray *opaque = mxGetField (pargin [0], 0, "s") ;
        CHECK_ERROR (opaque == NULL, "invalid GraphBLAS struct") ;
        // use mxGetData (best for Octave, fine for MATLAB)
        int64_t *s = (int64_t *) mxGetData (opaque) ;
        int64_t vlen = s [1] ;
        int64_t vdim = s [2] ;
        bool is_csc = (bool) (s [6]) ;

        nrows = (is_csc) ? vlen : vdim ;
        ncols = (is_csc) ? vdim : vlen ;

        //----------------------------------------------------------------------
        // return type of a GraphBLAS matrix, if requested
        //----------------------------------------------------------------------

        if (nargout > 2)
        { 
            // return the type
            pargout [2] = mxDuplicateArray (mx_type) ;
        }

    }
    else
    {

        //----------------------------------------------------------------------
        // get the size of a built-in matrix
        //----------------------------------------------------------------------

        nrows = (GrB_Index) mxGetM (pargin [0]) ;
        ncols = (GrB_Index) mxGetN (pargin [0]) ;

        //----------------------------------------------------------------------
        // get the type of a built-in matrix, if requested
        //----------------------------------------------------------------------

        if (nargout > 2)
        { 
            mxClassID class = mxGetClassID (pargin [0]) ;
            bool is_complex = mxIsComplex (pargin [0]) ;
            pargout [2] = gb_mxclass_to_mxstring (class, is_complex) ;
        }
    }

    //--------------------------------------------------------------------------
    // return the size as int64 or double
    //--------------------------------------------------------------------------

    if (nrows > FLINTMAX || ncols > FLINTMAX)
    { 
        // output is int64 to avoid flint overflow
        int64_t *p ;
        pargout [0] = mxCreateNumericMatrix (1, 1, mxINT64_CLASS, mxREAL) ;
        // use mxGetData (best for Octave, fine for MATLAB)
        p = (int64_t *) mxGetData (pargout [0]) ;
        p [0] = (int64_t) nrows ;
        pargout [1] = mxCreateNumericMatrix (1, 1, mxINT64_CLASS, mxREAL) ;
        p = (int64_t *) mxGetData (pargout [1]) ;
        p [0] = (int64_t) ncols ;
    }
    else
    { 
        // output is double
        pargout [0] = mxCreateDoubleScalar ((double) nrows) ;
        pargout [1] = mxCreateDoubleScalar ((double) ncols) ;
    }

    GB_WRAPUP ;
}