You
Hello.
Hello everyone.
I work as a scientific software engineer at Constack.
At Constack, we developed and maintained some major open source projects like
Project Jupiter, Condor Foge, Mamba, Micromamba, and even some parts of LLVM.
So today I shall be speaking on the topic interactive CNC++ workflows in Jupiter using Clang Rappin.
I would say there are a lot of use cases to this, but as I only have about 20 odd minutes,
I shall be focusing on the fundamental building blocks here, and the use cases just build on top of those.
So even before diving deeper, I would like to focus on a part of the topic here, which is what do I mean by interactive workflows in CNC++.
Here I am referring to the ability of executing code interactively, one single-spirited time,
without needing a full-fledged compilation step-assage.
And this is where the concept of Rappin or Rheed evaluate print loop comes in.
So Rappins form the backbone of interactive programming.
You just input a line of code, you have it evaluated immediately, and you see some results on the screen.
So I would say such a feedback loop is incredibly valuable for experience and debugging purposes.
And as we might know, languages like Python are Julia and even JavaScript offer mature Rapples.
These Rapples power notebooks and interactive shelves, and these interactive environments is where the Jupiter stack would shine as competitive or traditional ideas.
The Jupiter project was designed, keeping exploratory computing in mind, and was built from the ground up to be language ignored,
to power multiple programming languages seamlessly.
But what about C++, a language known for its performance and complexity?
And it's traditionally compiled.
We all might agree that C++ lacks mature Rapples like experience for us developers.
And this brings me to my first key motivation as to why does C++ even need a Rapple?
I would say as scientists and engineers, we don't just write software, we explore our workflows involved,
testing out small pieces of code, analyzing results, maybe tweaking some parameters, and running the whole thing again.
So this process in itself is interactive and a faster feedback loop would be really helpful here.
This is where things got interesting.
Over at Sun, where C++ was central to data analytics, in particle physics, they came up with a C++ interpreter built on top of Clang and LLVM.
And as I spoke about the Jupiter stack, which is based on the concept of Rapple, in 2017 Zeus Clink, Jupiter Coral was announced,
developed by people at Constax, Silver Coral, and Johan Mobile, it integrated Clink into the Jupiter ecosystem.
So that it could leverage Jupiter's rich features like interactive widgets and the rich display system.
So the blog, speaking on the release for Zeus Clink, was a really successful one.
We got about half a million views there, highlighting the demand for interactive C++ back in 2017 itself.
But now you all might think as to what Zeus stands for.
So yeah, this is what the kernel looks like.
And yeah, so Zeus is nothing but a framework that facilitates implementing the kernel for project Jupiter.
It takes the burden of implementing the Jupiter kernel protocol.
So as developers, we just need to focus on implementing the interpreter side of things.
And when I said project Jupiter was meant to be language agnostic, this is what I'm talking about.
So you can probably find the Zeus kernel for any language you're interested in and run that as a ripple.
And if you see the architecture for Zeus, the kernel protocol remains the same.
It's us who have to write a custom interpreter and probably connected back to Zeus to have a Zeus kernel with us.
So thinking about it, we had Clink, we had Zeus Clink back in 2017 itself.
So we technically had a solution to our problem statement.
But that's not what happened.
So Clink packaging Clink turned out to be really challenging as it was maintaining lot of patches over Clang and LLVM.
And the release cycles were not as frequent as the LLVM stack.
So it was causing difficulties rolling software distributions on Conduphoge.
So pitched on an effort by Clink co-creator Vasile Vasilev, the Clang Reppel project was born.
The Clang Reppel project was born with the idea of building the core of interactive C++ in Clang itself.
So the Clang Reppel has been undergoing major developments in the past few years now.
And now that you all have Zeus, which is the base framework for implementing a Jupiter kernel.
And you have Clang Reppel, which is your C++ interpreter.
You can just club them together to have Zeus CPP, a native kernel that is expected to work on your native platforms.
Now even before I dive into a demo, I'll just quickly educate you all on Clang Reppel's design here.
So most of the interpreters code lies in Clang, the Clang interpreter folder, the interpreter is managing two major components,
which is the incremental parser and the incremental executor.
The incremental parser is sort of the front end for the interpreter and is making use of the underlying incremental facilities provided by Clang.
The incremental parser technically manages something called as a PTO or a partial translation unit.
So we need to understand that Clang Reppel thinks in terms of incremental compilation, where the incoming input is incomplete in standard C++ sense,
but also complete within itself in a represents.
So Clang Reppel maintains a single ST, but this should be looked as a never ending ever growing ST.
So every input adds a PTO to that ST and that PTO is then lowered to the LLVMIR.
And this is where your incremental executor comes in.
The incremental executor is based on top of LLVM's object, and this did lowers the LLVMIR to machine code, which is then executed.
I would also quickly speak on an example kernel spec.
So when I say I'm building zoo CPP, I'm technically going from a kernel spec to a kernel.
A kernel spec just highlights some features of the kernel, like a display name, some environment variables for managing paths, some arguments that would reach Clang eventually and some other utilities.
So let me quickly show you all a demo.
Yeah, this is our build zoo CPP, and it's hosted here.
So we start with some basic C++, you have output and error streams, some exception handling.
You can do functions, classes, some polymorphism templates.
And then you have something called as inline documentation.
You can use the question mark, magic command, to perform a lookup, and fetch some documentation from the standard reference.
And just play around with it.
Yeah, some like this.
You have Jupiter's rich display system here.
So integrating C++ as a part of the Jupiter ecosystem helps us leverage Jupiter's rich mind type rendering.
So zoo CPP can't just do plain text.
You can do images, audio, HTML tables, later can even custom visualizations.
Let me quickly draw a merry queue image for you all.
So this works through the XCPP display function that sends a mind type bundle to the front end.
Let me play a drum snippet for you all.
Oh, sorry, it doesn't play.
Yeah, you can do some rectangular displays.
We update those displays.
You have some thread-based examples.
You can take some user inputs.
Yeah?
So going back to the slides.
Now that you have no what zoo CPP is, which is your native kernel.
You have, I should be speaking on zoo CPP light, which is the wasom kernel we offer.
So zoo CPP light is nothing but zoo CPP plus Jupiter light.
And the idea here is we are trying to interpret C++ completely in the browser, no set of whatsoever.
So Jupiter light is nothing but the Jupiter lab distribution that runs entirely in your browser.
It is being powered by web assembly.
And it expects us to have web assembly builds for our kernel and any desired package we would like to run.
These pins should be hosted somewhere and this is where mscriptin force comes in.
So mscriptin force is nothing but mscriptin plus conda force.
It is built for building and packaging libraries for the mscriptin wasn't 30 target.
It is a get a repo and with a growing set of recipes and we all can host our recipes there.
So my next question for you all would be what would it take to come up with zoo CPP light.
We always need to compile the entire stack and we plan zoo and zoo CPP for web assembly.
And we need to host it on mscriptin force so that it can be pulled into a working jupit light environment.
But sadly that alone isn't enough think about it.
We are not just trying to run some precompiled static C++ in the browser.
We are trying to build a live interpreter a repel in the browser itself and that has its own set of changes.
So plan a repel on native platforms is making use of LLGM's object.
Now how this works is the jit would compile your code into machine instructions.
Place that into memory jump to that memory address and executed for your classic just in time compilation.
But in the browser where the assembly follows the strict sandbox model which means we just can't write executable instructions into memory at runtime.
Which basically means there's no jit in wasom.
Which means even if we had plan a repel built for the assembly and hosted on mscriptin force.
We couldn't put it to use for dynamically compiling and executing incoming cells in zoo CPP light.
To tackle this we had to introduce a wasom back and for plan a repel.
This was done during LLGM 17's development cycle.
Side shopping the standard incremental executor based on top of LLGM's object.
We introduced a wasom incremental executor for wasom specific executions.
I'll pick me educate you all on how this works.
So let's say you have some code and selects that is passed into a PTO which is then wrote to some IR.
That IR is then compiled to some to a wasom object file.
And this object file is then fed to wasomally which is an appropriate flag to generate a standalone wasom module.
And this standalone wasom module acts as a dynamically linked side module.
Which is meant to be loaded on top of a persistent main module.
The persistent main module is nothing but yocernals wasom build.
It can be zoo CPP dot wasom.
And we are using emciptants, deer loop and mechanism here.
So you all might think as to how are these modules communicating with each other.
So there's shared memory between the side modules and the main wasom module.
And also there's symbol resolution going on at runtime which means cell X can access all the information from cell 1 to cell X.
So this was some proof of concept for interpreting C++ in the browser.
And yeah, it's all demos from here on.
So being a static link, you can just click on it, open up a kernel and do all the C++ you want.
I have some demos loaded.
Let me quickly open it up for you.
So firstly to establish zoo CPP light as a working wasom kernel.
We at least had to achieve whatever our native kernel was doing.
And that's exactly what we did.
So yeah, the same demo again.
Fetching the documentation, the Maricure image and all of it.
Yeah, next we move on to some advanced graphics.
So leveraging Jupiter's risk display system.
We could club zoo CPP light with the framework like SDL.
So you can just build zoo CPP light with the hyphen S, SGL flag.
To showcase this I've quoted Kevin Bson's small pt example.
This is global illumination in 90 and 90 and so C++ code.
I think the loop dictates as to how clear the image would be.
So if you run it for 10 hours, you get a clear image like this.
I just run it for 30 or 30 seconds.
You'll see some logs here.
So how this works is SDL renders the scene on to an in-memory canvas.
And that is being captured and displayed by the XCPP display function on the screen.
So the image is not clear enough, but let's move on.
When we're like SDL, it's a wasom version of SDL that is being run in the browser.
Yeah?
Yeah.
Also in wasom?
Yeah.
And this wasom is of course being kicked by five or five.
And that's what's happening now.
I'll get to.
Just be sure.
So next we don't have to use SDL if we don't want to.
I just tried porting the tiny ray trace example by Professor Dimitri Sokolov.
So it is a very famous ray tracing project that is taught at universities as coursework.
So yeah, the professor teaches you how to have a canvas, make a spear,
and it's 11 week course, I think.
And you finally end up on this image.
Yeah.
I just ported it here and let me quickly draw it for y'all.
This is all you need for the image.
One second.
Yep.
It's here.
Finally.
Next we move on to some symbolic and numeric computation.
You might have heard of Simpy, which is symbolic python and numpy, which is numeric python.
Now I would it would be great to just have this C++ counterparts in zoo CPP light.
And that's exactly what I did.
I shared with Sim Engine, which is a far C++ symbolic mat library.
You have all your mat there from linear algebra to calculus and all of it.
And it depends on boost.
So you start with some boost product here.
Yeah, and then you have a Sim Engine expression.
You're expanding that expression.
Next we have some area based computation.
So you all might know that projupiter is really famous among researchers and scientists for area based computing.
Once it's library that helps us do so is extensor, which is a C++ multi dimensional area with numpy like syntax.
Enabling numerical computation, area broadcasting lazy evaluation and element wise operations.
You can extensor to have extensor blasts, which uses the numpy x syntax from extensor and the efficiency of open blasts.
Extensor blasts should allow you to have numpy style convenient access to blasts and napa proteins.
So obviously to run extensor blasts, you have open blasts loaded.
Here's a LED composition algorithm for you all.
This is your factor as matrix. We can fetch some documentation for extensor.
Yeah, and yeah, these are some area based operations where you can view an array.
You can reshape it.
You're as some matrix based operations like matrix inversions and eigenvalue competitions.
Next we have interactive widgets.
Besides, Jupiter's inline documentation feature and the rich display feature.
Jupiter also provides you with interactive components for your notebook.
This is where library like ex widgets comes in.
So ex widgets is the C++ implementation of the Jupiter widget protocol.
Let me quickly draw a slider and a canvas for you all.
And you can play around with it, yeah.
You have some off-thing canvas functionalities with that respects mouse events.
And next comes probably my favorite feature of all of this, which is the magic commands.
So the magic commands are special commands assisting code execution for the user.
You have the file magic that should, yeah, you should be able to create the right append and read from a file.
One second, so you have this and you can read from it.
And next we have the mamma install magic, which is my personal favorite.
So let's say you want to learn about any C++ package there is.
We have we host about 400 packages on the script and coach.
So let's say you want to educate yourself about doc test.
You just do a mamma install for it.
You fetch it at runtime.
And yeah, you just try it a simple use case that fails.
Yep. So all the demos here can be festered runtime.
You don't really need to have it in your environment before you start.
And finally, yeah, finally we get to the time it magic.
You can sort of benchmark and compute the execution time for all of this.
So you can possibly compare your native kernel versus the performance on your wasom kernel here.
And this brings me to some near future work.
I say near future because all of this should probably be available by LLVM22 or probably the last few days of LLVM21.
You have something called as the last value printing, which is something that cling and zoos cling already had.
So as you can see, you can emit the semicolon here and like have your results at being executed in a python shell like syntax.
Like this. Next, we have debugger support for zoo CPP.
So this is something I'm entered during geosock Google some of code 25.
And we were able to debug jittered code produced by the repel through LLVM and LLVM.
We run clan repel out of process for this.
And yeah, we leverage the Jupyter debugger protocol for this.
Let me quickly show you all the demo.
So yeah, you can define some cells here.
You can switch on the debugger.
You should have the debug panel. You can set some breakpoints, hit those breakpoints.
You should be able to see the sources, maybe inspect some variables.
And I'll do all the step-in step-out continue functions.
Next, we have cool ass support.
So you should be, I think my PR is fixing this landed a couple months back.
So we should have this in LLVM 22.
So yeah, let me quickly show all the demo.
You should be able to define a cool kernel.
Yeah, allocate some data, launch the kernel and have some results.
Something this.
LLVM. Yeah, LLVM.
We have some Python entropy here.
This effort is towards bringing all the kernel together.
Something like that.
So you can define a C++ function and call it with a Python-like syntax.
Something like this.
And yep, I'm on to the acknowledgments slide now.
Some of the work here was funded by the compiler research group at Sun.
The initial work is what I'm talking about.
And yeah, we love Google, some of course ruins.
And we've entered them for all of this.
Yeah, that's the end.
Thank you.
What's the name of those time for questions?
But you can probably find them.
Sorry.
Somewhere around.
Because we have to move on to the next speaker.
You filled your slot perfectly.
All the demos.
Yep.
Thank you.