File: GB_monoid_shared_definitions.h

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 254,920 kB
  • sloc: ansic: 1,134,743; cpp: 46,133; makefile: 4,875; fortran: 2,087; java: 1,826; sh: 996; ruby: 725; python: 495; asm: 371; sed: 166; awk: 44
file content (177 lines) | stat: -rw-r--r-- 5,045 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
//------------------------------------------------------------------------------
// GB_monoid_shared_definitions.h: common macros for monoids
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2025, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// GB_monoid_shared_definitions.h provides default definitions for all monoids,
// if the special cases have not been #define'd prior to #include'ing this
// file.

#include "include/GB_kernel_shared_definitions.h"

#ifndef GB_MONOID_SHARED_DEFINITIONS_H
#define GB_MONOID_SHARED_DEFINITIONS_H

//------------------------------------------------------------------------------
// special monoids
//------------------------------------------------------------------------------

// 1 if monoid is ANY
#ifndef GB_IS_ANY_MONOID
#define GB_IS_ANY_MONOID 0
#endif

// 1 if monoid is PLUS_FC32
#ifndef GB_IS_PLUS_FC32_MONOID
#define GB_IS_PLUS_FC32_MONOID 0
#endif

// 1 if monoid is PLUS_FC64
#ifndef GB_IS_PLUS_FC64_MONOID
#define GB_IS_PLUS_FC64_MONOID 0
#endif

// 1 if monoid is MIN for signed or unsigned integers
#ifndef GB_IS_IMIN_MONOID
#define GB_IS_IMIN_MONOID 0
#endif

// 1 if monoid is MAX for signed or unsigned integers
#ifndef GB_IS_IMAX_MONOID
#define GB_IS_IMAX_MONOID 0
#endif

// 1 if monoid is MIN for float or double
#ifndef GB_IS_FMIN_MONOID
#define GB_IS_FMIN_MONOID 0
#endif

// 1 if monoid is MAX for float or double
#ifndef GB_IS_FMAX_MONOID
#define GB_IS_FMAX_MONOID 0
#endif

//------------------------------------------------------------------------------
// monoid simd reduction
//------------------------------------------------------------------------------

// This macro expands into one of the following, or is empty:

//      #pragma omp simd reduction(+:z)
//      #pragma omp simd reduction(*:z)
//      #pragma omp simd reduction(^:z)
//      ...

// by default, no simd vectorization reduction #pragma
#ifndef GB_PRAGMA_SIMD_REDUCTION_MONOID
#define GB_PRAGMA_SIMD_REDUCTION_MONOID(z)
#endif

//------------------------------------------------------------------------------
// monoid atomic updates
//------------------------------------------------------------------------------

// if not specified, the monoid cannot be done via a single atomic operation.
// The update must instead be done inside a critical section.

#ifndef GB_Z_HAS_ATOMIC_UPDATE
#define GB_Z_HAS_ATOMIC_UPDATE 0
#endif

#ifndef GB_Z_HAS_OMP_ATOMIC_UPDATE
#define GB_Z_HAS_OMP_ATOMIC_UPDATE 0
#endif

#ifndef GB_Z_HAS_CUDA_ATOMIC_BUILTIN
#define GB_Z_HAS_CUDA_ATOMIC_BUILTIN 0
#endif

#ifndef GB_Z_HAS_CUDA_ATOMIC_USER
#define GB_Z_HAS_CUDA_ATOMIC_USER 0
#endif

#ifdef GB_CUDA_KERNEL
#if GB_Z_HAS_CUDA_ATOMIC_USER
static __device__ __inline__
void GB_cuda_atomic_user (void *pz, GB_Z_TYPE t)
{
    GB_Z_CUDA_ATOMIC_TYPE *p = (GB_Z_CUDA_ATOMIC_TYPE *) pz ;
    GB_Z_CUDA_ATOMIC_TYPE assumed ;
    GB_Z_CUDA_ATOMIC_TYPE old = *p ;
    do
    {
        // assume the old value
        assumed = old ;
        // apply the pun to get the old value in GB_Z_TYPE
        GB_Z_TYPE zin = GB_PUN (GB_Z_TYPE, assumed) ;
        // compute the new value
        GB_Z_TYPE z ;
        GB_ADD (z, zin, t) ;
        // modify it atomically:
        old = atomicCAS (p, assumed, GB_PUN (GB_Z_CUDA_ATOMIC_TYPE, z)) ;
    }
    while (assumed != old) ;
}
#endif
#endif

//------------------------------------------------------------------------------
// monoid identity & terminal value and conditions, and handling ztype overflow
//------------------------------------------------------------------------------

// by default, monoid has no terminal value
#ifndef GB_DECLARE_TERMINAL_CONST
#define GB_DECLARE_TERMINAL_CONST(zterminal)
#endif

// by default, identity value is not a single repeated byte
#ifndef GB_HAS_IDENTITY_BYTE
#define GB_HAS_IDENTITY_BYTE 0
#endif
#ifndef GB_IDENTITY_BYTE
#define GB_IDENTITY_BYTE (none)
#endif

#if GB_IS_ANY_MONOID

    // by default, the ANY monoid is terminal
    #ifndef GB_MONOID_IS_TERMINAL
    #define GB_MONOID_IS_TERMINAL 1
    #endif
    #ifndef GB_TERMINAL_CONDITION
    #define GB_TERMINAL_CONDITION(z,zterminal) 1
    #endif
    #ifndef GB_IF_TERMINAL_BREAK
    #define GB_IF_TERMINAL_BREAK(z,zterminal) break
    #endif

    // ignore overflow since no numerical values computed
    #ifndef GB_Z_IGNORE_OVERFLOW
    #define GB_Z_IGNORE_OVERFLOW 1
    #endif

#else

    // monoids are not terminal unless explicitly declared otherwise
    #ifndef GB_MONOID_IS_TERMINAL
    #define GB_MONOID_IS_TERMINAL 0
    #endif
    #ifndef GB_TERMINAL_CONDITION
    #define GB_TERMINAL_CONDITION(z,zterminal) 0
    #endif
    #ifndef GB_IF_TERMINAL_BREAK
    #define GB_IF_TERMINAL_BREAK(z,zterminal)
    #endif

    // default, do not ignore overflow when replacing z+z+...+z with n*z.
    #ifndef GB_Z_IGNORE_OVERFLOW
    #define GB_Z_IGNORE_OVERFLOW 0
    #endif

#endif
#endif