source: trunk/yao/src/Translator.cpp @ 1

Last change on this file since 1 was 1, checked in by lnalod, 15 years ago

Initial import of YAO sources

  • Property svn:eol-style set to native
File size: 198.6 KB
Line 
1//! \file    Translator.cpp
2//! \brief   Implementation of the Translator class, which handles both
3//!          description analysis and code generation.
4//! \version 2007/10/01 (yyyy/mm/dd)
5//! \author  Luigi Nardi <luiginardi(at)gmail.com>
6//
7// This file is part of YAO, a framework for variational assimilation in
8// numerical models.
9// Copyright (c) 2001-onwards LOCEAN. All rights reserved.
10//
11// This program may be redistributed and/or modified under the terms of the GNU
12// General Public License as published by the Free Software Foundation, either
13// version 2 of the license, or (at your option) any later version.
14//
15// This program is provided AS IS and WITHOUT ANY WARRANTY, including any
16// implied warranty of DESIGN, MERCHANTABILITY or FITNESS FOR A PARTICULAR
17// PURPOSE.
18
19#include "help/FilePath.hpp"
20#include "Translator.hpp"
21//#include "help/Enforcer.hpp"
22#include "help/Helper.hpp"
23
24#include <iomanip>
25#include <numeric>
26
27//PROVE--------
28//#include <iostream>
29#include <cstdlib>
30#include <stdlib.h>
31
32using namespace std;
33using namespace yao;
34
35//-------------------GLOBAL VARIABLES----------------------------------------
36string projectName; 
37int maxNbInput = 0;           // The old Wmaxnbi: the max number of input for a module.
38int maxNbOutput = 0;          // The old Wmaxnbs: the max number of output for a module.
39int maxNbJacobianInput = 0;   // The old Wmaxjacnbi: the max number of input for a module that needs automatic jacobian operations.
40int maxNbJacobianOutput = 0;  // The old Wmaxjacnbs: the max number of output for a module that needs automatic jacobian operations.
41char buffer[BUFSIZE + 1];     // Used in particular to perform the format.
42int clonLevel = 0;            // Is the level of the clone: 2 all, 1 something.
43
44// For the profiling of the parallelism:
45int totalLoops = 0;           // Is the total number of loops generated analysing the order directive.
46int parallelForwardLoops = 0; // Is the total number of parallelized loops for the forward generated analysing the order directive and the connections.
47//int parallelBackwardLoops = 0;// Is the total number of parallelized loops for the backward generated analysing the order directive and the connections.
48int parallelForwardModules = 0;      // Is the total number of parallelized modules found analysing the order directive and the connections.
49//int parallelBackwardModules = 0;// Is the total number of parallelized modules found analysing the order directive and the connections.
50int totalModulesInOrders = 0; // Is the total number of modules that are present in the order directive.
51int totalAtomicOperations = 0;// Is the total number of atomic operations present in the order directive: this affect the performance.
52//---------------------------------------------------------------------------
53
54/**
55 * The Translator constructor.
56 * @param aTokenizer is the BaseLexer wrapper that handles the file opening and lexing.
57 */
58Translator::Translator(Tokenizer& aTokenizer): BaseParser(aTokenizer.theBaseLexer){
59  this->setFilename(aTokenizer.theBaseLexer.getFilename());
60  antlr::ASTFactory factory;
61  this->initializeASTFactory(factory);
62  this->setASTFactory(&factory);
63}
64
65/**
66 * Generation of the code in function of the description file reed.
67 * This method call all the generate code methods relative to all the directives.
68 */
69void Translator::generateCode(){
70  this->description(); // Description analysis.
71
72  if(theDisplay.isHelp()) // Display the help menu if requested in the description file.
73    this->theDisplay.displayHelp();
74
75  if(theDisplay.isDefval()) // Display the Constant table if requested in the description file.
76    this->theDisplay.display(theConstantTable);
77
78  projectName = static_cast<FilePath>(this->getFilename()).getTitle();
79
80  // Project declaration begins here.
81  string filename = "Y1" + projectName + ".h";  // The declaration file, the file where all the declaration are located.
82  ofstream declaration(filename.c_str(), ios::out | ios::binary);
83  if(!declaration.is_open())
84    throw ofstream::failure("couldn't create " + filename);
85
86  // Project information (should also provide #include guard).
87  declaration << endl << "//" << setfill('-') << setw(52) << "-" << setfill(' ') << endl;
88  declaration << "// project: " << projectName << "     header generated by YAO version " << VERSION << endl;
89  declaration << "//" << setfill('-') << setw(52) << "-" << setfill(' ') << endl << endl;
90
91  // Define some parallelism stuffs
92  if(theContext.isParallel()){
93    declaration << "// DEFINE FOR PARALLELISM" << endl
94      << "#define PARALLEL" << endl
95      << "#ifdef _OPENMP" << endl
96      << "  #include <omp.h>" << endl
97      << "#else" << endl
98      << "  #define omp_get_thread_num() 0" << endl
99      << "  #define omp_get_num_threads() 1" << endl
100      << "  #define omp_get_max_threads() 1" << endl
101      << "#endif" << endl << endl;
102  }else {
103    declaration << "// DEFINE FOR PARALLELISM" << endl
104      << "#define NOT_PARALLEL" << endl << endl;
105  }
106
107  declaration << "//€ € € € LES DECLARATIONS DE CLASS, DEFINE ET ALLOCATION DU PROJET" << endl;
108
109  // Constants declaration.
110  declaration.precision(numeric_limits<double>::digits10);
111
112  // Exception for MQN, the constant Y3_M must be added.
113  if(!theConstantTable.find(static_cast<string>("Y3_M")))
114    theConstantTable.push_back(Constant(static_cast<string>("Y3_M"), static_cast<string>("8"))); 
115
116  // Number of base 10 digits that can be represented without change.
117  for(Table<Constant>::const_iterator it = theConstantTable.begin(); it != theConstantTable.end(); ++it)
118    declaration << "#define \t" << it->getName() << " \t" << it->getText() << endl;
119
120  // Code generation context (options) declaration.
121  if(theContext.isExternal()){
122    // Extern objects declaration file.
123    filename = "Yaoext_" + projectName ;  // The extern objects file.
124    ofstream externfile(filename.c_str(), ios::out | ios::binary);
125    if(!externfile.is_open())
126      throw ofstream::failure("couldn't create " + filename);
127    this->generateCode(declaration, externfile,  theContext);
128    externfile.close();
129  }else this->generateCode(declaration, declaration,  theContext); 
130  // Display the context if requested in the description file.
131  if(theDisplay.isContext()){
132    Table<Context> theContextTable; // Just for printing we create a table of context with only one element.
133    theContextTable.push_back(theContext); // The table has just one element.
134    this->theDisplay.display(theContextTable);
135  }
136
137  // Trajectories declaration.
138  this->generateCode(declaration, theTrajectoryTable);
139  // Display the trajectories if requested in the description file.
140  if(theDisplay.isTrajectory())
141    this->theDisplay.display(theTrajectoryTable);
142
143  // So-called spaces (model operators) declaration.
144  this->generateCode(declaration, theSpaceTable);
145  // Display the spaces if requested in the description file.
146  if(theDisplay.isSpace())
147    this->theDisplay.display(theSpaceTable);
148
149  // Operators declaration.
150  this->generateCode(declaration, theOperatorTable);
151  // Display the operators if requested in the description file.
152  if(theDisplay.isOpera())
153    this->theDisplay.display(theOperatorTable);
154
155  // Project implementation begins here.
156  filename = "Y2" + projectName + ".h"; // The function implementation file.
157  ofstream implementation(filename.c_str(), ios::out | ios::binary);
158  if(!implementation.is_open())
159    throw ofstream::failure("couldn't create " + filename);
160
161  // Project information (should also provide #include guard).
162  implementation << endl << "//" << setfill('-') << setw(52) << "-" << setfill(' ') << endl;
163  implementation << "// project: " << projectName << "     header generated by YAO version " << VERSION  << endl;
164  implementation << "//" << setfill('-') << setw(52) << "-" << setfill(' ') << endl << endl;
165  implementation << "// € € € € € € € € LES FONCTIONS PREDEFINIES" << endl;
166
167  // cout << "Neuron......." << endl; // For see/debug.
168  // Neural net: netward declaration.
169  if(theNeuronTable.size())
170    this->generateCode(declaration, implementation, theNeuronTable);
171  // Display the neurons if requested in the description file.
172  if(theDisplay.isNeuron())
173    this->theDisplay.display(theNeuronTable);
174
175  // cout << "Module......." << endl; // For see/debug.
176  this->generateCode(declaration, implementation, theModulTable);
177  // Display the Modules if requested in the description file.
178  if(theDisplay.isModule())
179    this->theDisplay.display(theModulTable);
180
181  // cout << "connection......." << endl; // For see/debug.
182  this->generateCode(theConnectionTable);
183 
184  // Display the connections if requested in the description file.
185  if(theDisplay.isConnection())
186    this->theDisplay.display(theConnectionTable);
187
188  this->generateCode(implementation, theOrderTable);
189
190  this->generateCode(implementation, theFunctionTable);
191
192  // We have finished the generation of each directive. Here we have something more to generate lastly
193  this->generateCode(declaration, implementation);
194
195  // Close files declaration and implementation:
196  declaration.close();
197  implementation.close();
198  // End Translator
199
200 //Example sets the defined paths for the program to C:\
201//Example then lists the paths
202//    putenv("CIAO=parallel");
203//    cout << getenv("CIAO"); 
204
205   
206 
207  //setenv("CIAO","parallel",1);
208
209
210
211//  system( "CIAO=iiiiiiiiiiiiiiii" );
212//  system( "export CIAO" );
213//system( "echo $HOME" );
214   
215 
216
217
218}
219
220/**
221 * Generation of the code relative to the directive option.
222 * @param aDeclaration is the generated file we are writing on.
223 * @param anExternal is the generated external file we are writing on if it is present in the options, nothing otherwise.
224 * @param theContext is the object that contain all options and that define the context.
225 */
226void Translator::generateCode(ostream& aDeclaration, ostream& anExternal, Context& theContext){
227  // This way we do not generate YO_TOOL if gradtest is defined because not useful (this is a difference with Charles code).
228  if(theContext.isTool() && !theContext.isGradTest())       
229    aDeclaration << "#define\t\tYO_TOOL\n";
230  if(theContext.getNeuronSize()){
231    aDeclaration << "#define\t\tYO_NETWARD\n";
232    aDeclaration << "#define\t\tYNMAXCELL " << theContext.getNeuronSize() << endl;
233  }
234  if(theContext.isM1qn3())
235    aDeclaration << "#define\t\tYO_M1QN3\n";
236  if(theContext.isM2qn1())
237    aDeclaration << "#define\t\tYO_M2QN1\n";
238  if(theContext.isGradTest())
239    aDeclaration << "#define\t\tYO_GRADTEST\n";
240  if(theContext.isIncremental())
241    aDeclaration << "#define\t\tYO_VARINCR\n";
242  if(theContext.isDebugInput())
243    aDeclaration << "#define\t\tYO_DBG_TING\n";
244  if(theContext.isDebugBeta())
245    aDeclaration << "#define\t\tYO_DBG_BETA\n"; 
246  if(theContext.isDebugNan())
247    aDeclaration << "#define\t\tYO_DBG_NANF\n";
248  if(theContext.isDebugForward())
249    aDeclaration << "#define\t\tYO_DBG_FWARD\n";
250  if(theContext.isDebugBackward())
251    aDeclaration << "#define\t\tYO_DBG_BWARD\n";
252  if(theContext.isDebugLinward())
253    aDeclaration << "#define\t\tYO_DBG_LWARD\n"; 
254  if(theContext.isExternal()){
255    // Header for the creation script of the external objects that we have to link.
256    anExternal << "#!/bin/sh \nLDYEXTOBJ=\" ";
257    vector<string> vect = theContext.getExternal();
258    for(vector<string>::iterator it=vect.begin(); it!=vect.end(); it++)
259      anExternal << (*it) << " ";
260    anExternal << "\" "; 
261  }
262  if(theContext.isDouble()) {
263    aDeclaration << "#define\t\tYDOUBLE \n";
264    aDeclaration << "#define\t\tYTINY  1.e-15 \n";
265  }else{
266    aDeclaration << "#define\t\tYFLOAT \n";
267    aDeclaration << "#define\t\tYTINY  1.e-8 \n";
268  }
269  aDeclaration << "#define\t\tYREAL " << theContext.getReal() << "\n";
270}
271
272/**
273 * Generation of the code relative to the directive traj.
274 * @param aDeclaration is the generated file we are writing on.
275 * @param aTrajectoryTable is the table that contains all the objects trajectory.
276 */
277void Translator::generateCode(ostream& aDeclaration, Table<Trajectory>& aTrajectoryTable){
278  for (Table<Trajectory>::const_iterator tra = theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); ++tra){
279    int count = tra - aTrajectoryTable.begin();
280    aDeclaration << endl << "#define\t\tYNBUPTIME_" << tra->getName() << \t"
281      << tra->getBoot() << endl;
282    aDeclaration << "#define\t\tYNBSTEPTIME_" << tra->getName() << "\t"
283      << tra->getSize() << endl;
284    aDeclaration << "#define\t\tYNBALLTIME_" << tra->getName() << \t"
285      << tra->getBoot() + tra->getSize() << endl;
286    aDeclaration << "#define\t\tYDt_"  << tra->getName() << " \tYTabTraj["
287      << count << "].dtime" << endl;
288    aDeclaration << "#define\t\tYid_" << tra->getName() << " \t" << count << endl;
289  }
290}
291
292/**
293 * Generation of the code relative to the directive opera.
294 * @param aDeclaration is the generated file we are writing on.
295 * @param anOperatorTable is the table that contains all the objects operator.
296 */
297void Translator::generateCode(ostream& aDeclaration, const Table<Operator>& anOperatorTable){
298  for (Table<Operator>::const_iterator op = anOperatorTable.begin(); op != anOperatorTable.end(); ++op){
299    aDeclaration << endl;
300    for (int i=0; i < op->getDimension(); ++i)
301      aDeclaration << "#define\t\tYA" << i + 1 << "_" << op->getName() << "\t\t" << op->getShape()[i] << endl;
302    if (op->getDimension() == 3)
303      aDeclaration << "#define\t\tYA2A3_" << op->getName() << "\t\t" << op->getShape()[1] * op->getShape()[2] << endl;
304    aDeclaration << "#define\t\tYDIM_" << op->getName() << "\t\t" << op->getDimension() << endl;
305    aDeclaration << "#define\t\tYNB_" << op->getName() << "\t\t" 
306      << accumulate(op->getShape().begin(), op->getShape().end(), 1, multiplies<int>()) << endl;
307    aDeclaration << "#define\t\tYid_" << op->getName() << " \t" << op - anOperatorTable.begin() << endl;
308  }
309}
310
311/**
312 * Generation of the code relative to the directive netward.
313 * @param aDeclaration is the generated file we are writing on.
314 * @param anImplementation is the generated file we are writing on.
315 * @param aNeuronTable is the table that contains all the objects neuron.
316 */
317void Translator::generateCode(ostream& aDeclaration, ostream& anImplementation, const Table<Neuron>& aNeuronTable){
318  ENFORCE(theContext.getNeuronSize())("no O_NETWARD option has been declared\n");
319  aDeclaration << "\n\n// DECLARATION POUR DES RESEAUX DE NEURONES ... : \n";
320  for(Table<Neuron>::const_iterator ne = aNeuronTable.begin(); ne != aNeuronTable.end(); ne++){
321    aDeclaration << "#define  YNBI_" << ne->getName() << " " << ne->getInDegree() << "\n";
322    aDeclaration << "#define  YNBS_" << ne->getName() << " " << ne->getOutDegree() <<  "\n";
323    aDeclaration << "double  *YNTW_" << ne->getName() << ";\n";
324    aDeclaration << "int      YNBW_" << ne->getName() << ";\n"; 
325    aDeclaration << setw(6) << left << theContext.getReal() << "   YNTI_" << ne->getName() << "[" << ne->getInDegree() << "];\n";
326    aDeclaration << setw(6) << left << theContext.getReal() << "   YNTS_" << ne->getName() << "[" << ne->getOutDegree() << "];\n";
327    aDeclaration << setw(6) << left << theContext.getReal() << "   YNTG_" << ne->getName() << "[" << ne->getOutDegree() << "];\n";
328    aDeclaration << setw(6) << left << theContext.getReal() << "   YNTD_" << ne->getName() << "[" << ne->getInDegree() << "];\n";
329    aDeclaration << "#define  YNID_" << ne->getName() << " " << ne - aNeuronTable.begin() << "\n\n";
330
331    MACRO0_NETLOD(ne->getName().c_str(), ne - aNeuronTable.begin()); // Wheight load of the Neuron Net.
332    anImplementation << buffer;
333    if(ne->getInDegree() > maxNbInput) maxNbInput = ne->getInDegree();      // The input output number of the net
334    if(ne->getOutDegree() > maxNbOutput) maxNbOutput = ne->getOutDegree();  // are used in order to determine the max value.
335  }
336}
337
338/**
339 * Generation of the code relative to the directive modul.
340 * @param aDeclaration is the generated file we are writing on.
341 * @param anImplementation is the generated file we are writing on.
342 * @param aModulTable is the table that contains all the objects modul.
343 */
344void Translator::generateCode(ostream& aDeclaration, ostream& anImplementation, Table<Modul>& aModuleTable){
345  long sizeM1qn3=0;                         // Dimension of the problem = sum the number of states of target.     
346  int sizeCout=0;                           // Size off all modules cout: that's for the test functions.
347  int modId=0;                              // The module ID.
348  int w1, w2, w3;                           // Some counters useful in the generation process.
349  string traj;                              // The trajectory currently analyzed.
350  string filename;                          // It is the automatic differentiation file (in the case automatic differentiation is defined).
351  ostringstream  bufwrk;                    // A stream buffer to perform some work with strings.
352  ofstream automaticDifferentiation;        // It is the automatic differentiation stream linked to the automatic differentiation file.
353  ostringstream streamInputWardFunctions;   // It's useful in order to generate the string inputWardFunctions.
354  string inputWardFunctions;                // Parameters in input for functions *ward (Yting[i] sequence in Y2_project_file).
355  char YREAL[7];                            // Used in macros, we leave this declaration because at the moment we don't want change the Charles macros.
356  strcpy(YREAL, theContext.getReal().c_str());
357  char modul[LG_MAX_STRING + 1];            // Name of the actual module, used in macro's generation.
358  char spaceOrOperator[LG_MAX_STRING + 1];  // Name of the actual Space or Operator, used in macro's generation.
359  long Y3SizeRz2, Y3SizeRz3;                // Vectors dimension for m1qn2 and/or m1qn3 (rz is a characteristic of the minimizer).
360  char c1;                                  // A letter that say if the covt module is himself or not.
361
362  if(theModulTable.size())
363    aDeclaration << "\n/*----------------- GENERATION OF MODULES... -------------*/\n";
364  for(Table<Modul>::iterator it=aModuleTable.begin(); it != aModuleTable.end(); it++, modId++){
365
366    // FIRST PART: SOME CHECK & INIT of variables performed for each module already stocked from the grammar.
367    // ------------------------------------------------------------------------------------------------------
368    strcpy(modul, it->getName().c_str());
369    strcpy(spaceOrOperator, it->getSpaceOrOperator().c_str());
370    // Call of the function that control the cross options inside a module. This module member function also perform
371    // the adding of some values to the member's object. This values are directly accessed later in the generation of the code.
372    it->checkCrossOption(theSpaceTable, theOperatorTable, theContext, theModulTable, theNeuronTable);
373    // Set of global variables.
374    // Determination of the max for input output of modules.
375    if(it->isInput() && it->getInput() > maxNbInput)
376      maxNbInput = it->getInput();
377    if(it->isOutput() && it->getOutput() > maxNbOutput)
378      maxNbOutput = it->getOutput();
379    // Determination of the max for the jacobian (Yjac).
380    if(!it->isHidjac() && !it->isNetward() && !it->isAutonet()){         
381      if(it->getInput() > maxNbJacobianInput) maxNbJacobianInput = it->getInput();
382      if(it->getOutput() > maxNbJacobianOutput) maxNbJacobianOutput = it->getOutput();
383    }
384
385    if(it->isClonol())
386      clonLevel = 2; // With clonol we clone everything of the module inherited.
387
388    if(it->isTarget()){ // Calculates the dimension of the problem for M1qn3.
389      if(it->getNbStepTarget())
390        sizeM1qn3 += it->getNbStepTarget() * it->getOutput() * it->getGridPoints();
391      else sizeM1qn3 += it->getOutput() * it->getGridPoints();
392    }
393
394    if(it->isCout()) // Calculates the dimension of cout for the test functions.
395      sizeCout += it->getOutput() * it->getGridPoints();
396
397    // SECOND PART: --------------------------------Macro call and write into the files.
398    // ---------------------------------------------------------------------------------
399    aDeclaration << "\n//~~~~~~~~~~~~~~~~~~~~~~~~~ module " << modul << "~~~~~~~~~~~~~~~~~~~~~~~~~\n";
400    aDeclaration << "#define Yid_" << modul << " " << modId << "\n";
401
402    if(it->isOnAdf()){
403      if(filename.empty()){ // The first time that we find a module automatic differentiation we create the file.
404        filename = "Y3" + projectName + ".l";  // The automatic differentiation file.
405        automaticDifferentiation.open(filename.c_str(), ios::out | ios::binary);
406        if (!automaticDifferentiation.is_open())
407          throw ofstream::failure("couldn't create " + filename);
408        // Header for the differentiation file: performed one time.
409        automaticDifferentiation << "#" << theContext.getAutoDiffWriteMode() << "liste des modules a deriver automatiquement\n";
410      }
411      // We add a module on the list of modules to be derivated automatically.
412      automaticDifferentiation << modul << " " << it->getInput() << " " << it->getOutput();
413    }
414
415    if(it->isTarget()){       
416      aDeclaration << "#define YNBPTARGET_" << modul << " " <<  it->getNbStepTarget() << "\n";
417      aDeclaration << "#define YDEBTARGET_" << modul << " " <<  it->getBeginTarget() << "\n";
418      aDeclaration << "#define YENDTARGET_" << modul << " " <<  it->getEndTarget() << "\n";
419    }
420    // Line 2733 Yao8.c
421    if(theContext.isGradTestOrIncremental()){
422      if(it->getNbAxes()==1){
423        MACRO1_VALST(modul, 'D', YDELTA);  aDeclaration << buffer;
424        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
425          MACRO1_VALSIT(modul, 'D', YDELTA, w1);  aDeclaration << buffer;
426        }// We could perform just one "for" but the information will be mixed.
427        for (w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
428          MACRO1_HERESIT(modul, 'D', YDELTA, w1);  aDeclaration << buffer;
429        }
430      }else if(it->getNbAxes()==2){
431        MACRO2_VALST(modul, 'D', YDELTA);  aDeclaration << buffer;
432        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
433          MACRO2_VALSIT(modul, 'D', YDELTA, w1);  aDeclaration << buffer;
434        }// We could perform just one "for" but the information will be mixed.
435        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
436          MACRO2_HERESIT(modul, 'D', YDELTA, w1);  aDeclaration << buffer;
437        }
438      }else if(it->getNbAxes()==3){
439        MACRO3_VALST(modul, 'D', YDELTA);  aDeclaration << buffer;
440        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
441          MACRO3_VALSIT(modul, 'D', YDELTA, w1);  aDeclaration << buffer;
442        }// We could perform just one "for" but the information will be mixed.
443        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
444          MACRO3_HERESIT(modul, 'D', YDELTA, w1);  aDeclaration << buffer;
445        }
446      }
447    }
448
449    if(!it->isCloned()) // Not cloned.
450      aDeclaration << "\nclass Yao" << it->getName() << ";\n";
451    if(!it->isNoward())  // Not noward  i.e. case of a normal module with a source.h.
452      aDeclaration << "class " << it->getName() << ";\n";
453    if(it->isInter()){       
454      MACRO0_NBMOD(modul, it->getGridPoints());  aDeclaration << buffer;}
455    // We always have the number of output for a module.
456    MACRO0_NBSMOD(modul, it->getOutput()); 
457    aDeclaration << buffer;
458    if(it->getInput()){ // If there are inputs this is the input's number of a module.
459      MACRO0_NBIMOD(modul, it->getInput());     aDeclaration << buffer;}
460    if(theContext.isGradTest()){  // We constitute the input parameters handling of *ward functions.
461      streamInputWardFunctions.str("");
462      inputWardFunctions = "";
463      if(!it->isAutonet() && !it->isArray()){ // Not for autonet and in_array.
464        for(w1=0; w1<it->getInput(); ++w1){   
465          streamInputWardFunctions << " Yting[" << w1 << "],";
466          ENFORCE(streamInputWardFunctions.str().size() < BUFSIZE)("-->buffer not big enough for parameters sending; see your Yao administrator\n");
467        }
468        inputWardFunctions = streamInputWardFunctions.str();
469        if(inputWardFunctions.size())
470          inputWardFunctions.replace(inputWardFunctions.size()-1, 1, " ");
471      }
472    }
473    // Line 2805 Yao8.c dim=1
474    // In function of the dimension ..........................................................*/
475    if(it->getNbAxes()==1){
476      MACRO1_IRMOD(modul, it->getCharAxe1());       aDeclaration << buffer;
477      MACRO1_NOWMOD(modul, it->getCharAxe1());      aDeclaration << buffer;
478      if(it->isTarget()){   // Case: target.
479        if(it->isTempo()){  // Case: target, tempo.
480          MACRO1_ADJUST(modul, spaceOrOperator);  anImplementation << buffer;
481          if(theContext.isIncremental()){ 
482            MACRO1_ADJUDT(modul, spaceOrOperator); anImplementation << buffer;
483            MACRO1_ADJUKT(modul, spaceOrOperator); anImplementation << buffer; 
484          }
485          MACRO1_GCTOTBT(modul, spaceOrOperator);  anImplementation << buffer;
486          if(theContext.isM1qn3()){     
487            MACRO1_VSTAT(modul, spaceOrOperator);  anImplementation << buffer;
488            MACRO1_GSTAT(modul, spaceOrOperator);  anImplementation << buffer;
489            MACRO1_VGRADT(modul, spaceOrOperator);  anImplementation << buffer;
490            if(theContext.isM2qn1()){ 
491              MACRO1_VXINFT(modul, spaceOrOperator);  anImplementation << buffer;
492              MACRO1_VXSUPT(modul, spaceOrOperator);  anImplementation << buffer;
493              MACRO1_VDXMIT(modul, spaceOrOperator);  anImplementation << buffer;
494            }
495            if(theContext.isIncremental()){ 
496              MACRO1_GDELT(modul, spaceOrOperator);  anImplementation << buffer;
497              MACRO1_VDELT(modul, spaceOrOperator);  anImplementation << buffer;
498            }
499          }
500        }else{ // Case: target, not tempo.
501          MACRO1_ADJUS(modul, spaceOrOperator);  anImplementation << buffer;
502          if(theContext.isIncremental()){ 
503            MACRO1_ADJUD(modul, spaceOrOperator);  anImplementation << buffer;
504            MACRO1_ADJUK(modul, spaceOrOperator);  anImplementation << buffer;
505          }
506          MACRO1_GCTOTB(modul, spaceOrOperator);  anImplementation << buffer;
507          if(theContext.isM1qn3()){     
508            MACRO1_VSTA(modul, spaceOrOperator);  anImplementation << buffer; 
509            MACRO1_GSTA(modul, spaceOrOperator);  anImplementation << buffer;
510            MACRO1_VGRAD(modul, spaceOrOperator);  anImplementation << buffer;
511            if(theContext.isM2qn1()){ 
512              MACRO1_VXINF(modul, spaceOrOperator);  anImplementation << buffer; 
513              MACRO1_VXSUP(modul, spaceOrOperator);  anImplementation << buffer;
514              MACRO1_VDXMI(modul, spaceOrOperator);  anImplementation << buffer;
515            }
516            if(theContext.isIncremental()){ 
517              MACRO1_GDEL(modul, spaceOrOperator);  anImplementation << buffer;
518              MACRO1_VDEL(modul, spaceOrOperator);  anImplementation << buffer;
519            }
520          }
521        } // End if tempo else.
522      }// End if target.
523
524      // For state and grad, we have to distinguish between temporized and not temporized.
525      if(it->isTempo()){ // Case of temporized modules (ex: Nit).
526        MACRO1_VALST(modul, 'S', YSTATE);  aDeclaration << buffer;
527        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
528          MACRO1_VALSIT(modul, 'S', YSTATE, w1);  aDeclaration << buffer; 
529          MACRO1_HERESIT(modul, 'S', YSTATE, w1);  aDeclaration << buffer; 
530        }
531        MACRO1_VALST(modul, 'G', YGRAD);                    aDeclaration << buffer; 
532        for (w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
533          MACRO1_VALSIT(modul, 'G', YGRAD, w1);   aDeclaration << buffer;
534          MACRO1_HERESIT(modul, 'G', YGRAD, w1);  aDeclaration << buffer;
535        }
536        MACRO1_TBTOGT(modul, spaceOrOperator);  anImplementation << buffer;
537        // If it's O_GRADTEST or O_VARINCR: we need of the zone delta.
538        if(theContext.isGradTest() || (theContext.isIncremental() && it->isTarget()) ){
539          MACRO1_GEQPDT(modul, spaceOrOperator);  anImplementation << buffer;
540          MACRO1_DEQPST(modul, spaceOrOperator);  anImplementation << buffer;
541          MACRO1_DEQPGT(modul, spaceOrOperator);  anImplementation << buffer;
542          MACRO1_SEQPDT(modul, spaceOrOperator);  anImplementation << buffer;
543          MACRO1_SEQPODT(modul, spaceOrOperator);  anImplementation << buffer;
544          MACRO1_SEQAPTDT(modul, spaceOrOperator);  anImplementation << buffer;
545        }
546        if(theContext.isIncremental()){ 
547          MACRO1_GEQVT(modul, spaceOrOperator);  anImplementation << buffer;
548        }
549        if(theContext.isTool()) {
550          MACRO1_GEQPST(modul, spaceOrOperator);  anImplementation << buffer;
551          MACRO1_GEQPOST(modul, spaceOrOperator);  anImplementation << buffer;
552          MACRO1_STOTBT(modul, spaceOrOperator);  anImplementation << buffer;
553          MACRO1_GTOTBT(modul, spaceOrOperator);  anImplementation << buffer;
554        }
555        bufwrk.str("");
556        bufwrk << "YNBALLTIME_" << it->getTrajectory();
557        MACRO1_RGRADT(modul, spaceOrOperator, bufwrk.str().c_str());  anImplementation << buffer;
558        MACRO1_SETAT(modul, spaceOrOperator, bufwrk.str().c_str());  anImplementation << buffer;
559        MACRO1_YIOUT(modul);  anImplementation << buffer;
560        if(theContext.isGradTest()){
561          if(!it->isNetward() && !it->isAutonet() && !it->isNoward() && !it->isHidjac()){
562            // This is not for NN, for noward and for hidjac modules.
563            MACRO00_GTEST(modul);  anImplementation << buffer;
564            MACRO01_GTESTT(inputWardFunctions.c_str()); anImplementation << buffer;
565          }
566        }
567        if(it->isCout() || it->isTarget()){     
568          MACRO0_OUTOB(modul);  anImplementation << buffer;
569          MACRO1_OUTOBT(modul, spaceOrOperator);  anImplementation << buffer;
570          MACRO9_OUTOB();  anImplementation << buffer;
571        }
572      }else{ // Case of not temporized modules (ex: Bio).
573        MACRO1_VALSG(modul, 'S', YSTATE);  aDeclaration << buffer;
574        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
575          MACRO1_VALSGI(modul, 'S', YSTATE, w1);  aDeclaration << buffer;     
576          MACRO1_HERESGI(modul, 'S', YSTATE, w1); aDeclaration << buffer;
577        }
578        MACRO1_VALSG(modul, 'G', YGRAD);  aDeclaration << buffer;
579        for (w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
580          MACRO1_VALSGI(modul, 'G', YGRAD, w1); aDeclaration << buffer;
581          MACRO1_HERESGI(modul, 'G', YGRAD, w1); aDeclaration << buffer;
582        }
583        MACRO1_TBTOG(modul, spaceOrOperator);  anImplementation << buffer;
584        // If it's O_GRADTEST or O_VARINCR: we need of the zone delta.
585        if (theContext.isGradTest() || (theContext.isIncremental() && it->isTarget())){
586          MACRO1_GEQPD(modul, spaceOrOperator);  anImplementation << buffer;
587          MACRO1_DEQPS(modul, spaceOrOperator);  anImplementation << buffer;
588          MACRO1_DEQPG(modul, spaceOrOperator);  anImplementation << buffer;
589          MACRO1_SEQPD(modul, spaceOrOperator);  anImplementation << buffer;
590          MACRO1_SEQPOD(modul, spaceOrOperator);  anImplementation << buffer;
591          MACRO1_SEQAPTD(modul, spaceOrOperator);  anImplementation << buffer;
592        }
593        if(theContext.isIncremental()){ 
594          MACRO1_GEQV(modul, spaceOrOperator);  anImplementation << buffer;
595        }
596        if(theContext.isTool()){
597          MACRO1_GEQPS(modul, spaceOrOperator);  anImplementation << buffer;
598          MACRO1_GEQPOS(modul, spaceOrOperator);  anImplementation << buffer;
599          MACRO1_STOTB(modul, spaceOrOperator);  anImplementation << buffer;
600          MACRO1_GTOTB(modul, spaceOrOperator);  anImplementation << buffer;
601        }
602        MACRO1_RGRAD(modul, spaceOrOperator);  anImplementation << buffer;
603        MACRO1_SETA(modul, spaceOrOperator);  anImplementation << buffer;
604        MACRO1_YIOTU(modul);  anImplementation << buffer;
605        if(theContext.isGradTest()){
606          if(!it->isNetward() && !it->isAutonet() && !it->isNoward() && !it->isHidjac()){
607            // This is not for NN, for noward and for hidjac modules.
608            MACRO00_GTEST(modul);  anImplementation << buffer;
609            MACRO01_GTEST(inputWardFunctions.c_str()); anImplementation << buffer;
610          }
611        }
612        if(it->isCout() || it->isTarget()){ 
613          MACRO0_OUTOB(modul);  anImplementation << buffer;
614          MACRO1_OUTOB(modul, spaceOrOperator);  anImplementation << buffer;
615          MACRO9_OUTOB();  anImplementation << buffer;
616        }
617      } // End if tempo else
618
619      // Tempo or not tempo:
620      if(it->isTarget()){     
621        MACRO1_VALSG(modul, 'E', YEPSI);  aDeclaration << buffer;
622        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){         
623          MACRO1_VALSGI(modul, 'E', YEPSI, w1);   aDeclaration << buffer;
624        }
625        MACRO1_SEPS(modul, spaceOrOperator);    anImplementation << buffer;
626      }
627      if(it->isNoward()){ 
628        sprintf (buffer, "Yao%s", modul);
629        MACRO1_PTRMOD(buffer, modul, it->getStrYA1SpaceOperator().c_str());     aDeclaration << buffer;
630        MACRO1_CREY(modul, spaceOrOperator);      anImplementation << buffer;
631      }
632      else{     
633        MACRO1_PTRMOD(modul, modul, it->getStrYA1SpaceOperator().c_str());      aDeclaration << buffer;
634        MACRO1_CREU(modul, spaceOrOperator);      anImplementation << buffer;
635      }
636      if(it->isCout() || it->isTarget()){     
637        MACRO1_VALSG(modul, 'W', YWISH);    aDeclaration << buffer;
638        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){               
639          MACRO1_VALSGI(modul, 'W', YWISH, w1);     aDeclaration << buffer;
640          MACRO1_HERESGI(modul, 'W', YWISH, w1);    aDeclaration << buffer;
641        }
642        MACRO1_SWISH(modul, spaceOrOperator);     anImplementation << buffer;
643      }
644      // Line 3022 Yao8.c ------> Begin dim=2
645    }else if(it->getNbAxes()==2){
646      MACRO2_IRMOD(modul, it->getCharAxe1(), it->getCharAxe2());       aDeclaration << buffer;
647      MACRO2_NOWMOD(modul, it->getCharAxe1(), it->getCharAxe2());      aDeclaration << buffer;
648      if(it->isTarget()){   // Case: target.
649        if(it->isTempo()){  // Case: target, tempo.
650          MACRO2_ADJUST(modul, spaceOrOperator);  anImplementation << buffer;
651          if(theContext.isIncremental()){ 
652            MACRO2_ADJUDT(modul, spaceOrOperator); anImplementation << buffer;
653            MACRO2_ADJUKT(modul, spaceOrOperator); anImplementation << buffer; 
654          }
655          MACRO2_GCTOTBT(modul, spaceOrOperator);  anImplementation << buffer;
656          if(theContext.isM1qn3()){     
657            MACRO2_VSTAT(modul, spaceOrOperator);  anImplementation << buffer;
658            MACRO2_GSTAT(modul, spaceOrOperator);  anImplementation << buffer;
659            MACRO2_VGRADT(modul, spaceOrOperator);  anImplementation << buffer;
660            if(theContext.isM2qn1()){ 
661              MACRO2_VXINFT(modul, spaceOrOperator);  anImplementation << buffer;
662              MACRO2_VXSUPT(modul, spaceOrOperator);  anImplementation << buffer;
663              MACRO2_VDXMIT(modul, spaceOrOperator);  anImplementation << buffer;
664            }
665            if(theContext.isIncremental()){ 
666              MACRO2_GDELT(modul, spaceOrOperator);  anImplementation << buffer;
667              MACRO2_VDELT(modul, spaceOrOperator);  anImplementation << buffer;
668            }
669          }
670        }else{ // Case: target, not tempo.
671          MACRO2_ADJUS(modul, spaceOrOperator);  anImplementation << buffer;
672          if(theContext.isIncremental()){ 
673            MACRO2_ADJUD(modul, spaceOrOperator);  anImplementation << buffer;
674            MACRO2_ADJUK(modul, spaceOrOperator);  anImplementation << buffer;
675          }
676          MACRO2_GCTOTB(modul, spaceOrOperator);  anImplementation << buffer;
677          if(theContext.isM1qn3()){     
678            MACRO2_VSTA(modul, spaceOrOperator);  anImplementation << buffer; 
679            MACRO2_GSTA(modul, spaceOrOperator);  anImplementation << buffer;
680            MACRO2_VGRAD(modul, spaceOrOperator);  anImplementation << buffer;
681            if(theContext.isM2qn1()){ 
682              MACRO2_VXINF(modul, spaceOrOperator);  anImplementation << buffer; 
683              MACRO2_VXSUP(modul, spaceOrOperator);  anImplementation << buffer;
684              MACRO2_VDXMI(modul, spaceOrOperator);  anImplementation << buffer;
685            }
686            if(theContext.isIncremental()){ 
687              MACRO2_GDEL(modul, spaceOrOperator);  anImplementation << buffer;
688              MACRO2_VDEL(modul, spaceOrOperator);  anImplementation << buffer;
689            }
690          }
691        } // End if tempo else.
692      }   // End if target.
693
694      //For state and grad, we have to distinguish between temporized and not temporized.
695      if(it->isTempo()){ // Case of temporized modules (ex: Nit).
696        MACRO2_VALST(modul, 'S', YSTATE);  aDeclaration << buffer;
697        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
698          MACRO2_VALSIT(modul, 'S', YSTATE, w1);  aDeclaration << buffer; 
699          MACRO2_HERESIT(modul, 'S', YSTATE, w1);  aDeclaration << buffer; 
700        }
701        MACRO2_VALST(modul, 'G', YGRAD);                    aDeclaration << buffer; 
702        for (w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
703          MACRO2_VALSIT(modul, 'G', YGRAD, w1);   aDeclaration << buffer;
704          MACRO2_HERESIT(modul, 'G', YGRAD, w1);  aDeclaration << buffer;
705        }
706        MACRO2_TBTOGT(modul, spaceOrOperator);  anImplementation << buffer;
707        // If it's O_GRADTEST or O_VARINCR: we need of the zone delta.
708        if(theContext.isGradTest() || (theContext.isIncremental() && it->isTarget()) ){
709          MACRO2_GEQPDT(modul, spaceOrOperator);  anImplementation << buffer;
710          MACRO2_DEQPST(modul, spaceOrOperator);  anImplementation << buffer;
711          MACRO2_DEQPGT(modul, spaceOrOperator);  anImplementation << buffer;
712          MACRO2_SEQPDT(modul, spaceOrOperator);  anImplementation << buffer;
713          MACRO2_SEQPODT(modul, spaceOrOperator);  anImplementation << buffer;
714          MACRO2_SEQAPTDT(modul, spaceOrOperator);  anImplementation << buffer;
715        }
716        if(theContext.isIncremental()){ 
717          MACRO2_GEQVT(modul, spaceOrOperator);  anImplementation << buffer;
718        }
719        if(theContext.isTool()) {
720          MACRO2_GEQPST(modul, spaceOrOperator);  anImplementation << buffer;
721          MACRO2_GEQPOST(modul, spaceOrOperator);  anImplementation << buffer;
722          MACRO2_STOTBT(modul, spaceOrOperator);  anImplementation << buffer;
723          MACRO2_GTOTBT(modul, spaceOrOperator);  anImplementation << buffer;
724        }
725        bufwrk.str("");
726        bufwrk << "YNBALLTIME_" << it->getTrajectory();
727        MACRO2_RGRADT(modul, spaceOrOperator, bufwrk.str().c_str());  anImplementation << buffer;
728        MACRO2_SETAT(modul, spaceOrOperator, bufwrk.str().c_str());  anImplementation << buffer;
729        MACRO2_YIOUT(modul);  anImplementation << buffer;
730        if(theContext.isGradTest()){
731          if(!it->isNetward() && !it->isAutonet() && !it->isNoward() && !it->isHidjac()){
732            // This is not for NN, for noward and for hidjac modules.
733            MACRO00_GTEST(modul);  anImplementation << buffer;
734            MACRO01_GTESTT(inputWardFunctions.c_str()); anImplementation << buffer; // Control!!
735          }
736        }
737        if(it->isCout() || it->isTarget()){     
738          MACRO0_OUTOB(modul);  anImplementation << buffer;
739          MACRO2_OUTOBT(modul, spaceOrOperator);  anImplementation << buffer;
740          MACRO9_OUTOB();  anImplementation << buffer;
741        }
742      }else{ // Case of not temporized modules (ex: Bio).
743        MACRO2_VALSG(modul, 'S', YSTATE);  aDeclaration << buffer;
744        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
745          MACRO2_VALSGI(modul, 'S', YSTATE, w1);  aDeclaration << buffer;     
746          MACRO2_HERESGI(modul, 'S', YSTATE, w1); aDeclaration << buffer;
747        }
748        MACRO2_VALSG(modul, 'G', YGRAD);  aDeclaration << buffer;
749        for (w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
750          MACRO2_VALSGI(modul, 'G', YGRAD, w1); aDeclaration << buffer;
751          MACRO2_HERESGI(modul, 'G', YGRAD, w1); aDeclaration << buffer;
752        }
753        MACRO2_TBTOG(modul, spaceOrOperator);  anImplementation << buffer;
754        // If it's O_GRADTEST or O_VARINCR: we need of the zone delta.
755        if(theContext.isGradTest() || (theContext.isIncremental() && it->isTarget())){
756          MACRO2_GEQPD(modul, spaceOrOperator);  anImplementation << buffer;
757          MACRO2_DEQPS(modul, spaceOrOperator);  anImplementation << buffer;
758          MACRO2_DEQPG(modul, spaceOrOperator);  anImplementation << buffer;
759          MACRO2_SEQPD(modul, spaceOrOperator);  anImplementation << buffer;
760          MACRO2_SEQPOD(modul, spaceOrOperator);  anImplementation << buffer;
761          MACRO2_SEQAPTD(modul, spaceOrOperator);  anImplementation << buffer;
762        }
763        if(theContext.isIncremental()){ 
764          MACRO2_GEQV(modul, spaceOrOperator);  anImplementation << buffer;
765        }
766        if(theContext.isTool()){
767          MACRO2_GEQPS(modul, spaceOrOperator);  anImplementation << buffer;
768          MACRO2_GEQPOS(modul, spaceOrOperator);  anImplementation << buffer;
769          MACRO2_STOTB(modul, spaceOrOperator);  anImplementation << buffer;
770          MACRO2_GTOTB(modul, spaceOrOperator);  anImplementation << buffer;
771        }
772        MACRO2_RGRAD(modul, spaceOrOperator);  anImplementation << buffer;
773        MACRO2_SETA(modul, spaceOrOperator);  anImplementation << buffer;
774        MACRO2_YIOTU(modul);  anImplementation << buffer;
775        if(theContext.isGradTest()){
776          if(!it->isNetward() && !it->isAutonet() && !it->isNoward() && !it->isHidjac()){
777            // This is not for NN, for noward and for hidjac modules.
778            MACRO00_GTEST(modul);  anImplementation << buffer;
779            MACRO01_GTEST(inputWardFunctions.c_str()); anImplementation << buffer; // Control!!
780          }
781        }
782        if(it->isCout() || it->isTarget()){ 
783          MACRO0_OUTOB(modul);  anImplementation << buffer;
784          MACRO2_OUTOB(modul, spaceOrOperator);  anImplementation << buffer;
785          MACRO9_OUTOB();  anImplementation << buffer;
786        }
787      } // End if tempo else.
788
789      // Tempo or not tempo:
790      if(it->isTarget()){     
791        MACRO2_VALSG(modul, 'E', YEPSI);  aDeclaration << buffer;
792        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){         
793          MACRO2_VALSGI(modul, 'E', YEPSI, w1);   aDeclaration << buffer;
794        }
795        MACRO2_SEPS(modul, spaceOrOperator);    anImplementation << buffer;
796      }
797      if(it->isNoward()){ 
798        sprintf (buffer, "Yao%s", modul);
799        MACRO2_PTRMOD(buffer, modul, it->getStrYA1SpaceOperator().c_str(), it->getStrYA2SpaceOperator().c_str());       aDeclaration << buffer;
800        MACRO2_CREY(modul, spaceOrOperator);      anImplementation << buffer;
801      }
802      else{     
803        MACRO2_PTRMOD(modul, modul, it->getStrYA1SpaceOperator().c_str(), it->getStrYA2SpaceOperator().c_str());        aDeclaration << buffer;
804        MACRO2_CREU(modul, spaceOrOperator);      anImplementation << buffer;
805      }
806      if(it->isCout() || it->isTarget()){     
807        MACRO2_VALSG(modul, 'W', YWISH);    aDeclaration << buffer;
808        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){               
809          MACRO2_VALSGI(modul, 'W', YWISH, w1);     aDeclaration << buffer;
810          MACRO2_HERESGI(modul, 'W', YWISH, w1);    aDeclaration << buffer;
811        }
812        MACRO2_SWISH(modul, spaceOrOperator);     anImplementation << buffer;
813      }
814      // Line 3239 Yao8.c ------> Begin dim=3.
815    }else if(it->getNbAxes()==3){
816      MACRO3_IRMOD(modul);       aDeclaration << buffer;
817      MACRO3_NOWMOD(modul);      aDeclaration << buffer;
818      if(it->isTarget()){   // Case: target.
819        if(it->isTempo()){  // Case: target, tempo.
820          MACRO3_ADJUST(modul, spaceOrOperator);  anImplementation << buffer;
821          if(theContext.isIncremental()){ 
822            MACRO3_ADJUDT(modul, spaceOrOperator); anImplementation << buffer;
823            MACRO3_ADJUKT(modul, spaceOrOperator); anImplementation << buffer; 
824          }
825          MACRO3_GCTOTBT(modul, spaceOrOperator);  anImplementation << buffer;
826          if(theContext.isM1qn3()){     
827            MACRO3_VSTAT(modul, spaceOrOperator);  anImplementation << buffer;
828            MACRO3_GSTAT(modul, spaceOrOperator);  anImplementation << buffer;
829            MACRO3_VGRADT(modul, spaceOrOperator);  anImplementation << buffer;
830            if(theContext.isM2qn1()){ 
831              MACRO3_VXINFT(modul, spaceOrOperator);  anImplementation << buffer;
832              MACRO3_VXSUPT(modul, spaceOrOperator);  anImplementation << buffer;
833              MACRO3_VDXMIT(modul, spaceOrOperator);  anImplementation << buffer;
834            }
835            if(theContext.isIncremental()){ 
836              MACRO3_GDELT(modul, spaceOrOperator);  anImplementation << buffer;
837              MACRO3_VDELT(modul, spaceOrOperator);  anImplementation << buffer;
838            }
839          }
840        }else{ // Case: target, not tempo.
841          MACRO3_ADJUS(modul, spaceOrOperator);  anImplementation << buffer;
842          if(theContext.isIncremental()){ 
843            MACRO3_ADJUD(modul, spaceOrOperator);  anImplementation << buffer;
844            MACRO3_ADJUK(modul, spaceOrOperator);  anImplementation << buffer;
845          }
846          MACRO3_GCTOTB(modul, spaceOrOperator);  anImplementation << buffer;
847          if(theContext.isM1qn3()){     
848            MACRO3_VSTA(modul, spaceOrOperator);  anImplementation << buffer; 
849            MACRO3_GSTA(modul, spaceOrOperator);  anImplementation << buffer;
850            MACRO3_VGRAD(modul, spaceOrOperator);  anImplementation << buffer;
851            if(theContext.isM2qn1()){ 
852              MACRO3_VXINF(modul, spaceOrOperator);  anImplementation << buffer; 
853              MACRO3_VXSUP(modul, spaceOrOperator);  anImplementation << buffer;
854              MACRO3_VDXMI(modul, spaceOrOperator);  anImplementation << buffer;
855            }
856            if(theContext.isIncremental()){ 
857              MACRO3_GDEL(modul, spaceOrOperator);  anImplementation << buffer;
858              MACRO3_VDEL(modul, spaceOrOperator);  anImplementation << buffer;
859            }
860          }
861        } // End if tempo else.
862      }   // End if target.
863
864      // For state and grad, we have to distinguish between temporized and not temporized.
865      if(it->isTempo()){ // Case of temporized modules (ex: Nit).
866        MACRO3_VALST(modul, 'S', YSTATE);  aDeclaration << buffer;
867        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
868          MACRO3_VALSIT(modul, 'S', YSTATE, w1);  aDeclaration << buffer; 
869          MACRO3_HERESIT(modul, 'S', YSTATE, w1);  aDeclaration << buffer; 
870        }
871        MACRO3_VALST(modul, 'G', YGRAD);                    aDeclaration << buffer; 
872        for (w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
873          MACRO3_VALSIT(modul, 'G', YGRAD, w1);   aDeclaration << buffer;
874          MACRO3_HERESIT(modul, 'G', YGRAD, w1);  aDeclaration << buffer;
875        }
876        MACRO3_TBTOGT(modul, spaceOrOperator);  anImplementation << buffer;
877        // If it's O_GRADTEST or O_VARINCR: we need of the zone delta.
878        if(theContext.isGradTest() || (theContext.isIncremental() && it->isTarget()) ){
879          MACRO3_GEQPDT(modul, spaceOrOperator);  anImplementation << buffer;
880          MACRO3_DEQPST(modul, spaceOrOperator);  anImplementation << buffer;
881          MACRO3_DEQPGT(modul, spaceOrOperator);  anImplementation << buffer;
882          MACRO3_SEQPDT(modul, spaceOrOperator);  anImplementation << buffer;
883          MACRO3_SEQPODT(modul, spaceOrOperator);  anImplementation << buffer;
884          MACRO3_SEQAPTDT(modul, spaceOrOperator);  anImplementation << buffer;
885        }
886        if(theContext.isIncremental()){ 
887          MACRO3_GEQVT(modul, spaceOrOperator);  anImplementation << buffer;
888        }
889        if(theContext.isTool()) {
890          MACRO3_GEQPST(modul, spaceOrOperator);  anImplementation << buffer;
891          MACRO3_GEQPOST(modul, spaceOrOperator);  anImplementation << buffer;
892          MACRO3_STOTBT(modul, spaceOrOperator);  anImplementation << buffer;
893          MACRO3_GTOTBT(modul, spaceOrOperator);  anImplementation << buffer;
894        }
895        bufwrk.str("");
896        bufwrk << "YNBALLTIME_" << it->getTrajectory();
897        MACRO3_RGRADT(modul, spaceOrOperator, bufwrk.str().c_str());  anImplementation << buffer;
898        MACRO3_SETAT(modul, spaceOrOperator, bufwrk.str().c_str());  anImplementation << buffer;
899        MACRO3_YIOUT(modul);  anImplementation << buffer;
900        if(theContext.isGradTest()){
901          if(!it->isNetward() && !it->isAutonet() && !it->isNoward() && !it->isHidjac()){
902            // This is not for NN, for noward and for hidjac modules.
903            MACRO00_GTEST(modul);  anImplementation << buffer;
904            MACRO01_GTESTT(inputWardFunctions.c_str()); anImplementation << buffer; // Control!!
905          }
906        }
907        if(it->isCout() || it->isTarget()){     
908          MACRO0_OUTOB(modul);  anImplementation << buffer;
909          MACRO3_OUTOBT(modul, spaceOrOperator);  anImplementation << buffer;
910          MACRO9_OUTOB();  anImplementation << buffer;
911        }
912      }else{ // Case of not temporized modules (ex: Bio).
913        MACRO3_VALSG(modul, 'S', YSTATE);  aDeclaration << buffer;
914        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
915          MACRO3_VALSGI(modul, 'S', YSTATE, w1);  aDeclaration << buffer;     
916          MACRO3_HERESGI(modul, 'S', YSTATE, w1); aDeclaration << buffer;
917        }
918        MACRO3_VALSG(modul, 'G', YGRAD);  aDeclaration << buffer;
919        for (w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){
920          MACRO3_VALSGI(modul, 'G', YGRAD, w1); aDeclaration << buffer;
921          MACRO3_HERESGI(modul, 'G', YGRAD, w1); aDeclaration << buffer;
922        }
923        MACRO3_TBTOG(modul, spaceOrOperator);  anImplementation << buffer;
924        // If it's O_GRADTEST or O_VARINCR: we need of the zone delta.
925        if(theContext.isGradTest() || (theContext.isIncremental() && it->isTarget())){
926          MACRO3_GEQPD(modul, spaceOrOperator);  anImplementation << buffer;
927          MACRO3_DEQPS(modul, spaceOrOperator);  anImplementation << buffer;
928          MACRO3_DEQPG(modul, spaceOrOperator);  anImplementation << buffer;
929          MACRO3_SEQPD(modul, spaceOrOperator);  anImplementation << buffer;
930          MACRO3_SEQPOD(modul, spaceOrOperator);  anImplementation << buffer;
931          MACRO3_SEQAPTD(modul, spaceOrOperator);  anImplementation << buffer;
932        }
933        if(theContext.isIncremental()){ 
934          MACRO3_GEQV(modul, spaceOrOperator);  anImplementation << buffer;
935        }
936        if(theContext.isTool()){
937          MACRO3_GEQPS(modul, spaceOrOperator);  anImplementation << buffer;
938          MACRO3_GEQPOS(modul, spaceOrOperator);  anImplementation << buffer;
939          MACRO3_STOTB(modul, spaceOrOperator);  anImplementation << buffer;
940          MACRO3_GTOTB(modul, spaceOrOperator);  anImplementation << buffer;
941        }
942        MACRO3_RGRAD(modul, spaceOrOperator);  anImplementation << buffer;
943        MACRO3_SETA(modul, spaceOrOperator);  anImplementation << buffer;
944        MACRO3_YIOTU(modul);  anImplementation << buffer;
945        if(theContext.isGradTest()){
946          if(!it->isNetward() && !it->isAutonet() && !it->isNoward() && !it->isHidjac()){
947            // This is not for NN, for noward and for hidjac modules.
948            MACRO00_GTEST(modul);  anImplementation << buffer;
949            MACRO01_GTEST(inputWardFunctions.c_str()); anImplementation << buffer; // Control!!
950          }
951        }
952        if(it->isCout() || it->isTarget()){ 
953          MACRO0_OUTOB(modul);  anImplementation << buffer;
954          MACRO3_OUTOB(modul, spaceOrOperator);  anImplementation << buffer;
955          MACRO9_OUTOB();  anImplementation << buffer;
956        }
957      } // End if tempo else.
958
959      // Tempo or not tempo:
960      if(it->isTarget()){     
961        MACRO3_VALSG(modul, 'E', YEPSI);  aDeclaration << buffer;
962        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){         
963          MACRO3_VALSGI(modul, 'E', YEPSI, w1);   aDeclaration << buffer;
964        }
965        MACRO3_SEPS(modul, spaceOrOperator);    anImplementation << buffer;
966      }
967      if(it->isNoward()){ 
968        sprintf (buffer, "Yao%s", modul);
969        MACRO3_PTRMOD(buffer, modul, it->getStrYA1SpaceOperator().c_str(), it->getStrYA2SpaceOperator().c_str(), it->getStrYA3SpaceOperator().c_str());
970        aDeclaration << buffer;
971        MACRO3_CREY(modul, spaceOrOperator);      anImplementation << buffer;
972      }
973      else{     
974        MACRO3_PTRMOD(modul, modul, it->getStrYA1SpaceOperator().c_str(), it->getStrYA2SpaceOperator().c_str(), it->getStrYA3SpaceOperator().c_str());
975        aDeclaration << buffer;
976        MACRO3_CREU(modul, spaceOrOperator);      anImplementation << buffer;
977      }
978      if(it->isCout() || it->isTarget()){     
979        MACRO3_VALSG(modul, 'W', YWISH);    aDeclaration << buffer;
980        for(w1=0; w1<it->getOutput() && w1<NB_MAX_MACRO; ++w1){               
981          MACRO3_VALSGI(modul, 'W', YWISH, w1);     aDeclaration << buffer;
982          MACRO3_HERESGI(modul, 'W', YWISH, w1);    aDeclaration << buffer;
983        }
984        MACRO3_SWISH(modul, spaceOrOperator);     anImplementation << buffer;
985      }
986    } // End dim 3.
987  }   // End for each module.
988
989  // Line 3462 Yao8.c   
990  // SECOND PART: -------------------------------------------generation of GENERAL elements.
991  // --------------------------------------------------------------------------------------
992
993  // 2.-1.0) Creation of the functions YwishEQPstate_modul (complement to the first part).
994  // --------------------------------------------------------------------------------------
995  if(theContext.isGradTest())
996    for(Table<Modul>::iterator mod=aModuleTable.begin(); mod != aModuleTable.end(); mod++){
997      if(!mod->getCovt().empty() && mod->getCovt() != mod->getName()){ 
998        w2 = mod->getNbAxes();    // => w2 = is the dimension of the module: number of axes.
999        if(mod->getTime()){       // Case tempo (for the out module).
1000               if(w2==1) MACRO1_WEQPST(mod->getName().c_str(), mod->getSpaceOrOperator().c_str());         
1001          else if(w2==2) MACRO2_WEQPST(mod->getName().c_str(), mod->getSpaceOrOperator().c_str());         
1002          else            MACRO3_WEQPST(mod->getName().c_str(), mod->getSpaceOrOperator().c_str());         
1003        }else{ // => Non tempo.
1004               if(w2==1) MACRO1_WEQPS(mod->getName().c_str(), mod->getSpaceOrOperator().c_str());         
1005               //if(w2==1) MACRO1_WEQPS(mod->getCovt().c_str(), mod->getSpaceOrOperator().c_str());         
1006          else if(w2==2) MACRO2_WEQPS(mod->getName().c_str(), mod->getSpaceOrOperator().c_str());         
1007          else            MACRO3_WEQPS(mod->getName().c_str(), mod->getSpaceOrOperator().c_str());         
1008        }
1009        anImplementation << buffer;
1010      }
1011    }
1012/*
1013  if(theContext.isGradTest())
1014    for(Table<Modul>::iterator mod=aModuleTable.begin(); mod != aModuleTable.end(); mod++){
1015      if(!mod->getCovt().empty() && mod->getCovt() != mod->getName()){ 
1016        Modul *covt;
1017        covt = aModuleTable.find(mod->getCovt());
1018        w2 = covt->getNbAxes();   // => w2 = is the dimension of the covariance module: number of axes.
1019        if(covt->getTime()){      // Case tempo (for the out module).
1020               if(w2==1) MACRO1_WEQPST(covt->getName().c_str(), covt->getSpaceOrOperator().c_str());         
1021          else if(w2==2) MACRO2_WEQPST(covt->getName().c_str(), covt->getSpaceOrOperator().c_str());         
1022          else           MACRO3_WEQPST(covt->getName().c_str(), covt->getSpaceOrOperator().c_str());         
1023        }else{ // => Non tempo.
1024               if(w2==1) MACRO1_WEQPS(covt->getName().c_str(), covt->getSpaceOrOperator().c_str());         
1025          else if(w2==2) MACRO2_WEQPS(covt->getName().c_str(), covt->getSpaceOrOperator().c_str());         
1026          else           MACRO3_WEQPS(covt->getName().c_str(), covt->getSpaceOrOperator().c_str());         
1027        }
1028        anImplementation << buffer;
1029      }
1030    }
1031
1032*/
1033
1034
1035  // 3.0.0) Creation of ... for m1qn3 (and m2qn1 if required).
1036  //---------------------------------------------------------
1037  aDeclaration << "#define  YSIZEPB   " << sizeM1qn3 << "//sum of the number of states (output) of all targets\n";
1038  if(theContext.isM1qn3()){ 
1039    aDeclaration << "\n//€ € € € FOR M1QN3 € € € € € € € € € € € € € € € € € € € € € € €\n"; 
1040    aDeclaration << "float   Y3x[YSIZEPB]; //table for the states of targets \n";
1041    aDeclaration << "float   Y3g[YSIZEPB]; //table for the gradients of targets\n";
1042    // Dimension of the zone rz.
1043    Y3SizeRz2=sizeM1qn3*(sizeM1qn3+9)/2; // rz dimension for m1qn2.
1044    Y3SizeRz3=4*sizeM1qn3 + atoi(theConstantTable.find(static_cast<string>("Y3_M"))->getText().c_str()) * (2*sizeM1qn3+1); // rz dimension for m1qn3.
1045    if(theContext.isM2qn1() && Y3SizeRz2>Y3SizeRz3) // If m2qn1 demanded, we take the max dimension between m2qn1 et m1qn3.
1046      aDeclaration << "#define Y3_SZ_RZ   " << Y3SizeRz2 << "  //rz dimension\n"; 
1047    else  aDeclaration << "#define Y3_SZ_RZ   " << Y3SizeRz3 << "  //rz dimension\n"; 
1048    aDeclaration << "float   Y3rz[Y3_SZ_RZ];\n";
1049    if(theContext.isM2qn1()){ 
1050      aDeclaration << "float         Y3xinf[YSIZEPB]; //down borne table of target's states \n";
1051      aDeclaration << "float   Y3xsup[YSIZEPB]; //up borne table of target's state \n";
1052      aDeclaration << "#define Y3_SZ_IZ   " <<  2*sizeM1qn3+1 << "  //iz dimension\n"; // m2qn1 is always >= m1qn3
1053      aDeclaration << "float   Y3dxmin[YSIZEPB]; //resolution table for the vector to be controlled \n";
1054    }else{ // Case only m1qn3.
1055      aDeclaration << "#define Y3_SZ_IZ   5  //iz dimension\n"; 
1056      aDeclaration << "float   Y3dxmin[1]; //resolution scalar for the vector to be controlled \n";
1057    }
1058  }
1059
1060  // 2.0.1) Creation d'objets globaux.
1061  //-------------------------------------------------
1062  aDeclaration << "\n/*------- GENERATION of global objects ------------------------*/\n";
1063  aDeclaration << "#define YSIZECO             " << sizeCout << " //size of modules cout (atempo)(event if not in order !)\n";
1064  aDeclaration << "#define YMAX_NBI        " << maxNbInput << " //max input number of a module \n";
1065  aDeclaration << "#define YMAX_NBS        " << maxNbOutput << " //max output number of a module\n";
1066  aDeclaration << "#define YMAX_JAC_NBI    " << maxNbJacobianInput  << " //max number of input for the jacobian (Yjac) \n";
1067  aDeclaration << "#define YMAX_JAC_NBS    " << maxNbJacobianOutput << " //max number of output for the jacobian (Yjac) \n";
1068  aDeclaration << setw(6) <<left<< theContext.getReal() << "  Yting[YMAX_NBI];                //max table for a global and common inputs number\n";
1069  aDeclaration << setw(6) <<left<< theContext.getReal() << "  Yjac[YMAX_JAC_NBS][YMAX_JAC_NBI]; //max table for a global and common jacobian\n";
1070  for(w1=0; w1<maxNbJacobianOutput && w1<NB_MAX_MACRO; ++w1)
1071    for(w2=0; w2<maxNbJacobianInput && w2<NB_MAX_MACRO; ++w2){ 
1072      aDeclaration << "#define YJ" << w1+1 << "I" << w2+1 << "  Yjac[" << w1 << "][" << w2 << "] \n";
1073    }
1074  aDeclaration << setw(6) <<left<< theContext.getReal() << "  Ytbeta[YMAX_NBI];               //max table of global and common beta\n";
1075 
1076  // For the parallelization
1077  if(theContext.isParallel()){
1078    aDeclaration << "#ifdef _OPENMP" << endl;
1079    aDeclaration << "#pragma omp threadprivate(Yting,Yjac,Ytbeta)  // Yting is a private global variable in the case of parallelism" << endl;
1080    aDeclaration << "#endif" << endl;
1081  } 
1082
1083
1084  // 2.0.2) Code concerning Neural Network (NN).
1085  //..............................................................
1086  if(theNeuronTable.size()){ // We generate a table of Neural Network.
1087    aDeclaration << "\n/*------- GENERATION D'UN TABLEAU d'ACCES AUX RNET --------*/\n";
1088    aDeclaration << "#define YNBNET         " << theNeuronTable.size() << " \n";
1089    aDeclaration << "struct Yst_netward YTabNet[" << theNeuronTable.size() << "] = {\n";
1090    for(Table<Neuron>::iterator it=theNeuronTable.begin(); it < theNeuronTable.end(); it++)
1091      aDeclaration << "\t{\"" << it->getName() << "\", 0, " << it->getInDegree() << ", " << it->getOutDegree() << ", 0, NULL, SigLin},\n";
1092    aDeclaration << "};\n";
1093    aDeclaration << "#include\t\t\"Dynnet.h\"\n";
1094  }
1095  // Line 3358 Yao8.c
1096
1097  // 2.0.3) Creation of the structure of one obs (observation) in Y1.
1098  //----------------------------------------------------------------
1099  aDeclaration << "\n/*------- SOME OTHER AUTOMATIC GENERATION ------------------*/\n";
1100  if(theContext.isIncremental()){
1101    aDeclaration << "\nstruct Yst_obs {\n  int   time;\n  int   imod;\n  int   smod;\n  int   iaxe;";
1102    aDeclaration << "\n  int   jaxe;\n  int  kaxe;\n  YREAL vobs;\n  YREAL qtea;\n};";
1103  }
1104  else{ 
1105    aDeclaration << "\nstruct Yst_obs {\n  int   time;\n  int   imod;\n  int   smod;\n  int   iaxe;";
1106    aDeclaration << "\n  int   jaxe;\n  int   kaxe;\n  YREAL vobs;\n};";
1107  }
1108  aDeclaration << "\nstruct Yst_obs Yaobs;";
1109  aDeclaration << "\nint Yobs_insert(struct Yst_obs *aobs);\n";
1110
1111  // 2.0.4) Necessary prototypes.
1112  //-------------------------------------------------------
1113  aDeclaration << "\n/*------- GENERATION of NECESSARY PROTOTYPES -------------*/\n";
1114  aDeclaration << theContext.getReal() << " Ycostdiff(" << theContext.getReal() << " dinov, " << theContext.getReal()<< " dcov);\n"; // Opera.
1115
1116  // 2.1) Automatic creation of Yao modules.
1117  //-----------------------------------------------------------------------
1118  //(nb pour le moment : dans le meme Y1.h)
1119  aDeclaration << "\n/*------- AUTOMATIC GENERATION of YaoModul class ----------*/\n";
1120  createYaoModules(aDeclaration);
1121  // Line 3587 Yao8.c
1122  // 2.2) prototypes of auto-fonctions, charles comment:
1123  // (est-ce vraiment toujours utile? --> utile pour les fonctions que l'on veut rendre accessibles au realisateur).
1124  //-----------------------------------------------------------------------------------------------------------------
1125  aDeclaration << "\n//€ € € € PROTOTYPES of AUTO-FUNCTIONS € € € € € € € € € € €\n";
1126  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1127    aDeclaration << "void Yrazgrad_" << mod->getName() << "(); \nvoid Ysetstate_" << mod->getName() << "(); \n";
1128    if(mod->isTarget()){       
1129      aDeclaration << "void Ysetepsi_" << mod->getName() << "(); \nvoid Yadjust_" << mod->getName() << "(); \n";
1130      aDeclaration << "void Y3getstate_" << mod->getName() << "(float x[]); \nvoid Y3valstate_" << mod->getName() << "(); \nvoid Y3valgrad_" << mod->getName() << "(float g[]); ";
1131      if(theContext.isM2qn1())
1132        aDeclaration << "\nvoid Y3valxinf_" << mod->getName() << "(); \nvoid Y3valxsup_" << mod->getName() << "(); \nvoid Y3valdxmin_" << mod->getName() << "(); \n";
1133    }
1134  }
1135
1136  // 2.3.1) Creation of the function Ycreate_all .........................
1137  anImplementation << "\nvoid Ycreate_all () \n{";
1138  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1139    anImplementation << "\n\t Ycreate_" << mod->getName() << " ();";
1140  anImplementation << "\n}";
1141
1142  // 2.3.2) Computation of cout and gradient; standard case.
1143  // Charles comment: que diff dans zone wish = state - obs.
1144  anImplementation << "\nvoid Ywishdiff_all (char *nmmod, int Yws, int Yw1, int Yw2, int Yw3, int Ywt, YREAL vobs) \n{\t";
1145  anImplementation << "\n\t if(1==0);";
1146  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){       
1147    if(mod->isCout() || mod->isTarget()){       
1148      anImplementation << "\n\t else if (strcmp(nmmod, \"" << mod->getName() << "\") == 0)";
1149      if(mod->getNbAxes()==1){     
1150        if(mod->getTime())              // Tempo.
1151          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1) = YS_" << mod->getName() << "(Yws, Yw1, Ywt) - vobs;";
1152        else                        // Non tempo.
1153          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1) = YS_" << mod->getName() << "(Yws, Yw1) - vobs;";
1154      }else if(mod->getNbAxes()==2){     
1155        if(mod->getTime())              // Tempo.
1156          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1, Yw2) = YS_" << mod->getName() << "(Yws, Yw1, Yw2, Ywt) - vobs;";
1157        else                            // Non tempo.
1158          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1, Yw2) = YS_" << mod->getName() << "(Yws, Yw1, Yw2) - vobs;";
1159      }else if (mod->getNbAxes()==3){     
1160        if(mod->getTime())              // Tempo.
1161          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3) = YS_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3, Ywt) - vobs;";
1162        else         // Non tempo.
1163          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3) = YS_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3) - vobs;";
1164      }
1165    }
1166  }
1167  anImplementation << "\n}";
1168
1169  // Computation of cout and gradient with the difference (wish = state - obs) of the module cout
1170  // and eventually also the result of the computation of covariance (Ystate of caltype B, R or K).
1171  anImplementation << "\nvoid Ycostwishdiff_all (char *nmmod, int Yws, int Yw1, int Yw2, int Yw3, int Ywt) \n{\t";
1172  anImplementation << "\n\t if(1==0);";
1173  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){       
1174    if(mod->isCout() || mod->isTarget()){ 
1175      if(mod->getCovt() == mod->getName()) c1='W';      // The covt module is himself.
1176      else c1='S';                                      // The covt module is another module.
1177      anImplementation << "\n\t else if (strcmp(nmmod, \"" << mod->getName() << "\") == 0)";
1178      if(mod->getNbAxes()==1){     
1179        if(mod->getTime()){     // Tempo.
1180          anImplementation  << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Ywt) += Ycostdiff(YW_"
1181                            << mod->getName() << "(Yws, Yw1), Y" << c1 << "_" << mod->getCovt() << "(Yws, Yw1));";
1182        }else{              // Non tempo.
1183          anImplementation  << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1) += Ycostdiff(YW_"
1184                            << mod->getName() << "(Yws, Yw1), Y" << c1 << "_" << mod->getCovt() << "(Yws, Yw1));";
1185        }
1186      }else if (mod->getNbAxes()==2){     
1187        if(mod->getTime()){         // Tempo.
1188          anImplementation  << "\n\t\t\t\t      YG_" << mod->getName() << "(Yws, Yw1, Yw2, Ywt) += Ycostdiff(YW_"
1189                            << mod->getName() << "(Yws, Yw1, Yw2), Y" << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2));";
1190        }else{              // Non tempo.
1191          anImplementation  <<  "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Yw2) += Ycostdiff(YW_"
1192                            << mod->getName() << "(Yws, Yw1, Yw2), Y" << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2));";
1193        }
1194      }else if(mod->getNbAxes()==3){     
1195        if(mod->getTime()){    // Tempo.
1196          anImplementation  << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3, Ywt) += Ycostdiff(YW_"
1197                            << mod->getName() << "(Yws, Yw1, Yw2, Yw3), Y" << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2, Yw3));"; 
1198        }else{            // Non tempo.
1199          anImplementation  << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3) += Ycostdiff(YW_"
1200                            << mod->getName() << "(Yws, Yw1, Yw2, Yw3), Y" << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2, Yw3));";
1201        }
1202      }
1203    }
1204  } // End for.
1205  anImplementation << "\n}";
1206
1207  if(theContext.isIncremental()){
1208    // Computation of cout and gradient; incremental case. Charles comment:
1209    // 1) calcul de : d* alias dstar i.e. la quantite adjointe (qtea)  qtea = f(Ygrad, Ystate, obs) =  M'(Xk).dx - (y° - M(Xk))
1210    // avec Ygrad=M'(Xk).dx : c'est le resultat du LT sur les points de calcul du cout
1211    // Yo : ce sont les obs, et M(Xk) correspond aux etats i.e. a Ystate
1212    anImplementation << "\nvoid Yc_dstar_all (int indic, char *nmmod, int nout, int iaxe, int jaxe, ";
1213    anImplementation << "int kaxe, int apdt, int pdt, YREAL *vobs, YREAL *qtea) \n{\t\n\t if(1==0);";
1214    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){       
1215      if(mod->isCout() || mod->isTarget()){       
1216        anImplementation << "\n\t else if (strcmp(nmmod, \"" << mod->getName() << "\") == 0)";
1217        if(mod->getNbAxes()==1){     
1218          if(mod->getTime()){           // Tempo.
1219            anImplementation << "\n\t\t\t\t *qtea = YG_" << mod->getName() << "(nout, iaxe, pdt) - (*vobs - YS_";
1220            anImplementation << mod->getName() << "(nout, iaxe, pdt));";
1221          }else                         // Non tempo.
1222            anImplementation << "\n\t\t\t\t *qtea = YG_" << mod->getName() << "(nout, iaxe) - (*vobs - YS_" << mod->getName() << "(nout, iaxe));";
1223        }else if(mod->getNbAxes()==2){     
1224          if(mod->getTime()){           // Tempo.
1225            anImplementation << "\n\t\t\t\t *qtea = YG_" << mod->getName();
1226            anImplementation << "(nout, iaxe, jaxe, pdt) - (*vobs - YS_" << mod->getName() << "(nout, iaxe,jaxe, pdt));";
1227          }else{                                //Non tempo.
1228            anImplementation << "\n\t\t\t\t *qtea = YG_" << mod->getName();
1229            anImplementation << "(nout, iaxe, jaxe) - (*vobs - YS_" << mod->getName() << "(nout, iaxe, jaxe));";
1230          } 
1231        }else if(mod->getNbAxes()==3){     
1232          if(mod->getTime()){           // Tempo.
1233            anImplementation << "\n\t\t\t\t *qtea = YG_" << mod->getName();
1234            anImplementation << "s(nout, iaxe, jaxe, kaxe, pdt) - (*vobs - YS_" << mod->getName() << "(nout,iaxe, jaxe, kaxe, pdt));";
1235          }else{                            // Non tempo.
1236            anImplementation << "\n\t\t\t\t *qtea = YG_" << mod->getName();
1237            anImplementation << "(nout, iaxe, jaxe, kaxe) - (*vobs - YS_" << mod->getName() << "(nout, iaxe, jaxe, kaxe));";
1238          }
1239        }
1240      }
1241    }
1242    anImplementation << "\n}";
1243
1244    // 2) Charles comment: que qtea (deja=grad-(obs-state)) dans zone wish.
1245    anImplementation << "\nvoid Ywishqtea_all (char *nmmod, int Yws, int Yw1, int Yw2, int Yw3, YREAL qtea) \n{\t";
1246    anImplementation << "\n\t if(1==0);";
1247    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){       
1248      if(mod->isCout() || mod->isTarget()){       
1249        anImplementation << "\n\t else if (strcmp(nmmod, \"" << mod->getName() << "\") == 0)";
1250        if(mod->getNbAxes()==1){     
1251          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1) = qtea;";
1252        }else if(mod->getNbAxes()==2){     
1253          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1, Yw2) = qtea;";
1254        }else if(mod->getNbAxes()==3){     
1255          anImplementation << "\n\t\t\t\t YW_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3) = qtea;";
1256        }
1257      }
1258    }
1259    anImplementation << "\n}";
1260
1261    // Charles comment: calcul du cout et du gradient avec qtea (deja= deja=grad-(obs-state)) du module cout
1262    // et eventuellement aussi avec le resultat d'un calcul de covariance (Ystate de caltype B, R ou K).
1263    anImplementation << "\nvoid Ycostwishqtea_all (char *nmmod, int Yws, int Yw1, int Yw2, int Yw3, int Ywt, YREAL qtea) \n{\t";
1264    anImplementation << "\n\t if(1==0);";
1265    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){       
1266      if(mod->isCout() || mod->isTarget()){ 
1267        if(mod->getCovt() == mod->getName()) c1='W';      // With himself.
1268        else c1='S';                                      // The covt module associated.
1269        anImplementation << "\n\t else if (strcmp(nmmod, \"" << mod->getName() << "\") == 0)";
1270        if(mod->getNbAxes()==1){     
1271          if(mod->getTime()){                 // Tempo.
1272            anImplementation << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Ywt) += Ycostdiff(qtea, Y";
1273            anImplementation << c1 << "_" << mod->getCovt() << "(Yws, Yw1));";
1274          }else{                                  // Non tempo.
1275            anImplementation << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1) += Ycostdiff(qtea, Y";
1276            anImplementation << c1 << "_" << mod->getCovt() << "(Yws, Yw1));";
1277          }
1278        }else if(mod->getNbAxes()==2){     
1279          if(mod->getTime()){                 // Tempo.
1280            anImplementation << "\n\t\t\t\t      YG_" << mod->getName() << "(Yws, Yw1, Yw2, Ywt) += Ycostdiff(qtea, Y";
1281            anImplementation << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2));";
1282          }else{                                      // Non tempo.
1283            anImplementation << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Yw2) += Ycostdiff(qtea, Y";
1284            anImplementation << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2));";
1285          }
1286        }else if(mod->getNbAxes()==3){     
1287          if(mod->getTime()){                 // Tempo.
1288            anImplementation << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3, Ywt) += Ycostdiff(qtea, Y";
1289            anImplementation << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2,Yw3));";
1290          }else{                                      // Non tempo.
1291            anImplementation << "\n\t\t\t\t YG_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3) += Ycostdiff(qtea, Y";
1292            anImplementation << c1 << "_" << mod->getCovt() << "(Yws, Yw1, Yw2, Yw3));";
1293          }
1294        }
1295      }
1296    }
1297    anImplementation << "\n}";
1298  }// End incremental.
1299
1300  // 2.3.3) Creation of the function Youtoobs_mod for the Observations.
1301  anImplementation << "\nvoid Youtoobs_mod(YioKind yiokind, char *nmmod, int numout, int pdt, int arbpdt)\n{\n \t if(1==0);";
1302  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){       
1303    if(mod->isCout() || mod->isTarget()){
1304      anImplementation << "\n \t else if (strcmp(nmmod, \"" << mod->getName(); 
1305      anImplementation << "\") == 0) Youtoobs_" << mod->getName() << "(yiokind, numout, pdt, arbpdt);";
1306    }
1307  }
1308  anImplementation << "\n}";
1309
1310  // 2.3.4) Creation of the des functions Yadjust*_all ...........................
1311  // 2.3.4.1) Standard case: Yadjust_all : correction of states: state -= epsi*grad.
1312  anImplementation << "\nvoid Yadjust_all () \n{";
1313  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){       
1314    if(mod->isTarget())
1315      anImplementation << "\n\t Yadjust_" << mod->getName() << " ();";
1316  }
1317  anImplementation << "\n}";
1318
1319  // Line 3936 Yao8.c
1320  if(theContext.isIncremental()){
1321    // 2.3.4.2) Incremental case: Yadjustd_all : correction of dx : delta -= epsi*grad (internal loop).
1322    anImplementation << "\nvoid Yc_adjustd_all () \n{";
1323    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)       
1324      if(mod->isTarget())       
1325        anImplementation << "\n\t Yc_adjustd_" << mod->getName() << " ();";
1326    anImplementation << "\n}";
1327    // 2.3.4.3) Incremental case: Yadjustkall : states corrections : state += delta ; state(k+1) = state(k) + delta.
1328    anImplementation << "\nvoid Yc_adjustk_all () \n{";
1329    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)       
1330      if (mod->isTarget())
1331        anImplementation << "\n\t Yc_adjustk_" << mod->getName() << " ();";
1332    anImplementation << "\n}";
1333  } // End incremental.
1334
1335  // 2.3.5) Creation of the function Yrazgrad_all ........................
1336  anImplementation << "\nvoid Yrazgrad_all () \n{";
1337  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)       
1338    anImplementation << "\n\t Yrazgrad_" << mod->getName() << " ();";
1339  anImplementation << "\n}";
1340
1341  // 2.3.6) Creation of the function Yrazgrad_only .......................
1342  // Multi: we consider the trajectory!
1343  anImplementation <<  "\nvoid Yrazgrad_only (int itraj) \n{";
1344  for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1345    anImplementation << "\n\tif (itraj==Yid_" << tra->getName() << ")\n\t{";
1346    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1347      if(mod->getTime() == 0 && !mod->isNoward())     
1348        if(mod->getTrajectory() == tra->getName())
1349          anImplementation << "  Yrazgrad_" << mod->getName() << " ();\n\t ";
1350    anImplementation << "}";
1351  }
1352  anImplementation << "\n}";
1353
1354  //2.3.7) Creation of the function Ysetstate_mod .......................
1355  // Charles comment: (nb: etait auparavent pris en charge par auto_call).
1356  anImplementation << "\nint Ysetstate_mod (char *nmmod, YREAL val) \n{\tint codret=0; int all=0;\n\tif (!strcmp(nmmod, \"Y#A\")) all=1;";
1357  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1358    anImplementation << "\n\tif (!strcmp(nmmod, \"" << mod->getName() << "\") || all)\n\t{  Ysetstate_" << mod->getName() << "(val);codret=1;}";
1359  anImplementation << "\n\treturn(codret);\n}";
1360
1361  // 2.3.8) Creation of the function Ysetwish_mod ........................
1362  anImplementation << "\nvoid Ysetwish_mod (int imod, YREAL val) \n{\tif(1==0);";
1363  w1=0;
1364  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++, w1++)
1365    if(mod->isCout() || mod->isTarget())
1366      anImplementation << "\n\telse if (imod==" << w1 << ") Ysetwish_" << mod->getName() << "(val);";
1367  anImplementation << "\n}";
1368
1369  // 2.3.9) Creation of the function of i/o for each module ...............
1370  anImplementation << "\nvoid  Yio_mod (char *nmmod, int Yws, int Yw1, int Yw2, int Yw3, int Ywt, " << theContext.getReal() << " val)\n{";
1371  anImplementation << "\n\t if(1==0);";
1372  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1373    anImplementation << "\n\t else if (strcmp(nmmod, \"" <<mod->getName()<< "\") == 0) Yio_" << mod->getName() << "(Yws, Yw1, Yw2, Yw3, Ywt, val);";
1374  anImplementation << "\n}";
1375
1376  // 2.3.10) YgradCTOtab_all (+with target on trajectory ) (+Cumul for basic internal loop).
1377  anImplementation << "\nvoid YgradCTOtab_target (YREAL tab[]) \n{";
1378  anImplementation << "\t//Y3windice = 0;"; 
1379  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1380    if(mod->isTarget()){   
1381      if(mod->getTime()){
1382        anImplementation  << "\n\t YgradCTOtab_" << mod->getName() << " (YTabMod[Yid_" << mod->getName() 
1383                          << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, tab);";
1384      }else anImplementation << "\n\t YgradCTOtab_" << mod->getName() << " (tab);";
1385    }
1386  anImplementation << "\n}";
1387  // 2.3.11) YtabTOgrad_target (+with target on trajectory) (+tab TO grad of target for basic internal loop).
1388  anImplementation << "\nvoid YtabTOgrad_target (YREAL tab[]) \n{";
1389  anImplementation << "\t//Y3windice = 0;";
1390  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1391    if(mod->isTarget()){   
1392      if(mod->getTime()){
1393        anImplementation  << "\n\t YtabTOgrad_" << mod->getName() << " (YTabMod[Yid_" << mod->getName() 
1394                          << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, tab);";
1395      }else anImplementation << "\n\t YtabTOgrad_" << mod->getName() << " (tab);";
1396    }
1397  anImplementation << "\n}";
1398
1399  // 2.3.12) Creation of functions Y3..._all pour m1qn3 : ..............
1400  if(theContext.isM1qn3()){
1401    // 2.3.12.1) Creation of the function Y3getstate_all.
1402    anImplementation << "\nvoid Y3getstate_all (float x[]) \n{\t Y3windice = 0;";
1403    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)       
1404      if(mod->isTarget())
1405        anImplementation << "\n\t Y3getstate_" << mod->getName() << " (x);";
1406    anImplementation << "\n}";
1407
1408    // 2.3.12.2) Creation of the function Y3valstate_all.
1409    anImplementation << "\nvoid Y3valstate_all () \n{\t Y3windice = 0;";
1410    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1411      if(mod->isTarget())
1412        anImplementation << "\n\t Y3valstate_" << mod->getName() << " ();";
1413    anImplementation << "\n}";
1414
1415    // 2.3.12.3) Creation of the function Y3valgrad_all.
1416    anImplementation << "\nvoid Y3valgrad_all (float g[]) \n{\t Y3windice = 0;";
1417    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1418      if(mod->isTarget())
1419        anImplementation << "\n\t Y3valgrad_" << mod->getName() << " (g);";
1420    anImplementation << "\n}";
1421
1422    if(theContext.isM2qn1()){       
1423      // 2.3.12.4) Creation of the function Y3valxinf_all.
1424      anImplementation << "\nvoid Y3valxinf_all () \n{\t Y3windice = 0;";
1425      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)       
1426        if(mod->isTarget())
1427          anImplementation << "\n\t Y3valxinf_" << mod->getName() << " ();";
1428      anImplementation << "\n}";
1429
1430      // 2.3.12.5) Creation of the function Y3valxsup_all.
1431      anImplementation << "\nvoid Y3valxsup_all () \n{\t Y3windice = 0;";
1432      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1433        if(mod->isTarget())
1434          anImplementation << "\n\t Y3valxsup_" << mod->getName() << " ();";
1435      anImplementation << "\n}";
1436
1437      // 2.3.12.6) Creation of the function Y3valdxmin_all.
1438      anImplementation << "\nvoid Y3valdxmin_all () \n{\t Y3windice = 0;";
1439      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1440        if(mod->isTarget())
1441          anImplementation << "\n\t Y3valdxmin_" << mod->getName() << " ();";
1442      anImplementation << "\n}";
1443    }
1444
1445    if(theContext.isIncremental()){
1446      // 2.3.12.7) Creation of the function Y3getdelta_all.
1447      anImplementation << "\nvoid Y3getdelta_all (float x[]) \n{\t Y3windice = 0;";
1448      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1449        if(mod->isTarget())
1450          anImplementation << "\n\t Y3getdelta_" << mod->getName() << " (x);";
1451      anImplementation << "\n}";
1452
1453      // 2.3.12.8) Creation of the function Y3valdelta_all.
1454      anImplementation << "\nvoid Y3valdelta_all () \n{\t Y3windice = 0;";
1455      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1456        if(mod->isTarget())
1457          anImplementation <<  "\n\t Y3valdelta_" << mod->getName() << " ();";
1458      anImplementation << "\n}";
1459    } // End incremental.
1460  }   // End M1QN3.
1461  // Line 4122 Charles.
1462
1463  if(theContext.isIncremental()){
1464    // 2.3.13) Creation of affectation functions .......................
1465    // 2.3.13.1: YdeltaEQPCstate_all (with multi).
1466    anImplementation << "\nvoid YdeltaEQPCstate_traj(int itraj, char *norkmod, int frompdt, int topdt) \n{";
1467    anImplementation << "\n\tif (1==0){}";
1468    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1469      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1470      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1471        if(mod->getTrajectory() == tra->getName()){ 
1472          if(mod->isTarget() || theContext.isGradTest()){   
1473            norkmod(anImplementation, mod); // norkmod : test of the name and the kind of module: "Y#T": Target, "Y#C": Cout, "Y#A": All.
1474            if(mod->getTime())
1475              anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (frompdt, topdt, YTabMod[Yid_" << mod->getName() << "].pcoef);";
1476            else anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (0, 1, YTabMod[Yid_" << mod->getName() << "].pcoef);";
1477          }
1478        }
1479      }
1480      anImplementation << "\n\t}";
1481    }
1482    anImplementation << "\n}";
1483
1484    // 2.3.13.2: YdeltaEQPCstate_all (with target on trajectory).
1485    anImplementation << "\nvoid YdeltaEQPCstate_target() \n{";
1486    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1487      if(mod->isTarget())
1488        if(mod->getTime()){
1489          anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (YTabMod[Yid_" << mod->getName() << "].deb_target, YTabMod[Yid_";
1490          anImplementation << mod->getName() << "].end_target, YTabMod[Yid_" << mod->getName() << "].pcoef);";
1491        }else anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (0, 1, YTabMod[Yid_" << mod->getName() << "].pcoef);";
1492    }
1493    anImplementation << "\n}";
1494
1495    // 2.3.13.3: YgradEQPdelta_all (with multi).
1496    anImplementation << "\nvoid YgradEQPdelta_traj(int itraj, char *norkmod, int frompdt, int topdt, double pfact) \n{";
1497    anImplementation << "\n\tif (1==0){}";
1498    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1499      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1500      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1501        if(mod->getTrajectory() == tra->getName()){ 
1502          if(mod->isTarget() || theContext.isGradTest()){   
1503            norkmod(anImplementation, mod); // norkmod : test of the name and the kind of module: "Y#T": Target, "Y#C": Cout, "Y#A": All.
1504            if(mod->getTime())
1505              anImplementation << "\n\t YgradEQPdelta_" << mod->getName() << " (frompdt, topdt, pfact);";
1506            else anImplementation << "\n\t YgradEQPdelta_" << mod->getName() << " (0, 1, pfact);";
1507          }
1508        }
1509      }
1510      anImplementation << "\n\t}";
1511    }
1512    anImplementation << "\n}";
1513    // 2.3.13.4: YgradEQPdelta_all (with target on trajectory).
1514    anImplementation << "\nvoid YgradEQPdelta_target(double pfact) \n{";
1515    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1516      if(mod->isTarget()){ 
1517        if(mod->getTime()){
1518          anImplementation << "\n\t YgradEQPdelta_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1519          anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact);";
1520        }else anImplementation << "\n\t YgradEQPdelta_" << mod->getName() << " (0, 1, pfact);";
1521      }
1522    }
1523    anImplementation << "\n}";
1524
1525    // 2.3.13.5: YgradEQval_all (multi: we consider the trajectory!).
1526    anImplementation << "\nvoid YgradEQval_traj(int itraj, char *norkmod, int frompdt, int topdt, double val) \n{";
1527    anImplementation << "\n\tif (1==0){}";
1528    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1529      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1530      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1531        if(mod->getTrajectory() == tra->getName()){ 
1532          norkmod(anImplementation, mod);  // norkmod : test of the name and the kind of module: "Y#T": Target, "Y#C": Cout, "Y#A": All.
1533          if(mod->getTime())
1534            anImplementation << "\n\t\t YgradEQval_" << mod->getName() << " (frompdt, topdt, val);";
1535          else anImplementation << "\n\t\t YgradEQval_" << mod->getName() << " (val);";
1536        }
1537      }
1538      anImplementation << "\n\t}";
1539    }
1540    anImplementation << "\n}";
1541  } // End of incremental.
1542  // Line 4229 Charles.
1543
1544  if(theContext.isTool()){
1545    if(theContext.isGradTestOrIncremental()){
1546      // 2.3.13.6: YdeltaEQPstate_all(frompdt, topdt, pfact) (with multi).
1547      anImplementation << "\nvoid YdeltaEQPstate_traj(int itraj, char *norkmod, int frompdt, int topdt, double pfact) \n{";
1548      anImplementation << "\n\tif (1==0){}";
1549      for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1550        anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1551        for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1552          if(mod->getTrajectory() == tra->getName()){ 
1553            if(mod->isTarget() || theContext.isGradTest()){ 
1554              norkmod(anImplementation, mod); 
1555              if(mod->getTime())
1556                anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (frompdt, topdt, pfact);";
1557              else anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (0, 1, pfact);";
1558            }
1559          }
1560        }
1561        anImplementation << "\n\t}";
1562      }
1563      anImplementation << "\n}";
1564
1565      // 2.3.13.7: YdeltaEQPstate_all(frompdt, topdt, pfact) (with target on trajectory).
1566      anImplementation << "\nvoid YdeltaEQPstate_target(double pfact) \n{";
1567      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1568        if(mod->isTarget()){ 
1569          if(mod->getTime()){
1570            anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1571            anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact);";
1572          }else anImplementation << "\n\t YdeltaEQPstate_" << mod->getName() << " (0, 1, pfact);";
1573        }
1574      }
1575      anImplementation << "\n}";
1576     
1577      anImplementation << "\nvoid YdeltaEQPgrad_target(double pfact) \n{";
1578      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1579        if(mod->isTarget()){ 
1580          if(mod->getTime()){
1581            anImplementation << "\n\t YdeltaEQPgrad_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1582            anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact);";
1583          }else anImplementation << "\n\t YdeltaEQPgrad_" << mod->getName() << " (0, 1, pfact);";
1584        }
1585      }
1586      anImplementation << "\n}";
1587
1588      // 2.3.13.8: YstateEQPdelta_all(frompdt, topdt, pfact) (with multi).
1589      anImplementation << "\nvoid YstateEQPdelta_traj(int itraj, char *norkmod, int frompdt, int topdt, double pfact) \n{";
1590      anImplementation << "\n\tif (1==0){}";
1591      for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1592        anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1593        for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1594          if(mod->getTrajectory() == tra->getName()){ 
1595            if(mod->isTarget() || theContext.isGradTest()){ 
1596              norkmod(anImplementation, mod); 
1597              if(mod->getTime())
1598                anImplementation << "\n\t YstateEQPdelta_" << mod->getName() << " (frompdt, topdt, pfact);";
1599              else anImplementation << "\n\t YstateEQPdelta_" << mod->getName() << " (0, 1, pfact);";
1600            }
1601          }
1602        }
1603        anImplementation << "\n\t}";
1604      }
1605      anImplementation << "\n}";
1606
1607      // 2.3.13.9: YstateEQPdelta_all(frompdt, topdt, pfact) (with target sur trajectoire).
1608      anImplementation << "\nvoid YstateEQPdelta_target(double pfact) \n{";
1609      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1610        if(mod->isTarget()){       
1611          if(mod->getTime()){
1612            anImplementation << "\n\t YstateEQPdelta_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1613            anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact);";
1614          }else anImplementation << "\n\t YstateEQPdelta_" << mod->getName() << " (0, 1, pfact);";
1615        }
1616      }
1617      anImplementation << "\n}";
1618
1619      anImplementation << "\nvoid YstateEQPOdelta_target(double pfact, char *codop) \n{";
1620      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1621        if(mod->isTarget()){       
1622          if(mod->getTime()){
1623            anImplementation <<  "\n\t YstateEQPOdelta_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1624            anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact, codop);";
1625          }else anImplementation << "\n\t YstateEQPOdelta_" << mod->getName() << " (0, 1, pfact, codop);";
1626        }
1627      }
1628      anImplementation <<  "\n}";
1629     
1630      anImplementation << "\nvoid YstateEQAPTdelta_target(double pfact, YREAL tab[]) \n{";
1631      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1632        if(mod->isTarget()){       
1633          if(mod->getTime()){
1634            anImplementation << "\n\t YstateEQAPTdelta_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1635            anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact,tab);";
1636          }else anImplementation << "\n\t YstateEQAPTdelta_" << mod->getName() << " (0, 1, pfact, tab);";
1637        }
1638      }
1639      anImplementation << "\n}";
1640    } // End of if gradTestAndIncremental.
1641
1642    // 2.3.13.10: YgradEQPstate_all(frompdt, topdt, pfact) (with multi).
1643    anImplementation << "\nvoid YgradEQPstate_traj(int itraj, char *norkmod, int frompdt, int topdt, double pfact) \n{";
1644    anImplementation << "\n\tif (1==0){}";
1645    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1646      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1647      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1648        if(mod->getTrajectory() == tra->getName()){ 
1649          norkmod(anImplementation, mod); 
1650          if(mod->getTime())
1651            anImplementation << "\n\t YgradEQPstate_" << mod->getName() << " (frompdt, topdt, pfact);";
1652          else anImplementation << "\n\t YgradEQPstate_" << mod->getName() << "(pfact);";
1653        }
1654      }
1655      anImplementation << "\n\t}";
1656    }
1657    anImplementation << "\n}";
1658
1659    // 2.3.13.11: YgradEQPstate_all(frompdt, topdt, pfact) (with target on trajectory).
1660    anImplementation << "\nvoid YgradEQPstate_target(double pfact) \n{";
1661    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1662      if(mod->isTarget()){
1663        if(mod->getTime()){
1664          anImplementation << "\n\t YgradEQPstate_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1665          anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact);";
1666        }else anImplementation << "\n\t YgradEQPstate_" << mod->getName() << " (pfact);";
1667      }
1668    }
1669    anImplementation << "\n}";
1670   
1671    anImplementation << "\nvoid YgradEQPOstate_target(double pfact, char *codop) \n{";
1672    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1673      if(mod->isTarget()){
1674        if(mod->getTime()){
1675          anImplementation << "\n\t YgradEQPOstate_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1676          anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, pfact, codop);";
1677        }else anImplementation << "\n\t YgradEQPOstate_" << mod->getName() << " (pfact, codop);";
1678      }
1679    }
1680    anImplementation << "\n}";
1681
1682    // 2.3.13.12: YstateTOtab_all (with multi).
1683    anImplementation << "\nvoid YstateTOtab_traj (int itraj, char *norkmod, int frompdt, int topdt, YREAL tab[]) \n{";
1684    anImplementation << "\t//Y3windice = 0;"; 
1685    anImplementation << "\n\tif (1==0){}";
1686    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1687      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1688      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1689        if(mod->getTrajectory() == tra->getName()){ 
1690          norkmod(anImplementation, mod); 
1691          if(mod->getTime())
1692            anImplementation << "\n\t YstateTOtab_" << mod->getName() << " (frompdt, topdt, tab);";
1693          else anImplementation << "\n\t YstateTOtab_" << mod->getName() << " (tab);";
1694        }
1695      }
1696      anImplementation << "\n\t}";
1697    }
1698    anImplementation << "\n}";
1699
1700    // 2.3.13.13: YstateTOtab_all (with target with trajectory).
1701    anImplementation << "\nvoid YstateTOtab_target (YREAL tab[]) \n{";
1702    anImplementation << "\t//Y3windice = 0;"; 
1703    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1704      if(mod->isTarget()){
1705        if(mod->getTime()){
1706          anImplementation << "\n\t YstateTOtab_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1707          anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, tab);";
1708        }else anImplementation << "\n\t YstateTOtab_" << mod->getName() << " (tab);";
1709      }
1710    }
1711    anImplementation << "\n}";
1712
1713    // 2.3.13.14: YgradTOtab_all (with multi).
1714    anImplementation << "\nvoid YgradTOtab_traj (int itraj, char *norkmod, int frompdt, int topdt, YREAL tab[]) \n{";
1715    anImplementation << "\t//Y3windice = 0;";
1716    anImplementation << "\n\tif (1==0){}";
1717    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1718      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1719      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1720        if(mod->getTrajectory() == tra->getName()){ 
1721          norkmod(anImplementation, mod); 
1722          if(mod->getTime())
1723            anImplementation << "\n\t YgradTOtab_" << mod->getName() << " (frompdt, topdt, tab);";
1724          else anImplementation << "\n\t YgradTOtab_" << mod->getName() << " (tab);";
1725        }
1726      }
1727      anImplementation << "\n\t}";
1728    }
1729    anImplementation << "\n}";
1730
1731    // 2.3.13.15: YgradTOtab_all (with target on trajectory).
1732    anImplementation << "\nvoid YgradTOtab_target (YREAL tab[]) \n{";
1733    anImplementation << "\t//Y3windice = 0;";
1734    for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1735      if(mod->isTarget()){
1736        if(mod->getTime()){
1737          anImplementation << "\n\t YgradTOtab_" << mod->getName() << " (YTabMod[Yid_" << mod->getName();
1738          anImplementation << "].deb_target, YTabMod[Yid_" << mod->getName() << "].end_target, tab);";
1739        }else anImplementation << "\n\t YgradTOtab_" << mod->getName() << " (tab);";
1740      }
1741    }
1742    anImplementation << "\n}";
1743
1744    // 2.3.13.16: YtabTOgrad_all (with multi).
1745    anImplementation << "\nvoid YtabTOgrad_traj (int itraj, char *norkmod, int frompdt, int topdt, YREAL tab[]) \n{";
1746    anImplementation << "\t//Y3windice = 0;";
1747    anImplementation << "\n\tif (1==0){}";
1748    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1749      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1750      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1751        if(mod->getTrajectory() == tra->getName()){ 
1752          norkmod(anImplementation, mod); 
1753          if(mod->getTime())
1754            anImplementation << "\n\t\t\t YtabTOgrad_" << mod->getName() << " (frompdt, topdt, tab);";
1755          else anImplementation << "\n\t\t\t YtabTOgrad_" << mod->getName() << " (tab);";
1756        }
1757      }
1758      anImplementation << "\n\t}";
1759    }
1760    anImplementation << "\n}";
1761  } // End of O_TOOL.
1762  // Line 4483 Charles.
1763
1764  // 2.3.14) Generation of the Ydfward_all function, is the computation of the test concerning the gradient.
1765  if(theContext.isGradTest())
1766    dfwardAllGenerator(anImplementation);
1767
1768  // 2.3.15) Creation of function calls to wishEQPstate for each trajectory (pour les amonts de covariance).
1769  if(theContext.isGradTest()){
1770    anImplementation << "\nvoid YwishEQPstate_traj_tocov (int itraj, int pdt, double pfact) \n{";
1771    anImplementation << "\n\tif (1==0){}";
1772    for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
1773      anImplementation << "\n\telse if (itraj==Yid_" << tra->getName() << ")\n\t{";
1774      for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1775        if(mod->getTrajectory() == tra->getName()){ 
1776          if(!mod->getCovt().empty() && mod->getCovt() != mod->getName()){ 
1777            if(mod->getTime())
1778              anImplementation << "\n\t YwishEQPstate_" << mod->getName() << " (pdt, pfact);";
1779            else anImplementation << "\n\t YwishEQPstate_" << mod->getName() << " (pfact);";
1780          }
1781        }
1782      }
1783      anImplementation << "\n\t}";
1784    }
1785    anImplementation << "\n}";
1786  }
1787
1788  // 2.3.16) Creation of the function Yauto_call.....
1789  anImplementation << "\nint Yauto_call (int argc, char *argv[]) \n{\n\t int codret=0; int all=0; " << theContext.getReal() << " val;";
1790  anImplementation << "\n\t if (1==0);";
1791
1792  // 2.3.16.1 : setepsi.
1793  anImplementation << "\n\t else if ( !strcmp(argv[0], \"setepsi\") || !strcmp(argv[0], \"SETEPSI\") \n\t\t\t\t\t ||";
1794  anImplementation << "!strcmp(argv[0], \"setepsi_all\") || !strcmp(argv[0], \"SETEPSI_ALL\"))\n\t {";
1795  anImplementation << "\n\t\t\t if (!strcmp(argv[0], \"setepsi_all\") || !strcmp(argv[0], \"SETEPSI_ALL\"))";
1796  anImplementation << "{all=1; val=atof(argv[1]);} else val=atof(argv[2]);";
1797  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
1798    if(mod->isTarget()){
1799      anImplementation << "\n\t\t\t if (!strcmp(argv[1], \"" << mod->getName() << "\") || all)\n\t\t\t\t\t {Ysetepsi_";
1800      anImplementation << mod->getName() << "(val);codret=1;}";
1801    }
1802  anImplementation << "\n\t }";
1803
1804  // 2.3.16.2 : netload for NN (Neuron Net).
1805  if(theContext.isNetward()){
1806    anImplementation << "\n\t else if (!strcmp(argv[0], \"netload\") || !strcmp(argv[0], \"NETLOAD\"))\n\t {";
1807    anImplementation << "\n\t\t\t codret=1;\n\t\t\t if (1==0);";
1808    for(Table<Neuron>::iterator neuron=theNeuronTable.begin(); neuron != theNeuronTable.end(); neuron++){
1809      anImplementation << "\n\t\t\t else if (!strcmp(argv[1], \"" << neuron->getName() << "\"))\n\t\t\t\t\t Ynetload_";
1810      anImplementation << neuron->getName() << "(argc, argv);";
1811    }
1812    anImplementation << "\n\t\t\t else codret=0;\n\t }";
1813  }
1814  anImplementation  << "\n\t else codret=0;\n\t return(codret);\n}\n";
1815  // Line 4551 Charles.
1816}// END function generate code for module--------------------------------------------------------------------------------------
1817
1818
1819/**
1820 * Method for the creation of YaoModules in the generated file.
1821 * @param aDeclaration is the generated file we are writing on.
1822 */
1823void Translator::createYaoModules(ostream& aDeclaration){
1824  string space, module, traj;             // Names of the actual space, module and trajectory.
1825  int w1, w2;                             // Some useful counters.
1826  ostringstream bufwrk;                   // A stream buffer to perform some work with strings.
1827  ostringstream streamInputWardFunctions; // It's useful in order to generate the string inputWardFunctions.
1828  string inputWardFunctions;              // Parameters in input for functions *ward.
1829
1830  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1831    // Some initialization for each module.
1832    module = mod->getName();
1833    space = mod->getSpaceOrOperator();
1834    traj = mod->getTrajectory();
1835
1836    if(mod->isCloned()){       
1837      aDeclaration << "\n//////////// HERE IS A CLONE MODULE ////////////\n";
1838      if(mod->isNoward())
1839        aDeclaration << "class \t Yao" << module << ":public Yao" << mod->getCloned() << "{};\n";
1840      else aDeclaration << "class \t " << module << ":public " << mod->getCloned() << "{};\n";
1841      continue; // For a cloned module that's all!
1842    }
1843    bufwrk.str(""); 
1844    if(mod->isTempo())
1845      bufwrk << "[YNBALLTIME_" << traj <<"]";
1846    // 1) Declaration of the Class variables.
1847    aDeclaration << "\n//////////// Begin of the Yao Class Yao" << module << " ////////////\n";
1848    aDeclaration << "class   \t      Yao" << module << "\n{\n\t public:\n";
1849    aDeclaration << "\t      " << theContext.getReal() << "\t " << YSTATE << bufwrk.str() << "[YNBS_" << module << "];\n";
1850    aDeclaration << "\t      " << theContext.getReal() << "\t " << YGRAD << bufwrk.str() << "[YNBS_" << module << "];\n";
1851    if(mod->isTarget())
1852      aDeclaration << "\t      " << theContext.getReal() << "\t " << YEPSI << "[YNBS_" << module << "];\n";
1853    if(mod->isCout() || mod->isTarget())
1854      aDeclaration << "\t      " << theContext.getReal() << "\t " << YWISH << "[YNBS_" << module << "];\n";
1855    if(theContext.isIncremental() && !theContext.isGradTest())
1856      if(mod->isTarget())
1857        if(mod->isTempo()){ 
1858          if(mod->getEndTarget() == theTrajectoryTable.find(traj)->getBoot()) 
1859            // Case target on uptime.
1860            aDeclaration << "\t      " << theContext.getReal() << "\t " << YDELTA << "[YNBUPTIME_" << traj << "][YNBS_" << module << "];\n";
1861          else // Case target on steptime or alltime, we allocate on alltime in order to not have troubles for shift on the trajectory index.
1862            aDeclaration << "\t      " << theContext.getReal() << "\t " << YDELTA << "[YNBALLTIME_" << traj << "][YNBS_" << module << "];\n";
1863        }else aDeclaration << "\t      " << theContext.getReal() << "\t " << YDELTA << "[1][YNBS_" << module << "];\n";
1864
1865    if(theContext.isGradTest()){       
1866      if(mod->isNoward()){ 
1867        if(mod->isTempo())
1868          aDeclaration << "\t      " << theContext.getReal() << "\t " << YDELTA << "[YNBALLTIME_" << traj << "][YNBS_" << module << "];\n";
1869        else aDeclaration << "\t      " << theContext.getReal() << "\t " << YDELTA << "[1][YNBS_" << module << "];\n";
1870      }else // =>is ward.
1871        aDeclaration << "\t      " << theContext.getReal() << "\t " << YDELTA << "[YNBALLTIME_" << traj << "][YNBS_" << module << "];\n";
1872    }
1873
1874    // 2) Constructor - Destructor and end of the class.
1875    aDeclaration <<  "\n//:=========> Constructor - Destructor ============\n";
1876    aDeclaration << "Yao" << module << "(){}\n~Yao" << module << "(){}\n\n};\n";
1877
1878    // 3) Prototypes automatic generation of the not specific classes (non spec).
1879    streamInputWardFunctions.str("");
1880    inputWardFunctions = "";
1881    if(!mod->isSpec()){
1882      if(mod->isAutonet()){       
1883        if(mod->isTempo())
1884          MACRO0_PCLANT(module.c_str(), mod->getAutonet().c_str());     // Case of AutoNet Tempo.
1885        else MACRO0_PCLAN(module.c_str(), mod->getAutonet().c_str());   // Case of AutoNet non Tempo.
1886      }else if(!mod->isNoward()){ // Not useful for noward
1887        if(!mod->isArray()){       
1888          for(w1=0; w1<mod->getInput(); ++w1){
1889            streamInputWardFunctions << theContext.getReal() << " x" << w1 << ",";
1890            inputWardFunctions = streamInputWardFunctions.str();
1891            if(inputWardFunctions.size())
1892              inputWardFunctions.replace(inputWardFunctions.size()-1, 1, "");
1893          }
1894        }
1895        if(mod->isNetward())
1896          MACRO0_PCLNW(module.c_str(), inputWardFunctions.c_str());         // Case netward.
1897        else MACRO0_PCL(module.c_str(), inputWardFunctions.c_str());       
1898      } 
1899      if(!mod->isNoward()) // Not useful for noward.
1900        aDeclaration << buffer;
1901    }
1902  } // End for.
1903}
1904
1905/**
1906 * Is a method for the generation of the test of the name and the kind of module: "Y#T": Target, "Y#C": Cout, "Y#A": All.
1907 * Repetitive generation of code for the utilities functions.
1908 * @param anImplementation is the generated file we are writing on.
1909 * @param mod is the module who we are interested on.
1910 */
1911void Translator::norkmod(ostream& anImplementation, Table<Modul>::iterator mod){
1912  anImplementation << "\n\t\tif ( !strcmp(norkmod, \"" << mod->getName() << "\") || !strcmp(norkmod, \"Y#A\") ";
1913  if(mod->isTarget())       
1914    anImplementation << "|| !strcmp(norkmod, \"Y#T\") ";
1915  if(mod->isCout())
1916    anImplementation << "|| !strcmp(norkmod, \"Y#C\") ";
1917  anImplementation << ")";
1918}
1919
1920/**
1921 * Allows the generation of the Ydfward_all function that is: computation of the test concerning the gradient.
1922 * @param anImplementation is the generated file we are writing on.
1923 */
1924// gendfward_all for Yao8.c
1925void Translator::dfwardAllGenerator(ostream& anImplementation){
1926  int   w1;     // Just a counter.
1927  string mName; // The name of the current module.
1928  anImplementation << "\n int Ydfward_all(int modop, char *nmmod, int All, int KeKo,  float pdx, float ptol)\n{\n\tint nbko=0;\n";
1929  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
1930    mName = mod->getName();
1931    if(mod->getInput() && mod->getOutput() && !mod->isNetward() && !mod->isAutonet() && !mod->isNoward() && !mod->isHidjac()){       
1932      anImplementation << "\tif ( !strcmp(nmmod, \"" << mName << "\") || All )";
1933      if(mod->getNbAxes() == 1){                       
1934        if(mod->getTime()){
1935          anImplementation << "\n\t\tnbko += Ytestdf_" << mName << "(modop,KeKo,pdx,ptol,YNBI_" << mName << ",YNBS_";
1936          anImplementation << mName << ",\"" << mName << "\",Yting,Y" << mName << "[Yi]->Ystate[0],Y" << mName << "[Yi]);\n";
1937        }else {
1938          anImplementation << "\n\t\tnbko += Ytestdf_" << mName << "(modop,KeKo,pdx,ptol,YNBI_" << mName << ",YNBS_";
1939          anImplementation << mName << ",\"" << mName << "\",Yting,Y" << mName << "[Yi]->Ystate,Y" << mName << "[Yi]);\n";
1940        }
1941      }else if(mod->getNbAxes() == 2){                       
1942        if(mod->getTime()){
1943          anImplementation << "\n\t\tnbko += Ytestdf_" << mName << "(modop,KeKo,pdx,ptol,YNBI_" << mName << ",YNBS_";
1944          anImplementation << mName << ",\"" << mName << "\",Yting,Y" << mName << "[Yi][Yj]->Ystate[0],Y" << mName << "[Yi][Yj]);\n";
1945        }else{ 
1946          anImplementation << "\n\t\tnbko += Ytestdf_" << mName << "(modop,KeKo,pdx,ptol,YNBI_" << mName << ",YNBS_";
1947          anImplementation << mName << ",\"" << mName << "\",Yting,Y" << mName << "[Yi][Yj]->Ystate,Y" << mName << "[Yi][Yj]);\n";
1948        }
1949      }else if(mod->getNbAxes() == 3){                       
1950        if(mod->getTime()){
1951          anImplementation << "\n\t\tnbko += Ytestdf_" << mName << "(modop,KeKo,pdx,ptol,YNBI_" << mName << ",YNBS_";
1952          anImplementation << mName << ",\"" << mName << "\",Yting,Y" << mName << "[Yi][Yj][Yk]->Ystate[0],Y" << mName << "[Yi][Yj][Yk]);\n";
1953        }else {
1954          anImplementation << "\n\t\tnbko += Ytestdf_" << mName << "(modop,KeKo,pdx,ptol,YNBI_" << mName << ",YNBS_";
1955          anImplementation << mName << ",\"" << mName << "\",Yting,Y" << mName << "[Yi][Yj][Yk]->Ystate,Y" << mName << "[Yi][Yj][Yk]);\n";
1956        }
1957      }
1958    }
1959  }
1960  anImplementation << "\treturn(nbko);\n}\n";
1961}
1962
1963/**
1964 * For the Connection directive we have not to generate code but we leave this name to this member for continuity.
1965 * We perform some check and we manipulate the information of the table Connection.
1966 * At the end of this method in theConnectionTable we will have a simple connection for each element of the Table (before this method we could have
1967 * more connection in the same table entry caused from the range operators: "%" or "#" in the ctin-m directive.
1968 * Having one simple connection for each Table entry is more practical in the future order generation.
1969 * @param aConnectionTable is the table that contains all the objects connection.
1970 */
1971void Translator::generateCode(Table<Connection>& aConnectionTable){
1972  Modul* inMod;   // The module that takes an input.
1973  Modul* outMod;  // The module that gives an output.
1974 
1975  // SOME CHECK on the directive ctin-m for each entry of the theTableConnection.
1976  for(Table<Connection>::iterator con=theConnectionTable.begin(); con != theConnectionTable.end(); con++){
1977    inMod = theModulTable.find(con->getInModule());             // The input module on ctin-m.
1978    outMod = theModulTable.find(con->getOutModule());           // The output module on ctin-m.
1979
1980    // We have limited the creation of macros;
1981    // i.e. the generation of Yting[50]=YS51_mod(.) is rejected at compiling time because YS51_mod is not defined if the limit is 50!
1982    // In this case the affectation of the inputs is realized by the user.
1983    ENFORCENOT(inMod->getInput() > NB_MAX_MACRO && !inMod->isManageCtin())
1984      ("ctin-m directive: ctin is prohibited for module (")(con->getInModule())(") because it has more than ")(NB_MAX_MACRO)(" inputs \n");
1985    // Check for the option specified on the directive ctin-m.
1986    con->checkOptions(inMod, outMod, theSpaceTable, theOperatorTable, theTrajectoryTable);
1987  } // End for Connections checks.
1988
1989  // Generation of the Table composed by one simple connection for each element. We elaborate the actual theConnectionTable, we put all the simple
1990  // connection in the allConnectionTable and then we copy all the simple connections in the theConnectionTable.
1991  // So allConnectionTable is a support Table used to translate the ancien theConnectionTable that group a lot of connection in the same vector element
1992  // (i.e.: ctin A 1 from B 1 i-1 t#~1 is rapresented in one Table element). In allConnectionTable each Table element is one simple connection
1993  // (the same example is splitted in three connections: ctin A 1 from B 1 i-1 t-1, ctin A 1 from B 1 i-1 t, ctin A 1 from B 1 i-1 t+1.
1994  Table<Connection> allConnectionTable; 
1995  bool boolijk;       // For ctinm: is a flag that avoid the regeneration in the point i j k for one t.
1996  int ctinCounter;
1997  for(Table<Connection>::iterator con=theConnectionTable.begin(); con != theConnectionTable.end(); con++){
1998    Connection newCon;  // A simple connection.
1999    ctinCounter=0;
2000    newCon.setInModule(con->getInModule());
2001    newCon.setOutModule(con->getOutModule());
2002    newCon.setRelt(con->getRelt());
2003    if(!con->isCtinType()){ // CASE directive CTINM......................................
2004      // For all steps time in the directive we generate the coordinates (relative:=1, or absolute:=-1 (if the coordinate doesn't exist:=0).
2005      for(int wt=0; wt<con->getTElements(); ++wt){ 
2006        newCon.setT(con->ct[wt]);
2007        // Loop on the output; we have to remember do not variate togheter the output and the coordinates!!!!
2008        for(int wnout=0; wnout<con->getOutElements(); ++wnout){ 
2009          boolijk=false;
2010          // We work firstly with the variation of i.
2011          //if(con->isI()){ // Inevitably, but for harmonisation.
2012          if(theModulTable.find(con->getOutModule())->getNbAxes()>0){ // Inevitably, but for harmonisation.
2013            newCon.setReli(con->getReli());
2014            for(int wi=0; wi<con->getIElements(); ++wi){
2015              if(con->ci[wi]!=0 || (con->ci[wi]==0 && !boolijk)){ // Inevitably, but for harmonisation.
2016                newCon.setI(con->ci[wi]);
2017                if(outMod->getNbAxes() >1){newCon.setJ(0); newCon.setRelj(true);} // For definition of this kind of connection.
2018                if(outMod->getNbAxes() >2){newCon.setK(0); newCon.setRelk(true);} // For definition of this kind of connection.
2019
2020                newCon.setIn(con->getIn() + ctinCounter);
2021                if(con->getOutElements()>1)
2022                  newCon.setOut(con->getOut() + ctinCounter);
2023                else // con->getOutElements()==1.
2024                  newCon.setOut(con->getOut()); 
2025
2026                // We stock the simple connection in the temporary Table allConnectionTable.
2027                stockCheckConnection(allConnectionTable, newCon);
2028                ++ctinCounter;  // The simple connection counter (just for test).
2029                ENFORCENOT(ctinCounter>con->getInElements()) // Problem if the input number of connections is smaller than the connections created.
2030                  ("directive ctin: the number of input connections (")(con->getInElements())(") mismatch the number of axes connections (")
2031                  (ctinCounter)(") required between modules ")(con->getName())("\n");
2032                if(con->ci[wi]== 0) boolijk=true;
2033              }
2034            }
2035          } 
2036          if(theModulTable.find(con->getOutModule())->getNbAxes()>1){
2037            //if(con->isJ()){
2038            newCon.setRelj(con->getRelj());
2039            for(int wi=0; wi<con->getJElements(); ++wi){
2040              if(con->cj[wi]!=0 || (con->cj[wi]==0 && !boolijk)){ 
2041                newCon.setI(0); newCon.setReli(true); // For definition of this kind of connection.
2042                newCon.setJ(con->cj[wi]);
2043                if(outMod->getNbAxes() >2) 
2044                {newCon.setK(0); newCon.setRelk(true);}  // For definition of this kind of connection.
2045                newCon.setIn(con->getIn() + ctinCounter);
2046                if(con->getOutElements()>1)
2047                  newCon.setOut(con->getOut() + ctinCounter);
2048                else // con->getOutElements()==1.
2049                  newCon.setOut(con->getOut()); 
2050
2051                // We stock the simple connection in the temporary Table allConnectionTable.
2052                stockCheckConnection(allConnectionTable, newCon);
2053                ++ctinCounter;  // The simple connection counter (just for test).
2054                ENFORCENOT(ctinCounter>con->getInElements()) // Problem if the input number of connections is smaller than the connections created.
2055                  ("directive ctin: the number of input connections (")(con->getInElements())(") mismatch the number of axes connections (")
2056                  (ctinCounter)(") required between modules ")(con->getName())("\n");
2057                if(con->cj[wi]== 0) boolijk=true;
2058              }
2059            } 
2060          }
2061          if(theModulTable.find(con->getOutModule())->getNbAxes()>2){
2062          //if(con->isK()){
2063            newCon.setRelk(con->getRelk());
2064            for(int wi=0; wi<con->getKElements(); ++wi){
2065              if(con->ck[wi]!=0 || (con->ck[wi]==0 && !boolijk)){ 
2066                newCon.setI(0); newCon.setReli(true); // For definition of this kind of connection.
2067                newCon.setJ(0); newCon.setRelj(true); // For definition of this kind of connection.
2068                newCon.setK(con->ck[wi]);
2069
2070                newCon.setIn(con->getIn() + ctinCounter);
2071                if(con->getOutElements()>1)
2072                  newCon.setOut(con->getOut() + ctinCounter);
2073                else // con->getOutElements()==1.
2074                  newCon.setOut(con->getOut()); 
2075
2076                // We stock the simple connection in the temporary Table allConnectionTable.
2077                stockCheckConnection(allConnectionTable, newCon);
2078                ++ctinCounter;  // the simple connection counter (just for test).
2079                ENFORCENOT(ctinCounter>con->getInElements()) // Problem if the input number of connections is smaller than the connections created.
2080                  ("directive ctin: the number of input connections (")(con->getInElements())(") mismatch the number of axes connections (")
2081                  (ctinCounter)(") required between modules ")(con->getName())("\n");
2082                if(con->ck[wi]== 0) boolijk=true; // Not more useful but harmonisation.
2083              }
2084            } 
2085          }     
2086        }
2087      } // End for all t.
2088    }else{  // CASE directive CTIN...............................................       
2089      // For all the time instants we generate the coordinate (relative=1, absolute=-1, not used=0).
2090      for(int wt=0; wt<con->getTElements(); ++wt){  // So for each t fixed.
2091        newCon.setT(con->ct[wt]);
2092        // We work feeding the range of each axe.
2093        if(con->isI()){  // Inevitably, but for harmonisation.
2094          newCon.setReli(con->getReli());
2095        }
2096        if(con->isJ())
2097          newCon.setRelj(con->getRelj());
2098        if(con->isK())   
2099          newCon.setRelk(con->getRelk());
2100        // We loop for the creation of the connections (a cartesian loop).
2101        newCon.setJ(0); newCon.setK(0);                         
2102        for(int wnout=0; wnout<con->getOutElements(); ++wnout){ // Loop on all the output; we will remember that we can't accept to vary.
2103          // Togheter output and coordinate!!!!
2104          for(int wi=0; wi<con->getIElements();  ++wi){
2105            newCon.setIn(con->getIn() + ctinCounter);
2106            if(con->getOutElements()>1)
2107              newCon.setOut(con->getOut() + ctinCounter);
2108            else // nbeout=1.
2109              newCon.setOut(con->getOut()); //= supout.
2110            newCon.setI(con->ci[wi]);
2111            if(con->isJ()){
2112              for(int wj=0; wj<con->getJElements(); ++wj){
2113                newCon.setIn(con->getIn() + ctinCounter);
2114                if(con->getOutElements()>1)
2115                  newCon.setOut(con->getOut() + ctinCounter);
2116                else // nbeout=1.
2117                  newCon.setOut(con->getOut()); //= supout.
2118                newCon.setJ(con->cj[wj]);
2119
2120                if(con->isK()){
2121                  for(int wk=0; wk<con->getKElements(); ++wk){
2122                    newCon.setIn(con->getIn() + ctinCounter);
2123                    if(con->getOutElements()>1)
2124                      newCon.setOut(con->getOut() + ctinCounter);
2125                    else // nbeout=1.
2126                      newCon.setOut(con->getOut()); //= supout.
2127                    newCon.setK(con->ck[wk]);
2128                    stockCheckConnection(allConnectionTable, newCon);
2129                    ++ctinCounter;
2130                    ENFORCENOT(ctinCounter>con->getInElements()) // Problem if the input number of connections is smaller than the connections created.
2131                      ("directive ctin: the number of input connections (")(con->getInElements())(") mismatch the number of axes connections (")
2132                      (ctinCounter)(") required between modules ")(con->getName())("\n");
2133                  }
2134                }else{
2135                  stockCheckConnection(allConnectionTable, newCon);
2136                  ++ctinCounter;
2137                  ENFORCENOT(ctinCounter>con->getInElements()) // Problem if the input number of connections is smaller than the connections created.
2138                    ("directive ctin: the number of input connections (")(con->getInElements())(") mismatch the number of axes connections (")
2139                    (ctinCounter)(") required between modules ")(con->getName())("\n");
2140                }
2141              } // End for j.
2142            }else{
2143              stockCheckConnection(allConnectionTable, newCon);
2144              ++ctinCounter;
2145              ENFORCENOT(ctinCounter>con->getInElements()) // Problem if the input number of connections is smaller than the connections created.
2146                ("directive ctin: the number of input connections (")(con->getInElements())(") mismatch the number of axes connections (")
2147                (ctinCounter)(") required between modules ")(con->getName())("\n");
2148            } // End for i.
2149          }
2150        } // End for on output.   
2151      }
2152    } // End else.
2153
2154    // We test that the number of connections created match the range of input.
2155    ENFORCENOT(ctinCounter != con->getInElements())("directive ctin: the number of connection created(")
2156      (ctinCounter)(") do not match the input required(")(con->getInElements())(") in ")(con->getName())("\n");
2157  } // End global for.
2158
2159  /* Charles comment:
2160     Faut-il verifier que les coordonnees ne sont pas aberrantes par rapport a l'espace. Je ne ferait pas ca a priori ici;
2161     mais je pense que cela relevera des CDTL a gerer +ou- au moment de l'alimentation des inputs: si la connection
2162     qui doit alimenter une input provient d'un point hors de l'espace temps, alors ... PLM je mettrais ZERO ! */
2163
2164  // Just for test.
2165  // theDisplay.display(theConnectionTable); cout << "---------------------------" << endl; theDisplay.display(allConnectionTable);
2166
2167  // We put all the connections in the right vector: theConnectionTable (at the moment they are in allConnectionTable).
2168  theConnectionTable.clear();
2169  for(Table<Connection>::iterator con=allConnectionTable.begin(); con != allConnectionTable.end(); con++)
2170    theConnectionTable.push_back(*con);
2171}
2172
2173/**
2174 * Stock the new connection in the Table allConnectionTable if there are no anomalies.
2175 * @param allConnectionTable is the table containing all the connections.
2176 * @param newCon is the connection we want to add.
2177 */
2178void Translator::stockCheckConnection(Table<Connection> & allConnectionTable, Connection newCon){
2179  // A module in the point i,j,k,t can't be connected with himself (we can connect with his alter-ego only from other points of the space).
2180  if(newCon.getInModule() == newCon.getOutModule())
2181    // We can do this test only when the coordinates are express in a relative way.
2182    if(newCon.getReli() != -1 && newCon.getRelj() != -1 && newCon.getRelk() != -1 && newCon.getRelt() > 0)
2183      ENFORCENOT(newCon.getI()==0 && newCon.getJ()==0 && newCon.getK()==0 && newCon.getT()==0)
2184        ("ctin directive: modul ")(newCon.getOutModule())(" connected to himself not allowed\n");
2185
2186  // Charles comment: multi, on considere que les coordonnees se rapportent a celle de l'OUT.
2187  Modul* outMod = theModulTable.find(newCon.getOutModule()); // The output module on ctin.
2188
2189  // An absolute coordinate must be inside the space.
2190  ENFORCENOT((newCon.getReli()==-1 && newCon.getI()>outMod->getYA(1)) ||   
2191      (newCon.getRelj()==-1 && newCon.getJ()>outMod->getYA(2)) ||   
2192      (newCon.getRelk()==-1 && newCon.getK()>outMod->getYA(3))  )
2193    ("ctin directive: module ")(outMod->getName())(" has at least one absolute coordinate out of the defined space\n");
2194
2195  for(Table<Connection>::iterator con=allConnectionTable.begin(); con != allConnectionTable.end(); con++){
2196    // One input at least one connection.
2197    ENFORCENOT(con->getInModule() == newCon.getInModule() && con->getIn() == newCon.getIn())
2198      ("ctin directive: input ")(newCon.getInModule())(" ")(newCon.getIn())(" is already feed (only one connection for each input is allowed) \n");
2199
2200    // The connections that are repeted are not considered an anomaly; this is the case of relative coordinate.
2201    if(     con->getOutModule() == newCon.getOutModule() 
2202        &&    con->getOut()     == newCon.getOut()
2203        &&  con->getInModule()  == newCon.getInModule()
2204        &&    con->getIn()      == newCon.getIn()
2205        &&    con->getI()       == newCon.getI()
2206        &&    con->getJ()       == newCon.getJ()
2207        &&    con->getK()       == newCon.getK()
2208        &&    con->getT()       == newCon.getT()){
2209      cout << "ctin warning: duplicated connection: " << newCon.getOutModule() << " " << newCon.getOut() << " ====> " << newCon.getInModule();
2210      cout << " " << newCon.getIn() << endl;
2211      // We should understand how we have to do for the absolute coordinate !?
2212    }
2213  }
2214
2215  // Too much connections to generate: we limit the max size of the connections table.
2216  ENFORCENOT(allConnectionTable.size() >= NB_MAX_CONNECT)
2217    ("ctin directive: too much connections required (max is ")(NB_MAX_CONNECT)(") \n");
2218
2219  // All the controls are ok, we stock.
2220  allConnectionTable.push_back(newCon);
2221}
2222
2223/**
2224 * Generation of the code relative to the directive order.
2225 * This method is directly linked to the class Order. For all the Order objects in the table anOrderTable we generate some code.
2226 * @param anImplementation is the generated file we are writing on.
2227 * @param anOrderTable the table that contains all the Order.
2228 */
2229// blockorder() for Yao8.c. The structure of this function has changed a lot in the new version 9 of Yao.
2230// Some function called inside have been suppressed because too small in order to make less confusion.
2231void Translator::generateCode(ostream& anImplementation, Table<Order>& anOrderTable){
2232
2233  // Check the max number of order tokens.
2234  ENFORCE(anOrderTable.size() < NB_MAX_ORDER_TOKENS)
2235    ("too much order tokens found (max is ")(NB_MAX_ORDER_TOKENS)(") \n may be, should you split your order directive ?\n");
2236
2237  /*  For see/debug
2238   *  int j=0;
2239      for(Table<Order>::iterator ord=anOrderTable.begin(); ord < anOrderTable.end(); ord++){
2240      cout << endl << "Vector " << j++ << endl;
2241      for(vector<string>::iterator ordAPP=ord->orderTokens.begin(); ordAPP < ord->orderTokens.end(); ordAPP++)
2242      cout << *ordAPP << " "; 
2243      cout << endl;}*/
2244  for(Table<Order>::iterator ord=anOrderTable.begin(); ord < anOrderTable.end(); ord++)
2245    if(ord->getOrderPhase()==1){ // Case directive modinspace.
2246
2247      // Firstly we generate code for the forward.
2248      orderGenerator(anImplementation, string("forward"), *ord);
2249
2250      // Linear tangent case.
2251      if(theContext.isGradTestOrIncremental()){
2252        orderGenerator(anImplementation, string("linward"), *ord);
2253      }
2254
2255      // Test derivation function case.
2256      if(theContext.isGradTest()){ 
2257        orderGenerator(anImplementation, string("dfward"), *ord); // dfward function on the space.
2258        dfwardGridGenerator(anImplementation, *ord);              // dfward function on one grid point.
2259      }
2260
2261      // Then backward, but before we reverse the order of the axes and of the tokens.
2262      ord->backOrder();
2263
2264      // For see/debug: test the reversed vector.
2265      /*cout << "The orderTokens after the backOrder(): " << endl;
2266        for(vector<string>::iterator token=ord->orderTokens.begin(); token < ord->orderTokens.end(); token++)
2267        cout << " " << *token;
2268        cout << endl;*/
2269
2270      orderGenerator(anImplementation, string("backward"), *ord); 
2271    }else{ // Case directive spaceintraj.
2272
2273
2274
2275      // The code here is the same that phase==1 but we use orderGeneratorMulti instead of orderGenerator.
2276      // We have to maintain both simultaneously.
2277      orderGeneratorMulti(anImplementation, string("forward"), *ord); // Firstly we generate code for the forward.
2278      if(theContext.isGradTestOrIncremental())  // Linear tangent case.
2279        orderGeneratorMulti(anImplementation, string("linward"), *ord); 
2280      // Charles comment: l'aspect multi est-il opportun pour les test des derivees !? may be not (ARAR).
2281      if(theContext.isGradTest()){                                      // Test derivation function case.
2282        orderGeneratorMulti(anImplementation, string("dfward"), *ord);  // dfward function on the space.
2283        dfwardGridGenerator(anImplementation, *ord);                    // dfward function on one grid point.
2284      }
2285
2286      // Then backward, but before we reverse the order of the axes and of the tokens.
2287      ord->backOrder (); 
2288      orderGeneratorMulti(anImplementation, string("backward"), *ord); 
2289
2290      // Note: we can reverse all the time that we want the token vector, we just have to backOrder().
2291    } // End if-else and end for.
2292 
2293  // Ending the directive Order, we perform the last phase.
2294
2295  // Charles comment: on va produire automatiquement la phase 3 dans l'ordre de declaration des trajectoires !
2296  // pour continuer a avoir des fonctions *ward_order qui semble avoir encore leur utilite.
2297
2298  Order ord(&theModulTable); 
2299  ord.setOrderPhase(3); // To signal that we are in the last phase where there are all trajectories togheter.
2300  for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++)
2301    if(tra->isCounterOrder()) // Only the trajectories that has been part of a phase spaceintraj.
2302      ord.orderTokens.push_back(tra->getName());
2303
2304  // The code here is the same that phase==1 but we use orderGeneratorMulti instead of orderGenerator.
2305  // We have to maintain both simultaneously.
2306  orderGeneratorMulti(anImplementation, string("forward"), ord);    // Firstly we generate code for the forward.
2307  if(theContext.isGradTestOrIncremental())
2308    orderGeneratorMulti(anImplementation, string("linward"), ord);  // Linear tangent case.
2309  // Charles comment: l'aspect multi est-il opportun pour les test des derivees !? may be not (ARAR).
2310  if(theContext.isGradTest()){                                      // Test derivation function case.
2311    orderGeneratorMulti(anImplementation, string("dfward"), ord);   // dfward function on the space.
2312    dfwardGridGenerator(anImplementation, ord);                     // dfward function on one grid point.
2313  }
2314
2315  // Then backward, but before we reverse the order of the axes and of the tokens.
2316  ord.backOrder (); 
2317  orderGeneratorMulti(anImplementation, string("backward"), ord); 
2318
2319  // We produce the *ward of the operators. At the moment we generate only forward_operator, backward_operator and linward_operator.
2320  wardOperatorGenerator(anImplementation);
2321  //float b = parallelLoops;
2322  //float a = ((float)parallelLoops) / totalLoops * 100;
2323
2324  // In order to have a  statistic of the parallelization procedure we print some usefulle information here.
2325  if(theContext.isParallel()){
2326    cout << endl << "Parallelization profiling:" << endl;
2327    cout << "  The number of threads used for the parallelism is: ";
2328    if(theContext.getThreadsNumber()) 
2329      cout << theContext.getThreadsNumber() << ".";
2330    else cout << "default.";
2331    cout << endl << "  The number of total loops is " << totalLoops  << " containing " << totalModulesInOrders << " total modules.";
2332    //cout << endl << "  In the forward procedure:" << endl
2333    cout << endl << "  The number of parallelized loop is " << parallelForwardLoops << " containing " << parallelForwardModules << " modules," << endl
2334      //<< "  the number of total loop is " << totalLoops  << " containing " << theModulTable.size() << " total modules," << endl
2335      << "  the percentage of parallel loops is " << ((float)parallelForwardLoops) / totalLoops * 100 << "%" << endl
2336      //<< "  and the percentage of modules that have been parallelized is " << ((float)parallelModules) / theModulTable.size() * 100 << "%." << endl;
2337      << "  and the percentage of modules that have been parallelized is " << ((float)parallelForwardModules) / totalModulesInOrders * 100 << "%." << endl;
2338
2339    //cout << endl << "theModulTable.size() " << theModulTable.size() << endl;
2340    //cout << endl << "totalModulesInOrders " << totalModulesInOrders << endl;
2341
2342    if(theModulTable.size() - totalModulesInOrders) // If there modules that are not used for computation we show it.
2343      cout << "  There are " << theModulTable.size() - totalModulesInOrders << " modules not present in an order directive." << endl;
2344    //cout << "  In the backward procedure:" << endl
2345    if(parallelForwardLoops){
2346      cout << "  In the backward procedure:" << endl
2347        //<< "    the number of parallelized loop is " << parallelBackwardLoops << " containing " << parallelBackwardModules << " modules," << endl
2348        << "    The number of atomic update in the parallel regions is " << totalAtomicOperations
2349        << ", the total number of update is " << theConnectionTable.size() << "." << endl
2350        << "    The percentage of atomic update is " << ((float)totalAtomicOperations) / theConnectionTable.size() * 100 << "%" << endl;
2351    }
2352    cout << endl;
2353  }
2354}
2355
2356/**
2357 * Manages the code generation of the functions *ward.
2358 * This generation is relative only to the modinspace option of the order directive.
2359 * The ward to be generated in the file Y2projectName.h are: forward, linward, dfward (if GRADTEST option setted) and backward.
2360 * This method is called from the method generateCode.
2361 * @param anImplementation is the generated file we are writing on.
2362 * @param wardKind the kind of *ward to be generated.
2363 * @param ord is the object Order that we are working at the moment of the method call.
2364 */
2365// genorder() for Yao8.c. In this new version there is the parallelization.
2366void Translator::orderGenerator(ostream& anImplementation, string wardKind, Order ord){
2367  int firstAxis=0;                          // Which axis is the first axis of the order?
2368                                            // firstAxis Is used in the parallel generation (for the atomic operations) of the backward: 1=i, 2=j, 3=k.
2369  bool wasAxe=false;                        // In order to understand if the previous token was an axe.
2370  bool wasOrder=false;                      // In order to understand if the previous token was an order.
2371  bool parallel=false;                      // True if the current nested loop may be parallelized (so if the condition ct=0 && cY!=0
2372                                            // is not present, with cY the index of the extern loop).
2373  bool axeTable[3] = {false, false, false}; // A three dimension table that contains true in the relative axe position if the axe token is already met.
2374  int dimAxe=0;                             // The actual dimension of the axeTable: the number of true elements.
2375  Modul * mod;                              // A module encountered in the tokens sequence.
2376  char a, b;                                // They contain the letter 'i', 'j', 'k' in function of the actual axes in the sequence.
2377  ostringstream streamInputWardFunctions;   // It's useful in order to generate the string inputWardFunctions.
2378  string inputWardFunctions;                // Parameters in input for functions *ward (Yting[i] sequence in Y2_project_file).
2379  int w1;                                   // Just a counter.
2380  string fctWard;                           // Name of the function to call.
2381  string forward("forward"), linward("linward"), dfward("dfward"), backward("backward"), flinward("flinward"); // Like this is more confortable.
2382  string debugMessage;                      // For the debugging.
2383
2384//  if(wardKind==forward)
2385//    anImplementation << "cout <<  \"The number of threads used is: omp_get_num_threads();\" << endl;" << endl;
2386 
2387  if(wardKind == dfward){                   // Case dfward: there are some parameters in input to the genereted function.
2388    anImplementation << "\nint Ydfward_space_" << ord.getName();
2389    anImplementation << "(int modop, char *nmmod, int All, int KeKo, int koleft, float pdx, float ptol, int yi, int yj, int yk)\n{\n\t int nbko=0;\n";
2390  }else anImplementation << "\n int Y" << wardKind << "_space_" << ord.getName() << "()\n{\n"; // Normal case.
2391
2392  Space * spaceOrOperator = theSpaceTable.find(ord.getName());
2393  if(!spaceOrOperator)   
2394    spaceOrOperator = theOperatorTable.find(ord.getName());
2395
2396  anImplementation << "\t YA1=" << spaceOrOperator->getYA(1) << "; YA2=" << spaceOrOperator->getYA(2) << "; YA3=" << spaceOrOperator->getYA(3) << ";\n";
2397
2398  // Init of the grid index loop variables.
2399  anImplementation << "Yi=-1; Yj=-1; Yk=-1; /* init des indices de maille: maj par la boucle si valide*/\n"; 
2400
2401  // In the case of debug.
2402  if( (wardKind==forward  && theContext.isDebugForward())  || 
2403      (wardKind==backward && theContext.isDebugBackward())  || 
2404      (wardKind==linward  && theContext.isDebugLinward()))
2405    anImplementation << "printf (\"dbg: in function: Y" << wardKind << "_space_" << ord.getName() << "\\n\");\n";
2406
2407/*
2408  if(wardKind==forward)
2409    cout << endl << "We are in a forward----" << endl;
2410  else cout << endl << "We are in a backward----" << endl;
2411
2412  for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++){
2413    cout << *token << " ";
2414
2415  }
2416  cout << endl;
2417*/
2418
2419  // For the generation of a parallel forward code we control:
2420  // wardKind==forward we are generating the forward code;
2421  // parallel the option parallel is enabled;
2422  // dimAxe==0 && wasOrder we are in the first axis, the one that we want parallelize.
2423  for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++){
2424    if(*token == "YA1"){
2425      if((wardKind==forward || wardKind==backward) && parallel && dimAxe==0 && wasOrder){
2426        firstAxis=1; // The first axis of the order is i;
2427        anImplementation << "#pragma omp parallel for ";
2428        if(theContext.getThreadsNumber()) anImplementation << "num_threads(" << theContext.getThreadsNumber() << ")" << endl;
2429        else  anImplementation << endl;
2430        anImplementation << "for(YY=0; YY<YA1_" << ord.getName() << "; ++YY){" << endl
2431          << "  Yi=YY;" << endl;
2432      }else anImplementation << "for(Yi=0; Yi<YA1_" << ord.getName() << "; ++Yi)\n";   
2433      wasAxe=true; flagAxe(axeTable, 0, dimAxe); wasOrder=false;
2434    }
2435    else if(*token == "YA2"){
2436      if((wardKind==forward || wardKind==backward) && parallel && dimAxe==0 && wasOrder){
2437        firstAxis=2; // The first axis of the order is j;
2438        anImplementation << "#pragma omp parallel for "; 
2439        if(theContext.getThreadsNumber()) anImplementation << "num_threads(" << theContext.getThreadsNumber() << ")" << endl;
2440        else  anImplementation << endl;
2441        anImplementation << "for(YY=0; YY<YA2_" << ord.getName() << "; ++YY){" << endl
2442                         << "  Yj=YY;" << endl;
2443      }else anImplementation << "for(Yj=0; Yj<YA2_" << ord.getName() << "; ++Yj)\n";
2444      wasAxe=true; flagAxe(axeTable, 1, dimAxe); wasOrder=false; 
2445    }
2446    else if(*token == "YA3"){
2447     if((wardKind==forward || wardKind==backward) && parallel && dimAxe==0 && wasOrder){
2448        firstAxis=3; // The first axis of the order is k;
2449        anImplementation << "#pragma omp parallel for "; 
2450        if(theContext.getThreadsNumber()) anImplementation << "num_threads(" << theContext.getThreadsNumber() << ")" << endl;
2451        else  anImplementation << endl;
2452        anImplementation << "for(YY=0; YY<YA3_" << ord.getName() << "; ++YY){" << endl
2453                         << "  Yk=YY;" << endl;
2454      }else anImplementation << "for(Yk=0; Yk<YA3_" << ord.getName() << "; ++Yk)\n";   
2455     wasAxe=true; flagAxe(axeTable, 2, dimAxe); wasOrder=false;
2456    }
2457    else if(*token == "YB1"){
2458      if((wardKind==forward || wardKind==backward)  && parallel && dimAxe==0 && wasOrder){
2459        firstAxis=1; // The first axis of the order is i;
2460        anImplementation << "#pragma omp parallel for "; 
2461        if(theContext.getThreadsNumber()) anImplementation << "num_threads(" << theContext.getThreadsNumber() << ")" << endl;
2462        else  anImplementation << endl;
2463        anImplementation << "for(YY=YA1_" << ord.getName() << "-1; YY>=0; --YY){" << endl
2464                         << "  Yi=YY;" << endl;
2465      }else anImplementation << "for(Yi=YA1_" << ord.getName() << "-1; Yi>=0; --Yi)\n"; 
2466      wasAxe=true; flagAxe(axeTable, 0, dimAxe); wasOrder=false;
2467    }
2468    else if(*token == "YB2"){
2469      if((wardKind==forward || wardKind==backward) && parallel && dimAxe==0 && wasOrder){
2470        firstAxis=2; // The first axis of the order is j;
2471        anImplementation << "#pragma omp parallel for ";
2472        if(theContext.getThreadsNumber()) anImplementation << "num_threads(" << theContext.getThreadsNumber() << ")" << endl;
2473        else  anImplementation << endl;
2474        anImplementation << "for(YY=YA2_" << ord.getName() << "-1; YY>=0; --YY){" << endl
2475                         << "  Yj=YY;" << endl;
2476      }else anImplementation << "for(Yj=YA2_" << ord.getName() << "-1; Yj>=0; --Yj)\n"; 
2477    wasAxe=true; flagAxe(axeTable, 1, dimAxe); wasOrder=false;}
2478    else if(*token == "YB3"){
2479      if((wardKind==forward || wardKind==backward) && parallel && dimAxe==0 && wasOrder){
2480        firstAxis=3; // The first axis of the order is k;
2481        anImplementation << "#pragma omp parallel for "; 
2482        if(theContext.getThreadsNumber()) anImplementation << "num_threads(" << theContext.getThreadsNumber() << ")" << endl;
2483        else  anImplementation << endl;
2484        anImplementation << "for(YY=YA3_" << ord.getName() << "-1; YY>=0; --YY){" << endl
2485                         << "  Yk=YY;" << endl;
2486      }else anImplementation << "for(Yk=YA3_" << ord.getName() << "-1; Yk>=0; --Yk)\n"; 
2487      wasAxe=true; flagAxe(axeTable, 2, dimAxe); wasOrder=false;
2488    }
2489    else{
2490      if(wasAxe==1){ // If before we had an axe and now is not an axe ==> open parenthesis.
2491        anImplementation << "{\n";
2492        wasAxe = 0;
2493      }
2494      if(*token == "order" || *token == "ORDER"){
2495        wasOrder = true;
2496        if(dimAxe == 0 && (wardKind==forward || wardKind==backward) && theContext.isParallel()){
2497            parallel = parallelVerification(token, ord, wardKind);
2498          /*if(wardKind==forward)
2499            parallel = parallelVerification(token, ord);
2500          else if(wardKind==backward && theSpaceTable.find(ord.getName())->getYA(firstAxis)>1)
2501          {
2502            parallel = true;
2503          }
2504          else parallel=false;
2505            cout << endl << "Valore del first Axis..." << firstAxis;
2506            cout << endl << "Valore dell'asse..." << theSpaceTable.find(ord.getName())->getYA(firstAxis);
2507            cout << endl << "Valore di parallel..." << parallel << endl;
2508
2509          //------------>cout << endl << "The value of the axeTable after is parallel:"<< axeTable[0]<<" "<<axeTable[1]<<" "<<axeTable[2]<<endl; // For see/debug.
2510          //-------->//if(parallel) cout << "PARALLELIZZABILE   " << endl;
2511          //-------->//else cout << "NON parallelizzabile " << endl;
2512        */
2513         
2514          }
2515
2516        continue;
2517      }
2518      if(*token == "forder" || *token == "FORDER"){               
2519        anImplementation << "\n}" << endl;
2520        //cout << endl<<"The value of the axeTable BEFORE the unflag:"<< axeTable[0]<<" "<<axeTable[1]<<" "<<axeTable[2]<<endl; // For see/debug.
2521        unflagAxe(axeTable, ord, token, dimAxe); 
2522        wasOrder=false;
2523        if((wardKind==forward || wardKind==backward) && parallel && dimAxe==0){ 
2524          anImplementation << "}" << endl;
2525        }
2526        //cout <<endl<<"The value of the axeTable AFTER the unflag: "<<axeTable[0]<<" "<<axeTable[1]<<" "<<axeTable[2]<<endl; // For see/debug.
2527      }else{ // Here the token is a module. This module should not be noward.
2528
2529        wasOrder=false;
2530       
2531        // Init for the actual module
2532        mod = theModulTable.find(*token);
2533
2534        // Test: the module should not be noward.
2535        ENFORCE(!mod->isNoward())("order modinspace: ")(mod->getName())(": noward module are not allowed here\n");
2536        // Test: the module should belong to the space.
2537        ENFORCE(mod->getSpaceOrOperator() == ord.getName())("order modinspace: module ")(mod->getName())
2538          (" does not belong to ")(ord.getName())(" space\n");
2539
2540        //CONTROLLARE QUESTO CASO-----------------------------------------------------------------
2541        // Case of dfward_order --->
2542        if(wardKind==dfward){
2543          // Test: if ok we generate the call code to dfward for this module.
2544          if(!mod->isNoward() && mod->getOutput()>0){
2545            // Research of the axes.
2546            searchAxes(axeTable, &a, &b);
2547
2548            // Generation of the dfward code for the current module.
2549            dfwardGeneratorOrderModule(anImplementation, ord, *mod, dimAxe, a, b);
2550          }
2551          continue;
2552        }
2553        // End of case dfward.
2554        // ----------------------------------------------------------------------------------------------
2555
2556        // Creation of the input parameters for the *ward function if necessary (so if not autonet or array, in this case is not useful).
2557        streamInputWardFunctions.str("");
2558        inputWardFunctions = "";
2559        if(!mod->isAutonet() && !mod->isArray()){ 
2560          for(w1=0; w1<mod->getInput(); ++w1) streamInputWardFunctions <<" Yting[" << w1 << "],";
2561          inputWardFunctions = streamInputWardFunctions.str();
2562          if(inputWardFunctions.size()) 
2563            inputWardFunctions.replace(inputWardFunctions.size()-1, 1, " ");
2564        }
2565
2566        // Increment of the counter in the Order directive: warning if it has already appear (only with forward, so the first time).
2567        if(wardKind==forward){ 
2568          if(mod->isCounterOrder()){
2569            cout << "WARNING: the module " << mod->getName() << " appears more than once in order directive\n";
2570            cout << "         you should rather use clone key word !?\n";
2571          }
2572          mod->setCounterOrder(true);
2573        }
2574
2575        // Automatic feed of the input table Yting (this is for the forward, backward and linward).
2576        if(!mod->isManageCtin())
2577          feedward(anImplementation, ord, mod->getName(), 'I', firstAxis,false);
2578
2579        // Feed of Beta (Ytbeta) for the Linear Tangent.
2580        if(wardKind==linward)
2581          feedward(anImplementation, ord, mod->getName(), 'B', firstAxis,false);
2582
2583        // Name of the function to call.
2584        fctWard=wardKind;
2585        if(fctWard==linward){ 
2586          if(!mod->isNetward() && !mod->isAutonet())
2587            fctWard=backward;
2588          else
2589            fctWard=flinward;
2590        }
2591
2592        // We have to reinitialize the Jacobian matrix before the call of backward and linward?
2593        // If there is some input.
2594        if(fctWard==backward && mod->getInput()>0){       
2595          // This should not be necessary for the NN and for hidjac.
2596          if(!mod->isNetward() && !mod->isAutonet() && !mod->isHidjac()){     
2597            anImplementation << "\t memset(Yjac, 0, " << maxNbJacobianInput*mod->getOutput() << "*sizeof(" << theContext.getReal() << "));\n";
2598          }
2599        }
2600
2601        // We write the call to the function *ward().
2602
2603        // Generation of the call to the function *ward(inputWardFunctions) according to the dimension.
2604        // Charles comment: ici, (et PLM) on ne test pas, en particulier pour l'appel a la fonction backward (cas
2605        // de l'Adjoint et du LT), le nombre d'input because of the ghost module concept.
2606        if(dimAxe==1){ 
2607          a=b=' '; //Y a=b=0;
2608          searchAxes(axeTable, &a, &b);
2609          anImplementation << "\t Y" << *token << "(Y" << a << ")->" << fctWard<< "(" << inputWardFunctions << ");\n";
2610        }else if(dimAxe==2){ 
2611          a=b=' '; //Y a=b=0; 
2612          searchAxes(axeTable, &a, &b);
2613          anImplementation << "\t Y" << *token << "(Y" << a << ", Y" << b << ")->" << fctWard << "(" << inputWardFunctions << ");\n";
2614        }else if(dimAxe==3)
2615          anImplementation << "\t Y" << *token << "(Yi, Yj, Yk)->" << fctWard << "(" << inputWardFunctions << ");\n";
2616        else ENFORCE(false)("order modinspace failed: sorry, unpredictable error; dimaxe=")(dimAxe)(" \n");
2617
2618        // Automatic backward and linear tangent: the module must have inputs:
2619        if(mod->getInput()>0){       
2620          if(wardKind==backward){       
2621            // Generation of the computation of the betas (except for the modules NN and hidjac).
2622            if(!mod->isNetward() && !mod->isAutonet() && !mod->isHidjac()){
2623              anImplementation << "\t Yvsmatt (YNBS_" << mod->getName() << ", YNBI_" << mod->getName();
2624              anImplementation << ", YMAX_JAC_NBI, &YG1Y_" << mod->getName() << ", Yjac[0], Ytbeta);\n";
2625            }
2626            // Then retropropagation of betas toward the Alpha (YG: gradient) of the modules predecessor.
2627            if(!mod->isManageCtin())
2628              feedward(anImplementation, ord, mod->getName(), 'A', firstAxis, parallel);
2629
2630            // CONTROLLARE NEL CASO gradtest() che cosa cambia al livello della parallelizazione---------------------------------------------
2631            // For the test of the adjoint on the module.
2632            if(theContext.isGradTest()){
2633              anImplementation << "\t if (Ytestad_module) {\n";
2634              feedward(anImplementation, ord, mod->getName(), 'D', firstAxis, false);
2635              anImplementation << "\t\t\tYLTRes = Yprosca(&YD1Y_" << mod->getName();
2636              anImplementation << ", &YG1Y_" << mod->getName() << ", YNBS_" << mod->getName() << ");\n";
2637
2638              anImplementation << "\t\t\tYAdRes = Yprosca(Yting, Ytbeta, YNBI_" << mod->getName() <<");\n";
2639              anImplementation << "\t\t\tif (!Ytesterrad_mod(\"" << mod->getName() << "\", YLTRes,YAdRes)) return(0);\n\t }\n";
2640            }
2641          }else if(wardKind==linward){
2642            // Generation of the computation of the grad (except for the modules NN and hidjac).
2643            if(!mod->isNetward() && !mod->isAutonet() && !mod->isHidjac()){       
2644              anImplementation << "\t Yvsmat (YNBS_" << mod->getName() << ", YNBI_" << mod->getName();
2645              anImplementation << ", YMAX_JAC_NBI, &YG1Y_" << mod->getName() << ", Yjac[0], Ytbeta);\n";
2646            }
2647            // For the test of the adjoint on the module.
2648            if(theContext.isGradTest()){ 
2649              anImplementation << "\t if (Ytestad_module)\n\t {\tmemcpy(&YD1Y_" << mod->getName() << ", &YG1Y_" << mod->getName();
2650              anImplementation << ", YNBS_" << mod->getName() << "*sizeof(YREAL));\n\t }\n";
2651            }
2652          }
2653        }
2654
2655        // In the case of debug.
2656        if     (wardKind==forward)  debugMessage="F: ";
2657        else if(wardKind==backward) debugMessage="B: ";
2658        else if(wardKind==linward)  debugMessage="L: ";
2659        if(mod->getInput()>0){   // If there are inputs.
2660          if(theContext.isDebugInput())
2661            anImplementation << "\t Ydbg_ting (\"" << debugMessage << "\", YNBI_" << *token << ", \"" << *token << "\");\n";
2662          if(theContext.isDebugBeta()) 
2663            anImplementation << "\t Ydbg_beta (\"" << debugMessage << "\", YNBI_" << *token << ", \"" << *token << "\");\n";
2664          if(theContext.isDebugNan())       
2665            anImplementation << "\t Ydbg_nanf (\"" << debugMessage << "\", YNBI_" << *token << ", \"" << *token << "\");\n";
2666        }
2667
2668        continue;
2669      }
2670    }
2671  }
2672//Solo di prova per adesso per la parallelizazione.......
2673  //anImplementation << endl << "//}" << endl;
2674//  if(wardKind==forward){
2675//  anImplementation << endl << "}" << endl;
2676//  }
2677//.......................................................
2678
2679
2680  if(wardKind==dfward)
2681    anImplementation << "\n\t return(nbko);\n}\n";
2682  else anImplementation << "\n\t return(0);\n}\n";
2683}
2684
2685/**
2686 * The actual number of axes encountered in the scanning of the orderTokens vector is contained in a vector of three elements:
2687 * the three axes YA1, YA2, YA3.
2688 * Every time we do an order for an axe this axe is flagged on the vector. If we do un forder all the axes till the precedent order are unflagged.
2689 * This way we can check the consistency of the user definition and to manage the generation of the code (because we know the actual dimension).
2690 * @param axeTable is the actual axe table to be modified.
2691 * @param axe is the axe to be added to the table.
2692 * @param dimAxe is the actual dimension of the axeTable: the number of true elements
2693 */
2694void Translator::flagAxe(bool axeTable[3], int axe, int & dimAxe){       
2695  // Check if the axe has already been met in the hierarchy.
2696  ENFORCE(!axeTable[axe])("fail: in order, axe ")(axe+1)(" previously appeared \n");
2697  axeTable[axe] = true;
2698  ++dimAxe;
2699}
2700
2701/**
2702 * The actual number of axes encountered in the scanning of the orderTokens vector is contained in a vector of three elements:
2703 * the three axes YA1, YA2, YA3.
2704 * Every time we do an order for an axe this axe is flagged on the vector. If we do un forder all the axes till the precedent order are unflagged.
2705 * This method allows to unflag all the sequence of axes till the precedent order in the vector that contains all the tokens of the order orderTokens.
2706 * It is more or less the opposit of flagAxe().
2707 * @param axeTable is the actual axe table to be modified.
2708 * @param ord is the object Order that we are working at the moment of the method call.
2709 * @param tokenIndex is the actual token pointer where we arrived scanning the sequence.
2710 * @param dimAxe is the actual dimension of the axeTable: the number of true elements.
2711 */
2712void Translator::unflagAxe(bool axeTable[3], Order ord, vector<string>::iterator tokenIndex, int & dimAxe){
2713  int waxe;
2714
2715  // For see/debug
2716  /*cout << endl << "tokens" << endl;
2717    for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++) cout << " " << *token; cout << endl; */
2718
2719  // We firstly find the first axe to be unflagged.
2720  while(1){
2721    waxe = -1;
2722    if(*tokenIndex == "YA1" || *tokenIndex == "YB1") waxe=0;
2723    else if(*tokenIndex == "YA2" || *tokenIndex == "YB2") waxe=1;
2724    else if(*tokenIndex == "YA3" || *tokenIndex == "YB3") waxe=2;
2725    if(waxe!=-1)
2726      if(axeTable[waxe]) // We have found the first axe.
2727        break;
2728    --tokenIndex;
2729    //if(tokenIndex < ord.orderTokens.begin())
2730    //  break;
2731  }
2732
2733  // Then we unflag till the precedent order
2734  while(*tokenIndex != "order" && *tokenIndex != "ORDER" /*&& tokenIndex>=ord.orderTokens.begin()*/){
2735    waxe = -1;
2736    if(*tokenIndex == "YA1" || *tokenIndex == "YB1") waxe=0; 
2737    else if(*tokenIndex == "YA2" || *tokenIndex == "YB2") waxe=1;
2738    else if(*tokenIndex == "YA3" || *tokenIndex == "YB3") waxe=2;
2739    if(waxe!=-1){               
2740      axeTable[waxe]=false;
2741      --dimAxe;
2742      //    printf("deflag: T[%d]=%d \n", waxe, axeTable[waxe]);     // For see/debug.
2743    }
2744    --tokenIndex;
2745  }
2746}
2747
2748/**
2749 * Determination of the actual axes (if the dimension is lesser than three otherwise is 'i', 'j', 'k' for sure).
2750 * At the end of the method the parameter a and b will contain the first and the second axe in function of the actual dimension.
2751 * @param axeTable is the actual axe table.
2752 * @param a is the pointer to the letter that represent the first axe.
2753 * @param b is the pointer to the letter that represent the second axe.
2754 */
2755void Translator::searchAxes(bool axeTable[3], char *a, char *b){       
2756  *a=*b=' ';
2757  // printf("in search: %d %d %d \n", axeTable[0], axeTable[1], axeTable[2]); // For see/debug.
2758  if(axeTable[0]==1){ 
2759    *a='i';
2760    if (axeTable[1]==1) 
2761      *b='j'; 
2762    else *b='k';
2763  }else if (axeTable[1]==1)
2764  {*a='j'; *b='k';}
2765  else *a='k';
2766}
2767
2768/**
2769 * Code generation of the dfward in the directive order of a module.
2770 * This generation allows to test the code of the backward functions by the call of Ytestdf_() function and the check of ko.
2771 * @param anImplementation is the generated file we are writing on.
2772 * @param ord is the object Order that we are working at the moment of the method call.
2773 * @param mod is the module that we are interested for the dfward generation.
2774 * @param dimAxe is the actual dimension of the axeTable: the number of true elements.
2775 * @param a is the the letter that represent the first axe.
2776 * @param b is the the letter that represent the second axe.
2777 */
2778void Translator::dfwardGeneratorOrderModule(ostream& anImplementation, Order ord, Modul mod, int dimAxe, char a, char b){
2779  ostringstream streamInputWardFunctions; // It's useful in order to generate the string inputWardFunctions.
2780  string inputWardFunctions;              // Parameters in input for functions *ward (Yting[i] sequence in Y2_project_file).
2781  int w1;
2782
2783  ENFORCENOT(dimAxe>3 || dimAxe<1)("fail: sorry, unpredictable error dimaxe=")(dimAxe)(" \n");
2784
2785  // Yting feed for this module: we create all the code "Yting[]=Y..." in feedward.
2786  feedward(anImplementation, ord, mod.getName(), 'I', 0, false);
2787
2788  // Test on the module or on "All".
2789  anImplementation << "\tif (!strcmp(nmmod, \"" << mod.getName() << "\") || All)\n\t{\n";
2790
2791  // Remark1 and remark2 : cf dfwardGeneratorModule (gendfward_mod for Charles).
2792
2793  // Creation of the input parameters for the *ward function if necessary (so if not autonet or array, in this case is not useful).
2794  streamInputWardFunctions.str("");
2795  inputWardFunctions = "";
2796  if(!mod.isAutonet() && !mod.isArray()){ 
2797    for(w1=0; w1<mod.getInput(); ++w1) streamInputWardFunctions <<" Yting[" << w1 << "],";
2798    inputWardFunctions = streamInputWardFunctions.str();
2799    if(inputWardFunctions.size()) 
2800      inputWardFunctions.replace(inputWardFunctions.size()-1, 1, " ");
2801  }
2802
2803  // Test on the coordinate point arrived to the end.
2804  anImplementation << "\t if (Yi>=yi && Yj>=yj && Yk>=yk) \n\t {";
2805
2806  // Call of the testdf function according to the axe dimension;
2807  // Charles comment: nb: pas de test pour les modules sans input, les RN, les hidjac mais il faut quand meme faire un forward apres.
2808  if(dimAxe==1){     
2809    if(mod.getInput()>0 && !mod.isNetward() &&  !mod.isAutonet() && !mod.isHidjac()){       
2810      if(mod.getTime() > 0){
2811        anImplementation << "\tnbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() << ",YNBS_";
2812        anImplementation << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Y" << a << "]->Ystate[0],Y";
2813        anImplementation << mod.getName() << "[Y" << a << "]);\n";
2814      }else{
2815        anImplementation << "\tnbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() << ",YNBS_";
2816        anImplementation << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Y" << a << "]->Ystate,Y";
2817        anImplementation << mod.getName() << "[Y" << a << "]);\n";
2818      }
2819    }
2820    anImplementation << "\t\t if (nbko>=koleft) return(nbko);\n\t }\n"; // Test max ko reach.
2821    anImplementation << "\t}\n"; // End of if module or All.
2822    anImplementation << "\t Y" << mod.getName() << "(Y" << a << ")->forward(" << inputWardFunctions << ");\n"; // In any case.
2823  }else if(dimAxe==2){     
2824    if(mod.getInput()>0 && !mod.isNetward() &&  !mod.isAutonet() && !mod.isHidjac()){       
2825      if(mod.getTime() > 0){
2826        anImplementation << "\tnbko += Ytestdf_" << mod.getName()  << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName();
2827        anImplementation << ",YNBS_" << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName();
2828        anImplementation << "[Y" << a << "][Y" << b << "]->Ystate[0],Y" << mod.getName()  << "[Y" << a << "][Y" <<b << "]);\n";
2829      }else{
2830        anImplementation << "\tnbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName();
2831        anImplementation << ",YNBS_" << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Y" << a;
2832        anImplementation << "][Y" << b << "]->Ystate,Y" << mod.getName() << "[Y" << a << "][Y" << b << "]);\n";
2833      }
2834    }
2835    anImplementation << "\t\t if (nbko>=koleft) return(nbko);\n\t }\n"; // Test max ko reach
2836    anImplementation << "\t}\n"; // End of if module or All.
2837    anImplementation << "\t Y" << mod.getName() << "(Y" << a << ", Y" << b << ")->forward(" << inputWardFunctions << ");\n"; // In any case.
2838  }else if(dimAxe==3){     
2839    if(mod.getInput()>0 && !mod.isNetward() &&  !mod.isAutonet() && !mod.isHidjac()){       
2840      if(mod.getTime() > 0){
2841        anImplementation << "\tnbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() << ",YNBS_" << mod.getName() ;
2842        anImplementation << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Yi][Yj][Yk]->Ystate[0],Y" << mod.getName();
2843        anImplementation << "[Yi][Yj][Yk]);\n";
2844      }else{
2845        anImplementation << "\tnbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() ;
2846        anImplementation << ",YNBS_" << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName();
2847        anImplementation << "[Yi][Yj][Yk]->Ystate,Y" << mod.getName() << "[Yi][Yj][Yk]);\n";
2848      }
2849    }
2850    anImplementation << "\t\t if (nbko>=koleft) return(nbko);\n\t }\n"; // Test max ko reach.
2851    anImplementation << "\t}\n"; // End of if module or All.
2852    anImplementation << "\t Y" << mod.getName() << "(Yi, Yj, Yk)->forward(" << inputWardFunctions << ");\n"; // In any case.
2853  }
2854}
2855
2856/**
2857 * Generation of the automatic feed of the Yting global table for the function forward and backward.
2858 * For the backward we have to feed also the Ytbeta global table.
2859 * We manage here also the case of Delta added for the test of the adjoint on the module.
2860 * The Delta case is similar to Input but we employ YD instead of YS.
2861 * We manage here also the case called multi_t.
2862 * With multi_t we mean the cases were the trajectories of the modules, connected with the ctin-m connection, are different and
2863 * we could need to translate the time instant of the input trajectory in the time instant of the out trajectory.
2864 * This translation appear in the code generation of the file Y2projectname.cpp with the function Ytttt_pdt(....).
2865 * All the information needed in order to consider all the cases are already stocked in the object connection.
2866 * multi_t: if relt is -2 or 2 => little 't' with different trajectories => we have to translate.
2867 * Otherwise relt is -1 or 1: in this case, if and only if traj(IN) != traj(OUT) then => capital 'T' => we have to adjust on the traj OUT.
2868 *
2869 * The generation of code in this method is enaugh similar.
2870 * For the input we try to generate instruction like:
2871 * if (1==0 || Yk+1>YA3-1) Yting[12]=0;        else       (if necessary)
2872 * Yting[12]=YS1_MODULE_NAME( Yi, Yj, Yk+1, YTemps-1);    (for all cases)
2873 * For Alphas:
2874 * if (1==0 || Yi-1<0){}  else                            (if necessary)
2875 * @param anImplementation is the generated file we are writing on.
2876 * @param ord is the object Order that we are working at the moment of the method call.
2877 * @param inModule is the module that we are interested on. We work on the connections were the module inModule is the receiver.
2878 * @param ibad is the kind of requested generation. ibad is called like this because the possible values are: 'I', 'B', 'A, 'D'.
2879 * Input feed (Yting)             if ibad='I' (MD, LT)
2880 * Beta gradient (Ytbeta)         if ibad='B' (LT)
2881 * Alpha gradient (YG)            if ibad='A' (Adjoint)
2882 * Delta (YD)                     if ibad='D' (Adjoint for the module)
2883 * @param firstAxis is the first axis of the order? Is used in the parallel generation (for the atomic operations) of the backward: 1=i, 2=j, 3=k.
2884 * @param parallel is this current loop parallel or not. This information is useful for the generation of the adjoint on the backward (ibad='A')
2885 * in order to create un atomic update of the YG with the Ytbeta.
2886 */
2887void Translator::feedward(ostream& anImplementation, Order ord, string inModule, char ibad, int firstAxis, bool parallel){       
2888  Modul * inMod, *outMod;       // The modules of the Connection beeing analyzed.
2889  char inType, outType;         // The operator type of the spaces or operators directives binded with the input/output modules.
2890  int timeCase;                 // In order to manage the cases of translation of the time caused by multi_t (modules connected
2891                                // with different trajectory coordinate.
2892
2893  // We scan all the connections. We are interested to the connections where the module is the receiver.
2894  for(Table<Connection>::iterator con=theConnectionTable.begin(); con != theConnectionTable.end(); con++){
2895    if(con->getInModule() == inModule){ 
2896      // The modules of the connection.
2897      inMod = theModulTable.find(con->getInModule());
2898      outMod = theModulTable.find(con->getOutModule());
2899
2900      // Opera or space: type of computation.
2901      if(inMod->isSpaceOrOperator()) inType = theSpaceTable.find(inMod->getSpaceOrOperator())->getType();
2902      else inType = theOperatorTable.find(inMod->getSpaceOrOperator())->getType();
2903
2904      if(outMod->isSpaceOrOperator()) outType = theSpaceTable.find(outMod->getSpaceOrOperator())->getType();
2905      else outType = theOperatorTable.find(outMod->getSpaceOrOperator())->getType();
2906
2907      // Init of the case.
2908      timeCase=0;
2909
2910      // We need the number id of the trajectory. This is equivalent to the position of the trajectory in the table
2911      // theTrajectoryTable. The number id is used from the generated program, the trajectory at this moment will be
2912      // addressed with a number id: the idOutTrajectory.
2913      int idOutTrajectory=0;
2914      for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){
2915        if(outMod->getTrajectory() != tra->getName())
2916          idOutTrajectory++;
2917        else tra=theTrajectoryTable.end()-1;
2918      }
2919
2920      // In function of relt we set the variable Ytps. We analyze all the cases: relative, absolute, case of time translation.
2921      if(inMod->getTrajectory() == outMod->getTrajectory())    // Case 1, the easiest case: same trajectory.
2922        timeCase = 1; // We will work directly with YTemps.
2923      else if(abs(con->getRelt())==2){         
2924        // Little 't' in connection and different trajectory => translation of the time (including the deplacement).
2925        // We translate the actual traj IN in the traj OUT.
2926        timeCase = 2;
2927        if(con->getRelt()>=1){  //=>2: relative case.
2928          if(!con->getT())
2929            anImplementation << "Ytps = Ytttt_pdt(" << idOutTrajectory << ", YTemps, YidTraj);\n";
2930          else if(con->getT() > 0)
2931            anImplementation << "Ytps = Ytttt_pdt(" << idOutTrajectory << ", YTemps+" << con->getT() << ", YidTraj);\n";
2932          else
2933            anImplementation << "Ytps = Ytttt_pdt(" << idOutTrajectory << ", YTemps" << con->getT() << ", YidTraj);\n";
2934        }
2935        if(con->getRelt()<=-1){ //=>-2: absolute case: (Charles comment ==> probleme : comment savoir si la valeur absolue).
2936          // Charles comment: porte directement sur traj OUT :
2937          if(1) anImplementation << "Ytps = " << con->getT() << ";";         // ?
2938          // Charles comment: ou doit etre une traduction de traj IN pour traj OUT :
2939          else  anImplementation << "Ytps = Ytttt_pdt(" << idOutTrajectory << "," << con->getT() <<" , YidTraj);\n"; // ?
2940        }
2941      }else if(con->getRelt()){         
2942        //=> Charles comment: 'T' => deduire le temps: s'aligner sur celui la trajectoire OUT.
2943        timeCase = 3;
2944        anImplementation << "Ytps = YTabTraj[" << idOutTrajectory << "].toptime;\n";
2945      }else{  // Here we have con->getRelt() == 0: we have to do something jest for the delta zone, used for the test of the adjoint of a module,
2946              // and that is temporised (in order to stock the computation of LT ...
2947        if (ibad=='D'){ 
2948          anImplementation << "\t\t\tYtps = Ytttt_pdt(" << idOutTrajectory << ", YTemps, YidTraj);\n";
2949          timeCase = 4;
2950        }
2951      }
2952
2953      if( (con->getI() !=0 && con->getReli() ==1) || 
2954          (con->getJ() !=0 && con->getRelj() ==1) || 
2955          (con->getK() !=0 && con->getRelk() ==1)  ){
2956
2957        if(ibad!='D') anImplementation << "\t if (1==0";
2958        else anImplementation << "\t\t if (1==0";
2959
2960        if(con->getReli()==1){ 
2961          if(con->getI() < 0)
2962            anImplementation << " || Yi" << con->getI() << "<0";
2963          if(con->getI() > 0)
2964            anImplementation << " || Yi+" << con->getI() << ">YA1_" << ord.getName() << "-1";
2965        }
2966
2967        if(con->getRelj()==1){ 
2968          if(con->getJ() < 0)
2969            anImplementation << " || Yj" << con->getJ() << "<0";
2970          if(con->getJ() > 0)
2971            anImplementation << " || Yj+" << con->getJ() << ">YA2_" << ord.getName() << "-1";
2972        }
2973
2974        if(con->getRelk()==1){ 
2975          if(con->getK() < 0)
2976            anImplementation << " || Yk" << con->getK() << "<0";
2977          if(con->getK() > 0)
2978            anImplementation << " || Yk+" << con->getK() << ">YA3_" << ord.getName() << "-1";
2979        }
2980
2981        if(ibad=='I')             // For the inputs.
2982          anImplementation << ")\n\t Yting[" << con->getIn()-1 << "]=0; \n\t else \n";
2983        else if (ibad=='D')       // For the deltas, like inputs with a \t more.
2984          anImplementation << ")\n\t\t Yting[" << con->getIn()-1 << "]=0; \n\t\t else \n";
2985        else if (ibad=='B')       // For the gradients Beta.
2986          anImplementation << ")\n\t Ytbeta[" << con->getIn()-1 << "]=0; \n\t else \n";
2987        else                      // ibad=='A': For the gradients Alpha.
2988          anImplementation << "){} \n\t else \n";
2989
2990      }   
2991
2992      // Else, we have the normal case.
2993      if(ibad=='I'){                // For the inputs.
2994        if( (inType == 'B' || inType == 'R' || inType == 'K')  &&   
2995            (outType != 'B' && outType != 'R' && outType != 'K')) 
2996          anImplementation << "\t Yting[" << con->getIn()-1 << "]=YW" << con->getOut() << "_" << con->getOutModule() << "(";
2997        else anImplementation << "\t Yting[" << con->getIn()-1 << "]=YS" << con->getOut() << "_" << con->getOutModule() <<"(";
2998      }else if (ibad=='D')    // For the deltas (like input but with YD).
2999        anImplementation << "\t\t\tYting[" << con->getIn()-1 << "]=YD" << con->getOut() << "_" << con->getOutModule() << "(";
3000      else if (ibad=='B')     // For the gradients Beta.
3001        anImplementation << "\t Ytbeta[" << con->getIn()-1 << "]=YG" << con->getOut() << "_" << con->getOutModule() << "(";
3002      else{                   // ibad=='A': case gradients Alpha: backward.
3003        if(firstAxis==1 && con->getReli() && con->getI() ||
3004           firstAxis==2 && con->getRelj() && con->getJ() ||
3005           firstAxis==3 && con->getRelk() && con->getK() ){
3006          if(parallel){
3007            anImplementation << "\t #pragma omp atomic\n";
3008            totalAtomicOperations++;
3009          }
3010        }
3011        anImplementation << "\t YG" << con->getOut() << "_" << con->getOutModule() << "(";
3012      }
3013
3014      // Coordinate i axe.
3015      if(con->getReli()==1){         
3016        if(con->getI()==0)
3017          anImplementation << " Yi";
3018        else if(con->getI() > 0)
3019          anImplementation << " Yi+" << con->getI();
3020        else anImplementation << " Yi" << con->getI();
3021      }
3022      if(con->getReli()==-1) // Absolute case.
3023        anImplementation << " " << con->getI()-1;
3024
3025      // The same for j axe.
3026      if(con->getRelj()==1){         
3027        if(con->getJ()==0)
3028          anImplementation << ", Yj";
3029        else if(con->getJ() > 0)
3030          anImplementation << ", Yj+" << con->getJ();
3031        else
3032          anImplementation << ", Yj" << con->getJ();
3033      }
3034      if(con->getRelj()==-1)
3035        anImplementation << ", " << con->getJ()-1;
3036
3037      // The same for k axe. 
3038      if(con->getRelk()==1){         
3039        if(con->getK() == 0)
3040          anImplementation << ", Yk";
3041        else if(con->getK() > 0)
3042          anImplementation << ", Yk+" << con->getK();
3043        else anImplementation << ", Yk" << con->getK();
3044      }
3045      if (con->getRelk()==-1)
3046        anImplementation << ", " << con->getK()-1;
3047
3048      if( (ibad=='I') &&   
3049          (inType == 'B' || inType == 'R' || inType == 'K') &&   
3050          (outType != 'B' && outType != 'R' && outType != 'K')  )
3051      { // Charles comment: en input, la zone YW ne supporte pas de tempo ... donc pas de coordonnee de temps a constituer.
3052      }
3053      else if(timeCase==1){ // We work directly with YTemps.
3054        if(con->getRelt()==1){  // Relative case.
3055          if(con->getT()==0)
3056            anImplementation << ", YTemps";
3057          else if(con->getT() > 0)
3058            anImplementation << ", YTemps+" << con->getT();
3059          else anImplementation << ", YTemps" << con->getT();
3060        }
3061        if(con->getRelt()==-1) // Absolute case.
3062          anImplementation << ", " << con->getT();
3063      }
3064      else if(timeCase==2)  // We adjust on the time of the out trajectory.
3065        anImplementation << ", Ytps";
3066      else{   // timeCase==3 (ou 0 ou 4) (case timeCase==4 (=>relt==0) we don't manage this here...
3067        // We adjust on the time of the out trajectory.
3068        if(con->getRelt()>=1){  //=>2: relative case.
3069          if(con->getT() == 0)
3070            anImplementation << ", Ytps";
3071          else if(con->getT() > 0)
3072            anImplementation << ", Ytps+" << con->getT();
3073          else anImplementation << ", Ytps" << con->getT();
3074        }
3075        if(con->getRelt()<=-1) //=>-2: Absolute case.
3076          anImplementation << ", " << con->getT();
3077      }
3078
3079      // For Delta non tempo we must have the index of time, that in the case of noward (non tempo) should be 0.
3080      if(con->getRelt()==0 && ibad=='D'){
3081        if(outMod->isNoward())
3082          anImplementation << ", 0";
3083        else if(timeCase==1)
3084          anImplementation << ", YTemps";
3085        else
3086          anImplementation << ", Ytps";
3087      }
3088
3089      if(ibad=='I' || ibad=='D' || ibad=='B') // For Inputs, Delta or Beta gradients.
3090        anImplementation << ");\n";
3091      else     // ibad=='A': For the Alpha gradients.
3092        anImplementation << ") += Ytbeta[" << con->getIn()-1 << "];\n";
3093    }
3094  }
3095}
3096
3097/**
3098 * Generation of the code dfward for the module in a grid point.
3099 * @param anImplementation is the generated file we are writing on.
3100 * @param ord is the object Order that we are working at the moment of the method call.
3101 */
3102// gendfward_maille for Charles
3103void Translator::dfwardGridGenerator(ostream& anImplementation, Order ord){
3104  char a, b;
3105  bool axeTable[3] = {false, false, false}; // A three dimension table that contains true in the relative axe position if the axe token is already met.
3106  int dimAxe=0;                             // The actual dimension of the axeTable: the number of true elements.
3107
3108  if(ord.getOrderPhase()==3){ // Trajectories.
3109    anImplementation << "\nint Ydfward_order_maille(int modop, char *nmmod, int All, int KeKo,  float pdx, float ptol)\n{\n\t int nbko=0;\n";
3110    for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++)
3111      anImplementation << "\t nbko += Ydfward_traj_maille_" << *token << "(modop, nmmod, All, KeKo, pdx, ptol);\n";
3112    anImplementation << "\t return(nbko);\n}\n";
3113  }else if(ord.getOrderPhase()==2){ // Space in traj.
3114    anImplementation << "\nint Ydfward_traj_maille_" << ord.getName() << "(int modop, char *nmmod, int All, int KeKo,  float pdx, float ptol)\n{\n"; 
3115
3116    // We find the id of the trajectory necessary to the generated code.
3117    int idTraj=0;
3118    Table<Trajectory>::iterator tra=theTrajectoryTable.begin();
3119    while(tra != theTrajectoryTable.end() && tra->getName() != ord.getName()){
3120      tra++;
3121      idTraj++;
3122    }
3123
3124    anImplementation << "\t int nbko=0;\n\t if (!Ydftesttt(" << idTraj << ")) return(0);\n";
3125    for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++)
3126      anImplementation << "\t nbko += Ydfward_space_maille_" << *token << "(modop, nmmod, All, KeKo, pdx, ptol);\n";
3127    // In the Charles code there were here the gendfward_opera_maille() function. Is too small so I destroy it.
3128    //for(Table<Operator>::iterator op=theOperatorTable.end(); op<theOperatorTable.begin(); op--)
3129    for(Table<Operator>::reverse_iterator op=theOperatorTable.rbegin(); op!=theOperatorTable.rend(); op++)
3130      anImplementation << "\t nbko += Ydfward_space_maille_" << op->getName() << "(modop, nmmod, All, KeKo, pdx, ptol);\n";
3131    //dfwardOperaGridGenerator(anImplementation);
3132    anImplementation << "\t return(nbko);\n}\n";
3133  }else if(ord.getOrderPhase()==1){
3134    // Here phase = 1: module level (modinspace).
3135
3136    anImplementation << "\nint Ydfward_space_maille_" << ord.getName();
3137    anImplementation << "(int modop, char *nmmod, int All, int KeKo,  float pdx, float ptol)\n{\n\t int nbko=0;\n";
3138
3139    for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++){
3140      if      (*token=="YA1") {flagAxe(axeTable, 0, dimAxe);}                        // Part of code 
3141      else if (*token=="YA2") {flagAxe(axeTable, 1, dimAxe);}                        // necessary to the 
3142      else if (*token=="YA3") {flagAxe(axeTable, 2, dimAxe);}                        // management of the axes
3143      else if (*token=="YB1") {flagAxe(axeTable, 0, dimAxe);}                        // of the modules   
3144      else if (*token=="YB2") {flagAxe(axeTable, 1, dimAxe);}                        // in function of the order.
3145      else if (*token=="YB3") {flagAxe(axeTable, 2, dimAxe);}
3146      else if (*token=="forder" || *token== "FORDER"){               
3147        unflagAxe(axeTable, ord, token, dimAxe);
3148      }else if(theModulTable.find(*token)){ // On ne s'interesse qu'aux modules ...
3149
3150        Modul *mod=theModulTable.find(*token);
3151        // In these cases we generate the dfward call code for this module.
3152        if(!mod->isNoward() && mod->getOutput()>0 ){
3153          // Research of the axes ...
3154          a=b=' ';
3155          searchAxes(axeTable, &a, &b);
3156
3157          // Generation of the code dfward for the module.
3158          dfwardGeneratorModule(anImplementation, ord, *mod, dimAxe, a, b);
3159        }
3160      }
3161    }
3162    anImplementation << "\t return(nbko);\n}\n";
3163  }
3164}
3165
3166// gendfward_opera_maille for Yao8.cs: no more needed, it is considered too small for a new method.
3167
3168/**
3169 * Code generation of the dfward in the directive order of a module.
3170 * This generation allows to test the code of the backward functions by the call of Ytestdf_() function and the check of ko.
3171 * @param anImplementation is the generated file we are writing on.
3172 * @param ord is the object Order that we are working at the moment of the method call.
3173 * @param mod is the module that we are interested for the dfward generation.
3174 * @param dimAxe is the actual dimension of the axeTable: the number of true elements.
3175 * @param a is the letter that represent the first axe.
3176 * @param b is the letter that represent the second axe.
3177 */
3178// gendfward_mod for Yao8.c
3179void Translator::dfwardGeneratorModule(ostream& anImplementation, Order ord, Modul mod, int dimAxe, char a, char b){
3180  ostringstream streamInputWardFunctions; //It's useful in order to generate the string inputWardFunctions.
3181  string inputWardFunctions;              //Parameters in input for functions *ward (Yting[i] sequence in Y2_project_file).
3182
3183  // Yting feed for this module: we create all the code "Yting[]=Y..." in the feedward.
3184  feedward(anImplementation, ord, mod.getName(), 'I', 0, false);
3185
3186  // Test sur que le module ou All.
3187  anImplementation << "\tif (!strcmp(nmmod, \"" << mod.getName() << "\") || All)\n\t{\n";
3188
3189  // Charles comment--> remarque1 : Faut-il faire un forward avant ou apres pour propager les etats (YS) ? Mais en fait,
3190  // est-ce bien utile d'en rajouter puisque testdf en fait des forwards (a un dx pres) !
3191  // sauf pour les RN (que l'on ne test pas et pour lesquels il faut donc quand meme propager) !
3192  // (nb: l'utilisateur est sensed avoir valorised les etats initiaux, De plus, il peut
3193  // les propager avec un forward s'il veut tester sur un pas de temps particulier)
3194  // oui mais remarque2 : Si le test n'a ete demanded que pour un module, le testdf des autres ne
3195  // sera pas fait et donc pas non plus leur forward ... so: faire le forward systematiquement pour tous les modules.
3196
3197  // Creation of the input parameters for the *ward function if necessary (so if not autonet or array, in this case is not useful).
3198  streamInputWardFunctions.str("");
3199  inputWardFunctions = "";
3200  if(!mod.isAutonet() && !mod.isArray()){ 
3201    for(int i=0; i<mod.getInput(); ++i) streamInputWardFunctions <<" Yting[" << i << "],";
3202    inputWardFunctions = streamInputWardFunctions.str();
3203    if(inputWardFunctions.size()) 
3204      inputWardFunctions.replace(inputWardFunctions.size()-1, 1, " ");
3205  }
3206
3207  // Call of the testdf function according to the axe dimension;
3208  // Charles comment: nb: pas de test pour les modules sans input, les RN, les hidjac mais il faut quand meme faire un forward apres.
3209  if(dimAxe==1){     
3210    if(mod.getInput()>0 && !mod.isNetward() &&  !mod.isAutonet() && !mod.isHidjac()){       
3211      if(mod.getTime() > 0){
3212        anImplementation << "\t nbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() ;
3213        anImplementation << ",YNBS_" << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName();
3214        anImplementation << "[Y" << a << "]->Ystate[0],Y" << mod.getName() << "[Y" << a << "]);\n";
3215      }else{
3216        anImplementation << "\t nbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() ;
3217        anImplementation << ",YNBS_" << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Y" << a;
3218        anImplementation << "]->Ystate,Y" << mod.getName() << "[Y" << a << "]);\n";
3219      }
3220    } // cf !^ remarks.
3221    anImplementation << "\t}\n"; // End of the if module or All.
3222    anImplementation << "\t Y" << mod.getName() << "(Y" << a << ")->forward(" << inputWardFunctions << ");\n"; // In any case
3223  }else if(dimAxe==2){     
3224    if(mod.getInput()>0 && !mod.isNetward() &&  !mod.isAutonet() && !mod.isHidjac()){       
3225      if(mod.getTime() > 0){
3226        anImplementation << "\t nbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() << ",YNBS_" << mod.getName() ;
3227        anImplementation << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Y" << a << "][Y" << b;
3228        anImplementation << "]->Ystate[0],Y" << mod.getName() << "[Y" << a << "][Y" << b << "]);\n";
3229      }else{
3230        anImplementation << "\t nbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() ;
3231        anImplementation << ",YNBS_" << mod.getName() << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() ;
3232        anImplementation << "[Y" << a << "][Y" << b << "]->Ystate,Y" << mod.getName() << "[Y" << a << "][Y" << b << "]);\n";
3233      }
3234    } // cf !^ remarks.
3235    anImplementation << "\t}\n"; // End of the if module or All.
3236    anImplementation << "\t Y" << mod.getName() << "(Y" << a << ", Y" << b << ")->forward(" << inputWardFunctions << ");\n"; // In any case.
3237  }else if(dimAxe==3){     
3238    if(mod.getInput()>0 && !mod.isNetward() &&  !mod.isAutonet() && !mod.isHidjac()){       
3239      if(mod.getTime() > 0){
3240        anImplementation << "\t nbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() << ",YNBS_" << mod.getName() ;
3241        anImplementation << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Yi][Yj][Yk]->Ystate[0],Y" << mod.getName()<<"[Yi][Yj][Yk]);\n";
3242      }else{
3243        anImplementation << "\t nbko += Ytestdf_" << mod.getName() << "(modop,KeKo,pdx,ptol,YNBI_" << mod.getName() << ",YNBS_" << mod.getName() ;
3244        anImplementation << ",\"" << mod.getName() << "\",Yting,Y" << mod.getName() << "[Yi][Yj][Yk]->Ystate,Y" << mod.getName() << "[Yi][Yj][Yk]);\n";
3245      }
3246    } // cf !^ remarks.
3247    anImplementation << "\t}\n"; // End of the if module or All.
3248    anImplementation << "\t Y" << mod.getName() << "(Yi, Yj, Yk)->forward(" << inputWardFunctions << ");\n"; // In any case.
3249  }else
3250    ENFORCE(false)("fail: sorry, [4] unpredictable error dimaxe=")(dimAxe)(" \n");
3251}
3252
3253/**
3254 * Manages the code generation of the functions *ward in the multi context.
3255 * This generation is relative only to the spaceintraj option of the order directive (phase2 of the order)
3256 * and for the last trajectories generation (phase3 of the order).
3257 * The ward to be generated in the file Y2projectName.h are: forward, linward, dfward (if GRADTEST option setted) and backward.
3258 * This method is called from the method generateCode.
3259 * @param anImplementation is the generated file we are writing on.
3260 * @param wardKind the kind of *ward to be generated.
3261 * @param ord is the object Order that we are working at the moment of the method call.
3262 */
3263// genorder_multi for Yao8.c
3264void Translator::orderGeneratorMulti(ostream& anImplementation, string wardKind, Order ord){ 
3265  // Phase 2: block (spaceintraj) traj that contains spaces.
3266  string forward("forward"), linward("linward"), dfward("dfward"), backward("backward"), flinward("flinward"); // Like this is more confortable.
3267  // Phase 3: a final block that contains all trajectories needed for particular generation at the end of the directive order.
3268
3269  if(ord.getOrderPhase()==2){  // Spaceintraj.
3270    if(wardKind==dfward){ // With dfward there are parametres.
3271      // We find the id of the trajectory necessary to the generated code.
3272      int idTraj=0;
3273      Table<Trajectory>::iterator tra=theTrajectoryTable.begin();
3274      while(tra != theTrajectoryTable.end() && tra->getName() != ord.getName()){
3275        tra++;
3276        idTraj++;
3277      }
3278      anImplementation << "\nint Ydfward_traj_" << ord.getName() << "(int modop, char *nmmod, int All, int KeKo, int koleft,";
3279      anImplementation << "float pdx, float ptol, int yi, int yj, int yk)\n{\n";
3280      anImplementation << "\t int nbko=0;\n\t if (!Ydftesttt(" << idTraj << ")) return(0);\n";
3281    }else{ 
3282      anImplementation << "\nint Y" << wardKind << "_traj_" << ord.getName() << "(int nbp)\n{\n";
3283      if(wardKind==forward) anImplementation << "\tYcurward=FORWARD;\n";
3284      if(wardKind==linward) anImplementation << "\tYcurward=LINWARD;\n";
3285      if(wardKind==backward) anImplementation << "\tYcurward=BACKWARD;\n";
3286    }
3287    for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++){
3288      Space * spa = theSpaceTable.find(*token);
3289      ENFORCENOT(!spa->isCounterOrderHeader())  // Test: has this space already been in a modinspace (so in a modinspace header).
3290        ("order spaceintraj: no modinspace declared for space ")(*token)(" \n");
3291      if(wardKind==forward){                    // Test only on forward: has this space already been in a spaceintraj (so in a spaceintraj body).
3292        ENFORCENOT(spa->isCounterOrderBody())("order spaceintraj: ")(*token)(" space already appears in a trajectory\n");
3293        spa->setCounterOrderBody(true); // Flag of the counter.
3294      }
3295      ENFORCENOT(spa->getParent()->getName() != ord.getName()) // Test: is this space linked on this trajectory.
3296        ("order spaceintraj: ")(*token)(" space is not on ")(ord.getName())(" trajectory\n");
3297
3298      if(wardKind==dfward) // With dfward there are parametres.
3299        anImplementation << "\t nbko += Ydfward_space_" << *token << "(modop, nmmod, All, KeKo, koleft, pdx, ptol, yi, yj, yk);\n";
3300      else anImplementation << "\t Y" << wardKind << "_space_" << *token << "();\n";
3301    }
3302  }else if(ord.getOrderPhase()==3){  // Final block that contains all trajectories.
3303    // Charles comment: (nb PLM on ne traite pas de trajectoires ni parallele ni temporisees, mais si cela devait, y'aurait surement ARAR).
3304    if(wardKind==dfward){ // With dfward there are parametres.
3305      anImplementation << "\nint Ydfward_order(int modop, char *nmmod, int All, int KeKo, int koleft, float pdx, float ptol, int yi, ";
3306      anImplementation << "int yj, int yk)\n{\n\t int nbko=0;\n";
3307    }else anImplementation << "\nint Y" << wardKind << "_order()\n{\n"; // Ex: Yforward_order (idem *ward).
3308    for(vector<string>::iterator token=ord.orderTokens.begin(); token < ord.orderTokens.end(); token++)
3309      if(wardKind==dfward) // With dfward there are parametres.
3310        anImplementation << "\t nbko += Ydfward_traj_" << *token << "(modop, nmmod, All, KeKo, koleft, pdx, ptol, yi, yj, yk);\n";
3311      else anImplementation << "\t Y" << wardKind << "_traj_" << *token << "(0);\n";
3312  }
3313
3314  if(wardKind==dfward){ 
3315    // In the Charles code there were here the gendfward_opera() function. Is too small so I destroy it.
3316    for(Table<Operator>::reverse_iterator op=theOperatorTable.rbegin(); op!=theOperatorTable.rend(); op++)
3317      anImplementation << "\t nbko += Ydfward_space_" << op->getName() << "(modop, nmmod, All, KeKo, koleft, pdx, ptol, yi, yj, yk);\n";
3318    anImplementation << "\t return(nbko);\n}\n"; // With dfward we return nbko
3319  }
3320  else anImplementation << "\t return(0);\n}\n";
3321}
3322
3323/**
3324 * Used at the end of the Order generation to generate some functions relative to the operators.
3325 * We produce here the *ward of the operators. At the moment we generate only forward_operator, backward_operator and linward_operator
3326 * @param anImplementation is the generated file we are writing on.
3327 */
3328void Translator::wardOperatorGenerator(ostream &anImplementation){ 
3329  // Yforward_operator.
3330  anImplementation << "\nvoid Yforward_operator (char type) \n{\t";
3331  for(Table<Operator>::iterator op=theOperatorTable.begin(); op!=theOperatorTable.end(); op++){               
3332    anImplementation << "\n\tif ((YTabOpera[Yid_" << op->getName() << "].type==type || type=='*')  && YTabOpera[Yid_";
3333    anImplementation << op->getName() << "].isactiv) Yforward_space_" << op->getName() << "();";
3334  }
3335  anImplementation << "\n}";
3336
3337  // Ylinward_operator.
3338  if(theContext.isGradTestOrIncremental()){ 
3339    anImplementation << "\nvoid Ylinward_operator (char type) \n{\t";
3340    for(Table<Operator>::iterator op=theOperatorTable.begin(); op!=theOperatorTable.end(); op++){               
3341      anImplementation << "\n\tif ((YTabOpera[Yid_" << op->getName() << "].type==type || type=='*')  && YTabOpera[Yid_";
3342      anImplementation << op->getName() << "].isactiv) Ylinward_space_" << op->getName() << "();";
3343    }
3344    anImplementation << "\n}";
3345  }
3346
3347  // Ybackward_operator.
3348  anImplementation << "\nvoid Ybackward_operator (char type) \n{\t";
3349  for(Table<Operator>::reverse_iterator op=theOperatorTable.rbegin(); op!=theOperatorTable.rend(); op++){               
3350    anImplementation << "\n\tif ((YTabOpera[Yid_" << op->getName() << "].type==type || type=='*')  && YTabOpera[Yid_";
3351    anImplementation << op->getName() << "].isactiv) Ybackward_space_" << op->getName() << "();";
3352  }
3353  anImplementation << "\n}";
3354}
3355
3356/**
3357 * Code generation for the Function directive.
3358 * @param anImplementation is the generated file we are writing on.
3359 * @param aFunctionTable the table that contains all the Functions.
3360 */
3361void Translator::generateCode(ostream& anImplementation, Table<Function>& aFunctionTable){
3362  Table<Function>::iterator funct;
3363  if(aFunctionTable.size()>0){ // The first time.
3364    funct=aFunctionTable.begin();
3365    anImplementation << "\n\n// € € € € € € € € LES FONCTIONS UTILISATEUR ... : \n";
3366    anImplementation << "int Yuser_call (int argc, char *argv[]) \n{\n\t int codret=1;";
3367    anImplementation << "\n\t if (strcmp(argv[0], \"" << funct->getName() << "\") == 0)\n\t\t " << funct->getName();
3368    if(funct->isParameterized())
3369      anImplementation << "(argc, argv);"; 
3370    else anImplementation << "();"; 
3371  }
3372  if(aFunctionTable.size()>1){ // From the second time we need "else if" in the generated code.
3373    for(funct=aFunctionTable.begin()+1; funct < aFunctionTable.end(); funct++){
3374      anImplementation << "\n\t else if (strcmp(argv[0], \"" << funct->getName() << "\") == 0)\n\t\t " << funct->getName(); 
3375      if(funct->isParameterized())
3376        anImplementation << "(argc, argv);";
3377      else anImplementation << "();"; 
3378    }
3379  }
3380}
3381
3382/**
3383 * Last cronological code generation. We have finished the generation of each directive.
3384 * Here we have some generation that we could not perform before.
3385 * @param aDeclaration is the generated file we are writing on.
3386 * @param anImplementation is the generated file we are writing on.
3387 */
3388void Translator::generateCode(ostream& aDeclaration, ostream& anImplementation){
3389  ostringstream  bufwrk; // A stream buffer to perform some work with strings.
3390
3391  // 1) Treatment for trajectories.
3392  //------------------------------------------------------------------------
3393  aDeclaration << "\n/*------------- DUE TO MULTI TRAJECTOIRIES --------------*/\n";
3394  // Note:  a trajectory could not be present in any Order spaceintraj.
3395  //        For example the user could want to netralize it if on the trajectory are defined only modules noward. In this case:
3396  //       -> non prototype;
3397  //       -> *ward()=NULL
3398  //       -> isactiv=0 (rdg: not changeable if fward==NULL).
3399  aDeclaration << "#define YNBTRAJ        " << theTrajectoryTable.size() << " \n";
3400  //1.1) Prototype of the functions needed to go through the trajectories and other...
3401  for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++)
3402    if(tra->isCounterOrder()){ // If not spaceintraj => we will not have a prototype.
3403      aDeclaration << "int Yforward_traj_" << tra->getName() << "(int nbp);\n";
3404      aDeclaration << "int Ybackward_traj_" << tra->getName() << "(int nbp);\n";
3405      if(theContext.isGradTestOrIncremental()) aDeclaration << "int Ylinward_traj_" << tra->getName() << "(int nbp);\n";
3406      if(theContext.isGradTest()){ 
3407        aDeclaration << "int Ydfward_traj_" << tra->getName() << "(int modop, char *nmmod, int All, int KeKo, int koleft,";
3408        aDeclaration << "float pdx, float ptol, int yi, int yj, int yk);\n";
3409      }
3410    }
3411  if(theContext.isGradTest()) aDeclaration << "int Ydftestijkt(int imod);\nint Ydftesttt(int itraj);\n";
3412
3413  aDeclaration << "\n/*------- GENERATION DU TABLEAU DES TRAJECTOIRES --------*/\n";
3414  // 1.2) Creation of the table of trajectories.
3415  aDeclaration << "struct Yst_traj YTabTraj[" << theTrajectoryTable.size() << "] = {\n";
3416  for(Table<Trajectory>::iterator tra=theTrajectoryTable.begin(); tra != theTrajectoryTable.end(); tra++){   
3417    bufwrk.str("");
3418    if(tra->isCounterOrder()){ 
3419      if(theContext.isGradTestOrIncremental() && theContext.isGradTest()){ 
3420        bufwrk << "Yforward_traj_" << tra->getName() << ", Ybackward_traj_" << tra->getName() << ", Ylinward_traj_";
3421        bufwrk << tra->getName() << ", Ydfward_traj_" << tra->getName() << ", 1";
3422      }else if(theContext.isGradTestOrIncremental())
3423        bufwrk << "Yforward_traj_" << tra->getName() << ", Ybackward_traj_" << tra->getName() << ", Ylinward_traj_" << tra->getName() << ", NULL, 1";
3424      else if(theContext.isGradTest())
3425        bufwrk << "Yforward_traj_" << tra->getName() << ", Ybackward_traj_" << tra->getName() << ", NULL, Ydfward_traj_" << tra->getName() << ", 1";
3426      else bufwrk << "Yforward_traj_" << tra->getName() << ", Ybackward_traj_" << tra->getName() << ", NULL, NULL, 1";
3427    }else // Non spaceintraj => NULL everywhere and inactive.
3428      bufwrk << "NULL, NULL, NULL, NULL, 0";
3429
3430    ENFORCENOT(bufwrk.str().size() >= LG_MAX_STRING)("-->buffer not big enough for trajectories array; see your Yao administrator\n");
3431
3432    // The fixed and setprecision option are needed only for equality with Charles code: we could not put it.
3433    aDeclaration << "\t{\"" << tra->getName() << "\", '" << tra->getType() << "', " << tra->getBoot() << ", " << fixed << setprecision(6);
3434    aDeclaration << tra->getOffset() << ", " << tra->getStep() << ", " << tra->getOffset() << ", " << tra->getBoot() << ", " << tra->getSize();
3435    aDeclaration << ", " << tra->getOffset() + tra->getStep() * tra->getSize(); //stoptime initial (sachant begintime=0)
3436    aDeclaration << ", " << bufwrk.str() << "},\n";
3437  }
3438  aDeclaration << "};\n";
3439
3440  //2) Creation of the spaces table.
3441  //------------------------------------------------------------------------
3442  aDeclaration << "\n/*------- GENERATION DU TABLEAU DES ESPACES --------*/\n";
3443  aDeclaration << "#define YNBSPACE       " << theSpaceTable.size() << " \n";
3444  aDeclaration << "struct Yst_space YTabSpace[" << theSpaceTable.size() << "] = {\n";
3445  for(Table<Space>::iterator spa=theSpaceTable.begin(); spa != theSpaceTable.end(); spa++){
3446    aDeclaration << "\t{\"" << spa->getName() << "\", '" << spa->getProperty(3) << "', " << spa->getYA(1) << ", " << spa->getYA(2) << ", ";
3447    aDeclaration << spa->getYA(3) << ", \"" << spa->getParent()->getName() << "\"},\n";
3448  }
3449  aDeclaration << "};\n";
3450
3451  // 2) Creation of the operators table.
3452  //------------------------------------------------------------------------
3453  aDeclaration << "\n/*------ GENERATION DU TABLEAU DES OPERATEURS -------*/\n";
3454  aDeclaration << "#define YNBOPERA       " << theOperatorTable.size() << " \n";
3455  aDeclaration << "struct Yst_opera YTabOpera[" << theOperatorTable.size() << "] = {\n";
3456  for(Table<Operator>::iterator op=theOperatorTable.begin(); op!=theOperatorTable.end(); op++){               
3457    aDeclaration << "\t{\"" << op->getName() << "\", '" << op->getProperty(3) << "', " << op->getYA(1) << ", " << op->getYA(2);
3458    aDeclaration << ", " << op->getYA(3) << ", \"" << op->getParent()->getName() << "\", 0},\n";
3459  }
3460  aDeclaration << "};\n";
3461
3462  // 3) Creation of the modules table.
3463  //------------------------------------------------------------------------
3464  aDeclaration << "\n/*------- GENERATION D'UN TABLEAU d'ACCES AUX MODULES --------*/\n";
3465  aDeclaration << "#define YNBMODUL       " << theModulTable.size() << " \n";
3466  aDeclaration << "struct Yst_modul YTabMod[" << theModulTable.size() << "] = {\n";
3467  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
3468    aDeclaration << "\t{\"" << mod->getName() << "\", *Y" << mod->getName() << ", " << mod->getNbAxes() << ", " << mod->getYA(1);
3469    aDeclaration << ", " << mod->getYA(2) << ", " << mod->getYA(3) << ", " << mod->getInput() << ", " << mod->getOutput();
3470    aDeclaration << ", " << mod->getTime() << ", " << mod->isCout() << ", " << mod->isTarget() << ", " << mod->getBeginTarget() << scientific;
3471    aDeclaration << ", " << mod->getEndTarget() << ", " << mod->getScoef() << ", " << mod->getBcoef();
3472    aDeclaration << ", " << mod->getPcoef() << ", " << mod->isCounterOrder() << ", \"" << mod->getSpaceOrOperator() << "\"},\n";
3473  }
3474  aDeclaration << "};\n";
3475
3476  // Searching anomalies. We look for ghost and parasit module.
3477  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
3478    int predecessorNumber=0, successorNumber=0;
3479    for(Table<Connection>::iterator con=theConnectionTable.begin(); con != theConnectionTable.end(); con++){
3480      predecessorNumber += (mod->getName() == con->getInModule());
3481      successorNumber += (mod->getName() == con->getOutModule());
3482    }
3483
3484    if(predecessorNumber + successorNumber <=0) // Module without connections.
3485      if(mod->isCounterOrder())
3486        cout << "Warning: Ghost module found --> " << mod->getName() << " \n";
3487      else cout << "Warning: Parasit module found --> " << mod->getName() << " \n";
3488  }
3489
3490  // 3.2) Creation of the flag association module/operateurs table that will allow to guide from the modules the trigger of the operators.
3491  // ------------------------------------------------------------------------
3492  // 3.2.1) For the modules cout : table YTabMocop.
3493  aDeclaration << "\n/*------- GENERATION TABLEAU COUT_MODULES/OPERA --------*/\n";
3494  aDeclaration << "short   YTabMocop[YNBMODUL][YNBOPERA] = {\n";
3495  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++){
3496    bufwrk.str("");
3497    int count=0, i;
3498    for(Table<Operator>::iterator op=theOperatorTable.begin(); op!=theOperatorTable.end(); op++){ 
3499      i=0;
3500      for(vector<string>::iterator listOperator=mod->getLopera().begin(); listOperator!=mod->getLopera().end(); listOperator++){
3501        // It is very strange: *listOperator doesn't work! So I use *(mod->getLopera().begin() + i) and it works.
3502        // Anyway we cannot have more then one element in the vector in this YAO version so we could have *mod->getLopera().begin().
3503        // if(*listOperator == op->getName()){
3504        if(*(mod->getLopera().begin() + i) == op->getName()){
3505          bufwrk << " Yid_" << op->getName() << ",";
3506          ENFORCENOT(bufwrk.str().size()>=LG_MAX_STRING)("-->buffer not big enough for operator array; see your Yao administrator\n");
3507          ++count;
3508          i++;
3509        }
3510      } // End list lopera.
3511    } 
3512    for(int i=count; i<theOperatorTable.size(); ++i){
3513      bufwrk << "  -1,";
3514      ENFORCENOT(bufwrk.str().size()>=LG_MAX_STRING)("-->buffer not big enough for operator array; see your Yao administrator\n");
3515    }
3516    if(bufwrk.str().size()>0){
3517      string str = bufwrk.str();
3518      str.replace(str.size()-1, 1, " ");
3519      aDeclaration << "\t{ " << str << " },\n";
3520    }
3521    else aDeclaration << "\t{  },\n";
3522  } // End for Modules.
3523  aDeclaration << "};\n";
3524
3525  // 4) Creation of the constants table.
3526  // ------------------------------------------------------------------------
3527  // Remark: the constant Y3_M is a particular case of constant. It is in the table of constant but we have already generate all the necessary for it.
3528  // We exclude the generation relative to this constant in this phase.
3529  aDeclaration << "\n//----- GENERATION d'UN TABLEAU de DEFINITIONS de VALEURS -----\n";
3530  aDeclaration << "#define YNBDEFVAL      " << theConstantTable.size()-1 << " \n";
3531  aDeclaration << "struct Yst_defval YTabDefval[" << theConstantTable.size()-1 << "] = {\n";
3532  for(Table<Constant>::const_iterator cons = theConstantTable.begin(); cons != theConstantTable.end(); ++cons)
3533    if(cons->getName() != string("Y3_M")) 
3534      aDeclaration << "\t{\"" << cons->getName() << "\", \"" << cons->getText() << "\"},\n";
3535  aDeclaration << "};\n";
3536
3537  // 5) Automatic replacement of the directives include and module:
3538  // -----------------------------------------------------------------------
3539  // (we have to have a .h for each module!).
3540  // Charles comment: avant, ce code etait genere en fin de traitement des modules, mais il a
3541  // du etre deplaced apres la generation des tableaux car les hat et les modules
3542  // doivent pouvoir s'en servir (des tableaux) qui doivent donc etre declares avant.
3543  aDeclaration << "\n//€ € € € GENERATION AUTOMATIQUE DES include € € € € € € € € € € €\n";
3544  for(vector<string>::const_iterator hat = theHeaderList.begin(); hat != theHeaderList.end(); ++hat) // The hats.h
3545    aDeclaration << "#include \"" << *hat << "\" \n";
3546
3547  // For each module (excepty the autonet, the clones and the noward):
3548  for(Table<Modul>::iterator mod=theModulTable.begin(); mod != theModulTable.end(); mod++)
3549    if(!mod->isAutonet() && !mod->isCloned() && !mod->isNoward()){
3550      aDeclaration << "\n";
3551      aDeclaration << "#define  forward  void " << mod->getName() << "::forward \n";
3552      aDeclaration << "#define  backward void " << mod->getName() << "::backward\n";
3553      aDeclaration << "#define  flinward void " << mod->getName() << "::flinward\n";
3554
3555      bufwrk.str(""); 
3556      if(mod->getTime())
3557        bufwrk << "[" << YTEMPS << "]";
3558
3559      for(int w2=0; w2<mod->getOutput() && w2<NB_MAX_MACRO; ++w2){               
3560        aDeclaration << "#define  YS" << w2+1 << "Y " << YSTATE << bufwrk.str() <<"[" << w2 <<"] \n";
3561        aDeclaration << "#define  YS" << w2+1 << "  " << YSTATE << bufwrk.str() <<"[" << w2 <<"] \n";
3562        aDeclaration << "#define  YG" << w2+1 << "  " << YGRAD << bufwrk.str() <<"[" << w2 <<"] \n";
3563      }
3564      aDeclaration << "#include \"" << mod->getName() << ".h\" \n";
3565      for(int w2=0; w2<mod->getOutput() && w2<NB_MAX_MACRO; ++w2){               
3566        aDeclaration << "#undef   YS" << w2+1 << "Y  \n";
3567        aDeclaration << "#undef   YS" << w2+1 << "   \n";
3568        aDeclaration << "#undef   YG" << w2+1 << "   \n";
3569      }
3570
3571      aDeclaration << "#undef   forward \n";
3572      aDeclaration << "#undef   backward\n";
3573      aDeclaration << "#undef   flinward\n";
3574    }
3575
3576  // 6) Creation of a function Yuser_call empty in the case of no user functions.
3577  // ---------------------------------------------------------------------------
3578  if(!theFunctionTable.size()){ 
3579    anImplementation << "\n\n// € € € € € € € € LES FONCTIONS UTILISATEUR ... : \n";
3580    anImplementation << "int Yuser_call (int argc, char *argv[]) \n{\n\t int codret=0;\n\t if(1) codret=0;";
3581  }
3582  // This is the end of the user functions in both cases if functions exist or not:
3583  anImplementation << "\n\t else codret=0;\n\t return(codret);\n}\n";
3584
3585  aDeclaration << "\n//-------------- end Yao generation -----------------\n";
3586  anImplementation << "\n//-------------- end Yao generation -----------------\n";
3587}
3588
3589
3590/**
3591 * Is the nested loop parallel or not? This method answer to this question.
3592 * These are three examples of the vector orderTokens contained by the object Order, each string of the line is called token:
3593 * 1) order YA1 YA2 M1 M2 M3 forder
3594 * 2) order YA1 order YA2 M1 forder M2 forder
3595 * 3) order YA1 YB2 M1 M2 forder order YB1 YA2 M3 M4 forder
3596 * The last example is interesting because we can see that there are more than one nested loop generated,
3597 * the first one from the first order to the second order and the second for the las couple order-forder.
3598 * The objective of this method is to control that ONE nested loop can be parallelized. We do not scan all the vector in general.
3599 * It scans one interval order-forder and check all the connection between the modules encountered in this interval.
3600 * The condition of parallelization came from the extern loop index (it may be i, j or k) that we call Y and the time of the the connection.
3601 * The connection is defined as:
3602 * M1 from M2 i+ci j+cj k+ck t+ct
3603 * with ci,cj,ck relative integer and ct<=0.
3604 * So we call the extern loop in general Y+cy.
3605 * The bad condition is that cy!=0 and ct==0.
3606 * With these conditions we can perform a domain decomposition and parallelize the forward code.
3607 * This is a frequent case because the conditions has to be verified only for the modules in the current interval order-forder.
3608 * @param token is the current scanning element of the orderTokens vector.
3609 * @param ord is the current order analyzed.
3610 * @param wardKind the kind of *ward to be generated: forward or backward here.
3611 */
3612bool Translator::parallelVerification(vector<string>::iterator token, Order ord, string wardKind){
3613  bool axes[3] = {false, false, false};   // A three dimension table that contains true in the relative axe position if the axe token is already met.
3614  int dAxe=0;                             // The actual dimension of the axeTable: the number of true elements.
3615  bool ret;                               // Return value.
3616  int firstAxis=0;                        // Remember the first axis after the first order (the order with dimAxe=0).
3617  bool inOk, outOk;                       // Used to verify the connection. inOk/outOk is true if the in/out module is contained in the interval.
3618  bool spaceOrOperator = true;            // Used in order to understand if we are managing a Space (true) or an Operator (false).
3619  vector<string> modulesVector;           // Set of the modules contained in the current interval.
3620  vector<Connection> connectionVector;    // Set of the connections to be tested.
3621
3622  // We search the kind of order: Operator or Space?
3623  string name = ord.getName();
3624  for(Table<Operator>::const_iterator op = theOperatorTable.begin(); op != theOperatorTable.end(); ++op)
3625    if(name == op->getName()){
3626      spaceOrOperator = false;
3627      break;
3628    }
3629
3630  // We analyse all the tokens and separate the modules contained in the current interval.
3631  while(true){
3632    token++;
3633    if(*token == "YA1" || *token == "YB1"){
3634      if(dAxe==0) firstAxis=1;
3635      flagAxe(axes, 0, dAxe); 
3636    }
3637    else if(*token == "YA2" || *token == "YB2"){
3638      if(dAxe==0) firstAxis=2;
3639      flagAxe(axes, 1, dAxe);
3640    }
3641    else if(*token == "YA3" || *token == "YB3"){
3642      if(dAxe==0) firstAxis=3;
3643      flagAxe(axes, 2, dAxe); 
3644    }else{
3645      if(*token == "order" || *token == "ORDER")
3646        continue;
3647      if(*token == "forder" || *token == "FORDER"){               
3648//      cout << endl<<"The value of the axeTable BEFORE the unflag:"<< axes[0]<<" "<<axes[1]<<" "<<axes[2]<<endl; // For see/debug.
3649        unflagAxe(axes, NULL, token, dAxe); 
3650//      cout <<endl<<"The value of the axeTable AFTER the unflag: "<<axes[0]<<" "<<axes[1]<<" "<<axes[2]<<endl; // For see/debug.
3651        if(dAxe==0) break;
3652      }else{ // Here the token is a module.
3653        modulesVector.push_back(*token);
3654      }
3655    }
3656  }
3657
3658  // PRIMO ERRORE PARALLELISMO BACKWARD-----------------------
3659  // The backward is always parallel exept in the case tho parallelism option is not enabled and if the axis is not big enough
3660  /*if(wardKind=="backward"){
3661    ret = theContext.isParallel() && theSpaceTable.find(ord.getName())->getYA(firstAxis)>1;
3662    if(ret==true){
3663      parallelBackwardLoops++;
3664      parallelBackwardModules += modulesVector.size();
3665    }
3666    return ret;
3667  }*/
3668
3669  // Scan of all theTableConnection and the selection of the connections that we have to test.
3670  // A connection is to be tested if both the modules are in the interval order-forder.
3671  for(vector<Connection>::iterator conIt=theConnectionTable.begin(); conIt < theConnectionTable.end(); conIt++){
3672    inOk=false;
3673    outOk=false;
3674
3675    // Check of the in module
3676    for(vector<string>::iterator modIt=modulesVector.begin(); modIt!=modulesVector.end(); modIt++){
3677      if(conIt->getInModule() == *modIt){
3678        inOk=true;
3679        break;
3680      }
3681    }
3682
3683    // Check of the out module
3684    if(inOk==true)
3685      for(vector<string>::iterator modIt=modulesVector.begin(); modIt!=modulesVector.end(); modIt++){
3686        if(conIt->getOutModule() == *modIt){
3687          outOk=true;
3688          break;
3689        }
3690      }
3691
3692    if(inOk && outOk)
3693      connectionVector.push_back(*conIt);
3694  }
3695
3696  //-------------->Controllo!
3697  //if(connectionVector.size() == theConnectionTable.size())
3698  //  cout << endl << "Sono uguali, size: " << connectionVector.size() << endl;
3699  //else cout << endl << "Sono diversi, size: " << connectionVector.size() << endl;
3700
3701  // Final test of the connections: ct=0 && cY!=0.
3702  // We consider only relative connections. The absolute connections in the vector connectionVector are always not parallelizable.
3703  // The connection value cY is between 1 and YX1 so they are always detected by the condition defined.
3704  ret=true;
3705  for(vector<Connection>::iterator conIt=connectionVector.begin(); conIt < connectionVector.end(); conIt++){
3706    if(firstAxis==1 && !conIt->getT() && conIt->getI()){ 
3707    //cout << "   conIt->getName()" << conIt->getName() << endl;
3708      ret=false; break; }
3709    else if(firstAxis==2 && !conIt->getT() && conIt->getJ()){ 
3710    //cout << "   conIt->getName()" << conIt->getName() << endl;
3711      ret=false; break; }
3712    else if(firstAxis==3 && !conIt->getT() && conIt->getK()){ 
3713    //cout << "   conIt->getName()" << conIt->getName() << endl;
3714      ret=false; break; }
3715  }
3716
3717  // (theSpaceTable.find(ord.getName())->getYA(1) > 1) the axis that we want to decompose
3718  // is big than 1 otherwise the parallelism make no sense.
3719  if((wardKind=="forward" || wardKind=="backward") && ret){
3720    if(spaceOrOperator){
3721      if(theSpaceTable.find(ord.getName())->getYA(firstAxis)<=1){
3722        ret=false;
3723        cout << endl << "The axis of the domain decomposition for the order modinspace " << ord.getName() 
3724          << " is not big enaugh: " << theSpaceTable.find(ord.getName())->getYA(firstAxis) << endl
3725          << "the parallelization is not useful and because of that the parallel code is not generated." << endl;
3726      }
3727    }else if(theOperatorTable.find(ord.getName())->getYA(firstAxis)<=1){
3728      ret=false;
3729      cout << endl << "The axis of the domain decomposition for the order modinspace " << ord.getName() 
3730        << " is not big enaugh: " << theOperatorTable.find(ord.getName())->getYA(firstAxis) << endl
3731        << "the parallelization is not useful and because of that the parallel code is not generated." << endl;
3732    }
3733  }
3734
3735  //-------------------->
3736  //  for(vector<string>::iterator t=modulesVector.begin(); t < modulesVector.end(); t++){cout << "mod:   " << *t << endl;  }
3737
3738  if(wardKind=="forward"){
3739    if(ret==true){
3740      parallelForwardLoops++;
3741      parallelForwardModules += modulesVector.size();
3742    }
3743    totalLoops++;
3744    totalModulesInOrders += modulesVector.size(); 
3745  }
3746//  cout << "-------------------Sono parallelo?: " << (ret && theContext.isParallel()) << endl << endl << endl;
3747  return ret && theContext.isParallel();
3748}
Note: See TracBrowser for help on using the repository browser.