-
Notifications
You must be signed in to change notification settings - Fork 77
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
Recognize RISCV_WITH_RVV
env var on RISC-V to set WITH_RVV
cmake var
#218
Conversation
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.
Thanks a lot for tackling this!
What I like about this solution is that there is a documented cargo feature which (soon) would also advertise a corresponding environment variable. This resolves my biggest criticism towards using them - the difficulty to discover them outside of reading the code of build-scripts.
The only question left would be to what extend it has to be experimental. Is it the name that could change, or the way it's implemented, or is it the lack of CC
support?
Under which circumstances would it be possible to remove the experimental status?
My answer to this would be "Once cc.rs
also has support for it". As a matter of fact, if flate2
could use CC
instead of cmake
in the zlib-ng
backend, that would definitely make it more accessible and gitoxide
would be easier to compile as well.
I'd also be looking forward to hearing what @jongiddy thinks about this.
Would that be applicable to #206 as well then--could having both a feature and an environment variable there make sense? If so, should the environment variables be named with a similar naming convention? I assume that, if done, this would entail keeping the current name there and expanding this one. Relatedly, maybe that would shed light on whether the value should be examined. |
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.
Yes, there it's a sole environment variable without documentation in lib.rs
(on crate level at least for now). Here we started with something very specific to make it more suitable as a cargo feature, with the environment variable as another way to enable the feature to make it easier to enable for complex builds.
Admittedly, the only reason I am unsure about this is that I wonder what the original authors would want, or in lieu of this, what is most common with *-sys
crates. To my mind, I'd not use environment variables at all unless they are strongly requested, and if that's done, they'd need proper documentation.
If this PR should be more like #206 instead, the environment variable could be named less specifically, the value could matter, and it could be documented on crate level instead. It seems to be more 'common' at least.
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'm OK with the current PR. My one comment is mostly for consideration rather than requiring action.
I do suggest that a specific value is required for the environment variable, say RVV_OFF=1
. An empty string RVV_OFF=
should be the same as being unset. Any other values trigger an error. This allows flexibility if other variants are required.
zng/cmake.rs
Outdated
@@ -14,6 +14,9 @@ pub fn build_zlib_ng(target: &str, compat: bool) { | |||
.define("WITH_DFLTCC_INFLATE", "1") | |||
.cflag("-DDFLTCC_LEVEL_MASK=0x7e"); | |||
} | |||
if target.contains("riscv64") && (cfg!(feature = "rvv-off") || env::var_os("RVV_OFF").is_some()) { |
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.
Generally I prefer "positive" features over "negative" features. By this I mean that the feature sounds like it adds something rather than taking something away.
For example, you could name the environment variable WITH_RVV
and allowing the values ON
and OFF
. This would be familiar to someone who knows the zlib-ng
build. It would allow forcing the use of RVV if there was ever a case where it was disabled.
You could name the feature with-rvv
. However this would require the default to compile without RVV. This has the advantage of working in more places, at the cost of behaving differently to the default behavior of zlib-ng
.
Thanks a lot for sharing your expertise, @jongiddy! I'd be happy to go with all of the suggestions, while staying conservative on how the feature is handled so behaviour isn't changed. @EliahKagan are these changes you could do? And if present, please share your questions or suggestions as well. |
It seems to me that there is no particularly good design available here, and that it might be best either to wait to see what progress looks like on zlib-ng/zlib-ng#1705 (see zlib-ng/zlib-ng#1770), or to generalize this into a mechanism for passing arbitrary I think the problems here both for a feature (and its name) and for an environment variable (and its name) are that:
So I don't know what to do. I agree with the points raised by @jongiddy, but I don't think there is any easy way to address them properly. We can change which behavior a feature represents, and even separately from that we can rename it so it seems positive rather than negative, but I fear the situation would be inelegant, confusing, and misleading in almost the same way as in the PR now. Not adding a feature, and implementing functionality where an environment variable--or separate environment variables--can be used to pass arbitrary
I'd be happy to implement the more general functionality, but I'm checking first because I don't know if that is wanted. |
Thanks a lot for sharing your thoughts, @EliahKagan , I thought they cover all the bases, and are more complete than what I had in my mind. One part stuck out for me:
If we are actually waiting for this to be fixed downstream, but would like to offer a solution earlier, then it's in the nature of our solution that it's temporary. Maybe then we could keep it as is, as specific and negative as it may be, and add Those who want to use it can, but they would be facing breaking builds eventually or pin the version. With that it would probably help to know if this feature could be removed in a patch or a minor release. My suggestion here would be a minor release to give some room. Otherwise, if stability has to be guaranteed, I feel there is no way to do it sufficiently well. |
Even after the originally motivating upstream bug is fixed, the feature or other functionality for this in this project will remain useful for when one is building on a RISC-V system that supports RVV instructions, but planning to use the binaries on another system that does not support RVV instructions, or planning to redistribute them such that some users will need to run them on such a system. Nonetheless, the strong connection between this and zlib-ng/zlib-ng#1705 remains, because that is the use case that motivated #200 and this, and also because whatever happens upstream may provide insight into what should be done here. What if we call the feature
As an effectively separate decision, I lean toward thinking I should change the environment variable's handling to examine the value and treat some values as falsy. However, there is a disadvantage of doing so--there are ambiguous cases:
Is that a good argument against continuing just to check for the existence of the environment variable? Actually I think it is not:
|
Thanks a lot for sharing, it feels like this conversation leads to a solution soon.
To me that sounds preferable over
My intuition here was the opposite, primarily because I found it hard to decide what should override what. The solution seemed to be that if So the logic would be something like |
All good points here. In order to make something available, may I suggest that we support the environment variable My suggestions for allowed values are: The We can leave out the feature for now, hence skipping the question of priority. |
This sounds good to me. I will look into whether there is a reasonable way to force RVV on or, if not, to force RVV instructions to be emitted. Those two things are not quite the same. One problem, which I now recognize, is that I have not been properly distinguishing between checks that take place when zlib-ng is built and checks that take place at runtime unless the build has prevented them from being done. The currently broken detection is in the latter (or at least that), and a fix based on this workaround is being developed in this pull request which is waiting on a separate change but largely done. Maybe this was already clear based on the information in #200 and zlib-ng/zlib-ng#1705 but, if not, I'm worried that a lot of the discussion here may be based on my misleading descriptions. I am furthermore not at all sure that I have had them straight in my own thinking: why have I so confidently claimed that a build with RVV forced off would be needed for redistribution, even after a runtime check is fixed? I am sorry about the confusion. In any case, my plan now is to go forward with that approach unless it turns out not to be feasible or to involve excessive complexity, in which I'll go with something along previously discussed lines except (at least initially) still only with an environment variable. |
So far, this only attempts to have an effect when `cmake` is used, even though I documented it to be broader than that. In addition to testing this feature, it should either: - Be broadened to cover the non-`cmake` case (which I am unsure how to do, because which `-march` selection should be passed to `cc` varies according to other features too, which I believe `cmake` takes care of detecting), or - Have its documentation narrowed to say it only applies when `cmake` is used.
To aid in testing, and possibly as something that should even be kept in some form, this checks if an `RVV_OFF` environment variable is set and, if so, behaves as though the `rvv-off` feature is enabled, whether that feature is actually enabled or not.
+ Use the exact same comment for it in both manifest files.
Instead of `RVV_OFF`. This checks if the value appears to match any of several hard-coded truthy or falsy values. Typically the literal values `ON` or `OFF` would be used, as is typically done when passing boolean `-D...` options to `cmake` on the command-line. It is typically more useful to pass `OFF` here than `ON`, becuase the default is `ON`, as noted in the linked section of the zlib-ng readme. At least for now, empty, blank, and otherwise unrecognized values are simply ignored. Recognized values are always "normalized" as either `ON` (if truthy) or `OFF` (if falsy).
This is adapted from the comment on the feature that was added under the design that was previously explored. This way, the description will be present somewhere, even though it may be less discoverable here in `cmake.rs` than it would be in manifests.
e66a998
to
a1b2d3d
Compare
* Tweak string conversion For correctness and MSRV compatibility. * Match and explicitly do nothing for absent or strange value * Fix the conversion lifetime by reorganizing the code * Slightly simplify
It appears the only documented way to affect RVV in zlib-ng through build configuration is the It is The default is
One other change I've made here, which is subtle and possibly even irrelevant, is that I am matching I've tested that setting RISCV_WITH_RVV=OFF cargo build --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"'
RISCV_WITH_RVV=OFF cargo run --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"' --bin=gix -- status
RISCV_WITH_RVV=OFF cargo run --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"' --bin=gix -- clone git@github.com:Byron/gitoxide.git Edit: I have also tested with: RISCV_WITH_RVV=OFF cargo nextest run --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"' --all --no-fail-fast
GIX_TEST_IGNORE_ARCHIVES=1 RISCV_WITH_RVV=OFF cargo nextest run --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"' --all --no-fail-fast All tests passed. |
rvv-off
feature and RVV_OFF
environment variableWITH_RVV
for cmake
WITH_RVV
for cmakeWITH_RVV
for cmake
WITH_RVV
for cmakeRISCV_WITH_RVV
env var on RISC-V to set WITH_RVV
cmake var
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.
Thanks a lot, particularly for the additional description and with detailed reasoning.
When looking at the docs of this crate one sees that there is nothing hand-written. Hence, there is a strong precedent to also not require RISCV_WITH_RVV
to be documented as part of the (nonexistent) docs.
If one feels inspired, I'd definitely value any kind of crate-level documentation that informs about the various backend (CC, Cmake) and the environment variables they may be influenced by.
One small correction to something I reported above. I mentioned also testing with: RISCV_WITH_RVV=OFF cargo nextest run --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"' --all --no-fail-fast
GIX_TEST_IGNORE_ARCHIVES=1 RISCV_WITH_RVV=OFF cargo nextest run --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"' --all --no-fail-fast But this is effectively the same as testing with just the first command: RISCV_WITH_RVV=OFF cargo nextest run --config 'patch.crates-io.libz-sys.path="../libz-sys"' --config 'patch.crates-io.libz-ng-sys.path="../libz-ng-sys"' --all --no-fail-fast That's because I didn't clean the directories extracted from generated archives in the first test run, so Cleaning and running with (The failing test is |
I've opened GitoxideLabs/gitoxide#1605 for the gitoxide |
This adds an
rvv-off
feature that prevents RVV vector instructions from being emitted in riscv64 builds even when the build machine is detected to support RVV. As discussed in #200 (comment) and surrounding comments, this might be considered to fix #200.I don't regard this to be in especially good shape, mostly because it only affects builds that use
cmake
. I did not include any changes tocc.rs
to try to get it to work withoutcmake
.To make it easier to test this, I have also added recognition of an
RVV_OFF
environment variable with the same effect, whenever present with any value. Current use of this feature would often likely be to work around zlib-ng/zlib-ng#1705 as described in #200, but this might also make it undesirable to use it as a feature, since it would involve modifying multiple crates in a transitive dependency chain. Using an environment variable is less reliable--at least currently implemented, rerunningcargo
commands with a different value of the environment variable would not automatically rebuild anything--but more usable for this anticipated case. It also helped me in testing.I am not sure about the names of either the feature or the environment variable. For the feature, I suspect it should have "experimental" in its name and not just its description, since
zlib-ng-no-cmake-experimental-community-maintained
does and this is at least as experimental as that (and also exacerbate that feature's experimental nature, but not actually having an effect when that feature is used).I have not added anything in the test suite or to any CI scripts to test this. There seems to be a significant amount of functionality not under test in these ways, so maybe that is okay, but I am not sure.
Edit: Since opening this, I have noticed that the feature vs. environment variable considerations I was referring to have already been more precisely, clearly, and succinctly presented in #206 (comment). (However, since the functionality here and in #206 differ significantly in how they would likely be used, I don't know if a decision in either PR about this would predict a decision in the other.)
To test this manually, I used
gitoxide
, since that is the software where I observed #200 as documented there. First I produced and populated alibz-ng-sys
directory along thelibz-sys
working tree by running thecargo-zng
script after temporarily modifying it in this way:Then, in the
gitoxide
working tree, which was in the same parent directory aslibz-sys
andlibz-ng-sys
, I verified thatgix status
and agix clone
command both failed as described in #200 without patching in the changes here, as well as when they were patched in but nothing was set to enable them.Then I patched them in and also set
RVV_OFF
to1
. (I chose this value because it is intuitive. As noted above, the value is currently ignored.)That fixed the crash, as hoped.
That shows
gix status
. A test withgix clone
, as well as a number of tests to verify that without the change the problem occurs, i.e. to validate this manual testing procedure itself, appear in this other longer and fairly disorganized transcript. (When I ranvim
there, I did not use it to modify any files.)