CoDiPack  2.3.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
commonReaderWriterBase.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2024 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://scicomp.rptu.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://scicomp.rptu.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <cstdio>
38#include <cstdlib>
39#include <string>
40#include <vector>
41
42#include "../../config.h"
43#include "tapeReaderWriterInterface.hpp"
44
46namespace codi {
51 std::string fileName;
52
54 CommonReaderWriterMethods(std::string const& name) : fileName(name) {};
57
59 std::string modifyFileName(std::string const& suffix) {
60 std::string::size_type sepPosition = fileName.rfind('.');
61 return fileName.substr(0, sepPosition) + suffix;
62 }
63
67 void openFile(FILE*& fileHandle, std::string const& name, std::string const& mode) {
68 fileHandle = fopen(name.c_str(), mode.c_str());
69 if (nullptr == fileHandle) {
70 CODI_EXCEPTION("Could not open file %s", name.c_str());
71 }
72 }
73 };
74
83 template<typename T_Type>
85 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
86 using Identifier = typename Type::Identifier;
87 using Tape = typename Type::Tape;
88
89 std::vector<Identifier> inputVariables;
90 std::vector<Identifier> outputVariables;
91
93 CommonBaseTapeWriter(std::string const& name, std::vector<Identifier> const& in,
94 std::vector<Identifier> const& out)
96
97 protected:
98
100 void printIoText(Tape& tape) {
101 FILE* ioFileHandleTxt = nullptr;
102 this->openFile(ioFileHandleTxt, modifyFileName("IO.txt"), "w");
103
104 fprintf(ioFileHandleTxt, "%zu Inputs = ", inputVariables.size());
105 for (size_t inputCount = 0; inputCount < inputVariables.size(); inputCount++) {
106 fprintf(ioFileHandleTxt, "%d ", inputVariables[inputCount]);
107 }
108 fprintf(ioFileHandleTxt, "\n%zu Outputs = ", outputVariables.size());
109 for (size_t outputCount = 0; outputCount < outputVariables.size(); outputCount++) {
110 fprintf(ioFileHandleTxt, "%d ", outputVariables[outputCount]);
111 }
112 fprintf(ioFileHandleTxt, "\nLargest Index = %d", tape.getIndexManager().getLargestCreatedIndex());
113 fclose(ioFileHandleTxt);
114 }
115
117 void printIoBinary(Tape& tape) {
118 FILE* ioFileHandleBinary = nullptr;
119
120 this->openFile(ioFileHandleBinary, modifyFileName("IO.dat"), "wb");
121
122 size_t nInputs = inputVariables.size();
123 size_t nOutputs = outputVariables.size();
124
125 fwrite(&nInputs, sizeof(nInputs), 1, ioFileHandleBinary);
126 fwrite(&inputVariables[0], sizeof(Identifier), nInputs, ioFileHandleBinary);
127 fwrite(&nOutputs, sizeof(nOutputs), 1, ioFileHandleBinary);
128 fwrite(&outputVariables[0], sizeof(Identifier), nOutputs, ioFileHandleBinary);
129 Identifier largestIndex = tape.getIndexManager().getLargestCreatedIndex();
130 fwrite(&largestIndex, sizeof(Identifier), 1, ioFileHandleBinary);
131
132 fclose(ioFileHandleBinary);
133 }
134 };
135
142 template<typename T_Type>
144 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
145 using Tape = typename Type::Tape;
146 using Identifier = typename Type::Identifier;
147
148 std::vector<Identifier> inputVariables;
149 std::vector<Identifier> outputVariables;
150 size_t nInputs;
151 size_t nOutputs;
152
154
157
158 protected:
159
162 FILE* ioFileHandleTxt;
163 this->openFile(ioFileHandleTxt, modifyFileName("IO.txt"), "r+");
164
165 fscanf(ioFileHandleTxt, "%zu Inputs = ", &nInputs);
166 inputVariables.resize(nInputs, 0);
167 for (size_t inputCount = 0; inputCount < nInputs; inputCount++) {
168 fscanf(ioFileHandleTxt, "%d ", &inputVariables[inputCount]);
169 }
170 fscanf(ioFileHandleTxt, "\n%zu Outputs = ", &nOutputs);
171 outputVariables.resize(nOutputs, 0);
172 for (size_t outputCount = 0; outputCount < nOutputs; outputCount++) {
173 fscanf(ioFileHandleTxt, "%d ", &outputVariables[outputCount]);
174 }
175 fscanf(ioFileHandleTxt, "\nLargest Index = %d", &largestIndex);
176 fclose(ioFileHandleTxt);
177 }
178
181 FILE* fileIoHandleBin;
182 this->openFile(fileIoHandleBin, modifyFileName("IO.dat"), "rb");
183
184 fread(&nInputs, sizeof(nInputs), 1, fileIoHandleBin);
185 inputVariables.resize(nInputs, 0);
186 fread(inputVariables.data(), sizeof(Identifier), nInputs, fileIoHandleBin);
187 fread(&nOutputs, sizeof(nOutputs), 1, fileIoHandleBin);
188 outputVariables.resize(nOutputs, 0);
189 fread(outputVariables.data(), sizeof(Identifier), nOutputs, fileIoHandleBin);
190 fread(&largestIndex, sizeof(Identifier), 1, fileIoHandleBin);
191 }
192
195 return tape;
196 }
197
199 std::vector<Identifier> const& getInputs() const& {
200 return inputVariables;
201 }
202
204 std::vector<Identifier> const& getOutputs() const& {
205 return outputVariables;
206 }
207
209 void updateUserIO(Identifier const& linearOffset) {
210 if (Tape::TapeTypes::IsLinearIndexHandler && !TapeTraits::IsPrimalValueTape<Tape>::value) {
211 // For the linear case, user IO is updated with a potential offset.
212 for (size_t inputCount = 0; inputCount < inputVariables.size(); inputCount++) {
213 inputVariables[inputCount] -= linearOffset;
214 }
215
216 for (size_t outputCount = 0; outputCount < outputVariables.size(); outputCount++) {
217 outputVariables[outputCount] -= linearOffset;
218 }
219 }
220 }
221 };
222
230 template<typename T_Type>
232 using Type = CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
234
235 using Tape = typename Type::Tape;
236 using Identifier = typename Type::Identifier;
237 using Real = typename Type::Real;
238
240
241 FILE* fileHandleGraph = nullptr;
242
243 std::vector<Identifier> identifierExtensions;
245 std::vector<IdentifierType> identifierType;
247
248 CommonTextTapeWriter(bool writeDotHeaderFooter, std::string const& name, std::vector<Identifier> const& in,
249 std::vector<Identifier> const& out)
250 : Base(name, in, out),
252 fileHandleGraph(nullptr),
254 identifierType(0) {}
255
257 void start(Tape& tape) {
258 // Resize vectors to maximum index.
259 identifierExtensions.resize(tape.getIndexManager().getLargestCreatedIndex() + 1, 0);
260 identifierType.resize(tape.getIndexManager().getLargestCreatedIndex() + 1, IdentifierType::Temp);
261
262 // Record the input and output identifiers in the identifierType vector. This is used later to colour code the
263 // nodes and avoids searching through the input and output vectors for each statement.
264 for (size_t inputCount = 0; inputCount < this->inputVariables.size(); inputCount++) {
265 identifierType[this->inputVariables[inputCount]] = IdentifierType::Input;
266 }
267
268 for (size_t outputCount = 0; outputCount < this->outputVariables.size(); outputCount++) {
269 identifierType[this->outputVariables[outputCount]] = IdentifierType::Output;
270 }
271
272 this->openFile(fileHandleGraph, this->fileName, "w");
273
274 if (writeDotHeaderFooter) {
275 // Print out the header and add a color index.
276 fprintf(fileHandleGraph,
277 "digraph Net {\nInputs [label = \"Inputs\", color=\"blue\"];\nOutputs [label = \"Outputs\", "
278 "color=\"red\"];\nInter [label = \"Inter\"];\n");
279 }
280 }
281
283 void finish() {
285 fprintf(this->fileHandleGraph, "}");
286 }
287 fclose(this->fileHandleGraph);
288 }
289
290 protected:
292 std::string formatNodeName(Identifier const& identifier, int extensionOffset = 0) {
293 return "A" + std::to_string(identifier) + "_" +
294 std::to_string(identifierExtensions[identifier] + extensionOffset);
295 }
296
298 std::string nodeColorProperties(Identifier const& identifier) {
299 if (identifierType[identifier] == IdentifierType::Input) {
300 return "blue";
301 } else if (identifierType[identifier] == IdentifierType::Output) {
302 return "red";
303 } else {
304 return "black";
305 }
306 }
307
309 void createNode(Identifier const& identifier, std::string const& label) {
310 std::string node = formatNodeName(identifier, 1) + " [label = \"" + label + "\", color=\"" +
311 nodeColorProperties(identifier) + "\"];\n";
312 fprintf(this->fileHandleGraph, "%s", node.c_str());
313 }
314
316 std::string formatNodeLabel(Identifier const& identifier) {
317 std::string result;
318 if (this->identifierType[identifier] == IdentifierType::Input) {
319 result = "X";
320 } else if (this->identifierType[identifier] == IdentifierType::Output) {
321 result = "Y";
322 } else {
323 result = "T";
324 }
325
326 result += std::to_string(identifier);
327
328 return result;
329 }
330
332 void replaceAll(std::string& str, const std::string& search, const std::string& replace) {
333 size_t start_pos = 0;
334 while ((start_pos = str.find(search, start_pos)) != std::string::npos) {
335 str.replace(start_pos, search.length(), replace);
336 start_pos += replace.length();
337 }
338 }
339
344 std::string modifyMathRep(std::string const& mathRep, Identifier const& lhsIdentifier,
345 Identifier const* const rhsIdentifiers, size_t const& nActiveValues) {
346 std::string result = formatNodeLabel(lhsIdentifier) + " = " + mathRep;
347 // Iterate through the RHS and replace x1..xn with the identifier type and the identifier value.
348 for (size_t curArg = 0; curArg < nActiveValues; curArg++) {
349 std::string searchString = "x" + std::to_string(rhsIdentifiers[curArg]);
350 std::string replaceString = formatNodeLabel(rhsIdentifiers[curArg]);
351
352 replaceAll(result, searchString, replaceString);
353 }
354
355 return result;
356 }
357
359 void placeUnusedRhsNodes(Identifier const* const rhsIdentifiers, Config::ArgumentSize const& nArguments) {
360 // Check if the identifierExtension is zero for any of the rhsIdentifiers. A zero extension indicates that the
361 // node has not been placed. The type of the identifier is then checked to add the correct colour coding.
362 for (size_t argCount = 0; argCount < nArguments; argCount++) {
363 if (this->identifierExtensions[rhsIdentifiers[argCount]] == 0) {
364 createNode(rhsIdentifiers[argCount], formatNodeLabel(rhsIdentifiers[argCount]));
365 // Increment the extension of the newly placed identifier.
366 this->identifierExtensions[rhsIdentifiers[argCount]] += 1;
367 }
368 }
369 }
370
372 void createEdge(Identifier const& from, Identifier const& to, std::string const& label = "") {
373 std::string edge = formatNodeName(from) + " -> " + formatNodeName(to, 1);
374
375 if (0 != label.size()) {
376 edge += " [label=\"" + label + "\"];";
377 }
378 edge += "\n";
379 fprintf(this->fileHandleGraph, "%s", edge.c_str());
380 }
381 };
382}
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:94
uint8_t ArgumentSize
Type for the number of arguments in statements.
Definition config.h:117
CoDiPack - Code Differentiation Package.
Definition codi.hpp:91
Used to restore the IO from the "filename"IO.dat or "filename"IO.txt files. Also provides the get met...
Definition commonReaderWriterBase.hpp:143
void restoreIoText()
Constructor.
Definition commonReaderWriterBase.hpp:161
void updateUserIO(Identifier const &linearOffset)
This method is used to remove any offset and to update the largest created index.
Definition commonReaderWriterBase.hpp:209
typename Type::Tape Tape
See TapeReaderInterface.
Definition commonReaderWriterBase.hpp:145
T_Type Type
See TapeReaderInterface.
Definition commonReaderWriterBase.hpp:144
Tape & getTape()
Used to get a reference to the restored tape.
Definition commonReaderWriterBase.hpp:194
size_t nOutputs
Size of the output vector.
Definition commonReaderWriterBase.hpp:151
std::vector< Identifier > const & getInputs() const &
Used to get the restored inputs of the tape.
Definition commonReaderWriterBase.hpp:199
std::vector< Identifier > outputVariables
Stores the restored output variables from the tape file.
Definition commonReaderWriterBase.hpp:149
Tape tape
The newly resorted tape.
Definition commonReaderWriterBase.hpp:153
std::vector< Identifier > const & getOutputs() const &
Definition commonReaderWriterBase.hpp:204
Identifier largestIndex
The largest index on the stored tape.
Definition commonReaderWriterBase.hpp:155
typename Type::Identifier Identifier
See TapeReaderInterface.
Definition commonReaderWriterBase.hpp:146
size_t nInputs
Size of the input vector.
Definition commonReaderWriterBase.hpp:150
std::vector< Identifier > inputVariables
Stores the restored input variables from the tape file.
Definition commonReaderWriterBase.hpp:148
void restoreIoBinary()
Restore the IO for the binary readers.
Definition commonReaderWriterBase.hpp:180
This class is a common base for all the writers and produces a IO file that contains the input and ou...
Definition commonReaderWriterBase.hpp:84
void printIoText(Tape &tape)
Generate the IO file in a text format.
Definition commonReaderWriterBase.hpp:100
std::vector< Identifier > outputVariables
The identifiers which have been registered as outputs.
Definition commonReaderWriterBase.hpp:90
CommonBaseTapeWriter(std::string const &name, std::vector< Identifier > const &in, std::vector< Identifier > const &out)
Constructor.
Definition commonReaderWriterBase.hpp:93
std::vector< Identifier > inputVariables
The identifiers which have been registered as inputs.
Definition commonReaderWriterBase.hpp:89
T_Type Type
See TapeWriterInterface.
Definition commonReaderWriterBase.hpp:85
typename Type::Tape Tape
See TapeWriterInterface.
Definition commonReaderWriterBase.hpp:87
typename Type::Identifier Identifier
See TapeWriterInterface.
Definition commonReaderWriterBase.hpp:86
void printIoBinary(Tape &tape)
Generate the IO file in a binary format.
Definition commonReaderWriterBase.hpp:117
Used to implement methods common to both the tape readers and the tape writers.
Definition commonReaderWriterBase.hpp:50
CommonReaderWriterMethods(std::string const &name)
Constructor.
Definition commonReaderWriterBase.hpp:54
CommonReaderWriterMethods()
Constructor.
Definition commonReaderWriterBase.hpp:56
std::string fileName
The base file name provided by the user.
Definition commonReaderWriterBase.hpp:51
std::string modifyFileName(std::string const &suffix)
Remove the file extension and replace it with a new suffix.
Definition commonReaderWriterBase.hpp:59
void openFile(FILE *&fileHandle, std::string const &name, std::string const &mode)
Definition commonReaderWriterBase.hpp:67
This base class is used to modify the math representation of a statement.
Definition commonReaderWriterBase.hpp:231
std::vector< Identifier > identifierExtensions
Definition commonReaderWriterBase.hpp:243
void replaceAll(std::string &str, const std::string &search, const std::string &replace)
Replaces all substrings of search with replace in str.
Definition commonReaderWriterBase.hpp:332
std::string formatNodeName(Identifier const &identifier, int extensionOffset=0)
Add the identifier extension of the identifier to the node name.
Definition commonReaderWriterBase.hpp:292
std::vector< IdentifierType > identifierType
Definition commonReaderWriterBase.hpp:245
FILE * fileHandleGraph
The handle for the writer.
Definition commonReaderWriterBase.hpp:241
void start(Tape &tape)
Destructor.
Definition commonReaderWriterBase.hpp:257
typename Type::Identifier Identifier
See TapeWriterInterface.
Definition commonReaderWriterBase.hpp:236
bool writeDotHeaderFooter
This flag sets toggles the heading and color index.
Definition commonReaderWriterBase.hpp:239
std::string formatNodeLabel(Identifier const &identifier)
Return a string with the current identifier type and the identifier value.
Definition commonReaderWriterBase.hpp:316
std::string nodeColorProperties(Identifier const &identifier)
Returns the color for a given identifier.
Definition commonReaderWriterBase.hpp:298
CommonTextTapeWriter(bool writeDotHeaderFooter, std::string const &name, std::vector< Identifier > const &in, std::vector< Identifier > const &out)
Constructor.
Definition commonReaderWriterBase.hpp:248
typename Type::Tape Tape
See TapeWriterInterface.
Definition commonReaderWriterBase.hpp:235
T_Type Type
See TapeWriterInterface.
Definition commonReaderWriterBase.hpp:232
typename Type::Real Real
See TapeWriterInterface.
Definition commonReaderWriterBase.hpp:237
void createNode(Identifier const &identifier, std::string const &label)
Creates a new node for a given Identifier and label.
Definition commonReaderWriterBase.hpp:309
void createEdge(Identifier const &from, Identifier const &to, std::string const &label="")
Return a string that creates an edge between two nodes in the .dot language.
Definition commonReaderWriterBase.hpp:372
std::string modifyMathRep(std::string const &mathRep, Identifier const &lhsIdentifier, Identifier const *const rhsIdentifiers, size_t const &nActiveValues)
Replaces all general identifiers in the math representation with the input, output or temporary annot...
Definition commonReaderWriterBase.hpp:344
void placeUnusedRhsNodes(Identifier const *const rhsIdentifiers, Config::ArgumentSize const &nArguments)
Ensure that all the nodes on the rhs have been placed in the .dot file before creating edges to them.
Definition commonReaderWriterBase.hpp:359
void finish()
After all the statements have been written, the finish method finalizes the writing process.
Definition commonReaderWriterBase.hpp:283
The interface is used by all the tape readers. The tape readers are used to restore a tape from eithe...
Definition tapeReaderWriterInterface.hpp:250
If the tape inherits from PrimalValueBaseTape.
Definition tapeTraits.hpp:97
The interface used by all the tape writers. The tape writers are used to generate text,...
Definition tapeReaderWriterInterface.hpp:128