1 //------------------------------------------------------------------------------
2 // GB_stringify_binop: convert a binary op into a string or enum
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7
8 //------------------------------------------------------------------------------
9
10 // The binop macro generates an expression, not a full statement. There
11 // is no semicolon or assignment. For example:
12
13 // #define GB_MULT(x,y) ((x) * (y))
14
15 #include "GB.h"
16 #include "GB_stringify.h"
17
18 //------------------------------------------------------------------------------
19 // GB_stringify_binop: construct the binop macro
20 //------------------------------------------------------------------------------
21
GB_stringify_binop(char * binop_macro,const char * macro_name,GB_Opcode opcode,GB_Type_code xcode,bool for_semiring,bool flipxy)22 void GB_stringify_binop
23 (
24 // output:
25 char *binop_macro, // string with the #define macro
26 // input:
27 const char *macro_name, // name of macro to construct
28 GB_Opcode opcode, // opcode of GraphBLAS operator to convert into a macro
29 GB_Type_code xcode, // op->xtype->code of the operator
30 bool for_semiring, // if true: op is a multiplier in a semiring
31 bool flipxy // if true, use mult(y,x) else mult(x,y)
32 )
33 {
34
35 const char *op_string ;
36 int ecode ;
37
38 // get ecode from opcode, xcode, and for_semiring
39 GB_enumify_binop (&ecode, opcode, xcode, for_semiring) ;
40
41 // convert ecode to string
42 GB_charify_binop (&op_string, ecode) ;
43
44 // convert string to macro
45 GB_macrofy_binop (binop_macro, macro_name, op_string, flipxy) ;
46 }
47
48 //------------------------------------------------------------------------------
49 // GB_enumify_binop: convert binary opcode and xcode into a single enum
50 //------------------------------------------------------------------------------
51
52 // ecodes 0 to 31 can be used as a monoid, but only 0:22 are currently in use.
53 // ecodes 32 and up are not valid for use in a monoid; only 32:139 are in use.
54
GB_enumify_binop(int * ecode,GB_Opcode opcode,GB_Type_code xcode,bool for_semiring)55 void GB_enumify_binop
56 (
57 // output:
58 int *ecode, // enumerated operator, range 0 to 139; -1 on failure
59 // input:
60 GB_Opcode opcode, // opcode of GraphBLAS operator to convert into a macro
61 GB_Type_code xcode, // op->xtype->code of the operator
62 bool for_semiring // true for A*B, false for A+B or A.*B
63 )
64 {
65
66 int e = -1 ;
67
68 switch (opcode)
69 {
70
71 //----------------------------------------------------------------------
72 // user-defined operator
73 //----------------------------------------------------------------------
74
75 case GB_USER_opcode
76
77 e = 0 ; break ;
78
79 //----------------------------------------------------------------------
80 // built-in ops that can be used in a monoid:
81 //----------------------------------------------------------------------
82
83 case GB_FIRST_opcode : // z = x, can be used as the ANY monoid
84
85 e = 1 ; break ;
86
87 case GB_ANY_opcode : // z = y (same as SECOND)
88
89 e = 2 ; break ;
90
91 case GB_MIN_opcode : // z = min(x,y)
92
93 switch (xcode)
94 {
95 case GB_BOOL_code : e = 18 ; break ; // x && y
96 case GB_FP32_code : e = 3 ; break ; // fminf (x,y)
97 case GB_FP64_code : e = 4 ; break ; // fmin (x,y)
98 case GB_FC32_code : e = -1 ; break ; // invalid
99 case GB_FC64_code : e = -1 ; break ; // invalid
100 default : e = 5 ; break ; // GB_IMIN (x,y)
101 }
102 break ;
103
104 case GB_MAX_opcode : // z = max(x,y)
105
106 switch (xcode)
107 {
108 case GB_BOOL_code : e = 17 ; break ; // x || y
109 case GB_FP32_code : e = 6 ; break ; // fmaxf (x,y)
110 case GB_FP64_code : e = 7 ; break ; // fmax (x,y)
111 case GB_FC32_code : e = -1 ; break ; // invalid
112 case GB_FC64_code : e = -1 ; break ; // invalid
113 default : e = 8 ; break ; // GB_IMAX (x,y)
114 }
115 break ;
116
117 case GB_PLUS_opcode : // z = x + y
118
119 switch (xcode)
120 {
121 case GB_BOOL_code : e = 17 ; break ; // x || y
122 case GB_FC32_code : e = 9 ; break ; // GB_FC32_add(x,y)
123 case GB_FC64_code : e = 10 ; break ; // GB_FC64_add(x,y)
124 default : e = 11 ; break ; // x + y
125 }
126 break ;
127
128 case GB_TIMES_opcode : // z = x * y
129
130 switch (xcode)
131 {
132 case GB_BOOL_code : e = 18 ; break ; // x && y
133 case GB_FC32_code : e = 12 ; break ; // GB_FC32_mul(x,y)
134 case GB_FC64_code : e = 13 ; break ; // GB_FC64_mul(x,y)
135 default : e = 14 ; break ; // x * y
136 }
137 break ;
138
139 case GB_EQ_opcode : // z = (x == y), the LXNOR monoid for bool
140
141 // only a monoid for bool (lxnor)
142 switch (xcode)
143 {
144 case GB_BOOL_code : e = 15 ; break ; // x == y
145 case GB_FC32_code : e = 32 ; break ; // GB_FC32_eq(x,y)
146 case GB_FC64_code : e = 33 ; break ; // GB_FC64_eq(x,y)
147 default : e = 15 ; break ; // x == y, not a monoid
148 }
149 break ;
150
151 case GB_NE_opcode : // z = (x != y), the LXOR monoid for bool
152
153 // only a monoid for bool (lxor)
154 switch (xcode)
155 {
156 case GB_BOOL_code : e = 16 ; break ; // x != y
157 case GB_FC32_code : e = 36 ; break ; // GB_FC32_ne(x,y)
158 case GB_FC64_code : e = 37 ; break ; // GB_FC64_ne(x,y)
159 default : e = 16 ; break ; // x != y
160 }
161 break ;
162
163 case GB_LOR_opcode : // z = (x || y)
164
165 switch (xcode)
166 {
167 case GB_BOOL_code : e = 17 ; break ; // x || y
168 default : e = 40 ; break ; // not a monoid
169 }
170 break ;
171
172 case GB_LAND_opcode : // z = (x && y)
173
174 switch (xcode)
175 {
176 case GB_BOOL_code : e = 18 ; break ; // x && y
177 default : e = 41 ; break ; // not a monoid
178 }
179 break ;
180
181 case GB_LXOR_opcode : // z = (x != y)
182
183 switch (xcode)
184 {
185 case GB_BOOL_code : e = 16 ; break ; // x != y
186 default : e = 42 ; break ; // not a monoid
187 }
188 break ;
189
190 case GB_BOR_opcode : // z = (x | y), bitwise or
191
192 if (xcode >= GB_INT8_code && xcode <= GB_UINT64_code) e = 19 ;
193 break ;
194
195 case GB_BAND_opcode : // z = (x & y), bitwise and
196
197 if (xcode >= GB_INT8_code && xcode <= GB_UINT64_code) e = 20 ;
198 break ;
199
200 case GB_BXOR_opcode : // z = (x ^ y), bitwise xor
201
202 if (xcode >= GB_INT8_code && xcode <= GB_UINT64_code) e = 21 ;
203 break ;
204
205 case GB_BXNOR_opcode : // z = ~(x ^ y), bitwise xnor
206
207 if (xcode >= GB_INT8_code && xcode <= GB_UINT64_code) e = 22 ;
208 break ;
209
210 //----------------------------------------------------------------------
211 // built-in ops that cannot be used in a monoid:
212 //----------------------------------------------------------------------
213
214 case GB_SECOND_opcode : // z = y (same as ANY, but not a monoid)
215
216 e = 2 ; break ;
217
218 case GB_ISEQ_opcode : // z = (x == y), but not a monoid
219
220 switch (xcode)
221 {
222 case GB_BOOL_code : e = 15 ; break ; // x == y
223 case GB_FC32_code : e = 34 ; break ; // GB_FC32_iseq(x,y)
224 case GB_FC64_code : e = 35 ; break ; // GB_FC64_iseq(x,y)
225 default : e = 15 ; break ; // x == y, not a monoid
226 }
227 break ;
228
229 case GB_ISNE_opcode : // z = (x != y), but not a monoid
230
231 switch (xcode)
232 {
233 case GB_BOOL_code : e = 16 ; break ; // x != y
234 case GB_FC32_code : e = 38 ; break ; // GB_FC32_isne(x,y)
235 case GB_FC64_code : e = 39 ; break ; // GB_FC64_isne(x,y)
236 default : e = 16 ; break ; // x != y
237 }
238 break ;
239
240 case GB_MINUS_opcode : // z = x - y
241
242 switch (xcode)
243 {
244 case GB_BOOL_code : e = 16 ; break ; // x != y
245 case GB_FC32_code : e = 43 ; break ; // GB_FC32_minus(x,y)
246 case GB_FC64_code : e = 44 ; break ; // GB_FC64_minus(x,y)
247 default : e = 45 ; break ; // x - y
248 }
249 break ;
250
251 case GB_RMINUS_opcode : // z = y - x
252
253 switch (xcode)
254 {
255 case GB_BOOL_code : e = 16 ; break ; // x != y
256 case GB_FC32_code : e = 46 ; break ; // GB_FC32_minus(y,x)
257 case GB_FC64_code : e = 47 ; break ; // GB_FC64_minus(y,x)
258 default : e = 48 ; break ; // y - x
259 }
260 break ;
261
262 case GB_DIV_opcode : // z = x / y ;
263
264 switch (xcode)
265 {
266 case GB_BOOL_code : e = 1 ; break ; // x
267 case GB_INT8_code : e = 49 ; break ; // GB_IDIV_SIGNED(x,y,8)
268 case GB_INT16_code : e = 50 ; break ; // GB_IDIV_SIGNED(x,y,16)
269 case GB_INT32_code : e = 51 ; break ; // GB_IDIV_SIGNED(x,y,32)
270 case GB_INT64_code : e = 52 ; break ; // GB_IDIV_SIGNED(x,y,64)
271 case GB_UINT8_code : e = 53 ; break ; // GB_IDIV_UN...(x,y,8)
272 case GB_UINT16_code : e = 54 ; break ; // GB_IDIV_UN...(x,y,16)
273 case GB_UINT32_code : e = 55 ; break ; // GB_IDIV_UN...(x,y,32)
274 case GB_UINT64_code : e = 56 ; break ; // GB_IDIV_UN...(x,y,64)
275 case GB_FC32_code : e = 57 ; break ; // GB_FC32_div(x,y)
276 case GB_FC64_code : e = 58 ; break ; // GB_FC64_div(x,y)
277 default : e = 59 ; break ; // (x) / (y)
278 }
279 break ;
280
281 case GB_RDIV_opcode : // z = y / x ;
282
283 switch (xcode)
284 {
285 case GB_BOOL_code : e = 2 ; break ; // y
286 case GB_INT8_code : e = 60 ; break ; // GB_IDIV_SIGNED(y,x,8)
287 case GB_INT16_code : e = 61 ; break ; // GB_IDIV_SIGNED(y,x,16)
288 case GB_INT32_code : e = 62 ; break ; // GB_IDIV_SIGNED(y,x,32)
289 case GB_INT64_code : e = 63 ; break ; // GB_IDIV_SIGNED(y,x,64)
290 case GB_UINT8_code : e = 64 ; break ; // GB_IDIV_UN...(y,x,8)
291 case GB_UINT16_code : e = 65 ; break ; // GB_IDIV_UN...(y,x,16)
292 case GB_UINT32_code : e = 66 ; break ; // GB_IDIV_UN...(y,x,32)
293 case GB_UINT64_code : e = 67 ; break ; // GB_IDIV_UN...(y,x,64)
294 case GB_FC32_code : e = 68 ; break ; // GB_FC32_div(y,x)
295 case GB_FC64_code : e = 69 ; break ; // GB_FC64_div(y,x)
296 default : e = 70 ; break ; // (y) / (x)
297 }
298 break ;
299
300 case GB_GT_opcode :
301 case GB_ISGT_opcode : // z = (x > y)
302
303 e = 71 ; break ;
304
305 case GB_LT_opcode :
306 case GB_ISLT_opcode : // z = (x < y)
307
308 e = 72 ; break ;
309
310 case GB_GE_opcode :
311 case GB_ISGE_opcode : // z = (x >= y)
312
313 e = 73 ; break ;
314
315 case GB_LE_opcode :
316 case GB_ISLE_opcode : // z = (x <= y)
317
318 e = 74 ; break ;
319
320 case GB_BGET_opcode : // z = bitget (x,y)
321
322 switch (xcode)
323 {
324 case GB_INT8_code : e = 75 ; break ;
325 case GB_INT16_code : e = 76 ; break ;
326 case GB_INT32_code : e = 77 ; break ;
327 case GB_INT64_code : e = 78 ; break ;
328 case GB_UINT8_code : e = 79 ; break ;
329 case GB_UINT16_code : e = 80 ; break ;
330 case GB_UINT32_code : e = 81 ; break ;
331 case GB_UINT64_code : e = 82 ; break ;
332 default : e = -1 ; break ;
333 }
334 break ;
335
336 case GB_BSET_opcode : // z = bitset (x,y)
337
338 switch (xcode)
339 {
340 case GB_INT8_code : e = 83 ; break ;
341 case GB_INT16_code : e = 84 ; break ;
342 case GB_INT32_code : e = 85 ; break ;
343 case GB_INT64_code : e = 86 ; break ;
344 case GB_UINT8_code : e = 87 ; break ;
345 case GB_UINT16_code : e = 88 ; break ;
346 case GB_UINT32_code : e = 89 ; break ;
347 case GB_UINT64_code : e = 90 ; break
348 default : e = -1 ; break ;
349 }
350 break ;
351
352 case GB_BCLR_opcode : // z = bitclr (x,y)
353
354 switch (xcode)
355 {
356 case GB_INT8_code : e = 91 ; break ;
357 case GB_INT16_code : e = 92 ; break ;
358 case GB_INT32_code : e = 93 ; break ;
359 case GB_INT64_code : e = 94 ; break ;
360 case GB_UINT8_code : e = 95 ; break ;
361 case GB_UINT16_code : e = 96 ; break ;
362 case GB_UINT32_code : e = 97 ; break ;
363 case GB_UINT64_code : e = 98 ; break ;
364 default : e = -1 ; break ;
365 }
366 break ;
367
368 case GB_BSHIFT_opcode : // z = bitshift (x,y)
369
370 switch (xcode)
371 {
372 case GB_INT8_code : e = 99 ; break ;
373 case GB_INT16_code : e = 100 ; break ;
374 case GB_INT32_code : e = 101 ; break ;
375 case GB_INT64_code : e = 102 ; break ;
376 case GB_UINT8_code : e = 103 ; break ;
377 case GB_UINT16_code : e = 104 ; break ;
378 case GB_UINT32_code : e = 105 ; break ;
379 case GB_UINT64_code : e = 106 ; break ;
380 default : e = -1 ; break ;
381 }
382 break ;
383
384 case GB_POW_opcode : // z = pow (x,y)
385
386 switch (xcode)
387 {
388 case GB_BOOL_code : e = 71 ; break ; // x >= y
389 case GB_INT8_code : e = 107 ; break ;
390 case GB_INT16_code : e = 108 ; break ;
391 case GB_INT32_code : e = 109 ; break ;
392 case GB_INT64_code : e = 110 ; break ;
393 case GB_UINT8_code : e = 111 ; break ;
394 case GB_UINT16_code : e = 112 ; break ;
395 case GB_UINT32_code : e = 113 ; break ;
396 case GB_UINT64_code : e = 114 ; break ;
397 case GB_FP32_code : e = 115 ; break ;
398 case GB_FP64_code : e = 116 ; break ;
399 case GB_FC32_code : e = 117 ; break ;
400 case GB_FC64_code : e = 118 ; break ;
401 default : e = -1 ; break ;
402 }
403 break ;
404
405 case GB_ATAN2_opcode : // z = atan2 (x,y)
406
407 switch (xcode)
408 {
409 case GB_FP32_code : e = 119 ; break ;
410 case GB_FP64_code : e = 120 ; break ;
411 default : e = -1 ; break ;
412 }
413 break ;
414
415 case GB_HYPOT_opcode : // z = hypot (x,y)
416
417 switch (xcode)
418 {
419 case GB_FP32_code : e = 121 ; break ;
420 case GB_FP64_code : e = 122 ; break ;
421 default : e = -1 ; break ;
422 }
423 break ;
424
425 case GB_FMOD_opcode : // z = fmod (x,y)
426
427 switch (xcode)
428 {
429 case GB_FP32_code : e = 123 ; break ;
430 case GB_FP64_code : e = 124 ; break ;
431 default : e = -1 ; break ;
432 }
433 break ;
434
435 case GB_REMAINDER_opcode : // z = remainder (x,y)
436
437 switch (xcode)
438 {
439 case GB_FP32_code : e = 125 ; break ;
440 case GB_FP64_code : e = 126 ; break ;
441 default : e = -1 ; break ;
442 }
443 break ;
444
445 case GB_COPYSIGN_opcode : // z = copysign (x,y)
446
447 switch (xcode)
448 {
449 case GB_FP32_code : e = 127 ; break ;
450 case GB_FP64_code : e = 128 ; break ;
451 default : e = -1 ; break ;
452 }
453 break ;
454
455 case GB_LDEXP_opcode : // z = ldexp (x,y)
456
457 switch (xcode)
458 {
459 case GB_FP32_code : e = 129 ; break ;
460 case GB_FP64_code : e = 130 ; break ;
461 default : e = -1 ; break ;
462 }
463 break ;
464
465 case GB_CMPLX_opcode : // z = cmplx (x,y)
466
467 switch (xcode)
468 {
469 case GB_FP32_code : e = 131 ; break ;
470 case GB_FP64_code : e = 132 ; break ;
471 default : e = -1 ; break ;
472 }
473 break ;
474
475 case GB_PAIR_opcode : // z = 1
476
477 e = 133 ; break ;
478
479 //----------------------------------------------------------------------
480 // positional ops
481 //----------------------------------------------------------------------
482
483 case GB_FIRSTI_opcode : // z = i
484
485 e = 134 ; break ;
486
487 case GB_FIRSTI1_opcode : // z = i+1
488
489 e = 137 ; break ;
490
491 case GB_FIRSTJ_opcode : // z = for_semiring ? (k) : (j)
492
493 e = for_semiring ? 135 : 136 ; break ;
494
495 case GB_FIRSTJ1_opcode : // z = for_semiring ? (k+1) : (j+1)
496
497 e = for_semiring ? 138 : 139 ; break ;
498
499 case GB_SECONDI_opcode : // z = for_semiring ? (k) : (i)
500
501 e = for_semiring ? 135 : 134 ; break ;
502
503 case GB_SECONDI1_opcode : // z = for_semiring ? (k+1) : (i+1)
504
505 e = for_semiring ? 138 : 139 ; break ;
506
507 case GB_SECONDJ_opcode : // z = j
508
509 e = 136 ; break ;
510
511 case GB_SECONDJ1_opcode : // z = j+1
512
513 e = 139 ; break ;
514
515 default : break ;
516 }
517
518 (*ecode) = e ;
519 }
520
521 //------------------------------------------------------------------------------
522 // GB_charify_binop: convert an ecode into a string
523 //------------------------------------------------------------------------------
524
GB_charify_binop(char ** op_string,int ecode)525 void GB_charify_binop
526 (
527 // output:
528 char **op_string, // string defining the operator (NULL if failure)
529 // input:
530 int ecode // from GB_enumify_binop
531 )
532 {
533
534 const char *f ;
535
536 switch (ecode)
537 {
538
539 //----------------------------------------------------------------------
540 // user-defined ops
541 //----------------------------------------------------------------------
542
543 // f must be defined by a string provided by the user. This is
544 // only a place-holder
545
546 case 0 : f = "user-defined" ; break ;
547
548 //----------------------------------------------------------------------
549 // built-in ops, can be used in a monoid
550 //----------------------------------------------------------------------
551
552 // first
553 case 1 : f = "x" ; break ;
554
555 // any, second
556 case 2 : f = "y" ; break ;
557
558 // min
559 case 3 : f = "fminf (x,y)" ; break ;
560 case 4 : f = "fmin (x,y)" ; break ;
561 case 5 : f = "GB_IMIN (x,y)" ; break ;
562
563 // max
564 case 6 : f = "fmaxf (x,y)" ; break ;
565 case 7 : f = "fmax (x,y)" ; break ;
566 case 8 : f = "GB_IMAX (x,y)" ; break ;
567
568 // plus
569 case 9 : f = "GB_FC32_add(x,y)" ; break ;
570 case 10 : f = "GB_FC64_add(x,y)" ; break ;
571 case 11 : f = "(x) + (y)" ; break ;
572
573 // times
574 case 12 : f = "GB_FC32_mul(x,y)" ; break ;
575 case 13 : f = "GB_FC64_mul(x,y)" ; break ;
576 case 14 : f = "(x) * (y)" ; break ;
577
578 // eq, iseq, lxnor
579 case 15 : f = "(x) == (y)" ; break ;
580
581 // ne, isne, lxor
582 case 16 : f = "(x) != (y)" ; break ;
583
584 // lor
585 case 17 : f = "(x) || (y)" ; break ;
586
587 // land
588 case 18 : f = "(x) && (y)" ; break ;
589
590 // bor
591 case 19 : f = "(x) | (y)" ; break ;
592
593 // band
594 case 20 : f = "(x) & (y)" ; break ;
595
596 // bxor
597 case 21 : f = "(x) ^ (y)" ; break ;
598
599 // bxnor
600 case 22 : f = "~((x) ^ (y))" ; break ;
601
602 // 23 to 31 are unused, but reserved for future monoids
603
604 //----------------------------------------------------------------------
605 // built-in ops, cannot be used in a monoid
606 //----------------------------------------------------------------------
607
608 // eq for complex
609 case 32 : f = "GB_FC32_eq(x,y)" ; break ;
610 case 33 : f = "GB_FC64_eq(x,y)" ; break ;
611
612 // iseq for complex
613 case 34 : f = "GB_FC32_iseq(x,y)" ; break ;
614 case 35 : f = "GB_FC64_iseq(x,y)" ; break ;
615
616 // ne for complex
617 case 36 : f = "GB_FC32_ne(x,y)" ; break ;
618 case 37 : f = "GB_FC64_ne(x,y)" ; break ;
619
620 // isne for complex
621 case 38 : f = "GB_FC32_isne(x,y)" ; break ;
622 case 39 : f = "GB_FC64_isne(x,y)" ; break ;
623
624 // lor for non-boolean
625 case 40 : f = "((x)!=0) || ((y)!=0)" ; break ;
626
627 // land for non-boolean
628 case 41 : f = "((x)!=0) && ((y)!=0)" ; break ;
629
630 // lxor for non-boolean
631 case 42 : f = "((x)!=0) != ((y)!=0)" ; break ;
632
633 // minus
634 case 43 : f = "GB_FC32_minus(x,y)" ; break ;
635 case 44 : f = "GB_FC64_minus(x,y)" ; break ;
636 case 45 : f = "(x) - (y)" ; break ;
637
638 // rminus
639 case 46 : f = "GB_FC32_minus(y,x)" ; break ;
640 case 47 : f = "GB_FC64_minus(y,x)" ; break ;
641 case 48 : f = "(y) - (x)" ; break ;
642
643 // div
644 case 49 : f = "GB_IDIV_SIGNED(x,y,8)" ; break ;
645 case 50 : f = "GB_IDIV_SIGNED(x,y,16)" ; break ;
646 case 51 : f = "GB_IDIV_SIGNED(x,y,32)" ; break ;
647 case 52 : f = "GB_IDIV_SIGNED(x,y,64)" ; break ;
648 case 53 : f = "GB_IDIV_UNSIGNED(x,y,8)" ; break ;
649 case 54 : f = "GB_IDIV_UNSIGNED(x,y,16)" ; break ;
650 case 55 : f = "GB_IDIV_UNSIGNED(x,y,32)" ; break ;
651 case 56 : f = "GB_IDIV_UNSIGNED(x,y,64)" ; break ;
652 case 57 : f = "GB_FC32_div(x,y)" ; break ;
653 case 58 : f = "GB_FC64_div(x,y)" ; break ;
654 case 59 : f = "(x) / (y)" ; break ;
655
656 // rdiv
657 case 60 : f = "GB_IDIV_SIGNED(y,x,8)" ; break ;
658 case 61 : f = "GB_IDIV_SIGNED(y,x,16)" ; break ;
659 case 62 : f = "GB_IDIV_SIGNED(y,x,32)" ; break ;
660 case 63 : f = "GB_IDIV_SIGNED(y,x,64)" ; break ;
661 case 64 : f = "GB_IDIV_UNSIGNED(y,x,8)" ; break ;
662 case 65 : f = "GB_IDIV_UNSIGNED(y,x,16)" ; break ;
663 case 66 : f = "GB_IDIV_UNSIGNED(y,x,32)" ; break ;
664 case 67 : f = "GB_IDIV_UNSIGNED(y,x,64)" ; break ;
665 case 68 : f = "GB_FC32_div(x,y)" ; break ;
666 case 69 : f = "GB_FC64_div(x,y)" ; break ;
667 case 70 : f = "(y) / (x)" ; break ;
668
669 // gt, isgt
670 case 71 : f = "(x) > (y)" ; break ;
671
672 // lt, islt
673 case 72 : f = "(x) < (y)" ; break ;
674
675 // ge, isget
676 case 73 : f = "(x) >= (y)" ; break ;
677
678 // le, isle
679 case 74 : f = "(x) <= (y)" ; break ;
680
681 // bget
682 case 75 : f = "GB_BITGET(x,y,int8_t, 8)" ; break ;
683 case 76 : f = "GB_BITGET(x,y,int16_t,16)" ; break ;
684 case 77 : f = "GB_BITGET(x,y,int32_t,32)" ; break ;
685 case 78 : f = "GB_BITGET(x,y,int64_t,64)" ; break ;
686 case 79 : f = "GB_BITGET(x,y,uint8_t,8)" ; break ;
687 case 80 : f = "GB_BITGET(x,y,uint16_t,16)" ; break ;
688 case 81 : f = "GB_BITGET(x,y,uint32_t,32)" ; break ;
689 case 82 : f = "GB_BITGET(x,y,uint64_t,64)" ; break ;
690
691 // bset
692 case 83 : f = "GB_BITSET(x,y,int8_t, 8)" ; break ;
693 case 84 : f = "GB_BITSET(x,y,int16_t,16)" ; break ;
694 case 85 : f = "GB_BITSET(x,y,int32_t,32)" ; break ;
695 case 86 : f = "GB_BITSET(x,y,int64_t,64)" ; break ;
696 case 87 : f = "GB_BITSET(x,y,uint8_t,8)" ; break ;
697 case 88 : f = "GB_BITSET(x,y,uint16_t,16)" ; break ;
698 case 89 : f = "GB_BITSET(x,y,uint32_t,32)" ; break ;
699 case 90 : f = "GB_BITSET(x,y,uint64_t,64)" ; break ;
700
701 // bclr
702 case 91 : f = "GB_BITCLR(x,y,int8_t, 8)" ; break ;
703 case 92 : f = "GB_BITCLR(x,y,int16_t,16)" ; break ;
704 case 93 : f = "GB_BITCLR(x,y,int32_t,32)" ; break ;
705 case 94 : f = "GB_BITCLR(x,y,int64_t,64)" ; break ;
706 case 95 : f = "GB_BITCLR(x,y,uint8_t,8)" ; break ;
707 case 96 : f = "GB_BITCLR(x,y,uint16_t,16)" ; break ;
708 case 97 : f = "GB_BITCLR(x,y,uint32_t,32)" ; break ;
709 case 98 : f = "GB_BITCLR(x,y,uint64_t,64)" ; break ;
710
711 // bshift
712 case 99 : f = "GB_bitshift_int8(x,y)" ; break ;
713 case 100 : f = "GB_bitshift_int16(x,y)" ; break ;
714 case 101 : f = "GB_bitshift_int32(x,y)" ; break ;
715 case 102 : f = "GB_bitshift_int64(x,y)" ; break ;
716 case 103 : f = "GB_bitshift_uint8(x,y)" ; break ;
717 case 104 : f = "GB_bitshift_uint16(x,y)" ; break ;
718 case 105 : f = "GB_bitshift_uint32(x,y)" ; break ;
719 case 106 : f = "GB_bitshift_uint64(x,y)" ; break ;
720
721 // pow
722 case 107 : f = "GB_pow_int8 (x, y)" ; break ;
723 case 108 : f = "GB_pow_int16 (x, y)" ; break ;
724 case 109 : f = "GB_pow_int32 (x, y)" ; break ;
725 case 110 : f = "GB_pow_int64 (x, y)" ; break ;
726 case 111 : f = "GB_pow_uint8 (x, y)" ; break ;
727 case 112 : f = "GB_pow_uint16 (x, y)" ; break ;
728 case 113 : f = "GB_pow_uint32 (x, y)" ; break ;
729 case 114 : f = "GB_pow_uint64 (x, y)" ; break ;
730 case 115 : f = "GB_powf (x, y)" ; break ;
731 case 116 : f = "GB_pow (x, y)" ; break ;
732 case 117 : f = "GB_cpowf (x, y)" ; break ;
733 case 118 : f = "GB_cpow (x, y)" ; break ;
734
735 // atan2
736 case 119 : f = "atan2f (x, y)" ; break ;
737 case 120 : f = "atan2 (x, y)" ; break ;
738
739 // hypot
740 case 121 : f = "hypotf (x, y)" ; break ;
741 case 122 : f = "hypot (x, y)" ; break ;
742
743 // fmod
744 case 123 : f = "fmodf (x, y)" ; break ;
745 case 124 : f = "fmod (x, y)" ; break ;
746
747 // remainder
748 case 125 : f = "remainderf (x, y)" ; break ;
749 case 126 : f = "remainder (x, y)" ; break ;
750
751 // copysign
752 case 127 : f = "copysignf (x, y)" ; break ;
753 case 128 : f = "copysign (x, y)" ; break ;
754
755 // ldexp
756 case 129 : f = "ldexpf (x, y)" ; break ;
757 case 130 ; f = "ldexp (x, y)" ; break ;
758
759 // cmplex
760 case 131 : f = "GxB_CMPLXF (x, y)" ; break ;
761 case 132 : f = "GxB_CMPLX (x, y)" ; break ;
762
763 // pair
764 case 133 : f = "1" ; break ;
765
766 //----------------------------------------------------------------------
767 // positional ops
768 //----------------------------------------------------------------------
769
770 // in a semiring: cij += aik * bkj
771 // firsti is i, firstj is k, secondi k, secondj is j
772
773 // in an ewise operation: cij = aij + bij
774 // firsti is i, firstj is j, secondi i, secondj is j
775
776 case 134 : f = "i" ; break ;
777 case 135 : f = "k" ; break ;
778 case 136 : f = "j" ; break ;
779 case 137 : f = "i+1" ; break ;
780 case 138 : f = "k+1" ; break ;
781 case 139 : f = "j+1" ; break ;
782
783 default : f = NULL ; ; break ;
784 }
785
786 (*op_string) = f ;
787 }
788
789 //------------------------------------------------------------------------------
790 // GB_macrofy_binop: convert an opstring into a macro
791 //------------------------------------------------------------------------------
792
GB_macrofy_binop(char * binop_macro,const char * macro_name,char * op_string,bool flipxy)793 void GB_macrofy_binop
794 (
795 // output:
796 char *binop_macro, // string with the #define macro
797 // input:
798 const char *macro_name, // name of macro to construct
799 char *op_string, // string defining the operator
800 bool flipxy // if true, use mult(y,x) else mult(x,y)
801 )
802 {
803 if (flipxy)
804 {
805 // reverse the x and y arguments to flip the operator
806 snprintf (binop_macro, GB_CUDA_STRLEN,
807 "#define %s(y,x) (%s)", macro_name, op_string) ;
808 }
809 else
810 {
811 // operator is not flipped
812 snprintf (binop_macro, GB_CUDA_STRLEN,
813 "#define %s(x,y) (%s)", macro_name, op_string) ;
814 }
815 }
816
817