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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
//------------------------------------------------------------------------------
// GB_BinaryOp_check: check and print a binary operator
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
#include "GB.h"
#include "get_set/GB_get_set.h"
GrB_Info GB_BinaryOp_check // check a GraphBLAS binary operator
(
const GrB_BinaryOp op, // GraphBLAS operator to print and check
const char *name, // name of the operator
int pr, // print level
FILE *f // file for output
)
{
//--------------------------------------------------------------------------
// check inputs
//--------------------------------------------------------------------------
GB_CHECK_INIT ;
GBPR0 ("\n GraphBLAS BinaryOp: %s ", ((name != NULL) ? name : "")) ;
if (op == NULL)
{
// this may be an optional argument
GBPR0 ("NULL\n") ;
return (GrB_NULL_POINTER) ;
}
else if (op == GxB_IGNORE_DUP)
{
// this is a valid dup operator for build
GBPR0 ("ignore_dup\n") ;
return (GrB_SUCCESS) ;
}
//--------------------------------------------------------------------------
// check object
//--------------------------------------------------------------------------
GB_CHECK_MAGIC (op) ;
GB_Opcode opcode = op->opcode ;
if (!(GB_IS_BINARYOP_CODE (opcode) || GB_IS_INDEXBINARYOP_CODE (opcode)))
{
GBPR0 (" BinaryOp has an invalid opcode\n") ;
return (GrB_INVALID_OBJECT) ;
}
GrB_Info info = GB_Type_check (op->ztype, "ztype", GxB_SILENT, f) ;
if (info != GrB_SUCCESS)
{
GBPR0 (" BinaryOp has an invalid ztype\n") ;
return (GrB_INVALID_OBJECT) ;
}
bool op_is_from_idxbinop =
GB_IS_BUILTIN_BINOP_CODE_POSITIONAL (opcode) ||
GB_IS_INDEXBINARYOP_CODE (opcode) ;
bool op_is_first = (opcode == GB_FIRST_binop_code) ;
bool op_is_second = (opcode == GB_SECOND_binop_code) ;
bool op_is_pair = (opcode == GB_PAIR_binop_code) ;
int32_t actual_len = (int32_t) strlen (op->name) ;
int32_t name_len = op->name_len ;
char *op_name = (actual_len > 0) ? op->name : "f" ;
if (opcode == GB_USER_binop_code)
{
// user-defined binary operator
GBPR0 ("(user-defined): z=%s(x,y)\n", op_name) ;
}
else if (opcode == GB_USER_idxbinop_code)
{
GBPR0 ("(user-defined index):\n z=%s(x,ix,iy,y,iy,yj,theta)\n",
op_name) ;
}
else if (op_is_first && op->ztype->code == GB_UDT_code)
{
// FIRST_UDT binary operator created by GB_reduce_to_vector
GBPR0 ("(generated 1st): z=%s(x,y)\n", op_name) ;
}
else if (op_is_second && op->ztype->code == GB_UDT_code)
{
// SECOND_UDT binary operator created by GB_wait or GB_builder
GBPR0 ("(generated 2nd): z=%s(x,y)\n", op_name) ;
}
else if (op_is_from_idxbinop)
{
// built-in index binary operator
GBPR0 ("(built-in index):\n z=%s(x,ix,iy,y,iy,yj,theta)\n",
op_name) ;
}
else
{
// built-in
GBPR0 ("(built-in): z=%s(x,y)\n", op_name) ;
}
if ((!(op_is_from_idxbinop || op_is_first || op_is_second)
&& op->binop_function == NULL)
|| (op_is_from_idxbinop && op->idxbinop_function == NULL))
{
GBPR0 (" BinaryOp has a NULL function pointer\n") ;
return (GrB_INVALID_OBJECT) ;
}
if (opcode == GB_USER_binop_code && name_len != actual_len)
{
GBPR0 (" BinaryOp has an invalid name_len\n") ;
return (GrB_INVALID_OBJECT) ;
}
// name given by GrB_set, or 'GrB_*' name for built-in operators
const char *given_name = GB_op_name_get ((GB_Operator) op) ;
if (given_name != NULL)
{
GBPR0 (" BinaryOp given name: [%s]\n", given_name) ;
}
info = GB_Type_check (op->ztype, "ztype", pr, f) ;
ASSERT (info == GrB_SUCCESS) ;
if (!op_is_pair)
{
if (!op_is_second)
{
info = GB_Type_check (op->xtype, "xtype", pr, f) ;
if (info != GrB_SUCCESS)
{
GBPR0 (" BinaryOp has an invalid xtype\n") ;
return (GrB_INVALID_OBJECT) ;
}
}
if (!op_is_first)
{
info = GB_Type_check (op->ytype, "ytype", pr, f) ;
if (info != GrB_SUCCESS)
{
GBPR0 (" BinaryOp has an invalid ytype\n") ;
return (GrB_INVALID_OBJECT) ;
}
}
}
if (op_is_from_idxbinop)
{
info = GB_Type_check (op->theta_type, "theta_type", pr, f) ;
if (info != GrB_SUCCESS)
{
GBPR0 (" BinaryOp has an invalid theta_type\n") ;
return (GrB_INVALID_OBJECT) ;
}
if (pr != GxB_SILENT)
{
GBPR (" theta: [ ") ;
info = GB_entry_check (op->theta_type, op->theta, pr, f) ;
if (info != GrB_SUCCESS) return (info) ;
GBPR ("]") ;
}
GBPR0 ("\n") ;
}
if (op->defn != NULL)
{
GBPR0 ("%s\n", op->defn) ;
}
return (GrB_SUCCESS) ;
}
|