My code gets stuck at the following line:
m_bootPrecomMap[slots] = std::make_shared<CKKSBootstrapPrecom>();
Specifically, in the new version of OpenFHE, the code hangs at this point. I am trying to perform precomputations for SlotsToCoeffs and CoeffsToSlots by using the FHECKKSRNSShadow class, which is inherited from FHERNS. I access the private members m_correctionFactor and m_bootPrecomMap in this class, but it seems to fail when executing the line above.
Code Overview
EvalSlotsToCoeffsSetup Function
void EvalSlotsToCoeffsSetup(const CryptoContextImpl<DCRTPoly>& cc, std::vector<uint32_t> levelBudget,
std::vector<uint32_t> dim1, uint32_t numSlots, uint32_t lDec) {
const auto cryptoParams = std::dynamic_pointer_cast<CryptoParametersCKKSRNS>(cc.GetCryptoParameters());
cout << "S2C set up flows!" << endl;
uint32_t M = cc.GetCyclotomicOrder();
uint32_t slots = (numSlots == 0) ? M / 4 : numSlots;
bool precompute = true;
// Workaround to access private members m_correctionFactor and m_bootPrecomMap in FHECKKSRNS
auto shadow = reinterpret_cast<FHECKKSRNSShadow*>(this);
uint32_t &m_correctionFactor = shadow->m_correctionFactor;
std::map<uint32_t, std::shared_ptr<CKKSBootstrapPrecom>> &m_bootPrecomMap = shadow->m_bootPrecomMap;
m_correctionFactor = 9;
m_bootPrecomMap[slots] = std::make_shared<CKKSBootstrapPrecom>();
auto& precom = m_bootPrecomMap[slots];
precom->m_slots = slots;
precom->m_dim1 = dim1[0];
uint32_t logSlots = std::log2(slots);
if (logSlots == 0) {
logSlots = 1;
}
std::vector<uint32_t> newBudget = levelBudget;
if (newBudget[1] > logSlots) {
std::cerr << "\nWarning, the level budget for decoding is too large. Setting it to " << logSlots << std::endl;
newBudget[1] = logSlots;
}
if (newBudget[1] < 1) {
std::cerr << "\nWarning, the level budget for decoding cannot be zero. Setting it to 1" << std::endl;
newBudget[1] = 1;
}
precom->m_paramsDec = GetCollapsedFFTParams(slots, newBudget[1], dim1[1]);
if (precompute) {
uint32_t m = 4 * slots;
std::vector<uint32_t> rotGroup(slots);
uint32_t fivePows = 1;
for (uint32_t i = 0; i < slots; ++i) {
rotGroup[i] = fivePows;
fivePows *= 5;
fivePows %= m;
}
std::vector<std::complex<double>> ksiPows(m + 1);
for (uint32_t j = 0; j < m; ++j) {
double angle = 2.0 * M_PI * j / m;
ksiPows[j].real(cos(angle));
ksiPows[j].imag(sin(angle));
}
ksiPows[m] = ksiPows[0];
NativeInteger q = cryptoParams->GetElementParams()->GetParams()[0]->GetModulus().ConvertToInt();
double qDouble = q.ConvertToDouble();
uint128_t factor = ((uint128_t)1 << ((uint32_t)std::round(std::log2(qDouble))));
double pre = qDouble / factor;
double scaleDec = 1 / pre;
precom->m_U0PreFFT = EvalSlotsToCoeffsPrecompute(cc, ksiPows, rotGroup, false, scaleDec, lDec);
}
}
FHECKKSRNSShadow Class
class FHECKKSRNSShadow : public FHERNS {
public:
const uint32_t K_SPARSE = 28;
const uint32_t K_UNIFORM = 512;
const uint32_t K_UNIFORMEXT = 768;
static const uint32_t R_UNIFORM = 6;
static const uint32_t R_SPARSE = 3;
uint32_t m_correctionFactor = 0;
std::map<uint32_t, std::shared_ptr<CKKSBootstrapPrecom>> m_bootPrecomMap;
};
Possible Causes
I am using reinterpret_cast<FHECKKSRNSShadow*>(this) to bypass the private members m_correctionFactor and m_bootPrecomMap in FHECKKSRNS and then trying to access them in the EvalSlotsToCoeffsSetup function. However, the issue occurs at the line:
m_bootPrecomMap[slots] = std::make_shared<CKKSBootstrapPrecom>();
This seems to cause the program to freeze at this point.
-
I am not sure why m_bootPrecomMap is not working correctly in the new version of OpenFHE. Is it because the access pattern for FHECKKSRNS or m_bootPrecomMap has changed in the new version?
-
Is there a better way to solve this issue instead of using reinterpret_cast?
I would appreciate any suggestions or insights to help resolve this issue. Thank you!