00001
00002
00003
00004
00005
00006
00007
00008 #include "cklibs/idastar.h"
00009 #include "cklibs/search.h"
00010
00011 #define min(a,b) (a<b?a:b)
00012 #define max(a,b) (a>b?a:b)
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 void aStar(
00023 problem *issue,
00024 int maxdepth, int charesize, int serialdist,
00025 CkCallback finished
00026 ) {
00027 idaStar(issue, maxdepth, maxdepth, 1, 1,
00028 charesize, serialdist, finished);
00029 }
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 void idaStar(
00040 problem *issue,
00041 int startdepth, int maxdepth, int stride, int window,
00042 int charesize, int serialdist,
00043 CkCallback finished
00044 ) {
00045 CProxy_idaStarGroup::ckNew(issue, startdepth, maxdepth, stride, window,
00046 charesize, serialdist, finished);
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 idaStarWorker::idaStarWorker(
00059 CkGroupID master,
00060 problem *issue, int maxdepth,
00061 int charesize, int serialdist
00062 ) : Master(master), Issue(issue), Waiting(0), Solver(NULL), Solution(NULL) {
00063
00064 if ( maxdepth < issue->depth() + issue->depthToSolution() ) {
00065 ChildFinished(0);
00066 return;
00067 }
00068
00069
00070 CProxy_idaStarGroup gp(master);
00071 idaStarGroup *local = gp.ckLocalBranch();
00072 if ( !local ) {
00073 ckerr << "A request for a local group branch failed in idaStarWorker::idaStarWorker. Aborting computation." << endl;
00074 CkExit();
00075 }
00076
00077
00078
00079 if ( local->BestSolutionDepth < maxdepth ) {
00080 ChildFinished(0);
00081 return;
00082 }
00083
00084
00085 if ( local->BestSolutionDepth < issue->depth() + issue->depthToSolution() ) {
00086 ChildFinished(0);
00087 return;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 int depthsearched = charesize;
00099 if ( issue->depthToSolution() < serialdist ) {
00100 depthsearched = serialdist;
00101 }
00102 depthsearched = min( depthsearched, local->BestSolutionDepth-issue->depth() );
00103 Solver = new SerialTree(issue, depthsearched);
00104 Solution = Solver->Solution;
00105
00106
00107 local->CharesExpanded++;
00108 local->NodesExpanded += Solver->Expanded;
00109
00110
00111
00112
00113
00114
00115
00116
00117 if ( Solution != NULL ) {
00118 CkEntryOptions eo;
00119 eo.setPriority(1<<31);
00120 gp.SolutionFound(Solution, &eo);
00121 ChildFinished(0);
00122 return;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132 problem *child;
00133 Waiting = 0;
00134 while ( ( child = Solver->Children.deq() ) != NULL ) {
00135
00136
00137 if ( local->BestSolutionDepth > child->depth()+child->depthToSolution() ) {
00138 child->Parent = thishandle;
00139 child->Root = 0;
00140 local->Launch(child, maxdepth, charesize, serialdist);
00141 Waiting++;
00142 } else {
00143
00144 delete child;
00145 }
00146 }
00147 if ( Solver ) {
00148 delete Solver;
00149 Solver = NULL;
00150 }
00151
00152
00153
00154 if ( Waiting == 0 ) { ChildFinished(0); }
00155 }
00156
00157
00158 idaStarWorker::~idaStarWorker() {
00159
00160 if ( Issue ) { delete Issue; }
00161 if ( Solver ) { delete Solver; }
00162 }
00163
00164
00165 void idaStarWorker::ChildFinished(int dummy) {
00166
00167 Waiting--;
00168
00169
00170 if ( Waiting <= 0 ) {
00171 CkEntryOptions eo;
00172 eo.setPriority(1<<31);
00173 if ( Issue->Root ) {
00174 CProxy_idaStarGroup parent(Master);
00175 parent.ChildFinished(0, &eo);
00176 } else {
00177 CProxy_idaStarWorker parent(Issue->Parent);
00178 parent.ChildFinished(0, &eo);
00179 }
00180 delete this;
00181 }
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 idaStarGroup::idaStarGroup(problem *issue,
00196 int startdepth, int maxdepth, int stride, int window,
00197 int charesize, int serialdist,
00198 CkCallback finished)
00199 : CharesExpanded(0), NodesExpanded(0), Running(0), Issue(issue),
00200 ChareSize(charesize), SerialDist(serialdist),
00201 StartDepth(startdepth), CurrentDepth(startdepth),
00202 MaxDepth(maxdepth), Stride(stride),
00203 BestSolutionDepth(maxdepth), Solution(NULL), Finished(finished) {
00204
00205
00206 Issue->Root = 1;
00207 for ( int i = 0 ; i < window && CurrentDepth <= MaxDepth ; i++ ) {
00208 SpawnIteration();
00209 }
00210 }
00211
00212
00213 idaStarGroup::~idaStarGroup() {
00214
00215
00216 if ( Solution != NULL ) {
00217 delete Solution;
00218 }
00219 if ( Issue != NULL ) {
00220 delete Issue;
00221 }
00222 }
00223
00224
00225
00226
00227
00228
00229 void idaStarGroup::Launch(problem *it, int maxdepth, int charesize, int serialdist) {
00230
00231 CkEntryOptions eo;
00232 eo.setPriority(it->Priority);
00233 int onPE = CkMyPe();
00234 #ifdef RANDOM_STARTING_PROC
00235 onPE = CK_PE_ANY;
00236 #endif
00237 CProxy_idaStarWorker::ckNew(thisgroup, it, maxdepth, charesize, serialdist,
00238 (CkChareID *)NULL, onPE, &eo);
00239
00240
00241 delete it;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250 void idaStarGroup::ChildFinished(int dummy) {
00251 Running--;
00252
00253
00254
00255
00256 if ( CurrentDepth <= MaxDepth && Solution == NULL) {
00257 SpawnIteration();
00258 return;
00259 }
00260
00261 if ( Running == 0 ) {
00262 CkCallback result(CkIndex_idaStarGroup::ReductionResults(NULL), thishandle);
00263 unsigned int local[2];
00264 local[0] = NodesExpanded;
00265 local[1] = CharesExpanded;
00266 contribute(2*sizeof(unsigned int), local, CkReduction::sum_int, result);
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275 void idaStarGroup::ReductionResults(CkReductionMsg *m) {
00276 if ( !m ) {
00277 CkAbort("idaStar::ReductionResults, got passed a null reduction message!");
00278 }
00279
00280 unsigned int *values = (unsigned int *)m->getData();
00281 searchResults *sr = new searchResults;
00282 sr->GroupID = thisgroup;
00283 sr->NodesExpanded = values[0];
00284 sr->CharesExpanded = values[1];
00285 Finished.send(sr);
00286 }
00287
00288
00289
00290
00291 void idaStarGroup::SolutionFound(problem *soln) {
00292
00293 if ( soln->depth() < BestSolutionDepth ) {
00294
00295
00296 BestSolutionDepth = soln->depth();
00297 if ( Solution ) {
00298 delete Solution;
00299 }
00300 Solution = soln;
00301 } else {
00302
00303 delete soln;
00304 }
00305 }
00306
00307
00308 void idaStarGroup::SpawnIteration() {
00309 if ( CkMyPe() == 0 ) {
00310 problem *child = Issue->clone();
00311
00312
00313 child->Priority.Resize(0);
00314 int k = CkBitVector::ilog2((CurrentDepth-StartDepth)/Stride+2)-1, i;
00315
00316
00317 for ( i = 0 ; i < k ; i++ ) {
00318 child->Priority.Set(i+1);
00319 }
00320
00321
00322 child->Priority.Clear(0);
00323
00324
00325
00326 if ( k != 0 ) {
00327 CkBitVector choices(((CurrentDepth-StartDepth)/Stride)-(1<<k)+1, 1<<k);
00328 child->Priority.Concat(choices);
00329 }
00330
00331 ckerr << "Spawn Iteration " << child->Priority << endl;
00332
00333
00334 Launch(child, CurrentDepth, ChareSize, SerialDist);
00335 }
00336 Running++;
00337 CurrentDepth += Stride;
00338 }
00339
00340
00341
00342
00343 void idaStarGroup::Terminate() {
00344 delete this;
00345 }