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
|
//------------------------------------------------------------------------------
// GB_BinaryOp_compatible: check binary operator for type compatibility
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
// check type compatibilty for C = op (A,B). With typecasting: A is cast to
// op->xtype, B is cast to op->ytype, the operator is computed, and then the
// result of op->ztype is cast to C->type.
#include "GB.h"
GrB_Info GB_BinaryOp_compatible // check for domain mismatch
(
const GrB_BinaryOp op, // binary operator to check
const GrB_Type ctype, // C must be compatible with op->ztype
const GrB_Type atype, // A must be compatible with op->xtype
const GrB_Type btype, // B must be compatible with op->ytype
const GB_Type_code bcode, // B may not have a type, just a code
GB_Context Context
)
{
//--------------------------------------------------------------------------
// check inputs
//--------------------------------------------------------------------------
// ctype and btype may be NULL, but atype is never NULL
ASSERT (op != NULL) ;
ASSERT (atype != NULL) ;
ASSERT (bcode <= GB_UDT_code) ;
GB_Opcode opcode = op->opcode ;
bool op_is_pair_or_positional = (opcode == GB_PAIR_binop_code)
|| GB_OPCODE_IS_POSITIONAL (opcode) ;
//--------------------------------------------------------------------------
// first input A is cast into the type of op->xtype
//--------------------------------------------------------------------------
if (opcode == GB_SECOND_binop_code || op_is_pair_or_positional)
{
// first input is unused, so A is always compatible
;
}
else if (!GB_Type_compatible (atype, op->xtype))
{
GB_ERROR (GrB_DOMAIN_MISMATCH,
"Incompatible type for z=%s(x,y):\n"
"first input of type [%s]\n"
"cannot be typecast to x input of type [%s]",
op->name, atype->name, op->xtype->name) ;
}
//--------------------------------------------------------------------------
// second input B is cast into the type of op->ytype
//--------------------------------------------------------------------------
if (opcode == GB_FIRST_binop_code || op_is_pair_or_positional)
{
// second input is unused, so B is always compatible
;
}
else if (btype != NULL)
{
// B has a type
if (!GB_Type_compatible (btype, op->ytype))
{
GB_ERROR (GrB_DOMAIN_MISMATCH,
"Incompatible type for z=%s(x,y):\n"
"second input of type [%s]\n"
"cannot be typecast to y input of type [%s]",
op->name, btype->name, op->ytype->name) ;
}
}
else
{
// B has a just a type code, not a type
if (!GB_code_compatible (bcode, op->ytype->code))
{
GB_ERROR (GrB_DOMAIN_MISMATCH,
"Incompatible type for z=%s(x,y):\n"
"second input of type [%s]\n"
"cannot be typecast to y input of type [%s]",
op->name, GB_code_string (bcode), op->ytype->name) ;
}
}
//--------------------------------------------------------------------------
// result of binary operator of op->ztype is cast to C
//--------------------------------------------------------------------------
if (!GB_Type_compatible (ctype, op->ztype))
{
GB_ERROR (GrB_DOMAIN_MISMATCH,
"Incompatible type for z=%s(x,y):\n"
"operator output z of type [%s]\n"
"cannot be typecast to result of type [%s]",
op->name, op->ztype->name, ctype->name) ;
}
return (GrB_SUCCESS) ;
}
|