Changeset ffe057 for src/Actions


Ignore:
Timestamp:
Dec 10, 2012, 10:10:19 AM (12 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
c44322
Parents:
343401
git-author:
Frederik Heber <heber@…> (08/27/12 11:59:18)
git-committer:
Frederik Heber <heber@…> (12/10/12 10:10:19)
Message:

Added SpecificFragmentController and subclasses that contain functions to add type-specific jobs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Actions/FragmentationAction/FragmentationAutomationAction.cpp

    r343401 rffe057  
    4545#include "CodePatterns/Info.hpp"
    4646#include "CodePatterns/Log.hpp"
    47 #include "JobMarket/Controller/FragmentController.hpp"
    4847#include "JobMarket/Jobs/FragmentJob.hpp"
    4948
    50 #include "Atom/atom.hpp"
    51 #include "Box.hpp"
    52 #include "Element/element.hpp"
     49#include "Fragmentation/Automation/MPQCFragmentController.hpp"
     50#include "Fragmentation/Automation/VMGFragmentController.hpp"
    5351#include "Fragmentation/EnergyMatrix.hpp"
    5452#include "Fragmentation/ForceMatrix.hpp"
     
    6361#include "Fragmentation/Summation/SumUpPerLevel.hpp"
    6462#include "Fragmentation/Summation/OrthogonalFullSummator.hpp"
    65 #include "Fragmentation/Summation/OrthogonalSummation.hpp"
    6663#include "Fragmentation/Summation/writeTable.hpp"
    6764#include "Graph/DepthFirstSearchAnalysis.hpp"
     
    7168#include "Jobs/MPQCData_printKeyNames.hpp"
    7269#include "Jobs/Grid/SamplingGrid.hpp"
    73 #include "LinearAlgebra/RealSpaceMatrix.hpp"
    7470#ifdef HAVE_VMG
    7571#include "Jobs/VMGJob.hpp"
     
    7975#include "Jobs/VMGData_printKeyNames.hpp"
    8076#endif
    81 #include "molecule.hpp"
    8277#include "World.hpp"
    8378
     
    10398{
    10499  return NULL;
    105 }
    106 
    107 const int LEVEL = 5;
    108 
    109 /** Creates a MPQCCommandJob with argument \a filename.
    110  *
    111  * @param jobs created job is added to this vector
    112  * @param command mpqc command to execute
    113  * @param filename filename being argument to job
    114  * @param nextid id for this job
    115  */
    116 void parsejob(
    117     std::vector<FragmentJob::ptr> &jobs,
    118     const std::string &command,
    119     const std::string &filename,
    120     const JobId_t nextid)
    121 {
    122   std::ifstream file;
    123   file.open(filename.c_str());
    124   ASSERT( file.good(), "parsejob() - file "+filename+" does not exist.");
    125   std::string output((std::istreambuf_iterator<char>(file)),
    126       std::istreambuf_iterator<char>());
    127   double begin[NDIM] = { 0., 0., 0. };
    128   const RealSpaceMatrix& M = World::getInstance().getDomain().getM();
    129   const double size = M.at(0,0);
    130   ASSERT( M.determinant() == size*size*size,
    131       "parsejob() - current domain matrix "+toString(M)+" is not cubic.");
    132   const int level = LEVEL;
    133   FragmentJob::ptr testJob( new MPQCJob(nextid, output, begin, size, level) );
    134   jobs.push_back(testJob);
    135   file.close();
    136   LOG(1, "INFO: Added MPQCCommandJob from file "+filename+".");
    137100}
    138101
     
    166129}
    167130
    168 /** Extracts MPQCData from received vector of FragmentResults.
    169  *
    170  * @param results results to extract MPQCData from
    171  * @param fragmentData on return array filled with extracted MPQCData
    172  */
    173 template <typename T>
    174 void ConvertFragmentResultTo(
    175     const std::vector<FragmentResult::ptr> &results,
    176     std::map<JobId_t, T> &fragmentData)
    177 {
    178   // extract results
    179   fragmentData.clear();
    180 
    181   LOG(2, "DEBUG: Parsing now through " << results.size() << " results.");
    182   for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
    183       iter != results.end(); ++iter) {
    184     //LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result));
    185     T extractedData;
    186     std::stringstream inputstream((*iter)->result);
    187     LOG(2, "DEBUG: First 50 characters FragmentResult's string: "+(*iter)->result.substr(0, 50));
    188     boost::archive::text_iarchive ia(inputstream);
    189     ia >> extractedData;
    190     LOG(1, "INFO: extracted data is " << extractedData << ".");
    191     fragmentData.insert( std::make_pair( (*iter)->getId(), extractedData) );
    192   }
    193 
    194   ASSERT( results.size() == fragmentData.size(),
    195       "ConvertFragmentResultTo() - the number of extracted data differs from the number of results.");
    196 }
    197131
    198132/** Creates a lookup from FragmentJob::id to the true fragment  number.
     
    653587
    654588
    655 void RunService(
    656     boost::asio::io_service &io_service,
    657     std::string message)
    658 {
    659   message = std::string("io_service: ") + message;
    660   io_service.reset();
    661   Info info(message.c_str());
    662   io_service.run();
    663 }
    664 
    665 void requestIds(
    666     FragmentController &controller,
    667     const FragmentationFragmentationAutomationAction::FragmentationFragmentationAutomationParameters &params,
    668     const size_t numberjobs)
    669 {
    670   controller.requestIds(params.host.get(), params.port.get(), numberjobs);
    671 }
    672 
    673 bool createJobsFromFiles(
    674     FragmentController &controller,
    675     const FragmentationFragmentationAutomationAction::FragmentationFragmentationAutomationParameters &params,
    676     const std::vector< boost::filesystem::path > &jobfiles)
    677 {
    678   std::vector<FragmentJob::ptr> jobs;
    679   for (std::vector< boost::filesystem::path >::const_iterator iter = jobfiles.begin();
    680       iter != jobfiles .end(); ++iter) {
    681     const std::string &filename = (*iter).string();
    682     if (boost::filesystem::exists(filename)) {
    683       const JobId_t next_id = controller.getAvailableId();
    684       LOG(1, "INFO: Creating MPQCCommandJob with filename'"
    685           +filename+"', and id "+toString(next_id)+".");
    686       parsejob(jobs, params.executable.get().string(), filename, next_id);
    687     } else {
    688       ELOG(1, "Fragment job "+filename+" does not exist.");
    689       return false;
    690     }
    691   }
    692   controller.addJobs(jobs);
    693   controller.sendJobs(params.host.get(), params.port.get());
    694   return true;
    695 }
    696 
    697 #ifdef HAVE_VMG
    698 bool createLongRangeJobs(
    699     FragmentController &controller,
    700     const FragmentationFragmentationAutomationAction::FragmentationFragmentationAutomationParameters &params,
    701     const std::map<JobId_t, MPQCData> &fragmentData,
    702     const SamplingGrid &full_sampled_grid,
    703     const Fragment &full_fragment)
    704 {
    705   std::vector<FragmentJob::ptr> jobs;
    706   // add one job for each fragment as the short-range correction which we need
    707   // to subtract from the obtained full potential to get the long-range part only
    708   for (std::map<JobId_t, MPQCData>::const_iterator iter = fragmentData.begin();
    709       iter != fragmentData.end(); ++iter) {
    710     const JobId_t next_id = controller.getAvailableId();
    711     LOG(1, "INFO: Creating VMGJob with " << iter->second.sampled_grid.sampled_grid.size()
    712         << " gridpoints and " << iter->second.charges.size() << " particle charges.");
    713     FragmentJob::ptr testJob(
    714         new VMGJob(next_id, iter->second.sampled_grid, iter->second.positions, iter->second.charges) );
    715     jobs.push_back(testJob);
    716   }
    717 
    718   {
    719     const World::AtomComposite &atoms = World::getInstance().getAllAtoms();
    720     std::vector< std::vector<double> > positions;
    721     positions.reserve(atoms.size());
    722     std::vector<double> charges;
    723     charges.reserve(atoms.size());
    724     std::vector<double> position(3, 0.);
    725     for (World::AtomComposite::const_iterator iter = atoms.begin();
    726         iter != atoms.end(); ++iter) {
    727       const Vector &pos = (*iter)->getPosition();
    728       for (size_t i=0;i<3;++i) position[i] = pos[i];
    729       positions.push_back(position);
    730       charges.push_back((double)((*iter)->getElement().getAtomicNumber()));
    731     }
    732     const JobId_t next_id = controller.getAvailableId();
    733     LOG(1, "INFO: Creating full VMGJob with " << full_sampled_grid.sampled_grid.size()
    734         << " gridpoints and " << charges.size() << " particle charges.");
    735     FragmentJob::ptr testJob(
    736         new VMGJob(next_id, full_sampled_grid, positions, charges) );
    737     jobs.push_back(testJob);
    738   }
    739 
    740   // then send jobs to controller
    741   controller.addJobs(jobs);
    742   controller.sendJobs(params.host.get(), params.port.get());
    743   return true;
    744 }
    745 #endif
    746 
    747 void WaitforResults(
    748     boost::asio::io_service &io_service,
    749     FragmentController &controller,
    750     const FragmentationFragmentationAutomationAction::FragmentationFragmentationAutomationParameters &params,
    751     const size_t NoExpectedResults
    752     )
    753 {
    754   size_t NoCalculatedResults = 0;
    755   while (NoCalculatedResults != NoExpectedResults) {
    756     // wait a bit
    757     boost::asio::deadline_timer timer(io_service);
    758     timer.expires_from_now(boost::posix_time::milliseconds(500));
    759     timer.wait();
    760     // then request status
    761     controller.checkResults(params.host.get(), params.port.get());
    762     RunService(io_service, "Checking on results");
    763 
    764     const std::pair<size_t, size_t> JobStatus = controller.getJobStatus();
    765     LOG(1, "INFO: #" << JobStatus.first << " are waiting in the queue and #" << JobStatus.second << " jobs are calculated so far.");
    766     NoCalculatedResults = JobStatus.second;
    767   }
    768 }
    769 
    770 
    771589Action::state_ptr FragmentationFragmentationAutomationAction::performCall() {
    772590  boost::asio::io_service io_service;
    773   FragmentController controller(io_service);
     591  MPQCFragmentController mpqccontroller(io_service);
     592  mpqccontroller.setHost(params.host.get());
     593  mpqccontroller.setPort(params.port.get());
     594  VMGFragmentController vmgcontroller(io_service);
     595  vmgcontroller.setHost(params.host.get());
     596  vmgcontroller.setPort(params.port.get());
    774597
    775598  // TODO: Have io_service run in second thread and merge with current again eventually
     
    777600  // Phase One: obtain ids
    778601  std::vector< boost::filesystem::path > jobfiles = params.jobfiles.get();
    779   requestIds(controller, params, jobfiles.size());
    780   RunService(io_service, "Requesting ids");
     602  mpqccontroller.requestIds(jobfiles.size());
    781603
    782604  // Phase Two: create and add MPQCJobs
    783   if (!createJobsFromFiles(controller, params, jobfiles))
     605  if (!mpqccontroller.addJobsFromFiles(params.executable.get().string(), jobfiles))
    784606    return Action::failure;
    785   RunService(io_service, "Adding MPQCJobs");
    786607
    787608  // Phase Three: calculate result
    788   WaitforResults(io_service, controller, params, jobfiles.size());
    789   controller.receiveResults(params.host.get(), params.port.get());
    790   RunService(io_service, "Requesting short-range results");
    791   std::vector<FragmentResult::ptr> MPQCresults = controller.getReceivedResults();
     609  mpqccontroller.waitforResults(jobfiles.size());
    792610  std::map<JobId_t, MPQCData> fragmentData;
    793   ConvertFragmentResultTo<MPQCData>(MPQCresults, fragmentData);
     611  mpqccontroller.getResults(fragmentData);
    794612
    795613#ifdef HAVE_VMG
     
    797615  ASSERT( World::getInstance().getAllAtoms().size() != 0,
    798616      "FragmentationFragmentationAutomationAction::performCall() - please load the full molecule into the World before.");
    799 
    800   // create a vector of all job ids
    801   std::vector<JobId_t> jobids(MPQCresults.size(), JobId::IllegalJob);
    802   std::transform(MPQCresults.begin(), MPQCresults.end(), jobids.begin(),
    803       boost::bind(&FragmentResult::getId,
    804           boost::bind(&FragmentResult::ptr::operator->, _1)));
    805617
    806618  // obtain combined charge density
     
    815627
    816628  // Phase Four: obtain more ids
    817   requestIds(controller, params, fragmentData.size()+1);
    818   RunService(io_service, "Requesting ids");
     629  vmgcontroller.requestIds(fragmentData.size()+1);
    819630
    820631  // Phase Five: create VMGJobs
    821   if (!createLongRangeJobs(controller, params, fragmentData, full_sample, full_fragment))
     632  if (!vmgcontroller.createLongRangeJobs(fragmentData, full_sample, full_fragment))
    822633    return Action::failure;
    823   RunService(io_service, "Adding VMGJobs");
    824634
    825635  // Phase Six: calculate result
    826   WaitforResults(io_service, controller, params, fragmentData.size()+1);
    827   controller.receiveResults(params.host.get(), params.port.get());
    828   RunService(io_service, "Requesting long-range results");
    829   std::vector<FragmentResult::ptr> VMGresults = controller.getReceivedResults();
    830   ASSERT( MPQCresults.size()+1 == VMGresults.size(),
    831       "FragmentationFragmentationAutomationAction::performCall() - number of MPQCresultd and VMGresults don't match.");
    832 
     636  vmgcontroller.waitforResults(fragmentData.size()+1);
    833637  std::map<JobId_t, VMGData> longrangeData;
    834   ConvertFragmentResultTo<VMGData>(VMGresults, longrangeData);
     638  vmgcontroller.getResults(longrangeData);
     639  ASSERT( fragmentData.size()+1 == longrangeData.size(),
     640      "FragmentationFragmentationAutomationAction::performCall() - number of MPQCresults+1 "
     641      +toString(fragmentData.size()+1)+" and VMGresults "+toString(longrangeData.size())+" don't match.");
     642
    835643  // remove full solution from map (must be highest id), has to be treated extra
    836644  VMGData fullsolutionData = (--longrangeData.end())->second;
     
    860668  }
    861669#endif
    862   size_t Exitflag = controller.getExitflag();
     670  size_t Exitflag = vmgcontroller.getExitflag() + mpqccontroller.getExitflag();
    863671
    864672  return (Exitflag == 0) ? Action::success : Action::failure;
Note: See TracChangeset for help on using the changeset viewer.