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
|
//------------------------------------------------------------------------------
// GxB_BinaryOp_new_IndexOp: create a new user-defined binary op
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
#include "GB.h"
// GxB_BinaryOp_new_IndexOp: create a new binary op from an index binary op
GrB_Info GxB_BinaryOp_new_IndexOp
(
GrB_BinaryOp *binop_handle, // handle of binary op to create
GxB_IndexBinaryOp idxbinop, // based on this index binary op
GrB_Scalar theta // theta value to bind to the new binary op
)
{
//--------------------------------------------------------------------------
// check inputs
//--------------------------------------------------------------------------
GrB_Info info ;
GB_CHECK_INIT ;
GB_RETURN_IF_NULL (binop_handle) ;
(*binop_handle) = NULL ;
GB_RETURN_IF_NULL_OR_FAULTY (idxbinop) ;
GB_RETURN_IF_NULL_OR_INVALID (theta) ;
if (!GB_Type_compatible (idxbinop->theta_type, theta->type))
{
return (GrB_DOMAIN_MISMATCH) ;
}
//--------------------------------------------------------------------------
// allocate the binary op
//--------------------------------------------------------------------------
size_t header_size ;
GrB_BinaryOp
binop = GB_CALLOC_MEMORY (1, sizeof (struct GB_BinaryOp_opaque),
&header_size) ;
if (binop == NULL)
{
// out of memory
return (GrB_OUT_OF_MEMORY) ;
}
binop->header_size = header_size ;
//--------------------------------------------------------------------------
// create the binary op
//--------------------------------------------------------------------------
// copy the index binary op contents into the binary op
memcpy (binop, idxbinop, sizeof (struct GB_BinaryOp_opaque)) ;
// remove the components owned by the index binary op
binop->user_name = NULL ;
binop->user_name_size = 0 ;
binop->defn = NULL ;
binop->defn_size = 0 ;
bool jitable = (idxbinop->hash != UINT64_MAX) ;
info = GB_op_name_and_defn (
// output:
binop->name, &(binop->name_len), &(binop->hash),
&(binop->defn), &(binop->defn_size),
// input:
idxbinop->name, idxbinop->defn, true, jitable) ;
if (info != GrB_SUCCESS)
{
// out of memory
GB_FREE_MEMORY (&binop, header_size) ;
return (info) ;
}
//--------------------------------------------------------------------------
// copy theta into the new binary op
//--------------------------------------------------------------------------
binop->theta = GB_MALLOC_MEMORY (1, binop->theta_type->size,
&(binop->theta_size)) ;
if (binop->theta == NULL)
{
// out of memory
GB_Op_free ((GB_Operator *) (&binop)) ;
return (GrB_OUT_OF_MEMORY) ;
}
GB_cast_scalar (binop->theta, binop->theta_type->code,
theta->x, theta->type->code, theta->type->size) ;
//--------------------------------------------------------------------------
// return result
//--------------------------------------------------------------------------
ASSERT_BINARYOP_OK (binop, "new user-defined binary op (based on idxbinop)",
GB0) ;
(*binop_handle) = binop ;
return (GrB_SUCCESS) ;
}
|