- From: David Neto <dneto@google.com>
- Date: Tue, 12 Dec 2017 21:42:21 +0000
- To: Corentin Wallez <cwallez@google.com>
- Cc: Gregg Tavares <w3c@greggman.com>, "Myles C. Maxfield" <mmaxfield@apple.com>, Dzmitry Malyshau <dmalyshau@mozilla.com>, public-gpu <public-gpu@w3.org>
- Message-ID: <CAPmVsJXkpaBVF1C6tLUJ++PcNABbpFthw-UuiLjO4GEhLP=KgQ@mail.gmail.com>
Myles,
Thanks for posting something concrete we can talk about.
I've pasted my notes from a first quick pass over the doc. I'm not looking
for specific replies, but offer it for your consideration.
Overall I find it underspecified, especially among the many new features,
including how new features interact with each other. Separately, some
things will incur a high cost. Some requirements appear to be
unimplementable on GLSL or Vulkan (even extended with variable-pointers).
thanks
david
-----
Variables:
Where can you define a variable?
Can you reference a variable before its declaration:
{ int y = x;
int x;
int z = y; } // Require that z = 0?
Initializers:
- Allow interedependence?
- Initializers are constants?
- Want to forbid calling a function in an initializer. (No constexpr)
- Should say: re-initialzed each time execution enters the scope
Share storage between different shader stages?
- Haven't defined the lifetime of the program w.r.t. shader stages or the
pipeline
- Possible leakage of values across thread-groups
- Possible leakage of values across shader stages
Output variables: are they in thread memory space? (I assume so.)
Pointers: What operations are permitted? Better to have a whitelist
- E.g. Dereference for load and store
- But not for null
- Others: access-chain, "slide", compare?
- Basically, need to define the algebra for pointers
Array reference:
- You introduced with full generality, and then restricted later.
- Not knowing which underlying array
- Requires variable-pointers extension, and only works with
storage-buffer
or workgroup-shared (depending on the exact capability)
- various conversion operations on array references are not permitted in
GLSL
without extension
- @ operator on a "value". ?? Did you mean variable?
Otherwise you're forcing creation of a new storage location.
"Safe" pointer:
- Indexing into array reference can result in a pointer pointing at invalid
storage. So you can't say it's always either null or pointing at a valid
object
Out of bounds accesses:
- Requirement that all previous writes must complete: Therefore any
possibly
out-of-bounds operations can't be combined or reordered. That's a big
hinderance to optimization, e.g vectorization.
What use is a null pointer?
- You can't access it, you can't compare it.
- Sketch: Possible translation for "null" is a pointer to a phantom
variable, per type. Except even then you can't detect if it's that special
pointer, so I don't know how to enforce the requested early termination.
- But with null in the language at least you get known result, i.e.
requested early termination.
- What is the type of null?
- I assume this language is statically typed.
"Semantic errors inside generic functions show up once regardless of the
number of times the generic function is instantiated."
- That's a tooling concern, not a language concern.
Generics:
Example T identity<T>(T value)....
What are the lexical / symbol constraints on T. Can't be another
keyword,
already defined symbol, ..... ?
Constant expressions passed as type arguments:
"Only literals and references to other constant parameters qualify."
- Which others? Earlier parameters? Apparent circularity here.
What do protocols contain?
- Just method declarations?
- Member declarations?
Operator overloading:
- Casting syntax given as "type(vlaue)"
What about arrays. Array references.
- Are protocols types?
How do templates mix with protocols?
Operator overloading:
- If prefix increment is same as postfix increment, just ban one of them.
- The example for ++ for int is apparently wrong: does not modify the
value.
Default values:
- Do functions have types?
Compound overloads such as :
foo.doubleValue *= 2 ; must specify order of evaluation
Function overload resolution:
- Are the usual arithmetic conversions peformed? And how do they figure
into
ranks of specificity?
By usual arithmetic conversions, foo(1u) resolves to both
foo<T>(T) and foo(float) (The latter by a single step in usual arith
conversion lattice.)
- What is the type of "1"
If all you have is foo(uint), does foo(1) compile? Why?
- "specificity rank" is a partial order. May as well say so.
- With the single-most-specific overload requirement, it's possible to
break
code by introducing a new type or protocol. Very non-local effect. I
think
that could be ok.
Concurrency:
- Are there storage images in WebGPU? (Question for the community group.)
- This section is thin.
- "inteleaved or concurrent"
Interleaving = sequential consistency, it seems. That's super-strong.
"Concurrent" is underspecified. Defined behaviour in all cases for all
writes?
In real life, likely to have unspecified behaviour.
Logical mode:
- Pointers may never be assigned to. Is parameter passing different or
the same?
- Ternary expressions: This is the first and only mention in the doc
that this
exists.
Denorm flushing: That's expensive to guarantee after every op.
Divergent control flow: Haven't defined it, nor when reconvergence can
reoccur.
Nothing about textures or images: sampled images or storage images
On Mon, Dec 11, 2017 at 3:02 PM Corentin Wallez <cwallez@google.com> wrote:
> Thanks Myles for the document, here are my notes too, both on the document
> and some of the discussions on this thread.
>
> ## Preprocessor and multiple entry-points
>
> Not having #includes seems ok because you can do it in Javascript easily.
> I'd argue that for the same reasons the rest of the preprocessor isn't
> needed either, in particular since there isn't a good spec for how the C
> preprocessor works which would be a source of incompatibilities.
>
> Having multiple entry-points of different stages sounds ok, and is
> supported in SPIR-V.
>
> My suggestion for code reuse it to expose linking at that API-level. Some
> modules could be pure-libraries and contain no entry-points while others
> contain entry-points but some declared symbols are unimplemented. Module
> linking could produces fully implemented modules with entry-points which
> can be used for pipeline creation. Such linking would allow factoring of
> the validation and translation cost too, and maybe some of the native
> shader compilation cost.
>
> ## Builtin types
>
> Why remove the [RW]ByteAddressBuffer? It is important to allow
> heterogeneous data in buffers. It could be done with
> StructuredBuffer<uint32_t> and casts but that's not ideal imho.
>
> ## Variables
>
> Having things "as-if" local variables have a global lifetime sounds ok. It
> corresponds how things work in native APIs where program-global register
> allocation happens, and allows taking pointers to the variables (which
> would then have their lifetime extended to that of the pointer).
>
> ## Safe pointers and array references.
>
> The SPIR-V logical addressing mode doesn't allow null pointers, how would
> this feature be translated? I suggest that pointers should always be
> initialized and "null" doesn't exist.
>
> Array-references are syntactic sugar around global arrays so I don't think
> they are needed. Also there's a way to implement them for "thread" and
> "threadgroup" address spaces (the only spaces they can be used with in your
> proposal) such that they are assignable and translate correctly to SPIR-V.
>
> It is unlikely that we can require KHR_variable_pointer anytime soon, so
> the content of the "Logical Mode" could be merged in the pointer and
> arre-ref sections and treated as a hard constraint.
>
> ## Out Of Bounds accesses
>
> The trapping behavior described sounds extremely expensive to implement
> and doesn't even match with the "discard" fragment shader operation.
> Penalizing correct shaders to implement the trapping doesn't sound good and
> imo this is a place where having a "one of the following happens" statement
> would be ok. Same thing for NaN propagation and denorm floats.
>
> ## Syntax features
>
> No comment on the design of these. Their complexity reinforces my concerns
> about having incompatible implementations.
>
> ## High-level takeway
>
> The document presents an HLSL++ that removes some of the ancient stuff of
> HLSL and adds both pure-syntax features and a safe-pointer feature. There's
> a small incompatibility with SPIR-V that (null pointers) that would be easy
> to resolve.
>
> Out of all the additional features, only the safe pointers are compelling
> since they actually expose more features of the underlying platform. All
> the others increase the complexity of the language compared to HLSL
> resulting in even more interoperability concerns.
>
Received on Tuesday, 12 December 2017 21:43:27 UTC