pathrex-sys 0.1.0

Native FFI bindings for SuiteSparse:GraphBLAS and LAGraph used by the pathrex crate.
Documentation
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
//------------------------------------------------------------------------------
// LG_internal.h: include file for use within LAGraph itself
//------------------------------------------------------------------------------

// LAGraph, (c) 2019-2025 by The LAGraph Contributors, All Rights Reserved.
// SPDX-License-Identifier: BSD-2-Clause
//
// For additional details (including references to third party source code and
// other files) see the LICENSE file or contact permission@sei.cmu.edu. See
// Contributors.txt for a full list of contributors. Created, in part, with
// funding and support from the U.S. Government (see Acknowledgments.txt file).
// DM22-0790

// Contributed by Timothy A. Davis, Texas A&M University

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

// These definitions are not meant for the user application that relies on
// LAGraph and/or GraphBLAS.  LG_* methods are for internal use in LAGraph.

#ifndef LG_INTERNAL_H
#define LG_INTERNAL_H

//------------------------------------------------------------------------------
// include files
//------------------------------------------------------------------------------

#include <ctype.h>
#include "LAGraph.h"
#undef I

#if defined ( __linux__ )
#include <malloc.h>
#endif

#define LG_RESTRICT LAGRAPH_RESTRICT

//------------------------------------------------------------------------------
// string macros
//------------------------------------------------------------------------------

#define LG_XSTR(x) LG_STR(x)
#define LG_STR(x) #x

//------------------------------------------------------------------------------
// string matching
//------------------------------------------------------------------------------

#define MATCH(s1,s2,n) (strncmp (s1, s2, n) == 0)
#define MATCHNAME(s1,s2) MATCH (s1, s2, LAGRAPH_MAX_NAME_LEN)

//------------------------------------------------------------------------------
// typedefs
//------------------------------------------------------------------------------

// LG_void: used in place of (void *), but valid for pointer arithmetic
typedef unsigned char LG_void ;

//------------------------------------------------------------------------------
// LG_CLEAR_MSG: clear the error msg string
//------------------------------------------------------------------------------

// When an LAGraph method starts, it first clears the caller's msg string.
#define LG_CLEAR_MSG                    \
{                                       \
    if (msg != NULL) msg [0] = '\0' ;   \
}

//------------------------------------------------------------------------------
// LG_ERROR_MSG: set the error msg string
//------------------------------------------------------------------------------

// When an LAGraph method encounters an error, it can report details in the
// msg.  This is normally done via LG_ASSERT_MSG.  For example:

/*
    if (src < 0 || src >= n)
    {
        LG_ERROR_MSG ("Source node %ld must be in range 0 to n-1, "
            "where n = %ld is the number of nodes in the graph.", src, n) ;
        return (GrB_INVALID_INDEX) ;
    }
    // or, with a simpler message:
    LG_ASSERT_MSG (src >= 0 && src < n, GrB_INVALID_INDEX, "invalid src node") ;
*/

#define LG_ERROR_MSG(...)                                           \
{                                                                   \
    if (msg != NULL && msg [0] == '\0')                             \
    {                                                               \
        snprintf (msg, LAGRAPH_MSG_LEN, __VA_ARGS__) ;              \
    }                                                               \
}

//------------------------------------------------------------------------------
// LG_FREE_WORK: free all workspace
//------------------------------------------------------------------------------

#ifndef LG_FREE_WORK
#define LG_FREE_WORK ;
#endif

//------------------------------------------------------------------------------
// LG_FREE_ALL: free all workspace and all output arguments, on error
//------------------------------------------------------------------------------

#ifndef LG_FREE_ALL
#define LG_FREE_ALL             \
{                               \
    LG_FREE_WORK ;              \
}
#endif

//------------------------------------------------------------------------------
// GRB_CATCH: catch an error from GraphBLAS
//------------------------------------------------------------------------------

// A simple GRB_CATCH macro to be used by GRB_TRY.  If an LAGraph function
// wants something else, then #define a GRB_CATCH macro before the #include
// "LG_internal.h" statement.

#ifndef GRB_CATCH
#define GRB_CATCH(info)                                                 \
{                                                                       \
    LG_ERROR_MSG ("GraphBLAS failure (file %s, line %d): info: %d",     \
        __FILE__, __LINE__, info) ;                                     \
    LG_FREE_ALL ;                                                       \
    return (info) ;                                                     \
}
#endif

//------------------------------------------------------------------------------
// LAGRAPH_CATCH: catch an error from LAGraph
//------------------------------------------------------------------------------

// A simple LAGRAPH_CATCH macro to be used by LAGRAPH_TRY.  If an LAGraph
// function wants something else, then #define a LAGRAPH_CATCH macro before the
// #include "LG_internal.h" statement.

#ifndef LAGRAPH_CATCH
#define LAGRAPH_CATCH(status)                                           \
{                                                                       \
    LG_ERROR_MSG ("LAGraph failure (file %s, line %d): status: %d",     \
        __FILE__, __LINE__, status) ;                                   \
    LG_FREE_ALL ;                                                       \
    return (status) ;                                                   \
}
#endif

//------------------------------------------------------------------------------
// LG_ASSERT_MSGF: assert an expression is true, and return if it is false
//------------------------------------------------------------------------------

// Identical to LG_ASSERT_MSG, except this allows a printf-style formatted
// message.

#define LG_ASSERT_MSGF(expression,error_status,expression_format,...)   \
{                                                                       \
    if (!(expression))                                                  \
    {                                                                   \
        LG_ERROR_MSG ("LAGraph failure (file %s, line %d): "            \
            expression_format, __FILE__, __LINE__, __VA_ARGS__) ;       \
        LG_FREE_ALL ;                                                   \
        return (error_status) ;                                         \
    }                                                                   \
}

//------------------------------------------------------------------------------
// LG_ASSERT_MSG: assert an expression is true, and return if it is false
//------------------------------------------------------------------------------

// Identical to LG_ASSERT, except this allows a different string to be
// included in the message.

#define LG_ASSERT_MSG(expression,error_status,expression_message)       \
    LG_ASSERT_MSGF (expression,error_status,"%s",expression_message)

//------------------------------------------------------------------------------
// LG_ASSERT: assert an expression is true, and return if it is false
//------------------------------------------------------------------------------

// LAGraph methods can use this assertion macro for simple errors.

#define LG_ASSERT(expression, error_status)                                 \
{                                                                           \
    if (!(expression))                                                      \
    {                                                                       \
        LG_ERROR_MSG ("LAGraph assertion \"%s\" failed (file %s, line %d):" \
            " status: %d", LG_XSTR(expression), __FILE__, __LINE__,         \
            error_status) ;                                                 \
        LG_FREE_ALL ;                                                       \
        return (error_status) ;                                             \
    }                                                                       \
}

//------------------------------------------------------------------------------
// LG_TRY: check a condition and return on error
//------------------------------------------------------------------------------

// The msg is not modified.  This should be used when an LAGraph method calls
// another one.

#define LG_TRY(LAGraph_method)                  \
{                                               \
    int LAGraph_status = LAGraph_method ;       \
    if (LAGraph_status < 0)                     \
    {                                           \
        LG_FREE_ALL ;                           \
        return (LAGraph_status) ;               \
    }                                           \
}

//------------------------------------------------------------------------------
// LG_CLEAR_MSG_AND_BASIC_ASSERT: clear msg and do basic tests of a graph
//------------------------------------------------------------------------------

#define LG_CLEAR_MSG_AND_BASIC_ASSERT(G,msg)                                \
{                                                                           \
    LG_CLEAR_MSG ;                                                          \
    LG_ASSERT (G != NULL, GrB_NULL_POINTER) ;                               \
    LG_ASSERT_MSG (G->A != NULL, LAGRAPH_INVALID_GRAPH,                     \
        "graph adjacency matrix is NULL") ;                                 \
    LG_ASSERT_MSG (G->kind >= LAGraph_ADJACENCY_UNDIRECTED &&               \
        G->kind <= LAGraph_ADJACENCY_DIRECTED,                              \
        LAGRAPH_INVALID_GRAPH, "graph kind invalid") ;                      \
}

//------------------------------------------------------------------------------
// FPRINTF: fprintf and check result
//------------------------------------------------------------------------------

#define FPRINTF(f,...)                                                      \
{                                                                           \
    LG_ASSERT_MSG (fprintf (f, __VA_ARGS__) >= 0,                           \
        LAGRAPH_IO_ERROR, "Unable to write to file") ;                      \
}

//------------------------------------------------------------------------------
// code development settings
//------------------------------------------------------------------------------

// turn off debugging; do not edit these three lines
#ifndef NDEBUG
#define NDEBUG
#endif

// These flags are used for code development.  Uncomment them as needed.

// to turn on debugging, uncomment this line:
// #undef NDEBUG

#undef ASSERT

#ifndef NDEBUG

    // debugging enabled
    #ifdef MATLAB_MEX_FILE
        // debugging when LAGraph is part of a mexFunction
        #define ASSERT(x)                                               \
        {                                                               \
            if (!(x)) mexErrMsgTxt ("failure: " __FILE__ " line: ") ;   \
        }
    #else
        #include <assert.h>
        #define ASSERT(x) assert (x) ;
    #endif

#else

    // debugging disabled
    #define ASSERT(x)

#endif

// GraphBLAS version 10 flag
#if LAGRAPH_SUITESPARSE 
    #if GxB_IMPLEMENTATION >= GxB_VERSION (10,0,0)
        #define LG_SUITESPARSE_GRAPHBLAS_V10 1
    #else
        #define LG_SUITESPARSE_GRAPHBLAS_V10 0
    #endif
#else
    #define LG_SUITESPARSE_GRAPHBLAS_V10 0
#endif

//------------------------------------------------------------------------------
// LG_Multiply_size_t:  c = a*b but check for overflow
//------------------------------------------------------------------------------

static bool LG_Multiply_size_t  // true if ok, false if overflow
(
    size_t *c,                  // c = a*b, or zero if overflow occurs
    const size_t a,
    const size_t b
)
{

    ASSERT (c != NULL) ;

    (*c) = 0 ;
    if (a == 0 || b == 0)
    {
        return (true) ;
    }

    if (a > SIZE_MAX / 2 || b > SIZE_MAX / 2)
    {
        // a or b are out of range
        return (false) ;
    }

    // a + b is now safe to compute
    if ((a + b) > (SIZE_MAX / LAGRAPH_MIN (a,b)))
    {
        // a * b may overflow
        return (false) ;
    }

    // a * b will not overflow
    (*c) = a * b ;
    return (true) ;
}

//------------------------------------------------------------------------------
// Matrix Market format
//------------------------------------------------------------------------------

// %%MatrixMarket matrix <fmt> <type> <storage> uses the following enums:

typedef enum
{
    MM_coordinate,
    MM_array,
}
MM_fmt_enum ;

typedef enum
{
    MM_real,
    MM_integer,
    MM_complex,
    MM_pattern
}
MM_type_enum ;

typedef enum
{
    MM_general,
    MM_symmetric,
    MM_skew_symmetric,
    MM_hermitian
}
MM_storage_enum ;

// maximum length of each line in the Matrix Market file format

// The MatrixMarket format specificies a maximum line length of 1024.
// This is currently sufficient for GraphBLAS but will need to be relaxed
// if this function is extended to handle arbitrary user-defined types.
#define MMLEN 1024
#define MAXLINE MMLEN+6

//------------------------------------------------------------------------------
// LG_PART and LG_PARTITION: definitions for partitioning an index range
//------------------------------------------------------------------------------

LAGRAPH_PUBLIC extern
int LG_nthreads_outer ; // # of threads to use at the higher level of a nested
                        // parallel region in LAGraph.  Default: 1.

LAGRAPH_PUBLIC extern
int LG_nthreads_inner ; // # of threads to use at the lower level of a nested
                        // parallel region, or to use inside GraphBLAS.
                        // Default: the value obtained by omp_get_max_threads
                        // if OpenMP is in use, or 1 otherwise.

// LG_PART and LG_PARTITION:  divide the index range 0:n-1 uniformly
// for nthreads.  LG_PART(tid,n,nthreads) is the first index for thread tid.
#define LG_PART(tid,n,nthreads)  \
    (((tid) * ((double) (n))) / ((double) (nthreads)))

// thread tid will operate on the range k1:(k2-1)
#define LG_PARTITION(k1,k2,n,tid,nthreads)                                  \
    k1 = ((tid) ==  0          ) ?  0  : LG_PART ((tid),  n, nthreads) ;    \
    k2 = ((tid) == (nthreads)-1) ? (n) : LG_PART ((tid)+1,n, nthreads)

//------------------------------------------------------------------------------
// LG_eslice: uniform partition of e items to each task
//------------------------------------------------------------------------------

static inline void LG_eslice
(
    int64_t *Slice,         // array of size ntasks+1
    int64_t e,              // number items to partition amongst the tasks
    const int ntasks        // # of tasks
)
{
    Slice [0] = 0 ;
    for (int tid = 0 ; tid < ntasks ; tid++)
    {
        Slice [tid] = LG_PART (tid, e, ntasks) ;
    }
    Slice [ntasks] = e ;
}

//------------------------------------------------------------------------------
// definitions for sorting functions
//------------------------------------------------------------------------------

// All of the LG_qsort_* functions are single-threaded, by design.  The
// LG_msort* functions are parallel.  None of these sorting methods are
// guaranteed to be stable.  These functions are contributed by Tim Davis, and
// are derived from SuiteSparse:GraphBLAS.  Functions named LG_* are not
// meant to be accessible by end users of LAGraph.

#define LG_BASECASE (64 * 1024)

//------------------------------------------------------------------------------
// LG_msort1: sort array of size n
//------------------------------------------------------------------------------

// LG_msort1 sorts an int64_t array of size n in ascending order.

int LG_msort1
(
    // input/output:
    int64_t *A_0,       // size n array
    // input:
    const int64_t n,
    char *msg
) ;

//------------------------------------------------------------------------------
// LG_msort2: sort two arrays of size n
//------------------------------------------------------------------------------

// LG_msort2 sorts two int64_t arrays A of size n in ascending order.
// The arrays are kept in the same order, where the pair (A_0 [k], A_1 [k]) is
// treated as a single pair.  The pairs are sorted by the first value A_0,
// with ties broken by A_1.

int LG_msort2
(
    // input/output:
    int64_t *A_0,       // size n array
    int64_t *A_1,       // size n array
    // input:
    const int64_t n,
    char *msg
) ;

//------------------------------------------------------------------------------
// LG_msort3: sort three arrays of size n
//------------------------------------------------------------------------------

// LG_msort3 sorts three int64_t arrays A of size n in ascending order.
// The arrays are kept in the same order, where the triplet (A_0 [k], A_1 [k],
// A_2 [k]) is treated as a single triplet.  The triplets are sorted by the
// first value A_0, with ties broken by A_1, and then by A_2 if the values of
// A_0 and A_1 are identical.

int LG_msort3
(
    // input/output:
    int64_t *A_0,       // size n array
    int64_t *A_1,       // size n array
    int64_t *A_2,       // size n array
    // input:
    const int64_t n,
    char *msg
) ;

void LG_qsort_1a    // sort array A of size 1-by-n
(
    int64_t *LG_RESTRICT A_0,       // size n array
    const int64_t n
) ;

void LG_qsort_2     // sort array A of size 2-by-n, using 2 keys (A [0:1][])
(
    int64_t *LG_RESTRICT A_0,       // size n array
    int64_t *LG_RESTRICT A_1,       // size n array
    const int64_t n
) ;

void LG_qsort_3     // sort array A of size 3-by-n, using 3 keys (A [0:2][])
(
    int64_t *LG_RESTRICT A_0,       // size n array
    int64_t *LG_RESTRICT A_1,       // size n array
    int64_t *LG_RESTRICT A_2,       // size n array
    const int64_t n
) ;

//------------------------------------------------------------------------------
// LG_lt_1: sorting comparator function, one key
//------------------------------------------------------------------------------

// A [a] and B [b] are keys of one integer.

// LG_lt_1 returns true if A [a] < B [b], for LG_qsort_1b

#define LG_lt_1(A_0, a, B_0, b) (A_0 [a] < B_0 [b])

//------------------------------------------------------------------------------
// LG_lt_2: sorting comparator function, two keys
//------------------------------------------------------------------------------

// A [a] and B [b] are keys of two integers.

// LG_lt_2 returns true if A [a] < B [b], for LG_qsort_2 and LG_msort_2b

#define LG_lt_2(A_0, A_1, a, B_0, B_1, b)                                   \
(                                                                           \
    (A_0 [a] < B_0 [b]) ?                                                   \
    (                                                                       \
        true                                                                \
    )                                                                       \
    :                                                                       \
    (                                                                       \
        (A_0 [a] == B_0 [b]) ?                                              \
        (                                                                   \
            /* primary key is the same; tie-break on the 2nd key */         \
            (A_1 [a] < B_1 [b])                                             \
        )                                                                   \
        :                                                                   \
        (                                                                   \
            false                                                           \
        )                                                                   \
    )                                                                       \
)

//------------------------------------------------------------------------------
// LG_lt_3: sorting comparator function, three keys
//------------------------------------------------------------------------------

// A [a] and B [b] are keys of three integers.

// LG_lt_3 returns true if A [a] < B [b], for LG_qsort_3 and LG_msort_3b

#define LG_lt_3(A_0, A_1, A_2, a, B_0, B_1, B_2, b)                         \
(                                                                           \
    (A_0 [a] < B_0 [b]) ?                                                   \
    (                                                                       \
        true                                                                \
    )                                                                       \
    :                                                                       \
    (                                                                       \
        (A_0 [a] == B_0 [b]) ?                                              \
        (                                                                   \
            /* primary key is the same; tie-break on the 2nd and 3rd key */ \
            LG_lt_2 (A_1, A_2, a, B_1, B_2, b)                              \
        )                                                                   \
        :                                                                   \
        (                                                                   \
            false                                                           \
        )                                                                   \
    )                                                                       \
)

//------------------------------------------------------------------------------
// LG_eq_*: sorting comparator function, three keys
//------------------------------------------------------------------------------

// A [a] and B [b] are keys of two or three integers.
// LG_eq_* returns true if A [a] == B [b]

#define LG_eq_3(A_0, A_1, A_2, a, B_0, B_1, B_2, b)                         \
(                                                                           \
    (A_0 [a] == B_0 [b]) &&                                                 \
    (A_1 [a] == B_1 [b]) &&                                                 \
    (A_2 [a] == B_2 [b])                                                    \
)

#define LG_eq_2(A_0, A_1, a, B_0, B_1, b)                                   \
(                                                                           \
    (A_0 [a] == B_0 [b]) &&                                                 \
    (A_1 [a] == B_1 [b])                                                    \
)

#define LG_eq_1(A_0, a, B_0, b)                                             \
(                                                                           \
    (A_0 [a] == B_0 [b])                                                    \
)

//------------------------------------------------------------------------------
// count entries on the diagonal of a matrix
//------------------------------------------------------------------------------

int LG_nself_edges
(
    // output
    int64_t *nself_edges,   // # of entries
    // input
    GrB_Matrix A,           // matrix to count
    char *msg               // error message
) ;

//------------------------------------------------------------------------------
// simple and portable random number generator
//------------------------------------------------------------------------------

// return a random uint64_t
uint64_t LG_Random64 (uint64_t *seed) ;

// create operators for LAGraph_Random_* methods
int LG_Random_Init (char *msg) ;
int LG_Random_Finalize (char *msg) ;

//------------------------------------------------------------------------------
// LG_KindName: return the name of a kind
//------------------------------------------------------------------------------

// LG_KindName: return the name of a graph kind.  For example, if given
// LAGraph_ADJACENCY_UNDIRECTED, the string "undirected" is returned.

int LG_KindName
(
    // output:
    char *name,     // name of the kind (user provided array of size at least
                    // LAGRAPH_MAX_NAME_LEN)
    // input:
    LAGraph_Kind kind,  // graph kind
    char *msg
) ;

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

// # of entries to print for LAGraph_Matrix_Print and LAGraph_Vector_Print
#define LG_SHORT_LEN 30

//------------------------------------------------------------------------------
// GrB_get/set for SuiteSparse extensions
//------------------------------------------------------------------------------

#if LAGRAPH_SUITESPARSE

    // SuiteSparse:GraphBLAS v8.1 or later
    #define LG_HYPERSPARSE GxB_HYPERSPARSE
    #define LG_SPARSE      GxB_SPARSE
    #define LG_BITMAP      GxB_BITMAP
    #define LG_FULL        GxB_FULL
    #define LG_SET_FORMAT_HINT(object,sparsity) \
        GrB_set (object, (int32_t) (sparsity), GxB_SPARSITY_CONTROL)
    #define LG_GET_FORMAT_HINT(object,status) \
        GrB_get (object, (int32_t *) status, GxB_SPARSITY_STATUS)
    #define LG_SET_NTHREADS(nthreads) \
        GrB_set (GrB_GLOBAL, (int32_t) (nthreads), GxB_NTHREADS)
    #define LG_SET_HYPER_SWITCH(object,hyper) \
        GrB_set (object, hyper, GxB_HYPER_SWITCH)
    #define LG_GET_HYPER_SWITCH(object,hyper) \
        GrB_get (object, hyper, GxB_HYPER_SWITCH)
    #define LG_SET_BURBLE(burble) \
        GrB_set (GrB_GLOBAL, (int32_t) (burble), GxB_BURBLE)
    #define LG_GET_LIBRARY_DATE(date) \
        GrB_get (GrB_GLOBAL, (char *) date, GxB_LIBRARY_DATE)

    #define LG_JIT_OFF   GxB_JIT_OFF
    #define LG_JIT_PAUSE GxB_JIT_PAUSE
    #define LG_JIT_RUN   GxB_JIT_RUN
    #define LG_JIT_LOAD  GxB_JIT_LOAD
    #define LG_JIT_ON    GxB_JIT_ON
    #define LG_SET_JIT(jit) \
        GrB_set (GrB_GLOBAL, (int32_t) (jit), GxB_JIT_C_CONTROL)

    #if defined ( GRAPHBLAS_HAS_CUDA )
    // the LG_brutal_malloc family of methods.
    #define LG_BRUTAL_TESTS 0
    #else
    #define LG_BRUTAL_TESTS 1
    #endif

#else

    // vanilla GraphBLAS
    #define LG_HYPERSPARSE 1
    #define LG_SPARSE      2
    #define LG_BITMAP      4
    #define LG_FULL        8
    #define LG_SET_FORMAT_HINT(object,sparsity) GrB_SUCCESS
    #define LG_SET_NTHREADS(nthreads) GrB_SUCCESS
    #define LG_SET_HYPER_SWITCH(object,hyper) GrB_SUCCESS
    #define LG_GET_HYPER_SWITCH(object,hyper) GrB_SUCCESS
    #define LG_GET_FORMAT_HINT(object,status) GrB_SUCCESS
    #define LG_SET_BURBLE(burble) GrB_SUCCESS
    #define LG_GET_LIBRARY_DATE(date) GrB_SUCCESS

    #define LG_JIT_OFF   0
    #define LG_JIT_PAUSE 1
    #define LG_JIT_RUN   2
    #define LG_JIT_LOAD  3
    #define LG_JIT_ON    4
    #define LG_SET_JIT(jit) GrB_SUCCESS

    #define LG_BRUTAL_TESTS 0

#endif

#endif