/*
Copyright (C) 2000-2004
Code contributed by Greg Collecutt, Joseph Hope and Paul Cochrane
This file is part of xmds.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
$Id: xmdsoutput.cc,v 1.26 2004/10/21 09:49:27 paultcochrane Exp $
*/
/*! @file xmdsoutput.cc
@brief Output element parsing classes and methods
More detailed explanation...
*/
#include<xmlbasics.h>
#include<dom3.h>
#include<xmdsutils.h>
#include<xmdsclasses.h>
#include<vector>
// ******************************************************************************
// ******************************************************************************
// xmdsOutput public
// ******************************************************************************
// ******************************************************************************
extern bool debugFlag;
extern vector<string> simHeaderText, simBodyText, simFooterText;
long nxmdsOutputs=0; //!< Number of xmds output objects
// ******************************************************************************
xmdsOutput::xmdsOutput(
const xmdsSimulation *const yourSimulation,
const bool& yourVerboseMode) :
xmdsElement(yourSimulation,yourVerboseMode) {
if(debugFlag) {
nxmdsOutputs++;
printf("xmdsOutput::xmdsOutput\n");
printf("nxmdsOutputs=%li\n",nxmdsOutputs);
}
myInFileSplitPoint = 0;
};
// ******************************************************************************
xmdsOutput::~xmdsOutput() {
if(debugFlag) {
nxmdsOutputs--;
printf("xmdsOutput::~xmdsOutput\n");
printf("nxmdsOutputs=%li\n",nxmdsOutputs);
}
};
// ******************************************************************************
void xmdsOutput::processElement(
const Element *const yourElement) {
if(debugFlag) {
printf("xmdsOutput::processElement\n");
}
if(verbose()) {
printf("Processing output element ...\n");
}
list<XMLString> myXMLStringList;
list<bool> myBoolList;
// ************************************
// find output file name
getAssignmentStrings(yourElement,"filename",0,1,myXMLStringList);
if(myXMLStringList.size()==1) {
myOutputFileName=*myXMLStringList.begin();
if(verbose()) {
printf("Output file is '%s'\n",myOutputFileName.c_str());
}
}
else {
// Create default output file name
myOutputFileName = simulation()->parameters()->simulationName;
myOutputFileName += ".xsil";
printf("Output file name defaulting to '%s'\n",myOutputFileName.c_str());
}
// ************************************
// find and process moment groups
// ************************************
const NodeList* candidateElements;
// find constants element and process if present
candidateElements = yourElement->getElementsByTagName("group",NOT_DEEP);
if(candidateElements->length()==0) {
throw xmdsException(yourElement,"No moment <group>s defined!");
}
for(unsigned long i=0; i<candidateElements->length(); i++) {
xmdsMomentGroup* newxmdsMomentGroup = createxmdsMomentGroup();
const Element* yourElement = dynamic_cast<const Element*> (candidateElements->item(i));
newxmdsMomentGroup->processElement(yourElement);
}
// ************************************
// find and process breakpoint
// ************************************
// find breakpoint element and process if present
candidateElements = yourElement->getElementsByTagName("breakpoint",NOT_DEEP);
if(candidateElements->length()>1) {
throw xmdsException(yourElement,"More than one <breakpoint> defined!");
}
if(candidateElements->length()==1) {
if (debugFlag) {
printf("xmdsOutput::processElement; found <breakpoint> tag\n");
}
bpEnabledFlag = true; // by default, if the <breakpoint> tag is given, then breakpoints are enabled
getAttributeBools(yourElement, "breakpoint", "enabled", NOT_REQD, bpEnabledFlag);
if (debugFlag) {
printf("xmdsOutput::processElement : bpEnabledFlag = %d\n", bpEnabledFlag);
}
xmdsBreakPoint* newxmdsBreakPoint = createxmdsBreakPoint();
const Element* yourElement = dynamic_cast<const Element*> (candidateElements->item(0));
newxmdsBreakPoint->processElement(yourElement);
}
};
// ******************************************************************************
void xmdsOutput::setInFileSplitPoint(
const unsigned long& inFileSplitPoint) {
if(debugFlag) {
printf("xmdsOutput::setInFileSplitPoint\n");
}
myInFileSplitPoint = inFileSplitPoint;
};
// ******************************************************************************
unsigned long xmdsOutput::nMomentGroups() const {
if(debugFlag) {
printf("xmdsOutput::nMomentGroups\n");
}
return myMomentGroupsList.size();
};
// ******************************************************************************
XMLString xmdsOutput::getOutputFileName() const {
if (debugFlag) {
printf("xmdsOutput::getOutputFileName\n");
}
return myOutputFileName;
};
// ******************************************************************************
const xmdsMomentGroup* xmdsOutput::momentGroup(
const unsigned long& index) const {
if(debugFlag) {
printf("xmdsOutput::momentGroup\n");
}
if(index>=myMomentGroupsList.size()) {
throw xmdsException("Internal range error in xmdsOutput::momentGroup");
}
list<xmdsMomentGroup*>::const_iterator ppxmdsMomentGroup = myMomentGroupsList.begin();
for(unsigned long i=0; i<index; i++) {
ppxmdsMomentGroup++;
}
return *ppxmdsMomentGroup;
};
// ******************************************************************************
void xmdsOutput::addSamples(
const list<unsigned long>& samplesList) const {
if(debugFlag) {
printf("xmdsOutput::addSamples\n");
}
if(samplesList.size() != myMomentGroupsList.size()) {
throw xmdsException("Internal error in xmdsOutput::addSamples: wrong number of samples.");
}
list<unsigned long>::const_iterator pLong = samplesList.begin();
for(list<xmdsMomentGroup*>::const_iterator pxmdsMomentGroup = myMomentGroupsList.begin(); pxmdsMomentGroup != myMomentGroupsList.end(); pxmdsMomentGroup++) {
(*pxmdsMomentGroup)->addSamples(*pLong);
pLong++;
}
};
// ******************************************************************************
void xmdsOutput::finaliseGeometry() {
if(debugFlag) {
printf("xmdsOutput::finaliseGeometry\n");
}
for(list<xmdsMomentGroup*>::const_iterator pxmdsMomentGroup = myMomentGroupsList.begin(); pxmdsMomentGroup != myMomentGroupsList.end(); pxmdsMomentGroup++) {
(*pxmdsMomentGroup)->finaliseGeometry();
}
};
// ******************************************************************************
void xmdsOutput::assignActiveVectorPointers(
FILE *const outfile,
const char *const tempVectorName) const {
if(debugFlag) {
printf("xmdsOutput::assignActiveVectorPointers\n");
}
for(list<xmdsMomentGroup*>::const_iterator pxmdsMomentGroup = myMomentGroupsList.begin(); pxmdsMomentGroup != myMomentGroupsList.end(); pxmdsMomentGroup++) {
(*pxmdsMomentGroup)->assignActiveVectorPointers(outfile,tempVectorName);
}
};
// ******************************************************************************
void xmdsOutput::writePlanCreationCalls(
FILE *const outfile,
const bool& useFFTWMeasure,
const bool& useWisdom) const {
if(debugFlag) {
printf("xmdsOutput::writePlanCreationCalls\n");
}
for(list<xmdsMomentGroup*>::const_iterator pxmdsMomentGroup = myMomentGroupsList.begin(); pxmdsMomentGroup != myMomentGroupsList.end(); pxmdsMomentGroup++) {
(*pxmdsMomentGroup)->writePlanCreationCalls(outfile,useFFTWMeasure,useWisdom);
}
};
// ******************************************************************************
void xmdsOutput::writePlanDeletionCalls(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsOutput::writePlanDeletionCalls\n");
}
for(list<xmdsMomentGroup*>::const_iterator pxmdsMomentGroup = myMomentGroupsList.begin(); pxmdsMomentGroup != myMomentGroupsList.end(); pxmdsMomentGroup++) {
(*pxmdsMomentGroup)->writePlanDeletionCalls(outfile);
}
};
// ******************************************************************************
// ******************************************************************************
// xmdsOutput private
// ******************************************************************************
// ******************************************************************************
// ******************************************************************************
void xmdsOutput::writePrototypes(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsOutput::writePrototypes\n");
}
if(verbose()) {
printf("Writing output prototypes ...\n");
}
fprintf(outfile,
"// ********************************************************\n"
"// output prototypes\n"
"\n"
"void _write_output();\n"
"\n");
xmdsElement::writePrototypes(outfile);
fprintf(outfile,"\n");
};
// ******************************************************************************
void xmdsOutput::writeRoutines(
FILE *const outfile) const {
if(debugFlag) {
printf("xmdsOutput::writeRoutines\n");
}
if(verbose()) {
printf("Writing output routines ...\n");
}
// write out code to handle original simulation script
fprintf(outfile,
"// ********************************************************\n"
"// output routines\n"
"// ********************************************************\n"
"\n"
"// *************************\n"
"void _write_output() {\n"
"\n"
" printf(\"Generating output for %s\\n\");\n"
" //system(\"rm -f %s\");\n\n"
" //if(system(\"split -b %li %s\")) {\n"
"\n"
" //printf(\"Cannot open my original simulation script '%s'\\n\");\n"
" //printf(\"Writing xsil data to separate xml document\\n\");\n"
"\n"
" //FILE* _outfile=fopen(\"%s\",\"w\");\n"
"\n"
" //if(_outfile==0) {\n"
" //printf(\"Unable to create output file '%s'\\n\");\n"
" //printf(\"Exiting.\\n\");\n"
" //return;\n"
" //}\n"
"\n"
" //fprintf(_outfile,\"<?xml version=\\\"1.0\\\"?>\\n\");\n"
" //fprintf(_outfile,\"\\n\");\n"
"\n",
simulation()->parameters()->simulationName.c_str(),
myOutputFileName.c_str(),
myInFileSplitPoint,simulation()->parameters()->rawFileName.c_str(),
simulation()->parameters()->rawFileName.c_str(),
myOutputFileName.c_str(),
myOutputFileName.c_str());
// biff out some informative text about xmds - this is the header
fprintf(outfile," //fprintf(_outfile,\"<info>\\n\");\n");
fprintf(outfile," //fprintf(_outfile,\"Output generated with xmds version %s, release %s.\\n\");\n",
simulation()->parameters()->version.c_str(),
simulation()->parameters()->release.c_str());
fprintf(outfile," //fprintf(_outfile,\"See http://www.xmds.org for more information.\\n\");\n");
fprintf(outfile," //fprintf(_outfile,\"</info>\\n\");\n");
// end of informative text
// it's more logical to put the simulation tag here
fprintf(outfile," //fprintf(_outfile,\"<simulation>\\n\");\n");
// now write out all of the moment groups
for(unsigned long i=0;i<myMomentGroupsList.size();i++) {
fprintf(outfile," //_mg%li_write_out(_outfile);\n",i);
}
fprintf(outfile,
"\n"
" //fprintf(_outfile,\"\\n\");\n"
" //fprintf(_outfile,\"</simulation>\\n\");\n");
// biff out some informative text about xmds - this is the footer
fprintf(outfile," //fprintf(_outfile,\"<info>\\n\");\n");
fprintf(outfile," //fprintf(_outfile,\"Output generated with xmds version %s, release %s.\\n\");\n",
simulation()->parameters()->version.c_str(),
simulation()->parameters()->release.c_str());
fprintf(outfile," //fprintf(_outfile,\"See http://www.xmds.org for more information.\\n\");\n");
fprintf(outfile," //fprintf(_outfile,\"</info>\\n\");\n");
// end of informative text
fprintf(outfile,
"\n"
" //fclose(_outfile);\n"
" //}\n"
" //else {\n"
"\n"
" //system(\"mv -f xaa %s\");\n"
"\n"
" FILE* _outfile=fopen(\"%s\",\"w\");\n"
"\n"
" if(_outfile==0) {\n"
" printf(\"Unable to open output file %s\\n\");\n"
" printf(\"Exiting.\\n\");\n"
" return;\n"
" }\n"
"\n",
myOutputFileName.c_str(),
myOutputFileName.c_str(),
myOutputFileName.c_str());
// put the header text into the output from the xmds script
fprintf(outfile,"\n");
for (unsigned int i=0; i<simHeaderText.size(); i++) {
fprintf(outfile," fprintf(_outfile,\"%s\\n\");\n",simHeaderText[i].c_str());
}
// put the body text into the output from the xmds script
fprintf(outfile,"\n");
for (unsigned int i=0; i<simBodyText.size(); i++) {
fprintf(outfile," fprintf(_outfile,\"%s\\n\");\n",simBodyText[i].c_str());
}
// biff out some informative text about xmds - this is the footer
fprintf(outfile," fprintf(_outfile,\"\\n<info>\\n\");\n");
fprintf(outfile," fprintf(_outfile,\"Output generated with xmds version %s, release %s.\\n\");\n",
simulation()->parameters()->version.c_str(),
simulation()->parameters()->release.c_str());
fprintf(outfile," fprintf(_outfile,\"See http://www.xmds.org for more information.\\n\");\n");
if (simulation()->argStruct()->nameList.size() != 0) {
fprintf(outfile," fprintf(_outfile,\" Variables that can be specified on the command line: \\n\");\n");
list<string>::const_iterator inameList = simulation()->argStruct()->nameList.begin();
list<string>::const_iterator itypeList = simulation()->argStruct()->typeList.begin();
for (long unsigned int i=0; i<simulation()->argStruct()->nameList.size(); i++)
{
string theType=itypeList->c_str();
if( theType=="double "){
fprintf(outfile," fprintf(_outfile,\" Command line argument '%s' = %%e \\n\",%s);\n",inameList->c_str(),inameList->c_str());}
else if(theType=="long "){
fprintf(outfile," fprintf(_outfile,\" Command line argument '%s' = %%li \\n\",%s);\n",inameList->c_str(),inameList->c_str());}
else if(theType=="float "){
fprintf(outfile," fprintf(_outfile,\" Command line argument '%s' = %%e \\n\",%s);\n",inameList->c_str(),inameList->c_str());}
else if(theType=="int "){
fprintf(outfile," fprintf(_outfile,\" Command line argument '%s' = %%i \\n\",%s);\n",inameList->c_str(),inameList->c_str());}
else {
fprintf(outfile," fprintf(_outfile,\" Command line argument '%s' is an unimplemented output type '%s'\\n\");\n",inameList->c_str(),itypeList->c_str());}
itypeList++;
inameList++;
}
fprintf(outfile,"\n");
}
fprintf(outfile," fprintf(_outfile,\"</info>\\n\");\n");
// end of informative text
// now put the data into the file
for(unsigned long i=0;i<myMomentGroupsList.size();i++) {
fprintf(outfile," _mg%li_write_out(_outfile);\n",i);
}
// put the footer text into the xmds simulation output
fprintf(outfile,"\n");
for (unsigned int i=0; i<simFooterText.size(); i++) {
fprintf(outfile," fprintf(_outfile,\"%s\\n\");\n",simFooterText[i].c_str());
}
// close things down and tidy up a bit
fprintf(outfile,
"\n"
" fclose(_outfile);\n"
"\n"
" //system(\"cat xab >> %s\");\n"
"\n"
" //system(\"rm -f xab\");\n"
" //}\n"
"}\n"
"\n",
myOutputFileName.c_str());
xmdsElement::writeRoutines(outfile);
fprintf(outfile,"\n");
};
// ******************************************************************************
xmdsMomentGroup* xmdsOutput::createxmdsMomentGroup() {
if(debugFlag) {
printf("xmdsOutput::createxmdsMomentGroup\n");
}
xmdsMomentGroup* newxmdsMomentGroup = new xmdsMomentGroup(simulation(),verbose(),myMomentGroupsList.size());
addChild((xmdsElement*) newxmdsMomentGroup);
myMomentGroupsList.push_back(newxmdsMomentGroup);
return newxmdsMomentGroup;
};
// ******************************************************************************
xmdsBreakPoint* xmdsOutput::createxmdsBreakPoint() {
if(debugFlag) {
printf("xmdsOutput::createxmdsBreakPoint\n");
}
xmdsBreakPoint* newxmdsBreakPoint = new xmdsBreakPoint(simulation(),verbose());
addChild((xmdsElement*) newxmdsBreakPoint);
return newxmdsBreakPoint;
};
syntax highlighted by Code2HTML, v. 0.9.1