-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquark.h
272 lines (217 loc) · 10.5 KB
/
quark.h
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
/**
*
* @file quark.h
*
* Dynamic scheduler functions
*
* PLASMA is a software package provided by Univ. of Tennessee,
* Univ. of California Berkeley and Univ. of Colorado Denver
*
* @version 2.8.0
* @author Asim YarKhan
* @date 2010-11-15
*
**/
#ifndef QUARK_H
#define QUARK_H
#include <limits.h>
#include <stdio.h>
#if defined( _WIN32 )
/* This must be included before INPUT is defined below, otherwise we
have a name clash/problem */
#include <windows.h>
#include <limits.h>
#else
#include <inttypes.h>
#endif
#include "quark_unpack_args.h"
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
#ifdef DBGQUARK
/* #define DBGPRINTF(str, ...) { fprintf(stderr, "%s:%d: [%s] " str, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); } */
#define DBGPRINTF(...) { fprintf(stderr, __VA_ARGS__); }
#else
#define DBGPRINTF(...) if (0) {};
#endif
#define QUARK_SUCCESS 0
#define QUARK_ERR -1
#define QUARK_ERR_UNEXPECTED -1
#define QUARK_ERR_NOT_SUPPORTED -2
/* A bitmask of 8 bits to to hold region markers */
#define QUARK_REGION_BITMASK 0x0000FF
#define QUARK_REGION_ALL 0x0FF
typedef enum { QUARK_REGION_0=1<<0, QUARK_REGION_1=1<<1, QUARK_REGION_2=1<<2, QUARK_REGION_3=1<<3,
QUARK_REGION_4=1<<4, QUARK_REGION_5=1<<5, QUARK_REGION_6=1<<6, QUARK_REGION_7=1<<7 } quark_data_region_t;
typedef enum { QUARK_REGION_L=QUARK_REGION_0|QUARK_REGION_1|QUARK_REGION_2,
QUARK_REGION_D=QUARK_REGION_3|QUARK_REGION_4,
QUARK_REGION_U=QUARK_REGION_5|QUARK_REGION_6|QUARK_REGION_7 } quark_ldu_region_t;
/* Data items can be: */
/* INPUT, OUTPUT, INOUT: these data items create dependencies */
/* VALUE: these data items get copied over */
/* NODEP: these data items get copied over, and are not used for dependencies */
/* SCRATCH: these data items can be allocated (and deallocted) by the scheduler when tasks execute */
#define QUARK_DIRECTION_BITMASK 0x000F00
typedef enum { QINPUT=0x100, OUTPUT=0x200, INOUT=0x300, VALUE=0x400, NODEP=0x500, SCRATCH=0x600} quark_direction_t;
#define INPUT 0x100
#define QUARK_VALUE_FLAGS_BITMASK 0xFFF000
/* Data locality flag; ie keep data on the same core if possible */
#define LOCALITY ( 1 << 12 )
#define NOLOCALITY 0x00
/* A data address with a sequence of ACCUMULATOR dependencies will allow the related tasks to be reordered */
#define ACCUMULATOR ( 1 << 13 )
#define NOACCUMULATOR 0x00
/* A data address with a sequence of GATHERV dependencies will allow the related tasks to be run in parallel */
#define GATHERV ( 1 << 14 )
#define NOGATHERV 0x00
/* The following are task level flags, that can be either provided as additional arguments to the task, or via SET functions */
/* The task label; should be provided as a null terminated string */
#define TASK_LABEL ( 1 << 15 )
#define TASKLABEL TASK_LABEL /* depreciated label */
/* The task color; should be provided as a null terminated string */
#define TASK_COLOR ( 1 << 16 )
#define TASKCOLOR TASK_COLOR /* depreciated label */
/* The priority of the task, provided as an integer */
#define TASK_PRIORITY ( 1 << 17 )
/* Lock the task to a specific thread number (0 ... NTHREADS-1), provided as an integer */
#define TASK_LOCK_TO_THREAD ( 1 << 18 )
/* The sequence pointer to be associated with the task, provided as a pointer */
#define TASK_SEQUENCE ( 1 << 19 )
/* An integere for the number of threads require */
#define TASK_THREAD_COUNT ( 1 << 20 )
/* The thread that runs this task should have manual scheduling enabled (1) or disabled (0) */
#define THREAD_SET_TO_MANUAL_SCHEDULING ( 1 << 21 )
/* Lock the task to a thead mask (0 ... NTHREADS-1) bits long, provided as a character array (byte array) */
#define TASK_LOCK_TO_THREAD_MASK ( 1 << 22 )
/* The start/stop event code to overwrite quark events types for tracing */
#define TASK_START_CODE ( 1 << 23 )
#define TASK_STOP_CODE ( 1 << 24 )
/* The range for priority values */
#define QUARK_TASK_MIN_PRIORITY 0
#define QUARK_TASK_MAX_PRIORITY INT_MAX
/* Definition of structure holding scheduler information */
typedef struct quark_s Quark;
/* Structure holding task information */
typedef struct quark_task_s Quark_Task;
/* Create a type for setting task flags */
struct quark_task_flags_s {
int task_priority;
int task_lock_to_thread;
char *task_color;
char *task_label;
void *task_sequence;
int start_code, stop_code;
int task_thread_count;
int thread_set_to_manual_scheduling;
unsigned char *task_lock_to_thread_mask;
};
typedef struct quark_task_flags_s Quark_Task_Flags;
/* Static initializer for Quark_Task_Flags_t */
#define Quark_Task_Flags_Initializer { (int)0, (int)-1, (char *)NULL, (char *)NULL, (void *)NULL, (int)0, (int)0, (int)1, (int)-1, (unsigned char *)NULL }
/* Setup scheduler data structures, assumes threads are managed seperately */
Quark *QUARK_Setup(int num_threads);
/* Setup scheduler data structures, spawn worker threads, start the workers working */
Quark *QUARK_New(int num_threads);
/* Add a task, called by the master process (thread_rank 0) */
unsigned long long QUARK_Insert_Task(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags, ...);
/* Main work loop, called externally by everyone but the master
* (master manages this internally to the insert_task and waitall
* routines). Each worker thread can call work_main_loop( quark,
* thread_rank), where thread rank is 1...NUMTHREADS ) */
void QUARK_Worker_Loop(Quark *quark, int thread_rank);
/* Finish work and return. Workers do not exit */
void QUARK_Barrier(Quark * quark);
/* Just wait for current tasks to complete, the scheduler and
* strutures remain as is... should allow for repeated use of the
* scheduler. The workers return from their loops.*/
void QUARK_Waitall(Quark * quark);
/* Delete scheduler, shutdown threads, finish everything, free structures */
void QUARK_Delete(Quark * quark);
/* Free scheduling data structures */
void QUARK_Free(Quark * quark);
/* Cancel a specific task */
int QUARK_Cancel_Task(Quark *quark, unsigned long long taskid);
/* Returns a pointer to the list of arguments, used when unpacking the
arguments; Returna a pointer to icl_list_t, so icl_list.h will need
bo included if you use this function */
void *QUARK_Args_List(Quark *quark);
/* Returns the rank of a thread in a parallel task */
int QUARK_Get_RankInTask(Quark *quark);
/* Return a pointer to an argument. The variable last_arg should be
NULL on the first call, then each subsequent call will used
last_arg to get the the next argument. */
void *QUARK_Args_Pop( void *args_list, void **last_arg);
/* Utility function returning rank of the current thread */
int QUARK_Thread_Rank(Quark *quark);
/* Packed task interface */
/* Create a task data structure to hold arguments */
Quark_Task *QUARK_Task_Init(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags );
/* Add (or pack) the arguments into a task data structure (make sure of the correct order) */
void QUARK_Task_Pack_Arg( Quark *quark, Quark_Task *task, int arg_size, void *arg_ptr, int arg_flags );
/* Insert the packed task data strucure into the scheduler for execution */
unsigned long long QUARK_Insert_Task_Packed(Quark * quark, Quark_Task *task );
/* Unsupported function for debugging purposes; execute task AT ONCE */
unsigned long long QUARK_Execute_Task_Packed( Quark *quark, Quark_Task *task );
/* Unsupported function for debugging purposes; execute task AT ONCE */
unsigned long long QUARK_Execute_Task( Quark *quark, void (*function) (Quark *), Quark_Task_Flags *task_flags, ...);
/* Get the label (if any) associated with the current task; used for printing and debugging */
char *QUARK_Get_Task_Label(Quark *quark);
/* Method for setting task flags */
Quark_Task_Flags *QUARK_Task_Flag_Set( Quark_Task_Flags *flags, int flag, intptr_t val );
/* Type for task sequences */
typedef struct Quark_sequence_s Quark_Sequence;
/* Create a seqeuence structure, to hold sequences of tasks */
Quark_Sequence *QUARK_Sequence_Create( Quark *quark );
/* Called by worker, cancel any pending tasks, and mark sequence so that it does not accept any more tasks */
int QUARK_Sequence_Cancel( Quark *quark, Quark_Sequence *sequence );
/* Destroy a sequence structure, cancelling any pending tasks */
Quark_Sequence *QUARK_Sequence_Destroy( Quark *quark, Quark_Sequence *sequence );
/* Wait for a sequence of tasks to complete */
int QUARK_Sequence_Wait( Quark *quark, Quark_Sequence *sequence );
/* Get the sequence information associated the current task/worker, this was provided when the tasks was created */
Quark_Sequence *QUARK_Get_Sequence(Quark *quark);
/* Get the priority associated the current task/worker */
int QUARK_Get_Priority(Quark *quark);
/* Get information associated the current task and worker thread;
* Callable from within a task, since it works on the currently
* executing task */
intptr_t QUARK_Task_Flag_Get( Quark *quark, int flag );
/* Enable and disable DAG generation via API. Only makes sense after
* a sync, such as QUARK_Barrier. */
void QUARK_DOT_DAG_Enable( Quark *quark, int boolean_value );
/**
* Use the task_flags data structure to set various items in the task
* (priority, lock_to_thread, color, labels, etc ).
*/
Quark_Task *quark_set_task_flags_in_task_structure( Quark *quark, Quark_Task *task, Quark_Task_Flags *task_flags );
/* **************************************************************************** */
/* Get the number_th bit in a bitset (unsigned char *); useful for QUARK_LOCK_TO_THREAD_MASK flag */
static inline int QUARK_Bit_Get(unsigned char *set, int number)
{
set += number / 8;
return (*set & (1 << (7-(number % 8)))) != 0; /* 0 or 1 */
}
/* Set the number_th bit in a bitset (unsigned char *) to value (0 or 1); useful for QUARK_LOCK_TO_THREAD_MASK flag */
static inline void QUARK_Bit_Set(unsigned char *set, int number, int value)
{
set += number / 8;
if (value)
*set = (unsigned char)(*set | (1 << (7-(number % 8)))); /* set bit */
else *set = (unsigned char)(*set & ( ~(1 << (7-(number % 8))))); /* clear bit */
}
/* The following are QUARK internal functions, and will be moved to a
* separate header file in the future. Please do not use these
* functions outside of the QUARK source code. */
void quark_warning(const char *func_name, char* msg_text);
void quark_topology_init();
void quark_topology_finalize();
int quark_setaffinity(int rank);
int quark_unsetaffinity();
int quark_yield();
int quark_get_numthreads();
int *quark_get_affthreads();
int quark_getenv_int(char* name, int defval);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif
#endif /* QUARK.H */