Skip to content

Commit ac355f3

Browse files
authored
Use resources (#59)
Now that component model `resource`s are specified and implemented, it should be possible to use the `resource` type for specifying tensors, graphs and execution contexts. Closes #47.
1 parent 8bd40e2 commit ac355f3

File tree

2 files changed

+135
-106
lines changed

2 files changed

+135
-106
lines changed

ml.md

Lines changed: 108 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ Then, the user passes <em>tensor</em> inputs to the <em>graph</em>, computes the
1111
<ul>
1212
<li>interface <a href="#wasi:nn_tensor"><code>wasi:nn/tensor</code></a></li>
1313
<li>interface <a href="#wasi:nn_errors"><code>wasi:nn/errors</code></a></li>
14-
<li>interface <a href="#wasi:nn_graph"><code>wasi:nn/graph</code></a></li>
1514
<li>interface <a href="#wasi:nn_inference"><code>wasi:nn/inference</code></a></li>
15+
<li>interface <a href="#wasi:nn_graph"><code>wasi:nn/graph</code></a></li>
1616
</ul>
1717
</li>
1818
</ul>
@@ -45,12 +45,46 @@ and the array length must match the product of all of the dimensions and the num
4545
in the type (e.g., a 2x2 tensor with 4-byte f32 elements would have a data array of length
4646
16). Naturally, this representation requires some knowledge of how to lay out data in
4747
memory--e.g., using row-major ordering--and could perhaps be improved.</p>
48-
<h4><a name="tensor"><code>record tensor</code></a></h4>
49-
<h5>Record Fields</h5>
48+
<h4><a name="tensor"><code>resource tensor</code></a></h4>
49+
<hr />
50+
<h3>Functions</h3>
51+
<h4><a name="constructor_tensor"><code>[constructor]tensor: func</code></a></h4>
52+
<h5>Params</h5>
53+
<ul>
54+
<li><a name="constructor_tensor.dimensions"><code>dimensions</code></a>: <a href="#tensor_dimensions"><a href="#tensor_dimensions"><code>tensor-dimensions</code></a></a></li>
55+
<li><a name="constructor_tensor.ty"><code>ty</code></a>: <a href="#tensor_type"><a href="#tensor_type"><code>tensor-type</code></a></a></li>
56+
<li><a name="constructor_tensor.data"><code>data</code></a>: <a href="#tensor_data"><a href="#tensor_data"><code>tensor-data</code></a></a></li>
57+
</ul>
58+
<h5>Return values</h5>
5059
<ul>
51-
<li><a name="tensor.dimensions"><code>dimensions</code></a>: <a href="#tensor_dimensions"><a href="#tensor_dimensions"><code>tensor-dimensions</code></a></a></li>
52-
<li><a name="tensor.tensor_type"><a href="#tensor_type"><code>tensor-type</code></a></a>: <a href="#tensor_type"><a href="#tensor_type"><code>tensor-type</code></a></a></li>
53-
<li><a name="tensor.data"><code>data</code></a>: <a href="#tensor_data"><a href="#tensor_data"><code>tensor-data</code></a></a></li>
60+
<li><a name="constructor_tensor.0"></a> own&lt;<a href="#tensor"><a href="#tensor"><code>tensor</code></a></a>&gt;</li>
61+
</ul>
62+
<h4><a name="method_tensor.dimensions"><code>[method]tensor.dimensions: func</code></a></h4>
63+
<h5>Params</h5>
64+
<ul>
65+
<li><a name="method_tensor.dimensions.self"><code>self</code></a>: borrow&lt;<a href="#tensor"><a href="#tensor"><code>tensor</code></a></a>&gt;</li>
66+
</ul>
67+
<h5>Return values</h5>
68+
<ul>
69+
<li><a name="method_tensor.dimensions.0"></a> <a href="#tensor_dimensions"><a href="#tensor_dimensions"><code>tensor-dimensions</code></a></a></li>
70+
</ul>
71+
<h4><a name="method_tensor.ty"><code>[method]tensor.ty: func</code></a></h4>
72+
<h5>Params</h5>
73+
<ul>
74+
<li><a name="method_tensor.ty.self"><code>self</code></a>: borrow&lt;<a href="#tensor"><a href="#tensor"><code>tensor</code></a></a>&gt;</li>
75+
</ul>
76+
<h5>Return values</h5>
77+
<ul>
78+
<li><a name="method_tensor.ty.0"></a> <a href="#tensor_type"><a href="#tensor_type"><code>tensor-type</code></a></a></li>
79+
</ul>
80+
<h4><a name="method_tensor.data"><code>[method]tensor.data: func</code></a></h4>
81+
<h5>Params</h5>
82+
<ul>
83+
<li><a name="method_tensor.data.self"><code>self</code></a>: borrow&lt;<a href="#tensor"><a href="#tensor"><code>tensor</code></a></a>&gt;</li>
84+
</ul>
85+
<h5>Return values</h5>
86+
<ul>
87+
<li><a name="method_tensor.data.0"></a> <a href="#tensor_data"><a href="#tensor_data"><code>tensor-data</code></a></a></li>
5488
</ul>
5589
<h2><a name="wasi:nn_errors">Import interface wasi:nn/errors</a></h2>
5690
<p>TODO: create function-specific errors (https://github.com/WebAssembly/wasi-nn/issues/42)</p>
@@ -67,6 +101,59 @@ memory--e.g., using row-major ordering--and could perhaps be improved.</p>
67101
<li><a name="error.too_large"><code>too-large</code></a></li>
68102
<li><a name="error.not_found"><code>not-found</code></a></li>
69103
</ul>
104+
<h2><a name="wasi:nn_inference">Import interface wasi:nn/inference</a></h2>
105+
<p>An inference &quot;session&quot; is encapsulated by a <a href="#graph_execution_context"><code>graph-execution-context</code></a>. This structure binds a
106+
<a href="#graph"><code>graph</code></a> to input tensors before <code>compute</code>-ing an inference:</p>
107+
<hr />
108+
<h3>Types</h3>
109+
<h4><a name="error"><code>type error</code></a></h4>
110+
<p><a href="#error"><a href="#error"><code>error</code></a></a></p>
111+
<p>
112+
#### <a name="tensor">`type tensor`</a>
113+
[`tensor`](#tensor)
114+
<p>
115+
#### <a name="tensor_data">`type tensor-data`</a>
116+
[`tensor-data`](#tensor_data)
117+
<p>
118+
#### <a name="graph_execution_context">`resource graph-execution-context`</a>
119+
<hr />
120+
<h3>Functions</h3>
121+
<h4><a name="method_graph_execution_context.set_input"><code>[method]graph-execution-context.set-input: func</code></a></h4>
122+
<p>Define the inputs to use for inference.</p>
123+
<h5>Params</h5>
124+
<ul>
125+
<li><a name="method_graph_execution_context.set_input.self"><code>self</code></a>: borrow&lt;<a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a>&gt;</li>
126+
<li><a name="method_graph_execution_context.set_input.name"><code>name</code></a>: <code>string</code></li>
127+
<li><a name="method_graph_execution_context.set_input.tensor"><a href="#tensor"><code>tensor</code></a></a>: own&lt;<a href="#tensor"><a href="#tensor"><code>tensor</code></a></a>&gt;</li>
128+
</ul>
129+
<h5>Return values</h5>
130+
<ul>
131+
<li><a name="method_graph_execution_context.set_input.0"></a> result&lt;_, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
132+
</ul>
133+
<h4><a name="method_graph_execution_context.compute"><code>[method]graph-execution-context.compute: func</code></a></h4>
134+
<p>Compute the inference on the given inputs.</p>
135+
<p>Note the expected sequence of calls: <code>set-input</code>, <code>compute</code>, <code>get-output</code>. TODO: this
136+
expectation could be removed as a part of
137+
https://github.com/WebAssembly/wasi-nn/issues/43.</p>
138+
<h5>Params</h5>
139+
<ul>
140+
<li><a name="method_graph_execution_context.compute.self"><code>self</code></a>: borrow&lt;<a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a>&gt;</li>
141+
</ul>
142+
<h5>Return values</h5>
143+
<ul>
144+
<li><a name="method_graph_execution_context.compute.0"></a> result&lt;_, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
145+
</ul>
146+
<h4><a name="method_graph_execution_context.get_output"><code>[method]graph-execution-context.get-output: func</code></a></h4>
147+
<p>Extract the outputs after inference.</p>
148+
<h5>Params</h5>
149+
<ul>
150+
<li><a name="method_graph_execution_context.get_output.self"><code>self</code></a>: borrow&lt;<a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a>&gt;</li>
151+
<li><a name="method_graph_execution_context.get_output.name"><code>name</code></a>: <code>string</code></li>
152+
</ul>
153+
<h5>Return values</h5>
154+
<ul>
155+
<li><a name="method_graph_execution_context.get_output.0"></a> result&lt;own&lt;<a href="#tensor"><a href="#tensor"><code>tensor</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
156+
</ul>
70157
<h2><a name="wasi:nn_graph">Import interface wasi:nn/graph</a></h2>
71158
<p>A <a href="#graph"><code>graph</code></a> is a loaded instance of a specific ML model (e.g., MobileNet) for a specific ML
72159
framework (e.g., TensorFlow):</p>
@@ -78,10 +165,10 @@ framework (e.g., TensorFlow):</p>
78165
#### <a name="tensor">`type tensor`</a>
79166
[`tensor`](#tensor)
80167
<p>
81-
#### <a name="graph">`type graph`</a>
82-
`u32`
83-
<p>An execution graph for performing inference (i.e., a model).
84-
<p>TODO: replace with <code>resource</code> (https://github.com/WebAssembly/wasi-nn/issues/47).</p>
168+
#### <a name="graph_execution_context">`type graph-execution-context`</a>
169+
[`graph-execution-context`](#graph_execution_context)
170+
<p>
171+
#### <a name="graph">`resource graph`</a>
85172
<h4><a name="graph_encoding"><code>enum graph-encoding</code></a></h4>
86173
<p>Describes the encoding of the graph. This allows the API to be implemented by various
87174
backends that encode (i.e., serialize) their graph IR with different formats.</p>
@@ -109,6 +196,15 @@ backends that encode (i.e., serialize) their graph IR with different formats.</p
109196
graph IR in parts (e.g., OpenVINO stores its IR and weights separately).</p>
110197
<hr />
111198
<h3>Functions</h3>
199+
<h4><a name="method_graph.init_execution_context"><code>[method]graph.init-execution-context: func</code></a></h4>
200+
<h5>Params</h5>
201+
<ul>
202+
<li><a name="method_graph.init_execution_context.self"><code>self</code></a>: borrow&lt;<a href="#graph"><a href="#graph"><code>graph</code></a></a>&gt;</li>
203+
</ul>
204+
<h5>Return values</h5>
205+
<ul>
206+
<li><a name="method_graph.init_execution_context.0"></a> result&lt;own&lt;<a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
207+
</ul>
112208
<h4><a name="load"><code>load: func</code></a></h4>
113209
<p>Load a <a href="#graph"><code>graph</code></a> from an opaque sequence of bytes to use for inference.</p>
114210
<h5>Params</h5>
@@ -119,7 +215,7 @@ graph IR in parts (e.g., OpenVINO stores its IR and weights separately).</p>
119215
</ul>
120216
<h5>Return values</h5>
121217
<ul>
122-
<li><a name="load.0"></a> result&lt;<a href="#graph"><a href="#graph"><code>graph</code></a></a>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
218+
<li><a name="load.0"></a> result&lt;own&lt;<a href="#graph"><a href="#graph"><code>graph</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
123219
</ul>
124220
<h4><a name="load_by_name"><code>load-by-name: func</code></a></h4>
125221
<p>Load a <a href="#graph"><code>graph</code></a> by name.</p>
@@ -132,73 +228,5 @@ range from simple to complex (e.g., URLs?) and caching mechanisms of various kin
132228
</ul>
133229
<h5>Return values</h5>
134230
<ul>
135-
<li><a name="load_by_name.0"></a> result&lt;<a href="#graph"><a href="#graph"><code>graph</code></a></a>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
136-
</ul>
137-
<h2><a name="wasi:nn_inference">Import interface wasi:nn/inference</a></h2>
138-
<p>An inference &quot;session&quot; is encapsulated by a <a href="#graph_execution_context"><code>graph-execution-context</code></a>. This structure binds a
139-
<a href="#graph"><code>graph</code></a> to input tensors before <a href="#compute"><code>compute</code></a>-ing an inference:</p>
140-
<hr />
141-
<h3>Types</h3>
142-
<h4><a name="error"><code>type error</code></a></h4>
143-
<p><a href="#error"><a href="#error"><code>error</code></a></a></p>
144-
<p>
145-
#### <a name="tensor">`type tensor`</a>
146-
[`tensor`](#tensor)
147-
<p>
148-
#### <a name="tensor_data">`type tensor-data`</a>
149-
[`tensor-data`](#tensor_data)
150-
<p>
151-
#### <a name="graph">`type graph`</a>
152-
[`graph`](#graph)
153-
<p>
154-
#### <a name="graph_execution_context">`type graph-execution-context`</a>
155-
`u32`
156-
<p>Bind a `graph` to the input and output tensors for an inference.
157-
<p>TODO: this is no longer necessary in WIT (https://github.com/WebAssembly/wasi-nn/issues/43)</p>
158-
<hr />
159-
<h3>Functions</h3>
160-
<h4><a name="init_execution_context"><code>init-execution-context: func</code></a></h4>
161-
<p>Create an execution instance of a loaded graph.</p>
162-
<h5>Params</h5>
163-
<ul>
164-
<li><a name="init_execution_context.graph"><a href="#graph"><code>graph</code></a></a>: <a href="#graph"><a href="#graph"><code>graph</code></a></a></li>
165-
</ul>
166-
<h5>Return values</h5>
167-
<ul>
168-
<li><a name="init_execution_context.0"></a> result&lt;<a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
169-
</ul>
170-
<h4><a name="set_input"><code>set-input: func</code></a></h4>
171-
<p>Define the inputs to use for inference.</p>
172-
<h5>Params</h5>
173-
<ul>
174-
<li><a name="set_input.ctx"><code>ctx</code></a>: <a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a></li>
175-
<li><a name="set_input.name"><code>name</code></a>: <code>string</code></li>
176-
<li><a name="set_input.tensor"><a href="#tensor"><code>tensor</code></a></a>: <a href="#tensor"><a href="#tensor"><code>tensor</code></a></a></li>
177-
</ul>
178-
<h5>Return values</h5>
179-
<ul>
180-
<li><a name="set_input.0"></a> result&lt;_, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
181-
</ul>
182-
<h4><a name="compute"><code>compute: func</code></a></h4>
183-
<p>Compute the inference on the given inputs.</p>
184-
<p>Note the expected sequence of calls: <a href="#set_input"><code>set-input</code></a>, <a href="#compute"><code>compute</code></a>, <a href="#get_output"><code>get-output</code></a>. TODO: this
185-
expectation could be removed as a part of https://github.com/WebAssembly/wasi-nn/issues/43.</p>
186-
<h5>Params</h5>
187-
<ul>
188-
<li><a name="compute.ctx"><code>ctx</code></a>: <a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a></li>
189-
</ul>
190-
<h5>Return values</h5>
191-
<ul>
192-
<li><a name="compute.0"></a> result&lt;_, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
193-
</ul>
194-
<h4><a name="get_output"><code>get-output: func</code></a></h4>
195-
<p>Extract the outputs after inference.</p>
196-
<h5>Params</h5>
197-
<ul>
198-
<li><a name="get_output.ctx"><code>ctx</code></a>: <a href="#graph_execution_context"><a href="#graph_execution_context"><code>graph-execution-context</code></a></a></li>
199-
<li><a name="get_output.name"><code>name</code></a>: <code>string</code></li>
200-
</ul>
201-
<h5>Return values</h5>
202-
<ul>
203-
<li><a name="get_output.0"></a> result&lt;<a href="#tensor_data"><a href="#tensor_data"><code>tensor-data</code></a></a>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
231+
<li><a name="load_by_name.0"></a> result&lt;own&lt;<a href="#graph"><a href="#graph"><code>graph</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
204232
</ul>

wit/wasi-nn.wit

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,18 @@ interface tensor {
4343
/// memory--e.g., using row-major ordering--and could perhaps be improved.
4444
type tensor-data = list<u8>;
4545

46-
record tensor {
46+
resource tensor {
47+
constructor(dimensions: tensor-dimensions, ty: tensor-type, data: tensor-data);
48+
4749
// Describe the size of the tensor (e.g., 2x2x2x2 -> [2, 2, 2, 2]). To represent a tensor
4850
// containing a single value, use `[1]` for the tensor dimensions.
49-
dimensions: tensor-dimensions,
51+
dimensions: func() -> tensor-dimensions;
5052

5153
// Describe the type of element in the tensor (e.g., `f32`).
52-
tensor-type: tensor-type,
54+
ty: func() -> tensor-type;
5355

54-
// Contains the tensor data.
55-
data: tensor-data,
56+
// Return the tensor data.
57+
data: func() -> tensor-data;
5658
}
5759
}
5860

@@ -61,11 +63,12 @@ interface tensor {
6163
interface graph {
6264
use errors.{error};
6365
use tensor.{tensor};
66+
use inference.{graph-execution-context};
6467

6568
/// An execution graph for performing inference (i.e., a model).
66-
///
67-
/// TODO: replace with `resource` (https://github.com/WebAssembly/wasi-nn/issues/47).
68-
type graph = u32;
69+
resource graph {
70+
init-execution-context: func() -> result<graph-execution-context, error>;
71+
}
6972

7073
/// Describes the encoding of the graph. This allows the API to be implemented by various
7174
/// backends that encode (i.e., serialize) their graph IR with different formats.
@@ -107,27 +110,25 @@ interface graph {
107110
interface inference {
108111
use errors.{error};
109112
use tensor.{tensor, tensor-data};
110-
use graph.{graph};
111113

112114
/// Bind a `graph` to the input and output tensors for an inference.
113115
///
114-
/// TODO: this is no longer necessary in WIT (https://github.com/WebAssembly/wasi-nn/issues/43)
115-
type graph-execution-context = u32;
116-
117-
/// Create an execution instance of a loaded graph.
118-
init-execution-context: func(graph: graph) -> result<graph-execution-context, error>;
119-
120-
/// Define the inputs to use for inference.
121-
set-input: func(ctx: graph-execution-context, name: string, tensor: tensor) -> result<_, error>;
122-
123-
/// Compute the inference on the given inputs.
124-
///
125-
/// Note the expected sequence of calls: `set-input`, `compute`, `get-output`. TODO: this
126-
/// expectation could be removed as a part of https://github.com/WebAssembly/wasi-nn/issues/43.
127-
compute: func(ctx: graph-execution-context) -> result<_, error>;
128-
129-
/// Extract the outputs after inference.
130-
get-output: func(ctx: graph-execution-context, name: string) -> result<tensor-data, error>;
116+
/// TODO: this may no longer be necessary in WIT
117+
/// (https://github.com/WebAssembly/wasi-nn/issues/43)
118+
resource graph-execution-context {
119+
/// Define the inputs to use for inference.
120+
set-input: func(name: string, tensor: tensor) -> result<_, error>;
121+
122+
/// Compute the inference on the given inputs.
123+
///
124+
/// Note the expected sequence of calls: `set-input`, `compute`, `get-output`. TODO: this
125+
/// expectation could be removed as a part of
126+
/// https://github.com/WebAssembly/wasi-nn/issues/43.
127+
compute: func() -> result<_, error>;
128+
129+
/// Extract the outputs after inference.
130+
get-output: func(name: string) -> result<tensor, error>;
131+
}
131132
}
132133

133134
/// TODO: create function-specific errors (https://github.com/WebAssembly/wasi-nn/issues/42)

0 commit comments

Comments
 (0)