| 20 | #include "GB_scalar.h" |
| 21 | |
| 22 | GrB_Info GB_apply // C<M> = accum (C, op(A)) or op(A') |
| 23 | ( |
| 24 | GrB_Matrix C, // input/output matrix for results |
| 25 | const bool C_replace, // C descriptor |
| 26 | const GrB_Matrix M, // optional mask for C, unused if NULL |
| 27 | const bool Mask_comp, // M descriptor |
| 28 | const bool Mask_struct, // if true, use the only structure of M |
| 29 | const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) |
| 30 | const GB_Operator op_in, // unary/idxunop/binop to apply |
| 31 | const GrB_Scalar scalar_in, // scalar to bind to binop, or thunk |
| 32 | bool binop_bind1st, // if true, binop(x,A) else binop(A,y) |
| 33 | const GrB_Matrix A, // first or 2nd input: matrix A |
| 34 | bool A_transpose, // A matrix descriptor |
| 35 | GB_Context Context |
| 36 | ) |
| 37 | { |
| 38 | |
| 39 | //-------------------------------------------------------------------------- |
| 40 | // check inputs |
| 41 | //-------------------------------------------------------------------------- |
| 42 | |
| 43 | // C may be aliased with M and/or A |
| 44 | |
| 45 | struct GB_Matrix_opaque T_header ; |
| 46 | GrB_Matrix T = NULL ; |
| 47 | |
| 48 | GB_RETURN_IF_FAULTY_OR_POSITIONAL (accum) ; |
| 49 | GB_RETURN_IF_NULL_OR_FAULTY (op_in) ; |
| 50 | ASSERT_MATRIX_OK (C, "C input for GB_apply", GB0) ; |
| 51 | ASSERT_MATRIX_OK_OR_NULL (M, "M for GB_apply", GB0) ; |
| 52 | ASSERT_BINARYOP_OK_OR_NULL (accum, "accum for GB_apply", GB0) ; |
| 53 | ASSERT_MATRIX_OK (A, "A input for GB_apply", GB0) ; |
| 54 | ASSERT_OP_OK (op_in, "op for GB_apply", GB0) ; |
| 55 | |
| 56 | GB_Operator op = op_in ; |
| 57 | GB_Opcode opcode = op->opcode ; |
| 58 | GrB_Type T_type = op->ztype ; |
| 59 | GrB_Scalar scalar = (GrB_Scalar) scalar_in ; |
| 60 | |
| 61 | bool op_is_unop = GB_IS_UNARYOP_CODE (opcode) ; |
| 62 | bool op_is_binop = GB_IS_BINARYOP_CODE (opcode) ; |
| 63 | bool op_is_idxunop = GB_IS_INDEXUNARYOP_CODE (opcode) ; |
| 64 | bool op_is_positional = GB_OPCODE_IS_POSITIONAL (opcode) ; |
| 65 | struct GB_Scalar_opaque Thunk_header ; |
| 66 | int64_t ithunk = 0 ; |
| 67 | |
| 68 | if (op_is_unop) |
| 69 | { |
| 70 | // apply a unary operator: scalar is ignored |
| 71 | ASSERT_UNARYOP_OK (op, "unop for GB_apply", GB0) ; |
| 72 | if (!op_is_positional) |
| 73 | { |
| 74 | // A must also be compatible with op->xtype |
| 75 | if (!GB_Type_compatible (A->type, op->xtype)) |
| 76 | { |
| 77 | GB_ERROR (GrB_DOMAIN_MISMATCH, |
| 78 | "Incompatible type for z=%s(x):\n" |
| 79 | "input A of type [%s]\n" |
no test coverage detected