1 //------------------------------------------------------------------------------
2 // GB_BinaryOp_compatible: check binary operator for type compatibility
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 // check type compatibilty for C = op (A,B). With typecasting: A is cast to
11 // op->xtype, B is cast to op->ytype, the operator is computed, and then the
12 // result of op->ztype is cast to C->type.
13
14 #include "GB.h"
15
GB_BinaryOp_compatible(const GrB_BinaryOp op,const GrB_Type ctype,const GrB_Type atype,const GrB_Type btype,const GB_Type_code bcode,GB_Context Context)16 GrB_Info GB_BinaryOp_compatible // check for domain mismatch
17 (
18 const GrB_BinaryOp op, // binary operator to check
19 const GrB_Type ctype, // C must be compatible with op->ztype
20 const GrB_Type atype, // A must be compatible with op->xtype
21 const GrB_Type btype, // B must be compatible with op->ytype
22 const GB_Type_code bcode, // B may not have a type, just a code
23 GB_Context Context
24 )
25 {
26
27 //--------------------------------------------------------------------------
28 // check inputs
29 //--------------------------------------------------------------------------
30
31 ASSERT (op != NULL) ;
32 // ctype and btype may be NULL, but atype is never NULL
33 ASSERT (atype != NULL) ;
34 ASSERT (bcode <= GB_UDT_code) ;
35 GB_Opcode opcode = op->opcode ;
36 bool op_is_pair_or_positional = (opcode == GB_PAIR_opcode)
37 || GB_OPCODE_IS_POSITIONAL (opcode) ;
38
39 //--------------------------------------------------------------------------
40 // first input A is cast into the type of op->xtype
41 //--------------------------------------------------------------------------
42
43 if (opcode == GB_SECOND_opcode || op_is_pair_or_positional)
44 {
45 // first input is unused, so A is always compatible
46 ;
47 }
48 else if (!GB_Type_compatible (atype, op->xtype))
49 {
50 GB_ERROR (GrB_DOMAIN_MISMATCH,
51 "Incompatible type for z=%s(x,y):\n"
52 "first input of type [%s]\n"
53 "cannot be typecast to x input of type [%s]",
54 op->name, atype->name, op->xtype->name) ;
55 }
56
57 //--------------------------------------------------------------------------
58 // second input B is cast into the type of op->ytype
59 //--------------------------------------------------------------------------
60
61 if (opcode == GB_FIRST_opcode || op_is_pair_or_positional)
62 {
63 // second input is unused, so B is always compatible
64 ;
65 }
66 else if (btype != NULL)
67 {
68 // B has a type
69 if (!GB_Type_compatible (btype, op->ytype))
70 {
71 GB_ERROR (GrB_DOMAIN_MISMATCH,
72 "Incompatible type for z=%s(x,y):\n"
73 "second input of type [%s]\n"
74 "cannot be typecast to y input of type [%s]",
75 op->name, btype->name, op->ytype->name) ;
76 }
77 }
78 else
79 {
80 // B has a just a type code, not a type
81 if (!GB_code_compatible (bcode, op->ytype->code))
82 {
83 GB_ERROR (GrB_DOMAIN_MISMATCH,
84 "Incompatible type for z=%s(x,y):\n"
85 "second input of type [%s]\n"
86 "cannot be typecast to y input of type [%s]",
87 op->name, GB_code_string (bcode), op->ytype->name) ;
88 }
89 }
90
91 //--------------------------------------------------------------------------
92 // result of binary operator of op->ztype is cast to C
93 //--------------------------------------------------------------------------
94
95 if (!GB_Type_compatible (ctype, op->ztype))
96 {
97 GB_ERROR (GrB_DOMAIN_MISMATCH,
98 "Incompatible type for z=%s(x,y):\n"
99 "operator output z of type [%s]\n"
100 "cannot be typecast to result of type [%s]",
101 op->name, op->ztype->name, ctype->name) ;
102 }
103
104 return (GrB_SUCCESS) ;
105 }
106
107