Correct C++ update + reorganizing Module bindings#64
Conversation
|
@codex review this PR |
There was a problem hiding this comment.
💡 Codex Review
https://github.com/DavidLapous/multipers/blob/d50dbc275f968120cd0d981a340e2cc88fb83403/multiparameter_module_approximation.py#L778-L780
Skip empty tuple components before degree merge
When tuple inputs mix a valid minpres slicer with an empty slicer that has minpres_degree == -1, the earlier all(...) check still accepts it via len(s) == 0, but this direct merge now passes -1 into the C++ merge(..., int) binding, which rejects negative degrees before seeing that the module is empty. The previous m.get_module_of_degree(-1) path produced an empty module, so these partially empty batches now fail instead of ignoring the empty component.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| static Box_t get_flat_box_from_tensor(Tensor2D box) { | ||
| Numpy_2d_span boxView(box); | ||
| auto lowerView = boxView[0]; | ||
| auto upperView = boxView[1]; |
There was a problem hiding this comment.
Validate box arrays before indexing both corners
For public calls such as mod.box = np.zeros((1, n)) or constructing a module from a malformed box array, this helper blindly indexes row 1 after wrapping the tensor. The old setter validated that a box has exactly two corners with matching dimensions; without the check, a one-row array can read past the view/crash and a three-row array is silently accepted with the extra corner ignored.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
This should be handled better now in commit c1186f8.
I found that the behaviour accepting without reacting a negative dimension argument is prone to errors which are difficult to track when debugging. But it makes indeed loop mechanism less straight forward. @DavidLapous Do you prefer I replace for i, m in enumerate(modules):
mod.merge(
m, input[i].minpres_degree
)with for i, m in enumerate(modules):
if input[i].minpres_degree >= 0:
mod.merge(
m, input[i].minpres_degree
)? |
|
I think it's more a Also, could the lifetime of the box be binded to the life of the Module by transfering the ownership of the box to module? |
I guess, if the box is a numpy array, you could theoretically move ownership of the data. But it is a bit unsafe and a box is not that big to copy. Also, by copying the way it is done, you are sure to have something C-ordered and continuous. By taking ownership of the data, I would also need to copy the stride and the shape to be sure it always works. Again, feasible, but I am not sure worth the trouble in this particular case. |
For homogeneity, I would do the same for
SummandandBoxas a next step. Are there some methods you would like to add to the bindings of those two classes, while I am at it? (by default I will at least add__setstate__/__getstate__for both)Note that I added the method
summands_of_dimension_rangeto the Module bindings (to use likefor s in mod.summands_of_dimension_range(d): ...), which you could use instead ofget_module_of_degreeif no copy is needed.And please verify that I didn't forgot to add the latest changes you made to the Module bindings.
Edit: Did the changes for the
SummandandBoxbindings in this PR in the end as it was quick.For the changes in the
AIDA.ipynbnotebook, I just replaced the end of box 15 with: