00001 #ifndef QTHREAD_QLOOP
00002 #define QTHREAD_QLOOP
00003
00004 #include <qthread/qthread.h>
00005 #include <qthread/futurelib.h>
00006
00007 Q_STARTCXX
00008
00009 typedef void (*qt_loop_f) (qthread_t * me, const size_t startat,
00010 const size_t stopat, void *arg);
00011 typedef void (*qt_loopr_f) (qthread_t * me, const size_t startat,
00012 const size_t stopat, void *restrict arg,
00013 void *restrict ret);
00014 typedef void (*qt_accum_f) (void *restrict a, void *restrict b);
00015
00016 typedef struct qqloop_handle_s qqloop_handle_t;
00017
00018 void qt_loop(const size_t start, const size_t stop,
00019 const qt_loop_f func, void *argptr);
00020 void qt_loop_future(const size_t start, const size_t stop,
00021 const qt_loop_f func, void *argptr);
00022 void qt_loop_balance(const size_t start, const size_t stop,
00023 const qt_loop_f func, void *argptr);
00024 void qt_loop_balance_future(const size_t start, const size_t stop,
00025 const qt_loop_f func, void *argptr);
00026 void qt_loopaccum_balance(const size_t start, const size_t stop,
00027 const size_t size, void *restrict out,
00028 const qt_loopr_f func, void *restrict argptr,
00029 const qt_accum_f acc);
00030 void qt_loopaccum_balance_future(const size_t start, const size_t stop,
00031 const size_t size, void *restrict out,
00032 const qt_loopr_f func, void *restrict argptr,
00033 const qt_accum_f acc);
00034
00035 typedef enum { CHUNK, GUIDED, FACTORED, TIMED } qt_loop_queue_type;
00036 qqloop_handle_t *qt_loop_queue_create(const qt_loop_queue_type type,
00037 const size_t start, const size_t stop, const size_t incr,
00038 const qt_loop_f func, void *const argptr);
00039 void qt_loop_queue_run(qqloop_handle_t * loop);
00040 void qt_loop_queue_run_there(qqloop_handle_t * loop,
00041 qthread_shepherd_id_t shep);
00042 void qt_loop_queue_addworker(qqloop_handle_t * loop,
00043 const qthread_shepherd_id_t shep);
00044
00045 #ifdef QTHREAD_USE_ROSE_EXTENSIONS
00046 typedef void (*qt_loop_step_f) (qthread_t * me, const size_t startat,
00047 const size_t stopat, const size_t step, void *arg);
00048 typedef struct qtrose_loop_handle_s qtrose_loop_handle_t;
00049
00050 void qt_loop_queue_run_single(volatile qtrose_loop_handle_t * loop, void *t);
00051 void qt_parallel(const qt_loop_step_f func, const unsigned int threads,
00052 void *argptr);
00053 void qt_parallel_for(const qt_loop_step_f func, const size_t startat,
00054 const size_t stopat, const size_t step,
00055 void *restrict argptr);
00056 #endif
00057
00058 double qt_double_sum(double *array, size_t length, int checkfeb);
00059 double qt_double_prod(double *array, size_t length, int checkfeb);
00060 double qt_double_max(double *array, size_t length, int checkfeb);
00061 double qt_double_min(double *array, size_t length, int checkfeb);
00062
00063 saligned_t qt_int_sum(saligned_t * array, size_t length, int checkfeb);
00064 saligned_t qt_int_prod(saligned_t * array, size_t length, int checkfeb);
00065 saligned_t qt_int_max(saligned_t * array, size_t length, int checkfeb);
00066 saligned_t qt_int_min(saligned_t * array, size_t length, int checkfeb);
00067
00068 aligned_t qt_uint_sum(aligned_t * array, size_t length, int checkfeb);
00069 aligned_t qt_uint_prod(aligned_t * array, size_t length, int checkfeb);
00070 aligned_t qt_uint_max(aligned_t * array, size_t length, int checkfeb);
00071 aligned_t qt_uint_min(aligned_t * array, size_t length, int checkfeb);
00072
00073
00074 static Q_UNUSED void qt_dbl_add_acc(void *restrict a, void *restrict b)
00075 {
00076 *(double *)a += *(double *)b;
00077 }
00078
00079 static Q_UNUSED void qt_int_add_acc(void *restrict a, void *restrict b)
00080 {
00081 *(saligned_t *) a += *(saligned_t *) b;
00082 }
00083
00084 static Q_UNUSED void qt_uint_add_acc(void *restrict a, void *restrict b)
00085 {
00086 *(aligned_t *) a += *(aligned_t *) b;
00087 }
00088
00089 static Q_UNUSED void qt_dbl_prod_acc(void *restrict a, void *restrict b)
00090 {
00091 *(double *)a *= *(double *)b;
00092 }
00093
00094 static Q_UNUSED void qt_int_prod_acc(void *restrict a, void *restrict b)
00095 {
00096 *(saligned_t *) a *= *(saligned_t *) b;
00097 }
00098
00099 static Q_UNUSED void qt_uint_prod_acc(void *restrict a, void *restrict b)
00100 {
00101 *(aligned_t *) a *= *(aligned_t *) b;
00102 }
00103
00104 static Q_UNUSED void qt_dbl_max_acc(void *restrict a, void *restrict b)
00105 {
00106 if (*(double *)b > *(double *)a)
00107 *(double *)a = *(double *)b;
00108 }
00109
00110 static Q_UNUSED void qt_int_max_acc(void *restrict a, void *restrict b)
00111 {
00112 if (*(saligned_t *) b > *(saligned_t *) a)
00113 *(saligned_t *) a = *(saligned_t *) b;
00114 }
00115
00116 static Q_UNUSED void qt_uint_max_acc(void *restrict a, void *restrict b)
00117 {
00118 if (*(aligned_t *) b > *(aligned_t *) a)
00119 *(aligned_t *) a = *(aligned_t *) b;
00120 }
00121
00122 static Q_UNUSED void qt_dbl_min_acc(void *restrict a, void *restrict b)
00123 {
00124 if (*(double *)b < *(double *)a)
00125 *(double *)a = *(double *)b;
00126 }
00127
00128 static Q_UNUSED void qt_int_min_acc(void *restrict a, void *restrict b)
00129 {
00130 if (*(saligned_t *) b < *(saligned_t *) a)
00131 *(saligned_t *) a = *(saligned_t *) b;
00132 }
00133
00134 static Q_UNUSED void qt_uint_min_acc(void *restrict a, void *restrict b)
00135 {
00136 if (*(aligned_t *) b < *(aligned_t *) a)
00137 *(aligned_t *) a = *(aligned_t *) b;
00138 }
00139
00140 void qt_qsort(qthread_t * me, double *array, const size_t length);
00141
00142 Q_ENDCXX
00143 #endif