00001 #ifdef CH_LANG_CC 00002 /* 00003 * _______ __ 00004 * / ___/ / ___ __ _ / / ___ 00005 * / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00006 * \___/_//_/\___/_/_/_/_.__/\___/ 00007 * Please refer to Copyright.txt, in Chombo's root directory. 00008 */ 00009 #endif 00010 00011 // Purpose: 00012 // LoadBalance() is a global function to compute an assignment 00013 // of boxes to processors for an AMR mesh hierarchy. The assignment 00014 // is made so as to balance the computation and communication 00015 // workload on each processor (i.e. make it as even as possible). 00016 // 00017 // ******************************************************** 00018 // CAVEAT: this version ignores the communication workload. 00019 // It balances ONLY the compute workload. 00020 // ******************************************************** 00021 // 00022 // Usage: 00023 // The meshes in the AMR hierarchy are represented using 00024 // a Vector of Vectors of Boxes. 00025 // 00026 // The computational workload is a real number for each box in the 00027 // hierarchy, also represented as a Vector of Vectors. 00028 // 00029 // The communication workload is a real number for each connection 00030 // between pairs of boxes, which specifies the cost of communication 00031 // between the two boxes if they are on different processors. No 00032 // allowance is made for varying the communication cost depending on the 00033 // distance between processors (ie. all processors are equally far apart) 00034 // and it assumes that the effective cost of communicating between two 00035 // boxes on the same processor is zero. The communication workload is 00036 // represented as a graph. 00037 // 00038 // ******************************************************** 00039 // CAVEAT: the communication workload argument is not 00040 // present in this version of the function. 00041 // ******************************************************** 00042 // 00043 // The resulting assignment is an integer for each box in the hierarchy, 00044 // which gives the processor number (starting at zero) on which each box 00045 // should reside. Again, represented as a Vector of Vectors. 00046 // 00047 // The other output argument is the efficiency ratio, which is a measure 00048 // of how close to perfect the final load balance is. The \var{effRatio} 00049 // output variable is defined as the smallest load on any processor divided 00050 // by the largest load. A perfect load balance has efficiency == 1. 00051 // 00052 // ******************************************************** 00053 // CAVEAT: in this version, each level in the AMR hierarchy 00054 // is balanced independently, so the efficiency ratio 00055 // that is returned is the worst over all levels. 00056 // ******************************************************** 00057 // 00058 // It is important to note that it is the sum of the computation cost 00059 // and communication cost that is balanced, so the values in the two 00060 // variables must be in the same units. It doesn't matter what the 00061 // units are. 00062 // 00063 // ******************************************************** 00064 // CAVEAT: the communication workload argument is not 00065 // present in this version of the function. 00066 // ******************************************************** 00067 // 00068 // Interface Specification: 00069 // int LoadBalance() arguments are: 00070 // Vector<Vector<int>>& procAssignments //output: processor number 00071 // // for each box 00072 // Real& effRatio //output: efficiency ratio 00073 // const Vector<Vector<Box>>& Grids //input: meshes to balance 00074 // const Vector<Vector<long>>&ComputeLoads //input: computational cost 00075 // // of each box 00076 //###not used### 00077 //### const [...something...]&CommunicateLoads //input: communication cost 00078 // // between each pair of 00079 // // neighboring boxes 00080 // const Vector<int>& RefRatios //input: refinement ratio 00081 // // for each level 00082 // 00083 // Returns: integer status_code 00084 // =0 means succesful completion 00085 // exceptions: (output variables are not defined) 00086 // -1011 input vectors (\var{Grids} and \var{ComputeLoads}) are not 00087 // the same size 00088 // -1012 one of the vector elements of the input vectors (\var{Grids} 00089 // and \var{ComputeLoads}) are not the same size 00090 // -1013 input vectors (\var{Grids} and \var{RefRatios}) are not 00091 // the same size 00092 // 00093 // Modification History 00094 // 19Nov99 <dbs> initial design and coding 00095 // 00096 00097 #ifndef _LOADBALANCE_H_ 00098 #define _LOADBALANCE_H_ 00099 00100 #include "SPACE.H" 00101 #include "REAL.H" 00102 #include "Box.H" 00103 #include "Vector.H" 00104 #include "BoxLayout.H" 00105 #include "SPMD.H" 00106 #include "NamespaceHeader.H" 00107 00108 /// 00109 /** 00110 procAssignments output: processor number for each box 00111 effRatio output: ratio of min load to max load 00112 Grids input: meshes to balance 00113 ComputeLoads input: computational cost of each box 00114 RefRatios input: refinement ratio for each level 00115 */ 00116 int 00117 LoadBalance( Vector<Vector<int> >& a_procAssignments 00118 ,Real& a_effRatio 00119 ,const Vector<Vector<Box> >& a_Grids 00120 ,const Vector<Vector<long> >& a_ComputeLoads 00121 ,const Vector<int>& a_RefRatios 00122 ,int a_nProc = numProc() 00123 ) ; 00124 00125 /// 00126 /** 00127 00128 Grids in-out: input grids to balance and output proc. numbers 00129 effRatio output: ratio of min load to max load 00130 ComputeLoads input: computational cost of each box 00131 RefRatios input: refinement ratio for each level 00132 */ 00133 int 00134 LoadBalance( Vector<BoxLayout>& Grids 00135 ,Real& effRatio 00136 ,const Vector<Vector<long> >& ComputeLoads 00137 ,const Vector<int>& RefRatios 00138 ,int nProc = numProc() 00139 ) ; 00140 00141 /// 00142 /** convenience function to load balance a Vector of Boxes based 00143 on load=box.numPts() */ 00144 int LoadBalance(Vector<int>& a_procAssignments, const Vector<Box>& a_boxes, 00145 const int a_LBnumProc = numProc()); 00146 00147 /// 00148 /** convenience function to load balance a Vector of Loads based 00149 on load. boxes also passed in for possible use with box-swapping code */ 00150 int LoadBalance(Vector<int>& a_procAssignments, 00151 const Vector<long long>& a_computeLoads, 00152 const Vector<Box>& a_boxes, 00153 const int a_LBnumProc = numProc()); 00154 00155 /// 00156 /** Accepts "long int" computeLoads and then just calls the "long long" version. */ 00157 int LoadBalance(Vector<int>& a_procAssignments, 00158 const Vector<long int>& a_computeLoads, 00159 const Vector<Box>& a_boxes, 00160 const int a_LBnumProc = numProc()); 00161 00162 // 00163 /* 00164 This is experimental and to keep me from doing long long <-> long conversions. (dtg) 00165 I think we can remove this as it simply calls the above LoadBalance() (ndk 8.4.2008) 00166 */ 00167 int UnLongLongLoadBalance(Vector<int>& a_procAssignments, 00168 const Vector<unsigned long long>& a_computeLoads, 00169 const Vector<Box>& a_boxes, 00170 const int a_numProc = numProc()); 00171 00172 /// 00173 /* Even simpler load balance scheme that just dices vector to give as close to the same number 00174 of boxes to each rank. 00175 */ 00176 int basicLoadBalance(Vector<int>& a_procAssignments, int numBoxes, int a_numProc = numProc()); 00177 00178 /// 00179 int 00180 LoadBalance(Vector<int>& procAssignments 00181 ,Real& effRatio 00182 ,const Vector<Box>& Grids 00183 ,const Vector<long>& ComputeLoads); 00184 00185 /// convenience function to gather a distributed set of Boxes with their corresponding processor assignment 00186 /** Assumption is that each processor has at most one valid box. This is useful when interacting with other distributed codes which might not have the entire set of distributed boxes on all processors. 00187 */ 00188 int LoadBalance(Vector<int>& a_procAssignments, 00189 Vector<Box>& a_boxes, 00190 const Box& a_localGridBox, 00191 const int a_numProc = numProc()); 00192 00193 #include "NamespaceFooter.H" 00194 #endif