Example #1
0
  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";
    }
  }
Example #2
0
  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";
  }
Example #3
0
  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";
  }