webmachinelearning / webnn

🧠 Web Neural Network API
https://www.w3.org/TR/webnn/
Other
397 stars 48 forks source link

Revise graph resource validation #622

Closed inexorabletash closed 7 months ago

inexorabletash commented 8 months ago

compute() calls validate graph resources with the passed input/output maps and the graph's input/output descriptors. The intent is to ensure that all of a graph's descriptors are matched to a passed resource. However, the steps were only validating that a passed resource had a corresponding descriptor - it wouldn't flag if a resource was missing!

The Chromium prototype implementation made the test reflexive - all resources much have matching descriptors and vice versa. After deliberation we settled on a more helpful behavior: all inputs must be provided, but extra inputs are ignored. A requested output must be present, but dropping outputs is allowed.

Fixes #602


Preview | Diff

inexorabletash commented 8 months ago

@huningxin and @fdwr - can you please review? Thanks!

fdwr commented 8 months ago

Before reviewing, I'm just thinking aloud the various cases, given a graph that expects 2 inputs and generates 2 outputs...

Anyway, we definitely both agree (per https://github.com/webmachinelearning/webnn/issues/602) on the case where it "Should fail, because input2 is missing - but it doesn't" ❌.

huningxin commented 8 months ago
  • await context.compute(graph, {input1: inbuf1, input2: inbuf2}, {output1: outbuf1}); 🤷‍♂️✔ An output was generated by the graph was ignored and discarded.

Computing a subset of outputs is supported. There was an example using sync compute API https://www.w3.org/TR/2024/CRD-webnn-20240214/#example-4a21156c. Unfortunately, my PR https://github.com/webmachinelearning/webnn/pull/548 that removes the sync APIs deleted this example together. We may want to bring it back by adapting to async compute API.

inexorabletash commented 8 months ago

there isn't an IDL dictionary syntax to express {requiredOutput1: outbuf1, optionalOutput2: outbuf2}.

Correct.

Based on above ✔🤷‍♂️❌ it sounds like we might want:

Given this we'd want either one algorithm that takes a flag (is input or output?) or two algorithms. The latter is probably easier. And since they're only used in one place this could be in-line in "execute graph", something like this:

  1. For each name → descriptor of graph.[[inputDescriptors]]:
    1. If inputs[name] does not exist, then return a new promise rejected with a TypeError.
    2. If validating buffer with descriptor given inputs[name] and descriptor returns false, then return a new promise rejected with a TypeError.
  2. For each name → resource of outputs:
    1. If graph.[[outputDescriptors]][name] does not exist, then return a new promise rejected with a TypeError.
    2. If validating buffer with descriptor given resource and graph.[[outputDescriptors]][name] returns false, then return a new promise rejected with a TypeError.

... and then a non-normative note saying something like:

NOTE: Invocations of compute() will fail if any of the graph's inputs are not provided as input resources, or if any requested output resources do not match the graph's outputs.

huningxin commented 8 months ago

The latter is probably easier. And since they're only used in one place this could be in-line in "execute graph", something like this:

SGTM!

inexorabletash commented 8 months ago

1e7e2b988cc8141c347510012d97ccd7b7c9139b captures the algorithm discussed above. We should probably wait for the WG telecon to decide if this is what we want.

inexorabletash commented 8 months ago

I updated this PR's name/description to match the changes. I think we're probably good to merge now?

huningxin commented 7 months ago

@fdwr , do you have any further comments?

fdwr commented 7 months ago

... or two algorithms. The latter is probably easier. And since they're only used in one place this could be in-line in "execute graph", something like this ... I updated this PR's name/description to match the changes. I think we're probably good to merge now?

Yeah, I like it. Thanks for noticing and fixing.

fdwr commented 7 months ago

Minor merge conflict from the transferred inputs/outputs CR. So just resolved.