예제 #1
0
void RFDiagonalWKSubtask::run(){
    int start_diag = owner->START_DIAG;
    int end_diag = owner->END_DIAG;
    int d = start_diag - threadNum;

    while (d >= end_diag && !isCanceled()) {
        int x = d > 0 ? d : 0;
        int y = d > 0 ? 0 : -d;
        processDiagonal(x, y);
        d -= nThreads;

        currentS+= getDiagLen(d);
        stateInfo.progress = qMin(100, int(100 * currentS / areaS));
    }
}
예제 #2
0
파일: matmul.cpp 프로젝트: bbreck3/HElib
  // A recursive matrix-by-vector multiply, used by the dense matrix code.
  // This routine is optimized to use only the rotate1D routine rather
  // than the more expensive linear-array rotations.
  long rec_mul(const Ctxt* pdata, long dim, long idx,
               const vector<long>& idxes)
  {
    if (dim >= ea.dimension()) { // Last dimension (recursion edge condition)
      zzX pt;
      zzX* zxPtr=nullptr;
      DoubleCRT* dxPtr=nullptr;

      // Check if we have the relevant constant in cache
      CachedzzxMatrix* zcp;
      CachedDCRTMatrix* dcp;
      mat.getCache(&zcp, &dcp);
      if (dcp != nullptr)         // DoubleCRT cache exists
	dxPtr = (*dcp)[idx].get();
      else if (zcp != nullptr)    // zzx cache exists but no DoubleCRT
	zxPtr = (*zcp)[idx].get();
      else if (!processDiagonal(pt, idxes)) // no cache, compute const
	zxPtr = &pt; // if it is not a zero value, point to it

      // if constant is zero, return without doing anything
      if (zxPtr==nullptr && dxPtr==nullptr)
	return idx+1;

      // Constant is non-zero, store it in cache and/or multiply/add it

      if (pdata!=nullptr && res!=nullptr) {
        Ctxt tmp = *pdata;
        if (dxPtr!=nullptr) tmp.multByConstant(*dxPtr); // mult by DCRT
        else                tmp.multByConstant(*zxPtr); // mult by zzx
        *res += tmp;
      }

      if (buildCache==cachezzX) {
        (*zCache)[idx].reset(new zzX(*zxPtr));
      }
      else if (buildCache==cacheDCRT) {
        (*dCache)[idx].reset(new DoubleCRT(*zxPtr, ea.getContext()));
      }
      return idx+1;      
    }

    // not the last dimension, make a recursive call
    long sdim = ea.sizeOfDimension(dims[dim]);

    // compute "in spirit" sum_i (pdata >> i) * i'th-diagonal, but
    // adjust the indexes so that we only need to rotate the cipehrtext
    // along the different dimensions separately
    for (long offset = 0; offset < sdim; offset++) {
      vector<long> idxes1;
      ea.EncryptedArrayBase::rotate1D(idxes1, idxes, dims[dim], offset);
      if (pdata!=nullptr && res!=nullptr) {
	Ctxt pdata1 = *pdata;
	ea.rotate1D(pdata1, dims[dim], offset);
	// indexes adjusted, make the recursive call
	idx = rec_mul(&pdata1, dim+1, idx, idxes1);
      }
      else // don't bother with the ciphertext
	idx = rec_mul(pdata, dim+1, idx, idxes1);
    }

    return idx;
  }