-
Notifications
You must be signed in to change notification settings - Fork 10
Phase 2 #38
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
Comments
WebAssembly/meetings#885 requesting to present and poll at the next CG meeting (2021-09-28) |
We presented an update at the CG meeting today (will add link to meeting notes when they are available).
We did not continue polling for phase 2, since there wasn't consensus around this design. We should examine use cases more, and see if we can come up with a lighter way for modules to capture their consistency requirements. |
Thanks @ngzhian for presenting at the meeting! For |
If we don't have As such, the question isn't whether existing implementations will do anything different with them. It's about preserving a property of core wasm that, so far, we've been careful to protect. |
As @lukewagner pointed out, can you think of a use case where you would merge two modules with different |
Multiple That may not be a huge practical problem because it'd only make the semantics more deterministic. However if you want to split a module into two, you'd be increasing the scope for nondeterminism, so it wouldn't be valid to do unless you could prove that the module didn't care about the resulting nondeterminism. I submit that being able to link and split wasm modules without changing semantics is a useful property that we should preserve. |
I think CG was concerned about adding a new construct without strong use cases (please correct me if my reading of the room is off), and we would also want to preserve the semantics after linking/splitting using some sort of mechanism. One suggestion that came up was a placeholder immediate 0 byte (where the current fpenv immediate goes). This is useful for capturing the consistency dependencies, but useless if modules want flexibility.
Then as a future extension, this 0 byte will evolve into a fpenv index, as outlined in the overview currently, and fpenv will be an importabled/exportable construct. This 0 byte essentially captures what web engines will implement for relaxed-simd, keeps the initial language semantic changes smaller, and leaves room for future extensions. What do y'all think about this 0 byte placeholder? |
It's not clear to me how a plain 0 byte addresses the consistency concern. If we have a "consistency within a module" rule, and I link two modules together, plain 0 bytes don't contain the information of the location of the original module boundary, so the semantics are not preserved. Similarly, if I split a module, and produce two modules with a 0 byte, it doesn't seem distinguishable from two independently produced modules that both have a 0 byte, so the information about the split modules coming from the same source module and having an expectation of consistency is lost. |
I came up with the wording "WebAssembly implementations are required to be consistent, and either always generate FMA instruction, or always generate multiplication+addition pair for a QFMA instruction within a module.", and I had something different in mind than what is denoted as module in WAsm specification or what @sunfishcode's comments refer to. My idea was that code that shares the same address space lowers QFMA instructions the same way (i.e. always to FMA or always to FMUL+FADD). Thus, two WAsm modules linked into the same Web app would either both use FMA or both use FMUL+FADD. |
Not sure if this sounds reasonable: the 0 byte imposes an extreme view of consistency, it means all modules must have the same fpenv - there is only 1 fpenv, no matter how the modules are split (or combined) - the "runner" needs to make sure they get the same env. That's why I said this is "useless". A future extension that adds an importable/exportable fpenv will "relax" this requirement.
We assume the strict case, that they came from the same module and require the same fpenv. I.e. in the 0-byte world, all split modules come from a single parent source module, and expect to be consistent. The ability to be flexible comes later with fpenv. |
Yes, this is my interpretation. Essentially, all tools involved with splitting and merging modules would assume that all provided/produced modules are morally using the same "fpenv". If there's an example of a collection of modules which you'd want to split/merge for which this wouldn't work, that would be a good motivating example for the fpenv design. |
@Maratyszcza Is "address space" the host's virtual address space? I would be opposed to making wasm semantics aware of host virtual address spaces. @ngzhian Does this mean fully deterministic? If so, that would seem to defeat the entire purpose of relaxed-simd. I would be opposed to a wasm proposal advancing with no purpose other than to be enabled by a future wasm proposal. |
I think that is correct. Strictly speaking, I don't object to adding a zero byte placeholder. However I still not understand why Another point against it in my view is that even its intended use is going to be inconsistent with identical existing behavior (example linked in #11). This would break existing code, since code that only does platform detection and "strict" SIMD would be allowed to move to an incompatible machine. In my personal opinion, preserving FP semantics while moving execution between nodes should go to future features - it would require changes to existing spec (we already allow the behavior this is supposed to guard against), and we don't have a way to practically use it just yet. |
No, the instructions themselves can still return different results depending on underlying platform, but it is incorrect to return different results for the same instruction within the same function, module, 2 modules running in a VM, etc. Hm, but I do see a problem once I start to write this down - it's hard to draw the boundary for what "all modules must be consistent" mean. |
As a first stab at how this would look formally, within the core Wasm spec, each instantiated module could be implicitly passed an In 99% of cases, the host (e.g the JS level) would document (e.g. in the JS API) that across an execution every instantiated module gets exactly the same Tools such as binaryen would almost certainly default to assuming that all provided/produced modules get the same If per-instance granularity of EDIT: the simpler and more brutal option would be to model 1 |
AFAICT, the right definition from WAsm specification is "linear memory". |
I'm still a bit confused by this discussion. A few observations/questions:
|
IIUC, the choice of Could |
Some thoughts. Say I have an engine that optionally uses a portable interpreter for fast startup and an optimizing compiler for execution speed. At the latest when the interpreter executes a relaxed instruction with fpenv I think @Maratyszcza once said something about different families of Intel chips having different lookup tables for some of the reciprocal functions, and that this could be detected in the output of those instructions. Presumably this is a somewhat more relevant concern for code migration than migrating between two instruction sets. I think for fpenv to be credible we need some very concrete and detailed use cases on the table and some suggestions for plausible implementation strategies in environments that might benefit from having multiple fpenvs. I have a nagging suspicion that it only solves half of a problem. The bigger problem than code migration is data migration, ie distributed/cloud computation where some pieces of a computation might be done on one architecture and some pieces on another. |
@lukewagner brought up another issue, namely NaN - which is "nondeterministic" in exactly the sense of relaxed SIMD. What constraints do we have on NaN behavior that might carry over? |
Fyi, signed up to do an updated on the Nov 9 CG meeting https://github.com/WebAssembly/meetings/blob/main/main/2021/CG-11-09.md will be presenting what we basically went through in https://github.com/WebAssembly/meetings/blob/main/simd/2021/SIMD-10-29.md wrt spec changes, with some additional work looking into if the current relaxed semantics will work for PowerPC + RISC V . |
Updated https://www.ngzhian.com/relaxed-simd/core/exec/numerics.html#relaxed-operations to reflect changes after looking at PowerPC + RISC V. The only change needed is: relaxed min/max, RISC V is slightly different, corresponds to minimumNumber/maxmimumNumber of IEEE-754 2019. (PowerPC and ARM is minimum/maximum, x86 is its own thing). |
We polled successfully for phase 2 today.
|
I personally understood that comment a bit differently, that we should have consistency between similar ops, multiply add and multiply subtract, for example. |
Thanks for pointing this out, I missed this comment in the summary. |
#53 tracks TODO for spec text based on comments in Phase 2 poll. And since we have successfully advanced to Phase 2, closing thi issue. |
Hi all, I would like to try and move this proposal to phase 2 at an upcoming CG meeting. Filing this issue to gather feedback and concerns.
To recap, phase 2 entry requirements are:
We have text in the overview, though they aren't exactly what will appear in the actual spec. I believe we have a high level of consensus around the instructions we want in the proposal and the use of fpenv to state dependency.
Note that the instructions aren't fixed yet, but there is consensus around the kind of instructions we want.
The text was updated successfully, but these errors were encountered: