WEBVTT

00:00.000 --> 00:22.760
All right, hi. I'm Barish from Intel. I will continue talking about the work. So, we have

00:22.760 --> 00:31.840
seen that the overall location expressions are important. They play a crucial role in debugging.

00:31.840 --> 00:37.160
So here I'm giving you, and I took this, this is a real example. I took this from a, from

00:37.160 --> 00:46.960
a GPU program. It's a location expression, a sequence of the law for operators. And you

00:46.960 --> 00:53.920
may be now a developer who is relatively new to this debugging world. And then you may

00:53.920 --> 00:59.760
be wondering, okay, what does this mean? I mean, I want to learn. So I want to evaluate

00:59.760 --> 01:07.080
this step by step, and I want to understand how the dwarf expressions semantics are. Or you

01:07.080 --> 01:14.080
may be a relatively seasoned developer in this world. But then maybe there's a bug here,

01:14.080 --> 01:17.760
and then you want to debug the expression. You want to understand the details. Or perhaps

01:17.760 --> 01:25.480
you want to optimize it. You want to find a better way of expressing the location. Or perhaps

01:25.480 --> 01:32.160
you are an expert, and you want to introduce a new operator with some other with new semantics

01:32.160 --> 01:39.600
in the dwarf spec. And then you want to define this. You want to experiment with some examples.

01:39.680 --> 01:46.800
You want to test. You want to show this to other people and so on. Well, for this, I present

01:46.800 --> 01:55.600
you to the dwarf evaluator. We can go to, let's see if this is going to work.

01:55.600 --> 02:19.680
Yeah. So this is the repository. And there's one file here, ML. That's, you don't, okay, let me

02:19.680 --> 02:27.680
quit this. Yeah. Yeah. So there's one, there's one ML file. This is written in OCaml. I will just

02:27.680 --> 02:33.040
quit this scroll down. There are some definitions, functions, et cetera, et cetera, et cetera, and

02:33.040 --> 02:43.920
then there are the functions that define the semantics. And then like about here, let's

02:43.920 --> 02:55.840
the end. So in less than, less than 700 lines of code, it's, it's done. The rest is just examples.

02:55.840 --> 03:00.320
So you can just take this, I mean, it's lightweight and concise. So you can just take this one,

03:00.320 --> 03:07.040
just copy and paste. There are some, some OCaml interpreters online. You can just put them

03:07.040 --> 03:11.680
there. You can evaluate inside the browser or you can install it in your terminal and then

03:11.760 --> 03:29.440
work with it. It's not a parser. I will show. I will show. Yeah. So it's implemented in OCaml,

03:29.440 --> 03:36.000
which I think is the second best choice for this purpose. The first one would have been

03:36.080 --> 03:45.280
algal-68, but I don't know how to program it. Yeah. There's also a web playground. I'm going

03:45.280 --> 03:56.880
to show this to you. These are the operators that are currently implemented. It's not the full set,

03:56.880 --> 04:02.720
but I think it's, it's pretty, pretty representative and you can, you can do useful stuff.

04:03.680 --> 04:10.800
So on the left-hand side, we see some snippets from the actual devolve spec version 6.

04:12.080 --> 04:16.480
I don't expect you to read this, of course, but I have highlighted some important places,

04:16.480 --> 04:22.320
and I will show some correspondence with implementation. For instance, here it says a location

04:22.320 --> 04:28.960
names a block of storage and an offset. Well, what this means is that location is a pair of storage

04:29.040 --> 04:34.640
and offset. Here it's, here is the definition. Location is a pair, storage and an integer.

04:35.200 --> 04:41.600
Or it says there are six kinds of storage, memory register, the one in the composite. So memory

04:41.600 --> 04:47.680
register composite. Composite storage consists of a possibly empty series of continues pieces.

04:47.680 --> 04:57.520
Well, composite storage has a list of pieces and so on. So with the spec, the verbal English version

04:57.600 --> 05:04.400
of the spec versus the code. I hope that there will, there will be a nice correspondence to,

05:06.080 --> 05:10.480
to show how, how this is defined. Some more examples, again from the spec,

05:12.480 --> 05:18.160
the expressions operate on a stack of entries. Each of which may be either a value or location.

05:18.160 --> 05:24.480
Now, a stack element is either a value or a location. And then there is this evolve function,

05:24.480 --> 05:30.800
which takes an operator, stack and the context. Okamol is valid, it's typed and types are

05:30.800 --> 05:36.560
inferred. It's not explicit written here, but the inferred type for this argument,

05:36.560 --> 05:44.320
stack argument is a list of stack elements, which is just a stack. Again, taking a look at the definition

05:44.320 --> 05:52.640
of DWOp Adder. It says, well, takes an Ad, takes an operant, which is address in the default

05:52.720 --> 05:58.720
address space. And the corresponding memory location is pushed onto the stack. Well, let's take

05:58.720 --> 06:09.200
a look at how it's defined. Default address space is map 0, 0 is the default index. And then with

06:09.200 --> 06:15.360
the given address, which happens now, happens to be the offset, we push a location onto the stack.

06:15.520 --> 06:23.760
Or for the REC operators, a location that names the storage associated with the designated

06:23.760 --> 06:28.800
register with an offset of 0 is formed and pushed on the stack. Exactly what's happening here,

06:28.800 --> 06:37.040
furnishes for REC one. We form a location for REC one with offset 0 and push it on top of the stack.

06:37.120 --> 06:45.920
A few more examples. Well, DWOp top duplicates the entry. Here, the pattern matching

06:46.960 --> 06:55.440
feature of a cable disiting excellent. So we do a pattern matching on the stack. We expect an

06:55.440 --> 07:01.040
element on the top with rest of the stack, which is now a stack prime. And then we duplicate it,

07:01.120 --> 07:06.880
E1, the element E1 followed by E1 again, followed by rest of the stack. Or for rotation,

07:06.880 --> 07:13.280
says there are three stack entries. Well, then the stack has to be E1, an element followed by another,

07:13.280 --> 07:21.200
followed by the rest. And then we rotate them and then give the give the new state of the stack.

07:22.080 --> 07:27.280
Relational operators, again, I don't expect you to read, but what it says is that, well, we push the

07:27.360 --> 07:32.960
constant value one or zero depending on the operation. Well, here is the definition,

07:33.840 --> 07:40.400
we expect E1 and E2 and then they have to be values, so that we can compare them. And then depending

07:40.400 --> 07:52.000
on the result of comparison, we either push value one or value zero. Here is how you can use it.

07:52.560 --> 08:04.800
Um, for this I want to give a demo. I start your camera, yeah, interpreter and then I load the file.

08:05.760 --> 08:16.560
And then I can say for instance, I want to evaluate the work list of the work operators. So let me push

08:17.440 --> 08:28.720
um, three, let me push four and then I'm going to multiply. I want to evaluate this in an in the

08:28.720 --> 08:36.400
empty stack initially and in an empty context. So I do that and I get the result. Okay, so this is how

08:37.040 --> 08:52.080
it's not a parser, this is how you can use it. This is an actual example, again from the spec,

08:52.080 --> 09:00.400
an example for for the pick operator. Well, here is what I did. I want to, I want a DW pick

09:00.400 --> 09:09.680
two evaluated in this initial stack, 17, 29, 1000 and then I get this as the result.

09:14.080 --> 09:18.640
Um, another example, again, actual example from the stack, this time it relates to a

09:19.200 --> 09:30.640
location. Um, so composite location is being formed with these operators. What I did is that

09:30.640 --> 09:36.640
well, frame frame base register, I mean it's ABI dependent, so I just said, okay, let's let's

09:36.640 --> 09:43.360
say register nine is frame base. And then I evaluate in a context where we need to define our

09:43.360 --> 09:48.000
register zero and register nine and then I get this composite with three pieces. Well,

09:49.440 --> 09:57.360
the first part is first four bytes reciting register zero, so byte zero until four registers zero.

09:58.000 --> 10:04.240
Middle four bytes are unavailable, unavailable and the last four bytes are in memory 12 bytes

10:04.240 --> 10:10.800
before the frame base. So last four bytes, they are in memory and the value 30 which is 12 bytes

10:11.760 --> 10:23.680
below the frame base. This is the text which gives which defines piece operators, which defines

10:23.680 --> 10:32.880
the piece operations and there is also definition of compatibility rules for the world version five.

10:32.880 --> 10:38.640
There are three rules. Now, if you look at the, look at the code well, we have three

10:38.720 --> 10:44.800
compatibility rules. The point I'm trying to make here is that for some people looking at this

10:45.520 --> 10:51.120
maybe easier to understand and the purpose is to help these people.

10:54.000 --> 11:00.480
There's a web playground. This was contributed by Scott Lindner from AMD, so full credits goes to him.

11:00.560 --> 11:07.840
And I thank him very much. In the web playground, you can do step by step.

11:07.840 --> 11:30.800
So here you type the context, you type the expression and then it evaluates. Here's an example.

11:31.760 --> 11:52.320
In the AMD context, I'm going to evaluate DWOP lit 5 DWOP lit 8 DWOP plus DWOP lit 3 and then let's say multiply.

11:52.960 --> 12:00.880
And then I evaluate. This shows you the state of step by step. So here's the state of the

12:00.880 --> 12:09.280
stack and then we evaluate this. We get this stack state and so on until and we end up with the value.

12:09.280 --> 12:30.640
In the web, let's try it again. So I should have opened this already.

12:30.960 --> 12:42.000
I'm going to show you another example. The same example from the actual spec,

12:42.000 --> 12:58.800
but done in the web playground. What we see, here's the same example.

13:01.200 --> 13:07.920
The expression there and when I evaluate again, it goes step by step and then we end up with a location on

13:07.920 --> 13:26.000
top of the stack. This is the result. I just cut it from there and then again you can see the

13:26.000 --> 13:32.720
correspondence between what the spec explains and what we end up with. This is a composite location.

13:33.680 --> 13:44.000
There's actually a DWOP issue where which defines a new operator. Overlay.

13:45.600 --> 13:56.880
I'm finishing and here there are some examples and here you would see links like this.

13:57.200 --> 14:04.320
You can just open it, evaluate it and you can see what the example is named. So this is another

14:04.320 --> 14:07.920
use case where such a tool could be useful.

14:07.920 --> 14:28.920
I present to you, I present to you the Wurf evaluator. To learn or teach, to understand the

14:28.920 --> 14:36.600
Wurf expressions, I think it's useful. I want to thank my managers for allowing me the time to work on this.

14:38.280 --> 14:44.440
There are some notices and disclaimers. Thank you for reading and with that I conclude.

14:45.080 --> 15:08.520
Why is not in GDP? So the goal here is that it's lightweight. You just take it and we're

15:08.520 --> 15:16.200
not having to go into the details of a full-fledged compiler or a debugger you can just run it and

15:16.200 --> 15:26.040
experiment with it easily. Thank you.

