Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

first class scalar #712

Merged
merged 7 commits into from
Feb 9, 2021
Merged

first class scalar #712

merged 7 commits into from
Feb 9, 2021

Conversation

finiteprods
Copy link
Contributor

@finiteprods finiteprods commented Feb 3, 2021

The purpose of this PR is two-fold:

Currently, scalars are represented as f64 floats. But since scalars are (since #496) an integral part of the (un)masking process, they should be represented similarly to model weights, namely in "exact" form as Ratios of big integers.

Indeed, the bug mentioned above arises from the inexact nature of scalars: in the test_masking_and_aggregation! tests, we take scalars to be a fraction (morally 1 / model_count) which as per the usual limitations of floating point, cannot be represented exactly as f64 in many cases. Subsequently, the error this introduces propagates through the (un)masking process, and leads to failing closeness checks. #542 introduced a workaround by essentially adjusting model_count to a known "good" value.

OTOH by working with f64 scalars, it is easy for clients to construct imprecise (or worse, invalid e.g. negative, NaN) scalars, whether accidentally or maliciously. This could be prevented by insisting that scalars be constructed (or converted) via a safe API that statically guarantees their validity, similar to that of Model.

Summary of changes:

  • Introduces an API around a new "first class" Scalar type:
pub struct Scalar(Ratio<BigUint>);
  • Adjusts Masker::mask to take a scalar: Scalar (instead of scalar: f64).
  • Adjusts downstream clients of masking accordingly, using the Scalar API:
    • e.g. Scalar::new(1, model_count) creates an exact rational scalar 1 / model_count.
    • e.g. Scalar::unit() instead of 1.0.
  • Adjusts masking tests, in particular:
    • Fixes the floating point bug in test_masking_and_aggregation! tests by using Scalar, and removes workaround.
    • Adjusts test_xyz_scalar! families of randomized scalar tests (introduced in randomized scalar tests #589).

@finiteprods finiteprods changed the title First class scalar first class scalar Feb 3, 2021
@codecov
Copy link

codecov bot commented Feb 3, 2021

Codecov Report

Merging #712 (1c9dfb6) into master (dbaa0e5) will increase coverage by 0.47%.
The diff coverage is 72.83%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #712      +/-   ##
==========================================
+ Coverage   61.51%   61.99%   +0.47%     
==========================================
  Files         102      104       +2     
  Lines        4563     4581      +18     
==========================================
+ Hits         2807     2840      +33     
+ Misses       1756     1741      -15     
Impacted Files Coverage Δ
rust/xaynet-core/src/mask/model.rs 63.72% <ø> (ø)
rust/xaynet-mobile/src/ffi/mod.rs 0.00% <ø> (ø)
rust/xaynet-mobile/src/ffi/settings.rs 0.00% <0.00%> (ø)
rust/xaynet-mobile/src/settings.rs 0.00% <0.00%> (ø)
rust/xaynet-sdk/src/settings/mod.rs 0.00% <0.00%> (ø)
rust/xaynet-sdk/src/state_machine/phase.rs 16.66% <ø> (ø)
...ust/xaynet-server/src/state_machine/coordinator.rs 96.42% <ø> (ø)
rust/xaynet-server/src/state_machine/mod.rs 75.00% <ø> (ø)
rust/xaynet-server/src/state_machine/phases/mod.rs 73.33% <53.84%> (+3.94%) ⬆️
.../xaynet-server/src/state_machine/phases/handler.rs 71.87% <71.87%> (ø)
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ae6a723...1c9dfb6. Read the comment docs.

Copy link
Contributor

@janpetschexain janpetschexain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, i'm glad that this fixes the precision issues 👍

i left some comments mostly regarding trait streamlining.

rust/xaynet-core/src/mask/scalar.rs Outdated Show resolved Hide resolved
rust/xaynet-core/src/mask/scalar.rs Outdated Show resolved Hide resolved
rust/xaynet-core/src/mask/scalar.rs Outdated Show resolved Hide resolved
rust/xaynet-core/src/mask/scalar.rs Outdated Show resolved Hide resolved
rust/xaynet-core/src/mask/scalar.rs Show resolved Hide resolved
rust/xaynet-core/src/mask/scalar.rs Outdated Show resolved Hide resolved
rust/xaynet-core/src/mask/scalar.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@Robert-Steiner Robert-Steiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A great improvement👍 The code looks much cleaner.
I just added a small note on the Settings.

rust/xaynet-mobile/src/settings.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@Robert-Steiner Robert-Steiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

expose helpers from model

expose more scalar types

minor masking adjustment
update set_scalar docstring
fix clippy complaint: ok_or_else

remove unnecessary type annotations
regenerate C header file

update command for compiling FFI tests
@finiteprods finiteprods merged commit 2b98ec4 into master Feb 9, 2021
@finiteprods finiteprods deleted the 1st-class-scalar branch February 9, 2021 13:28
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants