Rose2xaif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Rose2XAIF.cpp
Go to the documentation of this file.
1 
13 #include "util/DumpAsDot.hpp"
14 #include "util/Types.hpp"
15 #include "Fortran/CFGcanon.hpp"
16 #include "xaif/Sage2XAIFGraph.hpp"
19 #include "xaif/DFSTraversal.hpp"
20 #include "xaif/XAIFPrinter.hpp"
21 #include "xaif/XAIFtoSage.hpp"
22 #include "main/Rose2XAIF.hpp"
23 
24 
25 namespace rose2xaif {
26  namespace SgXAIF {
27 
28  void printRose2XAIFStage(SgFile * file, SgGlobal * sg, std::string msg)
29  {
30  if (SgSourceFile * source = isSgSourceFile(file)) {
31  sg = source->get_globalScope();
32  debugMsg(1, msg);
33  UNPARSEANDPRINT_MACRO(3, sg, "FILE : ");
34  }
35  }
36 
37  void addHeaderFile(SgGlobal *sg, StateManager *state, std::string fileName)
38  {
39 
40  // Insert ADIC disclaimer comment string and include directive for ad_types.h
41 #ifdef AD_FORTRAN_SPECIFIC
42  std::string incstr = "";
43 #else
44  std::string incstr = state->getDisclaimer();
45 
46  incstr+= "\n\n#ifdef ADIC_DENSE";
47  incstr+= "\n#include \"ad_types.h\"";
48  if(state->naryflag){
49  incstr+= "\n#include \"ad_grad_saxpy-n_dense.h\"";
50  }
51  incstr+= "\n#endif";
52  incstr+= "\n\n#ifdef ADIC_DENSE_REVERSE";
53  incstr+= "\n#include \"ad_types.hpp\"";
54  if(state->naryflag){
55  incstr+= "\n#include \"ad_grad_saxpy-n_dense.h\"";
56  }
58  incstr+= "\n#include \"adic_class_initialization_header.h\"";
59  incstr+= "\n#endif";
60  incstr+= "\n\n#ifdef ADIC_DENSE_SEED";
61  incstr+= "\n#include \"ad_types.h\"";
62  if(state->naryflag){
63  incstr+= "\n#include \"ad_grad_saxpy-n_dense.h\"";
64  }
65  incstr+= "\n#endif";
66  incstr+= "\n\n#ifdef ADIC_GRAD_LENGTH";
67  incstr+= "\n#include \"ad_grad_length_types.h\"";
68  if(state->naryflag){
69  incstr+= "\n#include \"ad_grad_saxpy-n_dense.h\"";
70  }
71  incstr+= "\n#endif\n\n";
72  incstr+= "\n\n#ifdef ADIC_SPARSE_NO_GRAD";
73  incstr+= "\n#include \"noderiv_sparslinc.h\"";
74  if(state->naryflag){
75  incstr+= "\n#include \"ad_grad_saxpy-n_sparse.h\"";
76  }
77  incstr+= "\n#endif\n\n";
78  incstr+= "\n\n#ifdef ADIC_SPARSE";
79  incstr+= "\n#include \"sparslinc.h\"";
80  if(state->naryflag){
81  incstr+= "\n#include \"ad_grad_saxpy-n_sparse.h\"";
82  }
83  incstr+= "\n#endif\n\n";
84 #endif
85  SgDeclarationStatementPtrList & plst = sg->getDeclarationList();
86  SgDeclarationStatementPtrList::iterator liter = plst.begin();
87  for (liter; liter != plst.end(); liter++) {
88  std::string stmt_file = (*liter)->get_file_info()->get_filename();
89  if (stmt_file == fileName)
90  break;
91  }
92  SgStatement *first_stmt = NULL;
93  if (liter != plst.end()) {
94  first_stmt = (*liter);
95  }
96 
97  int alineno = 0;
98  int acolno = 0;
99  int nol = 0;
100  bool copied = false;
101  bool unparsed = false;
102 
103  std::string user = "user-generated";
104 #ifndef AD_FORTRAN_SPECIFIC
105  PreprocessingInfo * toadd = new PreprocessingInfo(
106  PreprocessingInfo::CplusplusStyleComment, incstr, user, alineno,
107  acolno, nol, PreprocessingInfo::before);
108 
109  if (first_stmt) {
110  first_stmt->addToAttachedPreprocessingInfo(toadd,
111  PreprocessingInfo::before);
112  }
113 #endif
114  debugMsg(3, "added preproc "<< incstr.c_str());
115  }
116 
117  std::string invokeXAIFBooster(const std::string &fileName, StateManager *state)
118  {
119  int found = fileName.find_last_of(".");
120  std::string suffix = ".cn.xaif";
121  std::string origfilenamewithsuffixbeforelastandpath = fileName.substr(0,found);
122  std::string xaiffilename = origfilenamewithsuffixbeforelastandpath + suffix;
123  if(state->getWorkflow()==CN_PP)
124  return xaiffilename;
125  struct stat statStruct;
126  std::string inlinableintrinsicsfilename = state->getXaifInlinableIntrinsicsFileName();
127  std::string noninlinableintrinsicsfilename = state->getXaifNonInlinableIntrinsicsFileName();
128  debugMsg(1,"******************* AD step, calling xaifBooster ****************");
129 
130  suffix = ".cn.xb.xaif";
131  std::string adxaiffilename = origfilenamewithsuffixbeforelastandpath + suffix;
132  // remove old ad xaif file if it exists
133  if (!stat(adxaiffilename.c_str(), &statStruct)) // file exists
134  unlink(adxaiffilename.c_str());
135  // invoke XAIF module
136  std::string command;
137  command = state->getDifferentiationModule();
138  //optionally call sparsehandling which involves setting -n ary flag in xaifBooster and Colpack interfacing
139  if(state->getSparseHandlingFlag()|| state->naryflag){
140  command += " -n";
141  }
142  if(state->getAdmmFlag() && state->getDifferentiationMode()=="reverse"){
143  command += " -p";
144  }
145  command += " -v -w free -i " + xaiffilename +
146  " -o " + adxaiffilename +
147  " -s " + state->getXaifSchemaLocation() +
148  " -c " + inlinableintrinsicsfilename +
149  " -N " + noninlinableintrinsicsfilename;
150  for(StringList::iterator stringListIt=state->getXaifBoosterOptions().begin();
151  stringListIt!=state->getXaifBoosterOptions().end();
152  ++stringListIt) command += " "+(*stringListIt);
153  // redirect:
154  command += " 2>&1";
155  debugMsg(0, "xaifBooster call: "<< command.c_str());
156  FILE *pFile_p=popen(command.c_str(),"r");
157  if (!pFile_p) {
158  int merr=errno;
159  THROW_LOGICEXCEPTION_MACRO("xaifBooster invocation via popen failed " << strerror(merr));
160  }
161  std::ostringstream xaifBoosterOutput;
162  char buffer[9];
163  while (fread(buffer, 1, 1, pFile_p) != 0) {
164  xaifBoosterOutput << buffer[0];
165  }
166  int rc=pclose(pFile_p);
167  if (rc!=0) {
168  std::cerr << xaifBoosterOutput.str().c_str() << std::endl;
169  THROW_LOGICEXCEPTION_MACRO("xaifBooster invocation returned error code, see messages above");
170  }
171  if (xaifBoosterOutput.str().length()) std::cout << xaifBoosterOutput.str().c_str() << std::endl;
172  return adxaiffilename;
173  }
174 
175  void parseAndPostProcessXAIF(const std::string &xaiffilename, const std::string fileName, StateManager *state, InlinableIntrinsicDefinitions &theInlinableIntrinsicDefinitions,
176  NonInlinableIntrinsicDefinitions &theNonInlinableIntrinsicDefinitions,SgFile * file, SgProject * psgproj, CanonStateC &canonC, SgGlobal * sg)
177  {
178  // Check if differentiated XAIF file exists
179  state->setContext("ad_XAIF Parsing");
180  struct stat statStruct;
181  if (stat(xaiffilename.c_str(), &statStruct)<0)
182  fatal("Differentiated XAIF file not found (check differentiation module errors).");
183 
184  debugMsg(2, "****************** reading produced XAIF back ****************");
185  rose2xaif::SgXAIF::CallGraph theTransformedXAIFCallGraph;
186  XAIFParser debuggingParser(theTransformedXAIFCallGraph,theInlinableIntrinsicDefinitions,theNonInlinableIntrinsicDefinitions);
187  debuggingParser.parse(xaiffilename);
188  debugMsg(3, "---- Successfully Parsed XAIF Graph in "<< xaiffilename.c_str());
189  debugMsg(5, "XML Output: ----");
190  DFSTraversal dfsTraversal;
191  if (state->getDebugLevel() > 5) {
192  XAIFPrinter debuggingPrintVisitor;
193  dfsTraversal.addVisitor(debuggingPrintVisitor);
194  dfsTraversal.traverse(&theTransformedXAIFCallGraph);
195  }
196  // Convert to Sage
197  state->setContext("XAIF2Sage");
198  debugMsg(2, "****************** converting XAIF to Sage ****************");
199  XAIFtoSage xaif2SageVisitor(file,state);
200  xaif2SageVisitor.setCallGraph(&theTransformedXAIFCallGraph);
201  xaif2SageVisitor.setIntrinsics(&theInlinableIntrinsicDefinitions,&theNonInlinableIntrinsicDefinitions);
202  dfsTraversal.clearVisitors();
203  dfsTraversal.addVisitor(xaif2SageVisitor);
204  dfsTraversal.traverse(&theTransformedXAIFCallGraph);
205 
206 #ifdef AD_FORTRAN_SPECIFIC
207  DumpAsDot().doIt(psgproj,"adic_after_unparse_before_conversion");
208  DumpAsDot().doIt("adic_all_after_unparse_before_conversion");
209 #endif
210 
211  state->setContext("Convert Declarations");
212 #ifndef AD_FORTRAN_SPECIFIC
213  ConvertDeclarationsPassC(psgproj, canonC).traverse(file, preorder);
214 #else
215  ConvertDeclarationsPassFortran(file).traverse(file, preorder);
216 #endif
217  printRose2XAIFStage(file, sg, "POST CONVERT DECLARATIONS : ");
218 
219  state->setContext("");
220  }
221 
222  void unparseAndCreateOutput(SgProject * psgproj, StateManager *state, SgFilePtrList *fptr)
223  {
224 #ifdef AD_FORTRAN_SPECIFIC
225  DumpAsDot().doIt(psgproj,"adic_after");
226  DumpAsDot().doIt("adic_all_after");
227 #endif
228 
229  for (SgFilePtrList::iterator iter = fptr->begin(); iter != fptr->end(); iter++)
230  createIntermediateOuputFileWithSuffix(psgproj, state, state->getWorkflow(), *iter);
231 
232  if(state->naryflag){
233  debugMsg(1, "Creating the dense saxpy array operations files");
234  state->generateSparseAXPYHeader();
235  state->generateDenseAXPYHeader();
236  }
237 
238  //If ADOL external function drivers need to be created
239  if(state->adolcflag==true){
241  }
242  }
243 
244  //Create a copy of the templatefile SgFile object and store it for future use.
245  //The original is removed from the SgProject so that it is not considered as a source file for differentiation.
246  void preprocessTemplateFile(StateManager *state, SgFilePtrList *fptr) {
247  SgFile * templatefileptr=0;
248  SgTreeCopy deepcopy; //This performs deep copy
249  for (SgFilePtrList::iterator iter = fptr->begin(); iter != fptr->end(); iter++) {
250  std::string curfilename = (*iter)->getFileName();
251  if((curfilename.compare(state->getTemplateFile()))==0){
252  SgNode * copy_node = (*iter)->copy(deepcopy);
253  templatefileptr = isSgFile(copy_node);
254  fptr->erase(iter);
255  break;
256  }
257  }
258  if (!templatefileptr) {
259  THROW_LOGICEXCEPTION_MACRO("preprocessTemplateFile: no template file named " << state->getTemplateFile().c_str() << " found");
260  }
261  state->setTemplate(templatefileptr);
262  }
263 
264  void createIntermediateOuputFileWithSuffix(SgProject * psgproj, StateManager * state, int stage, SgFile * file)
265  {
266  psgproj->unparse();
267 
268  std::string origfilenamewithsuffixandpath = std::string(file->getFileName());
269  int found = origfilenamewithsuffixandpath.find_last_of("/");
270  std::string folder;
271  if(isSymlink(origfilenamewithsuffixandpath))
272  folder = origfilenamewithsuffixandpath.substr(0,found);
273  else
274  folder = "$PWD";
275  std::string origfilenamewithsuffix = origfilenamewithsuffixandpath.substr(found+1);
276  std::string rosefilenamewithsuffixandpath = folder +"/rose_" + origfilenamewithsuffix;
277 
278  std::string suffix;
279  switch(stage)
280  {
281  case R_ONLY : suffix = ".r."; break;
282  case CN_ONLY : suffix = ".cn."; break;
283  case CN_PP : suffix = ".cn.pp."; break;
284  case CN_XB_PP : suffix = ".cn.xb.pp."; break;
285  dafault :
286  fatal("Unknown stage " << stage);
287  }
288 
289  found = origfilenamewithsuffixandpath.find_last_of(".");
290  std::string origfilenamewithsuffixbeforelastandpath = origfilenamewithsuffixandpath.substr(0,found);
291  std::string origfilenamesfinalsuffix = origfilenamewithsuffixandpath.substr(found+1);
292  std::string destinationfilename = origfilenamewithsuffixbeforelastandpath + suffix + origfilenamesfinalsuffix;
293 
294  copyFileNameInFileSystem(rosefilenamewithsuffixandpath, destinationfilename);
295 
296  }
297 
298  void copyFileNameInFileSystem(std::string src, std::string target)
299  {
300  std::string command;
301  command = "mv " + src + " "+ target;
302  assert(::system(command.c_str())==0);
303  }
304 
305  void processCommandLineAndInitializeState(BoostCommandLine &commandprocessor, StateManager * state, int myargc, char * myargv[])
306  {
307  int flags = 0, nOrder = 1;
308  commandprocessor.processCommandLine(myargc, myargv);
309  std::string mapModel, headerFile = "ad_deriv.h"; // use default (ROSE2XAIF_DIR env. var) for base dir
310  rose2xaif::StringList derivNames, defines, dirs, controlFiles;
311  derivNames.push_back("Jacobian");
312  state->init(flags, derivNames, mapModel, headerFile, defines, dirs, /*controlFiles,*/ nOrder);
313  }
314 
315  void processIntrinsics(StateManager * state, InlinableIntrinsicDefinitions &theInlinableIntrinsicDefinitions,NonInlinableIntrinsicDefinitions &theNonInlinableIntrinsicDefinitions)
316  {
317  XAIFParser intrinsicsParser(theInlinableIntrinsicDefinitions,theNonInlinableIntrinsicDefinitions);
318  intrinsicsParser.parse(state->getXaifInlinableIntrinsicsFileName());
319  debugMsg(2, "Successfully parsed XAIF Inlinable Intrinsics definition file " << state->getXaifInlinableIntrinsicsFileName());
320  intrinsicsParser.parse(state->getXaifNonInlinableIntrinsicsFileName());
321  debugMsg(2, "Successfully parsed XAIF NonInlinable Intrinsics definition file " << state->getXaifNonInlinableIntrinsicsFileName());
322  }
323 
324  }
325 }