00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <assert.h>
00038 #include <twod/rec_bisect_2d.hpp>
00039 #include <oned/rec_bisect.hpp>
00040 #include <util/tools.hpp>
00041
00042 template<typename T, typename Pr, int type>
00043 T twod::RecBisect2D<T,Pr,type>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00044 {
00045 using namespace util;
00046 rectangle r;
00047 bool orient;
00048 if(type == HOR_ALT)
00049 orient = true;
00050 else
00051 orient = false;
00052 r.x_top_l = 1;
00053 r.y_top_l = 1;
00054 r.x_bot_r = prefixSumArray.prefixsizeX() - 1;
00055 r.y_bot_r = prefixSumArray.prefixsizeY() - 1;
00056 return rec_bisect_2d_internal(procCount, prefixSumArray, parts, r, orient);
00057 }
00058
00059 template<typename T, typename Pr, int type>
00060 T twod::RecBisect2D<T,Pr,type>::rec_bisect_2d_internal(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts, util::rectangle r, bool orient)
00061 {
00062 using namespace oned;
00063 using namespace util;
00064
00065 if(procCount > 1)
00066 {
00067 bool can_vertical_cut;
00068 bool can_horizontal_cut;
00069
00070 if (type == LOAD)
00071 {
00072 can_vertical_cut = true;
00073 can_horizontal_cut = true;
00074 }
00075 if((type == HOR_ALT) || (type == VERT_ALT))
00076 {
00077 if (orient)
00078 {
00079 can_vertical_cut = false;
00080 can_horizontal_cut = true;
00081 }
00082
00083 else
00084 {
00085 can_vertical_cut = true;
00086 can_horizontal_cut = false;
00087 }
00088 }
00089 if (type == DIST)
00090 {
00091 if ((r.x_bot_r - r.x_top_l)
00092 <= (r.y_bot_r - r.y_top_l))
00093 {
00094 can_vertical_cut = true;
00095 can_horizontal_cut = false;
00096 }
00097 else
00098 {
00099 can_vertical_cut = false;
00100 can_horizontal_cut = true;
00101 }
00102 }
00103
00104
00105 double ver_max=-1, hor_max=-1;
00106 int cutIndex_ver=-1, cutIndex_ver1=-1,cutIndex_ver2=-1, cutIndex_hor=-1,cutIndex_hor1=-1,cutIndex_hor2=-1;
00107 rectangle subr1_ver = r, subr2_ver = r;
00108 rectangle subr1_hor = r, subr2_hor = r;
00109 int leftProc = (procCount >> 1);
00110 int rightProc = procCount - leftProc;
00111
00112 bool vswap=true;
00113
00114 bool hswap=true;
00115
00116
00117 if (can_vertical_cut)
00118 {
00119 Aggreg2Dto1D<T, Pr, false> ps1d_ver(prefixSumArray, (int)r.x_top_l, (int)r.x_bot_r, (int)r.y_top_l, (int)r.y_bot_r);
00120
00121 cutIndex_ver1 = r.y_top_l-1 + RecursiveBisection<T, Aggreg2Dto1D<T, Pr, false> >::findEvenCut(ps1d_ver, 1, r.y_bot_r-r.y_top_l+1, leftProc, rightProc);
00122
00123 double candDiff1 = RecursiveBisection<T, Aggreg2Dto1D<T, Pr, false> >::calculateDiff(ps1d_ver, 1, r.y_bot_r-r.y_top_l+1, leftProc, rightProc, cutIndex_ver1 - (r.y_top_l-1));
00124
00125
00126
00127
00128 double candDiff2;
00129
00130 if (leftProc != rightProc)
00131 {
00132 cutIndex_ver2 = r.y_top_l-1 + RecursiveBisection<T, Aggreg2Dto1D<T, Pr, false> >::findEvenCut(ps1d_ver, 1, r.y_bot_r - r.y_top_l+1, rightProc, leftProc);
00133 candDiff2 = RecursiveBisection<T, Aggreg2Dto1D<T, Pr, false> >::calculateDiff(ps1d_ver, 1, r.y_bot_r - r.y_top_l+1, rightProc, leftProc, cutIndex_ver2 - (r.y_top_l-1));
00134
00135 }
00136 else
00137 {
00138 cutIndex_ver2 = cutIndex_ver1;
00139 candDiff2 = candDiff1;
00140 }
00141
00142
00143 if(candDiff1 <= candDiff2)
00144 {
00145 cutIndex_ver = cutIndex_ver1;
00146 vswap = false;
00147 ver_max = candDiff1;
00148 }
00149 else
00150 { cutIndex_ver = cutIndex_ver2;
00151 vswap = true;
00152 ver_max = candDiff2;
00153 }
00154 assert (cutIndex_ver >= 0);
00155
00156 assert (cutIndex_ver >= r.y_top_l);
00157 assert (cutIndex_ver <= r.y_bot_r);
00158
00159 subr1_ver.y_bot_r = cutIndex_ver;
00160 subr2_ver.y_top_l = cutIndex_ver + 1;
00161 }
00162
00163
00164 if (can_horizontal_cut)
00165 {
00166 Aggreg2Dto1D<T, Pr, true> ps1d_hor(prefixSumArray, r.x_top_l, r.x_bot_r, r.y_top_l, r.y_bot_r);
00167
00168 cutIndex_hor1 = (r.x_top_l-1) + RecursiveBisection<T, Aggreg2Dto1D<T, Pr, true> >::findEvenCut(ps1d_hor, 1, r.x_bot_r - r.x_top_l+1, leftProc, rightProc);
00169
00170 double candDiff1 = RecursiveBisection<T, Aggreg2Dto1D<T, Pr, true> >::calculateDiff(ps1d_hor, 1, r.x_bot_r - r.x_top_l+1, leftProc, rightProc, cutIndex_hor1 - (r.x_top_l-1));
00171
00172
00173
00174
00175 double candDiff2;
00176
00177
00178 if (leftProc != rightProc)
00179 {
00180 cutIndex_hor2 = (r.x_top_l-1) + RecursiveBisection<T, Aggreg2Dto1D<T, Pr, true> >::findEvenCut(ps1d_hor, 1, r.x_bot_r - r.x_top_l+1, rightProc, leftProc);
00181 candDiff2 = RecursiveBisection<T, Aggreg2Dto1D<T, Pr, true> >::calculateDiff(ps1d_hor, 1, r.x_bot_r - r.x_top_l+1, rightProc, leftProc, cutIndex_hor2 - (r.x_top_l-1));
00182
00183 }
00184 else
00185 {
00186 cutIndex_hor2 = cutIndex_hor1;
00187 candDiff2 = candDiff1;
00188 }
00189
00190 if(candDiff1 <= candDiff2)
00191 {
00192 cutIndex_hor = cutIndex_hor1;
00193 hswap = false;
00194 hor_max = candDiff1;
00195 }
00196 else
00197 {
00198 cutIndex_hor = cutIndex_hor2;
00199 hswap = true;
00200 hor_max = candDiff2;
00201 }
00202
00203 assert(cutIndex_hor >= 0);
00204
00205 assert (cutIndex_hor >= r.x_top_l);
00206 assert (cutIndex_hor <= r.x_bot_r);
00207
00208
00209 subr1_hor.x_bot_r = cutIndex_hor;
00210 subr2_hor.x_top_l = cutIndex_hor + 1;
00211 }
00212
00213
00214 T load1, load2;
00215 if( can_vertical_cut && ((!can_horizontal_cut ) || ver_max<hor_max))
00216 {
00217
00218
00219 load1 = RecBisect2D::rec_bisect_2d_internal((vswap?rightProc:leftProc), prefixSumArray, parts, subr1_ver, !orient);
00220 if(cutIndex_ver + 1 < prefixSumArray.prefixsizeY())
00221 load2 = RecBisect2D::rec_bisect_2d_internal((vswap?leftProc:rightProc), prefixSumArray, parts, subr2_ver, !orient);
00222 else
00223 load2 = load1;
00224 }
00225 else
00226 {
00227
00228
00229 load1 = RecBisect2D::rec_bisect_2d_internal((hswap?rightProc:leftProc), prefixSumArray, parts, subr1_hor, !orient);
00230 if(cutIndex_hor + 1 < prefixSumArray.prefixsizeX())
00231 load2 = RecBisect2D::rec_bisect_2d_internal((hswap?leftProc:rightProc), prefixSumArray, parts, subr2_hor, !orient);
00232 else
00233 load2 = load1;
00234
00235 }
00236 if(load1 > load2)
00237 return load1;
00238 else
00239 return load2;
00240 }
00241 else
00242 {
00243 parts.add_rect(r);
00244 return r.get_load<T,Pr>(prefixSumArray);
00245 }
00246
00247 }