GrB_Info GrB_Matrix_apply // C<Mask> = accum (C, op(A)) or op(A') ( GrB_Matrix C, // input/output matrix for results const GrB_Matrix Mask, // optional Mask for C, unused if NULL const GrB_BinaryOp accum, // optional accum for Z=accum(C,T) const GrB_UnaryOp op, // operator to apply to the entries const GrB_Matrix A, // first input: matrix A const GrB_Descriptor desc // descriptor for C, Mask, and A ) { //-------------------------------------------------------------------------- // check inputs //-------------------------------------------------------------------------- GB_WHERE ("GrB_Matrix_apply (C, Mask, accum, op, A, desc)") ; GB_RETURN_IF_NULL_OR_FAULTY (C) ; GB_RETURN_IF_FAULTY (Mask) ; GB_RETURN_IF_NULL_OR_FAULTY (A) ; // get the descriptor GB_GET_DESCRIPTOR (info, desc, C_replace, Mask_comp, A_transpose, xx1, xx2); //-------------------------------------------------------------------------- // apply the operator and optionally transpose; assemble pending tuples //-------------------------------------------------------------------------- return (GB_apply ( C, C_replace, // C and its descriptor Mask, Mask_comp, // Mask and its descriptor accum, // optional accum for Z=accum(C,T) op, // operator to apply to the entries A, A_transpose, // A and its descriptor Context)) ; }
GrB_Info GrB_Matrix_assign // C<Mask>(Rows,Cols) += A or A' ( GrB_Matrix C, // input/output matrix for results const GrB_Matrix Mask, // mask for C, unused if NULL const GrB_BinaryOp accum, // accum for Z=accum(C(Rows,Cols),T) const GrB_Matrix A, // first input: matrix A const GrB_Index *Rows, // row indices GrB_Index nRows, // number of row indices const GrB_Index *Cols, // column indices GrB_Index nCols, // number of column indices const GrB_Descriptor desc // descriptor for C, Mask, and A ) { //-------------------------------------------------------------------------- // check inputs //-------------------------------------------------------------------------- GB_WHERE ("GrB_Matrix_assign" " (C, Mask, accum, A, Rows, nRows, Cols, nCols, desc)") ; GB_RETURN_IF_NULL_OR_FAULTY (C) ; GB_RETURN_IF_FAULTY (Mask) ; GB_RETURN_IF_NULL_OR_FAULTY (A) ; // get the descriptor GB_GET_DESCRIPTOR (info, desc, C_replace, Mask_comp, A_transpose, xx1, xx2); //-------------------------------------------------------------------------- // C<Mask>(Rows,Cols) = accum (C(Rows,Cols), A) and variations //-------------------------------------------------------------------------- return (GB_assign ( C, C_replace, // C matrix and its descriptor Mask, Mask_comp, // Mask matrix and its descriptor false, // do not transpose the mask accum, // for accum (C(Rows,Cols),A) A, A_transpose, // A and its descriptor (T=A or A') Rows, nRows, // row indices Cols, nCols, // column indices false, NULL, 0, // no scalar expansion false, false, // not GrB_Col_assign nor GrB_row_assign Context)) ; }
GrB_Info GxB_Vector_type // get the type of a vector ( GrB_Type *type, // returns the type of the vector const GrB_Vector v // vector to query ) { //-------------------------------------------------------------------------- // check inputs //-------------------------------------------------------------------------- GB_WHERE ("GxB_Vector_type (&type, v)") ; GB_RETURN_IF_NULL_OR_FAULTY (v) ; //-------------------------------------------------------------------------- // get the type //-------------------------------------------------------------------------- return (GB_type (type, (GrB_Matrix) v, Context)) ; }
GrB_Info GrB_Vector_nvals // get the number of entries in a vector ( GrB_Index *nvals, // number of entries const GrB_Vector v // vector to query ) { //-------------------------------------------------------------------------- // check inputs //-------------------------------------------------------------------------- GB_WHERE ("GrB_Vector_nvals (&nvals, v)") ; GB_RETURN_IF_NULL_OR_FAULTY (v) ; ASSERT (GB_VECTOR_OK (v)) ; // do not check if nvals is NULL; pending updates must be applied first, in // GB_nvals, per Table 2.4 in the spec //-------------------------------------------------------------------------- // get the number of entries //-------------------------------------------------------------------------- return (GB_nvals (nvals, (GrB_Matrix) v, Context)) ; }
GrB_Info GxB_Matrix_Option_get // gets the current option of a matrix ( GrB_Matrix A, // matrix to query GxB_Option_Field field, // option to query ... // return value of the matrix option ) { //-------------------------------------------------------------------------- // check inputs //-------------------------------------------------------------------------- GB_WHERE ("GxB_Matrix_Option_get (A, field, &value)") ; GB_RETURN_IF_NULL_OR_FAULTY (A) ; ASSERT_OK (GB_check (A, "A to get option", GB0)) ; //-------------------------------------------------------------------------- // get the option //-------------------------------------------------------------------------- va_list ap ; double *hyper_ratio, hyper ; GxB_Format_Value *format ; bool is_csc ; hyper = A->hyper_ratio ; is_csc = A->is_csc ; switch (field) { case GxB_HYPER : va_start (ap, field) ; hyper_ratio = va_arg (ap, double *) ; va_end (ap) ; GB_RETURN_IF_NULL (hyper_ratio) ; (*hyper_ratio) = hyper ; break ; case GxB_FORMAT : va_start (ap, field) ; format = va_arg (ap, GxB_Format_Value *) ; va_end (ap) ; GB_RETURN_IF_NULL (format) ; (*format) = (is_csc) ? GxB_BY_COL : GxB_BY_ROW ; break ; default : return (GB_ERROR (GrB_INVALID_VALUE, (GB_LOG, "invalid option field [%d], must be one of:\n" "GxB_HYPER [%d] or GxB_FORMAT [%d]", (int) field, (int) GxB_HYPER, (int) GxB_FORMAT))) ; } return (GrB_SUCCESS) ; }
GrB_Info GB_user_build // check inputs then build matrix ( GrB_Matrix C, // matrix to build const GrB_Index *I, // row indices of tuples const GrB_Index *J, // col indices of tuples const void *S, // array of values of tuples const GrB_Index nvals, // number of tuples const GrB_BinaryOp dup, // binary function to assemble duplicates const GB_Type_code scode, // GB_Type_code of S array const bool is_matrix, // true if C is a matrix, false if GrB_Vector GB_Context Context ) { //-------------------------------------------------------------------------- // check inputs //-------------------------------------------------------------------------- ASSERT_OK (GB_check (C, "C for GB_user_build", GB0)) ; GB_RETURN_IF_NULL (I) ; if (I == GrB_ALL) { return (GB_ERROR (GrB_INVALID_VALUE, (GB_LOG, "List of row indices cannot be GrB_ALL"))) ; } if (nvals == GxB_RANGE || nvals == GxB_STRIDE || nvals == GxB_BACKWARDS) { return (GB_ERROR (GrB_INVALID_VALUE, (GB_LOG, "nvals cannot be GxB_RANGE, GxB_STRIDE, or GxB_BACKWARDS"))) ; } if (is_matrix) { GB_RETURN_IF_NULL (J) ; if (J == GrB_ALL) { return (GB_ERROR (GrB_INVALID_VALUE, (GB_LOG, "List of column indices cannot be 'GrB_ALL'"))) ; } } else { // only GrB_Vector_build calls this function with J == NULL ASSERT (J == NULL) ; } GB_RETURN_IF_NULL (S) ; GB_RETURN_IF_NULL_OR_FAULTY (dup) ; ASSERT_OK (GB_check (dup, "dup operator for assembling duplicates", GB0)) ; ASSERT (scode <= GB_UDT_code) ; if (nvals > GB_INDEX_MAX) { // problem too large return (GB_ERROR (GrB_INVALID_VALUE, (GB_LOG, "problem too large: nvals "GBu" exceeds "GBu, nvals, GB_INDEX_MAX))) ; } // check types of dup if (dup->xtype != dup->ztype || dup->ytype != dup->ztype) { // all 3 types of z = dup (x,y) must be the same. dup must also be // associative but there is no way to check this in general. return (GB_ERROR (GrB_DOMAIN_MISMATCH, (GB_LOG, "All domains of dup " "operator for assembling duplicates must be identical.\n" "operator is: [%s] = %s ([%s],[%s])", dup->ztype->name, dup->name, dup->xtype->name, dup->ytype->name))) ; } if (!GB_Type_compatible (C->type, dup->ztype)) { // the type of C and dup must be compatible return (GB_ERROR (GrB_DOMAIN_MISMATCH, (GB_LOG, "operator dup [%s] has type [%s]\n" "cannot be typecast to entries in output of type [%s]", dup->name, dup->ztype->name, C->type->name))) ; } // C and S must be compatible if (!GB_code_compatible (scode, dup->ztype->code)) { // All types must be compatible with each other: C, dup, and S. // User-defined types are only compatible with themselves; they are not // compatible with any built-in type nor any other user-defined type. // Thus, if C, dup, or S have any user-defined type, this // condition requires all three types to be identical: the same // user-defined type. No casting will be done in this case. return (GB_ERROR (GrB_DOMAIN_MISMATCH, (GB_LOG, "numerical values of tuples of type [%s]\n" "cannot be typecast as input to the dup operator\n" "z=%s(x,y), whose input types are [%s]", GB_code_string (scode), dup->name, dup->ztype->name))) ; } if (!GB_EMPTY (C)) { // The matrix has existing entries. This is required by the GraphBLAS // API specification to generate an error, so the test is made here. // However, any existing content is safely freed immediately below, so // this test is not required, except to conform to the spec. Zombies // are excluded from this test. return (GB_ERROR (GrB_OUTPUT_NOT_EMPTY, (GB_LOG, "output already has existing entries"))) ; } //-------------------------------------------------------------------------- // build the matrix //-------------------------------------------------------------------------- return (GB_build (C, I, J, S, nvals, dup, scode, is_matrix, true, Context)); }