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)); } }
// 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; }