-
Notifications
You must be signed in to change notification settings - Fork 4
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
Reorganize the entire crate's structure #29
Comments
I know from benchmarking now what I need to work on (currently everything below 512 bits is superior to |
Do you have enough time to do this refactoring by the end of November? I really want to have this refactoring done with |
This is some awesome information btw! I like your checklist and I am also strongly favoring the proposed restructuring of In the next days I will create a proper It is also awesome to hear that Thanks for all your work! |
Its ok if you make me coauthor. I just realized that |
wait did you not see this issue until now? |
About your question in the beginning: Btw.: I am also greatly in favor of moving to Rust 2018 as soon as possible - I think the next Rust release 1.31 will be Rust 2018 already. That's about in 6 weeks from now. Reeeeeeeally looking forward to your div/rem implementations. Do we have a useful set of performance tests, yet? Would be great to have a benchmark comparing |
Yeah I should make a file just for benchmarks and preventing perf regressions between releases. I have a partial one already that includes |
Comparisons to |
The beta for Rust 2018 is ready to go, I would start compiling with it. |
Yeah you can do that. But keep in mind that we cannot release a new version of |
EDIT: I figured out that the errors happen when compiling with default-features=false, we can fix it in the reorganization. |
Ah that's a good hint!
What do you mean by
I get the idea that there is some kind of misunderstanding. I thought I shall wait for the reorganization of modules until you are done with your current task. So I had lots of ideas for |
Have you not done anything in the last month? I said that you can work in parallel with me because I was fixing performance problems inside functions and you were reorganizing where the functions are. Then when you were done with your commits it would be easy for me to replace the insides of the functions in a later PR. That was one of the points of the last PR I made.
Whoops I meant 0.2.0, that's the current version of |
I almost forgot to say that along with the crate reorganization, you can maybe change some things about the error type in the crate. I think that message and annotation part of the |
That's a good point and I should really do that!
Nope, as I have mentioned there was this slight misunderstanding. Even though I had ideas I postponed their implementation and did other stuff. Good to know! |
Rust 2018 is out! Make sure to run |
You can run stuff like |
Yeah we really should use 2018 edition for all future updates. |
My winter break is most of the way over already, how are you doing? |
Nice that you ask! My winter break is also almost over, have been some nice days. |
I just discovered I have two extra weeks to work on |
Do whatever needs to be done. I trust you and your work and I will review it asap! |
I prepared some benchmarking and discovered that in my past benchmarking I was causing Some indexing bounds checks are eliminated in compilation but not all of them. In my digit wise rotate function I replaced all the indexing with
I will change arithmetic functions that use So to summarize, I plan on doing the following, which I don't think is too much for one refactor: |
Ah sorry to hear that! So one can say that depending on the use-case either
As far as I understood you plan to introduce some abstractions to avoid safety checks in order to improve performance. I am okay with this as long as this doesn't allow users to accidentally or intentionally invalidate invariants of abstractions while using safe APIs. Functions or other abstractions that might accidentally or intentionally allow invalidating such invariances shall always be marked as
Initially I created the
As I have said I am really not eager to merge functionality that will allow users to forcefully, intentionally or accidentally invalidate inherent invariants of safe abstractions that are not marked as unsafe. I am faithful that we can find a useful design that solves our performance problems. There are many tech-talks about this topic of how to achieve great performance without sacrificing safety and by sticking to high-level abstractions. So I am also a bit skeptical about using inline assembly since I deeply think that you can nearly always achieve great performance without it. The main goal of
I am very much in favor of your roadmap, however please keep in mind my skeptical points about your ideas to achieve better performance. At first we should concentrate on getting it working correctly. Then we can improve its performance. Correctness is always more important than performance since nobody will use something that only sometimes works. |
I will not make a "unchecked_input" flag and functionality because of your concerns and the performance gains would only be noticeable for single Digit ApInts anyway. I will still do the "unchecked_internals" (disabled by default of course) and make a note in the readme that undefined behaviour results with the flag enabled if there is a bug in an algorithm that causes the function to panic with the flag disabled. |
I am looking at the standard ops implementations for |
To be honest, I am very concerned about the crate feature flag that may cause undefined behaviour as I have stated above. I think it is not a very elegant solution for the problem and I really think that especially with Rust we can do a lot better to tackle the efficiency problem. The
Good point! I am not sure if it was by intention to not implement some operations for As far as I know there are shift operations for |
Should I change I figured out that the new module system does not really eliminate Whenever any submodule imports stuff from around the library, I have made it look like this for example: use data::{ApInt, Storage, Digit}; To be clear, the public structs and functions the user of the library sees should still look the same as before the internal reorganization though. Folder |
Okay this is going to be a lot bigger than I initially thought. And also we should try to make PRs smaller in general.
I have several questions:
My proposal:
|
It initially took me days worth of working around
You see, if I organized the crate by what uses what, we would end up with basically our current organization with a lot of files in one folder, that all need each other but are unrelated in function. One reason is that files like The main reason for this is there are 14 files which have I think what I am naming the modules is confusing you and I could do better. Maybe I should rename |
Also, can I make |
I was planning on making a note in the readme that says this library considers it a bug to be able induce a panic internally, with the exception of standard library operation impls. I just discovered that there is one more way to induce a panic without doing it on the user side, and that is a |
The original |
The crate is compiling again and in the new edition! I have looked over every part of the code and am preparing Clippy and Rustfmt. I am going through the documentation and clearing up potential confusion. I promise not to do more than this in one single commit. |
The edition change made some of the places where |
Hey, I really do not like having these super giantic PRs and that's why I proposed splitting up this work into several smaller work items but I guess it is already too late for that. So please file the PR (no worries, I won't merge it until you are okay with it) and we can discuss your changes in more detail. That would help a lot! Thank you for all the work! |
For some reason, I have a false memory that you released a new version of |
Yeah we didn't have a release in a long time and we should actually have one in the next weeks with all those changes. We didn't release something since we weren't sure if all the new functionality is stable enough (which it wasn't as you have found out). |
Just so you know, I have spring break next week which means a lot of free time for me to work on Now that I think of it, I could actually take a break from changes that impact the crate as a whole and work on fixing string deserialization and single function stuff that is trivial to merge. So if you can't keep up with the PRs next week, I will just work on single function stuff instead. |
I can understand you and I will give my best. This sounds like good recommendations: https://hackernoon.com/the-art-of-pull-requests-6f0f099850f9 |
Those are some good recommendations. I can totally split up the upcoming PRs easily. There is one part of |
Looking forward to your new style of pull requests. ;) |
I went through the trouble of using a different Rust toolchain on a different computer (which has a intel processor so I can compare differences between that and AMD), disabling antivirus, customizing MSYS2 to set the internal PATH variable correctly, and finally managed to get the |
I can't bear the old crate structure, we need rustfmt, and we need to upgrade to Rust 2018. The problem is that all of these are lightly related to each other, which is the primary reason #36 was so large. Should I PR rustfmt stuff first? |
Best to shortly wait for my update.
They are not connected with each other so they do not have to live in the same PR and could have been easily shipped with different PRs each. So we could have had these updates long time ago while other (more research heavy) updates could have been in the pipeline in the form of a PR. That's why I always try to promote small PRs. Btw.: I have found tons of clippy warnings in your old codes (especially in the arithmetics module). I think it would be a good PR to clean up all of them with the help of clippy. Imo clippy is a great tool and teacher. |
I would not even bother with trying to clippy the mess that is the old |
one by one. first try to find the things that can live without introducing other changes. if parts of your code depend on those new data access snippets then you should first introduce them in isolation for example. And just then introduce the things that build upon them ... again one by one. |
I am almost finished with my fall semester at university and will be able to work on |
As always: Depends on the PR. |
My next PR I plan to do the following easy commits that will fix pain points for every future PR.
|
No please keep it private at first. |
I have had a lot of thinking over the past month about
apint
, and I think I will put most of it here. These are things I had off the top of my head that I had to type down, maybe I will remember more.Calling
BitWidth::new(...).unwrap()
just to handle the 0 width case outside the function might seem to have barely any performance increase when dynamically setting a variable with it and then calling several constructors with that one variable, but I think doing many small things like it will make a significant difference. In benchmarks I just did, we are outperformingramp
by about 0.4x on basic ops, and I think it is because of many small branching choices I am making in the newarithmetic.rs
and because of all your small design choices working together to make a big difference. For brevity though, I think we should make a macro, perhapsbw!()
, and make it a procedural macro so that it produces compilation errors on 0. We could also use the procedural macro crate for future compile time stuff.BitWidth::new()
should be kept for dynamic bit size purposes, and I wonder if we should get rid of the other BitWidth constructors since they have the unwrap inside them, and I much prefer to be able to seeunwrap
s and mess withResult
s. We obviously cannot do the same thing withShiftAmount
but we should keep that,BitPos
, andRadix
for purposes of easily distinguishing between widths and positions and shifts and them having special purpose methods. Thorough documentation could also be included for each of these types later.I had some trouble getting around the crate for a long while, and I think making the following organizational changes would help alot. Make sure that all tests pass before doing this, change to
edition = 2018
,cargo fix
ituint.rs
andint.rs
where they are. They are just complicated wrappers aroundApInt
and almost no impls for them should be anywhere else.mod.rs
should be changed toapint.rs
. The extremely unsafe and important stuff like the Drop impls inconstructor.rs
and the Clone impl incasting.rs
should be moved here.apint/utils.rs
should be moved toserialization.rs
is_one
,is_even
, etc inapint/utils.rs
should be put inrelational.rs
utils.rs
should be merged withapint/utils.rs
ShiftAmount
and what is inchecks.rs
and put them in a new fileshiftamount.rs
.shiftamount.rs
,bitpos.rs
,bitwidth.rs
,radix.rs
,traits.rs
, anderror.rs
in their own folder, maybe calledinfo
.apint.rs
,int.rs
,uint.rs
,digit.rs
,digit_seq.rs
are put into a folder calleddata
arithmetic.rs
,casting.rs
,constructors.rs
,relational.rs
,shift.rs
,bitwise.rs
, andutils.rs
are put into a folder calledlogic
rand_impl.rs
,serialization.rs
,serde_impl.rs
,to_primitive.rs
,lib.rs
, and the folders are what remain at the top level ofsrc
A while ago I raised an issue about the Clone impl you wrote for
apint
but benchmarks show that it is performing as quickly as whatramp
has, so unless we happened to end up with a same less than optimal cloning routine, it is good.I just realized something. The impl for ApInt looks like:
How does this work? wouldn't the
ext
have to beNonNull<Storage>
?The text was updated successfully, but these errors were encountered: