void SXFunctionInternal::spAdj(bvec_t** arg, bvec_t** res, int* iw, bvec_t* w) { fill_n(w, sz_w(), 0); // Propagate sparsity backward for (vector<AlgEl>::reverse_iterator it=algorithm_.rbegin(); it!=algorithm_.rend(); ++it) { // Temp seed bvec_t seed; // Propagate seeds switch (it->op) { case OP_CONST: case OP_PARAMETER: w[it->i0] = 0; break; case OP_INPUT: if (arg[it->i1]!=0) arg[it->i1][it->i2] |= w[it->i0]; w[it->i0] = 0; break; case OP_OUTPUT: if (res[it->i0]!=0) { w[it->i1] |= res[it->i0][it->i2]; res[it->i0][it->i2] = 0; } break; default: // Unary or binary operation seed = w[it->i0]; w[it->i0] = 0; w[it->i1] |= seed; w[it->i2] |= seed; } } }
void SXFunctionInternal::spInit(bool fwd) { // Quick return if just-in-time compilation for // sparsity pattern propagation, no work vector needed #ifdef WITH_OPENCL if (just_in_time_sparsity_) { return; // Quick return } #endif // WITH_OPENCL // We need a work array containing unsigned long rather than doubles. // Since the two datatypes have the same size (64 bits) // we can save overhead by reusing the double array alloc(); bvec_t *iwork = get_bvec_t(w_tmp_); if (!fwd) fill_n(iwork, sz_w(), bvec_t(0)); }
void SXFunctionInternal::generateBody(CodeGenerator& g) const { // Which variables have been declared vector<bool> declared(sz_w(), false); // Run the algorithm for (vector<AlgEl>::const_iterator it = algorithm_.begin(); it!=algorithm_.end(); ++it) { // Indent g.body << " "; if (it->op==OP_OUTPUT) { g.body << "if (res[" << it->i0 << "]!=0) " << "res["<< it->i0 << "][" << it->i2 << "]=" << "a" << it->i1; } else { // Declare result if not already declared if (!declared[it->i0]) { g.body << "real_t "; declared[it->i0]=true; } // Where to store the result g.body << "a" << it->i0 << "="; // What to store if (it->op==OP_CONST) { g.body << g.constant(it->d); } else if (it->op==OP_INPUT) { g.body << "arg[" << it->i1 << "] ? arg[" << it->i1 << "][" << it->i2 << "] : 0"; } else { int ndep = casadi_math<double>::ndeps(it->op); casadi_math<double>::printPre(it->op, g.body); for (int c=0; c<ndep; ++c) { if (c==0) { g.body << "a" << it->i1; } else { casadi_math<double>::printSep(it->op, g.body); g.body << "a" << it->i2; } } casadi_math<double>::printPost(it->op, g.body); } } g.body << ";" << endl; } }
/** \brief Get the length of the work vector */ virtual int getWorkSize() const { return sz_w();}