File: GB_iso_unop.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 (154 lines) | stat: -rw-r--r-- 5,621 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
146
147
148
149
150
151
152
153
154
//------------------------------------------------------------------------------
// GB_iso_unop: apply a unary or binary op (with scalar) with an iso result
//------------------------------------------------------------------------------

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

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

// The input matrix A need not be entirely valid.  GB_transpose can be
// transposing the matrix in place, which case the contents of A have already
// been transplanted into T, and only A->x remains.

#include "GB.h"

void GB_iso_unop            // Cx [0] = unop (A), binop (s,A) or binop (A,s)
(
    // output
    GB_void *restrict Cx,   // output scalar of iso array
    // input
    GrB_Type ctype,         // type of Cx
    GB_iso_code C_code_iso, // defines how C iso value is to be computed
    GB_Operator op,         // unary/binop operator, if present
    GrB_Matrix A,           // input matrix
    GrB_Scalar scalar       // input scalar (may be NULL)
)
{

    //--------------------------------------------------------------------------
    // get inputs
    //--------------------------------------------------------------------------

    ASSERT (A != NULL && A->type != NULL) ;
    ASSERT_TYPE_OK (ctype, "ctype for GB_iso_unop", GB0) ;
    ASSERT (Cx != NULL) ;

    GrB_Type stype = (scalar != NULL) ? scalar->type : GrB_BOOL ;
//  const size_t csize = ctype->size ;
    const size_t asize = A->type->size ;
    const size_t ssize = stype->size ;
    const GB_Type_code ccode = ctype->code ;
    const GB_Type_code acode = A->type->code ;
    const GB_Type_code scode = stype->code ;

    //--------------------------------------------------------------------------
    // compute the C iso value
    //--------------------------------------------------------------------------

    if (C_code_iso == GB_ISO_1)
    { 

        //----------------------------------------------------------------------
        // Cx [0] = (ctype) 1, via the PAIR binary op or ONE unary op
        //----------------------------------------------------------------------

        GB_cast_one (Cx, ccode) ;

    }
    else if (C_code_iso == GB_ISO_S)
    { 

        //----------------------------------------------------------------------
        // Cx [0] = (ctype) scalar via FIRST(s,A), SECOND(A,s), ANY(..), ...
        //----------------------------------------------------------------------

        ASSERT_SCALAR_OK (scalar, "scalar for GB_iso_unop", GB0) ;
        GB_cast_scalar (Cx, ccode, scalar->x, scode, ssize) ;

    }
    else
    {

        //----------------------------------------------------------------------
        // Cx [0] depends on the iso value of A
        //----------------------------------------------------------------------

        ASSERT (A->x != NULL && A->x_size >= asize) ;
        ASSERT (A->iso) ;

        if (C_code_iso == GB_ISO_A)
        { 
            //------------------------------------------------------------------
            // Cx [0] = (ctype) A
            //------------------------------------------------------------------

            GB_cast_scalar (Cx, ccode, A->x, acode, asize) ;

        }
        else if (C_code_iso == GB_ISO_OP1_A)
        { 

            //------------------------------------------------------------------
            // Cx [0] = unop (A)
            //------------------------------------------------------------------

            ASSERT_UNARYOP_OK (op, "op for GB_iso_unop", GB0) ;

            // x = (xtype) Ax [0]
            GB_Type_code xcode = op->xtype->code ;
            size_t xsize = op->xtype->size ;
            GB_void x [GB_VLA(xsize)] ;
            GB_cast_scalar (x, xcode, A->x, acode, asize) ;

            // Cx [0] = op (x)
            GxB_unary_function fop = op->unop_function ;
            fop (Cx, x) ;

        }
        else
        { 

            //------------------------------------------------------------------
            // Cx [0] = binop (scalar,A) or binop (A,scalar)
            //------------------------------------------------------------------

            ASSERT_BINARYOP_OK (op, "op for GB_iso_unop", GB0) ;
            ASSERT_SCALAR_OK (scalar, "scalar for GB_iso_unop binop", GB0) ;
            GB_Type_code xcode = op->xtype->code ;
            GB_Type_code ycode = op->ytype->code ;
            size_t xsize = op->xtype->size ;
            size_t ysize = op->ytype->size ;
            GxB_binary_function fop = op->binop_function ;
            GB_void x [GB_VLA(xsize)] ;
            GB_void y [GB_VLA(ysize)] ;

            if (C_code_iso == GB_ISO_OP2_SA)
            { 

                //--------------------------------------------------------------
                // Cx [0] = binop (scalar, A)
                //--------------------------------------------------------------

                GB_cast_scalar (x, xcode, scalar->x, scode, ssize) ;
                GB_cast_scalar (y, ycode, A->x, acode, asize) ;

            }
            else // (C_code_iso == GB_ISO_OP2_AS)
            { 

                //--------------------------------------------------------------
                // Cx [0] = binop (A, scalar)
                //--------------------------------------------------------------

                GB_cast_scalar (x, xcode, A->x, acode, asize) ;
                GB_cast_scalar (y, ycode, scalar->x, scode, ssize) ;

            }

            // Cx [0] = binop (x, y)
            fop (Cx, x, y) ;
        }
    }
}