QUARK  0.9.0
QUARK-QUeuingAndRuntimeforKernels
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
quark.h
Go to the documentation of this file.
1 
16 #ifndef QUARK_H
17 #define QUARK_H
18 
19 #include <limits.h>
20 #include <stdio.h>
21 
22 #if defined( _WIN32 )
23  /* This must be included before INPUT is defined below, otherwise we
24  have a name clash/problem */
25  #include <windows.h>
26  #include <limits.h>
27 #else
28  #include <inttypes.h>
29 #endif
30 
31 #include "quark_unpack_args.h"
32 
33 #if defined(c_plusplus) || defined(__cplusplus)
34 extern "C" {
35 #endif
36 
37 #ifdef DBGQUARK
38 /* #define DBGPRINTF(str, ...) { fprintf(stderr, "%s:%d: [%s] " str, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); } */
39 #define DBGPRINTF(...) { fprintf(stderr, __VA_ARGS__); }
40 #else
41 #define DBGPRINTF(...) if (0) {};
42 #endif
43 
44 #define QUARK_SUCCESS 0
45 #define QUARK_ERR -1
46 #define QUARK_ERR_UNEXPECTED -1
47 #define QUARK_ERR_NOT_SUPPORTED -2
48 
49 /* A bitmask of 8 bits to to hold region markers */
50 #define QUARK_REGION_BITMASK 0x0000FF
51 #define QUARK_REGION_ALL 0x0FF
52 typedef enum { QUARK_REGION_0=1<<0, QUARK_REGION_1=1<<1, QUARK_REGION_2=1<<2, QUARK_REGION_3=1<<3,
57 
58 /* Data items can be: */
59 /* INPUT, OUTPUT, INOUT: these data items create dependencies */
60 /* VALUE: these data items get copied over */
61 /* NODEP: these data items get copied over, and are not used for dependencies */
62 /* SCRATCH: these data items can be allocated (and deallocted) by the scheduler when tasks execute */
63 #define QUARK_DIRECTION_BITMASK 0x000F00
64 typedef enum { QINPUT=0x100, OUTPUT=0x200, INOUT=0x300, VALUE=0x400, NODEP=0x500, SCRATCH=0x600} quark_direction_t;
65 #define INPUT 0x100
66 
67 #define QUARK_VALUE_FLAGS_BITMASK 0xFFF000
68 
69 /* Data locality flag; ie keep data on the same core if possible */
70 #define LOCALITY ( 1 << 12 )
71 #define NOLOCALITY 0x00
72 
73 /* A data address with a sequence of ACCUMULATOR dependencies will allow the related tasks to be reordered */
74 #define ACCUMULATOR ( 1 << 13 )
75 #define NOACCUMULATOR 0x00
76 
77 /* A data address with a sequence of GATHERV dependencies will allow the related tasks to be run in parallel */
78 #define GATHERV ( 1 << 14 )
79 #define NOGATHERV 0x00
80 
81 /* The following are task level flags, that can be either provided as additional arguments to the task, or via SET functions */
82 /* The task label; should be provided as a null terminated string */
83 #define TASK_LABEL ( 1 << 15 )
84 #define TASKLABEL TASK_LABEL /* depreciated label */
85 /* The task color; should be provided as a null terminated string */
86 #define TASK_COLOR ( 1 << 16 )
87 #define TASKCOLOR TASK_COLOR /* depreciated label */
88 /* The priority of the task, provided as an integer */
89 #define TASK_PRIORITY ( 1 << 17 )
90 /* Lock the task to a specific thread number (0 ... NTHREADS-1), provided as an integer */
91 #define TASK_LOCK_TO_THREAD ( 1 << 18 )
92 /* The sequence pointer to be associated with the task, provided as a pointer */
93 #define TASK_SEQUENCE ( 1 << 19 )
94 /* An integere for the number of threads require */
95 #define TASK_THREAD_COUNT ( 1 << 20 )
96 /* The thread that runs this task should have manual scheduling enabled (1) or disabled (0) */
97 #define THREAD_SET_TO_MANUAL_SCHEDULING ( 1 << 21 )
98 /* Lock the task to a thead mask (0 ... NTHREADS-1) bits long, provided as a character array (byte array) */
99 #define TASK_LOCK_TO_THREAD_MASK ( 1 << 22 )
100 
101 /* The range for priority values */
102 #define QUARK_TASK_MIN_PRIORITY 0
103 #define QUARK_TASK_MAX_PRIORITY INT_MAX
104 
105 /* Definition of structure holding scheduler information */
106 typedef struct quark_s Quark;
107 
108 /* Structure holding task information */
109 typedef struct quark_task_s Quark_Task;
110 
111 /* Create a type for setting task flags */
115  char *task_color;
116  char *task_label;
120  unsigned char *task_lock_to_thread_mask;
121 };
122 
124 /* Static initializer for Quark_Task_Flags_t */
125 #define Quark_Task_Flags_Initializer { (int)0, (int)-1, (char *)NULL, (char *)NULL, (void *)NULL, (int)1, (int)-1, (unsigned char *)NULL }
126 
127 /* Setup scheduler data structures, assumes threads are managed seperately */
128 Quark *QUARK_Setup(int num_threads);
129 
130 /* Setup scheduler data structures, spawn worker threads, start the workers working */
131 Quark *QUARK_New(int num_threads);
132 
133 /* Add a task, called by the master process (thread_rank 0) */
134 unsigned long long QUARK_Insert_Task(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags, ...);
135 
136 /* Main work loop, called externally by everyone but the master
137  * (master manages this internally to the insert_task and waitall
138  * routines). Each worker thread can call work_main_loop( quark,
139  * thread_rank), where thread rank is 1...NUMTHREADS ) */
140 void QUARK_Worker_Loop(Quark *quark, int thread_rank);
141 
142 /* Finish work and return. Workers do not exit */
143 void QUARK_Barrier(Quark * quark);
144 
145 /* Just wait for current tasks to complete, the scheduler and
146  * strutures remain as is... should allow for repeated use of the
147  * scheduler. The workers return from their loops.*/
148 void QUARK_Waitall(Quark * quark);
149 
150 /* Delete scheduler, shutdown threads, finish everything, free structures */
151 void QUARK_Delete(Quark * quark);
152 
153 /* Free scheduling data structures */
154 void QUARK_Free(Quark * quark);
155 
156 /* Cancel a specific task */
157 int QUARK_Cancel_Task(Quark *quark, unsigned long long taskid);
158 
159 /* Returns a pointer to the list of arguments, used when unpacking the
160  arguments; Returna a pointer to icl_list_t, so icl_list.h will need
161  bo included if you use this function */
162 void *QUARK_Args_List(Quark *quark);
163 
164 /* Returns the rank of a thread in a parallel task */
165 int QUARK_Get_RankInTask(Quark *quark);
166 
167 /* Return a pointer to an argument. The variable last_arg should be
168  NULL on the first call, then each subsequent call will used
169  last_arg to get the the next argument. */
170 void *QUARK_Args_Pop( void *args_list, void **last_arg);
171 
172 /* Utility function returning rank of the current thread */
173 int QUARK_Thread_Rank(Quark *quark);
174 
175 /* Packed task interface */
176 /* Create a task data structure to hold arguments */
177 Quark_Task *QUARK_Task_Init(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags );
178 
179 /* Add (or pack) the arguments into a task data structure (make sure of the correct order) */
180 void QUARK_Task_Pack_Arg( Quark *quark, Quark_Task *task, int arg_size, void *arg_ptr, int arg_flags );
181 
182 /* Insert the packed task data strucure into the scheduler for execution */
183 unsigned long long QUARK_Insert_Task_Packed(Quark * quark, Quark_Task *task );
184 
185 /* Unsupported function for debugging purposes; execute task AT ONCE */
186 unsigned long long QUARK_Execute_Task(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags, ...);
187 
188 /* Get the label (if any) associated with the current task; used for printing and debugging */
189 char *QUARK_Get_Task_Label(Quark *quark);
190 
191 /* Method for setting task flags */
192 Quark_Task_Flags *QUARK_Task_Flag_Set( Quark_Task_Flags *flags, int flag, intptr_t val );
193 
194 /* Type for task sequences */
196 
197 /* Create a seqeuence structure, to hold sequences of tasks */
199 
200 /* Called by worker, cancel any pending tasks, and mark sequence so that it does not accept any more tasks */
201 int QUARK_Sequence_Cancel( Quark *quark, Quark_Sequence *sequence );
202 
203 /* Destroy a sequence structure, cancelling any pending tasks */
205 
206 /* Wait for a sequence of tasks to complete */
207 int QUARK_Sequence_Wait( Quark *quark, Quark_Sequence *sequence );
208 
209 /* Get the sequence information associated the current task/worker, this was provided when the tasks was created */
211 
212 /* Get the priority associated the current task/worker */
213 int QUARK_Get_Priority(Quark *quark);
214 
215 /* Get information associated the current task and worker thread;
216  * Callable from within a task, since it works on the currently
217  * executing task */
218 intptr_t QUARK_Task_Flag_Get( Quark *quark, int flag );
219 
220 /* Enable and disable DAG generation via API. Only makes sense after
221  * a sync, such as QUARK_Barrier. */
222 void QUARK_DOT_DAG_Enable( Quark *quark, int boolean_value );
223 
224 /* Get the number_th bit in a bitset (unsigned char *); useful for QUARK_LOCK_TO_THREAD_MASK flag */
225 static inline int QUARK_Bit_Get(unsigned char *set, int number)
226 {
227  set += number / 8;
228  return (*set & (1 << (7-(number % 8)))) != 0; /* 0 or 1 */
229 }
230 
231 /* Set the number_th bit in a bitset (unsigned char *) to value (0 or 1); useful for QUARK_LOCK_TO_THREAD_MASK flag */
232 static inline void QUARK_Bit_Set(unsigned char *set, int number, int value)
233 {
234  set += number / 8;
235  if (value)
236  *set |= 1 << (7-(number % 8)); /* set bit */
237  else *set &= ~(1 << (7-(number % 8))); /* clear bit */
238 
239 }
240 
241 #if defined(c_plusplus) || defined(__cplusplus)
242 }
243 #endif
244 
245 #endif /* QUARK.H */