Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[move] Implement generic comparison method in move cmp::compare #14714

Merged
merged 1 commit into from
Nov 13, 2024

Conversation

igor-aptos
Copy link
Contributor

Description

Implement generic comparison operator for any move type.
This enables writing generic methods that require comparison - for example binary_search on a vector.

Since move doesn't have signed integers, comparison return value is not intuitive (increased by 1 from usual -1, 0, 1), and so is wrapped into Ordering struct - so users don't need to think about it (with move 2, calling those will be pretty intuitive)

Type of Change

  • New feature

Which Components or Systems Does This Change Impact?

  • Move/Aptos Virtual Machine

How Has This Been Tested?

Provided unit tests

Key Areas to Review

Checklist

  • I have read and followed the CONTRIBUTING doc
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I identified and added all stakeholders and component owners affected by this change as reviewers
  • I tested both happy and unhappy path of the functionality
  • I have made corresponding changes to the documentation

Copy link

trunk-io bot commented Sep 20, 2024

⏱️ 1h 45m total CI duration on this PR
Slowest 15 Jobs Cumulative Duration Recent Runs
rust-move-unit-coverage 15m 🟩
rust-move-unit-coverage 15m 🟩
rust-move-unit-coverage 11m 🟩
rust-move-tests 10m 🟥
rust-move-tests 10m 🟥
rust-move-tests 10m 🟥
rust-move-tests 9m 🟥
rust-cargo-deny 7m 🟩🟩🟩🟩
check-dynamic-deps 6m 🟩🟩🟩🟩🟩
general-lints 6m 🟩🟩🟩🟩
rust-move-unit-coverage 3m 🟥
semgrep/ci 2m 🟩🟩🟩🟩
file_change_determinator 54s 🟩🟩🟩🟩
file_change_determinator 34s 🟩🟩🟩
permission-check 16s 🟩🟩🟩🟩

🚨 1 job on the last run was significantly faster/slower than expected

Job Duration vs 7d avg Delta
general-lints 25s 2m -76%

settingsfeedbackdocs ⋅ learn more about trunk.io

Copy link

codecov bot commented Sep 20, 2024

Codecov Report

Attention: Patch coverage is 4.57516% with 146 lines in your changes missing coverage. Please review.

Please upload report for BASE (igor/enable_move_2_for_framework@7a83ca1). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...party/move/move-vm/types/src/values/values_impl.rs 0.0% 117 Missing ⚠️
...ptos-move/framework/move-stdlib/src/natives/cmp.rs 22.5% 24 Missing ⚠️
aptos-move/aptos-native-interface/src/context.rs 0.0% 5 Missing ⚠️
Additional details and impacted files
@@                         Coverage Diff                         @@
##             igor/enable_move_2_for_framework   #14714   +/-   ##
===================================================================
  Coverage                                    ?    57.4%           
===================================================================
  Files                                       ?      859           
  Lines                                       ?   211663           
  Branches                                    ?        0           
===================================================================
  Hits                                        ?   121527           
  Misses                                      ?    90136           
  Partials                                    ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

/// 2 iff first value is larger than the second
native fun compare_impl<T>(first: &T, second: &T): u8;

struct Ordering has copy, drop {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use enum for this now? cc @wrwg

Copy link
Contributor Author

Choose a reason for hiding this comment

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

would enum be better here? Would enums be more inefficient here?

how would the native function return an enum that is defined in the module here?

}

// #[test]
// fun test_compare_enums() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is enum ignored?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

enum's are not yet enabled in the framework.

}

let len_cmp = l.len().cmp(&r.len());
if len_cmp.is_ne() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just l.len().cmp(&r.len())

(VecBool(r1), VecBool(r2)) => r1.borrow()[self.idx].cmp(&r2.borrow()[other.idx]),
(VecAddress(r1), VecAddress(r2)) => r1.borrow()[self.idx].cmp(&r2.borrow()[other.idx]),

// Equality between a generic and a specialized container.
Copy link
Contributor

Choose a reason for hiding this comment

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

Not equality

| (IndexedRef(_), _)
| (DelayedFieldID { .. }, _) => {
return Err(PartialVMError::new(StatusCode::INTERNAL_TYPE_ERROR)
.with_message(format!("cannot compare values: {:?}, {:?}", self, other)))
Copy link
Contributor

Choose a reason for hiding this comment

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

Shall we use Display instead of Debug in the message (hopefully that means more stable error message)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is copied from equals. I am not sure what is more stable from MoveVM prespective, but seems like this should be the same as in equals.

and changing equals would require feature flag? if we wanted to change eeverything to {} , we should do that separately, I think

Copy link
Contributor

@msmouse msmouse Sep 25, 2024

Choose a reason for hiding this comment

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

okay.. putting Debug text to messages we dare not to change generally makes me very sad but you don't make it worse I guess

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@vgao1996 for thoughts

Copy link
Contributor

Choose a reason for hiding this comment

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

The error message of VMError is (more or less unfortunately, making it hard to show to users) not stored on chain, so I do not think it is very important to be stable.

| (VecAddress(_), _) => {
return Err(
PartialVMError::new(StatusCode::INTERNAL_TYPE_ERROR).with_message(format!(
"cannot compare container values: {:?}, {:?}",
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

@@ -36,5 +39,8 @@ crate::gas_schedule::macros::define_gas_parameters!(
[bcs_serialized_size_base: InternalGas, { RELEASE_V1_18.. => "bcs.serialized_size.base" }, 735],
[bcs_serialized_size_per_byte_serialized: InternalGasPerByte, { RELEASE_V1_18.. => "bcs.serialized_size.per_byte_serialized" }, 36],
[bcs_serialized_size_failure: InternalGas, { RELEASE_V1_18.. => "bcs.serialized_size.failure" }, 3676],

[cmp_compare_base: InternalGas, { RELEASE_V1_21.. => "cmp.base" }, 367],
Copy link
Contributor

Choose a reason for hiding this comment

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

how do we get 367?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

copied from equality costs

Comment on lines 2 to 4
const EQUAL: u8 = 1;
const LESS_THAN: u8 = 0;
const GREATER_THAN: u8 = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

why not enum?

Comment on lines 13 to 9
struct Ordering has copy, drop {
value: u8,
}
Copy link
Contributor

@lightmark lightmark Sep 28, 2024

Choose a reason for hiding this comment

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

less_than, equal, greater_than can be ordering and return value. Why do we choose u8 instead?

@igor-aptos igor-aptos changed the base branch from main to igor/use_native_vector_move_range October 3, 2024 22:15
@igor-aptos
Copy link
Contributor Author

I cannot use move 2 features (i.e. enums), until framework is compiled with it.

I can modify it in additional commit in the stack, and decide when landing.

@igor-aptos igor-aptos force-pushed the igor/use_native_vector_move_range branch from 0df908c to 0fab436 Compare October 4, 2024 17:00
@igor-aptos igor-aptos force-pushed the igor/use_native_vector_move_range branch from 0fab436 to b1a2e70 Compare October 4, 2024 22:36
@igor-aptos igor-aptos force-pushed the igor/use_native_vector_move_range branch from b1a2e70 to 6b493cd Compare October 8, 2024 19:00
@igor-aptos igor-aptos force-pushed the igor/use_native_vector_move_range branch from 6b493cd to 6046016 Compare October 9, 2024 20:31
@igor-aptos igor-aptos force-pushed the igor/native_compare branch 2 times, most recently from cef8611 to df51e9c Compare October 9, 2024 22:50
@igor-aptos igor-aptos changed the base branch from igor/use_native_vector_move_range to igor/enable_move_2_for_framework October 9, 2024 23:10
@igor-aptos igor-aptos force-pushed the igor/enable_move_2_for_framework branch from 5394fb5 to 927268c Compare October 10, 2024 00:08
fn compare(&self, other: &Self) -> PartialVMResult<Ordering> {
use Container::*;

let res = match (
Copy link
Contributor

Choose a reason for hiding this comment

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

Was wondering if the logic would be easier if you do a read_ref on both ends and compare?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure, why equals doesn't do that? maybe perf?

(Bool(l), Bool(r)) => l.cmp(r),
(Address(l), Address(r)) => l.cmp(r),

(Container(l), Container(r)) => l.compare(r)?,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can a Container be compared with IndexedRef etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, as equals doesn't have those either.

@runtian-zhou
Copy link
Contributor

The value logic is indeed very redundent. Let's try to blow that logic as soon as possible... @ziaptos

@igor-aptos
Copy link
Contributor Author

@runtian-zhou do you mean 100% code coverage with move unit tests, or something else?

For the complexity of code - code (i.e. all the matches) have been copied 1-1 from equals, so they should cover all the cases exactly.

signature of this move function uses enums, so I cannot land the move file with private function, until move 2 is enabled for the framework. So I've separated them out - but will confirm all tests in #15245 pass, before I land this one.

Copy link
Contributor

@ziaptos ziaptos left a comment

Choose a reason for hiding this comment

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

I've reviewed this before, but didn't stamp

@igor-aptos igor-aptos force-pushed the igor/native_compare branch 2 times, most recently from 7f9c9c7 to c721045 Compare November 13, 2024 19:33
@igor-aptos igor-aptos changed the base branch from igor/native_vector_move_range to main November 13, 2024 19:33
@igor-aptos igor-aptos enabled auto-merge (squash) November 13, 2024 19:37

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

Copy link
Contributor

✅ Forge suite realistic_env_max_load success on 73c4d4d881346b17d2dcb3c50ae6b6fb42164931

two traffics test: inner traffic : committed: 14643.66 txn/s, latency: 2715.71 ms, (p50: 2700 ms, p70: 2700, p90: 2700 ms, p99: 3000 ms), latency samples: 5567900
two traffics test : committed: 100.06 txn/s, latency: 1483.54 ms, (p50: 1400 ms, p70: 1400, p90: 1600 ms, p99: 10100 ms), latency samples: 1740
Latency breakdown for phase 0: ["MempoolToBlockCreation: max: 1.977, avg: 1.525", "ConsensusProposalToOrdered: max: 0.315, avg: 0.290", "ConsensusOrderedToCommit: max: 0.356, avg: 0.347", "ConsensusProposalToCommit: max: 0.644, avg: 0.637"]
Max non-epoch-change gap was: 0 rounds at version 0 (avg 0.00) [limit 4], 0.84s no progress at version 2926701 (avg 0.20s) [limit 15].
Max epoch-change gap was: 0 rounds at version 0 (avg 0.00) [limit 4], 8.60s no progress at version 2926699 (avg 8.60s) [limit 15].
Test Ok

Copy link
Contributor

✅ Forge suite framework_upgrade success on ea6e45f0eee4b6da2ebf93b9b89d269d334fcf70 ==> 73c4d4d881346b17d2dcb3c50ae6b6fb42164931

Compatibility test results for ea6e45f0eee4b6da2ebf93b9b89d269d334fcf70 ==> 73c4d4d881346b17d2dcb3c50ae6b6fb42164931 (PR)
Upgrade the nodes to version: 73c4d4d881346b17d2dcb3c50ae6b6fb42164931
framework_upgrade::framework-upgrade::full-framework-upgrade : committed: 1323.62 txn/s, submitted: 1327.13 txn/s, failed submission: 3.51 txn/s, expired: 3.51 txn/s, latency: 2183.10 ms, (p50: 1800 ms, p70: 2100, p90: 3600 ms, p99: 6000 ms), latency samples: 120580
framework_upgrade::framework-upgrade::full-framework-upgrade : committed: 1281.09 txn/s, submitted: 1283.77 txn/s, failed submission: 2.67 txn/s, expired: 2.67 txn/s, latency: 2330.38 ms, (p50: 2100 ms, p70: 2400, p90: 3600 ms, p99: 5100 ms), latency samples: 115100
5. check swarm health
Compatibility test for ea6e45f0eee4b6da2ebf93b9b89d269d334fcf70 ==> 73c4d4d881346b17d2dcb3c50ae6b6fb42164931 passed
Upgrade the remaining nodes to version: 73c4d4d881346b17d2dcb3c50ae6b6fb42164931
framework_upgrade::framework-upgrade::full-framework-upgrade : committed: 1453.67 txn/s, submitted: 1457.30 txn/s, failed submission: 3.63 txn/s, expired: 3.63 txn/s, latency: 2134.85 ms, (p50: 1800 ms, p70: 2100, p90: 3300 ms, p99: 4900 ms), latency samples: 128200
Test Ok

Copy link
Contributor

✅ Forge suite compat success on ea6e45f0eee4b6da2ebf93b9b89d269d334fcf70 ==> 73c4d4d881346b17d2dcb3c50ae6b6fb42164931

Compatibility test results for ea6e45f0eee4b6da2ebf93b9b89d269d334fcf70 ==> 73c4d4d881346b17d2dcb3c50ae6b6fb42164931 (PR)
1. Check liveness of validators at old version: ea6e45f0eee4b6da2ebf93b9b89d269d334fcf70
compatibility::simple-validator-upgrade::liveness-check : committed: 16477.36 txn/s, latency: 2078.92 ms, (p50: 1900 ms, p70: 2000, p90: 2200 ms, p99: 5400 ms), latency samples: 526320
2. Upgrading first Validator to new version: 73c4d4d881346b17d2dcb3c50ae6b6fb42164931
compatibility::simple-validator-upgrade::single-validator-upgrading : committed: 7204.00 txn/s, latency: 3762.68 ms, (p50: 4000 ms, p70: 4700, p90: 5300 ms, p99: 5400 ms), latency samples: 129160
compatibility::simple-validator-upgrade::single-validator-upgrade : committed: 7651.58 txn/s, latency: 4186.30 ms, (p50: 4300 ms, p70: 4400, p90: 6200 ms, p99: 6400 ms), latency samples: 252500
3. Upgrading rest of first batch to new version: 73c4d4d881346b17d2dcb3c50ae6b6fb42164931
compatibility::simple-validator-upgrade::half-validator-upgrading : committed: 7764.18 txn/s, latency: 3630.67 ms, (p50: 4100 ms, p70: 4300, p90: 4400 ms, p99: 4500 ms), latency samples: 142120
compatibility::simple-validator-upgrade::half-validator-upgrade : committed: 7785.42 txn/s, latency: 4109.84 ms, (p50: 4300 ms, p70: 4500, p90: 5500 ms, p99: 5800 ms), latency samples: 256480
4. upgrading second batch to new version: 73c4d4d881346b17d2dcb3c50ae6b6fb42164931
compatibility::simple-validator-upgrade::rest-validator-upgrading : committed: 13262.18 txn/s, latency: 2066.40 ms, (p50: 2200 ms, p70: 2400, p90: 2600 ms, p99: 2700 ms), latency samples: 228840
compatibility::simple-validator-upgrade::rest-validator-upgrade : committed: 11454.86 txn/s, latency: 2715.16 ms, (p50: 2200 ms, p70: 2600, p90: 5500 ms, p99: 7600 ms), latency samples: 371080
5. check swarm health
Compatibility test for ea6e45f0eee4b6da2ebf93b9b89d269d334fcf70 ==> 73c4d4d881346b17d2dcb3c50ae6b6fb42164931 passed
Test Ok

@igor-aptos igor-aptos merged commit 77679db into main Nov 13, 2024
48 checks passed
@igor-aptos igor-aptos deleted the igor/native_compare branch November 13, 2024 21:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants