-
Notifications
You must be signed in to change notification settings - Fork 27
Implementing a Desktop Compiler Optimization
We have a closed ticket to implement the desktop compiler's optimizations in Tortoise. This is a brief overview on the process to follow to implement one of them.
You may wish to start by reading up on how the NetLogo desktop compiler architecture, paying particular attention to the optimization steps.
For reference, a few example optimizations that have been done already and can be used as reference include "Nsums", "Nsums4", and "OtherWith".
The NetLogo desktop optimizations (well, most of them), are defined in the package.scala
file and live in the org.nlogo.compile.middle.optimize
package. The Optimizations.scala
file contains a class that collects those optimizations for application during compilation (after the first pass of parsing). One of the reasons they are collected there is so they can be selectively disabled in order to allow us to test NetLogo headless compiled code against NetLogo Web compiled code where we may not have implemented the optimizations yet.
On the Tortoise side, There is a different Optimizer.scala
file. This file defines the NetLogo Web "middle layer" compilation optimizations - after parsing but before final transformation into Javascript. It provides classes and code to turn common NetLogo command and reporter combinations into more efficient versions. Then in the final compiler pass when these efficient primitives are found, they are replaced with the optimized Javascript code.
We assume we want to implement the "AnyWith1"
optimization in this process, as an example.
- Make sure to understand what you're testing in NetLogo code. A lot of these optimizations take combinations of primitives that can be more efficient when they're processed together.
- The reporter
any? turtles with [ color = red ]
would normally runturtles with [ color = red ]
creating an agent set of red turtles followed by anany?
check on that result, but they can be combined to save some time by reportingtrue
when the first turtlewith
the condition is found.
- The reporter
- Create a simple language test for it in
Tortoise.txt
in Tortoise so you can quickly test it usingnetLogoWeb/testOnly *Commands -- -z Tortoise
using thesbt
console.- This is just a fast, easy-to-run test for implementation purposes, it shouldn't be checked in with any commits.
- Add the optimization in the proper
DockingFixtures.scala
section (Command or Reporter), matched against the NetLogo repository'sOptimizations.scala
, so it'll be used in all other tests, too. - Find the optimized prim version in the NetLogo repository. This will be the logic we'd like to duplicate.
- Example: The
_anywith
class in_anywith.scala
. But make sure to look at the version fromheadless
and notnetlogo-gui
.
- Example: The
- In Tortoise, create the appropriate primitive class and transformation object in
Optimizer.scala
.- You'll also need to add it to the
apply()
procedure to get it inserting itself into the AST. - For implementing
_anywith
you can check out_oneofwith
, which is a similar optimization.
- You'll also need to add it to the
- In Tortoise, add the matching prim in
Prims.scala
.- This is where the compiled primitive from the AST is translated into the CoffeeScript code that will actually be run by the engine.
- After adding the prim, you should re-run your quick
Tortoise.txt
test and confirm it fails - the optimization is seen, but you haven't implemented the functionality yet so it breaks. If the test passes, something may not be right.
- In Tortoise, add the optimized code in the appropriate place in the engine, depending on the prim and optimization.
- For
_anywith
, this applies to agent sets, so we'd look to an agent set class to implement it.
- For
- Run tests, work on it until it passes.
- Run a broader set of tests (
netLogoWeb/test:fast
andnetLogoWeb/testOnly *Reporters
are good ones), make sure they all still pass. - Publish the Tortoise artifacts locally and use them in Galapagos to test a model using the now optimized primitives. You should be able to use a web developer console to actually step through your optimized code.
All desktop compiler optimizations are implemented as of September 2020. see the Optimizations.scala
file for the full list and to check if maybe we're missing some new ones (hopefully a docking test or model test would fail if so).