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 | |
---|
32 | using namespace std; |
---|
33 | using namespace yao; |
---|
34 | |
---|
35 | //-------------------GLOBAL VARIABLES---------------------------------------- |
---|
36 | string projectName; |
---|
37 | int maxNbInput = 0; // The old Wmaxnbi: the max number of input for a module. |
---|
38 | int maxNbOutput = 0; // The old Wmaxnbs: the max number of output for a module. |
---|
39 | int maxNbJacobianInput = 0; // The old Wmaxjacnbi: the max number of input for a module that needs automatic jacobian operations. |
---|
40 | int maxNbJacobianOutput = 0; // The old Wmaxjacnbs: the max number of output for a module that needs automatic jacobian operations. |
---|
41 | char buffer[BUFSIZE + 1]; // Used in particular to perform the format. |
---|
42 | int clonLevel = 0; // Is the level of the clone: 2 all, 1 something. |
---|
43 | |
---|
44 | // For the profiling of the parallelism: |
---|
45 | int totalLoops = 0; // Is the total number of loops generated analysing the order directive. |
---|
46 | int 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. |
---|
48 | int 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. |
---|
50 | int totalModulesInOrders = 0; // Is the total number of modules that are present in the order directive. |
---|
51 | int 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 | */ |
---|
58 | Translator::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 | */ |
---|
69 | void 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 | */ |
---|
226 | void 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 | */ |
---|
277 | void 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 | */ |
---|
297 | void 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 | */ |
---|
317 | void 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 | */ |
---|
344 | void 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 | */ |
---|
1823 | void 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 | */ |
---|
1911 | void 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 |
---|
1925 | void 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 | */ |
---|
1971 | void 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 | */ |
---|
2178 | void 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. |
---|
2231 | void 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. |
---|
2366 | void 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 | */ |
---|
2694 | void 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 | */ |
---|
2712 | void 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 | */ |
---|
2755 | void 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 | */ |
---|
2778 | void 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 | */ |
---|
2887 | void 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 |
---|
3103 | void 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 |
---|
3179 | void 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 |
---|
3264 | void 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 | */ |
---|
3328 | void 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 | */ |
---|
3361 | void 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 | */ |
---|
3388 | void 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 | */ |
---|
3612 | bool 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 | } |
---|