4. 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 4.1 contains a basic example of how to construct such an object.

Listing 4.1 Simple example using PopXL
 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")

Download simple_addition.py

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 4.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 4.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.