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