Checkpoint the party/runtime stack before share-program and malicious-mode work.
Ship the TLS mesh, composer, Beaver/Yao/leaf MPC, prep/online paths, apps, and docs so the tree is pushable before elevating share_expr, security_mode, and prep resume. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
695f8e84f7
commit
0d22946a0e
1835 changed files with 170291 additions and 2849 deletions
164
test/tests/exact_steps_test.cpp
Normal file
164
test/tests/exact_steps_test.cpp
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "grotto/exact_steps.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int ref_bit_width(std::uint16_t bits)
|
||||
{
|
||||
if (bits == 0)
|
||||
return 0;
|
||||
return 32 - __builtin_clz(static_cast<unsigned>(bits));
|
||||
}
|
||||
|
||||
int ref_countl_one(std::uint16_t bits)
|
||||
{
|
||||
int n = 0;
|
||||
for (int b = 15; b >= 0; --b)
|
||||
{
|
||||
if (((bits >> b) & 1u) == 0)
|
||||
break;
|
||||
++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
std::uint16_t ref_bit_floor(std::uint16_t bits)
|
||||
{
|
||||
if (bits == 0)
|
||||
return 0;
|
||||
return std::uint16_t{1} << (ref_bit_width(bits) - 1);
|
||||
}
|
||||
|
||||
std::uint32_t ref_bit_ceil(std::uint16_t bits)
|
||||
{
|
||||
if (bits <= 1)
|
||||
return 1;
|
||||
if ((bits & (bits - 1u)) == 0)
|
||||
return bits;
|
||||
return std::uint32_t{1} << ref_bit_width(bits);
|
||||
}
|
||||
|
||||
int ref_ceil_log(std::int16_t raw, unsigned k, int group)
|
||||
{
|
||||
const long double x = std::ldexp(static_cast<long double>(raw < 0 ? -raw : raw), -static_cast<int>(k));
|
||||
return static_cast<int>(std::ceil(std::log2(static_cast<double>(x)) / group - 1e-15));
|
||||
}
|
||||
|
||||
int ref_logstar(std::int16_t raw, unsigned k)
|
||||
{
|
||||
long double x = std::ldexp(static_cast<long double>(raw), -static_cast<int>(k));
|
||||
int n = 0;
|
||||
while (x > 1.0L)
|
||||
{
|
||||
x = std::log2(static_cast<double>(x));
|
||||
++n;
|
||||
if (n > 8)
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int ref_length(std::int16_t raw, unsigned k, int base)
|
||||
{
|
||||
const long double x = std::ldexp(static_cast<long double>(raw < 0 ? -raw : raw), -static_cast<int>(k));
|
||||
const auto n = static_cast<std::int64_t>(std::floor(static_cast<double>(x)));
|
||||
if (n <= 0)
|
||||
return 1;
|
||||
int digits = 0;
|
||||
auto m = n;
|
||||
while (m > 0)
|
||||
{
|
||||
m /= base;
|
||||
++digits;
|
||||
}
|
||||
return digits;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(ExactSteps, WordBitsMatchTheUnsignedPattern)
|
||||
{
|
||||
for (int raw = -32768; raw <= 32767; ++raw)
|
||||
{
|
||||
const auto bits = static_cast<std::uint16_t>(raw);
|
||||
const auto value = static_cast<std::int64_t>(static_cast<std::int16_t>(raw));
|
||||
EXPECT_EQ(grotto::eval_bit_width<std::int16_t>(value, 0), ref_bit_width(bits));
|
||||
EXPECT_EQ(grotto::eval_countl_one<std::int16_t>(value, 0), ref_countl_one(bits));
|
||||
EXPECT_EQ(grotto::eval_has_single_bit<std::int16_t>(value, 0),
|
||||
((bits != 0 && (bits & (bits - 1u)) == 0) ? 1 : 0));
|
||||
EXPECT_EQ(grotto::eval_bit_floor<std::int16_t>(value), ref_bit_floor(bits));
|
||||
EXPECT_EQ(grotto::eval_bit_ceil<std::int16_t>(value), ref_bit_ceil(bits));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ExactSteps, IntegerLogsAndLogstar)
|
||||
{
|
||||
for (unsigned k : {0u, 4u})
|
||||
{
|
||||
for (int raw = 1; raw <= 32767; raw += (k == 0 ? 17 : 3))
|
||||
{
|
||||
const auto value = static_cast<std::int64_t>(raw);
|
||||
EXPECT_EQ(grotto::eval_ilog16<std::int16_t>(value, k) >> k, ref_ceil_log(static_cast<std::int16_t>(raw), k, 4))
|
||||
<< raw << " k=" << k;
|
||||
EXPECT_EQ(grotto::eval_ilog256<std::int16_t>(value, k) >> k, ref_ceil_log(static_cast<std::int16_t>(raw), k, 8))
|
||||
<< raw;
|
||||
EXPECT_EQ(grotto::eval_logstar<std::int16_t>(value, k) >> k, ref_logstar(static_cast<std::int16_t>(raw), k))
|
||||
<< raw;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(grotto::eval_ilog16<std::int16_t>(0, 0), grotto::ilog_of_zero);
|
||||
EXPECT_EQ(grotto::eval_logstar<std::int16_t>(-4, 0), grotto::ilog_of_zero);
|
||||
EXPECT_EQ(grotto::eval_logstar<std::int16_t>(1, 0), 0);
|
||||
EXPECT_EQ(grotto::eval_logstar<std::int16_t>(2, 0), 1);
|
||||
EXPECT_EQ(grotto::eval_logstar<std::int16_t>(4, 0), 2);
|
||||
EXPECT_EQ(grotto::eval_logstar<std::int16_t>(16, 0), 3);
|
||||
}
|
||||
|
||||
TEST(ExactSteps, DecimalFloorCeilAndLengths)
|
||||
{
|
||||
for (unsigned k : {0u, 4u})
|
||||
{
|
||||
for (int raw = -4000; raw <= 4000; raw += 3)
|
||||
{
|
||||
const long double x = std::ldexp(static_cast<long double>(raw), -static_cast<int>(k));
|
||||
const auto floor_raw = static_cast<std::int64_t>(std::floor(static_cast<double>(x)) * std::ldexp(1.0, static_cast<int>(k)));
|
||||
const auto ceil_raw = static_cast<std::int64_t>(std::ceil(static_cast<double>(x)) * std::ldexp(1.0, static_cast<int>(k)));
|
||||
EXPECT_EQ(grotto::eval_dec_floor(raw, k), floor_raw) << raw;
|
||||
EXPECT_EQ(grotto::eval_dec_ceil(raw, k), ceil_raw) << raw;
|
||||
const auto width = static_cast<std::int16_t>(raw);
|
||||
EXPECT_EQ(grotto::eval_dec_width(raw, k) >> k, ref_length(width, k, 10));
|
||||
EXPECT_EQ(grotto::eval_oct_width(raw, k) >> k, ref_length(width, k, 8));
|
||||
EXPECT_EQ(grotto::eval_b64_width(raw, k) >> k, ref_length(width, k, 64));
|
||||
const auto digits = std::llabs(static_cast<long long>(std::floor(std::fabs(static_cast<double>(x)))));
|
||||
EXPECT_EQ(grotto::eval_has_single_digit(raw, k) >> k, digits <= 9 ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ExactSteps, AngleScaleIsTheLinearFactor)
|
||||
{
|
||||
const unsigned k = 16;
|
||||
const std::int64_t deg = 180ll << k;
|
||||
const auto rad = grotto::eval_deg2rad(deg, k);
|
||||
const long double want = 180.0L * 3.14159265358979323846L / 180.0L * std::ldexp(1.0L, k);
|
||||
EXPECT_LE(std::fabsl(static_cast<long double>(rad) - want), 64.0L);
|
||||
const auto back = grotto::eval_rad2deg(rad, k);
|
||||
EXPECT_LE(std::llabs(back - deg), 4096);
|
||||
}
|
||||
|
||||
TEST(ExactSteps, StepLutAgreesWithTheScalarOnInt8)
|
||||
{
|
||||
const auto lut = grotto::make_exact_step_lut<std::int8_t>(0, [](std::int64_t raw) {
|
||||
return grotto::eval_bit_width<std::int8_t>(raw, 0);
|
||||
});
|
||||
for (int raw = -128; raw <= 127; ++raw)
|
||||
EXPECT_EQ(lut(static_cast<std::int8_t>(raw)), grotto::eval_bit_width<std::int8_t>(raw, 0));
|
||||
EXPECT_THROW(grotto::make_exact_step_lut<std::int32_t>(0, [](std::int64_t) { return 0; }), std::invalid_argument);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue