Skip to content

Implement Number Protocol#3507

Merged
youknowone merged 7 commits into
RustPython:mainfrom
qingshi163:number-protocol
May 29, 2022
Merged

Implement Number Protocol#3507
youknowone merged 7 commits into
RustPython:mainfrom
qingshi163:number-protocol

Conversation

@qingshi163

@qingshi163 qingshi163 commented Dec 20, 2021

Copy link
Copy Markdown
Contributor

number protocol of #3244

@youknowone

Copy link
Copy Markdown
Member

@qingshi163 what have to be done to finish this PR?

@youknowone

Copy link
Copy Markdown
Member

awesome!

@youknowone youknowone left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have questions about cow and OnceCell part, but it looks working!
This is the way to go and we can fix other stuff later.

Do you have remaining plans to do on this PR?

Comment thread vm/src/protocol/number.rs Outdated
@@ -0,0 +1,242 @@
use std::borrow::Cow;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change

Comment thread vm/src/builtins/int.rs Outdated
};

try_int(&val, vm)
// try_int(&val, vm)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
// try_int(&val, vm)

Comment thread vm/src/types/slot.rs Outdated
pub trait AsNumber: PyPayload {
#[inline]
#[pyslot]
fn slot_as_number(zelf: &PyObject, vm: &VirtualMachine) -> Cow<'static, PyNumberMethods> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this slot need to return Cow? Which part prevent this to be &'static PyNumberMethods?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think for heap object we need to use Cow::Owned witch implemented in as_number_wrapper

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

They are not decided by object, but decided by type. Then I think the type can hold a cloned PyNumberMethods with edited values. instead of Cow for every object when as_number is called.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I found AsMapping has the same mechanism. Then it is ok for now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, it should be stored in the type struct, but we can fix it later

@qingshi163

Copy link
Copy Markdown
Contributor Author

There is quite a lot of things not done yet, i think all the mathematic operations should be implemented via number protocol

@youknowone

Copy link
Copy Markdown
Member

How about finishing this PR as current state as core implementation of AsNumber trait, and working on other types in following other PRs?
Keeping a huge PR will be a burden to maintain (to rebase everything after other merge)

@youknowone

Copy link
Copy Markdown
Member

@qingshi163 are you going to make this ready for review? or do you want to do more work on it?

@qingshi163

Copy link
Copy Markdown
Contributor Author

I am still busy with it

@qingshi163 qingshi163 marked this pull request as ready for review May 29, 2022 06:53
@qingshi163 qingshi163 requested a review from youknowone May 29, 2022 06:53
@youknowone youknowone changed the title [WIP] Implement Number Protocol Implement Number Protocol May 29, 2022

@youknowone youknowone left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think #3750 changes also be able to be adapt here.
They can be done later, but I attached a commit simplifying AsNumber interfaces.

Comment thread vm/src/builtins/float.rs Outdated
if let Some(f) = val.try_to_f64(vm)? {
f
if cls.is(vm.ctx.types.float_type) && val.class().is(PyFloat::class(vm)) {
unsafe { val.downcast_unchecked::<PyFloat>().value }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

here is a regression. val object will not be reused even for same type.

Comment thread vm/src/builtins/float.rs Outdated
Comment thread vm/src/builtins/int.rs Outdated
negative: Some(|number, vm| {
Self::number_downcast(number)
.value
.clone()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

https://docs.rs/num/latest/num/struct.BigInt.html#impl-Neg-1

Neg is also implemented for &BigInt. This clone is redundant.

Comment thread vm/src/builtins/int.rs Outdated
absolute: Some(|number, vm| Self::number_downcast(number).value.abs().to_pyresult(vm)),
boolean: Some(|number, _vm| Ok(Self::number_downcast(number).value.is_zero())),
invert: Some(|number, vm| {
let value = Self::number_downcast(number).value.clone();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Comment thread vm/src/protocol/number.rs
Comment on lines +14 to +13
/* Number implementations must check *both*
arguments for proper type and implement the necessary conversions
in the slot functions themselves. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this mean we need to check the first argument(&PyNumber) is a correct PyNumber object?
In this case, I feel like the type will fit better in &PyObject rather than &PyNumber

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The comment is from cpython but as the source shows that cpython only does the check for binary operations which could be called invertly but assume the type is correct for other functions

Comment thread vm/src/protocol/number.rs Outdated
Comment thread vm/src/protocol/number.rs Outdated
Comment thread vm/src/protocol/number.rs Outdated
Comment thread vm/src/protocol/number.rs Outdated
Comment thread vm/src/protocol/number.rs Outdated
@youknowone

Copy link
Copy Markdown
Member
+-----------+----------------------------------+-----------------------------------+----------------------------------------+
| Benchmark | benches/out/cpython38/nbody.json | benches/out/rustpython/nbody.json | benches/out/rustpython-3507/nbody.json |
+===========+==================================+===================================+========================================+
| nbody     | 103 ms                           | 1.79 sec: 17.39x slower           | 1.82 sec: 17.70x slower                |
+-----------+----------------------------------+-----------------------------------+----------------------------------------+

@youknowone

Copy link
Copy Markdown
Member

at least, no regression after using references

+-----------+----------------------------------+-----------------------------------+----------------------------------------+--------------------------------------------+
| Benchmark | benches/out/cpython38/nbody.json | benches/out/rustpython/nbody.json | benches/out/rustpython-3507/nbody.json | benches/out/rustpython-3507/nbody-ref.json |
+===========+==================================+===================================+========================================+============================================+
| nbody     | 103 ms                           | 1.79 sec: 17.39x slower           | 1.82 sec: 17.70x slower                | 1.79 sec: 17.38x slower                    |
+-----------+----------------------------------+-----------------------------------+----------------------------------------+--------------------------------------------+

@youknowone youknowone force-pushed the number-protocol branch 2 times, most recently from 1b9b663 to 7a61d07 Compare May 29, 2022 22:34
Comment thread vm/src/protocol/number.rs Outdated
Comment thread vm/src/protocol/number.rs Outdated
@youknowone youknowone merged commit c40bc62 into RustPython:main May 29, 2022
@qingshi163 qingshi163 deleted the number-protocol branch July 3, 2022 19:19
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.

2 participants