The pibake script

From Compilers
Revision as of 12:54, 14 October 2021 by Mike (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Note: the server farm has been disabled until Mike gives the Compilers course again. The commands make test0 and make test1 continue to work, but make test2 does not work any longer.

Like all our other compilers, the one in Lab 4 is an OCaml program that inputs a text – the source code of a program in picoPascal – and outputs a text, this time, the same program translated into ARM assembly language. Consequently, the compiler itself can run on any machine, including the x86-based machines in the lab, or an ordinary laptop. What's not possible without installing special software is to assemble and link the compiler output, or to run the resulting object code.

Typing make in the lab4 directory will build the compiler as usual, but the command make test that's typically used to run regression tests has been replaced by three commands: make test0 will compile the whole test suite, but only compare the object code with the previous version stored in the test files, and not try to run it. The command make test1 compiles the test cases, then assembles them using a cross-assembler and runs them on an emulator called qemu-arm. The third option, test2, runs the code on a real ARM chip: I've set up an immense server farm of Raspberry Pi's somewhere on the internet to act as a batch service, and make test2 submits the object code for each test case as a batch job and checks the results.

There's a shell script tools/pibake that mediates the process of submitting batch jobs, and is called with the assembly code for each test. It generates a shell script in which the assembly code is embedded, and uses the Secure Shell protocol ssh to submit it to a machine called iota for execution. It goes like this:

$ make test2-digits
*** Test digits.p
./ppc -O2 test/digits.p >b.s
sed -n -e '1,/^(\*\[\[/d' -e '/^]]\*)/q' -e p test/digits.p | diff -u -b - b.s
tools/pibake b.s >b.test
+ gcc -o b.out /home/guest/lib/pas0.o b.s
+ ./b.out
sed -n -e '1,/^(\*<</d' -e '/^>>\*)/q' -e p test/digits.p | diff - b.test
*** Passed
Our Raspberry Pi based server farm (artist's impression)

Here you can see the picoPascal compiler being run on the source program test/digits.p to produce an assembly language file b.s. This is compared with the saved code, then tools/pibake is invoked to assemble and run it, capturing the output in a file b.test. The next two lines show commands executed on the iota server: first using gcc to assemble the code and link it with the library pas0.o, a precompiled copy of which is conveniently located on the target machine; then running the object code as a native program on the ARM.[1] Finally, the output of the program is compared (on the host) with the expected output contained in the test file.

I've introduced a rudimentary mechanism that aims to prevent batch jobs from different people from interfering with each other: the batch job works inside a directory named according to your user name on the host machine. That is not enforced, however. There's no provision for avoiding interference between two simultaneous batch jobs from the same person, and in fact there's no mechanism to stop you from using the login token to connect to iota and do whatever takes your fancy. No mechanism, that is, apart from the forbidding phrase, Tout abus sera puni.

  1. Although we use the gcc program for assembly and linking, that does not mean we are using the Gnu C Compiler. It's just that the gcc command provides a convenient way to invoke the assembler and linker with all the standard libraries.