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 237 : void LG_set_LAGr_Init_has_been_called (bool setting)
43 : {
44 237 : LG_LAGr_Init_has_been_called = setting ;
45 237 : }
46 :
47 : LAGRAPH_PUBLIC
48 299 : bool LG_get_LAGr_Init_has_been_called (void)
49 : {
50 299 : 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 240 : 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 240 : LG_CLEAR_MSG ;
136 :
137 : #if LAGRAPH_SUITESPARSE
138 240 : if (!(mode == GxB_NONBLOCKING_GPU || mode == GxB_BLOCKING_GPU))
139 : #endif
140 : {
141 240 : LG_ASSERT (user_malloc_function != NULL, GrB_NULL_POINTER) ;
142 238 : LG_ASSERT (user_free_function != NULL, GrB_NULL_POINTER) ;
143 : }
144 : GrB_Info info ;
145 :
146 : // ensure LAGr_Init has not already been called
147 237 : LG_ASSERT_MSG (!LG_get_LAGr_Init_has_been_called ( ), GrB_INVALID_VALUE,
148 : "LAGr*_Init can only be called once") ;
149 :
150 : //--------------------------------------------------------------------------
151 : // start GraphBLAS
152 : //--------------------------------------------------------------------------
153 :
154 : #if LAGRAPH_SUITESPARSE
155 :
156 235 : info = GxB_init (mode,
157 : user_malloc_function,
158 : user_calloc_function,
159 : user_realloc_function,
160 : user_free_function) ;
161 :
162 : #else
163 :
164 : // GxB_init is not available. Use GrB_init instead.
165 : info = GrB_init (mode) ;
166 :
167 : #endif
168 :
169 235 : LG_ASSERT_MSG (info == GrB_SUCCESS || info == GrB_INVALID_VALUE, info,
170 : "failed to initialize GraphBLAS") ;
171 :
172 : #undef LG_FREE_ALL
173 : #define LG_FREE_ALL \
174 : { \
175 : LAGraph_Finalize (msg) ; \
176 : }
177 :
178 : //--------------------------------------------------------------------------
179 : // save the memory management pointers in global LAGraph space
180 : //--------------------------------------------------------------------------
181 :
182 : #if LAGRAPH_SUITESPARSE
183 : // ask SuiteSparse:GraphBLAS for the function pointers
184 225 : GRB_TRY (GrB_Global_get_VOID (GrB_GLOBAL,
185 : (void *) (&LAGraph_Malloc_function),
186 : GxB_MALLOC_FUNCTION)) ;
187 225 : GRB_TRY (GrB_Global_get_VOID (GrB_GLOBAL,
188 : (void *) (&LAGraph_Calloc_function),
189 : GxB_CALLOC_FUNCTION)) ;
190 225 : GRB_TRY (GrB_Global_get_VOID (GrB_GLOBAL,
191 : (void *) (&LAGraph_Realloc_function),
192 : GxB_REALLOC_FUNCTION)) ;
193 225 : GRB_TRY (GrB_Global_get_VOID (GrB_GLOBAL,
194 : (void *) (&LAGraph_Free_function),
195 : GxB_FREE_FUNCTION)) ;
196 : #else
197 : LAGraph_Malloc_function = user_malloc_function ;
198 : LAGraph_Calloc_function = user_calloc_function ;
199 : LAGraph_Realloc_function = user_realloc_function ;
200 : LAGraph_Free_function = user_free_function ;
201 : #endif
202 :
203 : //--------------------------------------------------------------------------
204 : // set # of LAGraph threads
205 : //--------------------------------------------------------------------------
206 :
207 225 : LG_nthreads_outer = 1 ; // for LAGraph itself, if nested
208 : // regions call GraphBLAS
209 : #ifdef _OPENMP
210 : LG_nthreads_inner = omp_get_max_threads ( ) ; // for lower-level parallelism
211 : #else
212 225 : LG_nthreads_inner = 1 ;
213 : #endif
214 :
215 225 : GRB_TRY (LG_SET_NTHREADS (LG_nthreads_inner)) ;
216 :
217 : //--------------------------------------------------------------------------
218 : // create global objects
219 : //--------------------------------------------------------------------------
220 :
221 225 : LG_Random_Init (msg) ;
222 :
223 : // LAGraph_plus_first_T: using the GrB_PLUS_MONOID_T monoid and the
224 : // GrB_FIRST_T multiplicative operator. These semirings compute C=A*B
225 : // where only the structure of B is accessed. In MATLAB, this can be
226 : // written as:
227 : //
228 : // C = A * spones (B)
229 :
230 225 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int8,
231 : GrB_PLUS_MONOID_INT8 , GrB_FIRST_INT8 )) ;
232 220 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int16,
233 : GrB_PLUS_MONOID_INT16 , GrB_FIRST_INT16 )) ;
234 219 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int32,
235 : GrB_PLUS_MONOID_INT32 , GrB_FIRST_INT32 )) ;
236 218 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_int64,
237 : GrB_PLUS_MONOID_INT64 , GrB_FIRST_INT64 )) ;
238 217 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint8,
239 : GrB_PLUS_MONOID_UINT8 , GrB_FIRST_UINT8 )) ;
240 216 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint16,
241 : GrB_PLUS_MONOID_UINT16, GrB_FIRST_UINT16)) ;
242 215 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint32,
243 : GrB_PLUS_MONOID_UINT32, GrB_FIRST_UINT32)) ;
244 214 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_uint64,
245 : GrB_PLUS_MONOID_UINT64, GrB_FIRST_UINT64)) ;
246 213 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_fp32,
247 : GrB_PLUS_MONOID_FP32 , GrB_FIRST_FP32 )) ;
248 212 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_first_fp64,
249 : GrB_PLUS_MONOID_FP64 , GrB_FIRST_FP64 )) ;
250 :
251 : // LAGraph_plus_second_T: using the GrB_PLUS_MONOID_T monoid and the
252 : // GrB_SECOND_T multiplicative operator. These semirings compute C=A*B
253 : // where only the structure of A is accessed. In MATLAB, this can be
254 : // written as:
255 : //
256 : // C = spones (A) * B
257 :
258 211 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int8,
259 : GrB_PLUS_MONOID_INT8 , GrB_SECOND_INT8 )) ;
260 210 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int16,
261 : GrB_PLUS_MONOID_INT16 , GrB_SECOND_INT16 )) ;
262 209 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int32,
263 : GrB_PLUS_MONOID_INT32 , GrB_SECOND_INT32 )) ;
264 208 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_int64,
265 : GrB_PLUS_MONOID_INT64 , GrB_SECOND_INT64 )) ;
266 207 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint8,
267 : GrB_PLUS_MONOID_UINT8 , GrB_SECOND_UINT8 )) ;
268 206 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint16,
269 : GrB_PLUS_MONOID_UINT16, GrB_SECOND_UINT16)) ;
270 205 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint32,
271 : GrB_PLUS_MONOID_UINT32, GrB_SECOND_UINT32)) ;
272 204 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_uint64,
273 : GrB_PLUS_MONOID_UINT64, GrB_SECOND_UINT64)) ;
274 203 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_fp32,
275 : GrB_PLUS_MONOID_FP32 , GrB_SECOND_FP32 )) ;
276 202 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_second_fp64,
277 : GrB_PLUS_MONOID_FP64 , GrB_SECOND_FP64 )) ;
278 :
279 : // LAGraph_plus_one_T: using the GrB_PLUS_MONOID_T monoid and the
280 : // corresponding GrB_ONEB_T multiplicative operator. These semirings
281 : // compute a matrix C=A*B that does not depend on the type or values of
282 : // the matrices A and B. C(i,j) is the size of the intersection of the
283 : // structures of A(i,:) and B(:,j). In MATLAB, for the FP64 data type,
284 : // this can be written as:
285 : //
286 : // C = spones (A) * spones (B)
287 :
288 201 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int8,
289 : GrB_PLUS_MONOID_INT8 , GrB_ONEB_INT8 )) ;
290 200 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int16,
291 : GrB_PLUS_MONOID_INT16 , GrB_ONEB_INT16 )) ;
292 199 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int32,
293 : GrB_PLUS_MONOID_INT32 , GrB_ONEB_INT32 )) ;
294 198 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_int64,
295 : GrB_PLUS_MONOID_INT64 , GrB_ONEB_INT64 )) ;
296 197 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint8,
297 : GrB_PLUS_MONOID_UINT8 , GrB_ONEB_UINT8 )) ;
298 196 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint16,
299 : GrB_PLUS_MONOID_UINT16, GrB_ONEB_UINT16)) ;
300 195 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint32,
301 : GrB_PLUS_MONOID_UINT32, GrB_ONEB_UINT32)) ;
302 194 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_uint64,
303 : GrB_PLUS_MONOID_UINT64, GrB_ONEB_UINT64)) ;
304 193 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_fp32,
305 : GrB_PLUS_MONOID_FP32 , GrB_ONEB_FP32 )) ;
306 192 : GRB_TRY (GrB_Semiring_new (&LAGraph_plus_one_fp64,
307 : GrB_PLUS_MONOID_FP64 , GrB_ONEB_FP64 )) ;
308 :
309 : // LAGraph_any_one_T: using the GrB_MIN_MONOID_T for non-boolean types,
310 : // or GrB_LOR_MONOID_BOOL for boolean, and the GrB_ONEB_T multiplicative
311 : // operator. Given any matrices A and B, C = A*B when using this semiring
312 : // computes a matrix C whose values (for entries present) are all equal to
313 : // 1. The result is dependent only on the structure of A and B, not their
314 : // data types or values. In MATLAB, this could be written for FP64 as:
315 : //
316 : // C = spones (spones (A) * spones (B))
317 : //
318 : // The MIN monoid could also be MAX, TIMES, or GxB_ANY (for SuiteSparse
319 : // GraphBLAS), or it could be BOR or BAND for the unsigned integer types.
320 : // The LOR monoid could also be LAND or EQ. All of these monoids reduce
321 : // a set of values { 1, 1, 1, ... 1, 1 } down to the single scalar value
322 : // of 1, or true, and thus any of these monoids will compute the same
323 : // thing.
324 :
325 191 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_bool,
326 : GrB_LOR_MONOID_BOOL , GrB_ONEB_BOOL )) ;
327 190 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int8,
328 : GrB_MIN_MONOID_INT8 , GrB_ONEB_INT8 )) ;
329 189 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int16,
330 : GrB_MIN_MONOID_INT16 , GrB_ONEB_INT16 )) ;
331 188 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int32,
332 : GrB_MIN_MONOID_INT32 , GrB_ONEB_INT32 )) ;
333 187 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_int64,
334 : GrB_MIN_MONOID_INT64 , GrB_ONEB_INT64 )) ;
335 186 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint8,
336 : GrB_MIN_MONOID_UINT8 , GrB_ONEB_UINT8 )) ;
337 185 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint16,
338 : GrB_MIN_MONOID_UINT16 , GrB_ONEB_UINT16)) ;
339 184 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint32,
340 : GrB_MIN_MONOID_UINT32 , GrB_ONEB_UINT32)) ;
341 183 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_uint64,
342 : GrB_MIN_MONOID_UINT64 , GrB_ONEB_UINT64)) ;
343 182 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_fp32,
344 : GrB_MIN_MONOID_FP32 , GrB_ONEB_FP32 )) ;
345 181 : GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_fp64,
346 : GrB_MIN_MONOID_FP64 , GrB_ONEB_FP64 )) ;
347 :
348 180 : LG_set_LAGr_Init_has_been_called (true) ;
349 180 : return (GrB_SUCCESS) ;
350 : }
|