Skip to content

Add an API to describe variant using labels #12

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mgorny
Copy link
Contributor

@mgorny mgorny commented Mar 25, 2025

Add a minimal API that lets plugins process the variant description and add short labels that could be used to describe the wheel. The labels are entirely optional -- plugins may not return any, and clients may ignore them. The design also assumes that the client is responsible for choosing how many labels to use before truncating -- though I suppose I'll add a helper function to variantlib for that purpose.

The design assumes that plugin get complete unfiltered VariantDescription -- and therefore also see variant metadata from other plugins. I don't think that's really a problem, though it assumes that the plugin must compare both against provider and key names.

At this point, the protocol makes the API mandatory, even if it would only return an empty list unconditionally. Perhaps we should make the function optional somehow instead.

@mgorny
Copy link
Contributor Author

mgorny commented Mar 25, 2025

Marking this as draft until I've got meson-python counterpart ready.

@mgorny mgorny marked this pull request as ready for review March 26, 2025 16:52
mgorny added 2 commits March 26, 2025 17:59
Add a minimal API that lets plugins process the variant description
and add short labels that could be used to describe the wheel.
The labels are entirely optional -- plugins may not return any,
and clients may ignore them.  The design also assumes that the client
is responsible for choosing how many labels to use before truncating --
though I suppose I'll add a helper function to `variantlib` for that
purpose.

The design assumes that plugin get complete unfiltered
`VariantDescription` -- and therefore also see variant metadata from
other plugins.  I don't think that's really a problem, though it assumes
that the plugin must compare both against provider and key names.

At this point, the protocol makes the API mandatory, even if it would
only return an empty list unconditionally.  Perhaps we should
make the function optional somehow instead.
@DEKHTIARJonathan
Copy link
Member

Damn it ! I didn't see that PR before the big refactoring ...
Sorry about that I thought it was a great opportunity that nothing was opened ...

@DEKHTIARJonathan
Copy link
Member

DEKHTIARJonathan commented Mar 27, 2025

@mgorny I read this PR (because I was trying to rebase it) and I think I disagree with what is being done here (as an objective - not how it's done).

I don't think this is a good idea.I think that should be a package maintainer API:

python -m build --variant_alias=cuda12_sm90

Given that these names have no way to guarantee unicity (unlike the hash). We shouldn't pretend they are "part of the variant API". They are not. They are convenience identifiers - mostly for maintainers / power users. They are not part of either the variant resolution nor checked in any way for unicity / validity (beyond a regex and max length maybe).

Plus different packages will want to "name the same variant" differently because they will focus on different aspects.

And lastly I don't think the alias should include every "features" inside the alias: +cuda12+sm90+avx512+avx2+sse+.... This is exactly what I'm trying to prevent.


From my perspective, variantlib can completely ignore the alias. Maybe pip / installers could be made aware of it if we decide that pip install --variant_by_alias=cuda12_sm90 package is a good interface. Again given it's not unique and package specific I am not certain it's a good idea.

@mgorny
Copy link
Contributor Author

mgorny commented Mar 27, 2025

@rgommers, what do you think?

@rgommers
Copy link

Two main thoughts after seeing this:

  1. I'm a little surprised that variantlib would be involved in this at all. It seems to me like it should be an interface between each plugin and the build backend. That's how I sketched it in https://github.com/wheelnext/pep_xxx_wheel_variants/pull/9/files. Any thoughts on the tradeoffs here?
  2. It does seem useful to have good defaults for alias strings (but overridable of course, if the defaults don't work out well). Having each package author come up with this themselves, seems like a recipe for having multiple spellings for the same things (cu12 vs cuda-12 vs cu124, etc. - it'd be much better if this were uniform).

Given that these names have no way to guarantee unicity (unlike the hash). We shouldn't pretend they are "part of the variant API".

I was indeed expecting variantlib to only deal with the hashes.

Plus different packages will want to "name the same variant" differently because they will focus on different aspects.

They should be free to override it of course, but forcing non-uniformity by design seems worse than having good defaults. In addition, the UX is worse without defaults, because you have to add something like --variant_by_alias=cuda12_sm90 to every build invocation. And since in CI you're often building in a matrix, it will get even worse with string interpolation (e.g., --variant_by_alias=${{ matrix.buildplat[4] }}_${{ matrix.buildplat[5] }}.

The UX I'd hope we aim for on the build side is fairly extensively described in wheelnext/pep_xxx_wheel_variants#9. More discussion/review on that would be useful.

And lastly I don't think the alias should include every "features" inside the alias: +cuda12+sm90+avx512+avx2+sse+.... This is exactly what I'm trying to prevent.

That seems a little far-fetched since we don't want that many variables to begin with. Specifically for these x86-64 SIMD labels I included the desired level of granularity in wheelnext/pep_xxx_wheel_variants#9. So this will be something like psabi-x86-64v3 or psabi-v3, instead of each SIMD feature separately.

@mgorny
Copy link
Contributor Author

mgorny commented Mar 28, 2025

  1. I'm a little surprised that variantlib would be involved in this at all. It seems to me like it should be an interface between each plugin and the build backend. That's how I sketched it in https://github.com/wheelnext/pep_xxx_wheel_variants/pull/9/files. Any thoughts on the tradeoffs here?

My idea is that variantlib is a convenient place to provide plugin lookup code and interface, so we don't end up independently searching for plugins all over the place. As you can see, the API here is pretty much limited to querying labels from the plugins, and passing them back.

@rgommers
Copy link

My idea is that variantlib is a convenient place to provide plugin lookup code and interface, so we don't end up independently searching for plugins all over the place.

Yeah I can see the case for that. It can/will work either way I think. And whatever the design is, it needs a documented and stable interface anyway, because variantlib should be reimplementable - so a build backend anyway has the choice to query plugins directly if it really wants to for some reason.

@DEKHTIARJonathan
Copy link
Member

I was indeed expecting variantlib to only deal with the hashes.

I'm a little surprised that variantlib would be involved in this at all. It seems to me like it should be an interface between each plugin and the build backend.

That was the original idea, though I do agree with @mgorny here that we should increase the scope. It's much cleaner to provide a very strong, well tested complete implementation of the variant standard behavior. Rather than 50 projects implementing 15% of the complete standard.

It's both a reference implementation and a support library for the entire ecosystem of tools that will build on top of wheel variant features.

They should be free to override it of course, but forcing non-uniformity by design seems worse than having good defaults. In addition, the UX is worse without defaults, because you have to add something like --variant_by_alias=cuda12_sm90 to every build invocation.

I think here the "disconnect" is more on the "usecase/scenario" and we should answer that question first.

  • Why do we want that feature ? To answer what kind of workflow ?
  • What type of users are we expecting to use variant_aliases ?

I think it's reasonable to say >95-98% of users will never see them - never be aware of them - never even understand them in most cases. I would argue if that statement is not correct, we need to re-engineer the "variant resolution algorithm" because that's not good.

If the idea is to give a "unique name" to each [major ?] variant to allow people to fix "variant resolution issue" then I would argue that there is no need for correlation for feature / name. A high level name that can be documented is good enough. And that most importantly will be short because it's an alias (e.g. cu128_hopper, skylake_ompi, etc.)

Now if the idea is to provide package maintainers a way to in local identify different variants to the "smallest degree of granularity", this is a completely use-case and they can be flagged as "development wheels" and not be published "as-is".

And since in CI you're often building in a matrix, it will get even worse with string interpolation (e.g., --variant_by_alias=${{ matrix.buildplat[4] }}_${{ matrix.buildplat[5] }}.

Depending on the "usecase" I am not convinced every variants need an "alias".

Question: so now that clearly opens the door to alias conflicts. Because obviously I can have matrix.buildplat[1], matrix.buildplat[2], matrix.buildplat[3] varying and generating the same alias. It kinda reinforces that not every variants should have an alias. Only those we do want to flag as "major variants" and document.

That seems a little far-fetched since we don't want that many variables to begin with.

I don't disagree. But unless you block it people will do it. My whole point is "if we consider a behavior undesirable - let's close the door to that behavior". I don't want to limit the number of features a variant can declare (arbitrary philosophy), but then consequently I need to block that feature to prevent the filenames to become arbitrarily long.


My overall perspective on this variant alias feature is that we have to be careful.

Adding this "variant alias" feature, a non-essential feature though very nice to have, implies to modify the filename a lot more than absolutely necessary (vhash is the only essential part). Any modification of that filename is already something that people might get defensive about. I really want to keep the "frustration on the low side". I do believe people will hear us out that we need to add the hash to the filename for so many good reasons. I am not convinced at all the community will let us add anything else beyond that hash, and almost certainly not an arbitrary long string. Especially that this alias comes with no unicity guarantee. We should totally include it in the PEP, and ask for the best case scenario. However if we are not reasonable in our approach we will make an easy target (and we are already an easy one).

I do not care much about how this is implemented. I don't care much if it's fully manual or auto + override. But we need a very very clear use-case, and be able to explain why we believe it's really important to have this. Because arguably - if the variant resolution algorithm is good - then most users will never see these aliases.

  • If we target users consuming from an index, this is a totally functional solution:
    Screenshot 2025-03-31 at 15 59 09

  • If we target users using wheels locally (like @rgommers you were mentioning) - then we can remove any limit at all and just allow this scheme locally/from disk.

@rgommers
Copy link

rgommers commented Apr 1, 2025

It's much cleaner to provide a very strong, well tested complete implementation of the variant standard behavior. Rather than 50 projects implementing 15% of the complete standard.

Yes, that's a good point in favor of adding it to variantlib.

  • What type of users are we expecting to use variant_aliases ?

I think it's reasonable to say >95-98% of users will never see them

There are more types of users than "end users who use pip or uv to install". It's going to be important for all package authors who want to use variants to begin with.

There's also a lot of precedent, e.g, for PyTorch (see https://download.pytorch.org/whl/torch/) and JAX (see https://storage.googleapis.com/jax-releases/jax_nightly_releases.html).

Just imagine what those indexes would look like if you removed all +cpu, +cu124, etc. - you can't easily check anymore whether the variant you need is even present on the index, you'd have to write a script for it, where today you can hit Ctrl-F in the browser and find out. Same as for downloading a single wheel to inspect it for dev purposes, say from a CI run where you use actions/upload-artifact on GitHub Actions to store them. I can easily think of 5 more scenarios like that of dev tasks that will be cumbersome without it.

Any modification of that filename is already something that people might get defensive about. I really want to keep the "frustration on the low side". I do believe people will hear us out that we need to add the hash to the filename for so many good reasons. I am not convinced at all the community will let us add anything else beyond that hash,

The whole argument here is backwards in my opinion. Hashes are essential to the internals to make things work, but are basically leaking an internal implementation detail to wide visibility in the filename. There's nothing else like this today, all tags are strings with a meaning. My expectation is grudging acceptance of hashes in filenames only because there's no good way to hide them - but people may try to come up with schemes to get rid of them.

But we need a very very clear use-case, and be able to explain why we believe it's really important to have this

You can give me this task to wordsmith it in docs/PEP. But essentially: it makes maintainers job significantly harder if we don't have string aliases, for wheel building/authoring, for debugging, and other maintenance/development tasks.


Taking a step back: I think the resistance comes from arguing against arbitrary-length strings. I agree that's a bad idea (or at least, it's not going to be accepted, hence we should avoid it). I don't really want to have an opinion on whether no alias or super-long alias is worse. Both are bad. Let's pick a max length and stay with that, with the understanding that that limit can change in community review. Something like <=20 very clearly is better than no alias.

@mgorny
Copy link
Contributor Author

mgorny commented Apr 6, 2025

I'd like to merge #20 finish, but then I'd like to revisit this, so I'd appreciate some guidance on what's your preferred course of action here. FWICS, the main options here are:

  1. rebase/update it as-is, i.e. with labels being added automatically
  2. abandon variantlib part, and instead add a meson-python option to add labels explicitly

@DEKHTIARJonathan
Copy link
Member

DEKHTIARJonathan commented Apr 6, 2025

There is absolutely no consensus among us about label. I would suggest to hold off entirely on the feature.
This feature has a high potential to become an easy target to attack the PEP - @warsaw was suggesting to even add that behavior in a second PEP to avoid unnecessary blockers to the greater objective.

I'm sympathetic to the objective being achieved here, but I'm not convinced at all:

  1. It will accepted at all in the PEP review process - I'm actually quite pessimistic about it.
  2. I don't want this to become a point of contention and create unnecessary fuss on DPO.

Before we make a decision whether or not to add variant alias and in what form to the initial PEP - I'd really like that we agree at least among all core WheelNext members that we have picked the best "initial idea" and we are all comfortable to support this idea. Right now I don't think we have such a consensus.

@mgorny @rgommers @msarahan @warsawnv @emmatyping-nv @aterrel @charliermarsh @konstin @seemethere @atalman

Summary for those who discover the topic - discussions happened in different places.

We are discussing if/how to give "human readable" aliases to variants.

The "common current ground is the following":
dummy_project-0.0.1-py3-none-any-4f8ae729.whl

Obviously 4f8ae729 is not very readable. So the question is - how can we do that better ?

This could be addressed by:

  • Appending a limitless alias group: dummy_project-0.0.1-py3-none-any-4f8ae729+feature1+feature2+...+featureN.whl
  • Appending a limited alias group [max 2 for example]: dummy_project-0.0.1-py3-none-any-4f8ae729+feature1+feature2.whl
  • Appending a limited alias group [max 20 chars for example]: dummy_project-0.0.1-py3-none-any-4f8ae729+feature1+feature2+f.whl
  • Using a "configuration alias" [human-defined] aka not linked to features: dummy_project-0.0.1-py3-none-any-4f8ae729+cu12_hopper_openmpi.whl
  • Using no alias in the file and using either the package / variants.json / variantlib / tools (pip, uv, etc.) to do the job of converting 4f8ae729 into smthg readable.
  • Allowing "locally" alias that are limitless but not published one on PyPI or other [if a developer wants to do smthg on their machine - why not]
  • etc.

There are very valid argument to pretty much defend each approach - It quite depends on which perspective you position yourself. It's a compromise you can't win everywhere.

Obviously this "feature" is important to distinguish at a glance which package is which. However if we don't pick the right solution we might bump into other issues:

  • Windows limit filenames to 255 chars by default
  • DPO community might be firmly opposed to "arbitrary strings" in the filename - even if bound by a max length - this could create an unecessary reason point of friction reducing the likelihood of acceptance. [@warsawnv was proposing to tackle this PEP is a second - separately discussed PEP - precisely for that reason]

@charliermarsh
Copy link

Thanks for the summary @DEKHTIARJonathan. Personally, I agree that this feels non-critical (and that we have larger points to align on) -- I would also prefer to defer this for now.

@mgorny mgorny marked this pull request as draft April 7, 2025 06:56
@warsaw
Copy link

warsaw commented Apr 7, 2025

I know @rgommers feels strongly that aliases should be included in the first (and only) PEP, but you also know that I agree that I think this will be a bone of contention that distracts from the core bits of the PEP. I think it would be perfectly fine to lay out the argument for aliases in an Open Questions section and explicitly state that a) it's not critical to the functional success of variants, b) enhances the usability of variants, c) may be proposed in a companion PEP. If we're wrong about that, then this will come up in the DPO thread and we can update the variants spec to include aliases pretty easily.

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.

5 participants