Ejemplo n.º 1
0
void Densification::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd){
  bvec_t *inputd = get_bvec_t(input[0]->data());
  bvec_t *outputd = get_bvec_t(output[0]->data());
  
  int d1 = input[0]->size1();
  int d2 = input[0]->size2();
  const vector<int>& rowind = input[0]->rowind();
  const vector<int>& col = input[0]->col();
  
  int k=0; // index of the result
  for(int i=0; i<d1; ++i){ // loop over rows
    for(int el=rowind[i]; el<rowind[i+1]; ++el){ // loop over the non-zero elements
      int j=col[el];  // column
      for(; k<i*d2+j; ++k){
        if(fwd) outputd[k] = 0; // add zeros before the non-zero element
      }
      
      // add the non-zero element
      if(fwd){
        outputd[k] = inputd[el];
      } else {
        inputd[el] |= outputd[k];
      }
      k++;
    }
  }
  
  // add sparse zeros at the end of the matrix
  for(; k<d1*d2; ++k)
    if(fwd) outputd[k] = 0;
}
Ejemplo n.º 2
0
void UnaryMX::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd){
  bvec_t *inputd = get_bvec_t(input[0]->data());
  bvec_t *outputd = get_bvec_t(output[0]->data());
  if(fwd){
    copy(inputd,inputd+size(),outputd);
  } else {
    int nz = input[0]->data().size();
    for(int el=0; el<nz; ++el){
      inputd[el] |= outputd[el];
    }
  }
}
Ejemplo n.º 3
0
  void Reshape::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd) {
    // Quick return if inplace
    if (input[0]==output[0]) return;

    bvec_t *res_ptr = get_bvec_t(output[0]->data());
    vector<double>& arg = input[0]->data();
    bvec_t *arg_ptr = get_bvec_t(arg);
    if (fwd) {
      copy(arg_ptr, arg_ptr+arg.size(), res_ptr);
    } else {
      for (int k=0; k<arg.size(); ++k) {
        *arg_ptr++ |= *res_ptr;
        *res_ptr++ = 0;
      }
    }
  }
Ejemplo n.º 4
0
 void Concat::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd) {
   bvec_t *res_ptr = get_bvec_t(output[0]->data());
   for (int i=0; i<input.size(); ++i) {
     vector<double>& arg_i = input[i]->data();
     bvec_t *arg_i_ptr = get_bvec_t(arg_i);
     if (fwd) {
       copy(arg_i_ptr, arg_i_ptr+arg_i.size(), res_ptr);
       res_ptr += arg_i.size();
     } else {
       for (int k=0; k<arg_i.size(); ++k) {
         *arg_i_ptr++ |= *res_ptr;
         *res_ptr++ = 0;
       }
     }
   }
 }
Ejemplo n.º 5
0
  void UnaryMX::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd) {
    // Quick return if inplace
    if (input[0]==output[0]) return;

    bvec_t *inputd = get_bvec_t(input[0]->data());
    bvec_t *outputd = get_bvec_t(output[0]->data());
    if (fwd) {
      copy(inputd, inputd+size(), outputd);
    } else {
      int nz = input[0]->data().size();
      for (int el=0; el<nz; ++el) {
        bvec_t s = outputd[el];
        outputd[el] = bvec_t(0);
        inputd[el] |= s;
      }
    }
  }
Ejemplo n.º 6
0
  void GetNonzerosSlice::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd) {
    // Get references to the assignment operations and data
    bvec_t *outputd = get_bvec_t(output[0]->data());
    bvec_t *inputd = get_bvec_t(input[0]->data());

    // Propagate sparsity
    if (fwd) {
      for (int k=s_.start_; k!=s_.stop_; k+=s_.step_) {
        *outputd++ = inputd[k];
      }
    } else {
      for (int k=s_.start_; k!=s_.stop_; k+=s_.step_) {
        inputd[k] |= *outputd;
        *outputd++ = 0;
      }
    }
  }
Ejemplo n.º 7
0
  void GetNonzerosVector::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd) {
    // Get references to the assignment operations and data
    bvec_t *outputd = get_bvec_t(output[0]->data());
    bvec_t *inputd = get_bvec_t(input[0]->data());

    // Propagate sparsity
    if (fwd) {
      for (vector<int>::const_iterator k=nz_.begin(); k!=nz_.end(); ++k) {
        *outputd++ = *k>=0 ? inputd[*k] : 0;
      }
    } else {
      for (vector<int>::const_iterator k=nz_.begin(); k!=nz_.end(); ++k) {
        if (*k>=0) inputd[*k] |= *outputd;
        *outputd++ = 0;
      }
    }
  }
Ejemplo n.º 8
0
 void Multiplication<TrX,TrY>::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd){
   bvec_t *zd = get_bvec_t(input[0]->data());
   bvec_t *rd = get_bvec_t(output[0]->data());
   const size_t n = this->size();
   if(fwd){
     if(zd!=rd) copy(zd,zd+n,rd);
     DMatrix::mul_sparsity<true>(*input[1],*input[2],*input[0]);
   } else {
     DMatrix::mul_sparsity<false>(*input[1],*input[2],*output[0]);
     if(zd!=rd){
       for(int i=0; i<n; ++i){
         zd[i] |= rd[i];
         rd[i] = bvec_t(0);
       }
     }
   }
 }
Ejemplo n.º 9
0
 void InnerProd::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd){
   bvec_t& res = *get_bvec_t(output[0]->data());
   bvec_t* arg0 = get_bvec_t(input[0]->data());
   bvec_t* arg1 = get_bvec_t(input[1]->data());
   const int n = input[0]->size();
   if(fwd){
     res = 0;
     for(int i=0; i<n; ++i){
       res |= *arg0++ | *arg1++;
     }
   } else {
     for(int i=0; i<n; ++i){
       *arg0++ |= res;
       *arg1++ |= res;
     }
     res = 0;
   }
 }
Ejemplo n.º 10
0
void ParallelizerInternal::spEvaluateTask(bool use_fwd, int task){
  // Get a reference to the function
  FX& fcn = funcs_[task];

  if(use_fwd){
    // Set input influence
    for(int j=inind_[task]; j<inind_[task+1]; ++j){
      int nv = input(j).size();
      const bvec_t* p_v = get_bvec_t(input(j).data());
      bvec_t* f_v = get_bvec_t(fcn.input(j-inind_[task]).data());
      copy(p_v,p_v+nv,f_v);
    }
    
    // Propagate
    fcn.spEvaluate(use_fwd);
    
    // Get output dependence
    for(int j=outind_[task]; j<outind_[task+1]; ++j){
      int nv = output(j).size();
      bvec_t* p_v = get_bvec_t(output(j).data());
      const bvec_t* f_v = get_bvec_t(fcn.output(j-outind_[task]).data());
      copy(f_v,f_v+nv, p_v);
    }
  
  } else {
    
    // Set output influence
    for(int j=outind_[task]; j<outind_[task+1]; ++j){
      int nv = output(j).size();
      const bvec_t* p_v = get_bvec_t(output(j).data());
      bvec_t* f_v = get_bvec_t(fcn.output(j-outind_[task]).data());
      copy(p_v,p_v+nv,f_v);
    }
    
    // Propagate
    fcn.spEvaluate(use_fwd);
    
    // Get input dependence
    for(int j=inind_[task]; j<inind_[task+1]; ++j){
      int nv = input(j).size();
      bvec_t* p_v = get_bvec_t(input(j).data());
      const bvec_t* f_v = get_bvec_t(fcn.input(j-inind_[task]).data());
      copy(f_v,f_v+nv,p_v);
    }
  }
}
Ejemplo n.º 11
0
  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));
  }
Ejemplo n.º 12
0
void EvaluationMX::propagateSparsity(DMatrixPtrV& arg, DMatrixPtrV& res,bool use_fwd) {
  if (fcn_.spCanEvaluate(use_fwd)) {
    // Propagating sparsity pattern supported
    
    // Pass/clear forward seeds/adjoint sensitivities
    for (int iind = 0; iind < fcn_.getNumInputs(); ++iind) {
      // Input vector
      vector<double> &v = fcn_.input(iind).data();
      if (v.empty()) continue; // FIXME: remove?

      if (arg[iind] == 0) {
        // Set to zero if not used
        fill_n(get_bvec_t(v), v.size(), bvec_t(0));
      } else {
        // Copy output
        fcn_.input(iind).sparsity().set(
          get_bvec_t(fcn_.input(iind).data()),
          get_bvec_t(arg[iind]->data()),
          arg[iind]->sparsity());
      }
    }

    // Pass/clear adjoint seeds/forward sensitivities
    for (int oind = 0; oind < fcn_.getNumOutputs(); ++oind) {
      // Output vector
      vector<double> &v = fcn_.output(oind).data();
      if (v.empty()) continue; // FIXME: remove?

      if (res[oind] == 0) {
        // Set to zero if not used
        fill_n(get_bvec_t(v), v.size(), bvec_t(0));
      } else {
        // Copy output
        fcn_.output(oind).sparsity().set(
            get_bvec_t(fcn_.output(oind).data()),
            get_bvec_t(res[oind]->data()),
            res[oind]->sparsity());
      }
    }

    // Propagate seedsfcn_.
    fcn_.spInit(use_fwd); // NOTE: should only be done once
    fcn_.spEvaluate(use_fwd);

    // Get the sensitivities
    if (use_fwd) {
      for (int oind = 0; oind < res.size(); ++oind) {
        if (res[oind] != 0) {
          res[oind]->sparsity().set(
              get_bvec_t(res[oind]->data()),
              get_bvec_t(fcn_.output(oind).data()),
              fcn_.output(oind).sparsity());
        }
      }
    } else {
      for (int iind = 0; iind < arg.size(); ++iind) {
        if (arg[iind] != 0) {
          arg[iind]->sparsity().bor(
              get_bvec_t(arg[iind]->data()),
              get_bvec_t(fcn_.input(iind).data()),
              fcn_.input(iind).sparsity());
        }
      }
    }

    // Clear seeds and sensitivities
    for (int iind = 0; iind < arg.size(); ++iind) {
      vector<double> &v = fcn_.input(iind).data();
      fill(v.begin(), v.end(), 0);
    }
    for (int oind = 0; oind < res.size(); ++oind) {
      vector<double> &v = fcn_.output(oind).data();
      fill(v.begin(), v.end(), 0);
    }

  } else {
    // Propagating sparsity pattern not supported

    if (use_fwd) {
      // Clear the outputs
      for (int oind = 0; oind < res.size(); ++oind) {
        // Skip of not used
        if (res[oind] == 0)
          continue;

        // Get data array for output and clear it
        bvec_t *outputd = get_bvec_t(res[oind]->data());
        fill_n(outputd, res[oind]->size(), 0);
      }
    }

    // Loop over inputs
    for (int iind = 0; iind < arg.size(); ++iind) {
      // Skip of not used
      if (arg[iind] == 0)
        continue;

      // Skip if no seeds
      if (use_fwd && arg[iind]->empty())
        continue;

      // Get data array for input
      bvec_t *inputd = get_bvec_t(arg[iind]->data());

      // Loop over outputs
      for (int oind = 0; oind < res.size(); ++oind) {

        // Skip of not used
        if (res[oind] == 0)
          continue;

        // Skip if no seeds
        if (!use_fwd && res[oind]->empty())
          continue;

        // Get the sparsity of the Jacobian block
        CRSSparsity& sp = fcn_.jacSparsity(iind, oind, true);
        if (sp.isNull() || sp.size() == 0)
          continue; // Skip if zero
        const int d1 = sp.size1();
        //const int d2 = sp.size2();
        const vector<int>& rowind = sp.rowind();
        const vector<int>& col = sp.col();

        // Get data array for output
        bvec_t *outputd = get_bvec_t(res[oind]->data());

        // Carry out the sparse matrix-vector multiplication
        for (int i = 0; i < d1; ++i) {
          for (int el = rowind[i]; el < rowind[i + 1]; ++el) {
            // Get column
            int j = col[el];

            // Propagate dependencies
            if (use_fwd) {
              outputd[i] |= inputd[j];
            } else {
              inputd[j] |= outputd[i];
            }
          }
        }
      }
    }
  }
}
Ejemplo n.º 13
0
void SymbolicMX::propagateSparsity(DMatrixPtrV& input, DMatrixPtrV& output, bool fwd){
  bvec_t *outputd = get_bvec_t(output[0]->data());
  fill_n(outputd,output[0]->size(),0);
}