ExaFMM 1
Fast-multipole Method for exascale systems
|
00001 /** 00002 * 00003 * @file quark.h 00004 * 00005 * Dynamic scheduler functions 00006 * 00007 * PLASMA is a software package provided by Univ. of Tennessee, 00008 * Univ. of California Berkeley and Univ. of Colorado Denver 00009 * 00010 * @version 2.4.5 00011 * @author Asim YarKhan 00012 * @date 2010-11-15 00013 * 00014 **/ 00015 00016 #ifndef QUARK_H 00017 #define QUARK_H 00018 00019 #include <limits.h> 00020 #include <stdio.h> 00021 00022 #if defined( _WIN32 ) 00023 /* This must be included before INPUT is defined below, otherwise we 00024 have a name clash/problem */ 00025 #include <windows.h> 00026 #include <limits.h> 00027 #else 00028 #include <inttypes.h> 00029 #endif 00030 00031 #include "quark_unpack_args.h" 00032 00033 #if defined(c_plusplus) || defined(__cplusplus) 00034 extern "C" { 00035 #endif 00036 00037 #ifdef DBGQUARK 00038 /* #define DBGPRINTF(str, ...) { fprintf(stderr, "%s:%d: [%s] " str, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); } */ 00039 #define DBGPRINTF(...) { fprintf(stderr, __VA_ARGS__); } 00040 #else 00041 #define DBGPRINTF(...) if (0) {}; 00042 #endif 00043 00044 #define QUARK_SUCCESS 0 00045 #define QUARK_ERR -1 00046 #define QUARK_ERR_UNEXPECTED -1 00047 #define QUARK_ERR_NOT_SUPPORTED -2 00048 00049 /* A bitmask of 8 bits to to hold region markers */ 00050 #define QUARK_REGION_BITMASK 0x0000FF 00051 #define QUARK_REGION_ALL 0x0FF 00052 typedef enum { QUARK_REGION_0=1<<0, QUARK_REGION_1=1<<1, QUARK_REGION_2=1<<2, QUARK_REGION_3=1<<3, 00053 QUARK_REGION_4=1<<4, QUARK_REGION_5=1<<5, QUARK_REGION_6=1<<6, QUARK_REGION_7=1<<7 } quark_data_region_t; 00054 typedef enum { QUARK_REGION_L=QUARK_REGION_0|QUARK_REGION_1|QUARK_REGION_2, 00055 QUARK_REGION_D=QUARK_REGION_3|QUARK_REGION_4, 00056 QUARK_REGION_U=QUARK_REGION_5|QUARK_REGION_6|QUARK_REGION_7 } quark_ldu_region_t; 00057 00058 /* Data items can be: */ 00059 /* INPUT, OUTPUT, INOUT: these data items create dependencies */ 00060 /* VALUE: these data items get copied over */ 00061 /* NODEP: these data items get copied over, and are not used for dependencies */ 00062 /* SCRATCH: these data items can be allocated (and deallocted) by the scheduler when tasks execute */ 00063 #define QUARK_DIRECTION_BITMASK 0x000F00 00064 typedef enum { QINPUT=0x100, OUTPUT=0x200, INOUT=0x300, VALUE=0x400, NODEP=0x500, SCRATCH=0x600} quark_direction_t; 00065 #define INPUT 0x100 00066 00067 #define QUARK_VALUE_FLAGS_BITMASK 0xFFF000 00068 00069 /* Data locality flag; ie keep data on the same core if possible */ 00070 #define LOCALITY ( 1 << 12 ) 00071 #define NOLOCALITY 0x00 00072 00073 /* A data address with a sequence of ACCUMULATOR dependencies will allow the related tasks to be reordered */ 00074 #define ACCUMULATOR ( 1 << 13 ) 00075 #define NOACCUMULATOR 0x00 00076 00077 /* A data address with a sequence of GATHERV dependencies will allow the related tasks to be run in parallel */ 00078 #define GATHERV ( 1 << 14 ) 00079 #define NOGATHERV 0x00 00080 00081 /* The following are task level flags, that can be either provided as additional arguments to the task, or via SET functions */ 00082 /* The task label; should be provided as a null terminated string */ 00083 #define TASK_LABEL ( 1 << 15 ) 00084 #define TASKLABEL TASK_LABEL /* depreciated label */ 00085 /* The task color; should be provided as a null terminated string */ 00086 #define TASK_COLOR ( 1 << 16 ) 00087 #define TASKCOLOR TASK_COLOR /* depreciated label */ 00088 /* The priority of the task, provided as an integer */ 00089 #define TASK_PRIORITY ( 1 << 17 ) 00090 /* Lock the task to a specific thread number (0 ... NTHREADS-1), provided as an integer */ 00091 #define TASK_LOCK_TO_THREAD ( 1 << 18 ) 00092 /* The sequence pointer to be associated with the task, provided as a pointer */ 00093 #define TASK_SEQUENCE ( 1 << 19 ) 00094 /* An integere for the number of threads require */ 00095 #define TASK_THREAD_COUNT ( 1 << 20 ) 00096 /* The thread that runs this task should have manual scheduling enabled (1) or disabled (0) */ 00097 #define THREAD_SET_TO_MANUAL_SCHEDULING ( 1 << 21 ) 00098 /* Lock the task to a thead mask (0 ... NTHREADS-1) bits long, provided as a character array (byte array) */ 00099 #define TASK_LOCK_TO_THREAD_MASK ( 1 << 22 ) 00100 00101 /* The range for priority values */ 00102 #define QUARK_TASK_MIN_PRIORITY 0 00103 #define QUARK_TASK_MAX_PRIORITY INT_MAX 00104 00105 /* Definition of structure holding scheduler information */ 00106 typedef struct quark_s Quark; 00107 00108 /* Structure holding task information */ 00109 typedef struct quark_task_s Quark_Task; 00110 00111 /* Create a type for setting task flags */ 00112 struct quark_task_flags_s { 00113 int task_priority; 00114 int task_lock_to_thread; 00115 char *task_color; 00116 char *task_label; 00117 void *task_sequence; 00118 int task_thread_count; 00119 int thread_set_to_manual_scheduling; 00120 unsigned char *task_lock_to_thread_mask; 00121 }; 00122 00123 typedef struct quark_task_flags_s Quark_Task_Flags; 00124 /* Static initializer for Quark_Task_Flags_t */ 00125 #define Quark_Task_Flags_Initializer { (int)0, (int)-1, (char *)NULL, (char *)NULL, (void *)NULL, (int)1, (int)-1, (unsigned char *)NULL } 00126 00127 /* Setup scheduler data structures, assumes threads are managed seperately */ 00128 Quark *QUARK_Setup(int num_threads); 00129 00130 /* Setup scheduler data structures, spawn worker threads, start the workers working */ 00131 Quark *QUARK_New(int num_threads); 00132 00133 /* Add a task, called by the master process (thread_rank 0) */ 00134 unsigned long long QUARK_Insert_Task(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags, ...); 00135 00136 /* Main work loop, called externally by everyone but the master 00137 * (master manages this internally to the insert_task and waitall 00138 * routines). Each worker thread can call work_main_loop( quark, 00139 * thread_rank), where thread rank is 1...NUMTHREADS ) */ 00140 void QUARK_Worker_Loop(Quark *quark, int thread_rank); 00141 00142 /* Finish work and return. Workers do not exit */ 00143 void QUARK_Barrier(Quark * quark); 00144 00145 /* Just wait for current tasks to complete, the scheduler and 00146 * strutures remain as is... should allow for repeated use of the 00147 * scheduler. The workers return from their loops.*/ 00148 void QUARK_Waitall(Quark * quark); 00149 00150 /* Delete scheduler, shutdown threads, finish everything, free structures */ 00151 void QUARK_Delete(Quark * quark); 00152 00153 /* Free scheduling data structures */ 00154 void QUARK_Free(Quark * quark); 00155 00156 /* Cancel a specific task */ 00157 int QUARK_Cancel_Task(Quark *quark, unsigned long long taskid); 00158 00159 /* Returns a pointer to the list of arguments, used when unpacking the 00160 arguments; Returna a pointer to icl_list_t, so icl_list.h will need 00161 bo included if you use this function */ 00162 void *QUARK_Args_List(Quark *quark); 00163 00164 /* Returns the rank of a thread in a parallel task */ 00165 int QUARK_Get_RankInTask(Quark *quark); 00166 00167 /* Return a pointer to an argument. The variable last_arg should be 00168 NULL on the first call, then each subsequent call will used 00169 last_arg to get the the next argument. */ 00170 void *QUARK_Args_Pop( void *args_list, void **last_arg); 00171 00172 /* Utility function returning rank of the current thread */ 00173 int QUARK_Thread_Rank(Quark *quark); 00174 00175 /* Packed task interface */ 00176 /* Create a task data structure to hold arguments */ 00177 Quark_Task *QUARK_Task_Init(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags ); 00178 00179 /* Add (or pack) the arguments into a task data structure (make sure of the correct order) */ 00180 void QUARK_Task_Pack_Arg( Quark *quark, Quark_Task *task, int arg_size, void *arg_ptr, int arg_flags ); 00181 00182 /* Insert the packed task data strucure into the scheduler for execution */ 00183 unsigned long long QUARK_Insert_Task_Packed(Quark * quark, Quark_Task *task ); 00184 00185 /* Unsupported function for debugging purposes; execute task AT ONCE */ 00186 unsigned long long QUARK_Execute_Task(Quark * quark, void (*function) (Quark *), Quark_Task_Flags *task_flags, ...); 00187 00188 /* Get the label (if any) associated with the current task; used for printing and debugging */ 00189 char *QUARK_Get_Task_Label(Quark *quark); 00190 00191 /* Method for setting task flags */ 00192 Quark_Task_Flags *QUARK_Task_Flag_Set( Quark_Task_Flags *flags, int flag, intptr_t val ); 00193 00194 /* Type for task sequences */ 00195 typedef struct Quark_sequence_s Quark_Sequence; 00196 00197 /* Create a seqeuence structure, to hold sequences of tasks */ 00198 Quark_Sequence *QUARK_Sequence_Create( Quark *quark ); 00199 00200 /* Called by worker, cancel any pending tasks, and mark sequence so that it does not accept any more tasks */ 00201 int QUARK_Sequence_Cancel( Quark *quark, Quark_Sequence *sequence ); 00202 00203 /* Destroy a sequence structure, cancelling any pending tasks */ 00204 Quark_Sequence *QUARK_Sequence_Destroy( Quark *quark, Quark_Sequence *sequence ); 00205 00206 /* Wait for a sequence of tasks to complete */ 00207 int QUARK_Sequence_Wait( Quark *quark, Quark_Sequence *sequence ); 00208 00209 /* Get the sequence information associated the current task/worker, this was provided when the tasks was created */ 00210 Quark_Sequence *QUARK_Get_Sequence(Quark *quark); 00211 00212 /* Get the priority associated the current task/worker */ 00213 int QUARK_Get_Priority(Quark *quark); 00214 00215 /* Get information associated the current task and worker thread; 00216 * Callable from within a task, since it works on the currently 00217 * executing task */ 00218 intptr_t QUARK_Task_Flag_Get( Quark *quark, int flag ); 00219 00220 /* Enable and disable DAG generation via API. Only makes sense after 00221 * a sync, such as QUARK_Barrier. */ 00222 void QUARK_DOT_DAG_Enable( Quark *quark, int boolean_value ); 00223 00224 /* Get the number_th bit in a bitset (unsigned char *); useful for QUARK_LOCK_TO_THREAD_MASK flag */ 00225 static inline int QUARK_Bit_Get(unsigned char *set, int number) 00226 { 00227 set += number / 8; 00228 return (*set & (1 << (7-(number % 8)))) != 0; /* 0 or 1 */ 00229 } 00230 00231 /* Set the number_th bit in a bitset (unsigned char *) to value (0 or 1); useful for QUARK_LOCK_TO_THREAD_MASK flag */ 00232 static inline void QUARK_Bit_Set(unsigned char *set, int number, int value) 00233 { 00234 set += number / 8; 00235 if (value) 00236 *set |= 1 << (7-(number % 8)); /* set bit */ 00237 else *set &= ~(1 << (7-(number % 8))); /* clear bit */ 00238 00239 } 00240 00241 #if defined(c_plusplus) || defined(__cplusplus) 00242 } 00243 #endif 00244 00245 #endif /* QUARK.H */