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 <twod/nicol_2d.hpp>
00038 #include <util/rect_list.hpp>
00039 #include <iostream>
00040 #include <math.h>
00041 #include <assert.h>
00042 #include <util/tools.hpp>
00043 #include <oned/nicol_plus.hpp>
00044 #include <oned/nicol_plus_interval.hpp>
00045
00046
00047 template <typename T, typename Pr, bool DEBUG>
00048 T twod::RectNicol<T,Pr,DEBUG>::part(int procCount, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00049 {
00050 using namespace util;
00051 assert(procCount > 0);
00052
00053
00054 int procX;
00055
00056 if (P==0)
00057 procX = intfactor(procCount);
00058 else
00059 procX = P;
00060
00061 int procY = procCount / procX;
00062
00063 return nicol_2d_internal(procX, procY, prefixSumArray, parts);
00064 }
00065
00066 template <typename T, typename Pr, bool DEBUG >
00067 T twod::RectNicol<T,Pr,DEBUG>::nicol_2d_internal(int procX, int procY, const Pr& prefixSumArray, util::RectList<T,Pr> &parts)
00068
00069 {
00070 using namespace util;
00071 int *x_cuts;
00072 int *y_cuts;
00073 T max_load = -1;
00074 T min_max_load = -2;
00075
00076
00077
00078 if (procX >= prefixSumArray.prefixsizeX())
00079 procX = prefixSumArray.prefixsizeX()-1;
00080 if (procY >= prefixSumArray.prefixsizeY())
00081 procY = prefixSumArray.prefixsizeY()-1;
00082
00083
00084
00085
00086 x_cuts = new int[procX - 1];
00087 y_cuts = new int[procY - 1];
00088
00089
00090
00091
00092
00093 Aggreg2Dto1D<T, Pr, true> ps1dx(prefixSumArray, 1, prefixSumArray.prefixsizeX() - 1, 1, prefixSumArray.prefixsizeY() -1);
00094
00095 min_max_load = oned::Nicol_plus_interval<T,Aggreg2Dto1D<T, Pr, true> >::nicol_plus(procX, ps1dx, prefixSumArray.prefixsizeX(), x_cuts, -1);
00096
00097 while(true)
00098 {
00099
00100 AggregMax2Dto1D<T,Pr,false> xMax (prefixSumArray, procX, x_cuts);
00101
00102
00103 max_load = fix_y_dimension(xMax, prefixSumArray.prefixsizeY(), procY, y_cuts);
00104 if (DEBUG)
00105 {
00106 std::cerr<<"previous bottleneck : "<<min_max_load<<std::endl;
00107 std::cerr<<"new bottleneck : "<<max_load<<std::endl;
00108 RectList<T,Pr> rl (prefixSumArray);
00109 convertToRectList(prefixSumArray.prefixsizeX(), prefixSumArray.prefixsizeY(), x_cuts, y_cuts, procX, procY, rl);
00110 std::cerr<<"computed bottleneck : "<<rl.get_maximum_load()<<std::endl;
00111 std::cerr<<rl<<std::endl;
00112
00113 assert (rl.valid_part());
00114 assert (max_load == rl.get_maximum_load());
00115 }
00116
00117 assert (max_load <= min_max_load);
00118
00119 if(max_load == min_max_load)
00120 break;
00121 min_max_load = max_load;
00122
00123
00124 AggregMax2Dto1D<T,Pr,true> yMax (prefixSumArray, procY, y_cuts);
00125
00126 max_load = fix_x_dimension(yMax, prefixSumArray.prefixsizeX(), procX, x_cuts);
00127
00128 if (DEBUG)
00129 {
00130 std::cerr<<"previous bottleneck : "<<min_max_load<<std::endl;
00131 std::cerr<<"new bottleneck : "<<max_load<<std::endl;
00132 RectList<T,Pr> rl (prefixSumArray);
00133 convertToRectList(prefixSumArray.prefixsizeX(), prefixSumArray.prefixsizeY(), x_cuts, y_cuts, procX, procY, rl);
00134 std::cerr<<"computed bottleneck : "<<rl.get_maximum_load()<<std::endl;
00135 }
00136
00137 assert (max_load <= min_max_load);
00138 if(max_load == min_max_load)
00139 break;
00140 min_max_load = max_load;
00141
00142
00143 }
00144
00145 convertToRectList(prefixSumArray.prefixsizeX(), prefixSumArray.prefixsizeY(), x_cuts, y_cuts, procX, procY, parts);
00146 delete[] x_cuts;
00147 delete[] y_cuts;
00148 return max_load;
00149
00150 }
00151
00152 template <typename T, typename Pr, bool DEBUG >
00153 T twod::RectNicol<T,Pr,DEBUG>::fix_x_dimension(util::AggregMax2Dto1D<T,Pr,true>& array, int length, int procX, int *x_cuts)
00154 {
00155 using namespace util;
00156 if (DEBUG) std::cerr<<"fixing x dimension using "<<procX<<" processors" <<std::endl;
00157
00158 if (DEBUG)
00159 {
00160 std::cerr<<"cuts before are : ";
00161 for (int i=0; i< procX; i++)
00162 std::cerr<<x_cuts[i]<<'\t';
00163 std::cerr<<std::endl;
00164 }
00165
00166 T ret = oned::Nicol_plus_interval<T,AggregMax2Dto1D<T,Pr,true> >::nicol_plus(procX, array, length, x_cuts, -1);
00167
00168 if (DEBUG)
00169 {
00170 std::cerr<<"cuts after are : ";
00171 for (int i=0; i< procX-1; i++)
00172 std::cerr<<x_cuts[i]<<'\t';
00173 std::cerr<<std::endl;
00174 }
00175
00176 return ret;
00177 }
00178
00179 template <typename T, typename Pr, bool DEBUG >
00180 T twod::RectNicol<T,Pr,DEBUG>::fix_y_dimension(util::AggregMax2Dto1D<T,Pr,false>& array, int length, int procY, int *y_cuts)
00181 {
00182 using namespace util;
00183 if (DEBUG) std::cerr<<"fixing y dimension using "<<procY<<" processors"<<std::endl;
00184
00185 if (DEBUG)
00186 {
00187 std::cerr<<"cuts before are : ";
00188 for (int i=0; i< procY; i++)
00189 std::cerr<<y_cuts[i]<<'\t';
00190 std::cerr<<std::endl;
00191 }
00192
00193 T ret = oned::Nicol_plus_interval<T,AggregMax2Dto1D<T,Pr,false> >::nicol_plus(procY, array, length, y_cuts, -1);
00194
00195 if (DEBUG)
00196 {
00197 std::cerr<<"cuts after are : ";
00198 for (int i=0; i< procY-1; i++)
00199 std::cerr<<y_cuts[i]<<'\t';
00200 std::cerr<<std::endl;
00201 }
00202
00203
00204 return ret;
00205 }
00206
00207 template <typename T, typename Pr, bool DEBUG >
00208 void twod::RectNicol<T,Pr,DEBUG>::convertToRectList(int lengthX, int lengthY, int *x_cuts, int *y_cuts, int procX, int procY, util::RectList<T,Pr> &parts)
00209 {
00210 using namespace util;
00211
00212 rectangle r;
00213 int i, j;
00214 int lastx = 1;
00215 int lasty = 1;
00216 for(i = 0; i < procX-1; i++){
00217 r.x_top_l = lastx;
00218 r.x_bot_r = x_cuts[i];
00219 for(j = 0; j < procY-1; j++){
00220 r.y_top_l = lasty;
00221 r.y_bot_r = y_cuts[j];
00222 parts.add_rect(r);
00223 lasty = y_cuts[j] + 1;
00224 }
00226 r.y_top_l = lasty;
00227 r.y_bot_r = lengthY - 1;
00228 parts.add_rect(r);
00229 lasty = 1;
00230 lastx = x_cuts[i] + 1;
00231 }
00233 r.x_top_l = lastx;
00234 r.x_bot_r = lengthX - 1;
00235 for(j = 0; j < procY-1; j++){
00236 r.y_top_l = lasty;
00237 r.y_bot_r = y_cuts[j];
00238 parts.add_rect(r);
00239 lasty = y_cuts[j] + 1;
00240 }
00241 r.y_top_l = lasty;
00242 r.y_bot_r = lengthY - 1;
00243 parts.add_rect(r);
00244 }
00245