-
Notifications
You must be signed in to change notification settings - Fork 22
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
forbid float weights for int storage for #289 #346
Conversation
@henryiii I have fixed the bugs in #289 . I saw your work #290 and found you were focusing on the pybind11 part. However, I focused on the Python part -- Now, the target has been achieved: import boost_histogram as bh
import numpy as np
h = bh.Histogram(bh.axis.Regular(10, 0, 1), storage=bh.storage.Int64())
h.fill([.2, .3], weight=[1, 2]) # this will work
h.fill([.2, .3], weight=[1., 2]) # this will not work -- TypeError: "Weight type must match storage type."
h.fill([.2, .3], weight=[1, 2.]) # this will not work -- TypeError: "Weight type must match storage type."
h.fill([.2, .3], weight=[1., 2.]) # this will not work -- TypeError: "Weight type must match storage type."
w, data = h.to_numpy() This works in my notebooks. |
By the way, CI failed again. I wonder why this always happens. 😢 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should fix the underlying problem (as done in the old PR), rather than trying to add a check here. However, maybe a check like you have here might help that PR.
@@ -98,11 +98,11 @@ def __init__(self, *axes, **kwargs): | |||
|
|||
# Keyword only trick (change when Python2 is dropped) | |||
with KWArgs(kwargs) as k: | |||
storage = k.optional("storage", Double()) | |||
self._storage = k.optional("storage", Double()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can access the storage type from the C++ object, which is better than trying to hang on to it in Python.
# should not allow float weight for int storage | ||
if "weight" in kwargs: | ||
for w in kwargs["weight"]: | ||
if not isinstance(self._storage._PyType, type(w)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an incorrect check; weight could be a single value or an array of values, this is only checking for one int rather than an array (I think).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, it does work on arrays of ints? Something like this might fix the other PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might misunderstand. As you can see, for w in kwargs["weight"]:
will iterate every value in weight list. And you can see the demo above in my comments. Every possible broken case is considered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay. I see the loop. Does this work when this is not an array? And this will be horribly slow, since it's a Python loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You get the point! Only weight=[1]
is supported now. weight=1
is not supported. But it would not be a hard job if you really want!
And this will be horribly slow, since it's a Python loop
Yep, I have seen the importance to deep into the underlying C++ parts.
@@ -17,6 +17,8 @@ def __repr__(self): | |||
@set_family(MAIN_FAMILY) | |||
@set_module("boost_histogram.storage") | |||
class Int64(store.int64, Storage): | |||
def __init__(self): | |||
self._PyType = int() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is causing the segfault in the CI, as Int64 is not properly initializing store.int64 (but could be wrong). The fact the tests are segfaulting is slightly bothering me.
This PR doesn't fix the Unlimited storage, since internally they still are always converted to floats, while the the other PR does fix that. |
@henryiii Do you expect a build-in exception rather than I agree that we should modify the underlying parts. The bad thing is, in storage.hpp, a histogram even stores data in double naturally, that's why I think your modification, using C++ templates, is a good direction. So, do you have any plans? Close this PR and stick to your draft PR, |
No description provided.