File: GB_werk.h

package info (click to toggle)
suitesparse 1%3A7.10.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: 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 (124 lines) | stat: -rw-r--r-- 5,233 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
//------------------------------------------------------------------------------
// GB_werk.h: definitions for werkspace management on the Werk stack
//------------------------------------------------------------------------------

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

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

#ifndef GB_WERK_H
#define GB_WERK_H

//------------------------------------------------------------------------------
// GB_Werk: error logging and Werk space
//------------------------------------------------------------------------------

// Error messages are logged in Werk->logger_handle, on the stack which is
// handle to the input/output matrix/vector (typically C).  If the user-defined
// data types, operators, etc have really long names, the error messages are
// safely truncated (via snprintf).  This is intentional, but gcc with
// -Wformat-truncation will print a warning (see pragmas above).  Ignore the
// warning.

// GB_WERK_SIZE is the size of a small fixed-sized array in the Werk, used
// for small werkspace allocations (typically O(# of threads or # tasks)).
// GB_WERK_SIZE must be a multiple of 8.  The Werk->Stack array is placed first
// in the GB_Werk struct, to ensure proper alignment.

#define GB_WERK_SIZE 16384

typedef struct
{
    GB_void Stack [GB_WERK_SIZE] ;  // werkspace stack
    const char *where ;             // GraphBLAS function where error occurred
    char **logger_handle ;          // error report
    size_t *logger_size_handle ;
    int pwerk ;                     // top of Werk stack, initially zero

    // integer control, combines C->[pji]_control and Global [pji]_control:
    uint8_t p_control ;             // effective p_control for this method
    uint8_t j_control ;             // effective j_control for this method
    uint8_t i_control ;             // effective i_control for this method
}
GB_Werk_struct ;

typedef GB_Werk_struct *GB_Werk ;

//------------------------------------------------------------------------------
// GB_werk_push/pop: manage werkspace in the Werk stack
//------------------------------------------------------------------------------

// Werk->Stack is a small fixed-size array that is allocated on the stack
// of any user-callable GraphBLAS function.  It is used for small werkspace
// allocations.

//------------------------------------------------------------------------------
// GB_werk_push: allocate werkspace from the Werk stack or malloc
//------------------------------------------------------------------------------

// The werkspace is allocated from the Werk static if it small enough and space
// is available.  Otherwise it is allocated by malloc.

#ifdef comments_only
void *GB_werk_push    // return pointer to newly allocated space
(
    // output
    size_t *size_allocated,     // # of bytes actually allocated
    bool *on_stack,             // true if werkspace is from Werk stack
    // input
    size_t nitems,              // # of items to allocate
    size_t size_of_item,        // size of each item
    GB_Werk Werk
) ;
#endif

//------------------------------------------------------------------------------
// GB_werk_pop:  free werkspace from the Werk stack
//------------------------------------------------------------------------------

// If the werkspace was allocated from the Werk stack, it must be at the top of
// the stack to free it properly.  Freeing a werkspace in the middle of the
// Werk stack also frees everything above it.  Freeing werkspace from the Werk
// stack is done in LIFO order, like a stack.

#ifdef comments_only
void *GB_werk_pop     // free the top block of werkspace memory
(
    // input/output
    void *p,                    // werkspace to free
    size_t *size_allocated,     // # of bytes actually allocated for p
    // input
    bool on_stack,              // true if werkspace is from Werk stack
    size_t nitems,              // # of items to allocate
    size_t size_of_item,        // size of each item
    GB_Werk Werk
) ;
#endif

//------------------------------------------------------------------------------
// Werk helper macros
//------------------------------------------------------------------------------

// declare a werkspace X of a given type
#define GB_WERK_DECLARE(X,type)                             \
    type *restrict X = NULL ;                               \
    bool X ## _on_stack = false ;                           \
    size_t X ## _nitems = 0, X ## _size_allocated = 0 ;

// push werkspace X
#define GB_WERK_PUSH(X,nitems,type)                                         \
    X ## _nitems = (nitems) ;                                               \
    X = (type *) GB_werk_push (&(X ## _size_allocated), &(X ## _on_stack),  \
        X ## _nitems, sizeof (type), Werk) ; 

// pop werkspace X
#define GB_WERK_POP(X,type)                                                 \
    X = (type *) GB_werk_pop (X, &(X ## _size_allocated), X ## _on_stack,   \
        X ## _nitems, sizeof (type), Werk) ; 

// GB_ROUND8(s) rounds up s to a multiple of 8
#define GB_ROUND8(s) (((s) + 7) & (~0x7))

#endif