void Call::generate(CodeGenerator& g, const std::string& mem, const vector<int>& arg, const vector<int>& res) const { if (fcn_->simplifiedCall()) { // Collect input arguments for (int i=0; i<arg.size(); ++i) { g << "w[" << i << "]=" << g.workel(arg[i]) << ";\n"; } // Call function g << g(fcn_, "w", "w+"+g.to_string(arg.size())) << ";\n"; // Collect output arguments for (int i=0; i<res.size(); ++i) { if (res[i]>=0) { g << g.workel(res[i]) << "=w[" << (arg.size()+i) << "];\n"; } } } else { // Collect input arguments g.local("arg1", "const real_t", "**"); for (int i=0; i<arg.size(); ++i) { g << "arg1[" << i << "]=" << g.work(arg[i], fcn_.nnz_in(i)) << ";\n"; } // Collect output arguments g.local("res1", "real_t", "**"); for (int i=0; i<res.size(); ++i) { g << "res1[" << i << "]=" << g.work(res[i], fcn_.nnz_out(i)) << ";\n"; } // Call function g << "if (" << g(fcn_, "arg1", "res1", "iw", "w") << ") return 1;\n"; } }
void BinaryMX<ScX, ScY>:: generate(CodeGenerator& g, const std::string& mem, const std::vector<int>& arg, const std::vector<int>& res) const { // Quick return if nothing to do if (nnz()==0) return; // Check if inplace bool inplace; switch (op_) { case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: inplace = res[0]==arg[0]; break; default: inplace = false; break; } // Scalar names of arguments (start assuming all scalars) string r = g.workel(res[0]); string x = g.workel(arg[0]); string y = g.workel(arg[1]); // Codegen loop, if needed if (nnz()>1) { // Iterate over result g.local("rr", "real_t", "*"); g.local("i", "int"); g << "for (i=0, " << "rr=" << g.work(res[0], nnz()); r = "(*rr++)"; // Iterate over first argument? if (!ScX && !inplace) { g.local("cr", "const real_t", "*"); g << ", cr=" << g.work(arg[0], dep(0).nnz()); x = "(*cr++)"; } // Iterate over second argument? if (!ScY) { g.local("cs", "const real_t", "*"); g << ", cs=" << g.work(arg[1], dep(1).nnz()); y = "(*cs++)"; } // Close loop g << "; i<" << nnz() << "; ++i) "; } // Perform operation g << r << " "; if (inplace) { g << casadi_math<double>::sep(op_) << "= " << y; } else { g << " = " << casadi_math<double>::print(op_, x, y); } g << ";\n"; }
void Switch::codegen_body(CodeGenerator& g) const { // Project arguments with different sparsity if (project_in_) { // Project one or more argument g.local("i", "casadi_int"); g << "const casadi_real** arg1 = arg + " << n_in_ << ";\n"; } // Temporary memory for results with different sparsity if (project_out_) { // Project one or more results g.local("i", "casadi_int"); g << "casadi_real** res1 = res + " << n_out_ << ";\n"; } if (project_in_) g << "for (i=0; i<" << n_in_-1 << "; ++i) arg1[i]=arg[i+1];\n"; if (project_out_) g << "for (i=0; i<" << n_out_ << "; ++i) res1[i]=res[i];\n"; // Codegen condition bool if_else = f_.size()==1; g.add_auxiliary(CodeGenerator::AUX_TO_INT); g << (if_else ? "if" : "switch") << " (arg[0] ? casadi_to_int(*arg[0]) : 0) {\n"; // Loop over cases/functions for (casadi_int k=0; k<=f_.size(); ++k) { // For if, reverse order casadi_int k1 = if_else ? 1-k : k; if (!if_else) { // Codegen cases if (k1<f_.size()) { g << "case " << k1 << ":\n"; } else { g << "default:\n"; } } else if (k1==0) { // Else g << "} else {\n"; } // Get the function: const Function& fk = k1<f_.size() ? f_[k1] : f_def_; if (fk.is_null()) { g << "return 1;\n"; } else { // Project arguments with different sparsity for (casadi_int i=0; i<n_in_-1; ++i) { const Sparsity& f_sp = fk.sparsity_in(i); const Sparsity& sp = sparsity_in_[i+1]; if (f_sp!=sp) { if (f_sp.nnz()==0) { g << "arg1[" << i << "]=0;\n"; } else { g.local("t", "casadi_real", "*"); g << "t=w, w+=" << f_sp.nnz() << ";\n" << g.project("arg1[" + str(i) + "]", sp, "t", f_sp, "w") << "\n" << "arg1[" << i << "]=t;\n"; } } } // Temporary memory for results with different sparsity for (casadi_int i=0; i<n_out_; ++i) { const Sparsity& f_sp = fk.sparsity_out(i); const Sparsity& sp = sparsity_out_[i]; if (f_sp!=sp) { if (f_sp.nnz()==0) { g << "res1[" << i << "]=0;\n"; } else { g << "res1[" << i << "]=w, w+=" << f_sp.nnz() << ";\n"; } } } // Function call g << "if (" << g(fk, project_in_ ? "arg1" : "arg+1", project_out_ ? "res1" : "res", "iw", "w") << ") return 1;\n"; // Project results with different sparsity for (casadi_int i=0; i<n_out_; ++i) { const Sparsity& f_sp = fk.sparsity_out(i); const Sparsity& sp = sparsity_out_[i]; if (f_sp!=sp) { g << g.project("res1[" + str(i) + "]", f_sp, "res[" + str(i) + "]", sp, "w") << "\n"; } } // Break (if switch) if (!if_else) g << "break;\n"; } } // End switch/else g << "}\n"; }