1 //------------------------------------------------------------------------------
2 // GxB_Desc_set: set a field in a descriptor
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 // This is identical to GrB_Descriptor_set, except that the last argument is a
11 // pointer whose type depends on the field.  For the four descriptor fields
12 // in the spec, the type is the same as GrB_Descriptor_set (a scalar of
13 // type GrB_Desc_Value).
14 
15 #include "GB.h"
16 
GxB_Desc_set(GrB_Descriptor desc,GrB_Desc_Field field,...)17 GrB_Info GxB_Desc_set           // set a parameter in a descriptor
18 (
19     GrB_Descriptor desc,        // descriptor to modify
20     GrB_Desc_Field field,       // parameter to change
21     ...                         // value to change it to
22 )
23 {
24 
25     //--------------------------------------------------------------------------
26     // check inputs
27     //--------------------------------------------------------------------------
28 
29     if (desc != NULL && desc->header_size == 0)
30     {
31         // built-in descriptors may not be modified
32         return (GrB_INVALID_VALUE) ;
33     }
34 
35     GB_WHERE (desc, "GxB_Desc_set (desc, field, value)") ;
36     GB_RETURN_IF_NULL_OR_FAULTY (desc) ;
37     ASSERT_DESCRIPTOR_OK (desc, "desc to set", GB0) ;
38 
39     //--------------------------------------------------------------------------
40     // set the parameter
41     //--------------------------------------------------------------------------
42 
43     va_list ap ;
44 
45     switch (field)
46     {
47 
48         case GrB_OUTP :
49 
50             {
51                 va_start (ap, field) ;
52                 int value = va_arg (ap, int) ;
53                 va_end (ap) ;
54                 if (! (value == GxB_DEFAULT || value == GrB_REPLACE))
55                 {
56                     GB_ERROR (GrB_INVALID_VALUE,
57                         "invalid descriptor value [%d] for GrB_OUTP field;\n"
58                         "must be GxB_DEFAULT [%d] or GrB_REPLACE [%d]",
59                         value, (int) GxB_DEFAULT, (int) GrB_REPLACE) ;
60                 }
61                 desc->out = (GrB_Desc_Value) value ;
62             }
63             break ;
64 
65         case GrB_MASK :
66 
67             {
68                 va_start (ap, field) ;
69                 int value = va_arg (ap, int) ;
70                 va_end (ap) ;
71                 if (! (value == GxB_DEFAULT ||
72                        value == GrB_COMP ||
73                        value == GrB_STRUCTURE ||
74                        value == (GrB_COMP + GrB_STRUCTURE)))
75                 {
76                     GB_ERROR (GrB_INVALID_VALUE,
77                         "invalid descriptor value [%d] for GrB_MASK field;\n"
78                         "must be GxB_DEFAULT [%d], GrB_COMP [%d],\n"
79                         "GrB_STRUCTURE [%d], or GrB_COMP+GrB_STRUCTURE [%d]",
80                         value, (int) GxB_DEFAULT, (int) GrB_COMP,
81                         (int) GrB_STRUCTURE,
82                         (int) (GrB_COMP + GrB_STRUCTURE)) ;
83                 }
84                 int mask = (int) desc->mask ;
85                 switch (value)
86                 {
87                     case GrB_COMP      : mask |= GrB_COMP ;      break ;
88                     case GrB_STRUCTURE : mask |= GrB_STRUCTURE ; break ;
89                     default            : mask = value ;          break ;
90                 }
91                 desc->mask = (GrB_Desc_Value) mask ;
92             }
93             break ;
94 
95         case GrB_INP0 :
96 
97             {
98                 va_start (ap, field) ;
99                 int value = va_arg (ap, int) ;
100                 va_end (ap) ;
101                 if (! (value == GxB_DEFAULT || value == GrB_TRAN))
102                 {
103                     GB_ERROR (GrB_INVALID_VALUE,
104                         "invalid descriptor value [%d] for GrB_INP0 field;\n"
105                         "must be GxB_DEFAULT [%d] or GrB_TRAN [%d]",
106                         value, (int) GxB_DEFAULT, (int) GrB_TRAN) ;
107                 }
108                 desc->in0 = (GrB_Desc_Value) value ;
109             }
110             break ;
111 
112         case GrB_INP1 :
113 
114             {
115                 va_start (ap, field) ;
116                 int value = va_arg (ap, int) ;
117                 va_end (ap) ;
118                 if (! (value == GxB_DEFAULT || value == GrB_TRAN))
119                 {
120                     GB_ERROR (GrB_INVALID_VALUE,
121                         "invalid descriptor value [%d] for GrB_INP1 field;\n"
122                         "must be GxB_DEFAULT [%d] or GrB_TRAN [%d]",
123                         value, (int) GxB_DEFAULT, (int) GrB_TRAN) ;
124                 }
125                 desc->in1 = (GrB_Desc_Value) value ;
126             }
127             break ;
128 
129         case GxB_DESCRIPTOR_NTHREADS :      // same as GxB_NTHREADS
130 
131             {
132                 va_start (ap, field) ;
133                 desc->nthreads_max = va_arg (ap, int) ;
134                 va_end (ap) ;
135             }
136             break ;
137 
138         case GxB_DESCRIPTOR_CHUNK :         // same as GxB_CHUNK
139 
140             {
141                 va_start (ap, field) ;
142                 desc->chunk = va_arg (ap, double) ;
143                 va_end (ap) ;
144             }
145             break ;
146 
147         case GxB_AxB_METHOD :
148 
149             {
150                 va_start (ap, field) ;
151                 int value = va_arg (ap, int) ;
152                 va_end (ap) ;
153                 if (! (value == GxB_DEFAULT  || value == GxB_AxB_GUSTAVSON
154                     || value == GxB_AxB_DOT
155                     || value == GxB_AxB_HASH || value == GxB_AxB_SAXPY))
156                 {
157                     GB_ERROR (GrB_INVALID_VALUE,
158                         "invalid descriptor value [%d] for GrB_AxB_METHOD"
159                         " field;\nmust be GxB_DEFAULT [%d], GxB_AxB_GUSTAVSON"
160                         " [%d]\nGxB_AxB_DOT [%d]"
161                         " GxB_AxB_HASH [%d] or GxB_AxB_SAXPY [%d]",
162                         value, (int) GxB_DEFAULT, (int) GxB_AxB_GUSTAVSON,
163                         (int) GxB_AxB_DOT,
164                         (int) GxB_AxB_HASH, (int) GxB_AxB_SAXPY) ;
165                 }
166                 desc->axb = (GrB_Desc_Value) value ;
167             }
168             break ;
169 
170         case GxB_SORT :
171 
172             {
173                 va_start (ap, field) ;
174                 desc->do_sort = va_arg (ap, int) ;
175                 va_end (ap) ;
176             }
177             break ;
178 
179         default :
180 
181             GB_ERROR (GrB_INVALID_VALUE,
182                 "invalid descriptor field [%d], must be one of:\n"
183                 "GrB_OUTP [%d], GrB_MASK [%d], GrB_INP0 [%d], GrB_INP1 [%d]\n"
184                 "GxB_NTHREADS [%d], GxB_CHUNK [%d], GxB_AxB_METHOD [%d]\n"
185                 "or GxB_SORT [%d]\n",
186                 (int) field, (int) GrB_OUTP, (int) GrB_MASK, (int) GrB_INP0,
187                 (int) GrB_INP1, (int) GxB_NTHREADS, (int) GxB_CHUNK,
188                 (int) GxB_AxB_METHOD, (int) GxB_SORT) ;
189     }
190 
191     return (GrB_SUCCESS) ;
192 }
193 
194