Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGr_Init: start GraphBLAS and LAGraph, and set malloc/etc functions
3 : //------------------------------------------------------------------------------
4 :
5 : // LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved.
6 : // SPDX-License-Identifier: BSD-2-Clause
7 : //
8 : // For additional details (including references to third party source code and
9 : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
10 : // Contributors.txt for a full list of contributors. Created, in part, with
11 : // funding and support from the U.S. Government (see Acknowledgments.txt file).
12 : // DM22-0790
13 :
14 : // Contributed by Timothy A. Davis, Texas A&M University
15 :
16 : //------------------------------------------------------------------------------
17 :
18 : #define LG_FREE_ALL ;
19 :
20 : #include "LG_internal.h"
21 :
22 : //------------------------------------------------------------------------------
23 : // LG_LAGr_Init_has_been_called: a static value only accessible within this file
24 : //------------------------------------------------------------------------------
25 :
26 : // LG_LAGr_Init_has_been_called indicates if LAGr_Init has been called.
27 : // LAGr_Init (or LAGraph_Init) can be called only once, even after
28 : // LAGraph_Finalize has been called. For testing purposes, the flag can be
29 : // cleared by src/test/test_Xinit, to allow LAGr_Init or LAGraph_Init to be
30 : // called again.
31 :
32 : static bool LG_LAGr_Init_has_been_called = false ;
33 :
34 : // LG_LAGr_Init_has_been_called is only modified or accessed by the following
35 : // two routines (even in this file). The two functions are made accessible via
36 : // LAGRAPH_PUBLIC, only for testing purposes by src/test/test_Xinit.c.
37 :
38 : LAGRAPH_PUBLIC void LG_set_LAGr_Init_has_been_called (bool setting) ;
39 : LAGRAPH_PUBLIC bool LG_get_LAGr_Init_has_been_called (void) ;
40 :
41 : LAGRAPH_PUBLIC
42 184 : void LG_set_LAGr_Init_has_been_called (bool setting)
43 : {
44 184 : LG_LAGr_Init_has_been_called = setting ;
45 184 : }
46 :
47 : LAGRAPH_PUBLIC
48 242 : bool LG_get_LAGr_Init_has_been_called (void)
49 : {
50 242 : return (LG_LAGr_Init_has_been_called) ;
51 : }
52 :
53 : //------------------------------------------------------------------------------
54 : // LAGraph global objects
55 : //------------------------------------------------------------------------------
56 :
57 : // LAGraph_plus_first_T: using the GrB_PLUS_MONOID_T monoid and the
58 : // corresponding GrB_FIRST_T multiplicative operator.
59 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int8 = NULL ;
60 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int16 = NULL ;
61 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int32 = NULL ;
62 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int64 = NULL ;
63 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint8 = NULL ;
64 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint16 = NULL ;
65 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint32 = NULL ;
66 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint64 = NULL ;
67 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_fp32 = NULL ;
68 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_fp64 = NULL ;
69 :
70 : // LAGraph_plus_second_T: using the GrB_PLUS_MONOID_T monoid and the
71 : // corresponding GrB_SECOND_T multiplicative operator.
72 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int8 = NULL ;
73 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int16 = NULL ;
74 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int32 = NULL ;
75 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int64 = NULL ;
76 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint8 = NULL ;
77 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint16 = NULL ;
78 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint32 = NULL ;
79 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint64 = NULL ;
80 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_fp32 = NULL ;
81 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_fp64 = NULL ;
82 :
83 : // LAGraph_plus_one_T: using the GrB_PLUS_MONOID_T monoid and the
84 : // corresponding GrB_ONEB_T multiplicative operator.
85 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int8 = NULL ;
86 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int16 = NULL ;
87 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int32 = NULL ;
88 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int64 = NULL ;
89 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint8 = NULL ;
90 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint16 = NULL ;
91 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint32 = NULL ;
92 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint64 = NULL ;
93 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_fp32 = NULL ;
94 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_fp64 = NULL ;
95 :
96 :
97 : // use LAGraph_any_one_bool, etc
98 :
99 : // LAGraph_any_one_T: using the GrB_MIN_MONOID_T for non-boolean types
100 : // or GrB_LOR_MONOID_BOOL for boolean, and the GrB_ONEB_T multiplicative op.
101 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_bool = NULL ;
102 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int8 = NULL ;
103 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int16 = NULL ;
104 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int32 = NULL ;
105 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int64 = NULL ;
106 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint8 = NULL ;
107 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint16 = NULL ;
108 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint32 = NULL ;
109 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint64 = NULL ;
110 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_fp32 = NULL ;
111 : LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_fp64 = NULL ;
112 :
113 : //------------------------------------------------------------------------------
114 : // LAGr_Init
115 : //------------------------------------------------------------------------------
116 :
117 : LAGRAPH_PUBLIC
118 187 : int LAGr_Init
119 : (
120 : // input:
121 : GrB_Mode mode, // mode for GrB_Init or GxB_Init
122 : void * (* user_malloc_function ) (size_t),
123 : void * (* user_calloc_function ) (size_t, size_t),
124 : void * (* user_realloc_function ) (void *, size_t),
125 : void (* user_free_function ) (void *),
126 : char *msg
127 : )
128 : {
129 :
130 : //--------------------------------------------------------------------------
131 : // check inputs
132 : //--------------------------------------------------------------------------
133 :
134 : // malloc and free are required; calloc and realloc are optional
135 187 : LG_CLEAR_MSG ;
136 187 : LG_ASSERT (user_malloc_function != NULL, GrB_NULL_POINTER) ;
137 185 : LG_ASSERT (user_free_function != NULL, GrB_NULL_POINTER) ;
138 : GrB_Info info ;
139 :
140 : // ensure LAGr_Init has not already been called
141 184 : LG_ASSERT_MSG (!LG_get_LAGr_Init_has_been_called ( ), GrB_INVALID_VALUE,
142 : "LAGr*_Init can only be called once") ;
143 :
144 : //--------------------------------------------------------------------------
145 : // start GraphBLAS
146 : //--------------------------------------------------------------------------
147 :
148 : #if LAGRAPH_SUITESPARSE
149 :
150 182 : info = GxB_init (mode,
151 : user_malloc_function,
152 : user_calloc_function,
153 : user_realloc_function,
154 : user_free_function) ;
155 :
156 : #else
157 :
158 : // GxB_init is not available. Use GrB_init instead.
159 : info = GrB_init (mode) ;
160 :
161 : #endif
162 :
163 182 : LG_ASSERT_MSG (info == GrB_SUCCESS || info == GrB_INVALID_VALUE, info,
164 : "failed to initialize GraphBLAS") ;
165 :
166 : #undef LG_FREE_ALL
167 : #define LG_FREE_ALL \
168 : { \
169 : LAGraph_Finalize (msg) ; \
170 : }
171 :
172 : //--------------------------------------------------------------------------
173 : // save the memory management pointers in global LAGraph space
174 : //--------------------------------------------------------------------------
175 :
176 172 : LAGraph_Malloc_function = user_malloc_function ;
177 172 : LAGraph_Calloc_function = user_calloc_function ;
178 172 : LAGraph_Realloc_function = user_realloc_function ;
179 172 : LAGraph_Free_function = user_free_function ;
180 :
181 : //--------------------------------------------------------------------------
182 : // set # of LAGraph threads
183 : //--------------------------------------------------------------------------
184 :
185 172 : LG_nthreads_outer = 1 ; // for LAGraph itself, if nested
186 : // regions call GraphBLAS
187 : #ifdef _OPENMP
188 : LG_nthreads_inner = omp_get_max_threads ( ) ; // for lower-level parallelism
189 : #else
190 172 : LG_nthreads_inner = 1 ;
191 : #endif
192 :
193 : #if LAGRAPH_SUITESPARSE
194 : {
195 172 : GRB_TRY (GxB_set (GxB_NTHREADS, LG_nthreads_inner)) ;
196 : }
197 : #endif
198 :
199 : //--------------------------------------------------------------------------
200 : // create global objects
201 : //--------------------------------------------------------------------------
202 :
203 : // LAGraph_plus_first_T: using the GrB_PLUS_MONOID_T monoid and the
204 : // GrB_FIRST_T multiplicative operator. These semirings compute C=A*B
205 : // where only the structure of B is accessed. In MATLAB, this can be
206 : // written as:
207 : //
208 : // C = A * spones (B)
209 :
210 172 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int8,
211 : GrB_PLUS_MONOID_INT8 , GrB_FIRST_INT8 )) ;
212 171 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int16,
213 : GrB_PLUS_MONOID_INT16 , GrB_FIRST_INT16 )) ;
214 170 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int32,
215 : GrB_PLUS_MONOID_INT32 , GrB_FIRST_INT32 )) ;
216 169 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int64,
217 : GrB_PLUS_MONOID_INT64 , GrB_FIRST_INT64 )) ;
218 168 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint8,
219 : GrB_PLUS_MONOID_UINT8 , GrB_FIRST_UINT8 )) ;
220 167 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint16,
221 : GrB_PLUS_MONOID_UINT16, GrB_FIRST_UINT16)) ;
222 166 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint32,
223 : GrB_PLUS_MONOID_UINT32, GrB_FIRST_UINT32)) ;
224 165 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint64,
225 : GrB_PLUS_MONOID_UINT64, GrB_FIRST_UINT64)) ;
226 164 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_fp32,
227 : GrB_PLUS_MONOID_FP32 , GrB_FIRST_FP32 )) ;
228 163 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_fp64,
229 : GrB_PLUS_MONOID_FP64 , GrB_FIRST_FP64 )) ;
230 :
231 : // LAGraph_plus_second_T: using the GrB_PLUS_MONOID_T monoid and the
232 : // GrB_SECOND_T multiplicative operator. These semirings compute C=A*B
233 : // where only the structure of A is accessed. In MATLAB, this can be
234 : // written as:
235 : //
236 : // C = spones (A) * B
237 :
238 162 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int8,
239 : GrB_PLUS_MONOID_INT8 , GrB_SECOND_INT8 )) ;
240 161 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int16,
241 : GrB_PLUS_MONOID_INT16 , GrB_SECOND_INT16 )) ;
242 160 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int32,
243 : GrB_PLUS_MONOID_INT32 , GrB_SECOND_INT32 )) ;
244 159 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int64,
245 : GrB_PLUS_MONOID_INT64 , GrB_SECOND_INT64 )) ;
246 158 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint8,
247 : GrB_PLUS_MONOID_UINT8 , GrB_SECOND_UINT8 )) ;
248 157 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint16,
249 : GrB_PLUS_MONOID_UINT16, GrB_SECOND_UINT16)) ;
250 156 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint32,
251 : GrB_PLUS_MONOID_UINT32, GrB_SECOND_UINT32)) ;
252 155 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint64,
253 : GrB_PLUS_MONOID_UINT64, GrB_SECOND_UINT64)) ;
254 154 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_fp32,
255 : GrB_PLUS_MONOID_FP32 , GrB_SECOND_FP32 )) ;
256 153 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_fp64,
257 : GrB_PLUS_MONOID_FP64 , GrB_SECOND_FP64 )) ;
258 :
259 : // LAGraph_plus_one_T: using the GrB_PLUS_MONOID_T monoid and the
260 : // corresponding GrB_ONEB_T multiplicative operator. These semirings
261 : // compute a matrix C=A*B that does not depend on the type or values of
262 : // the matrices A and B. C(i,j) is the size of the intersection of the
263 : // structures of A(i,:) and B(:,j). In MATLAB, for the FP64 data type,
264 : // this can be written as:
265 : //
266 : // C = spones (A) * spones (B)
267 :
268 152 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int8,
269 : GrB_PLUS_MONOID_INT8 , GrB_ONEB_INT8 )) ;
270 151 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int16,
271 : GrB_PLUS_MONOID_INT16 , GrB_ONEB_INT16 )) ;
272 150 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int32,
273 : GrB_PLUS_MONOID_INT32 , GrB_ONEB_INT32 )) ;
274 149 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int64,
275 : GrB_PLUS_MONOID_INT64 , GrB_ONEB_INT64 )) ;
276 148 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint8,
277 : GrB_PLUS_MONOID_UINT8 , GrB_ONEB_UINT8 )) ;
278 147 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint16,
279 : GrB_PLUS_MONOID_UINT16, GrB_ONEB_UINT16)) ;
280 146 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint32,
281 : GrB_PLUS_MONOID_UINT32, GrB_ONEB_UINT32)) ;
282 145 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint64,
283 : GrB_PLUS_MONOID_UINT64, GrB_ONEB_UINT64)) ;
284 144 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_fp32,
285 : GrB_PLUS_MONOID_FP32 , GrB_ONEB_FP32 )) ;
286 143 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_fp64,
287 : GrB_PLUS_MONOID_FP64 , GrB_ONEB_FP64 )) ;
288 :
289 : // LAGraph_any_one_T: using the GrB_MIN_MONOID_T for non-boolean types,
290 : // or GrB_LOR_MONOID_BOOL for boolean, and the GrB_ONEB_T multiplicative
291 : // operator. Given any matrices A and B, C = A*B when using this semiring
292 : // computes a matrix C whose values (for entries present) are all equal to
293 : // 1. The result is dependent only on the structure of A and B, not their
294 : // data types or values. In MATLAB, this could be written for FP64 as:
295 : //
296 : // C = spones (spones (A) * spones (B))
297 : //
298 : // The MIN monoid could also be MAX, TIMES, or GxB_ANY (for SuiteSparse
299 : // GraphBLAS), or it could be BOR or BAND for the unsigned integer types.
300 : // The LOR monoid could also be LAND or EQ. All of these monoids reduce
301 : // a set of values { 1, 1, 1, ... 1, 1 } down to the single scalar value
302 : // of 1, or true, and thus any of these monoids will compute the same
303 : // thing.
304 :
305 142 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_bool,
306 : GrB_LOR_MONOID_BOOL , GrB_ONEB_BOOL )) ;
307 141 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int8,
308 : GrB_MIN_MONOID_INT8 , GrB_ONEB_INT8 )) ;
309 140 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int16,
310 : GrB_MIN_MONOID_INT16 , GrB_ONEB_INT16 )) ;
311 139 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int32,
312 : GrB_MIN_MONOID_INT32 , GrB_ONEB_INT32 )) ;
313 138 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int64,
314 : GrB_MIN_MONOID_INT64 , GrB_ONEB_INT64 )) ;
315 137 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint8,
316 : GrB_MIN_MONOID_UINT8 , GrB_ONEB_UINT8 )) ;
317 136 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint16,
318 : GrB_MIN_MONOID_UINT16 , GrB_ONEB_UINT16)) ;
319 135 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint32,
320 : GrB_MIN_MONOID_UINT32 , GrB_ONEB_UINT32)) ;
321 134 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint64,
322 : GrB_MIN_MONOID_UINT64 , GrB_ONEB_UINT64)) ;
323 133 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_fp32,
324 : GrB_MIN_MONOID_FP32 , GrB_ONEB_FP32 )) ;
325 132 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_fp64,
326 : GrB_MIN_MONOID_FP64 , GrB_ONEB_FP64 )) ;
327 :
328 131 : LG_set_LAGr_Init_has_been_called (true) ;
329 131 : return (GrB_SUCCESS) ;
330 : }
331 :
|