00001 #include <pvm3.h> 00002 #include "SIGEL_GP/SIG_GPFitnessTrainer.h" 00003 #include "SIGEL_Program/SIG_Program.h" 00004 #include "SIGEL_Tools/SIG_Randomizer.h" 00005 00006 #include "SIGEL_Tools/SIG_IO.h" 00007 00008 SIGEL_GP::SIG_GPFitnessTrainer::SIG_GPFitnessTrainer(SIGEL_GP::SIG_GPExperiment& exp) 00009 :exp(exp), 00010 modifiedRobot( exp.robot ), 00011 PVMData( modifiedRobot, 00012 exp.environment, 00013 exp.simulationParameter, 00014 exp.gpParameter.getFitnessName(), 00015 false), 00016 nextFreeNumber(0), 00017 nextHostNumber(0), 00018 pvmTasks( exp.population.getSize() ), 00019 pvmHosts(), 00020 toSpawnList() 00021 { 00022 toSpawnList.setAutoDelete( true ); 00023 pvmTasks.setAutoDelete( true ); 00024 pvmHosts.setAutoDelete( true ); 00025 00026 switch (exp.simulationParameter.getSimulationLibrary()) 00027 { 00028 case SIGEL_Simulation::SIG_SimulationParameters::DynaMo: 00029 try 00030 { 00031 modifiedRobot.prepareDynaMo(); 00032 } 00033 catch (SIGEL_Tools::SIG_Exception &e) 00034 { 00035 SIGEL_Tools::SIG_IO::cerr << e.getMessage(); 00036 exit( 1 ); 00037 }; 00038 break; 00039 case SIGEL_Simulation::SIG_SimulationParameters::DynaMechs: 00040 try 00041 { 00042 modifiedRobot.prepareDynaMechs(); 00043 } 00044 catch (SIGEL_Tools::SIG_Exception &e) 00045 { 00046 SIGEL_Tools::SIG_IO::cerr << e.getMessage(); 00047 exit( 1 ); 00048 }; 00049 break; 00050 }; 00051 00052 for (int i=0; i<pvmTasks.size(); i++) 00053 pvmTasks.insert( i, 0 ); 00054 00055 int noOfActiveHosts = 0; 00056 SIG_GPPVMHost *actHost = exp.gpParameter.getHostList().first(); 00057 00058 while (actHost) 00059 { 00060 if (actHost->enabled) 00061 noOfActiveHosts++; 00062 actHost = exp.gpParameter.getHostList().next(); 00063 }; 00064 00065 pvmHosts.resize( noOfActiveHosts ); 00066 00067 int hostCounter = 0; 00068 actHost = exp.gpParameter.getHostList().first(); 00069 00070 while (actHost) 00071 { 00072 if (actHost->enabled) 00073 { 00074 pvmHosts.insert( hostCounter, new SIG_GPActivePVMHost( *actHost ) ); 00075 00076 QCString actHostNameQCString = actHost->name.utf8(); 00077 00078 char const *actHostNameCString = actHostNameQCString; 00079 00080 int singleInfo = 0; 00081 00082 int info = pvm_addhosts( &const_cast< char* >(actHostNameCString), 1, &singleInfo ); 00083 00084 hostCounter++; 00085 }; 00086 00087 actHost = exp.gpParameter.getHostList().next(); 00088 }; 00089 }; 00090 00091 SIGEL_GP::SIG_GPFitnessTrainer::~SIG_GPFitnessTrainer() 00092 { 00093 for (int i=0; i<pvmHosts.size(); i++) 00094 { 00095 SIG_GPActivePVMHost *actHost = pvmHosts[i]; 00096 00097 QCString actHostNameQCString = actHost->name.utf8(); 00098 00099 char const *actHostNameCString = actHostNameQCString; 00100 00101 int singleInfo = 0; 00102 00103 int info = pvm_delhosts( &const_cast< char* >(actHostNameCString), 1, &singleInfo ); 00104 }; 00105 }; 00106 00107 int SIGEL_GP::SIG_GPFitnessTrainer::spawnTask(SIGEL_GP::SIG_GPIndividual const& ind) 00108 { 00109 int hostNumber = getNextHost(); 00110 00111 int actId = nextFreeNumber; 00112 00113 bool success = false; 00114 00115 #ifdef SIG_DEBUG 00116 SIGEL_Tools::SIG_IO::cerr << "Trying to spawn task for individual " 00117 << ind.getPoolPos() 00118 << "\n"; 00119 #endif 00120 00121 int oldSize = pvmTasks.size(); 00122 int oldMaxIndex = oldSize - 1; 00123 if ( oldMaxIndex < (nextFreeNumber + 1) ) 00124 { 00125 pvmTasks.resize( oldSize + exp.population.getSize() ); 00126 for (int i=oldSize; i<pvmTasks.size(); i++) 00127 pvmTasks.insert( i, 0 ); 00128 }; 00129 00130 if (hostNumber != -1) 00131 { 00132 SIG_GPActivePVMHost *usedHost = pvmHosts[ hostNumber ]; 00133 00134 QCString hostNameQCString = usedHost->name.utf8(); 00135 char const *hostNameCString = hostNameQCString; 00136 00137 QString executableName = usedHost->executableDir.path() + "/sigel_slave"; 00138 QCString executableNameQCString = executableName.utf8(); 00139 00140 char const *executableNameCString = executableNameQCString; 00141 00142 int taskId = 0; 00143 int spawnInfo = pvm_spawn( const_cast< char* >( executableNameCString ), 00144 0, 00145 PvmTaskHost, 00146 const_cast< char* >( hostNameCString ), 00147 1, 00148 &taskId ); 00149 00150 if (spawnInfo == 1) 00151 { 00152 success = true; 00153 00154 SIG_GPPVMTask *newTask = new SIG_GPPVMTask( *usedHost, 00155 actId, 00156 taskId, 00157 ind.getPoolPos(), 00158 QDateTime::currentDateTime() ); 00159 00160 pvmTasks.insert( actId, newTask ); 00161 00162 usedHost->noOfSlaves++; 00163 00164 QString senderStr; 00165 QTextStream qts( &senderStr, IO_ReadWrite ); 00166 SIGEL_Program::SIG_Program const &program = ind.getProgram(); 00167 00168 PVMData.savePVMDataTransfer(qts, program); 00169 PVMData.sendQStringToPVM(senderStr, taskId, 23); 00170 }; 00171 }; 00172 00173 if (!success) 00174 { 00175 QArray<int> *toSpawn = new QArray<int>(2); 00176 (*toSpawn)[0] = actId; 00177 (*toSpawn)[1] = ind.getPoolPos(); 00178 toSpawnList.append( toSpawn ); 00179 }; 00180 00181 nextFreeNumber++; 00182 00183 return actId; 00184 }; 00185 00186 double SIGEL_GP::SIG_GPFitnessTrainer::checkTask(int taskId) 00187 { 00188 double result = -1; 00189 00190 SIG_GPPVMTask *pvmTask = pvmTasks[ taskId ]; 00191 00192 if (pvmTask) 00193 { 00194 int info = pvm_probe(pvmTask->pvmTaskId, 5); 00195 00196 if (info != 0) 00197 { 00198 pvm_recv(pvmTask->pvmTaskId, 5); 00199 pvm_upkdouble(&result,1,1); 00200 00201 pvmTask->host.noOfSlaves--; 00202 pvmTasks.insert( taskId, 0 ); 00203 } 00204 else 00205 { 00206 if (exp.gpParameter.getTimeOutMinutes() > 0) 00207 { 00208 int const timeOutSeconds = exp.gpParameter.getTimeOutMinutes() * 60; 00209 00210 QDateTime timeOutTime = pvmTask->spawnTime.addSecs( timeOutSeconds ); 00211 00212 if (QDateTime::currentDateTime() >= timeOutTime) 00213 { 00214 pvm_kill( pvmTask->pvmTaskId ); 00215 pvmTask->host.noOfSlaves--; 00216 QArray<int> *toSpawn = new QArray<int>(2); 00217 (*toSpawn)[0] = taskId; 00218 (*toSpawn)[1] = pvmTask->indPosition; 00219 toSpawnList.append( toSpawn ); 00220 00221 pvmTasks.insert( taskId, 0 ); 00222 }; 00223 }; 00224 }; 00225 }; 00226 00227 #ifdef SIG_DEBUG 00228 SIGEL_Tools::SIG_IO::cerr << "Checking task " 00229 << taskId 00230 << "\n"; 00231 #endif 00232 00233 return result; 00234 }; 00235 00236 void SIGEL_GP::SIG_GPFitnessTrainer::stopTrainersSlaves() 00237 { 00238 int const noOfTries = 100; 00239 00240 for (int i=0; i < nextFreeNumber; i++) 00241 { 00242 if ( pvmTasks[i] ) 00243 for (int j=0; j<noOfTries; j++) 00244 { 00245 int info = pvm_kill( pvmTasks[i]->pvmTaskId ); 00246 00247 if (info >= 0) 00248 break; 00249 }; 00250 }; 00251 }; 00252 00253 void SIGEL_GP::SIG_GPFitnessTrainer::sweepToSpawn() 00254 { 00255 QArray< int > *actJob = toSpawnList.first(); 00256 QArray< int > *prevJob = 0; 00257 00258 #ifdef SIG_DEBUG 00259 SIGEL_Tools::SIG_IO::cerr << "Sweeping to spawn!\n"; 00260 #endif 00261 00262 while (actJob) 00263 { 00264 #ifdef SIG_DEBUG 00265 SIGEL_Tools::SIG_IO::cerr << "Entering spawn loop!\n"; 00266 #endif 00267 00268 int hostNumber = getNextHost(); 00269 00270 bool success = false; 00271 00272 if (hostNumber != -1) 00273 { 00274 SIG_GPActivePVMHost *usedHost = pvmHosts[ hostNumber ]; 00275 00276 QCString usedHostNameQCString = usedHost->name.utf8(); 00277 char const *usedHostNameCString = usedHostNameQCString; 00278 00279 QString executableName = usedHost->executableDir.path() + "/sigel_slave"; 00280 QCString executableNameQCString = executableName.utf8(); 00281 00282 char const *executableNameCString = executableNameQCString; 00283 00284 int taskId = 0; 00285 int spawnInfo = pvm_spawn( const_cast< char* >( executableNameCString ), 00286 static_cast< char** >(0), 00287 PvmTaskHost, 00288 const_cast< char* >( usedHostNameCString ), 00289 1, 00290 &taskId ); 00291 00292 if (spawnInfo == 1) 00293 { 00294 success = true; 00295 00296 int internalId = (*actJob)[0]; 00297 int individualNumber = (*actJob)[1]; 00298 00299 SIG_GPIndividual &ind = exp.population.getIndividual( individualNumber ); 00300 00301 SIG_GPPVMTask *newTask = new SIG_GPPVMTask( *usedHost, 00302 internalId, 00303 taskId, 00304 individualNumber, 00305 QDateTime::currentDateTime() ); 00306 00307 pvmTasks.insert( internalId, newTask ); 00308 00309 usedHost->noOfSlaves++; 00310 00311 QString senderStr; 00312 QTextStream qts( &senderStr, IO_ReadWrite ); 00313 SIGEL_Program::SIG_Program const &program = ind.getProgram(); 00314 00315 PVMData.savePVMDataTransfer(qts, program); 00316 PVMData.sendQStringToPVM(senderStr, taskId, 23); 00317 }; 00318 }; 00319 00320 if (success) 00321 { 00322 toSpawnList.remove(); 00323 actJob = toSpawnList.current(); 00324 if (actJob == prevJob) 00325 break; 00326 } 00327 else 00328 { 00329 prevJob = actJob; 00330 actJob = toSpawnList.next(); 00331 }; 00332 }; 00333 }; 00334 00335 int SIGEL_GP::SIG_GPFitnessTrainer::getNextHost() 00336 { 00337 int result = -1; 00338 00339 SIG_GPActivePVMHost *nextHost = pvmHosts[ nextHostNumber ]; 00340 00341 for (int i=0; i<pvmHosts.size(); i++) 00342 { 00343 SIG_GPActivePVMHost *nextHost = pvmHosts[ nextHostNumber ]; 00344 if (nextHost->noOfSlaves < nextHost->maxSlaves) 00345 result = nextHostNumber; 00346 00347 nextHostNumber = ++nextHostNumber % pvmHosts.size(); 00348 00349 if (result != -1) 00350 break; 00351 }; 00352 00353 #ifdef SIG_DEBUG 00354 SIGEL_Tools::SIG_IO::cerr << "Next Host: " 00355 << result 00356 << "\n"; 00357 #endif 00358 00359 return result; 00360 };