1 00:00:00,480 --> 00:00:03,480 foreign 2 00:00:09,679 --> 00:00:15,000 ER on the micropython project and a 3 00:00:12,960 --> 00:00:17,580 part-time physics student 4 00:00:15,000 --> 00:00:20,699 um a student of part-time physics and 5 00:00:17,580 --> 00:00:22,680 then formerly SRE at Google and uh 6 00:00:20,699 --> 00:00:25,980 programmer of group learning 7 00:00:22,680 --> 00:00:28,260 um thank you thanks very much Jim 8 00:00:25,980 --> 00:00:30,420 okay thank you very much for the intro 9 00:00:28,260 --> 00:00:32,340 okay so people who are in this room are 10 00:00:30,420 --> 00:00:33,780 going to feel a lot of deja vu from the 11 00:00:32,340 --> 00:00:34,800 last half an hour 12 00:00:33,780 --> 00:00:36,000 um we're gonna go in a slightly 13 00:00:34,800 --> 00:00:37,320 different direction but a lot of the 14 00:00:36,000 --> 00:00:39,300 topic is going to be the same I might 15 00:00:37,320 --> 00:00:40,739 reinforce a couple of the same ideas if 16 00:00:39,300 --> 00:00:42,360 if you're new to wasm that might be 17 00:00:40,739 --> 00:00:44,399 useful but 18 00:00:42,360 --> 00:00:46,440 um bear with us and and save some 19 00:00:44,399 --> 00:00:49,760 questions at the end we'll try and 20 00:00:46,440 --> 00:00:49,760 together and answer them 21 00:00:49,800 --> 00:00:54,300 this is a talk about Distributing native 22 00:00:51,600 --> 00:00:56,460 code in your python wheel so when I 23 00:00:54,300 --> 00:00:57,660 install a package from pip I install it 24 00:00:56,460 --> 00:00:59,280 it downloads 25 00:00:57,660 --> 00:01:01,079 some untrusted piece of code from the 26 00:00:59,280 --> 00:01:02,399 internet that I am about to run on my 27 00:01:01,079 --> 00:01:03,000 computer 28 00:01:02,399 --> 00:01:04,860 um 29 00:01:03,000 --> 00:01:06,720 but sometimes I want to put native code 30 00:01:04,860 --> 00:01:08,280 in that but where Python program is why 31 00:01:06,720 --> 00:01:09,720 do why do we want to do this 32 00:01:08,280 --> 00:01:11,820 and the answer is that there's just some 33 00:01:09,720 --> 00:01:13,860 things that we cannot do in Python 34 00:01:11,820 --> 00:01:15,720 um two main reasons one is we need 35 00:01:13,860 --> 00:01:16,740 performance and the second is that the 36 00:01:15,720 --> 00:01:19,280 code is already written in another 37 00:01:16,740 --> 00:01:21,420 language be it C or rust 38 00:01:19,280 --> 00:01:24,000 and it's just not feasible for us to 39 00:01:21,420 --> 00:01:25,320 rewrite that in Python and we want to 40 00:01:24,000 --> 00:01:27,500 distribute it as part of our Python 41 00:01:25,320 --> 00:01:27,500 program 42 00:01:27,900 --> 00:01:31,560 and this talk is going to build built 43 00:01:30,240 --> 00:01:33,240 around a project that I worked on for 44 00:01:31,560 --> 00:01:34,860 micropython this is not a talk about 45 00:01:33,240 --> 00:01:36,600 micropython but this is the thing that 46 00:01:34,860 --> 00:01:38,880 we ran into while building a micropython 47 00:01:36,600 --> 00:01:40,860 tool so we have this tool called Empire 48 00:01:38,880 --> 00:01:43,259 cross it is the micro python cross 49 00:01:40,860 --> 00:01:45,600 compiler what it does is it takes python 50 00:01:43,259 --> 00:01:48,119 source code and emits python micro 51 00:01:45,600 --> 00:01:50,399 python bytecode so the output of this 52 00:01:48,119 --> 00:01:52,560 program is a DOT mpy file that you can 53 00:01:50,399 --> 00:01:54,299 copy onto your embedded device and then 54 00:01:52,560 --> 00:01:56,100 have The micropython Interpreter on the 55 00:01:54,299 --> 00:01:58,320 device execute that code 56 00:01:56,100 --> 00:01:59,759 it's a very useful tool because even 57 00:01:58,320 --> 00:02:00,780 though the devices have a compiler on 58 00:01:59,759 --> 00:02:03,180 them and it's very useful to be able to 59 00:02:00,780 --> 00:02:05,399 put a py file straight on the device 60 00:02:03,180 --> 00:02:07,380 it's bigger and takes more time and uses 61 00:02:05,399 --> 00:02:10,200 more memory and so forth 62 00:02:07,380 --> 00:02:11,819 but this compiler is written using the 63 00:02:10,200 --> 00:02:15,180 same code base as micropython itself 64 00:02:11,819 --> 00:02:16,739 it's written in C and it's not feasible 65 00:02:15,180 --> 00:02:19,739 to tell people here's our GitHub 66 00:02:16,739 --> 00:02:22,260 download it and run make install the 67 00:02:19,739 --> 00:02:23,400 tool chain all that sort of thing the 68 00:02:22,260 --> 00:02:26,220 second thing is people want to use this 69 00:02:23,400 --> 00:02:27,300 as a building block in their own python 70 00:02:26,220 --> 00:02:29,819 tooling someone might write a 71 00:02:27,300 --> 00:02:32,160 micropython IDE and need to generate 72 00:02:29,819 --> 00:02:34,080 micro python bytecode so we actually 73 00:02:32,160 --> 00:02:36,239 publish it as a library for python users 74 00:02:34,080 --> 00:02:38,040 as well and it turns out pip is just a 75 00:02:36,239 --> 00:02:40,200 really great way to distribute software 76 00:02:38,040 --> 00:02:42,120 everyone in the python community and 77 00:02:40,200 --> 00:02:44,160 micropython is part of that micropy of 78 00:02:42,120 --> 00:02:45,720 the part of the Python Community knows 79 00:02:44,160 --> 00:02:47,879 how to use pip to install packages and 80 00:02:45,720 --> 00:02:49,739 tools 81 00:02:47,879 --> 00:02:51,000 um it's also an interesting case that it 82 00:02:49,739 --> 00:02:53,040 doesn't actually need to be really 83 00:02:51,000 --> 00:02:55,739 really really fast most times you 84 00:02:53,040 --> 00:02:58,620 compile a python source code that might 85 00:02:55,739 --> 00:03:00,660 be at most a few kilobytes long we can 86 00:02:58,620 --> 00:03:02,879 we can run quite slowly and still have 87 00:03:00,660 --> 00:03:05,160 an instantaneous response time 88 00:03:02,879 --> 00:03:06,420 it's also interesting because it has no 89 00:03:05,160 --> 00:03:08,760 dependencies 90 00:03:06,420 --> 00:03:11,220 um it it needs a c compiler to compile 91 00:03:08,760 --> 00:03:13,019 and it doesn't do anything to the 92 00:03:11,220 --> 00:03:15,360 operating system it doesn't use any 93 00:03:13,019 --> 00:03:16,860 other complicated libraries so it's a 94 00:03:15,360 --> 00:03:18,480 self-contained piece of code that does a 95 00:03:16,860 --> 00:03:19,980 calculation this is a bit different to 96 00:03:18,480 --> 00:03:21,180 Katie's talking that in that we're 97 00:03:19,980 --> 00:03:22,440 talking about running a program that 98 00:03:21,180 --> 00:03:24,780 does all sorts of operating system 99 00:03:22,440 --> 00:03:26,819 functionality and and YZ provides an 100 00:03:24,780 --> 00:03:28,200 interface to do that micro python the 101 00:03:26,819 --> 00:03:30,239 cross compiler you can think of much 102 00:03:28,200 --> 00:03:31,980 more as a 103 00:03:30,239 --> 00:03:34,379 um a thing that does a calculation and 104 00:03:31,980 --> 00:03:37,019 produces a result it's just code rather 105 00:03:34,379 --> 00:03:39,840 than anything else 106 00:03:37,019 --> 00:03:41,519 and what we currently do is we build it 107 00:03:39,840 --> 00:03:43,319 as an executable you can run it at your 108 00:03:41,519 --> 00:03:46,560 command line on Windows it's a DOT XC on 109 00:03:43,319 --> 00:03:48,659 Linux it's a an a DOT out and we write 110 00:03:46,560 --> 00:03:51,000 we have a python library that wraps that 111 00:03:48,659 --> 00:03:54,120 and invokes it with sub process so if I 112 00:03:51,000 --> 00:03:57,120 want to invoke uh when I invoke the 113 00:03:54,120 --> 00:03:59,220 thing that I installed by by pip it's a 114 00:03:57,120 --> 00:04:01,019 python thing with a main function that 115 00:03:59,220 --> 00:04:03,720 just calls sub process with with its 116 00:04:01,019 --> 00:04:05,099 arguments straight through we could have 117 00:04:03,720 --> 00:04:07,280 written this as I see python extension 118 00:04:05,099 --> 00:04:10,560 and then I would have a python library 119 00:04:07,280 --> 00:04:12,659 that Imports the C python extension that 120 00:04:10,560 --> 00:04:14,519 is the same code AS Empire cross instead 121 00:04:12,659 --> 00:04:16,859 of being packaged in a standalone 122 00:04:14,519 --> 00:04:18,000 executable it's a it's an it's a just a 123 00:04:16,859 --> 00:04:20,900 piece of code that I could load into 124 00:04:18,000 --> 00:04:20,900 python somehow 125 00:04:21,359 --> 00:04:24,240 um this is almost the exact same thing 126 00:04:22,860 --> 00:04:25,919 that a lot of other libraries do there's 127 00:04:24,240 --> 00:04:29,460 a lot of things with native code on on 128 00:04:25,919 --> 00:04:31,919 on on Pi Pi numpy is probably the 129 00:04:29,460 --> 00:04:34,560 example that everybody's come across 130 00:04:31,919 --> 00:04:36,600 um or at least is most likely to 131 00:04:34,560 --> 00:04:38,820 compress a numpy's a dependency on so 132 00:04:36,600 --> 00:04:41,220 many things in the python ecosystem 133 00:04:38,820 --> 00:04:43,020 and numpy has both of those requirements 134 00:04:41,220 --> 00:04:45,300 one is that it's very high performance 135 00:04:43,020 --> 00:04:46,979 code couldn't be written in pure Python 136 00:04:45,300 --> 00:04:49,380 and the second is that it's code that 137 00:04:46,979 --> 00:04:51,479 was written decades ago in Fortran and 138 00:04:49,380 --> 00:04:53,220 has been perfected and evolved and 139 00:04:51,479 --> 00:04:55,139 nobody understands it anymore and nobody 140 00:04:53,220 --> 00:04:55,979 wants to modify it or change it in any 141 00:04:55,139 --> 00:04:57,979 way 142 00:04:55,979 --> 00:05:01,139 but it works and it's perfect it's it's 143 00:04:57,979 --> 00:05:03,620 probably perfect and and and and can be 144 00:05:01,139 --> 00:05:03,620 used as is 145 00:05:04,259 --> 00:05:08,160 but it's really hard to distribute code 146 00:05:06,020 --> 00:05:10,080 it's unbelievable to be standing here in 147 00:05:08,160 --> 00:05:11,639 2023 and say I don't know how to 148 00:05:10,080 --> 00:05:13,919 distribute code on the Internet or like 149 00:05:11,639 --> 00:05:15,000 distribute my software on the internet 150 00:05:13,919 --> 00:05:16,919 um does anyone here know what a mini 151 00:05:15,000 --> 00:05:19,560 Linux is does that word mean anything 152 00:05:16,919 --> 00:05:20,340 okay so simple to build native packages 153 00:05:19,560 --> 00:05:23,639 um 154 00:05:20,340 --> 00:05:26,520 this is numpy on Pi Pi 155 00:05:23,639 --> 00:05:30,180 there are 24 different Wheels to install 156 00:05:26,520 --> 00:05:31,680 pipei and depending on what platform OS 157 00:05:30,180 --> 00:05:33,360 architecture 158 00:05:31,680 --> 00:05:35,160 phase of the moon 159 00:05:33,360 --> 00:05:36,539 one of those files gets downloaded and 160 00:05:35,160 --> 00:05:38,220 installed on your computer 161 00:05:36,539 --> 00:05:39,539 now you can see here that this I have to 162 00:05:38,220 --> 00:05:41,400 Target different C python versions 163 00:05:39,539 --> 00:05:44,039 because it's a c python extension so the 164 00:05:41,400 --> 00:05:48,660 ABI changes I have to Target different 165 00:05:44,039 --> 00:05:50,039 architectures there's arm there's x86 166 00:05:48,660 --> 00:05:51,300 um someone said to me earlier this week 167 00:05:50,039 --> 00:05:52,740 so you can tell your compiler person 168 00:05:51,300 --> 00:05:55,139 because when I said arm you said which 169 00:05:52,740 --> 00:05:57,780 arm and there are multiple versions of 170 00:05:55,139 --> 00:05:59,340 arm ah 64 is different if you're on a 171 00:05:57,780 --> 00:06:01,560 Raspberry Pi versus if you're on an M1 172 00:05:59,340 --> 00:06:02,940 Mac for example 173 00:06:01,560 --> 00:06:04,440 um there's even different variations of 174 00:06:02,940 --> 00:06:06,300 the same platform in the middle there is 175 00:06:04,440 --> 00:06:09,300 two versions of Linux there's muza Linux 176 00:06:06,300 --> 00:06:10,860 and many Linux different glibc versions 177 00:06:09,300 --> 00:06:14,220 um to answer the question many Linux is 178 00:06:10,860 --> 00:06:18,000 a very carefully maintained 2014 era 179 00:06:14,220 --> 00:06:20,039 image of a Linux machine that if you 180 00:06:18,000 --> 00:06:21,360 build software on that it will still run 181 00:06:20,039 --> 00:06:23,460 today 182 00:06:21,360 --> 00:06:26,039 um on any on a Linux today but if I 183 00:06:23,460 --> 00:06:27,360 compile a binary on my PC now it would 184 00:06:26,039 --> 00:06:29,819 not run on 185 00:06:27,360 --> 00:06:31,740 other other linuxes and especially older 186 00:06:29,819 --> 00:06:33,660 linuxes 187 00:06:31,740 --> 00:06:35,940 imagine you're a project like us we 188 00:06:33,660 --> 00:06:37,680 write embedded code we don't think about 189 00:06:35,940 --> 00:06:39,780 software distribution we're not part of 190 00:06:37,680 --> 00:06:41,400 an ecosystem like this we cannot take on 191 00:06:39,780 --> 00:06:43,440 board the maintenance of building a CI 192 00:06:41,400 --> 00:06:46,500 Pipeline and a build system that can 193 00:06:43,440 --> 00:06:50,039 produce 24 different things so we were 194 00:06:46,500 --> 00:06:51,840 talking about how to solve this and 195 00:06:50,039 --> 00:06:53,160 thinking about how do we actually 196 00:06:51,840 --> 00:06:54,539 distribute code and because we're 197 00:06:53,160 --> 00:06:56,759 embedded people the conversation went 198 00:06:54,539 --> 00:06:59,580 something like what if we wrote a risk 5 199 00:06:56,759 --> 00:07:01,259 emulator in Python and compiled Empire 200 00:06:59,580 --> 00:07:02,759 cross because we because we're a 201 00:07:01,259 --> 00:07:05,220 microphone there is an embedded software 202 00:07:02,759 --> 00:07:07,800 project and we target risk five and arm 203 00:07:05,220 --> 00:07:09,240 and cortex and stuff like that 204 00:07:07,800 --> 00:07:10,380 um and we're like no that's a bad idea 205 00:07:09,240 --> 00:07:13,979 and then 206 00:07:10,380 --> 00:07:15,660 um another well but we thought about it 207 00:07:13,979 --> 00:07:17,520 um somebody else sent me this the other 208 00:07:15,660 --> 00:07:20,280 day which is if you take a Windows 209 00:07:17,520 --> 00:07:22,440 binary from like the early 90s it will 210 00:07:20,280 --> 00:07:24,599 run on whatever the latest Windows 11 211 00:07:22,440 --> 00:07:26,460 today they have done an incredible job 212 00:07:24,599 --> 00:07:28,139 of Ford's compatibility and they can use 213 00:07:26,460 --> 00:07:30,599 wine on pretty much every other platform 214 00:07:28,139 --> 00:07:32,280 to run that 1995 here at Windows binary 215 00:07:30,599 --> 00:07:34,740 what if we just made a Windows 216 00:07:32,280 --> 00:07:37,160 compilation of Empire cross and just if 217 00:07:34,740 --> 00:07:37,160 you did that 218 00:07:41,599 --> 00:07:44,699 thing maybe why is themselves this 219 00:07:43,860 --> 00:07:46,199 problem 220 00:07:44,699 --> 00:07:47,039 and it turns out it wasn't to solve this 221 00:07:46,199 --> 00:07:49,020 problem 222 00:07:47,039 --> 00:07:51,120 so what is wasm you should go back in 223 00:07:49,020 --> 00:07:52,380 time and watch Katie's talk and learn 224 00:07:51,120 --> 00:07:53,460 what was them is but this is a quick 225 00:07:52,380 --> 00:07:54,060 recap 226 00:07:53,460 --> 00:07:56,520 um 227 00:07:54,060 --> 00:07:58,740 we have a compiler M scripton this is a 228 00:07:56,520 --> 00:08:01,020 replacement for your C compiler GCC or 229 00:07:58,740 --> 00:08:03,599 whatever and built on the amazing 230 00:08:01,020 --> 00:08:05,460 infrastructure of llvm and clang and it 231 00:08:03,599 --> 00:08:07,740 can produce what was originally a thing 232 00:08:05,460 --> 00:08:09,539 that ran in the browser JavaScript and 233 00:08:07,740 --> 00:08:10,139 now is a dedicated 234 00:08:09,539 --> 00:08:13,860 um 235 00:08:10,139 --> 00:08:15,120 binary format webassembly the browser 236 00:08:13,860 --> 00:08:16,440 support and as we're going to see things 237 00:08:15,120 --> 00:08:18,000 as Katie mentioned things outside the 238 00:08:16,440 --> 00:08:19,139 browser now support 239 00:08:18,000 --> 00:08:21,139 now 240 00:08:19,139 --> 00:08:25,560 this is not a talk about running 241 00:08:21,139 --> 00:08:27,240 code in the browser but related to this 242 00:08:25,560 --> 00:08:28,979 we're all this is why was kind of on our 243 00:08:27,240 --> 00:08:30,240 radar is that we also run micropython in 244 00:08:28,979 --> 00:08:31,919 the browser as part of a thing called Pi 245 00:08:30,240 --> 00:08:33,180 script it's a totally different problem 246 00:08:31,919 --> 00:08:35,520 a totally different thing that we're 247 00:08:33,180 --> 00:08:38,419 solving but it's really cool what you 248 00:08:35,520 --> 00:08:38,419 can do with that wasm 249 00:08:38,820 --> 00:08:42,959 um 250 00:08:40,260 --> 00:08:44,099 within the day we just distribute code 251 00:08:42,959 --> 00:08:46,560 and 252 00:08:44,099 --> 00:08:49,260 um and you have to 253 00:08:46,560 --> 00:08:50,820 have a way to run that code 254 00:08:49,260 --> 00:08:53,279 um I'm starting to think of computers 255 00:08:50,820 --> 00:08:56,160 less as I have a computer that is like 256 00:08:53,279 --> 00:08:58,560 an x86 or a PC or a Mac or whatever 257 00:08:56,160 --> 00:08:59,580 rather I just distribute code and I 258 00:08:58,560 --> 00:09:02,339 happen to sometimes have Hardware 259 00:08:59,580 --> 00:09:04,320 acceleration for it and 260 00:09:02,339 --> 00:09:06,120 wasm is just one thing that can generate 261 00:09:04,320 --> 00:09:07,800 a thing that my computer can run and it 262 00:09:06,120 --> 00:09:09,779 just so happens that we have a common 263 00:09:07,800 --> 00:09:12,000 way of running that on lots of different 264 00:09:09,779 --> 00:09:14,339 types of computers now 265 00:09:12,000 --> 00:09:15,899 as I said earlier Empire cross is just a 266 00:09:14,339 --> 00:09:17,459 thing that does a calculation it takes a 267 00:09:15,899 --> 00:09:19,080 byte stream as an input and produces a 268 00:09:17,459 --> 00:09:21,899 byte stream of output 269 00:09:19,080 --> 00:09:23,519 but sometimes we want to do regular C 270 00:09:21,899 --> 00:09:25,620 program things or regular rust program 271 00:09:23,519 --> 00:09:28,080 things and so Wazi which we're not going 272 00:09:25,620 --> 00:09:29,580 to talk about much is a standard for how 273 00:09:28,080 --> 00:09:32,220 to replace all those things that I 274 00:09:29,580 --> 00:09:33,839 expect my operating system to provide in 275 00:09:32,220 --> 00:09:35,940 this particular case of doing something 276 00:09:33,839 --> 00:09:38,399 like a computation I don't need any of 277 00:09:35,940 --> 00:09:41,540 that I just need a way to call a 278 00:09:38,399 --> 00:09:43,620 function and a way to get a result 279 00:09:41,540 --> 00:09:46,200 so there are actually four different 280 00:09:43,620 --> 00:09:47,880 ways to run wasm in Python so to recap 281 00:09:46,200 --> 00:09:49,980 what we have is I have a Python program 282 00:09:47,880 --> 00:09:51,899 that I want to use a piece of native 283 00:09:49,980 --> 00:09:53,100 code inside and so previously what I 284 00:09:51,899 --> 00:09:56,399 would have done is written a python 285 00:09:53,100 --> 00:09:58,620 extension a a native extension and 286 00:09:56,399 --> 00:09:59,880 linked that into my wheel 287 00:09:58,620 --> 00:10:01,500 but now what we're going to do is we 288 00:09:59,880 --> 00:10:03,600 we're going to compile our code to wasm 289 00:10:01,500 --> 00:10:06,899 and we're going to try and call 290 00:10:03,600 --> 00:10:10,620 functions inside that wasm binary 291 00:10:06,899 --> 00:10:12,000 so these four runtimes are piwasm which 292 00:10:10,620 --> 00:10:13,920 is a pure python implementation 293 00:10:12,000 --> 00:10:15,360 otherwise and runtime this is really 294 00:10:13,920 --> 00:10:17,040 cool because it has no dependencies 295 00:10:15,360 --> 00:10:19,320 other than things that are already on Pi 296 00:10:17,040 --> 00:10:20,940 Pi like like numpy but as you can 297 00:10:19,320 --> 00:10:23,519 imagine writing a Python program to 298 00:10:20,940 --> 00:10:25,339 emulate a machine to run webassembly 299 00:10:23,519 --> 00:10:27,660 code it's really slow 300 00:10:25,339 --> 00:10:28,860 it's very easy to use and works very 301 00:10:27,660 --> 00:10:30,480 well and it's a great way to learn about 302 00:10:28,860 --> 00:10:32,220 wasm 303 00:10:30,480 --> 00:10:34,200 although we don't need micropython cross 304 00:10:32,220 --> 00:10:36,000 compiler to be really fast it's too slow 305 00:10:34,200 --> 00:10:37,500 for microphone 306 00:10:36,000 --> 00:10:40,080 the next three are all really really 307 00:10:37,500 --> 00:10:42,720 good options so piwasm three is 308 00:10:40,080 --> 00:10:44,160 distributed as a source binary so as a 309 00:10:42,720 --> 00:10:46,260 source wheel so it will install 310 00:10:44,160 --> 00:10:47,640 everywhere the problem is is that 311 00:10:46,260 --> 00:10:49,440 because it's distributed to Source 312 00:10:47,640 --> 00:10:53,459 binary it needs to compile so you must 313 00:10:49,440 --> 00:10:55,980 have GCC and the python Dev like the 314 00:10:53,459 --> 00:10:58,920 development headers installed so as a 315 00:10:55,980 --> 00:11:00,720 fallback as a way to run wasm as a 316 00:10:58,920 --> 00:11:02,640 dependency to have to your program so 317 00:11:00,720 --> 00:11:04,620 that your program can run wasm it's kind 318 00:11:02,640 --> 00:11:06,200 of a universal run Universal will run 319 00:11:04,620 --> 00:11:08,459 anywhere on time 320 00:11:06,200 --> 00:11:10,440 plasma and wasm time are the sort of 321 00:11:08,459 --> 00:11:12,660 slightly more sophisticated ones 322 00:11:10,440 --> 00:11:14,040 um based on based on projects that are 323 00:11:12,660 --> 00:11:15,540 built to run wise them in lots of 324 00:11:14,040 --> 00:11:17,420 different places and Katie already 325 00:11:15,540 --> 00:11:19,620 mentioned wasm time 326 00:11:17,420 --> 00:11:21,120 these use quite sophisticated things 327 00:11:19,620 --> 00:11:22,700 like crane lift so they can generate 328 00:11:21,120 --> 00:11:25,680 native code they'll take your wasm 329 00:11:22,700 --> 00:11:27,360 binary and re-emit that as native code 330 00:11:25,680 --> 00:11:29,279 for your machine so you get nearly 331 00:11:27,360 --> 00:11:31,380 performance parity 332 00:11:29,279 --> 00:11:33,300 um and nowadays with things that the web 333 00:11:31,380 --> 00:11:36,000 the wasm has extensions for things like 334 00:11:33,300 --> 00:11:38,459 simd and Vector instructions 335 00:11:36,000 --> 00:11:40,740 um it knows how to do things like 336 00:11:38,459 --> 00:11:42,660 um set jump and and all sorts of 337 00:11:40,740 --> 00:11:44,399 floating Point features and whatever and 338 00:11:42,660 --> 00:11:45,779 so you can actually 339 00:11:44,399 --> 00:11:47,820 run 340 00:11:45,779 --> 00:11:48,660 your original code as fast as it would 341 00:11:47,820 --> 00:11:51,000 have run 342 00:11:48,660 --> 00:11:53,339 if you just compiled it directly 343 00:11:51,000 --> 00:11:56,279 I'm going to talk about the last three 344 00:11:53,339 --> 00:11:59,760 and highlights as an API sort of study 345 00:11:56,279 --> 00:12:01,019 of how the three different projects work 346 00:11:59,760 --> 00:12:04,440 but all you really need to know about 347 00:12:01,019 --> 00:12:07,560 running wasm code is that a wasm binary 348 00:12:04,440 --> 00:12:09,060 is a DOT wasm file that Imports a bunch 349 00:12:07,560 --> 00:12:11,339 of functions that it expects you to 350 00:12:09,060 --> 00:12:12,720 provide it exports a bunch of functions 351 00:12:11,339 --> 00:12:15,120 that you can call 352 00:12:12,720 --> 00:12:16,980 everything is integers it doesn't know 353 00:12:15,120 --> 00:12:18,180 it's just machine code it knows how to 354 00:12:16,980 --> 00:12:19,980 take an integer as an argument and 355 00:12:18,180 --> 00:12:21,120 return as an integration argument if you 356 00:12:19,980 --> 00:12:22,560 want to do something more sophisticated 357 00:12:21,120 --> 00:12:24,240 like deal with strings 358 00:12:22,560 --> 00:12:25,620 it's an integer that points to memory 359 00:12:24,240 --> 00:12:28,019 that's the start of the string and it 360 00:12:25,620 --> 00:12:30,120 tells you how long the string is so it's 361 00:12:28,019 --> 00:12:32,399 quite low level and and built on on 362 00:12:30,120 --> 00:12:34,500 these fundamentals but as far as your 363 00:12:32,399 --> 00:12:37,320 python interrupt goes you only have to 364 00:12:34,500 --> 00:12:38,640 deal with int and then a day memory just 365 00:12:37,320 --> 00:12:40,860 looks like this big 366 00:12:38,640 --> 00:12:42,899 list of integers that you can read and 367 00:12:40,860 --> 00:12:45,420 write to 368 00:12:42,899 --> 00:12:46,139 so I'm going to give a quick 369 00:12:45,420 --> 00:12:48,740 um 370 00:12:46,139 --> 00:12:48,740 demo 371 00:12:50,279 --> 00:12:53,300 so here is a piece of native code that 372 00:12:52,019 --> 00:12:55,019 is doing a very very sophisticated 373 00:12:53,300 --> 00:12:57,480 calculation in this case it's 374 00:12:55,019 --> 00:12:59,160 calculating the greatest common divisor 375 00:12:57,480 --> 00:13:01,320 of two numbers using Euclid's algorithm 376 00:12:59,160 --> 00:13:02,639 I would write this in Python and there 377 00:13:01,320 --> 00:13:04,200 would be no reason not to write this in 378 00:13:02,639 --> 00:13:06,300 Python just to be really clear but I'm 379 00:13:04,200 --> 00:13:08,880 giving an example of how to how to how I 380 00:13:06,300 --> 00:13:11,160 might be starting from some point 381 00:13:08,880 --> 00:13:13,260 and what I've done is I've added this 382 00:13:11,160 --> 00:13:15,300 notation to annotation to it to say in 383 00:13:13,260 --> 00:13:16,860 script and keep alive and that says this 384 00:13:15,300 --> 00:13:18,720 function needs to be exported from my 385 00:13:16,860 --> 00:13:20,940 wise and binary 386 00:13:18,720 --> 00:13:22,560 um it's the it's it's an entry point to 387 00:13:20,940 --> 00:13:24,060 this to this program this program 388 00:13:22,560 --> 00:13:26,459 doesn't have a main I can't run it 389 00:13:24,060 --> 00:13:28,980 directly I'm building it as a if you're 390 00:13:26,459 --> 00:13:31,139 from Windows you'd call it a dll Linux a 391 00:13:28,980 --> 00:13:34,019 bit.so file 392 00:13:31,139 --> 00:13:37,019 and it takes an end it takes two 393 00:13:34,019 --> 00:13:39,240 integers and returns an integer 394 00:13:37,019 --> 00:13:42,180 um normally I would compile C with with 395 00:13:39,240 --> 00:13:43,860 GCC but in this case I compile with EMCC 396 00:13:42,180 --> 00:13:45,959 and I've got this extra flag that says 397 00:13:43,860 --> 00:13:48,240 no entry it doesn't have an entry point 398 00:13:45,959 --> 00:13:50,700 um like a main a main function and this 399 00:13:48,240 --> 00:13:51,959 produces this wasm file 400 00:13:50,700 --> 00:13:53,519 and what's quite cool about the wasm 401 00:13:51,959 --> 00:13:55,260 tooling is it's quite inspectable and 402 00:13:53,519 --> 00:13:57,480 and debuggable there's a wasm 403 00:13:55,260 --> 00:13:58,920 disassembler 404 00:13:57,480 --> 00:14:01,320 and 405 00:13:58,920 --> 00:14:04,139 this is what Katie showed in her slide 406 00:14:01,320 --> 00:14:06,300 I've got in her in her talk it exports a 407 00:14:04,139 --> 00:14:07,740 function called gcd 408 00:14:06,300 --> 00:14:09,959 um which is the which is the number one 409 00:14:07,740 --> 00:14:12,480 function and this function is number one 410 00:14:09,959 --> 00:14:14,100 is defined and it does it does some 411 00:14:12,480 --> 00:14:16,560 computation I'm not gonna 412 00:14:14,100 --> 00:14:19,019 spend time looking into this but 413 00:14:16,560 --> 00:14:21,839 um this is the text-based representation 414 00:14:19,019 --> 00:14:24,380 of my binary gcd uasm file so if I do a 415 00:14:21,839 --> 00:14:24,380 hex dump 416 00:14:26,040 --> 00:14:29,760 is that that's actually what the file is 417 00:14:27,839 --> 00:14:31,260 it's it's it's it's it's it's it's in 418 00:14:29,760 --> 00:14:32,760 code 419 00:14:31,260 --> 00:14:34,019 um 420 00:14:32,760 --> 00:14:36,660 then 421 00:14:34,019 --> 00:14:38,579 I can use this code from python 422 00:14:36,660 --> 00:14:40,860 so what I'm doing here 423 00:14:38,579 --> 00:14:43,139 is I'm creating I'm importing wasm3 424 00:14:40,860 --> 00:14:44,519 which is the pierson3 library and I'm 425 00:14:43,139 --> 00:14:45,899 creating a wasm environment so the 426 00:14:44,519 --> 00:14:48,959 environment kind of represents the state 427 00:14:45,899 --> 00:14:50,040 of the of how to create a machine I'm 428 00:14:48,959 --> 00:14:52,440 going to configure it with things like 429 00:14:50,040 --> 00:14:54,300 stack sizes and resource limits and 430 00:14:52,440 --> 00:14:55,860 things like that related to what Katie 431 00:14:54,300 --> 00:14:58,079 said about sandboxing you can also you 432 00:14:55,860 --> 00:14:59,399 can also do quite fine grain control of 433 00:14:58,079 --> 00:15:01,880 things like how much memory the thing is 434 00:14:59,399 --> 00:15:04,380 allowed to allocate and how much 435 00:15:01,880 --> 00:15:05,760 gas it's allowed to use it's kind of a 436 00:15:04,380 --> 00:15:07,500 weird concept but you can use that as a 437 00:15:05,760 --> 00:15:09,300 kind of a way to limit how much work it 438 00:15:07,500 --> 00:15:11,399 can do 439 00:15:09,300 --> 00:15:13,440 um I'm loading 440 00:15:11,399 --> 00:15:16,380 um assist.v1 so I'm going to give the 441 00:15:13,440 --> 00:15:18,300 name of the dot wasm file as bytes and 442 00:15:16,380 --> 00:15:19,620 I'm parsing that into a module so I now 443 00:15:18,300 --> 00:15:22,079 have this was a module which is the 444 00:15:19,620 --> 00:15:24,120 python run times representation of my 445 00:15:22,079 --> 00:15:26,639 wasm file 446 00:15:24,120 --> 00:15:29,579 uh I'm creating a runtime from it um 447 00:15:26,639 --> 00:15:31,800 giving it 2K of of Stack size 448 00:15:29,579 --> 00:15:33,959 and loading my module into it 449 00:15:31,800 --> 00:15:34,860 and then I'm asking get me the gcd 450 00:15:33,959 --> 00:15:36,480 function 451 00:15:34,860 --> 00:15:38,699 and if you've ever used any kind of like 452 00:15:36,480 --> 00:15:40,139 native interop or or things like Swig 453 00:15:38,699 --> 00:15:42,060 and stuff like that this is kind of 454 00:15:40,139 --> 00:15:44,579 magic I just said find me the function 455 00:15:42,060 --> 00:15:46,139 called gcd and call it and it knew 456 00:15:44,579 --> 00:15:48,540 automatically what what arguments it 457 00:15:46,139 --> 00:15:53,160 takes what types it returns and I can 458 00:15:48,540 --> 00:15:56,060 invoke that function as gcd 459 00:15:53,160 --> 00:15:56,060 um if I run this 460 00:15:58,800 --> 00:16:02,220 yeah I've got to give it the 1005 461 00:16:00,360 --> 00:16:06,180 gcd.orgasm 462 00:16:02,220 --> 00:16:08,160 so gcd of 57 and 190 is 19. 463 00:16:06,180 --> 00:16:09,480 um 464 00:16:08,160 --> 00:16:11,820 that's all you have to do you can 465 00:16:09,480 --> 00:16:15,120 compile your C code right literally 10 466 00:16:11,820 --> 00:16:17,279 lines of python and and execute compiled 467 00:16:15,120 --> 00:16:19,199 C code in in your in your in your wheel 468 00:16:17,279 --> 00:16:21,360 the only extra step you have to do is 469 00:16:19,199 --> 00:16:24,480 add that wyzen file to your wheel which 470 00:16:21,360 --> 00:16:26,600 is one line in your automobile file 471 00:16:24,480 --> 00:16:26,600 um 472 00:16:27,120 --> 00:16:31,560 I have a quick demo here which is that 473 00:16:29,519 --> 00:16:33,180 in theory I could have written 474 00:16:31,560 --> 00:16:34,620 um I could have written this from 475 00:16:33,180 --> 00:16:35,880 scratch what I'm trying to highlight 476 00:16:34,620 --> 00:16:37,560 here is that it's not that I had to 477 00:16:35,880 --> 00:16:39,420 write it in C lots of languages can 478 00:16:37,560 --> 00:16:41,160 generate wasm 479 00:16:39,420 --> 00:16:42,660 um and I could I could write you could 480 00:16:41,160 --> 00:16:44,699 even write it by hand and some sort of 481 00:16:42,660 --> 00:16:45,300 very optimized whatever 482 00:16:44,699 --> 00:16:46,860 um 483 00:16:45,300 --> 00:16:49,320 and 484 00:16:46,860 --> 00:16:51,000 if I compile this to Dot gcd from 485 00:16:49,320 --> 00:16:53,480 scratch.wasm I could run it with with 486 00:16:51,000 --> 00:16:55,560 same the same tool 487 00:16:53,480 --> 00:16:57,360 but this is not a very interesting 488 00:16:55,560 --> 00:16:58,740 example because I took two integers in 489 00:16:57,360 --> 00:17:00,180 return to integer I'm going to be 490 00:16:58,740 --> 00:17:02,399 working with more complicated types like 491 00:17:00,180 --> 00:17:04,740 in Empire cross I have to take a python 492 00:17:02,399 --> 00:17:06,600 source code file in and return compiled 493 00:17:04,740 --> 00:17:08,400 bytecode out 494 00:17:06,600 --> 00:17:10,620 but very quickly I'll just show you so 495 00:17:08,400 --> 00:17:12,780 this is pi wyzen 3. and then why some 496 00:17:10,620 --> 00:17:14,880 time is a very very similar kind of set 497 00:17:12,780 --> 00:17:16,679 of steps I'm building something that's 498 00:17:14,880 --> 00:17:18,480 like an environment in this case it's an 499 00:17:16,679 --> 00:17:19,880 engine in a store I'm loading a module 500 00:17:18,480 --> 00:17:22,079 same concept 501 00:17:19,880 --> 00:17:24,419 and then I'm 502 00:17:22,079 --> 00:17:27,500 asking for things that are exports and 503 00:17:24,419 --> 00:17:27,500 call in the gcd function 504 00:17:28,620 --> 00:17:31,980 so the next example I'm going to give is 505 00:17:30,540 --> 00:17:33,600 a function that that does something more 506 00:17:31,980 --> 00:17:36,059 interesting with calling external 507 00:17:33,600 --> 00:17:37,980 functions and dealing with memory 508 00:17:36,059 --> 00:17:39,840 so this is a function I'm going to 509 00:17:37,980 --> 00:17:41,520 export called calculate bytes and I'm 510 00:17:39,840 --> 00:17:43,559 going to give it a number of bytes and 511 00:17:41,520 --> 00:17:46,620 it's going to call a function that I'm 512 00:17:43,559 --> 00:17:48,299 going to provide with some chunk of data 513 00:17:46,620 --> 00:17:50,340 that that's calculated based on those 514 00:17:48,299 --> 00:17:52,679 inputs in this case it's going to write 515 00:17:50,340 --> 00:17:55,320 the numbers 0 through n into my byte 516 00:17:52,679 --> 00:17:56,340 array and an invoker function when the 517 00:17:55,320 --> 00:17:58,919 data is ready so this is sort of 518 00:17:56,340 --> 00:18:00,059 building up to what Empire cross does 519 00:17:58,919 --> 00:18:03,960 um 520 00:18:00,059 --> 00:18:06,539 as before this is my uh exported 521 00:18:03,960 --> 00:18:09,780 function that I can call from python 522 00:18:06,539 --> 00:18:11,760 um this is saying I expect python to 523 00:18:09,780 --> 00:18:13,620 provide this function to me I'm going to 524 00:18:11,760 --> 00:18:14,880 call this function when I'm ready 525 00:18:13,620 --> 00:18:16,440 and 526 00:18:14,880 --> 00:18:19,320 I said I only take everything works in 527 00:18:16,440 --> 00:18:22,140 ins it's an it's a un8 pointer and a 528 00:18:19,320 --> 00:18:24,059 size T these are both just integers so 529 00:18:22,140 --> 00:18:25,260 um it it 530 00:18:24,059 --> 00:18:27,419 um fits into this model of everything 531 00:18:25,260 --> 00:18:29,160 it's just integers 532 00:18:27,419 --> 00:18:31,440 um now what I have to do though is tell 533 00:18:29,160 --> 00:18:34,799 the inscript and compiler and in 534 00:18:31,440 --> 00:18:36,960 addition this JS Library flag 535 00:18:34,799 --> 00:18:38,160 and even though I'm doing nothing to do 536 00:18:36,960 --> 00:18:39,840 with JavaScript and nothing to do with 537 00:18:38,160 --> 00:18:41,640 the browser inscription is configured 538 00:18:39,840 --> 00:18:43,380 with a JavaScript library file that says 539 00:18:41,640 --> 00:18:46,620 this is the function that I'm going to 540 00:18:43,380 --> 00:18:48,780 be providing from outside from outside 541 00:18:46,620 --> 00:18:50,580 wasm 542 00:18:48,780 --> 00:18:54,000 and then 543 00:18:50,580 --> 00:18:55,620 exactly as before I create an engine but 544 00:18:54,000 --> 00:18:57,240 now I'm defining a Linker and so the 545 00:18:55,620 --> 00:18:59,580 Linker is what lets me link my python 546 00:18:57,240 --> 00:19:00,720 functions into my wise and functions and 547 00:18:59,580 --> 00:19:02,880 I'm saying that there's this function 548 00:19:00,720 --> 00:19:04,799 called bytes ready that you expect me to 549 00:19:02,880 --> 00:19:06,360 provide 550 00:19:04,799 --> 00:19:08,280 um it takes 551 00:19:06,360 --> 00:19:10,860 sorry yeah the function takes two 552 00:19:08,280 --> 00:19:12,840 integers and returns nothing 553 00:19:10,860 --> 00:19:15,840 and I'm going to 554 00:19:12,840 --> 00:19:17,700 um Define that function on the Linker 555 00:19:15,840 --> 00:19:19,100 that when I instantiate my module the 556 00:19:17,700 --> 00:19:21,419 dot wasm file 557 00:19:19,100 --> 00:19:23,340 it will it will now know how to call 558 00:19:21,419 --> 00:19:26,120 that and so when I call calculate bytes 559 00:19:23,340 --> 00:19:26,120 with 20 560 00:19:28,860 --> 00:19:30,980 um 561 00:19:35,820 --> 00:19:41,280 what we're printing when the function 562 00:19:37,679 --> 00:19:42,660 gets called is the memory I'll come back 563 00:19:41,280 --> 00:19:44,100 to what this means but we're putting the 564 00:19:42,660 --> 00:19:45,000 other hex representation of my data so 565 00:19:44,100 --> 00:19:47,820 just to confirm that we're getting what 566 00:19:45,000 --> 00:19:51,360 we want it's the bytes 0 through 20 in a 567 00:19:47,820 --> 00:19:52,500 20 byte in a 20 byte um 568 00:19:51,360 --> 00:19:54,780 um 569 00:19:52,500 --> 00:19:57,000 chunk of memory and the way it works is 570 00:19:54,780 --> 00:19:59,100 that my my buffer was in it was a una 571 00:19:57,000 --> 00:20:01,980 pointer but a pointer is an address in 572 00:19:59,100 --> 00:20:05,660 memory and so I can index memory 573 00:20:01,980 --> 00:20:08,880 by doing mem.read so mem came from my 574 00:20:05,660 --> 00:20:11,820 things exported from the wasm runtime 575 00:20:08,880 --> 00:20:13,919 and I read from buff to buff plus buff 576 00:20:11,820 --> 00:20:14,880 line so the start pointer to the end 577 00:20:13,919 --> 00:20:16,679 pointer 578 00:20:14,880 --> 00:20:18,900 and this gives me back a thing that 579 00:20:16,679 --> 00:20:20,580 looks like a bytes object in Python and 580 00:20:18,900 --> 00:20:22,760 I'm printing the hex representation of 581 00:20:20,580 --> 00:20:22,760 it 582 00:20:23,039 --> 00:20:25,740 um and so finally I'm going to run 583 00:20:23,940 --> 00:20:27,660 through this very quickly which is that 584 00:20:25,740 --> 00:20:30,539 um another quite neat thing you can do 585 00:20:27,660 --> 00:20:32,460 is you can use wasm as a way to run a 586 00:20:30,539 --> 00:20:34,980 self-contained piece of code that I can 587 00:20:32,460 --> 00:20:38,280 completely throw away and and run again 588 00:20:34,980 --> 00:20:39,480 later with with a brand new state so a 589 00:20:38,280 --> 00:20:40,740 lot of time when you when you work with 590 00:20:39,480 --> 00:20:42,780 native code like you're linking it into 591 00:20:40,740 --> 00:20:46,260 your process and it's 592 00:20:42,780 --> 00:20:48,059 um and it's it's permanent in my process 593 00:20:46,260 --> 00:20:49,860 whereas I can use wasm as a way to 594 00:20:48,059 --> 00:20:51,059 temporarily run a Sandbox piece of code 595 00:20:49,860 --> 00:20:52,620 and then run the same piece of code 596 00:20:51,059 --> 00:20:53,880 again so this is a function that has 597 00:20:52,620 --> 00:20:55,200 some Global this is a piece of code that 598 00:20:53,880 --> 00:20:58,140 has some Global state 599 00:20:55,200 --> 00:21:00,179 but when I load it 600 00:20:58,140 --> 00:21:02,220 um three different times I'm going to 601 00:21:00,179 --> 00:21:04,020 instantiate this module that I've loaded 602 00:21:02,220 --> 00:21:07,080 and run it with a completely fresh State 603 00:21:04,020 --> 00:21:08,400 each time so imagine I could write a 604 00:21:07,080 --> 00:21:09,660 plug-in or whatever and then the plugin 605 00:21:08,400 --> 00:21:11,460 can do whatever it likes with global 606 00:21:09,660 --> 00:21:12,900 variables and Global State and just 607 00:21:11,460 --> 00:21:15,440 instantiate it and run it as many times 608 00:21:12,900 --> 00:21:15,440 as I like 609 00:21:15,780 --> 00:21:21,059 um and 610 00:21:18,299 --> 00:21:22,980 uh 611 00:21:21,059 --> 00:21:25,380 yeah the libraries are subtly different 612 00:21:22,980 --> 00:21:27,059 so then in in wazen 3 you access memory 613 00:21:25,380 --> 00:21:28,559 just like a memory view the result you 614 00:21:27,059 --> 00:21:30,299 get back from this is in Factor memory 615 00:21:28,559 --> 00:21:32,700 view instance and so 616 00:21:30,299 --> 00:21:34,320 um and this one uses a sort of a strange 617 00:21:32,700 --> 00:21:36,539 syntax where you have to tell it the um 618 00:21:34,320 --> 00:21:37,980 you have to tell it the uh the signature 619 00:21:36,539 --> 00:21:40,440 of the function 620 00:21:37,980 --> 00:21:42,240 um wasm wasma the other Library uses 621 00:21:40,440 --> 00:21:44,159 python type annotations so you annotate 622 00:21:42,240 --> 00:21:45,299 your functions with with tie pints and 623 00:21:44,159 --> 00:21:46,559 it uses that to figure out what the 624 00:21:45,299 --> 00:21:48,840 interop is between the different 625 00:21:46,559 --> 00:21:51,179 runtimes 626 00:21:48,840 --> 00:21:53,100 uh and then finally 627 00:21:51,179 --> 00:21:55,919 as a very quick sort of explanation of 628 00:21:53,100 --> 00:21:59,400 how we implemented this in Empire cross 629 00:21:55,919 --> 00:22:01,320 so Empire cross is a c program it has a 630 00:21:59,400 --> 00:22:02,820 make file so we would just write a 631 00:22:01,320 --> 00:22:04,799 second make file that is identical to 632 00:22:02,820 --> 00:22:08,400 the first make file except for we say 633 00:22:04,799 --> 00:22:10,020 that our C compiler is EMCC instead 634 00:22:08,400 --> 00:22:12,120 um we had a couple more things which is 635 00:22:10,020 --> 00:22:15,900 that we had to add that JS Library flag 636 00:22:12,120 --> 00:22:18,900 to say what imports and exports are 637 00:22:15,900 --> 00:22:18,900 and 638 00:22:19,220 --> 00:22:24,240 uh there's a no there's no entry flag as 639 00:22:22,919 --> 00:22:25,799 well somewhere here yeah no entry as 640 00:22:24,240 --> 00:22:26,700 well 641 00:22:25,799 --> 00:22:28,200 um 642 00:22:26,700 --> 00:22:30,720 that's literally all I had to do I had a 643 00:22:28,200 --> 00:22:32,400 c program that was written that that was 644 00:22:30,720 --> 00:22:33,960 written C I copied it to make file and I 645 00:22:32,400 --> 00:22:35,460 added a couple of flags and changed what 646 00:22:33,960 --> 00:22:38,580 the compiler is 647 00:22:35,460 --> 00:22:40,620 and now when I compile it I get 648 00:22:38,580 --> 00:22:43,620 um Empire cross dot wasm instead of 649 00:22:40,620 --> 00:22:46,559 Empire cross.exe or or whatever 650 00:22:43,620 --> 00:22:49,140 and then where we used to have 651 00:22:46,559 --> 00:22:50,520 um this this script this this is this is 652 00:22:49,140 --> 00:22:54,600 our python package that we published it 653 00:22:50,520 --> 00:22:55,919 has a main that calls main main works 654 00:22:54,600 --> 00:22:58,080 like you'd expect for any other Python 655 00:22:55,919 --> 00:23:01,260 program and parses its inputs and then 656 00:22:58,080 --> 00:23:03,840 used sub process 657 00:23:01,260 --> 00:23:06,980 our early sub process I know compiler 658 00:23:03,840 --> 00:23:06,980 native sorry uh 659 00:23:08,960 --> 00:23:12,299 subprices.check output to run a native 660 00:23:11,340 --> 00:23:13,559 binary 661 00:23:12,299 --> 00:23:15,539 we've now implemented three different 662 00:23:13,559 --> 00:23:17,520 backends the idea being that for any 663 00:23:15,539 --> 00:23:18,840 Target that we support one of those 664 00:23:17,520 --> 00:23:21,179 three ways and runtimes will be 665 00:23:18,840 --> 00:23:22,740 available for you 666 00:23:21,179 --> 00:23:24,659 um which sounds terrible but each one of 667 00:23:22,740 --> 00:23:26,700 these literally took half an hour to 668 00:23:24,659 --> 00:23:27,960 write it's it's exactly the demo code I 669 00:23:26,700 --> 00:23:29,400 just showed you 670 00:23:27,960 --> 00:23:31,919 um with slightly more functions it has 671 00:23:29,400 --> 00:23:34,679 to call and Export and import but you'll 672 00:23:31,919 --> 00:23:37,020 see the exact same stuff around creating 673 00:23:34,679 --> 00:23:38,580 a store and creating a module and so 674 00:23:37,020 --> 00:23:40,559 forth 675 00:23:38,580 --> 00:23:44,640 um 676 00:23:40,559 --> 00:23:46,919 uh and then in our toml file 677 00:23:44,640 --> 00:23:49,400 we have this one extra step 678 00:23:46,919 --> 00:23:52,320 which is that we copy the dot wasm file 679 00:23:49,400 --> 00:23:54,480 into the into the output directory that 680 00:23:52,320 --> 00:23:55,799 sits alongside the dot py files so what 681 00:23:54,480 --> 00:23:58,919 the code does 682 00:23:55,799 --> 00:24:02,100 is it looks in compile it at pi 683 00:23:58,919 --> 00:24:03,659 it can look in um 684 00:24:02,100 --> 00:24:05,700 in 685 00:24:03,659 --> 00:24:06,539 the same directory as so you can kind of 686 00:24:05,700 --> 00:24:08,760 see what's going through the absolute 687 00:24:06,539 --> 00:24:12,679 path of file and so it looks adjacent to 688 00:24:08,760 --> 00:24:12,679 my DOT Pi files to find it 689 00:24:21,179 --> 00:24:25,500 so is this a good idea 690 00:24:24,840 --> 00:24:27,299 um 691 00:24:25,500 --> 00:24:28,500 we have to take a fairly pragmatic 692 00:24:27,299 --> 00:24:30,539 approach on micro python like I said 693 00:24:28,500 --> 00:24:32,520 earlier we can't with a small project we 694 00:24:30,539 --> 00:24:34,620 can't spend time maintaining build 695 00:24:32,520 --> 00:24:36,360 systems and things for for things a long 696 00:24:34,620 --> 00:24:37,919 way away from the the type of things 697 00:24:36,360 --> 00:24:39,780 that we work on 698 00:24:37,919 --> 00:24:42,179 um 699 00:24:39,780 --> 00:24:44,039 the performance is excellent we we you 700 00:24:42,179 --> 00:24:45,120 cannot as a user you do not notice that 701 00:24:44,039 --> 00:24:46,260 this is any different to the regular 702 00:24:45,120 --> 00:24:48,179 tool you'd use even when you're 703 00:24:46,260 --> 00:24:49,820 compiling a large number of files or big 704 00:24:48,179 --> 00:24:51,960 files or whatever 705 00:24:49,820 --> 00:24:53,520 filaments will only get better as was 706 00:24:51,960 --> 00:24:55,200 evolves to support more instruction 707 00:24:53,520 --> 00:24:56,900 types and it learns more about the 708 00:24:55,200 --> 00:24:59,460 original code 709 00:24:56,900 --> 00:25:00,840 my one little hesitation here is that by 710 00:24:59,460 --> 00:25:02,580 doing this ourselves the old-fashioned 711 00:25:00,840 --> 00:25:03,840 way we could have supported more targets 712 00:25:02,580 --> 00:25:06,059 and more architectures because we could 713 00:25:03,840 --> 00:25:07,740 just enumerate all 24 possible abilities 714 00:25:06,059 --> 00:25:10,440 that we needed or whatever we're now 715 00:25:07,740 --> 00:25:13,140 limited to about seven but I think those 716 00:25:10,440 --> 00:25:14,400 seven are the most common ones and for 717 00:25:13,140 --> 00:25:17,700 users that have the option to install 718 00:25:14,400 --> 00:25:20,400 GCC and the python Dev headers the 719 00:25:17,700 --> 00:25:21,780 piwasm 3 runtime will work 720 00:25:20,400 --> 00:25:22,919 there's a big to do here which I would 721 00:25:21,780 --> 00:25:24,000 have loved to have presented about but I 722 00:25:22,919 --> 00:25:25,380 haven't quite figured out the details 723 00:25:24,000 --> 00:25:27,000 yet is figuring out how to write a 724 00:25:25,380 --> 00:25:29,520 requirements.text that figures out 725 00:25:27,000 --> 00:25:30,900 exactly which run time to install but I 726 00:25:29,520 --> 00:25:32,520 think this can be solved I've had a look 727 00:25:30,900 --> 00:25:35,279 at it at a few things and and that will 728 00:25:32,520 --> 00:25:37,799 be a so an interesting code to this 729 00:25:35,279 --> 00:25:39,900 um we haven't shipped this yet 730 00:25:37,799 --> 00:25:40,980 um we're going to find out and um and I 731 00:25:39,900 --> 00:25:43,260 guess 732 00:25:40,980 --> 00:25:45,779 hit me up on Mastodon or something or um 733 00:25:43,260 --> 00:25:47,159 uh or getting cut touch and find out how 734 00:25:45,779 --> 00:25:49,020 it goes for us 735 00:25:47,159 --> 00:25:50,039 but the conclusion is it's it's so much 736 00:25:49,020 --> 00:25:51,240 better than what we have at the moment 737 00:25:50,039 --> 00:25:52,740 which is what we're telling people is 738 00:25:51,240 --> 00:25:54,000 download this get repository and run 739 00:25:52,740 --> 00:25:54,900 this make file and people look at us 740 00:25:54,000 --> 00:25:56,340 like 741 00:25:54,900 --> 00:25:57,900 did you just tell me to write a map 742 00:25:56,340 --> 00:25:59,640 reduce in erlang like what are you 743 00:25:57,900 --> 00:26:00,299 talking about and 744 00:25:59,640 --> 00:26:02,580 um 745 00:26:00,299 --> 00:26:06,659 and it's very very simple it's it's one 746 00:26:02,580 --> 00:26:09,419 python dependency and uh it's quite easy 747 00:26:06,659 --> 00:26:12,179 to introspect the tooling is good um 748 00:26:09,419 --> 00:26:13,919 yeah so that's it 749 00:26:12,179 --> 00:26:15,420 um I'd love to answer questions Katie 750 00:26:13,919 --> 00:26:19,380 will come up and help join 751 00:26:15,420 --> 00:26:21,120 [Applause] 752 00:26:19,380 --> 00:26:23,159 thanks very much Tim 753 00:26:21,120 --> 00:26:26,159 I'll invite Katie up and we'll share the 754 00:26:23,159 --> 00:26:28,380 mic or she can have the micromote 755 00:26:26,159 --> 00:26:30,860 um do we have questions hands up yep 756 00:26:28,380 --> 00:26:30,860 just at the bank 757 00:26:31,679 --> 00:26:34,679 you actually missed some methods that 758 00:26:33,360 --> 00:26:36,000 you are not providing and where they're 759 00:26:34,679 --> 00:26:38,039 coming from where's Malik and free 760 00:26:36,000 --> 00:26:43,620 coming from 761 00:26:38,039 --> 00:26:45,480 uh so malakan free provided because uh 762 00:26:43,620 --> 00:26:48,659 the runtime provides the runtime 763 00:26:45,480 --> 00:26:50,220 provides a way to get memory and Malik 764 00:26:48,659 --> 00:26:52,200 is available to you in your wazen binary 765 00:26:50,220 --> 00:26:54,539 it's actually a very good observation um 766 00:26:52,200 --> 00:26:55,860 in my bytes example 767 00:26:54,539 --> 00:26:58,200 um what happened was I wanted to return 768 00:26:55,860 --> 00:27:00,840 a byte array so I allocated it 769 00:26:58,200 --> 00:27:03,179 um the wazen run time is just this giant 770 00:27:00,840 --> 00:27:05,279 array of of of bytes that it can 771 00:27:03,179 --> 00:27:07,080 allocate and grow as it needs to and it 772 00:27:05,279 --> 00:27:08,820 provides the way the amount the airlock 773 00:27:07,080 --> 00:27:10,500 implementation for you 774 00:27:08,820 --> 00:27:12,240 what's quite useful and what we do in 775 00:27:10,500 --> 00:27:14,700 Empire cross is that we actually just 776 00:27:12,240 --> 00:27:16,320 export malloc directly to the python 777 00:27:14,700 --> 00:27:18,000 level and so when python wants to get 778 00:27:16,320 --> 00:27:20,960 some memory to read and write into it 779 00:27:18,000 --> 00:27:20,960 calls malloc directly 780 00:27:23,460 --> 00:27:27,059 um I was wondering what the debugging 781 00:27:25,080 --> 00:27:29,700 story is like and how you go about 782 00:27:27,059 --> 00:27:32,120 getting errors back from your library to 783 00:27:29,700 --> 00:27:32,120 users 784 00:27:34,380 --> 00:27:40,740 so when you like when you make an error 785 00:27:37,620 --> 00:27:43,559 for example in a function that you're in 786 00:27:40,740 --> 00:27:45,779 the the Wizard module Imports if you 787 00:27:43,559 --> 00:27:47,340 have an exception it gets very very 788 00:27:45,779 --> 00:27:49,020 confused 789 00:27:47,340 --> 00:27:51,120 um because you've now got a stack Trace 790 00:27:49,020 --> 00:27:53,760 that involves python back through the 791 00:27:51,120 --> 00:27:55,620 map wasm runtime through C then back 792 00:27:53,760 --> 00:27:57,179 into the your python code that uh 793 00:27:55,620 --> 00:27:59,179 initiate it 794 00:27:57,179 --> 00:27:59,179 um 795 00:27:59,400 --> 00:28:02,820 it's quite challenging 796 00:28:01,260 --> 00:28:04,500 um and the other thing is when you when 797 00:28:02,820 --> 00:28:07,140 you disassemble the wasm code you you 798 00:28:04,500 --> 00:28:09,960 can't uh that's it what I've been doing 799 00:28:07,140 --> 00:28:11,880 is is debugging the C code using my 800 00:28:09,960 --> 00:28:13,620 normal build 801 00:28:11,880 --> 00:28:14,940 um but I'm not aware of for example a 802 00:28:13,620 --> 00:28:16,559 wasm debugger 803 00:28:14,940 --> 00:28:18,779 um one thing you can do is you can take 804 00:28:16,559 --> 00:28:20,400 your wasm file and you can load it 805 00:28:18,779 --> 00:28:22,200 directly in the browser at the end it is 806 00:28:20,400 --> 00:28:23,760 just wazm you have to and if you provide 807 00:28:22,200 --> 00:28:26,279 the same inputs and exports and I think 808 00:28:23,760 --> 00:28:28,440 there are better tools in the browser 809 00:28:26,279 --> 00:28:31,380 um but yes debugging is is not a well 810 00:28:28,440 --> 00:28:32,400 answered story at this point 811 00:28:31,380 --> 00:28:34,320 um I haven't had much experience 812 00:28:32,400 --> 00:28:36,539 debugging wasm directly because I've 813 00:28:34,320 --> 00:28:39,120 mostly just been running C python 814 00:28:36,539 --> 00:28:41,159 um but yes the browser tools are there 815 00:28:39,120 --> 00:28:42,900 you have the same kind of interaction 816 00:28:41,159 --> 00:28:44,400 between if you're running JavaScript and 817 00:28:42,900 --> 00:28:45,960 you're calling a wasm function you also 818 00:28:44,400 --> 00:28:47,520 need to sort of allocate the memory and 819 00:28:45,960 --> 00:28:49,740 copy the strings across and then send 820 00:28:47,520 --> 00:28:50,880 pointers into webassembly 821 00:28:49,740 --> 00:28:53,760 um it's just for when you're building 822 00:28:50,880 --> 00:28:56,039 for the browser those those functions in 823 00:28:53,760 --> 00:28:57,900 JavaScript are kind of created for you A 824 00:28:56,039 --> 00:28:59,820 lot of the time so if you build rust and 825 00:28:57,900 --> 00:29:02,159 you compile it to webassembly it has 826 00:28:59,820 --> 00:29:03,480 convenient functions for those but yes 827 00:29:02,159 --> 00:29:05,100 there are I think there is some kind of 828 00:29:03,480 --> 00:29:06,840 debugging tool for webassembly directly 829 00:29:05,100 --> 00:29:09,299 but I've not used it so I don't know 830 00:29:06,840 --> 00:29:10,620 yeah I have an anecdotal story of one of 831 00:29:09,299 --> 00:29:12,360 the runtimes the very first one that's 832 00:29:10,620 --> 00:29:14,640 written in pure python it didn't 833 00:29:12,360 --> 00:29:16,679 Implement some part of the wasm spec I 834 00:29:14,640 --> 00:29:18,179 didn't know that and I ran Empire I 835 00:29:16,679 --> 00:29:19,440 wrote for my test programs and around 836 00:29:18,179 --> 00:29:21,419 Empire cross and it crashed with the 837 00:29:19,440 --> 00:29:23,340 legal instruction 838 00:29:21,419 --> 00:29:25,919 um so the answer to that is 839 00:29:23,340 --> 00:29:29,520 I had to debug the way you would debug 840 00:29:25,919 --> 00:29:31,559 python code to yeah 841 00:29:29,520 --> 00:29:32,700 we're out of time I'm afraid okay 842 00:29:31,559 --> 00:29:35,520 um but thank you so much for the 843 00:29:32,700 --> 00:29:37,080 questions thanks KD thanks Jim thank you 844 00:29:35,520 --> 00:29:38,580 um once again and um we're gonna 845 00:29:37,080 --> 00:29:39,299 reconvene again oh I need to give you 846 00:29:38,580 --> 00:29:41,159 the 847 00:29:39,299 --> 00:29:43,320 cool thank you so much ceremonial mug 848 00:29:41,159 --> 00:29:44,390 and thank you card thank you 849 00:29:43,320 --> 00:29:49,279 very good 850 00:29:44,390 --> 00:29:49,279 [Applause]