3. Simple example
To illustrate the PopXL concepts, here is a simple example.
You need to import the popxl
package in order to use it:
import popxl
The IR in PopXL is represented by the class Ir
.
Listing 3.1 contains a basic example of how to construct such an object.
8import popxl.ops as ops
9
10# Creating a model with popxl
11ir = popxl.Ir()
12main = ir.main_graph
13with main:
14 # host load
15 input0 = popxl.h2d_stream([1], popxl.float32, name="input0_stream")
16 a = ops.host_load(input0, "a")
17 input1 = popxl.h2d_stream([1], popxl.float32, name="input1_stream")
18 b = ops.host_load(input1, "b")
19
20 # addition
21 o = ops.add(a, b)
22
23 # host store
24 o_d2h = popxl.d2h_stream(o.shape, o.dtype, name="output_stream")
25 ops.host_store(o_d2h, o)
26
27session = popxl.Session(ir, "ipu_model")
In PopXL, an IR is essentially a collection of Graph
objects.
Each such graph contains a number of operations.
Each IR has a main graph that is constructed by default.
This main graph serves as the entry point for your model and is created with main_graph()
in Listing 3.1.
By adding operations within a with main
context, the operations
are automatically added to the main graph.
In this example, three operations are added: host_load
, add
and host_store
.
In Listing 3.1, we created two device-to-host streams input0_stream
and input1_stream
and one host-to-device stream output_stream
.
The host_load
operations are used to stream data from the host to
the device populating tensors a
and b
, respectively.
Another operation, add
, then adds these two tensors together.
Finally, the host_store
streams the result data back from the device to the host.