Skip to content
Snippets Groups Projects
Commit dde5ca29 authored by Marcel Loose's avatar Marcel Loose :sunglasses:
Browse files

BugID: 753

Yet another iteration in the long way to a new BBSControl ;-).
Most significant changes:
- Added execute() and getAllSteps() methods to BBSStep classes.
- Tried to restructure SC_Simple.cc (for what it's worth); don't know if I
  broke anything, 'cause I can't test the darn thing. I may have to ditch it
  anyway, sooner or later.
parent befc3429
No related branches found
No related tags found
No related merge requests found
Showing
with 291 additions and 141 deletions
......@@ -51,6 +51,8 @@ namespace LOFAR
virtual void print(ostream& os) const;
virtual void execute(const StrategyController*) const;
private:
// Check to see if there's an infinite recursion present in the
// definition of a BBSMultiStep. This can happen when one of the steps
......@@ -58,6 +60,11 @@ namespace LOFAR
// directly or indirectly to that same BBSMultiStep.
void infiniteRecursionCheck(const string& name) const;
// Implementation of getAllSteps() for BBSMultiStep. It retrieves all
// steps by calling getAllSteps() on all steps that comprise this
// multistep.
void doGetAllSteps(vector<const BBSStep*>& steps) const;
// Vector holding a sequence of BBSSteps.
vector<const BBSStep*> itsSteps;
};
......
......@@ -57,6 +57,8 @@ namespace LOFAR
// Print the contents of \c *this in human readable form.
virtual void print(ostream& os) const;
virtual void execute(const StrategyController*) const;
private:
// Name of the data column to write data to
string itsOutputData;
......
......@@ -50,6 +50,8 @@ namespace LOFAR
virtual void print(ostream& os) const;
virtual void execute(const StrategyController* sc) const;
private:
// Solve domain size.
struct DomainSize
......
......@@ -42,6 +42,7 @@ namespace LOFAR
{
//# Forward Declarations.
class BBSMultiStep;
class StrategyController;
// \addtogroup BBS
// @{
......@@ -62,20 +63,30 @@ namespace LOFAR
// is not present, then the value will be that of the parent BBSStep
// object.
// Print the contents of \c *this in human readable form into the output
// stream \a os.
virtual void print(ostream& os) const;
// Return the name of this step.
const string& getName() const { return itsName; }
// Return a pointer to the parent of this step.
const BBSStep* getParent() const { return itsParent; }
// Return the full name of this step. The full name consists of the name
// of this step, preceeded by that of its parent, etc., separated by
// dots.
string fullName() const;
string getFullName() const;
// Return a pointer to the parent of this step.
const BBSStep* getParent() const { return itsParent; }
// Get all steps that this step consists of. The result will be a vector
// containing pointers to all steps, sorted pre-order depth-first.
//
// \todo Instead of making getAllSteps() a member function, returning a
// vector of BBSStep*, it would be better to have a BBSStepIterator
// class that can be used to iterate over the all steps. I had some
// trouble getting that thingy working, so, due to time constraints, I
// implemented things the ugly way.
vector<const BBSStep*> getAllSteps() const;
// Print the contents of \c *this in human readable form into the output
// stream \a os.
virtual void print(ostream& os) const;
// Create a new step object. The new step can either be a BBSSingleStep
// or a BBSMultiStep object. This is determined by examining the
......@@ -87,6 +98,20 @@ namespace LOFAR
const ACC::APS::ParameterSet& parSet,
const BBSStep* parent = 0);
// Execute will do a callback to a member function of \a sc. Which
// member function will be called depends on the runtime type of the
// BBSStep that's being executed. For example, a BBSSolveStep will call
// \a sc->doSolveStep().
//
// \note The current "double dispatch" implementation is (probably)
// temporary. Once the "old" BBS3 control part has been rewritten it
// will likely be removed.
//
// \attention StrategyController has \e nothing to do with a
// BBSStrategy. The name is just a remnant of the "old" BBS3 code. Much
// of this code will be rewritten after CS1.
virtual void execute(const StrategyController* sc) const = 0;
protected:
// Construct a BBSStep. \a name identifies the step name in the
// parameter set file. It does \e not uniquely identify the step \e
......@@ -101,6 +126,11 @@ namespace LOFAR
// for those members that are specified in \a parSet.
void setParms(const ACC::APS::ParameterSet& parSet);
// Implementation of getAllSteps(). The default implementation adds \c
// this to the vector \a steps.
// \note This method must be overridden by BBSMultiStep.
virtual void doGetAllSteps(vector<const BBSStep*>& steps) const;
// Name of this step.
string itsName;
......
......@@ -56,6 +56,13 @@ namespace LOFAR
// Print the contents of \c this into the output stream \a os.
void print(ostream& os) const;
// Return the steps that this strategy consists of. Multisteps are
// expanded recursively until only single steps remain. Expansion is
// done in pre-order, depth-first.
// \todo Do we really want to implement such "iterator-like behaviour"
// in this class?
vector<const BBSStep*> getAllSteps() const;
private:
// Name of the Measurement Set
......
......@@ -54,10 +54,11 @@ namespace LOFAR
void write (const ParmDataInfo& pData,
double fStart, double fEnd,
double tStart, double tEnd);
double tStart, double tEnd) const;
private:
void setCoeff (ParmDB::ParmValueRep& pval, const MeqMatrix& coeff);
void setCoeff (LOFAR::ParmDB::ParmValueRep& pval,
const MeqMatrix& coeff) const;
};
// @}
......
......@@ -40,6 +40,7 @@ namespace LOFAR
// @{
//# Forward Declarations
class BBSStep;
class SC_Simple : public StrategyController
{
......@@ -62,12 +63,34 @@ namespace LOFAR
// Get strategy type
virtual string getType() const;
virtual void doSolveStep() const;
private:
SC_Simple(const SC_Simple&);
SC_Simple& operator=(const SC_Simple&);
void readSolution();
// Write parameter values to the ParmDB tables.
void writeParmData() const;
// Create a new prediffer workorder and insert it into the database. The
// work order ID \a woid will be used as key in the database.
void setWOPrediff(int woid);
// Create a new solver workorder and insert it into the database. The
// work order ID \a woid will be used as key in the database.
void setWOSolve(int woid);
// Vector of all BBSSteps to be executed.
vector<const BBSStep*> itsSteps;
// The BBSStep currently being executed.
const BBSStep* itsCurrentStep;
// Indicate whether we're done with the current work domain.
bool itsWorkDomainDone;
int itsPrevWOID;
ACC::APS::ParameterSet itsArgs;
int itsNrIterations;
......
......@@ -71,6 +71,9 @@ namespace LOFAR
// Get strategy implementation type
virtual string getType() const = 0;
// Execute one CEPFrame run of a solve step.
virtual void doSolveStep() const;
// Get and set in/output dataholders
DH_Solution* getSolution() const;
......@@ -84,7 +87,7 @@ namespace LOFAR
int getNumberOfPrediffers() const;
ParmWriter& getParmWriter();
const ParmWriter& getParmWriter() const;
protected:
Connection* itsInSolConn;
......@@ -118,7 +121,7 @@ namespace LOFAR
inline int StrategyController::getNewWorkOrderID()
{ return theirNextWOID++; }
inline ParmWriter& StrategyController::getParmWriter()
inline const ParmWriter& StrategyController::getParmWriter() const
{ return itsParmWriter; }
inline int StrategyController::getNumberOfPrediffers() const
......
......@@ -76,6 +76,21 @@ namespace LOFAR
}
void BBSMultiStep::execute(const StrategyController*) const
{
THROW(BBSControlException, "Cannot call execute() on a multi-step");
}
void BBSMultiStep::doGetAllSteps(vector<const BBSStep*>& steps) const
{
for (uint i = 0; i < itsSteps.size(); ++i) {
vector<const BBSStep*> substeps = itsSteps[i]->getAllSteps();
steps.insert(steps.end(), substeps.begin(), substeps.end());
}
}
void BBSMultiStep::infiniteRecursionCheck(const string& name) const
{
LOG_TRACE_FLOW(AUTO_FUNCTION_NAME);
......
......@@ -50,11 +50,13 @@ namespace LOFAR
itsOutputData = ps.getString("OutputData");
}
BBSSingleStep::~BBSSingleStep()
{
LOG_TRACE_FLOW(AUTO_FUNCTION_NAME);
}
void BBSSingleStep::print(ostream& os) const
{
BBSStep::print(os);
......@@ -62,6 +64,12 @@ namespace LOFAR
os << endl << indent << "Output data: " << itsOutputData;
}
void BBSSingleStep::execute(const StrategyController*) const
{
THROW(BBSControlException, "Not yet implemented");
}
} // namespace BBS
} // namespace LOFAR
......@@ -27,6 +27,7 @@
#include <APS/ParameterSet.h>
#include <Common/LofarLogger.h>
#include <BBSControl/StreamFormatting.h>
#include <BBSControl/StrategyController.h>
namespace LOFAR
{
......@@ -81,6 +82,12 @@ namespace LOFAR
}
void BBSSolveStep::execute(const StrategyController* sc) const
{
sc->doSolveStep();
}
ostream& operator<<(ostream& os, const BBSSolveStep& bs)
{
bs.print(os);
......
......@@ -48,11 +48,20 @@ namespace LOFAR
}
string BBSStep::getFullName() const
{
string name;
if (itsParent) name = itsParent->getFullName() + ".";
name += itsName;
return name;
}
void BBSStep::print(ostream& os) const
{
os << "Step: " << itsName;
Indent id; // add an extra indentation level
os << endl << indent << "Full name: " << fullName()
os << endl << indent << "Full name: " << getFullName()
<< endl << indent << itsBaselines
<< endl << indent << itsCorrelation
<< endl << indent << itsIntegration
......@@ -62,12 +71,11 @@ namespace LOFAR
}
string BBSStep::fullName() const
vector<const BBSStep*> BBSStep::getAllSteps() const
{
string name;
if (itsParent) name = itsParent->fullName() + ".";
name += itsName;
return name;
vector<const BBSStep*> steps;
doGetAllSteps(steps);
return steps;
}
......@@ -179,6 +187,12 @@ namespace LOFAR
}
void BBSStep::doGetAllSteps(vector<const BBSStep*>& steps) const
{
steps.push_back(this);
}
//##-------- G l o b a l m e t h o d s --------##//
ostream& operator<<(ostream& os, const BBSStep& bs)
......
......@@ -122,10 +122,15 @@ namespace LOFAR
}
// void BBSStrategy::addStep(const BBSStep*& aStep)
// {
// itsSteps.push_back(aStep);
// }
vector<const BBSStep*> BBSStrategy::getAllSteps() const
{
vector<const BBSStep*> steps;
for (uint i = 0; i < itsSteps.size(); ++i) {
vector<const BBSStep*> substeps = itsSteps[i]->getAllSteps();
steps.insert(steps.end(), substeps.begin(), substeps.end());
}
return steps;
}
//##-------- G l o b a l m e t h o d s --------##//
......
......@@ -22,11 +22,6 @@
#include <lofar_config.h>
#include <cstdio>
#include <cstdlib>
#include <Common/lofar_iostream.h>
#include <Common/lofar_string.h>
#include <APS/ParameterSet.h>
#include <CEPFrame/Step.h>
#include <tinyCEP/Profiler.h>
......@@ -38,6 +33,9 @@
#include <BBSControl/WH_Prediff.h>
#include <BBSControl/WH_Solve.h>
#include <Common/lofar_sstream.h>
#include <Common/lofar_iostream.h>
#include <Common/lofar_string.h>
#ifdef HAVE_MPI
# include <Transport/TH_MPI.h>
......
......@@ -47,7 +47,7 @@ namespace LOFAR
void ParmWriter::write (const ParmDataInfo& pDataInfo,
double fStart, double fEnd,
double tStart, double tEnd)
double tStart, double tEnd) const
{
const vector<ParmData>& pData = pDataInfo.parms();
ParmDB::ParmDomain pdomain(fStart, fEnd, tStart, tEnd);
......@@ -110,7 +110,7 @@ namespace LOFAR
}
void ParmWriter::setCoeff (ParmDB::ParmValueRep& pval,
const MeqMatrix& coeff)
const MeqMatrix& coeff) const
{
ASSERT (int(pval.itsCoeff.size()) == coeff.nelements());
const double* vals = coeff.doubleStorage();
......
......@@ -26,8 +26,11 @@
#include <BBSControl/DH_Solution.h>
#include <BBSControl/DH_WOPrediff.h>
#include <BBSControl/DH_WOSolve.h>
#include <BBSControl/BBSStrategy.h>
#include <BBSControl/BBSStep.h>
#include <BBS/BBSTestLogger.h>
#include <Common/LofarLogger.h>
#include <unistd.h> // for usleep()
namespace LOFAR
{
......@@ -83,10 +86,39 @@ namespace LOFAR
WOSolve->setNewDomain(true);
WOSolve->setCleanUp(false);
itsCurStartTime = itsArgs.getDouble ("startTimeSec");
// Retrieve the parameter set file describing the BBSStrategy to be
// used. The name of this file must be specified by the key
// "strategyParset".
string strategyParset = itsArgs.getString("strategyParset");
BBSStrategy strategy(ParameterSet("strategyParset"));
// Put all the steps that comprise this strategy into our private vector
// of BBSSteps.
itsSteps = strategy.getAllSteps();
// Set the current step to the first step of the strategy
itsCurrentStep = *itsSteps.begin();
}
bool SC_Simple::execute()
{
// IF workdomain done THEN
// Set new workdomain. (Re)initialize data structures.
// Make first BBSStep in BBSStrategy current
// ENDIF
// Call execute() on current BBSStep
// IF stop-criterion met THEN
// Goto next BBSStep
// IF all BBSSteps done THEN
// Set workdomain done
// ENDIF
// ENDIF
#if 0
itsCurrentStep->execute(this);
#endif
BBSTest::ScopedTimer si_exec("C:strategycontroller_execute");
BBSTest::ScopedTimer getWOTimer("C:getWorkOrders");
bool finished = false; // Has this strategy completed?
......@@ -114,34 +146,18 @@ namespace LOFAR
readSolution();
readSolTimer.end();
// If Controller handles parameter writing
if (itsControlParmUpd)
{
// Controller writes new parameter values directly to the tables
ParmDataInfo pData;
getSolution()->getSolution(pData);
double fStart = getSolution()->getStartFreq();
double fEnd = getSolution()->getEndFreq();
double tStart = getSolution()->getStartTime();
double tEnd = getSolution()->getEndTime();
BBSTest::ScopedTimer st("C:parmwriter");
getParmWriter().write(pData, fStart, fEnd, tStart, tEnd);
}
else
{
// Send the (reference to) parameter values to Prediffers.
WOPD->setSolutionID(itsPrevWOID);
}
// If Controller handles parameter writing, then write new parameter
// values directly to the tables; else send the (reference to)
// parameter values to Prediffers.
if (itsControlParmUpd) writeParmData();
else WOPD->setSolutionID(itsPrevWOID);
}
// Take absolute value of fit
double fit = getSolution()->getQuality().itsFit;
if (fit<0)
{
fit = -fit;
}
double fit = abs(getSolution()->getQuality().itsFit);
itsSendDoNothingWO = false;
// If max number of iterations reached, go to next interval. If
// solution for this interval is good enough, send "do nothing"
// workorders until max number of iterations reached.
......@@ -169,17 +185,8 @@ namespace LOFAR
// If controller should write params at end of each interval and has
// not already done so...
if (itsWriteParms && (!itsControlParmUpd))
{
ParmDataInfo pData;
getSolution()->getSolution(pData);
double fStart = getSolution()->getStartFreq();
double fEnd = getSolution()->getEndFreq();
double tStart = getSolution()->getStartTime();
double tEnd = getSolution()->getEndTime();
BBSTest::ScopedTimer st("C:parmwriter");
getParmWriter().write(pData, fStart, fEnd, tStart, tEnd);
}
if (itsWriteParms && (!itsControlParmUpd)) writeParmData();
BBSTest::Logger::log("NextInterval");
}
else if (fit < itsFitCriterion)
......@@ -190,11 +197,77 @@ namespace LOFAR
}
}
// Get a new work order id
int woid = getNewWorkOrderID();
// Set prediffer workorder data
setWOPrediff(woid);
// Set solver workorder data
setWOSolve(woid);
return (!finished);
}
void SC_Simple::postprocess()
{
// Only read solution if previous workorder was not a "do nothing"
if (itsSendDoNothingWO == false)
{
// write solution in parmtable
if (itsWriteParms || itsControlParmUpd) {
readSolution();
writeParmData();
}
}
BBSTest::Logger::log("End of TestRun");
}
void SC_Simple::readSolution()
{
LOG_TRACE_FLOW("SC_Simple reading solution");
DH_DB* solPtr = getSolution();
// Wait for solution
bool firstTime = true;
ostringstream oss;
oss << "SELECT * FROM bbs3solutions WHERE WOID=" << itsPrevWOID;
string query(oss.str());
while (solPtr->queryDB(query, *itsInSolConn) <= 0) {
if (firstTime) {
cout << "No solution found by SC_Simple " << getID()
<< ". Waiting for solution..." << endl;
firstTime = false;
// Sleep for 50 ms, in order not to hammer the database.
usleep(50000);
}
}
// getSolution()->dump();
}
void SC_Simple::writeParmData() const
{
ParmDataInfo pData;
getSolution()->getSolution(pData);
double fStart = getSolution()->getStartFreq();
double fEnd = getSolution()->getEndFreq();
double tStart = getSolution()->getStartTime();
double tEnd = getSolution()->getEndTime();
BBSTest::ScopedTimer st("C:parmwriter");
getParmWriter().write(pData, fStart, fEnd, tStart, tEnd);
}
void SC_Simple::setWOPrediff(int woid)
{
DH_WOPrediff* WOPD = getPrediffWorkOrder();
WOPD->setDoNothing(itsSendDoNothingWO);
WOSolve->setDoNothing(itsSendDoNothingWO);
if (itsSendDoNothingWO==false)
{
// Set prediffer workorder data
WOPD->setStatus(DH_WOPrediff::New);
WOPD->setKSType("Prediff1");
WOPD->setStartChannel (itsStartChannel);
......@@ -224,104 +297,51 @@ namespace LOFAR
msParams.add ("calcUVW", itsArgs.getString("calcUVW"));
WOPD->setVarData (msParams, ant, pNames, exPNames, srcs, corrs);
}
int woid = getNewWorkOrderID();
WOPD->setWorkOrderID(woid);
WOPD->setStrategyControllerID(getID());
WOPD->setNewDomain(nextInter);
// Set solver workorder data
WOSolve->setStatus(DH_WOSolve::New);
WOSolve->setKSType("Solver");
WOSolve->setUseSVD (itsArgs.getBool ("useSVD"));
WOSolve->setIteration(itsCurIter);
WOSolve->setWorkOrderID(woid);
// Remember the issued workorder id
itsPrevWOID = WOSolve->getWorkOrderID();
WOSolve->setStrategyControllerID(getID());
WOSolve->setNewDomain(nextInter);
WOPD->setNewDomain(itsWorkDomainDone);
// Temporarily show on cout
// cout << "!!!!!!! Sent workorders: " << endl;
//WOPD->dump();
//WOSolve->dump();
// cout << "!!!!!!! " << endl;
// Insert WorkOrders into database
BBSTest::ScopedTimer st("C:putWOinDB");
// Insert WorkOrders into database;
WOPD->insertDB(*itsOutWOPDConn);
// Send workorders the same workorders to other prediffers (if there are
// more than 1)
// Send the same workorder to other prediffers (if there's more than 1)
int nrPred = getNumberOfPrediffers();
for (int i = 2; i <= nrPred; i++)
{
WOPD->setWorkOrderID(getNewWorkOrderID());
char str[32];
sprintf(str, "%i", i);
WOPD->setKSType("Prediff"+string(str));
ostringstream oss;
oss << "Prediff" << i;
WOPD->setKSType(oss.str());
WOPD->insertDB(*itsOutWOPDConn);
}
WOSolve->insertDB(*itsOutWOSolveConn);
return (!finished);
}
void SC_Simple::postprocess()
{
// Only read solution if previous workorder was not a "do nothing"
if (itsSendDoNothingWO == false)
{
// write solution in parmtable
if (itsWriteParms || itsControlParmUpd)
{
readSolution();
// Controller writes found parameter values in the tables
ParmDataInfo pData;
getSolution()->getSolution(pData);
double fStart = getSolution()->getStartFreq();
double fEnd = getSolution()->getEndFreq();
double tStart = getSolution()->getStartTime();
double tEnd = getSolution()->getEndTime();
BBSTest::ScopedTimer st("C:parmwriter");
getParmWriter().write(pData, fStart, fEnd, tStart, tEnd);
}
}
BBSTest::Logger::log("End of TestRun");
}
void SC_Simple::readSolution()
void SC_Simple::setWOSolve(int woid)
{
LOG_TRACE_FLOW("SC_Simple reading solution");
DH_DB* solPtr = getSolution();
DH_WOSolve* WOSolve = getSolveWorkOrder();
WOSolve->setDoNothing(itsSendDoNothingWO);
WOSolve->setStatus(DH_WOSolve::New);
WOSolve->setKSType("Solver");
WOSolve->setUseSVD (itsArgs.getBool ("useSVD"));
WOSolve->setIteration(itsCurIter);
// Wait for solution
bool firstTime = true;
int id = itsPrevWOID;
char str[64];
sprintf(str, "SELECT * FROM bbs3solutions WHERE WOID=%i", id);
string query(str);
// We need to set the work-id of the solver equal to that of the
// prediffer (for reasons that elude me (GML)).
WOSolve->setWorkOrderID(woid);
while (solPtr->queryDB(query, *itsInSolConn) <= 0)
{
if (firstTime)
{
cout << "No solution found by SC_Simple " << getID()
<< ". Waiting for solution..." << endl;
firstTime = false;
}
}
// Remember the issued workorder id
itsPrevWOID = WOSolve->getWorkOrderID();
//getSolution()->dump();
WOSolve->setStrategyControllerID(getID());
WOSolve->setNewDomain(itsWorkDomainDone);
// Insert workorder into the database
WOSolve->insertDB(*itsOutWOSolveConn);
}
} // namespace BBS
} // namespace LOFAR
......@@ -22,6 +22,8 @@
#include <lofar_config.h>
#include <BBSControl/BBSStrategy.h>
#include <BBSControl/BBSStep.h>
#include <BBSControl/BBSMultiStep.h>
#include <Common/LofarLogger.h>
using namespace LOFAR;
......@@ -38,6 +40,12 @@ int main()
BBSStrategy strategy(ParameterSet(progName + ".parset"));
cout << strategy << endl;
// vector<const BBSStep*> steps = strategy.getAllSteps();
// cout << "This strategy contains " << steps.size() << " steps:" << endl;
// for (uint i = 0; i < steps.size(); ++i) {
// cout << " " << steps[i]->getName() << endl;
// }
} catch (LOFAR::Exception& e) {
LOG_FATAL_STR(e);
return 1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment