Skip to main content
Springer Nature - PMC COVID-19 Collection logoLink to Springer Nature - PMC COVID-19 Collection
. 2020 Jun 17;12227:272–279. doi: 10.1007/978-3-030-52482-1_18

A Reversible Runtime Environment for Parallel Programs

Takashi Ikeda , Shoji Yuen ‡,
Editors: Ivan Lanese8, Mariusz Rawski9
PMCID: PMC7345313

Abstract

We present a reversible runtime environment for simple parallel programs and its experimental implementation. We aim at a light-weight implementation of the backtrack reversibility by the state-saving mechanism using stacks. We translate a program to a sequence of simple commands of an executable intermediate representation for reversible stack machines. The parallel composition is implemented using the multiprocessing feature of Python. While executing the commands, the stack machines collect the information for the backward execution in the auxiliary stacks for the update history of the variables and the history of jumps. The commands for the backward execution is obtained by reversing the commands for the forward execution by replacing each command with the corresponding reversed command. In the purpose of behaviour analysis with reversibility such as debugging, our runtime is more portable than the source-to-source translation of a high-level programming language.

Keywords: Reversible computation, Imparative parallel programs, Stack machine, Python multiprocessing

Introduction

Reverse execution of programs has been investigated based on the reversible computing recently. Undoing the effect of an execution of a program till returning to the initial state is useful in analysing the finer-grained behavioural property of the program. In general, the execution of a parallel program depends on the environment such as the scheduler and I/O channels. Replaying the program may not reach the same states as the previous run. This makes behavioural analysis difficult to work out the cause of the defect for debugging.

Reversible programming languages such as Janus [4, 7] and RFUN [6] are designed for the reversed execution at the level of the design of programming languages. For example, Janus needs the extra-control structure at the end of the conditional branch in order to know which branch is executed to reverse the conditional statement. For this approach, the state-saving mechanism is not needed since the computation is fully reversed. However, introducing parallel composition becomes difficult since the runtime environment is not directly described in programs.

We present a reverse execution mechanism that the runtime collects the information in stacks at a forward execution. At the reverse execution, the runtime executes the program simply in the reversed order using the information stored in the stacks. A source program is compiled to a sequence of simple commands executed by the stack machine. Each process in the parallel composition is dispatched to each stack machine forked from the initial stack machine. We implement the backtrack reversibility with the multiprocessing feature of Python. In the reverse execution, multiple stack machines are invoked, but they are controlled by the stacks to follow back the forward execution.

The report is structured as follows. Section 2 gives the syntax of the programs, Sect. 3 presents the stack machine design and Sect. 4 states the concluding remarks.

Programming Language with Parallel Composition

Our parallel programming language is defined as follows where Inline graphic and Inline graphic denotes the repetition of one or more times and zero or more times respectively:graphic file with name 501864_1_En_18_Figa_HTML.jpg

The language is a simplified version of that in [2, 3]. Inline graphic denotes the parallel composition of sequential procedures. For simplicity, we remove the nested block structure and procedures. Inline graphic statements at the end of a program correspond to the variables declared at the beginning of the program, where the order of declarations is supposed to be reversed. For example, if variables are declared as Inline graphic , the variables are removed as Inline graphic . This ensures the correspondence between the variable and the entry of the symbol table.

Reversible Execution of Stack Machine Code

Reversible Stack Machine

For simplicity, a parallel program in this report is limited in the form that an initial stack machine runs first followed by parallel blocks. For values, we consider the integers Inline graphic. Inline graphic is the set of address Inline graphic as the locations of commands in a stack machine code. Here an address is a positive natural number. Inline graphic is the set of stack machine identifiers (SMid). An SMid is a natural number. We assume the initial stack machine has the SMid of 0. Other stack machines have id’s in a row from 1 to N where N is the number of parallel blocks.

The stack machine configuration is Inline graphic where PC is the program counter, Inline graphic holds the previous PC value, Inline graphic is a local stack, Inline graphic is a label stack, and Inline graphic is a value stack. Inline graphic is a symbol table that maps a variable to its value. Inline graphic presents the value of v. For the local stack w and Inline graphic, zw is the concatenation of z and w.

Each stack machine is identified by (pN) with p is a process identifier and N is a number of all parallel blocks in a program. The behaviour of a stack machine Inline graphic for command c is specified by Inline graphic as follows:

nop:

Inline graphic

Inline graphic does nothing but increasing the program counter.

ipush:

Inline graphic

Inline graphic pushes an immediate value of z to the local stack.

load:

Inline graphic

Inline graphic puts a value of v on the top of the local stack.

store:

Inline graphic

Inline graphic pops a value from the local stack and store the value z to the local storage Inline graphic after saving the previous value Inline graphic to the value stack along with the process number.

jpc:

Inline graphic Inline graphic

Inline graphic jumps to a when the stack top is 0. Otherwise, it moves to the next instruction by increasing the program counter.

jmp:

Inline graphic

Inline graphic jumps to a unconditionally.

op:

Inline graphic

where Inline graphic.

Inline graphic and Inline graphic are 1 when the relations hold and 0 otherwise.

Inline graphic applies the operation specified by k. Depending on k, it pops two or one from the local stack and pushes the result on the local stack. When Inline graphic is a relation, it pushes 1 when the relation holds and pushes 0 otherwise.

label:

Inline graphic

Inline graphic pushes the address for backward execution to the label stack where n is the number of all instructions. Inline graphic is the only instruction that uses Inline graphic.

rjmp:

Inline graphic

Inline graphic is a reverse jump that pops an address and a stack machine number from the label stack and jump back to the address on that process with the number.

restore:

Inline graphic

Inline graphic pops the value of v and the stack machine number from the value stack on the specified stack machine.

alloc:

Inline graphic

Inline graphic adds v to the environment Inline graphic and initialises v.

free:

Inline graphic

Inline graphic removes v from the environment Inline graphic.

Inline graphic and Inline graphic collect the information in a forward execution. Inline graphic updates Inline graphic and Inline graphic. In Inline graphic, it records the value is stored by p. But in the backward execution, the process number is also reversed, and it stores Inline graphic as the backward process number. Inline graphic records from which address the control reach this place.

Inline graphic and Inline graphic restore the information for a backward execution. Inline graphic corresponds to Inline graphic and pops the location from Inline graphic and jump back to the location where the forward execution came from. And Inline graphic puts back the previous value from the value stack. In both cases, the stack machine must be identified where the SMid is inverted since the order of the parallel blocks is reversed1.

Figure 1 shows the mechanism of Inline graphic and Inline graphic. Inline graphic is a destination of Inline graphic and Inline graphic. If Inline graphic is executed, it pushes the source address of that jump to the label stack. In the backward execution, Inline graphic is substituted by Inline graphic. By popping the label stack, one of the stack machines executes Inline graphic and jumps back to the source address.

Fig. 1.

Fig. 1.

Reversing jump instructions

Inline graphic allocates a variable slot on the stack and updates the symbol table. Inline graphic removes a variable slot. Inline graphic removes v from the domain of Inline graphic. In current target codes, Inline graphic and Inline graphic are executed only by the initial stack machine with id 0.

Inverting Stack Machine Code

We do not present the detailed translation from a source program to the stack machine code here. The translator is implemented using Javacc. In the translation, Inline graphic is inserted at a target of Inline graphic and Inline graphic. The argument of Inline graphic is the length of the generated code. Since this is not known until the whole translation is done, it can be specified by back-patching. Inline graphic 0 and Inline graphic 1 are inserted for a parallel block.

From a forward stack machine code s, the backward code Inline graphic is obtained:

graphic file with name M89.gif

where Inline graphic for each command is defined as below where n is the :

graphic file with name M91.gif

For other command c, Inline graphic.

Execution from the Initial Stack Machine

Let s be the forward stack machine code. From the construction of a program, s is partitioned to:

graphic file with name M93.gif

where M is the length of the code and Inline graphic executes Inline graphic, Inline graphic, and Inline graphic where Inline graphic and Inline graphic are Inline graphic and Inline graphic for variables. Inline graphic is the sequential code for Inline graphic to initiase the variables followed by the parallel composition. Inline graphic executes Inline graphic in parallel for Inline graphic.

Figure 2 shows the overview of executing a program. The code starts on the initial stack machine Inline graphic. After reaching the parallel composition starting with Inline graphic, the N stack machines run in parallel. When all the executions of parallel processes terminate, it passes the control to the initial stack machine, freeing the variable at the end. The environment Inline graphic, the label stack Inline graphic, and the value stack Inline graphic are shared by all stack machines.

Fig. 2.

Fig. 2.

Execution by stack machines

Let Inline graphic and Inline graphic be the label stack and the value stack. Inline graphic is a configuration of code s with the initial SM. For the forward execution, the initial configuration is Inline graphic and the final configuration is Inline graphic. The corresponding backward execution starts with Inline graphic and ends with Inline graphic. While the parallel blocks are executed, the configuration is in the form:

graphic file with name M119.gif

We define the execution of s as the transition relation between configurations shown in Fig. 3. In the rules above, Inline graphic denotes that PC points a code in s. s(PC) is the code pointed by PC and Inline graphic is the address of Inline graphic in the stack machine code.

Fig. 3.

Fig. 3.

Execution for code s

  • Inline graphic defines the behaviour before and after the parallel composition. Inline graphic is the number of variables. Inline graphic constructs the symbol table by Inline graphic and executes the initial sequential code Inline graphic.

  • Inline graphic dispatches the development of the parallel blocks once it reaches the first Inline graphic. The program counter of stack machine Inline graphic is set to Inline graphic.

  • Inline graphic defines the interleaving behaviour of the parallel composition.

  • Inline graphic goes back to the initial stack machine and sets the PC to Inline graphic once all Inline graphic reaches Inline graphic. The execution continues with Inline graphic.

In order to implement the operational semantics, it is necessary to scan the whole stack machine code before executing the code to identify N, Inline graphic and Inline graphic.

Concluding Remarks

We present a reversible runtime environment for simple parallel programs and its experimental implementation by Python. The reversibility mechanism is state-saving and the environment performs the back-track reversibility. The runtime environment is a set of reversible stack machines. The stack machines that execute the parallel blocks share the stacks for value-updates and jumps. Since we focus on the reversibility of states, we do not precisely reverse the forward computation. We replace the commands for computing values with Inline graphic in the backward code. This eases the concurrency control in the backward execution since it has no effect for states. We regard this is enough for behavioural analysis such as debugging. The approach of forward and backward executions is fundamentally similar to that of [2]. Our approach is finer-grained than [2]. This eases the implementation with the existing runtime since the runtime is often less controlled. As the result, in our approach a backward execution does not precisely undo the forward execution at the level of stack machine code. By sharing the variable environment, the label stack, and the value stack, we manage the consistency of variable updates among the stack machines running in parallel.

As related work, our stack machine is close to the basic architecture of [1] in jumping mechanism although only a sequential execution is considered. The label stack maintains the control of jumps across the parallel composition. [5] presents the reversible semantics in the functional programming style at the abstract machine level with communications and concurrency. [5] gives the operational semantics for backward execution, while our approach translates the abstract machine instructions for backwards within the single operational semantics. Our language has no built-in communication mechanism.

For future work, we need to prove the correctness of our translation by strictly formalising the behaviour of the concurrent execution of a program. The programming language in Sect. 2 limits the class of programs although the stack machine operations have more capability. Adding the nested structure of blocks and procedure is possible by extending the reference mechanism for variables. Adding recursion with the parallel composition make the number of parallel processes dynamic. We need to extend the numbering scheme for identifying the sequential processes executed in parallel and how to choose the next available process in the backward execution.

Acknowledgement

The authors thank Dr. I. Ulidowski and Dr. J. Hoey for the valuable suggestions and discussion. This work was supported by JSPS KAKENHI Grant Numbers JP17H01722 and JP17K19969.

A Runtime Environment by Python

The concrete examples and our implementation by Python are shown at https://github.com/syuen1/RevRunTimeEnv.

A source program is compiled to the forward stack machine code.graphic file with name 501864_1_En_18_Fige_HTML.jpg

The forward stack machine code is stored in Inline graphic . To run the code forward, graphic file with name 501864_1_En_18_Figg_HTML.jpg

Then, we get Inline graphic , Inline graphic , and Inline graphic as the stack for variable values and the stack for labels2

To invert the forward code,graphic file with name 501864_1_En_18_Figk_HTML.jpg

And run the backward code,graphic file with name 501864_1_En_18_Figl_HTML.jpg

In the backward, Inline graphic reads the stack files. The result for the airline ticket example is shown in the appendix.

A.1 Controlling Parallel Blocks

The runtime can be executed step-by-step choosing which parallel block is executed in the next step in both directions. The execution of the parallel blocks is controlled by the process that is running the initial stack machine. By entering the process number, the program executes one step in the forward and backward execution showing the stacks.

Footnotes

1

Since an address of command is uniquely assigned to a unique stack machine, it is not essential to record p in Inline graphic. Without p in Inline graphic, another table is necessary.

2

The last v shows the verbose mode to show all the steps. No intermediate result is shown when q is specified.

Contributor Information

Ivan Lanese, Email: ivan.lanese@gmail.com.

Mariusz Rawski, Email: mariusz.rawski@gmail.com.

Takashi Ikeda, Email: tikeda@sqlab.jp.

Shoji Yuen, Email: yuen@sqlab.jp.

References

  • 1.Axelsen HB, Glück R, Yokoyama T. Reversible machine code and its abstract processor architecture. In: Diekert V, Volkov MV, Voronkov A, editors. Computer Science – Theory and Applications; Heidelberg: Springer; 2007. pp. 56–69. [Google Scholar]
  • 2.Hoey J, Ulidowski I. Reversible imperative parallel programs and debugging. In: Thomsen MK, Soeken M, editors. Reversible Computation; Cham: Springer; 2019. pp. 108–127. [Google Scholar]
  • 3.Hoey, J., Ulidowski, I., Yuen, S.: Reversing parallel programs with blocks and procedures. In: EXPRESS/SOS 2018, Beijing, China, 3 September 2018, EPTCS, vol. 276, pp. 69–86 (2018)
  • 4.Levin RY, Sherman AT. A note on Bennett’s time-space tradeoff for reversible computation. SIAM J. Comput. 1990;19(4):673–677. doi: 10.1137/0219046. [DOI] [Google Scholar]
  • 5.Lienhardt M, Lanese I, Mezzina CA, Stefani J-B. A reversible abstract machine and its space overhead. In: Giese H, Rosu G, editors. Formal Techniques for Distributed Systems; Heidelberg: Springer; 2012. pp. 1–17. [Google Scholar]
  • 6.Thomsen, M.K., Axelsen, H.B.: Interpretation and programming of the reversible functional language RFUN. In: IFL 2015, Koblenz, Germany, 14–16 September 2015, pp. 8:1–8:13. ACM (2015)
  • 7.Yokoyama, T., Glück, R.: A reversible programming language and its invertible self-interpreter. In: PEPM 2007, pp. 144–153. ACM (2007)

Articles from Reversible Computation are provided here courtesy of Nature Publishing Group

RESOURCES