void DebugEval::print_stats()

in src/hit/api/evaluator/debug.cpp [145:226]


    void DebugEval::print_stats(const CKKSCiphertext &ct) {
        homomorphic_eval->print_stats(ct);
        scale_estimator->print_stats(ct);

        double norm = 0;

        // decrypt to compute the approximate plaintext
        vector<double> homom_plaintext = decrypt(ct, true);
        vector<double> exact_plaintext = ct.raw_pt;

        norm = relative_error(exact_plaintext, homom_plaintext);
        if (abs(log2(ct.scale()) - log2(ct.backend_scale())) > 0.1) {
            LOG_AND_THROW_STREAM("Internal error: HIT scale does not match SEAL scale: " << log2(ct.scale()) << " != "
                                                                                         << ct.backend_scale());
        }

        VLOG(VLOG_EVAL) << setprecision(8) << "    + Approximation norm: " << norm;

        int max_print_size = 8;
        stringstream verbose_info;
        verbose_info << "    + Homom Result:   < ";
        for (int i = 0; i < min(max_print_size, static_cast<int>(homom_plaintext.size())); i++) {
            verbose_info << setprecision(8) << homom_plaintext[i] << ", ";
        }
        if (homom_plaintext.size() > max_print_size) {
            verbose_info << "... ";
        }
        verbose_info << ">";
        VLOG(VLOG_EVAL) << verbose_info.str();

        if (norm > MAX_NORM) {
            max_print_size = 32;
            stringstream expect_debug_result;
            expect_debug_result << "    + DEBUG Expected result: <";
            for (int i = 0; i < min(max_print_size, static_cast<int>(exact_plaintext.size())); i++) {
                expect_debug_result << setprecision(8) << exact_plaintext[i];
                if (i < exact_plaintext.size() - 1) {
                    expect_debug_result << ", ";
                }
            }
            if (exact_plaintext.size() > max_print_size) {
                expect_debug_result << "..., ";
            }
            expect_debug_result << ">";
            LOG(ERROR) << expect_debug_result.str();

            stringstream actual_debug_result;
            actual_debug_result << "    + DEBUG Actual result:   <";
            for (int i = 0; i < min(max_print_size, static_cast<int>(homom_plaintext.size())); i++) {
                actual_debug_result << setprecision(8) << homom_plaintext[i];
                if (i < exact_plaintext.size() - 1) {
                    actual_debug_result << ", ";
                }
            }
            if (homom_plaintext.size() > max_print_size) {
                actual_debug_result << "..., ";
            }
            actual_debug_result << ">";
            LOG(ERROR) << actual_debug_result.str();

            Plaintext encoded_plain;
            homomorphic_eval->backend_encoder->encode(ct.raw_pt, ct.backend_ct.parms_id(), ct.scale(), encoded_plain);
            vector<double> decoded_plain;
            homomorphic_eval->backend_encoder->decode(encoded_plain, decoded_plain);

            // the exact_plaintext and homom_plaintext should have the same length.
            // decoded_plain is full-dimensional, however. This may not match
            // the dimension of exact_plaintext if the plaintext in question is a
            // vector, so we need to truncate the decoded value.
            vector<double> truncated_decoded_plain(decoded_plain.begin(),
                                                   decoded_plain.begin() + exact_plaintext.size());
            double norm2 = relative_error(exact_plaintext, truncated_decoded_plain);
            double norm3 = relative_error(truncated_decoded_plain, homom_plaintext);

            LOG(ERROR) << "Encoding norm: " << norm2;
            LOG(ERROR) << "Encryption norm: " << norm3;

            LOG_AND_THROW_STREAM("Plaintext and ciphertext divergence: " << norm << " > " << MAX_NORM << ". Scale is "
                                                                         << homomorphic_eval->context->log_scale()
                                                                         << " bits. See error log for more details.");
        }
    }