ExaFMM 1
Fast-multipole Method for exascale systems
include/quark.h
Go to the documentation of this file.
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 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines