1 //------------------------------------------------------------------------------
2 // GB_compatible: check input and operators for type compatibility
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7 
8 //------------------------------------------------------------------------------
9 
10 // Check if the types for C<M> = accum (C,T) are all compatible,
11 // and (if present) make sure the size of C and M match.
12 
13 #define GB_FREE_ALL ;
14 #include "GB.h"
15 
GB_compatible(const GrB_Type ctype,const GrB_Matrix C,const GrB_Matrix M,const bool Mask_struct,const GrB_BinaryOp accum,const GrB_Type ttype,GB_Context Context)16 GrB_Info GB_compatible          // SUCCESS if all is OK, *_MISMATCH otherwise
17 (
18     const GrB_Type ctype,       // the type of C (matrix or scalar)
19     const GrB_Matrix C,         // the output matrix C; NULL if C is a scalar
20     const GrB_Matrix M,         // optional mask, NULL if no mask
21     const bool Mask_struct,     // true if M is structural
22     const GrB_BinaryOp accum,   // C<M> = accum(C,T) is computed
23     const GrB_Type ttype,       // type of T
24     GB_Context Context
25 )
26 {
27 
28     //--------------------------------------------------------------------------
29     // check inputs
30     //--------------------------------------------------------------------------
31 
32     // C may be aliased with M
33 
34     GrB_Info info ;
35 
36     //--------------------------------------------------------------------------
37     // check accum compatibility
38     //--------------------------------------------------------------------------
39 
40     if (accum != NULL)
41     {
42         // Results T are accumlated via C<M>=accum(C,T)
43 
44         // For entries in C and T, c=z=accum(c,t) is computed, so C must
45         // be compatible with both the ztype and xtype of accum, and T
46         // must be compatible with the ytype of accum.
47 
48         // For entries in T but not C, c=t is assigned, so C and T must
49         // be compatible.  This is the same as the condition below
50         // when accum is NULL.
51 
52         GB_OK (GB_BinaryOp_compatible (accum, ctype, ctype, ttype,
53             GB_ignore_code, Context)) ;
54     }
55 
56     //--------------------------------------------------------------------------
57     // check the types of C and T
58     //--------------------------------------------------------------------------
59 
60     // C<M> = T, so C and T must be compatible.
61     // also C<M> = accum(C,T) for entries in T but not C
62     if (!GB_Type_compatible (ctype, ttype))
63     {
64         GB_ERROR (GrB_DOMAIN_MISMATCH,
65             "Result of computation of type [%s]\n"
66             "cannot be typecast to final output of type [%s]",
67             ttype->name, ctype->name) ;
68     }
69 
70     //--------------------------------------------------------------------------
71     // check the mask
72     //--------------------------------------------------------------------------
73 
74     return (GB_Mask_compatible (M, Mask_struct, C, 1, 1, Context)) ;
75 }
76 
77