| 19 | #include "GB_transpose.h" |
| 20 | |
| 21 | GrB_Info GB_select // C<M> = accum (C, select(A,k)) or select(A',k) |
| 22 | ( |
| 23 | GrB_Matrix C, // input/output matrix for results |
| 24 | const bool C_replace, // C descriptor |
| 25 | const GrB_Matrix M, // optional mask for C, unused if NULL |
| 26 | const bool Mask_comp, // descriptor for M |
| 27 | const bool Mask_struct, // if true, use the only structure of M |
| 28 | const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) |
| 29 | const GB_Operator op, // GxB_SelectOp or GrB_IndexUnaryOp |
| 30 | const GrB_Matrix A, // input matrix |
| 31 | const GrB_Scalar Thunk, // optional input for select operator |
| 32 | const bool A_transpose, // A matrix descriptor |
| 33 | GB_Context Context |
| 34 | ) |
| 35 | { |
| 36 | |
| 37 | //-------------------------------------------------------------------------- |
| 38 | // check inputs |
| 39 | //-------------------------------------------------------------------------- |
| 40 | |
| 41 | // C may be aliased with M and/or A |
| 42 | |
| 43 | GB_RETURN_IF_FAULTY_OR_POSITIONAL (accum) ; |
| 44 | GB_RETURN_IF_FAULTY (Thunk) ; |
| 45 | GB_RETURN_IF_NULL_OR_FAULTY (op) ; |
| 46 | |
| 47 | ASSERT_MATRIX_OK (C, "C input for GB_select", GB0) ; |
| 48 | ASSERT_MATRIX_OK_OR_NULL (M, "M for GB_select", GB0) ; |
| 49 | ASSERT_BINARYOP_OK_OR_NULL (accum, "accum for GB_select", GB0) ; |
| 50 | ASSERT_OP_OK (op, "selectop/indexunaryop for GB_select", GB0) ; |
| 51 | ASSERT_MATRIX_OK (A, "A input for GB_select", GB0) ; |
| 52 | ASSERT_SCALAR_OK_OR_NULL (Thunk, "Thunk for GB_select", GB0) ; |
| 53 | |
| 54 | struct GB_Matrix_opaque T_header ; |
| 55 | GrB_Matrix T = NULL ; |
| 56 | |
| 57 | // check domains and dimensions for C<M> = accum (C,T) |
| 58 | GrB_Info info ; |
| 59 | GB_OK (GB_compatible (C->type, C, M, Mask_struct, accum, A->type, Context)); |
| 60 | |
| 61 | GB_Type_code acode = A->type->code ; |
| 62 | GB_Type_code xcode = (op->xtype == NULL) ? GB_ignore_code : op->xtype->code; |
| 63 | GB_Type_code tcode = GB_ignore_code ; |
| 64 | GB_Opcode opcode = op->opcode ; |
| 65 | bool op_is_selectop = GB_IS_SELECTOP_CODE (opcode) ; |
| 66 | bool op_is_idxunop = GB_IS_INDEXUNARYOP_CODE (opcode) ; |
| 67 | ASSERT (op_is_selectop || op_is_idxunop) ; |
| 68 | ASSERT (opcode != GB_FLIPDIAGINDEX_idxunop_code) ; |
| 69 | |
| 70 | if (op_is_idxunop) |
| 71 | { |
| 72 | // Thunk is optional for GxB_Selectop, required for GrB_IndexUnaryOp |
| 73 | GB_RETURN_IF_NULL (Thunk) ; |
| 74 | } |
| 75 | |
| 76 | // this opcodes are not available to the user |
| 77 | ASSERT (opcode != GB_NONZOMBIE_selop_code) ; |
| 78 |
no test coverage detected