CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
lang_c_default_var_name_gen.hpp
1 #ifndef CPPAD_CG_LANG_C_DEFAULT_VAR_NAME_GEN_INCLUDED
2 #define CPPAD_CG_LANG_C_DEFAULT_VAR_NAME_GEN_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2012 Ciengis
6  * Copyright (C) 2018 Joao Leal
7  *
8  * CppADCodeGen is distributed under multiple licenses:
9  *
10  * - Eclipse Public License Version 1.0 (EPL1), and
11  * - GNU General Public License Version 3 (GPL3).
12  *
13  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
14  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
15  * ----------------------------------------------------------------------------
16  * Author: Joao Leal
17  */
18 
19 namespace CppAD {
20 namespace cg {
21 
27 template<class Base>
28 class LangCDefaultVariableNameGenerator : public VariableNameGenerator<Base> {
29 protected:
30  // auxiliary string stream
31  std::stringstream _ss;
32  // array name of the dependent variables
33  std::string _depName;
34  // array name of the independent variables
35  std::string _indepName;
36  // array name of the temporary variables
37  std::string _tmpName;
38  // array name of the temporary array variables
39  std::string _tmpArrayName;
40  // sparse array name of the temporary array variables
41  std::string _tmpSparseArrayName;
42  // the lowest variable ID used for the temporary variables
43  size_t _minTemporaryID;
44  // the highest variable ID used for the temporary variables
45  size_t _maxTemporaryID;
46  // the highest ID used for the temporary array variables
47  size_t _maxTemporaryArrayID;
48  // the highest ID used for the temporary sparse array variables
49  size_t _maxTemporarySparseArrayID;
50 public:
51 
52  inline explicit LangCDefaultVariableNameGenerator(std::string depName = "y",
53  std::string indepName = "x",
54  std::string tmpName = "v",
55  std::string tmpArrayName = "array",
56  std::string tmpSparseArrayName = "sarray") :
57  _depName(std::move(depName)),
58  _indepName(std::move(indepName)),
59  _tmpName(std::move(tmpName)),
60  _tmpArrayName(std::move(tmpArrayName)),
61  _tmpSparseArrayName(std::move(tmpSparseArrayName)),
62  _minTemporaryID(0), // not really required (but it avoids warnings)
63  _maxTemporaryID(0), // not really required (but it avoids warnings)
64  _maxTemporaryArrayID(0), // not really required (but it avoids warnings)
65  _maxTemporarySparseArrayID(0) { // not really required (but it avoids warnings)
66 
67  this->_independent.push_back(FuncArgument(_indepName));
68  this->_dependent.push_back(FuncArgument(_depName));
69  this->_temporary.push_back(FuncArgument(_tmpName));
70  this->_temporary.push_back(FuncArgument(_tmpArrayName));
71  this->_temporary.push_back(FuncArgument(_tmpSparseArrayName));
72  }
73 
74  inline virtual ~LangCDefaultVariableNameGenerator() = default;
75 
76  inline size_t getMinTemporaryVariableID() const override {
77  return _minTemporaryID;
78  }
79 
80  inline size_t getMaxTemporaryVariableID() const override {
81  return _maxTemporaryID;
82  }
83 
84  inline size_t getMaxTemporaryArrayVariableID() const override {
85  return _maxTemporaryArrayID;
86  }
87 
88  size_t getMaxTemporarySparseArrayVariableID() const override {
89  return _maxTemporarySparseArrayID;
90  }
91 
92  inline std::string generateDependent(size_t index) override {
93  _ss.clear();
94  _ss.str("");
95 
96  _ss << _depName << "[" << index << "]";
97 
98  return _ss.str();
99  }
100 
101  inline std::string generateIndependent(const OperationNode<Base>& independent,
102  size_t id) override {
103  _ss.clear();
104  _ss.str("");
105 
106  _ss << _indepName << "[" << (id - 1) << "]";
107 
108  return _ss.str();
109  }
110 
111  inline std::string generateTemporary(const OperationNode<Base>& variable,
112  size_t id) override {
113  _ss.clear();
114  _ss.str("");
115 
116  if (this->_temporary[0].array) {
117  _ss << _tmpName << "[" << (id - this->_minTemporaryID) << "]";
118  } else {
119  _ss << _tmpName << id;
120  }
121 
122  return _ss.str();
123  }
124 
125  std::string generateTemporaryArray(const OperationNode<Base>& variable,
126  size_t id) override {
127  _ss.clear();
128  _ss.str("");
129 
130  CPPADCG_ASSERT_UNKNOWN(variable.getOperationType() == CGOpCode::ArrayCreation)
131 
132  _ss << "&" << _tmpArrayName << "[" << (id - 1) << "]";
133 
134  return _ss.str();
135  }
136 
138  size_t id) override {
139  _ss.clear();
140  _ss.str("");
141 
142  CPPADCG_ASSERT_UNKNOWN(variable.getOperationType() == CGOpCode::SparseArrayCreation)
143 
144  _ss << "&" << _tmpSparseArrayName << "[" << (id - 1) << "]";
145 
146  return _ss.str();
147  }
148 
150  size_t id,
151  const IndexPattern& ip) override {
152  CPPADCG_ASSERT_KNOWN(var.getOperationType() == CGOpCode::LoopIndexedDep, "Invalid node type")
153  CPPADCG_ASSERT_KNOWN(!var.getArguments().empty(), "Invalid number of arguments")
154 
155  _ss.clear();
156  _ss.str("");
157 
158  _ss << _depName << "[" << LanguageC<Base>::indexPattern2String(ip, getIndexes(var, 1)) << "]";
159 
160  return _ss.str();
161  }
162 
163  std::string generateIndexedIndependent(const OperationNode<Base>& independent,
164  size_t id,
165  const IndexPattern& ip) override {
166  CPPADCG_ASSERT_KNOWN(independent.getOperationType() == CGOpCode::LoopIndexedIndep, "Invalid node type")
167  CPPADCG_ASSERT_KNOWN(independent.getArguments().size() > 0, "Invalid number of arguments")
168 
169  _ss.clear();
170  _ss.str("");
171 
172  _ss << _indepName << "[" << LanguageC<Base>::indexPattern2String(ip, getIndexes(independent, 0)) << "]";
173 
174  return _ss.str();
175  }
176 
177  inline void setTemporaryVariableID(size_t minTempID,
178  size_t maxTempID,
179  size_t maxTempArrayID,
180  size_t maxTempSparseArrayID) override {
181  _minTemporaryID = minTempID;
182  _maxTemporaryID = maxTempID;
183  _maxTemporaryArrayID = maxTempArrayID;
184  _maxTemporarySparseArrayID = maxTempSparseArrayID;
185 
186  // if
187  // _minTemporaryID == _maxTemporaryID + 1
188  // then no temporary variables are being used
189  CPPADCG_ASSERT_UNKNOWN(_minTemporaryID <= _maxTemporaryID + 1)
190  }
191 
192  const std::string& getIndependentArrayName(const OperationNode<Base>& indep,
193  size_t id) override {
194  return _indepName;
195  }
196 
198  size_t id) override {
199  return id - 1;
200  }
201 
203  size_t idFirst,
204  const OperationNode<Base>& indepSecond,
205  size_t idSecond) override {
206  return idFirst + 1 == idSecond;
207  }
208 
210  size_t id1,
211  const OperationNode<Base>& indep2,
212  size_t id2) override {
213  return true;
214  }
215 
216  const std::string& getTemporaryVarArrayName(const OperationNode<Base>& var,
217  size_t id) override {
218  return _tmpName;
219  }
220 
222  size_t id) override {
223  return id - this->_minTemporaryID;
224  }
225 
227  size_t idFirst,
228  const OperationNode<Base>& varSecond,
229  size_t idSecond) override {
230  return idFirst + 1 == idSecond;
231  }
232 
234  size_t id1,
235  const OperationNode<Base>& var2,
236  size_t id2) override {
237  return true;
238  }
239 
240 protected:
241 
242  static inline std::vector<const OperationNode<Base>*> getIndexes(const OperationNode<Base>& var,
243  size_t offset) {
244  const std::vector<Argument<Base> >& args = var.getArguments();
245  std::vector<const OperationNode<Base>*> indexes(args.size() - offset);
246 
247  for (size_t a = offset; a < args.size(); a++) {
248  CPPADCG_ASSERT_KNOWN(args[a].getOperation() != nullptr, "Invalid argument")
249  CPPADCG_ASSERT_KNOWN(args[a].getOperation()->getOperationType() == CGOpCode::Index, "Invalid argument")
250 
251  indexes[a - offset] = &static_cast<const IndexOperationNode<Base>*> (args[a].getOperation())->getIndex();
252  }
253 
254  return indexes;
255  }
256 };
257 
258 } // END cg namespace
259 } // END CppAD namespace
260 
261 #endif
std::string generateIndexedDependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip) override
std::string generateTemporarySparseArray(const OperationNode< Base > &variable, size_t id) override
std::string generateIndependent(const OperationNode< Base > &independent, size_t id) override
std::string generateTemporary(const OperationNode< Base > &variable, size_t id) override
const std::vector< Argument< Base > > & getArguments() const
STL namespace.
void setTemporaryVariableID(size_t minTempID, size_t maxTempID, size_t maxTempArrayID, size_t maxTempSparseArrayID) override
bool isInSameTemporaryVarArray(const OperationNode< Base > &var1, size_t id1, const OperationNode< Base > &var2, size_t id2) override
std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id) override
size_t getTemporaryVarArrayIndex(const OperationNode< Base > &var, size_t id) override
size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id) override
CGOpCode getOperationType() const
bool isConsecutiveInTemporaryVarArray(const OperationNode< Base > &varFirst, size_t idFirst, const OperationNode< Base > &varSecond, size_t idSecond) override
std::string generateIndexedIndependent(const OperationNode< Base > &independent, size_t id, const IndexPattern &ip) override
const std::string & getIndependentArrayName(const OperationNode< Base > &indep, size_t id) override
const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id) override
bool isConsecutiveInIndepArray(const OperationNode< Base > &indepFirst, size_t idFirst, const OperationNode< Base > &indepSecond, size_t idSecond) override
bool isInSameIndependentArray(const OperationNode< Base > &indep1, size_t id1, const OperationNode< Base > &indep2, size_t id2) override