io_instruction.cpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #include "io_instruction.hpp"
27 #include "serializing_stream.hpp"
28 
29 namespace casadi {
30  Input::Input(const Sparsity& sp, casadi_int ind, casadi_int segment, casadi_int offset)
31  : IOInstruction(ind, segment, offset) {
32  set_sparsity(sp);
33  }
34 
35  std::string Input::disp(const std::vector<std::string>& arg) const {
36  std::stringstream s;
37  s << "input[" << ind_ << "][" << segment_ << "]";
38  return s.str();
39  }
40 
42  const std::vector<casadi_int>& arg,
43  const std::vector<casadi_int>& res,
44  const std::vector<bool>& arg_is_ref,
45  std::vector<bool>& res_is_ref) const {
46  casadi_int nnz = this->nnz();
47  if (nnz==0) return; // quick return
48  std::string a = g.arg(ind_);
49  casadi_int i = res.front();
50  if (nnz==1) {
51  g << g.workel(i) << " = " << a << " ? " << a << "[" << offset_ << "] : 0;\n";
52  } else if (offset_==0) {
53  if (g.elide_copy(nnz)) {
54  g << g.work(i, nnz, true) << " = " << a << " ? " << a << " : " << g.zeros(nnz) << ";\n";
55  res_is_ref[0] = true;
56  } else {
57  g << g.copy(a, nnz, g.work(i, nnz, false)) << "\n";
58  }
59  } else {
60  if (g.elide_copy(nnz)) {
61  g << g.work(i, nnz, true) << " = " << a << " ? " << a + "+" + str(offset_)
62  << " : " << g.zeros(nnz) << ";\n";
63  res_is_ref[0] = true;
64  } else {
65  g << g.copy(a + " ? " + a + "+" + str(offset_) + " : 0",
66  nnz, g.work(i, nnz, false)) << "\n";
67  }
68  }
69  }
70 
71  Output::Output(const MX& x, casadi_int ind, casadi_int segment, casadi_int offset)
72  : IOInstruction(ind, segment, offset) {
73  set_dep(x);
74  }
75 
76  std::string Output::disp(const std::vector<std::string>& arg) const {
77  std::stringstream s;
78  s << "output[" << ind_ << "][" << segment_ << "]";
79  return s.str();
80  }
81 
83  const std::vector<casadi_int>& arg,
84  const std::vector<casadi_int>& res,
85  const std::vector<bool>& arg_is_ref,
86  std::vector<bool>& res_is_ref) const {
87  casadi_int nnz = dep().nnz();
88  if (nnz==0) return; // quick return
89  casadi_int i = arg.front();
90  std::string r = g.res(ind_);
91  if (nnz==1) {
92  g << "if (" << r << ") " << r << "[" << offset_ << "] = " << g.workel(i) << ";\n";
93  } else if (offset_==0) {
94  g << g.copy(g.work(i, nnz, arg_is_ref[0]), nnz, r) << "\n";
95  } else {
96  g << "if (" << r << ") "
97  << g.copy(g.work(i, nnz, arg_is_ref[0]), nnz, r + "+" + str(offset_)) << "\n";
98  }
99 
100  }
101 
103  Dict ret;
104  ret["ind"] = ind_;
105  ret["segment"] = segment_;
106  ret["offset"] = offset_;
107  return ret;
108  }
109 
112  s.pack("IOInstruction::ind", ind_);
113  s.pack("IOInstruction::segment", segment_);
114  s.pack("IOInstruction::offset", offset_);
115  }
116 
118  s.unpack("IOInstruction::ind", ind_);
119  s.unpack("IOInstruction::segment", segment_);
120  s.unpack("IOInstruction::offset", offset_);
121  }
122 
123 } // namespace casadi
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string arg(casadi_int i) const
Refer to argument.
std::string copy(const std::string &arg, std::size_t n, const std::string &res)
Create a copy operation.
std::string workel(casadi_int n) const
std::string res(casadi_int i) const
Refer to resuly.
bool elide_copy(casadi_int sz)
std::string zeros(casadi_int sz)
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
An input or output instruction.
IOInstruction(casadi_int ind, casadi_int segment, casadi_int offset)
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Dict info() const override
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Input(const Sparsity &sp, casadi_int ind, casadi_int segment, casadi_int offset)
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
Node class for MX objects.
Definition: mx_node.hpp:51
casadi_int nnz(casadi_int i=0) const
Definition: mx_node.hpp:389
const MX & dep(casadi_int ind=0) const
dependencies - functions that have to be evaluated before this one
Definition: mx_node.hpp:354
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.
Definition: mx_node.cpp:523
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
Definition: mx_node.cpp:222
void set_dep(const MX &dep)
Set unary dependency.
Definition: mx_node.cpp:226
MX - Matrix expression.
Definition: mx.hpp:92
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
Output(const MX &x, casadi_int ind, casadi_int segment, casadi_int offset)
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
General sparsity class.
Definition: sparsity.hpp:106
The casadi namespace.
Definition: archiver.cpp:28
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.