<%BANNER%>

Implementation of a parallel program, program generator

University of Florida Institutional Repository

PAGE 1

IMPLEMENTATION OF A PARALLEL PROGRAM, PROGRAM GENERATOR By JEAN-DAVID G. OLADELE A THESIS PRESENTED TO THE GRADUATE SCHOOL OF THE UNIVERSITY OF FLOR IDA IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR THE DEGREE OF MASTER OF ENGINEERING UNIVERSITY OF FLORIDA 2002

PAGE 2

Copyright 2002 by Jean-David G. Oladele

PAGE 3

Dedicated to Renee Williams.

PAGE 4

iv ACKNOWLEDGMENTS I thank my Lord Jesus Christ for his mercy and strengthening me in all that I do. I would like to express my sincere gratitude to my advisor, Dr. Beverly Sanders, for serving as the chairperson of my committee. Her sugges tions and support went a long way in making this thesis a reality. I w ould also like to thank Dr. Hammer and Dr. Wilson for their commitments. I thank Alejandro Pauly for his examples that provided much needed insight during the early stages of my wo rk. In addition I am grateful to all my friends for their support and encouragement. Finally, I would lik e to express my love and gratitude to my family for their support and dedication.

PAGE 5

v TABLE OF CONTENTS page ACKNOWLEDGMENTS.................................................................................................iv LIST OF TABLES............................................................................................................vii LIST OF FIGURES.........................................................................................................viii ABSTRACT....................................................................................................................... ..x CHAPTER 1 INTRODUCTION...........................................................................................................1 2 BACKGROUND.............................................................................................................4 Program Generators........................................................................................................4 The OO-Driven Style...............................................................................................5 Code-Driven Style....................................................................................................6 Table-Driven Style...................................................................................................6 Patterns, Pattern Languages and Parallel Patterns..........................................................7 Extensible Markup Language a nd Data Type Definitions............................................10 Document Object Model...............................................................................................10 3 THE PPPG USER SPECIFICATIONS.........................................................................11 The design.space Element.............................................................................................12 The task.group Element................................................................................................13 The grp.struct Element..................................................................................................13 The grp.sub.struct Element...........................................................................................13 The task.decomposition Element..................................................................................14 The task.relationships Element.....................................................................................14 The dependency.type Element......................................................................................14 4 USING THE PPPG TOOL............................................................................................22 The PPPG User Interface..............................................................................................22 General Information Pane......................................................................................22 Datatypes Pane.......................................................................................................23 Concurrency Organization Pane............................................................................24 Dependencies and Partitioning Pane......................................................................25

PAGE 6

vi The XML Viewer Pane..........................................................................................26 Executing from the Command Line..............................................................................27 5 IMPLEMENTATION DETAILS..................................................................................29 A Walk through the Code-Generation Process.............................................................29 Modules and Class Detail.............................................................................................35 Parse and Package Module.....................................................................................35 Datacapsule............................................................................................................37 Code Generator Module.........................................................................................38 6 GENERATED PROGRAMS.........................................................................................41 Concurrent Implementation of Mergesort....................................................................41 Assembly Line Simulation............................................................................................43 Implementation of the Game of Life............................................................................45 7 CONCLUSION..............................................................................................................48 Summary of Work Done...............................................................................................48 Future Work..................................................................................................................49 APPENDIX A EXAMPLE PROGRAMS SOURCE CODE LISTINGS.............................................51 B SPECIFICATIONS FOR EXAMPLE PROGRAMS...................................................56 LIST OF REFERENCES...................................................................................................58 BIOGRAPHICAL SKETCH.............................................................................................60

PAGE 7

vii LIST OF TABLES Table page 3-1 design.space Element summary......................................................................................16 3-2 task.group Element summary.........................................................................................17 3-3 grp.struct Element summary...........................................................................................18 3-4 grp.sub.struct Element summary....................................................................................18 3-5 task.decomposition Element summary...........................................................................19 3-6 task.relationships Element summary..............................................................................19 3-7 dependency.type Element summary...............................................................................20

PAGE 8

viii LIST OF FIGURES Figure page 2-1 Algorithm struct ure decision tree................................................................................... 8 3-1 The design.space Element..............................................................................................16 3-2 The task.group Element..................................................................................................17 3-3 The grp.struct Element...................................................................................................1 7 3-4 The grp.sub.struct Element.............................................................................................18 3-5 The task.decomposition Element....................................................................................18 3-6 The task.relationships Element.......................................................................................19 3-7 The dependency.type Element........................................................................................19 3-8 The design.space element code snippet..........................................................................20 3-9 The task.group element code snippet.............................................................................20 3-10 The grp.struct element code snippet.............................................................................20 3-11 Complete specification document................................................................................21 4-1 General information screen............................................................................................23 4-2 Datatypes window.......................................................................................................... 24 4-3 Concurrency organization pane......................................................................................25 4-4 Dependencies and partitioning pane...............................................................................26 4-5 The XML Viewer Pane...................................................................................................27 5-1 Specification file fo r mergesort procedure.....................................................................29 5-2 Decision tree............................................................................................................. ......31 5-3 Boilerplate code generated to mergeSort.java file.........................................................32

PAGE 9

ix 5-4 Remainder of code generated for mergeSort.java class.................................................34 5-4 Structure of PPPG......................................................................................................... ..36 5-5 Parse and package module..............................................................................................37 5-6 SyntaxAnalyzer UML diagram......................................................................................38 5-7 DataCapsule UML diagram............................................................................................39 5-8 CodeGenerator UML diagram........................................................................................40 6-1 Concurrent MergeSort algorithm....................................................................................42 6-2 Implementation of the split method................................................................................43 6-3 MathFactory code snippet..............................................................................................44 6-4 Inner Class Stage code snippet.......................................................................................45 6-5 Game of life.............................................................................................................. ......47

PAGE 10

x Abstract of Thesis Presen ted to the Graduate School of the University of Florida in Partial Fulfillment of the Requirements for the Degree of Master of Engineering IMPLEMENTATION OF A PARALLEL PROGRAM, PROGRAM GENERATOR By Jean-David G. Oladele December 2002 Chair: Dr. Beverly Sanders Department: Computer and Info rmation Science and Engineering Efficient parallel programs and algorithms are difficult to write. Parallel programs present the programmer not only with the questions of what needs to be done, and when an operation takes place, but also where the operation needs to occur. A large number of parallel programs are dynamic in na ture and do not provide a regular structure for parallelization. The programmer must provide complex algorithms for scheduling, load balancing, and rebalancing in order fo r these programs to perform efficiently in parallel. This thesis presents the design and implementation of the PARALLEL PROGRAM, PROGRAM GENERATOR (PPPG). PPPG reduces the complexity of creating parallel pr ograms. PPPG generates efficient a nd portable parallel patterns for different classes of the parallel program do main. The patterns ge nerated are dependent on Extensible Markup Language (XML) input specifications. The input specifications may be supplied as a raw XML file or generate d from a series of responses by the user.

PAGE 11

xi The output patterns are provided in the Java language to allow for portable parallel programs. The Java Virtual Machine (JVM) is responsible for processor scheduling.

PAGE 12

1 CHAPTER 1 INTRODUCTION Parallel programming involves breaking an algorithm or data into parts. These parts are then distributed as tasks for simu ltaneous execution over multiple processors or concurrent execution over a single processo r. The motivation for parallel programming is that a program being executed over multiple processors might execute faster than it would during serial execution on a single proc essor. Parallel programming involves design steps to assign threads, tasks, or processes to phys ical processor(s ) for execution [6]. Creating and writing para llel programs is often very difficult and time consuming. The programmer must deal with issues of co rrectness and efficiency, which become more complex and magnified in a parallel e nvironment. Dependencies among concurrent threads of execution must be carefully ma naged to ensure a consistent result. The aforementioned difficulties necessitate a tool that can generate a shell program or template that makes writing parall el programs easier for the developer. This tool will handle all the concurrency and pe rformance issues. The ge nerated shell program is essentially ready for use. The develope r need only modify the template by adding application-specific functionality, and the program is ready for use. This thesis describes the design and imple mentation of a program generator that provides a template for the creation of effi cient and portable parallel programs. The program generator is referred to as the Parallel Program Program Generator (PPPG). A program generator is a tool that au tomates the creation of programs from precise descriptions of syntax and desired be havior [1]. Program generators provide an

PAGE 13

2 effective way to automatically create variant programs with in the same family. They allow for consistency of commonalities within a particular application domain. When there is sufficient information about how a program will be used, program generators construct optimized and robust code. The PPPG generates shell programs for di fferent classes of the parallel program domain. The generated shell/skeleton pr ograms are based on the results of ongoing research at the University of Florida. This research focuses on developing pattern language for parallel applicati on programming. Patterns are de fined as representations of reusable object design. Patterns and Pattern lang uages are ways to describe best practices and good designs, and to capture experience in a way that allows others to reuse this experience [4]. Parallel patterns can be used to design high quality software because the pattern language acts as a gui de through application design and the development process [7]. The PPPG requires information from th e user in order to determine the characteristics, behavior, and cl ass of parallel program to be generated. This information is called the input specificati on. The input specification for PPPG is represented using the Extensible Markup Language (XML). The XML is a cross-platform, software and hardware-independent language for data desc ription and information transmission. The XML is used to help accomplish the PPPG’s goal of portability. The information representing the parallel programming doma in is called the Document Type Definition (DTD). The DTD lists all the element types and attributes and their constraints as used in the input specification. A valid XML input specification docum ent must meet the conditions imposed by the DTD.

PAGE 14

3 The skeleton program generated by PPPG is written in the Java programming language. The main advantage of having the code generated in Java is portability over different and diverse operating environments. An added benefit is th at the user need not worry about scheduling issues; the Java Virtual Machine (JVM ) will handle this. Using XML and Java, a program generator that is efficient and portable can be created. This development tool takes much of the burden of designing and implementing parallel programs off of the user. The re mainder of this thesis paper describes the implementation of such a tool. Chapter 2 gives background information on the technologies behind PPPG. Chapter 3 discu sses the DTD for the domain and how it constrains the XML specification. Chapter 4 pr ovides a high-level vi ew of the PPPG tool from the user’s perspective and addresses the effective use of the tool. Chapter 5 deals with implementation details and issues, from a designer’s point of view. Chapter 6 discusses sample programs based on pattern s generated using PPPG. Chapter 7 gives conclusions and suggestions for fu ture additions and improvements.

PAGE 15

4 CHAPTER 2 BACKGROUND This chapter presents an overview of the core development technology used to implement PPPG. This includes a brief revi ew of program generators, patterns and pattern languages, the extensible markup la nguage (XML), and data type definitions (DTD). This chapter also di scusses parallel patterns and the parallel pattern language developed at University of Florida (UF). Program Generators A program generator is a software tool that creates the source code for another computer program. The description of what the generated computer program should do is supplied to the program generator as a specif ication file. Data about the program to be generated is supplied to the program genera tor, which after anal yzing and transforming the data generates the desired program. Some popular examples of program generators are parser generators such as yacc, GUI builders, and visual programming tools. Using program generators can greatly in crease productivity. One reason for this is that specifications are usually easier to cr eate, edit, and verify co rrectness than the code that implements the specifications. This is often the case because implementation often requires specialized knowledge and technique s that are very time consuming. These techniques are usually not required to understa nd and create the specifications. When a program generator is being used the progr ammer need only be concerned with the specification; without the program generato r, a significant amount of time would also have been spent on implementation.

PAGE 16

5 Program generators also increase productiv ity because they can easily be used to generate variant programs within the same pr oblem domain or program family. Program generators can generate other files, such as documentation about the software, user documentation, test scripts and more. They can also resolve the consistent-update problem. During software maintenance or update, fixing an error may often set off a chain of other errors within the software produc t. This occurs often in situations where the change is not updated consistently acro ss the software product. When using a program generator, the specification need only be updated and the program can be regenerated. Doing this will ensure consiste nt update across the application. In cases where information on how the generated program will be used is available, program generators can be specifically cust omized to generate optimized code. There are 3 main styles of programming us ed in program generators. These styles relate directly to the type of code gene rated by the program generator. The three approaches are € OO-driven € Code-driven € Table-driven The OO-Driven Style The OO-Driven approach uses standard object oriented techniques such as inheritance, interfacing, a nd message passing, for organi zing the structure of the generated program [2]. Rela ted variables and methods ar e bundled to create specific objects. Data from specifications are insert ed where needed and Classes are created for attributes where needed. This approach is based on stacking object -oriented layers of

PAGE 17

6 abstraction. Each layer contai ns a number of object classe s where each top layer refines the layer below it by adding new classes a nd new methods to existing classes [3]. This particular style is usually difficult to create and is less efficient than the code-driven style. The advantage of this style is that it allo ws for separation of concerns based on specific performance and design goals. Code-Driven Style This is the most natural and simplistic approach to program generation. In this method the code is simply generated where it is needed without any concerns about program structure but focuses on simplicity and e fficiency of code generation [2]. In this method data from the specification is simply embedded where needed. Table-Driven Style Table-driven design is a software engineering me thodology that attempts to simplify and generalize by separating program control variable and parameters from the program code and placing them in external tables. Design objectives include an emphasis on modularity and decoupling program control da ta from application logic. Applications are made more flexible by postponing the time when control values and rules are bound to the processes they direct [11]. This approach to program generation em phasizes the separation between data and the code that performs the generation. Data from the specifications are stored in the tables and other data structures The code simply refers to the tables when the data is needed rather than embedding the da ta directly into the code [2]. PPPG uses a hybrid of the OO and Code-driven approaches for program generation. Combining these 2 approaches resu lts in simple and effi cient code generation with attributes represented as objects.

PAGE 18

7 Patterns, Pattern Language s and Parallel Patterns Patterns are reusable representations of good design, which assist programmers in the development of good quality software. A collection of patterns is referred to as a pattern language. Pattern la nguages can be used as a guide from problem specifications to complete design [7]. PPPG will generate source code based on parallel patterns from ongoing research at the University of Florida. The resear ch focuses on developing a pattern language for parallel application programming. The patt ern language is to be used by application programmers who are interested in designing pr ograms that will execute in parallel. The pattern language is organized around the following design spaces: € Finding concurrency € Algorithm structure € Supporting structures € Implementation mechanisms This thesis focuses on patterns from th e algorithm structure design space. This space deals with methods for exploiting concur rency. The patterns w ithin this space are organized by means of the deci sion tree shown in Figure 2-1. Starting at the root of the tree the program generator makes decisions based on the input specification and generate s one of the 9 terminal patterns. The terminal patterns are discussed below: Pipeline Processing This pattern is used in situat ions where the data requires a number of basic operations to be performed in seque nce. The operations may be regarded as stages or stops within a pipeline, where a ll the stages have the potential of executing concurrently. At each pipeline stage an opera tion is performed and then the data moves on to the next sequential stage. A good exam ple of pipeline processing is an assembly

PAGE 19

8 line at an electronics manufacturer. An unfinished VCR or DVD player may go through go through different line stages before comple tion. At each stage the same operation is performed over and over again. Figure 2-1 Algorithm stru cture decision tree[7] Asynchronous Composition. This pattern is applicable in situations where units may interact with each other in a random non-specific manner. Embarrassingly Parallel. The embarrassingly parallel patter n is applicable in situations where various units can operate without any inte raction. This pattern usually involves the concurrent execution of independent units. This pattern shows how to organize such units so that they may execu te in an efficient manner. Reduction. The reduction pattern is used in si tuations where dependencies between tasks can be removed based on whether the global da ta can be copied to individual tasks and

PAGE 20

9 partial results stored in these tasks can be recombined to form a global solution. This pattern represents the class of problems in wh ich the following issues can be separated. € Allocating the tasks among the processors so the computational load is evenly distributed. € Managing the dependencies between tasks so that if multiple tasks update the same data structure, these updates do not interfere with each other. Shared Memory The Shared Memory pattern is used in situations where dependencies between tasks cannot be removed. The two ma in challenges that this pattern helps the programmer deal with are, the partitioning of tasks amongst un its of execution in such a manner that the computation load on the pr ocessor(s) is evenly distributed, and the management of any dependencies that may exist between tasks. Balanced Tree This pattern applies to problems in which a bala nced tree can be built on the input elements. The pattern will allow the tree to be traversed in forward and backward directions while computing and stor ing information at each internal node [3]. Divide and Conquer This pattern applies to problems where the input ca n be partitioned into individual tasks. Each of these task s can be solved recursively and in parallel (concurrently) and the solutions of the diffe rent sub problems can be merged into the solution for the original problem. Geometric Decomposition This pattern is applicable when the initial problem can stored in a data structure which can be broken down into separate pieces. The concurrency is achieved based on parallel updates of the indi vidual pieces. When any piece is updated data is required from all the other pieces. Reference Following This pattern is used for pa rallel applications in which an apparently sequential operati on on a recursive data is rewo rked to make it possible to operate on all elements of the da ta structure concurrently [7].

PAGE 21

10 Extensible Markup Language and Data Type Definitions Extended Markup Language (XML) provide s a way to define, manipulate, transform and transport data over multiple pl atforms. XML provides a way to define an arbitrary structure for documents. It ha s the advantage of keeping structure and presentation information separate. This in turn leads to more flexible and thus more valuable documents. There are two types of correct XML documents, valid XML documents and wellformed XML documents. A well-formed XM L document contains just the needed information. They do not spell out their ow n rules but simply follow the general XML rules. Valid XML documents on the other hand are self-describing and contain or provide a link to informati on about the documents struct ure and contents. These documents require a document type descrip tion (DTD). The DTD constrains the XML document for the application progra m that is to process the XML. Document Object Model The document object model (DOM) is a W3C specification described as follows: The Document Object Model is a platfo rmand language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. The document can be further processed and the results of that processing can be incorporated back into the presented page[13]. The DOM provides standard interfaces to allow for programmatic access to the contents of an XML document. An XML documen t is represented as a tree data structure in which the nodes represent portions of the document. Using DOM, specific information can be retrieved from the XML document.

PAGE 22

11 CHAPTER 3 THE PPPG USER SPECIFICATIONS In order for PPPG to create useful and va luable programs for the user, there must be a means by which the user can clearly desc ribe the characteristics and functionality of the program to be generated. The user mu st be able to easily and unambiguously communicate what kind of program is needed an d the program generator must be able to understand the users’ descripti on and generate the correct program. XML is used to create a specification language that adequate ly addresses the aforementioned goals. The rest of this chapter will focus on the XML that specifies the program to be generated and the DTD that describes and constrains it. The primary goal of the specifications is to help the user describe his/her target program in terms of one of the terminal patter ns shown in Figure 2-1. In other words, the specification language fits the user’s initial problem to the closest related terminal pattern. To adequately express what kind of program is to be generated the programmer must be able to answer the follo wing questions about their problem: € What kind of top level organizati on is desired for concurrency? € What kind of structure does th e top-level organization possess? € Do any dependencies exist amongst tasks or task groups? Let us now examine the individual elem ents and their corre sponding attributes that make up the document type description for the PPPG specifications. This document type description will be refe rred to as the design space DTD.

PAGE 23

12 The design space DTD contains the followi ng elements in hierarchical order: € design.space € task.group € grp.struct € grp.sub.struct € task.decomposition € task.relationships € dependency.type The design.space Element The design.space element serves as the r oot element for the design space DTD. Every other element is a descendant of this element. The design.space element has five attributes and one sub element. The attributes are listed below: € Classname. This particular attribut e represents the name of the Java class for which code will be generated. This is a requir ed attribute and must be provided in the specification document. The required data type for this element is string. € Sourcepath. This attribute represents the targ et directory in which the generated code should be stored. This attribute is op tional. If it is not provided the generated code will be stored in the directory PPPG is being executed in. The required data type for this attribute is string. € Units. This attribute indicates the number of units of execution that the user wants the generated program to use in the solution. This attr ibute is optional. If not specified a default value of three units is used. The required data type for this attribute is the primitive type int. € Initdatatype. This attribute should contain the data type of the initial problem. This is an optional attribute and if not supplied the default data type Object is used. This attribute should be specified as a string. € Findatatype. This attribute indicates the data type in which the user expects the solution to the problem to be stored. As in the case of the previous attribute, findatatype is also optional and a default data type of Object is assumed when the attribute is missing. This attribut e should be specified as a string. The design space element must contain an instance of the task.group element. A diagram of the design.space element is shown in Figure 3-1.

PAGE 24

13 The task.group Element The task.group element captures informati on about the top-level organization of the problem to be solved. It has two attribut es and one sub-element. The attributes are described below: € Name. This attribute should contain the name of the top-level organization for the problem. There are three acceptable values for this attribute. The values are Ordering Tasks and Data This is a required attribute and must be provided in the specification document. The required data type for this element is string. € Datatype. This attribute should contain the data type of the sub-problems that the initial problem will be broken down into. This attribute is optional. If the attribute is not supplied the data type Object is used. This attri bute should be specified within specification document as a string. The task group element require s a grp.struct sub-element. The grp.struct Element The grp.struct element helps to capture information about the underlying structure of a given top-level organizat ion. It allows the user to provide information on how a problem with a given organization (orderings, task s, or data) is composed. It consists of two attributes and a required sub elemen t. The attributes are shown below: € Name. This attribute contains the type of underlying structure for a specific toplevel organization type. If th e top-level organization is by Ordering the possible values are Regular or Irregular For any other valid to p-level organization the valid values are either Linear or Recursive This attribute is required and must be specified as a string. € Numstages This attribute is only applicable when the problem is organized by ordering and has a regular stru cture. This attribute allo ws the user to specify the number of stages required. This is an op tional attribute. The required data type for this attribute is the primitive type int. The grp.sub.struct Element The grp.sub.struct element captures info rmation about tasks relationships and dependencies. It is only applic able in problems that are orga nized by tasks. It contains no

PAGE 25

14 attributes but it must have e ither a task.decomposition or a ta sk.relationships element as a sub element. The task.decomposition Element The task.decomposition element is applicable when we have a problem that is organized by tasks and has a recursive substruc ture. The possible values for this element are one-way and two-way These values indicate the t ype of recursion the problem exhibits. The task.relationships Element The task.relationships element is appli cable only when the to p-level organization is by tasks. This element captures depe ndency information among linearly partitioned tasks. It contains a single required attribute and an optional sub-element. The attribute is described below: € Type. This attribute indicates whethe r or not dependencies exist among the partitioned tasks. This attribute has two possible correct values. It can either be Dependent or Independent This is a required attribute and must be provided in the specification document. The required data type for this element is string. The dependency.type Element The dependency.type element simply e xpresses what kind of dependencies are exhibited by the tasks. There are two valid op tions for this element. It can be either Separable or Inseparable The design space DTD elements that have been discussed help constrain and describe the XML specifications for the PPPG application. In th is section the DTD elements will be transformed into the corresponding XML specification. Consider the following example, a user wish es to write a parall el version of the game of life. The game should use no more than nine threads and the initial problem is

PAGE 26

15 represented in a two dimensiona l integer array. The solution s hould be in a class with the name Life.java. Using the information given above, the XML specifications for the presented scenario will be created accord ing to the design space DTD elements. Starting with the design.space root element the user must identify the required attributes from the problem description: Th e class name is “Life”; the generated file should be stored in the user’s home direct ory, it should use nine units of execution and the problem is represented in a two dimensional array. Our initial specification document with the information a bove will look like this: The design space DTD requires that a design.space element must also contain a task.group element. For the game of Life problem the top-level organization is by tasks. The user has also chosen to create a user-defined class named Task to contain the information on which part of the array each unit of execution will have access to. Adding this information to our specification file will result in Figure 3-9. The task.group element requires that a grp.struct element be present. The user must focus on what attributes are needed for th is element. From our specifications it can be deduced that the Tasks substructure is linear In this particular scenario the numstages attribute is not applicable. Adding this inform ation results in the specification file shown in Figure 3-10. Now that information has been captured about the grp.struct we must also examine what information can be extracted fr om the problem descri ption relating to the grp.sub.struct element. The grp.sub.struct element must contain either a task.relationships or task.dependency element type. The tasks in this problem are independent of one another and the task.relationships element is applicable in this

PAGE 27

16 particular case. Adding this information resu lts in the completed specification shown in Figure 3-11. Using the design space DTD we have been able to transform the game of life problem description into an XML specifica tion file that conveys all the necessary information needed to generate the source code for the problem solution. The design space DTD has allowed us to fit the details of a problem to one of the decision tree terminal patterns. In doing so, we have been able to create accurate and concise specifications fo r the PPPG application. Figure 3-1 The design.space Element Table 3-1 design.space Element summary Element Name design.space Attributes classname, sourcepath, unit, initdatatype, findatatype Uses element(s) task.group Used by (None) root element Content a sequence of elements Occurrence required

PAGE 28

17 Figure 3-2 The task.group Element Table 3-2 task.gr oup Element summary Element Name task.group Attributes name, datatype Uses element(s) grp.struct Used by design.space Content a sequence of elements Occurrence required Figure 3-3 The grp.struct Element

PAGE 29

18 Table 3-3 grp.struct Element summary Element Name grp.struct Attributes name, numstages Uses element(s) grp.sub.struct Used by task.group Content a sequence of elements Occurrence required Figure 3-4 The grp.sub.struct Element Table 3-4 grp.sub.struct Element summary Element Name grp.sub.struct Attributes None Uses element(s) task.decomposition task.relationships Used by grp.struct Content choice Occurrence required Figure 3-5 The task.decomposition Element

PAGE 30

19 Table 3-5 task.decomposition Element summary Element Name task.decomposition Attributes None Uses element(s) None Used by grp.sub.struct Content character data Occurrence optional Figure 3-6 The task.relationships Element Table 3-6 task.relationships Element summary Element Name task.relationships Attributes type Uses element(s) dependency.type Used by grp.sub.struct Content a sequence of elements Occurrence required Figure 3-7 The dependency.type Element

PAGE 31

20 Table 3-7 dependency.type Element summary Element Name dependency.type Attributes None Uses element(s) None Used by task.relationships Content character data Occurrence optional Figure 3-8 The design.space element code snippet Figure 3-9 The task.group element code snippet Figure 3-10 The grp.struct element code snippet

PAGE 32

21 Figure 3-11 Complete specification document

PAGE 33

22 CHAPTER 4 USING THE PPPG TOOL The PPPG tool provides two options for th e user to generate source code for concurrent /parallel programs. Users may choose to generate their source code by supplying an XML specification document containi ng the details of the problem that is to be solved via the command line. An altern ative to doing this is to use the PPPG user interface to generate th e specification document and program source code. The PPPG User Interface The PPPG user interface (PPPGUI) allows the user to generate source code without having to manually create the XM L specification document. This is advantageous as it removes some of the responsibility for the correctness of the specification document from the user. The remainder of this chapter serves as a walkthrough the PPPG user interface. The PPPGUI consists of five tabbed panes. Four of these panes help to gather requirements about the nature of the problem at hand. The fifth pane displays the specification document correspond ing to the user’s input. General Information Pane The general information tabbed pane se rves as the front page for the PPPG application. When the program is started the user is presented with a screen similar to the one shown in Figure 4-1. The purpose of this pane is to collect general information concerning the problem for which the user wishes to generate code. The user is expected to enter the path to the directory in which the generated source code wi ll be store into the

PAGE 34

23 Target Directory textbox. A Browse button is also provided to allow the user to look through the directory tree for a desi red location for the source code. Figure 4-1 General information screen The Classname textbox should contain the name of the file in which the solution should be stored. The Units of execution drop down box allows the user to select the number of threads desired in the solution. Datatypes Pane The datatypes tabbed window pane allows the user to specify the different datatypes that the generated program will have to handle. This window helps to capture information about the datatypes that the problem will evolve through during the solution process. It allows us to capture how the da tatype of the problem to be solved will be changed from its initial repres entation to the datatype that the final solution. The radio buttons within the Initial Problem Datatype group box allow the user to pick the datatype

PAGE 35

24 that the initial problem will be represente d as programmatically. The user may also select a user defined type or class by selecting the Other radio button and entering the name of user defined class or type in the appropriate textbox. This is applicable to all three group boxes. The Intermediate Datatype group box contains radio buttons that allow the user to pick the datatype for the intermediate objects that the initial problem will be broken down into during execution of the generated code. The Result Datatype group box contains radio buttons that allow the user to speci fy the desired datatype for the problem solution. Figure 4-2 Datatypes window Concurrency Organization Pane The concurrency organization pane allows the user to be able to specify the problem (for which the user wishes to gene rate source code) in te rms of the terminal patterns of Figure 2-1.

PAGE 36

25 Figure 4-3 Concurrency organization pane The Top Level Organization group box contains three ch eck boxes that allow the user to pick which organizati on best matches that of the pr oblem for which a solution is being generated. The Ordering Structure group box allows for the user to specify the applicable sub ordering which best matches that of his or her problem. In the particular scenario where a pipeline processing pattern is applicable the user ha s the option to select the number of pipeline stages desired in the so lution. The right side of the pane is a text area that displays real-time help for the user. Dependencies and Partitioning Pane The dependencies and partitioning pane allo w the user to select what kind of relationships exist among tasks and also to determine where applicable the type of recursion a specific problem exhibits.

PAGE 37

26 Figure 4-4 Dependencie s and partitioning pane The Task Dependencies group box contains a drop dow n list box that allows the user to select whether the tasks in questi on are dependent or not. If the tasks are dependent the drop down list box within the Dependency Type group box is enabled. This drop down list box allows the user to pi ck whether the dependenc ies are separable or inseparable. The Tree Structure Recursion group box contains a recursion type drop down list that allows the user to select whether or not the recursion exhib ited by the problem is one-way or two-way. The XML Viewer Pane When the required information describing the problem that the user wishes to generate the source code for has been entere d on each of the previous four panes, the Create XML button on the bottom left corner of the application will become enabled.

PAGE 38

27 When the user clicks this button, the XML specification corresponding to the input on all the information panes will be created. The XML specification is displayed in the XML viewer pane as shown in Figure 4-5. Figure 4-5 The XML Viewer Pane Advanced users may copy and paste the specification from the XML viewer pane into any text editor and modify for greater control. The new specification file must be supplied via the command line. Upon creation of the XML documentation, the Generate Source Code button is enabled, the user may click it to create the s ource code in the direct ory specified in the General tabbed pane. Executing from the Command Line In order to generate source code from the command line the user must supply a valid XML specification document. The document may either be generated by hand according to the DTD described in chapter three of this thesis. Users may also generate the specification document using PPPGui a nd then further customize the generated

PAGE 39

28 specification file using any text or XML editor. In other to run the PPPG tool from the command line the user must enter the following at the command prompt: pppgcmdrun The generated files will be stored in the target directory specified in the XML specification file. If a target directory is not supplied, the generated source code is placed in the current working directory.

PAGE 40

29 CHAPTER 5 IMPLEMENTATION DETAILS Chapter 4 presents an overview of PPPG from the user’s perspective. This chapter discusses the underlying details from a programmer’s perspective. Using an example problem, this chapter walks through code generation process and explains the implementation methodologies that are utilized w ithin the process. In addition, the main modules that make up PPPG are discusse d along with their respective functions. A Walk through the Code-Generation Process Consider the example of an applicati on programmer who wishes to develop a parallel/concurrent mergesort procedure for use within his/her particular application. The programmer decides to use the PPPG tool. Afte r careful analysis of the requirements for the procedure, the programmer creates the XM L specification file shown in Figure 5-1. Figure 5-1 Specification file for mergesort procedure The tool begins its work after the XML f ile containing the specifications is passed as an input, either via the command line or through the GUI tool. PPPG attempts to open the specification file, if the file does not exis t, an appropriate error message is generated

PAGE 41

30 and the tool stops execution. However, if the specification file does exist, the file is opened and the XML specification is parsed using IBM’s XML4J XML parser to ensure the validity of the XML. The next step is to ensure that the XML specification document is well formed. This is done by validating th e document against the DTD that is defined for the application. The DTD ensures that th e specifications are in the format required by the application. If this is not the case a me ssage indicating an error is generated and the tool stops execution. If the XML specificat ion is both valid and well formed, the XML parser is used to create a DOM data structure. The DOM data structure presents the XML specification as a tree where each node contains data from the specification document. The next series of steps start with the creation of the Data capsule. The Data capsule is an application specifi c data structure that facilita tes the transportation of data within the application. Upon creation of the data capsule object, the DOM data structure is traversed, and at each node specification information (originally from the user XML specification) is copied into the data capsule object. When the DOM data structure has been traversed and all relevant data copied to the data capsule the ac tual process of code generation begins. Before code generation be gins a new file (name is specified in the specifications by the user) is created by PPPG. The source code will be generated into this file. The generation of code takes plac e as the decision tree shown in Figure 5-2 is traversed in a top down manner. The generate d code at the end of the tree traversal process corresponds to an instan ce of one of the terminal patt erns shown in the diagram. Starting at the top of the tree, PPPG must determine what kind of top-level organization is desired for concurrency. There are three major branches that can be taken from the root of the decision tree. They each corre spond to the types of top-level organization

PAGE 42

31 available. Concurrency can be organized by the ordering of task groups, decomposition of tasks, or by decomposition of data [9]. The information on which type of top-level organization was specified in the XML specifi cations. All specification information is now available in the data capsule object. PPPG gets the top-level information from the data capsule at run time. Source code is ge nerated based on the type of organization the user specified. In the case of our earlier example, merge sort’s concurrency can be organized in terms of task decomposition and thus the second branch is taken. Since there are no commonalities for which code can be generated at this level, boilerplate code indicating the class name and user informa tion is generated as shown in Figure 5-3. Figure 5-2 Decision tree

PAGE 43

32 Figure 5-3 Boilerplate code generated to mergeSort.java file At the first level a decision must be ma de about how the previously selected ordering is structured. For both the second a nd third major branches the ordering can be either linear or recursive. This depends on whether the tasks (branch two) or the data (branch three) is ordere d linearly or recursively. At level one after taking branch one; a decision must be made on whether the ordering is structured regularly or irregularly. PPPG makes this decision based on data from the data capsule. Regular orderings ar e those that do not ch ange during execution of the algorithm, while irregular orderings re fer to orderings that change dynamically during algorithm execution [7]. In our example the merge sort algorithm is organized recursivel y by task. In this particular situation PPPG does not generate code because of inadequate commonalities between recursive and lin early partitioned tasks. On the second level, for branch one the choice (based on data capsule data) of regular ordering corresponds to the pipeline processing terminal pattern, at this point PPPG generates the remainder of the code co rresponding to the afore mentioned pattern. If at the same level and branch the choice of the ordering is irre gular, then the code corresponding to the asynchronous decomposition pattern is generated.

PAGE 44

33 The second major branch (Order by Tasks) is more involved than the other two branches. At the second level within this branch, PPPG must make either of the following choices based on the information in the data capsule. The choice of linear ordering, which indicates that th e tasks are structured as line ar collections, leads to the partitioning intermediate pattern. All programs that have the partitioning pattern as an intermediate pattern share the characteristic that the initial problem can be spilt into tasks. At this point, if linear orde ring is indicated in the data capsule, PPPG generates the code for splitting the initial problem into tasks. At the same level and branch, if the c hoice of recursive ordering was specified by the user, indicating that the tasks are struct ured recursively, we arrive at the tree intermediate pattern. At this point PPPG cannot generate any source code until further distinctions can be made. At level four w ithin the second branch a decision must be made based on whether the tasks are independent of each other or not. If the tasks are independent PPPG arrives at the Embarrassingly Parallel terminal pattern and the rest of the code corresponding to this pa rticular pattern is generated. If the tasks are dependent then PPPG must verify whether the dependenc ies are separable or inseparable between the tasks. If the dependencies are separa ble PPPG generates the source code for the Reduction terminal pattern. In the case that the dependencies are not separable, the source code corresponding to the Shared Memory pattern is generated. At level three still within the second branch, if PPPG has an instance of the tree intermediate pattern, as is the case with the mergesort example, a decision must be made about the nature of the recursion. PPPG must decide whether the r ecursion in one-way or two-way. If the recursion is one -way, source code corresponding to Balanced Tree

PAGE 45

34 pattern is generated. On the other hand if PPPG is dealing with a two-way recursion the Divide and Conquer pattern is generated. In our exam ple, the recursion is two-way and thus code for the divide and conque r terminal pattern is generated. Figure 5-4 Remainder of code generated for mergeSort.java class Since it is now known that the code bei ng generated is an instance of the divide and conquer pattern. The buffer is modified to make the mergeSort class extend the DivideAndConquer class. At this poin t PPPG generates the source code for DivideAndConquer.java The source code generated fo r this class and all other code generated is attached as appendix A. It is important to mention that PPPG provides genericity. Genericity is a generalization mechanism that al lows a single definition to appl y to a whole set of classes with different behaviors. Genericity is th e ability to parameterize modules. It is applicable when the implementation behavior is constant but the data type can change. If the user had supplied a more detailed specifi cation that included the initial, intermediate, and final datatypes, PPPG would have generate d different parameter and return types for the methods shown in Figure 5-4. The datatypes would have changed but the implementation behavior for each of the methods would stay the same.

PAGE 46

35 At the first level within the third major branch PPPG examines the data capsule to see if the data structures are linear or recursive. If PPPG encounters a situation in which the data structures are linear th en source code co rresponding to the Geometric Decomposition pattern is generated. Otherwise, if the data structures are found to be recursive, source code corresponding to the Reference Following pattern is generated. Modules and Class Detail PPPG performs the following tasks. € Validates the XML input specifications and reports errors and warnings where applicable € Completes the specification using de fault settings where necessary € Generates the solution implementation These tasks are implemented as two cons ecutive and separate modules. When PPPG receives the specification in a textual fo rm from the command line it parses the file to transform the data into the DataCapsule representation. If the PPPGUI is used to create the specification the informa tion is directly inserted into a DataCapsule object and the parsing stage is bypassed. PPPG consists of two main modules, the parse and package module and the code generator module. The relationships and in teractions between these modules are shown in Figure 5-4. Parse and Package Module This module as its name implies is re sponsible for readi ng and validating the XML input specifications against the DTD. Af ter validation of the specification, the input data is analyzed and packaged into a data cap sule object. The data capsule object is now ready to be passed to the code generator module.

PAGE 47

36 The Syntax Analyzer object implements the parse and package module. When the syntax analyzer object is instantiate d, it expects an input string containing the filename of the XML input specifications. If the input file can be opened, an instance of an XML parser is created; the parser checks th e input for syntax errors and then validates it against the DTD. If syntax analysis and validation are successful, the parser will create a document object model (DOM) document. Th e syntax analyzer completes its work by iterating through the DOM document, collecting data and storing it in a user defined data structure called the data capsule. Upon co mpletion the data capsule containing the specifications for the program generator is passed to the generator module. Figure 5-4 Structure of PPPG

PAGE 48

37 Figure 5-5 Parse and package module SyntaxAnalyzer Class Detail The SyntaxAnalyzer class contains two very important methods. They are the verify and extractData methods. The verify method is responsible for validating the XML specification and initiating the creation of the DOM document. The extractData method extracts the data from the DOM document and populates the DataCapsule. Datacapsule The data capsule module is a user defined data structure used to store data from the XML input specification. The data capsule allows easie r transportation of data between the two main modules. It not as bulky as the DOM document and allows easier access to the specification data. The data capsule contains fields representing the entities

PAGE 49

38 and their respective attributes as defined in the DTD. For more information on the DTD please see Chapter 3. Figure 5-6 SyntaxAnalyzer UML diagram DataCapsule Class Detail The DataCapsule class contai ns several variables to store specification information. It also provides the generateXml method which is responsible for transforming the current contents of the DataCapsule into its equivalent XML specification. This method is used primarily by PPPGUI. Code Generator Module The code generator module upon receipt of the data capsule begins the work of creating the desired outp ut program based on the data cont ained data capsule object. The information in the DataCapsule usually repres ents a path down the tree given in Figure 52. The CodeGenerator object contains the im plementation of the Code Generator module as described above. The code generator expects a data capsule object and a string containing the path for the destination file wh en it is initialized. The generation process itself involves making decisions at each level of the tree. At each non-terminal tree node, code corresponding to the particular path take n is generated and adde d to the output file until a terminal pattern is reached. Traversing th e tree in Figure 5-2 from the root to any of the leaf nodes generates the code.

PAGE 50

39 Figure 5-7 DataCa psule UML diagram CodeGenerator Class Detail. The CodeGenerator class contains the various methods for generating the different terminal patterns availa ble. It also contains methods to handle generation of either C++ or Java source code.

PAGE 51

40 Figure 5-8 CodeGenerator UML diagram

PAGE 52

41 CHAPTER 6 GENERATED PROGRAMS This chapter focuses on several example programs that were developed based on patterns generated by PPPG. Three sample programs are discussed. These programs illustrate the functionality a nd usability of PPPG and the efficiency of the generated programs. The first program is a concurre nt implementation of the classic mergesort algorithm. The second is an implementation of the game of life and the final program simulates an assembly line. Each of th ese programs and their corresponding base patterns will be discussed in this chapter. Concurrent Implementation of Mergesort The sorting algorithm Merges ort produces a sorted se quence by sorting its two halves and merging them. With a time comple xity of O(n log(n)) mergesort is optimal. In order to generate a concurrent merges ort algorithm using PPPG a valid specification file describing the algorithm was created. For this partic ular instance the specification file contained information about the dataty pe in which the problem instance would be supplied to the program. It also contained in formation about the user defined structure Task that the threads would manipulate while solving the problem. The specification1 file was passed as input into PPPG and an instance of the DivideAndConquer terminal pattern was generated. The file gene rated is shown in Figure 6-1. 1 The complete specification f ile for the concurrent merges ort algorithm can be found in appendix B of this thesis paper.

PAGE 53

42 Figure 6-1 Concurrent MergeSort algorithm The next step is to implement the abstract methods that define how the problem is to be solved. It is important to note that all the details about concurrency and thread scheduling are not visible to the programm er. These details are contained in the superclass DivideAndConquer generated by PPPG. The programmer need only worry about how to implement the methods provided in the generated file. In this particular example the programmer will need to define a new class Task The methods within the Mergesort.java file shown in Figure 6-1. should be implemented as follows, the baseSolve method is responsible for solving an atomic instance of the problem and returning the result a Task object. The baseCase method examines a Task object and returns a true or fa lse value based on whether the Task can be divided into smaller tasks or not. The split method divides a Task object into smaller Tasks and returns and array of Tasks The merge method accepts an array of Tasks and merges them into a single Task

PAGE 54

43 An implementation of the split method is shown in Figure 6-2. The complete implementation of the concurrent Me rgeSort can be found in appendix A. Figure 6-2 Implementation of the split method Assembly Line Simulation This example creates an assembly line simulation called the Math Factory. The math factory performs sequen ce of identical operations on an input number and returns the results after completion. Each unique ope ration represents a stage, and the stages together form a pipeline. The key here is to have the maximum number of stages executing concurrently at any given time during program execution. To accomplish this task, a specification2 file containing details about th e initial problem representation, classes representing input into the factory, th e number of stages and other information 2 The complete specification file for th e math factory simulation can be found in appendix B of this thesis paper.

PAGE 55

44 concerning the problem was created. This sp ecification was passed as input to PPPG and an instance of the PipelineProcessing pattern was generated. A portion of the generated program is shown in Figure 6-3. Figure 6-3 MathFactory code snippet. In order to complete the Math factor y, the programmer needs to create an implementation of the Event class that was suppl ied as the intermediate data type in the XML specification file. In the MathFact ory class two methods will need to be implemented. The split method is responsible for divi ding the initial problem into instances of the intermediate datatype and th en placing them into a shared queue object.

PAGE 56

45 This method returns a shared queue containing the objects to be worked on my individual threads. The complete method should contain any opera tions to be performed after processing of the Event object. Such processing may include but is not limited to displaying the end result after all pipeline stages have been cleared. The Math Factory class also contains a Stage object. This obje ct contains all the operations corresponding to the different stages of the pipeline. A code snippet from the inner class Stage is shown in Figure 6-4. Figure 6-4 Inner Class Stage code snippet Implementation of the Game of Life The game of life is an example of cell automaton, which is any system in which rules are applied to cells and th eir neighbors in a regular grid. Life is played on a grid of square cells, like a chess board but extending infinitely in ev ery direction. A cell can be live or dead. A live cell is shown by putting a marker on its square. A dead cell is shown by leaving the square empty. Each cell in the grid has a neighborhood consisting of the

PAGE 57

46 eight cells in every direction including diagona ls. The rules of the game of life are as follows: For a space that contains a live cell: € Each cell with one or no neighbor s dies, as if by loneliness. € Each cell with four or more nei ghbors dies, as if by overpopulation. € Each cell with two or th ree neighbors survives. For a space that is empty: € Each cell with three ne ighbors becomes populated. To continue our implementation of the game of life, we need to create a specification file describing the nature of the problem and details specific to this particular implementation. A completed specification is prov ided in appendix B. Based on the input to PPPG an instance of the EmbarrassinglyParallel pattern was generated. The generated pattern is shown in Figure 6-5. The generated file shown above shield s the programmer from the details of concurrency. The programmer need only concern themselves with the details of the problem solution alone. In the game of life ex ample the initial problem is represented in a multi dimensional array. The split method is responsible for dividing up portions of the array into Task objects which are then insert ed into a shared queue. The processResults method will retrieve objects from the result queue and possibly update the display or perform any other similar actions. The taskProcessing method will process a Task object and update the result queue. In this chapter we have examined th ree programs created based on patterns generated by PPPG. These patterns have enab led the programmer to focus on the task of what the program needs to do, rather than worry about details on how to make the

PAGE 58

47 program run concurrently and verifying thread safety and other related issues. By using PPPG to generate concurrent/p arallel versions of the progr am a lot of development time is saved. Figure 6-5 Game of life

PAGE 59

48 CHAPTER 7 CONCLUSION From the onset of this research proj ect, the desired purpose was to create a program generator that enables the us er to create portable and efficient parallel/concurrent programs while minimizing overall development time. This research project has been able to accomplish these goals This chapter highlights the features of PPPG and their significance to end-users. This chapter also discusse s some limitations of PPPG and corresponding suggestions for improvement. Summary of Work Done A program generator is very ineffective if there is no way for the user to specify what kind of programs are to be generated. Therefore, the need arose to create a specification language that can adequately and robustly communicate the details of the user’s problem in a manner that the PPPG tool can understand and generate the appropriate source code to solve the problem The decision was made to use XML. A DTD to represent the algorithm design space of Figure 2-2. was created to help the user map their problem to one of the terminal patte rns within the domain. This DTD not only helped describe the user’s problem but wa s used to constrain and validate input XML specifications into the PPPG tool. The creation of the program generato r involved developing several modules responsible for parsing and valid ation of the input specification, extracting the data from the specification, and generating the appropria te terminal pattern corresponding to the information obtained from the user. A signi ficant amount of development time went into

PAGE 60

49 the creation of the Asynchronous Decomposition Divide and Conquer Embarrassingly Parallel Pipeline Processing Protected and Separable Dependencies terminal patterns, as the patterns had to be initially created by hand before automati ng their creation using PPPG. The development of the PPPG was completed with the creation of a graphical tool that simplifies the specification creation pr ocess and removes the burden of specification correctness from the user. This tool also permitted code generation directly from graphical interface. Future Work While this research effort has achieved the initial goals of simplifying the creation of parallel programs, and por tability of the generated program, there are some improvements that can be made to increase th e functionality and usab ility of the system. Two of the terminal patterns within the algorithm structure design space are not included in this initial version of PPPG. Since this work is based on ongoing research, enough information on the Reference Following and Balanced Tree terminal patterns were not available at the time of development. As research uncovers more information about these patterns and their implementati ons, adding the pattern implementations to PPPG will provide completeness and allow the user to be able to gene rate a broader range of parallel programs. With several of the patterns generated by PPPG, if information about the specific platform on which the generated program will used is made available, optimizations may be made to make the generated program more efficient by generating a more specialized version of the given pattern. It is however important to not e that while any such change

PAGE 61

50 may increase efficiency, the portability of th e generated source code may be significantly affected. An added suggestion is to include functiona lity that permits PPPG to generate its target programs in programming language s other than the Java language. Such functionality will give the user freedom to ge nerate their solution in languages that they may be more familiar with. This functi onality while increasi ng usability will add additional complexity to the generated progr ams and greatly decrea se portability. Using the Java programming language for the genera ted programs provides a language with inbuilt multithreading and allows the JVM to handle thread scheduling issues. Not all programming languages support built-in multithre ading and thus PPPG will have to use operating system function manually and may also have to worry about thread scheduling issues, thus greatly increasing the co mplexity of the generated programs. Finally, while PPPG provides genericity, th ere are specific situations in which a user defined class may need to be cast into a primitive type or vice-versa. Such situations currently require that the progr ammer manually modify the generated code to ensure that these type conversions do not result in co mpilation errors. Improvements may be made so that this sort of occurrences can be eff ectively handled within the program generator.

PAGE 62

51 APPENDIX A EXAMPLE PROGRAMS SOURCE CODE LISTINGS Source Listing for MergeSort. java ( Pre Implematation) package MergeSort; public class MergeSort extends DivideAndConquer { static int SPLIT_SIZE = 2; public Task[] split ( Integer [ ] problem ) { } public Integer [ ] merge ( Task [] solutions ) { } public boolean baseCase ( Task p ) { } public Object baseSolve ( Task p ) { } } Source Listing for MergeSort.java (postimplementation) public class MergeSort extends DivideAndConquer { static int SPLIT_SIZE = 2; public Task[] split ( Task problem ) { Task [ ] ret_arra y = new Task [SPLIT_SIZE]; // pick pivot int mid_point = problem.myArray.length / SPLIT_SIZE; int end_point = problem.myArray.length 1; Integer [] temp1 = new Integer[mid_point]; Integer [] temp2 = new Integer[end_point+1-mid_point];

PAGE 63

52 for (int i = 0; i < mid_point; i++) temp1[i] = problem.myArray[i]; for (int i = mi d_point; i <= end_point; i++) temp2[i-mid_point] = problem.myArray[i]; ret_array[0] = new Task (temp1); ret_array[1] = new Task (temp2); return ret_array; } public Task merge ( Task [] solutions ) { //return new Task (); // basic case when even int tot_elem =0, ret_index=0, first=0, scnd = 0; int num_elem = solutions.length; for ( int i = 0; i < num_elem;++i ) tot_elem += solutions[i].size; Integer [ ] ret = new Integer[tot_elem]; while ( first < so lutions[0].myArray.length || scnd < solutions[1] .myArray.length ) { if ( first < solutions[0].myArra y.length && scnd < soluti ons[1].myArray.length) { if (solutions [0].myArray[first].intValue() < solutions[1].myArray[scnd].intValue()) ret[ret_index++] = solutions[0].myArray[first++]; else ret[ret_index++] = solutions[1].myArray[scnd++]; } else { if (scnd == solutions[ 1].myArray.length) // sec array finished ret[ret_index++] = solutions[0].myArray[first++]; else if ( first == solutions[0].myArray.length) ret[ret_index++] = solutions[1].myArray[scnd++]; } // end else } // end while return new Task (ret); } public boolean baseCase ( Task p ) {

PAGE 64

53 if (p.myArray.length == 1) return true; else return false; } public Task baseSolve ( Task p ) { return p; } public static void main(String [] args ) { Task probtask; if ( args.length != 0){ Integer [] numbers = new Integer [args.length]; for ( int i = 0; i < args.length; i++ ) numbers[i] = new Integer ( args[i]); probtask = new Task(numbers); } else { Integer [] prob = {new Integer(13), new Integer(6), new Integer(4), new Integer(14), new Integer(3), new Integer(12), new Integer(11), new Integer(7), new Integer(15), new Integer(9), new Integer(16), new Integer(5), new Integer(2), new Integer(1), new Integer(8), new Integer(10)}; probtask = new Task (prob); } MergeSort x = new MergeSort(); Object y = x.solve (probtask); System.out.print(y); } } Source Listing for DivideandConquer.java import edu.ufl.cise.joladele.pppglib.*; public abstract class DivideAndConquer { public abstract Task[] split ( Task problem ); public abstract Task merge ( Task [] solutions ); public abstract boolean baseCase ( Task p ); public abstract Task baseSolve ( Task p ); public Object solve ( Task p ) { if ( baseCase (p)) return baseSolve(p); else {

PAGE 65

54 Task [] subproblems = split (p); int N = subproblems.length; Task [] subsolutions = new Task [N]; Barrier b = new Barrier(N + 1); // start thread s to solve subproblems for ( int i = 0; i < N; i++ ) (new solverThread(b, i, subpr oblems, subsolutions)).start(); // wait for all subsolutions to be completed try { b.barrier(); } catch ( InterruptedException e ) { ; } // merge all subsolutions and return result return merge ( subsolutions ); } } class solverThread extends Thread { Barrier passed_barrier; int number; Task [] subproblems; Task [] subsolution; public solverThread() { passed_barrier = null; } public solverThread(Bar rier b, int num, Task [] subp, Task [] subsol) { passed_barrier = b; number = num; subproblems = subp; subsolution = subsol; } public void run () { subsolution[number] = (Task)solve(subproblems[number]); try { passed_barrier.barrier(); } catch ( InterruptedException e )

PAGE 66

55 { ; } } } }

PAGE 67

56 APPENDIX B SPECIFICATIONS FOR EXAMPLE PROGRAMS Specification for MergeSort Example two way . Specification for Assembly Line Simulation Specification for Game of Life

PAGE 68

57


PAGE 69

58 LIST OF REFERENCES [1] S. Bromling, S. MacDonald, J. Anvik, J. Schaeffer, D. Szafron, and K. Tan, "Pattern-based Parallel Programming." Proceedings of the 2002 International Conference on Parallel Processing (ICPP2002), Toronto, Canada, August 2002. [2] C.J. Cleaveland. “Program Generato rs with XML and Java.” New-Jersey: Prentice-Hall, 2001. [3] K. Czarnecki, and U.W. Eisenecker. “Generative Programming Methods, Tools, and Applications." New York: Addison-Wesley, 2000. [4] The Hillside Group. "Patterns Home Page." October 2001. Accessed May 2002. http://www.hillside.net/ patternsnavigation.htm [5] J.F. Jaja. “Fundamentals of Parallel Algor ithms.” In Albert Y. H. Zomaya, editor, Parallel and Distribu ted Computing Handbook New York: McGraw-Hill, 1995, 333-354. [6] D. Lea. “Concurrent Programming in Java: Design Principles and Patterns.” Boston: Addison-Wesley, 2000. [7] B.L. Massingill, T.G. Mattson, and B. A. Sanders. “A Pattern Language for Parallel Application Programming.” Proceedings of the Sixth Pattern Languages of Programs Workshop (PLoP 1999), Monticello, Illinois, August 1999. [8] B. Meyer. “Genericity versus Inheritance.” Proceedings of the first conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 1986) Portland, Oregon, November 1986. [9] L. Patterson. “Using the IBM XML Pa rser (XML4J): Find & Replace Elements in an XML Document.” January 2000. IBM Corporation. Accessed May 2002. http://www.ibm.com/servers/eserver/iser ies/developer/java/xml/xml_parser2.html [10] S. Sarkar, and C.J. Cleaveland. “C ode Generation using XML based Document Transformation.” November 2001. The Middleware Company. Accessed July 2002. http://www2.theserverside.com/res ources/article.jsp?l=XMLCodeGen [11] Gary Shute. “Table Driven Design.” Accessed May2002. http://www.d.umn.edu /~gshute/ softeng/table-driven.html

PAGE 70

59 [12] T. Wilmarth. “PPL:Load Balancing.” Accessed June 2002. http://charm.cs.uiuc.e du/ppl_research/ldbal/ [13] World Wide Web Consortium. “W3C Document Object Model.” March 2002. W3C. Accessed June 2002. http://www.w3c.org/DOM

PAGE 71

60 BIOGRAPHICAL SKETCH Jean-David Oladele was born June 25, 1976 in Lyon, France. He received his Bachelor of Engineering degree in computer engineering from the University of Florida, Gainesville, Florida in May 1999. He worked as a junior consu ltant for Software Architects Inc. in Tampa, Florida, for about a year and a half. In the fall of 2000, he began graduate study in the Department of Computer and Information Science and Engineering at the University of Florida for the Master of E ngineering degree in computer engineering. He r eceived the degree in December 2002.


Permanent Link: http://ufdc.ufl.edu/UFE0000583/00001

Material Information

Title: Implementation of a parallel program, program generator
Physical Description: Mixed Material
Creator: Oladele, Jean-David G. ( Author, Primary )
Publication Date: 2002
Copyright Date: 2002

Record Information

Source Institution: University of Florida
Holding Location: University of Florida
Rights Management: All rights reserved by the source institution and holding location.
System ID: UFE0000583:00001

Permanent Link: http://ufdc.ufl.edu/UFE0000583/00001

Material Information

Title: Implementation of a parallel program, program generator
Physical Description: Mixed Material
Creator: Oladele, Jean-David G. ( Author, Primary )
Publication Date: 2002
Copyright Date: 2002

Record Information

Source Institution: University of Florida
Holding Location: University of Florida
Rights Management: All rights reserved by the source institution and holding location.
System ID: UFE0000583:00001


This item has the following downloads:


Full Text











IMPLEMENTATION OF A PARALLEL PROGRAM, PROGRAM GENERATOR


By

JEAN-DAVID G. OLADELE

















A THESIS PRESENTED TO THE GRADUATE SCHOOL
OF THE UNIVERSITY OF FLORIDA IN PARTIAL FULFILLMENT
OF THE REQUIREMENTS FOR THE DEGREE OF
MASTER OF ENGINEERING

UNIVERSITY OF FLORIDA


2002




























Copyright 2002

by

Jean-David G. Oladele






















Dedicated to Renee Williams.















ACKNOWLEDGMENTS

I thank my Lord Jesus Christ for his mercy and strengthening me in all that I do. I

would like to express my sincere gratitude to my advisor, Dr. Beverly Sanders, for

serving as the chairperson of my committee. Her suggestions and support went a long

way in making this thesis a reality. I would also like to thank Dr. Hammer and Dr.

Wilson for their commitments.

I thank Alejandro Pauly for his examples that provided much needed insight

during the early stages of my work. In addition I am grateful to all my friends for their

support and encouragement. Finally, I would like to express my love and gratitude to my

family for their support and dedication.
















TABLE OF CONTENTS
page

A C K N O W L E D G M E N T S ................................................................................................. iv

LIST OF TABLES ........... ........ ..... .. .............. ............ .. ........... vii

LIST OF FIGURES ......................... .. .. ............... ....... ............. ..... viii

A B ST R A C T .......... ..... ...................................................................................... x

CHAPTER

1 INTRODUCTION .............. .....................................................1.. 1

2 BA CK GROUND ......................... ............................ .... .............. ....

Program Generators ........................................................... ...... .......... 4
The 0 0 -D riven Style .................. ..................................... .. .......... 5
Code-D riven Style................ .................... .. ...... .... .......... .............. 6
Table-D riven Style ................................................................... ... .. .......... 6
Patterns, Pattern Languages and Parallel Patterns...................................................... 7
Extensible Markup Language and Data Type Definitions.................. .............. 10
D ocum ent Object M odel........................................................... ... ........... ... 10

3 THE PPPG U SER SPECIFICATION S .................................. ................................... 11

The design.space Elem ent................... ........................................ .......................... 12
The task.group Elem ent ....................................................... ..... .............. 13
The grp.struct Elem ent ............................................... .. ...... ... .......... .. 13
The grp.sub.struct Elem ent .................................... ............................................... 13
The task.decom position Elem ent.................. ............. ......................... .............. 14
The task.relationships Elem ent .............. ......... ................................. .............. 14
The dependency.type Element .............. ..... ........ ............................. 14

4 U SIN G THE PPPG TO OL .................................................. .............................. 22

The PPPG U ser Interface .......................................................................... .............. 22
G general Inform ation Pane ......................................................... .............. 22
D atatypes Pane .................................... .............................. ........ 23
Concurrency O organization Pane ........................................ ....................... 24
Dependencies and Partitioning Pane .............................................. ........... 25


v









The X M L V iew er Pane ....................................................................... 26
Executing from the C om m and Line................................................... .... .. .............. 27

5 IMPLEMENTATION DETAILS ..................................................... .....................29

A Walk through the Code-Generation Process.......................................................... 29
M o du les an d C lass D detail ............................................................................................. 3 5
Parse and Package M odule.................... ................................ .......................... 35
D ata c a p su le ................................................................................................. 3 7
Code G enerator M odule.................... .................................... .......................... 38

6 G EN ER A TED PR O G R A M S....................................... ............................................41

Concurrent Implementation of Mergesort ........................................... ............. 41
A ssem bly L ine Sim ulation...................................................... .......................... 43
Im plem entation of the G am e of Life ........................................ ....................... 45

7 CONCLUSION ............... ........................................................ 48

Sum m ary of W ork D one .............................................................................. .. ...... 48
F u tu re W o rk ........................................................................................ 4 9

APPENDIX

A EXAMPLE PROGRAMS SOURCE CODE LISTINGS ..........................................51

B SPECIFICATIONS FOR EXAMPLE PROGRAMS ................................................56

L IST O F R E F E R E N C E S ........................................................................ .....................58

B IO G R A PH IC A L SK E TCH ..................................................................... ..................60
















LIST OF TABLES

Table page

3-1 design.space Elem ent sum m ary......... .................................................. ............... 16

3-2 task.group E lem ent sum m ary ........................................... ........................................ 17

3-3 grp.struct Elem ent sum m ary................................................ ............................... 18

3-4 grp.sub.struct Element summary .............................................................................18

3-5 task.decomposition Element summary ....................... ... ............ ...............19

3-6 task.relationships Elem ent sum m ary .................................. ............................... ....... 19

3-7 dependency.type Elem ent sum m ary .................................... ............................. ........ 20
















LIST OF FIGURES

Figure page

2-1 A lgorithm structure decision tree ............................................ ............. .............. 8

3-1 T he design .space E lem ent ...................................................................... ..................16

3-2 T he task .group E lem ent......................................................................... ........ .......... 17

3-3 The grp.struct Elem ent ................................. .. ............... ...............17

3-4 The grp.sub.struct Elem ent.......................................................................... 18

3-5 The task.decom position Elem ent.............................................................................. .... 18

3-6 The task.relationships E lem ent.................................................................................... 19

3-7 The dependency.type Elem ent.............................................. .............................. 19

3-8 The design.space elem ent code snippet................................... .................. ... ......... 20

3-9 The task.group elem ent code snippet ........................................ ........................ 20

3-10 The grp.struct elem ent code snippet............................................................ ........... 20

3-11 Com plete specification docum ent ........................................ .......................... 21

4-1 G general inform action screen ................................................. ............................... 23

4-2 D atatypes w window .............................................. .. .. .......................24

4-3 Concurrency organization pane ......................................................... .............. 25

4-4 D ependencies and partitioning pane........................................ ........................... 26

4-5 T he X M L V iew er P ane.......................................................................... ...................27

5-1 Specification file for mergesort procedure......... ...... ................ ..............29

5-2 D decision tree .................. ............... ................. ................... 31

5-3 Boilerplate code generated to mergeSort.java file ........................................ ...32









5-4 Remainder of code generated for mergeSort.java class ...........................................34

5-4 Structure of PPPG .................. ............... ................. .......... .. ............. 36

5-5 P arse and package m odule...................................................................... ..................37

5-6 SyntaxA nalyzer U M L diagram ........................................................... .....................38

5-7 DataCapsule UM L diagram ..................................................................... 39

5-8 CodeGenerator UM L diagram ....................................................... ............... 40

6-1 Concurrent MergeSort algorithm....... .............................................. .................42

6-2 Implementation of the split method ............ ..... .............................. 43

6-3 M athF actor code snippet. ...................................................................... ..................44

6-4 Inner C lass Stage code snippet .......................................................................... ... ... 45

6-5 G am e of life ..............................................................................47

































ix















Abstract of Thesis Presented to the Graduate School
of the University of Florida in Partial Fulfillment of the
Requirements for the Degree of Master of Engineering

IMPLEMENTATION OF A PARALLEL PROGRAM, PROGRAM GENERATOR

By

Jean-David G. Oladele

December 2002


Chair: Dr. Beverly Sanders
Department: Computer and Information Science and Engineering

Efficient parallel programs and algorithms are difficult to write. Parallel

programs present the programmer not only with the questions of what needs to be done,

and when an operation takes place, but also where the operation needs to occur. A large

number of parallel programs are dynamic in nature and do not provide a regular structure

for parallelization. The programmer must provide complex algorithms for scheduling,

load balancing, and rebalancing in order for these programs to perform efficiently in

parallel.

This thesis presents the design and implementation of the PARALLEL

PROGRAM, PROGRAM GENERATOR (PPPG). PPPG reduces the complexity of

creating parallel programs. PPPG generates efficient and portable parallel patterns for

different classes of the parallel program domain. The patterns generated are dependent

on Extensible Markup Language (XML) input specifications. The input specifications

may be supplied as a raw XML file or generated from a series of responses by the user.









The output patterns are provided in the Java language to allow for portable parallel

programs. The Java Virtual Machine (JVM) is responsible for processor scheduling.














CHAPTER 1
INTRODUCTION

Parallel programming involves breaking an algorithm or data into parts. These

parts are then distributed as tasks for simultaneous execution over multiple processors or

concurrent execution over a single processor. The motivation for parallel programming

is that a program being executed over multiple processors might execute faster than it

would during serial execution on a single processor. Parallel programming involves

design steps to assign threads, tasks, or processes to physical processors) for execution

[6]. Creating and writing parallel programs is often very difficult and time consuming.

The programmer must deal with issues of correctness and efficiency, which become more

complex and magnified in a parallel environment. Dependencies among concurrent

threads of execution must be carefully managed to ensure a consistent result.

The aforementioned difficulties necessitate a tool that can generate a shell

program or template that makes writing parallel programs easier for the developer. This

tool will handle all the concurrency and performance issues. The generated shell program

is essentially ready for use. The developer need only modify the template by adding

application-specific functionality, and the program is ready for use.

This thesis describes the design and implementation of a program generator that

provides a template for the creation of efficient and portable parallel programs. The

program generator is referred to as the Parallel Program, Program Generator (PPPG).

A program generator is a tool that automates the creation of programs from

precise descriptions of syntax and desired behavior [1]. Program generators provide an









effective way to automatically create variant programs within the same family. They

allow for consistency of commonalities within a particular application domain. When

there is sufficient information about how a program will be used, program generators

construct optimized and robust code.

The PPPG generates shell programs for different classes of the parallel program

domain. The generated shell/skeleton programs are based on the results of ongoing

research at the University of Florida. This research focuses on developing pattern

language for parallel application programming. Patterns are defined as representations of

reusable object design. Patterns and Pattern languages are ways to describe best practices

and good designs, and to capture experience in a way that allows others to reuse this

experience [4]. Parallel patterns can be used to design high quality software because the

pattern language acts as a guide through application design and the development process

[7].

The PPPG requires information from the user in order to determine the

characteristics, behavior, and class of parallel program to be generated. This information

is called the input specification. The input specification for PPPG is represented using

the Extensible Markup Language (XML). The XML is a cross-platform, software and

hardware-independent language for data description and information transmission. The

XML is used to help accomplish the PPPG's goal of portability. The information

representing the parallel programming domain is called the Document Type Definition

(DTD). The DTD lists all the element types and attributes and their constraints as used in

the input specification. A valid XML input specification document must meet the

conditions imposed by the DTD.









The skeleton program generated by PPPG is written in the Java programming

language. The main advantage of having the code generated in Java is portability over

different and diverse operating environments. An added benefit is that the user need not

worry about scheduling issues; the Java Virtual Machine (JVM) will handle this.

Using XML and Java, a program generator that is efficient and portable can be

created. This development tool takes much of the burden of designing and implementing

parallel programs off of the user. The remainder of this thesis paper describes the

implementation of such a tool. Chapter 2 gives background information on the

technologies behind PPPG. Chapter 3 discusses the DTD for the domain and how it

constrains the XML specification. Chapter 4 provides a high-level view of the PPPG tool

from the user's perspective and addresses the effective use of the tool. Chapter 5 deals

with implementation details and issues, from a designer's point of view. Chapter 6

discusses sample programs based on patterns generated using PPPG. Chapter 7 gives

conclusions and suggestions for future additions and improvements.














CHAPTER 2
BACKGROUND

This chapter presents an overview of the core development technology used to

implement PPPG. This includes a brief review of program generators, patterns and

pattern languages, the extensible markup language (XML), and data type definitions

(DTD). This chapter also discusses parallel patterns and the parallel pattern language

developed at University of Florida (UF).

Program Generators

A program generator is a software tool that creates the source code for another

computer program. The description of what the generated computer program should do

is supplied to the program generator as a specification file. Data about the program to be

generated is supplied to the program generator, which after analyzing and transforming

the data generates the desired program. Some popular examples of program generators

are parser generators such as yacc, GUI builders, and visual programming tools.

Using program generators can greatly increase productivity. One reason for this

is that specifications are usually easier to create, edit, and verify correctness than the code

that implements the specifications. This is often the case because implementation often

requires specialized knowledge and techniques that are very time consuming. These

techniques are usually not required to understand and create the specifications. When a

program generator is being used the programmer need only be concerned with the

specification; without the program generator, a significant amount of time would also

have been spent on implementation.









Program generators also increase productivity because they can easily be used to

generate variant programs within the same problem domain or program family. Program

generators can generate other files, such as documentation about the software, user

documentation, test scripts and more. They can also resolve the consistent-update

problem. During software maintenance or update, fixing an error may often set off a

chain of other errors within the software product. This occurs often in situations where

the change is not updated consistently across the software product. When using a

program generator, the specification need only be updated and the program can be

regenerated. Doing this will ensure consistent update across the application. In cases

where information on how the generated program will be used is available, program

generators can be specifically customized to generate optimized code.

There are 3 main styles of programming used in program generators. These styles

relate directly to the type of code generated by the program generator. The three

approaches are

* 00-driven
* Code-driven
* Table-driven

The 00-Driven Style

The 00-Driven approach uses standard object oriented techniques such as

inheritance, interfacing, and message passing, for organizing the structure of the

generated program [2]. Related variables and methods are bundled to create specific

objects. Data from specifications are inserted where needed and Classes are created for

attributes where needed. This approach is based on stacking object-oriented layers of









abstraction. Each layer contains a number of object classes where each top layer refines

the layer below it by adding new classes and new methods to existing classes [3].

This particular style is usually difficult to create and is less efficient than the

code-driven style. The advantage of this style is that it allows for separation of concerns

based on specific performance and design goals.

Code-Driven Style

This is the most natural and simplistic approach to program generation. In this

method the code is simply generated where it is needed without any concerns about

program structure but focuses on simplicity and efficiency of code generation [2]. In this

method data from the specification is simply embedded where needed.

Table-Driven Style

Table-driven design is a software engineering methodology that attempts to

simplify and generalize by separating program control variable and parameters from the

program code and placing them in external tables. Design objectives include an emphasis

on modularity and decoupling program control data from application logic. Applications

are made more flexible by postponing the time when control values and rules are bound

to the processes they direct [11].

This approach to program generation emphasizes the separation between data and

the code that performs the generation. Data from the specifications are stored in the

tables and other data structures. The code simply refers to the tables when the data is

needed rather than embedding the data directly into the code [2].

PPPG uses a hybrid of the 00 and Code-driven approaches for program

generation. Combining these 2 approaches results in simple and efficient code generation

with attributes represented as objects.









Patterns, Pattern Languages and Parallel Patterns

Patterns are reusable representations of good design, which assist programmers in

the development of good quality software. A collection of patterns is referred to as a

pattern language. Pattern languages can be used as a guide from problem specifications

to complete design [7].

PPPG will generate source code based on parallel patterns from ongoing research

at the University of Florida. The research focuses on developing a pattern language for

parallel application programming. The pattern language is to be used by application

programmers who are interested in designing programs that will execute in parallel. The

pattern language is organized around the following design spaces:

* Finding concurrency
* Algorithm structure
* Supporting structures
* Implementation mechanisms

This thesis focuses on patterns from the algorithm structure design space. This

space deals with methods for exploiting concurrency. The patterns within this space are

organized by means of the decision tree shown in Figure 2-1.

Starting at the root of the tree the program generator makes decisions based on the

input specification and generates one of the 9 terminal patterns. The terminal patterns are

discussed below:

Pipeline Processing. This pattern is used in situations where the data requires a number

of basic operations to be performed in sequence. The operations may be regarded as

stages or stops within a pipeline, where all the stages have the potential of executing

concurrently. At each pipeline stage an operation is performed and then the data moves

on to the next sequential stage. A good example of pipeline processing is an assembly










line at an electronics manufacturer. An unfinished VCR or DVD player may go through

go through different line stages before completion. At each stage the same operation is

performed over and over again.

Start


,rganaeB yld.erinIg Oqi&aLmByTa51 OigBayByData


Regula? I~negl Linea? Recunive? Lir? Reurive?


Pipelin- Asyrin-=us Paritig e Geonric Refere
Pimcessing |Decomposition --- ----_ Decomposition Following


Inlependerd? Dependert? OrF



EnIanas1uily Sepakble Irepablek Balared DivideAr1
Paxallil | Depeenaes? Depndenries? Ime I Coquer

DecisionPoirt t
Reductin 11 SharedMFIenimiy DeonPc
-Indiate Pattefrn

TeminalPattem


Figure 2-1 Algorithm structure decision tree[7]

Asynchronous Composition. This pattern is applicable in situations where units may

interact with each other in a random non-specific manner.

Embarrassingly Parallel. The embarrassingly parallel pattern is applicable in situations

where various units can operate without any interaction. This pattern usually involves the

concurrent execution of independent units. This pattern shows how to organize such

units so that they may execute in an efficient manner.

Reduction. The reduction pattern is used in situations where dependencies between tasks

can be removed based on whether the global data can be copied to individual tasks and









partial results stored in these tasks can be recombined to form a global solution. This

pattern represents the class of problems in which the following issues can be separated.

* Allocating the tasks among the processors so the computational load is evenly
distributed.
* Managing the dependencies between tasks so that if multiple tasks update the same
data structure, these updates do not interfere with each other.

Shared Memory. The Shared Memory pattern is used in situations where dependencies

between tasks cannot be removed. The two main challenges that this pattern helps the

programmer deal with are, the partitioning of tasks amongst units of execution in such a

manner that the computation load on the processors) is evenly distributed, and the

management of any dependencies that may exist between tasks.

Balanced Tree. This pattern applies to problems in which a balanced tree can be built on

the input elements. The pattern will allow the tree to be traversed in forward and

backward directions while computing and storing information at each internal node [3].

Divide and Conquer. This pattern applies to problems where the input can be partitioned

into individual tasks. Each of these tasks can be solved recursively and in parallel

(concurrently) and the solutions of the different sub problems can be merged into the

solution for the original problem.

Geometric Decomposition. This pattern is applicable when the initial problem can stored

in a data structure which can be broken down into separate pieces. The concurrency is

achieved based on parallel updates of the individual pieces. When any piece is updated

data is required from all the other pieces.

Reference Following. This pattern is used for parallel applications in which an

apparently sequential operation on a recursive data is reworked to make it possible to

operate on all elements of the data structure concurrently [7].









Extensible Markup Language and Data Type Definitions

Extended Markup Language (XML) provides a way to define, manipulate,

transform and transport data over multiple platforms. XML provides a way to define an

arbitrary structure for documents. It has the advantage of keeping structure and

presentation information separate. This in turn leads to more flexible and thus more

valuable documents.

There are two types of correct XML documents, valid XML documents and well-

formed XML documents. A well-formed XML document contains just the needed

information. They do not spell out their own rules but simply follow the general XML

rules. Valid XML documents on the other hand are self-describing and contain or

provide a link to information about the documents structure and contents. These

documents require a document type description (DTD). The DTD constrains the XML

document for the application program that is to process the XML.

Document Object Model

The document object model (DOM) is a W3C specification described as follows:

The Document Object Model is a platform- and language-neutral interface that
will allow programs and scripts to dynamically access and update the content,
structure and style of documents. The document can be further processed and
the results of that processing can be incorporated back into the presented
page[13].

The DOM provides standard interfaces to allow for programmatic access to the

contents of an XML document. An XML document is represented as a tree data structure

in which the nodes represent portions of the document. Using DOM, specific

information can be retrieved from the XML document.














CHAPTER 3
THE PPPG USER SPECIFICATIONS

In order for PPPG to create useful and valuable programs for the user, there must

be a means by which the user can clearly describe the characteristics and functionality of

the program to be generated. The user must be able to easily and unambiguously

communicate what kind of program is needed and the program generator must be able to

understand the users' description and generate the correct program. XML is used to

create a specification language that adequately addresses the aforementioned goals. The

rest of this chapter will focus on the XML that specifies the program to be generated and

the DTD that describes and constrains it.

The primary goal of the specifications is to help the user describe his/her target

program in terms of one of the terminal patterns shown in Figure 2-1. In other words, the

specification language fits the user's initial problem to the closest related terminal

pattern. To adequately express what kind of program is to be generated the programmer

must be able to answer the following questions about their problem:

* What kind of top level organization is desired for concurrency?
* What kind of structure does the top-level organization possess?
* Do any dependencies exist amongst tasks or task groups?

Let us now examine the individual elements and their corresponding attributes

that make up the document type description for the PPPG specifications. This document

type description will be referred to as the design space DTD.









The design space DTD contains the following elements in hierarchical order:

* design.space
* task.group
* grp.struct
* grp.sub.struct
* task.decomposition
* task.relationships
* dependency.type

The design.space Element

The design.space element serves as the root element for the design space DTD.

Every other element is a descendant of this element. The design.space element has five

attributes and one sub element. The attributes are listed below:

* Classname. This particular attribute represents the name of the Java class for which
code will be generated. This is a required attribute and must be provided in the
specification document. The required data type for this element is string.

* Sourcepath. This attribute represents the target directory in which the generated
code should be stored. This attribute is optional. If it is not provided the generated
code will be stored in the directory PPPG is being executed in. The required data
type for this attribute is string.

* Units. This attribute indicates the number of units of execution that the user wants
the generated program to use in the solution. This attribute is optional. If not
specified a default value of three units is used. The required data type for this
attribute is the primitive type int.

* Initdatatype. This attribute should contain the data type of the initial problem. This
is an optional attribute and if not supplied the default data type Object is used. This
attribute should be specified as a string.

* Findatatype. This attribute indicates the data type in which the user expects the
solution to the problem to be stored. As in the case of the previous attribute,
findatatype is also optional and a default data type of Object is assumed when the
attribute is missing. This attribute should be specified as a string.

The design space element must contain an instance of the task.group element. A


diagram of the design.space element is shown in Figure 3-1.









The task.group Element

The task.group element captures information about the top-level organization of

the problem to be solved. It has two attributes and one sub-element. The attributes are

described below:

* Name. This attribute should contain the name of the top-level organization for the
problem. There are three acceptable values for this attribute. The values are
Ordering, Tasks, and Data. This is a required attribute and must be provided in the
specification document. The required data type for this element is string.

* Datatype. This attribute should contain the data type of the sub-problems that the
initial problem will be broken down into. This attribute is optional. If the attribute
is not supplied the data type Object is used. This attribute should be specified
within specification document as a string.

The task group element requires a grp.struct sub-element.

The grp.struct Element

The grp.struct element helps to capture information about the underlying structure

of a given top-level organization. It allows the user to provide information on how a

problem with a given organization orderingss, tasks, or data) is composed. It consists of

two attributes and a required sub element. The attributes are shown below:

* Name. This attribute contains the type of underlying structure for a specific top-
level organization type. If the top-level organization is by Ordering the possible
values are Regular or Irregular. For any other valid top-level organization the
valid values are either Linear or Recursive. This attribute is required and must be
specified as a string.
* Numstages. This attribute is only applicable when the problem is organized by
ordering and has a regular structure. This attribute allows the user to specify the
number of stages required. This is an optional attribute. The required data type for
this attribute is the primitive type int.

The grp.sub.struct Element

The grp.sub.struct element captures information about tasks relationships and

dependencies. It is only applicable in problems that are organized by tasks. It contains no









attributes but it must have either a task.decomposition or a task.relationships element as a

sub element.

The task.decomposition Element

The task.decomposition element is applicable when we have a problem that is

organized by tasks and has a recursive substructure. The possible values for this element

are one-way and two-way. These values indicate the type of recursion the problem

exhibits.

The task.relationships Element

The task.relationships element is applicable only when the top-level organization

is by tasks. This element captures dependency information among linearly partitioned

tasks. It contains a single required attribute and an optional sub-element. The attribute is

described below:

* ype. This attribute indicates whether or not dependencies exist among the
partitioned tasks. This attribute has two possible correct values. It can either be
Dependent or Independent. This is a required attribute and must be provided in the
specification document. The required data type for this element is string.


The dependency.type Element

The dependency.type element simply expresses what kind of dependencies are

exhibited by the tasks. There are two valid options for this element. It can be either

Separable or Inseparable.

The design space DTD elements that have been discussed help constrain and

describe the XML specifications for the PPPG application. In this section the DTD

elements will be transformed into the corresponding XML specification.

Consider the following example, a user wishes to write a parallel version of the

game of life. The game should use no more than nine threads and the initial problem is









represented in a two dimensional integer array. The solution should be in a class with the

name Life.java. Using the information given above, the XML specifications for the

presented scenario will be created according to the design space DTD elements.

Starting with the design.space root element the user must identify the required

attributes from the problem description: The class name is "Life"; the generated file

should be stored in the user's home directory, it should use nine units of execution and

the problem is represented in a two dimensional array. Our initial specification document

with the information above will look like this:

The design space DTD requires that a design.space element must also contain a

task.group element. For the game of Life problem the top-level organization is by tasks.

The user has also chosen to create a user-defined class named Task to contain the

information on which part of the array each unit of execution will have access to. Adding

this information to our specification file will result in Figure 3-9.

The task.group element requires that a grp.struct element be present. The user

must focus on what attributes are needed for this element. From our specifications it can

be deduced that the Tasks substructure is linear. In this particular scenario the numstages

attribute is not applicable. Adding this information results in the specification file shown

in Figure 3-10.

Now that information has been captured about the grp.struct we must also

examine what information can be extracted from the problem description relating to the

grp.sub.struct element. The grp.sub.struct element must contain either a

task.relationships or task.dependency element type. The tasks in this problem are

independent of one another and the task.relationships element is applicable in this










particular case. Adding this information results in the completed specification shown in

Figure 3-11.

Using the design space DTD we have been able to transform the game of life

problem description into an XML specification file that conveys all the necessary

information needed to generate the source code for the problem solution.

The design space DTD has allowed us to fit the details of a problem to one of the

decision tree terminal patterns. In doing so, we have been able to create accurate and

concise specifications for the PPPG application.

rilassname fisourcepath J iinitdatatype
string strain inte er strin
findatatype
Instrngna

+ design.space task.group


Figure 3-1 The design.space Element


Table 3-1 design.space Element summary
Element Name design.space

Attributes classname, sourcepath, unit, initdatatype, findatatype


Uses elements)


Used by

Content


task.group

(None) root element

a sequence of elements


Occurrence required










[* name J p datatype
,string I I" string )

taskgroup grp.struct


Figure 3-2 The task.group Element


Table 3-2 task.group Element summary

Element Name task.group

Attributes name, datatype


Uses elements) grp.struct

Used by design. space

Content a sequence of elements
Content

Occurrence required


name ?* numstages
Sgrpstrins 7 inteterrt

grp.struct grp.sub.struct


Figure 3-3 The grp.struct Element










Table 3-3 grp.struct Element summary
Element Name grp.struct

Attributes name, numstages

Uses elements) grp.sub.struct

Used by task.group

Content a sequence of elements

Occurrence required


task.decomposition
+ grp.sub.struct
Stask,relationships


Figure 3-4 The grp.sub.struct Element


Table 3-4 grp.sub.struct Element summary
Element Name grp.sub.struct

Attributes None

Uses elements) task.decomposition task.relationships

Used by grp.struct

Content choice

Occurrence required


Figure 3-5 The task.decomposition Element


+ task.decomposition









Table 3-5 task.decomposition Element summary
Element Name task.decomposition

Attributes None

Uses elements) None

Used by grp.sub.struct

Content character data

Occurrence optional





[* type
string )A

+ task.relationships 1: dependency.tyi


Figure 3-6 The task.relationships Element


Table 3-6 task.relationships Element summary
Element Name task.relationships

Attributes type

Uses elements) dependency.type

Used by grp.sub.struct

Content a sequence of elements

Occurrence required



dependency.type


Figure 3-7 The dependency.type Element










Table 3-7 dependency.type Element summary


Element Name


Attributes


Uses elements)


Used by


Content


Occurrence


dependency.type


None


None


task.relationships


character data


optional








Figure 3-8 The design.space element code snippet





S/task.group



Figure 3-9 The task.group element code snippet


Figure 3-10 The grp.struct element code snippet







4/grp.struct>










21
















Figure 3-11 Complete specification document














CHAPTER 4
USING THE PPPG TOOL

The PPPG tool provides two options for the user to generate source code for

concurrent /parallel programs. Users may choose to generate their source code by

supplying an XML specification document containing the details of the problem that is to

be solved via the command line. An alternative to doing this is to use the PPPG user

interface to generate the specification document and program source code.

The PPPG User Interface

The PPPG user interface (PPPGUI) allows the user to generate source code

without having to manually create the XML specification document. This is

advantageous as it removes some of the responsibility for the correctness of the

specification document from the user. The remainder of this chapter serves as a walk-

through the PPPG user interface.

The PPPGUI consists of five tabbed panes. Four of these panes help to gather

requirements about the nature of the problem at hand. The fifth pane displays the

specification document corresponding to the user's input.

General Information Pane

The general information tabbed pane serves as the front page for the PPPG

application. When the program is started the user is presented with a screen similar to the

one shown in Figure 4-1. The purpose of this pane is to collect general information

concerning the problem for which the user wishes to generate code. The user is expected

to enter the path to the directory in which the generated source code will be store into the









Target Directory textbox. A Browse button is also provided to allow the user to look

through the directory tree for a desired location for the source code.


. rlJl


Fi le I.- 1e 1I







*I a.T. l" I; *fT, t1r I':1-"




t.'r it:.. :,, ,i ,ul l, ,l









Figure 4-1 General information screen

The Classname textbox should contain the name of the file in which the solution

should be stored. The Units of execution drop down box allows the user to select the

number of threads desired in the solution.

Datatypes Pane

The datatypes tabbed window pane allows the user to specify the different

datatypes that the generated program will have to handle. This window helps to capture

information about the datatypes that the problem will evolve through during the solution

process. It allows us to capture how the datatype of the problem to be solved will be

changed from its initial representation to the datatype that the final solution. The radio

buttons within the Initial Problem Datatype group box allow the user to pick the datatype


IO, PPPG r









that the initial problem will be represented as programmatically. The user may also

select a user defined type or class by selecting the Other radio button and entering the

name of user defined class or type in the appropriate textbox. This is applicable to all

three group boxes. The Intermediate Datatype group box contains radio buttons that

allow the user to pick the datatype for the intermediate objects that the initial problem

will be broken down into during execution of the generated code. The Result Datatype

group box contains radio buttons that allow the user to specify the desired datatype for

the problem solution.


. IJ l


File H -.Iii


llr'ti.lil F'r,.ller'i L- ['-.tt le r-Teir','r.r i I-,T- L'.t-,t-,T l- e--

r \ ,,rr : I. ,?

r i'.Ier ch Lr:

rr int



" r':'.Ite Other


S-I
:. FI.. i- lM [1EV" i .i- T .I '.i L [1 [1"


.i d i.j F iilii:liirig. l : rF L
IF e lil.t 1' Mt-p *l : 'rtin ;i.-









r ,. 1, i
r :11~


j ." ." "I :r1ii i lE'l : 1'i .i


Figure 4-2 Datatypes window

Concurrency Organization Pane

The concurrency organization pane allows the user to be able to specify the

problem (for which the user wishes to generate source code) in terms of the terminal

patterns of Figure 2-1.










- IJ2l


Fil- Helpi
:- ,i 1I L' i r'- ~11 o ., -I ,-I l '- 1 1 II l '"J" F llill':.rII |' 1 : r.Li
-Tll, L el.1 ,' l|-i r l'Ti l', H :. .L n.:*.,., *:.-* .* L i r iu. .dlI
*.1LC r. l'-.l ; i i Jj.j .L 'i'ii-'J. L L- .
F :r ,ri; B., ':.r'J'nriiJ


l ,.'l, z ? ,,'E T[:I l :


lJeilir II i iuL.: ui e-





1 PJ i ,I j IV l -." u I j ,'j I I





Figure 4-3 Concurrency organization pane

The Top Level Organization group box contains three check boxes that allow the

user to pick which organization best matches that of the problem for which a solution is

being generated. The Ordering Structure group box allows for the user to specify the

applicable sub ordering which best matches that of his or her problem. In the particular

scenario where a pipeline processing pattern is applicable the user has the option to select

the number of pipeline stages desired in the solution. The right side of the pane is a text

area that displays real-time help for the user.

Dependencies and Partitioning Pane

The dependencies and partitioning pane allow the user to select what kind of

relationships exist among tasks and also to determine where applicable the type of

recursion a specific problem exhibits.


10PPPG A~l










SIJ2 l


File H--ell


-TT'- .',r',Jri ',,ri.-- -i !:.ti 'J.-Tljlr- F1,-.,1i1I-.- 'i -


I ll r :ii I I .Ill l il: r il- F' I:i r i I

|Fnons> _I


TElJ iL i:.lA3( *i .jt I1.iu iTli-
directions will be displayed here.










Figure 4-4 Dependencies and partitioning pane

The Task Dependencies group box contains a drop down list box that allows the

user to select whether the tasks in question are dependent or not. If the tasks are

dependent the drop down list box within the Dependency Type group box is enabled.

This drop down list box allows the user to pick whether the dependencies are separable or

inseparable.

The Tree Structure Recursion group box contains a recursion type drop down list

that allows the user to select whether or not the recursion exhibited by the problem is

one-way or two-way.

The XML Viewer Pane

When the required information describing the problem that the user wishes to

generate the source code for has been entered on each of the previous four panes, the

Create XML button on the bottom left corer of the application will become enabled.


1IOPPPG A










When the user clicks this button, the XML specification corresponding to the input on all

the information panes will be created. The XML specification is displayed in the XML

viewer pane as shown in Figure 4-5.


Fil- HI.l1.

.'I E i I. 1 1 i l. r r |.1 "-1














I I I I

Figure 4-5 The XML Viewer Pane

Advanced users may copy and paste the specification from the XML viewer pane

into any text editor and modify for greater control. The new specification file must be

supplied via the command line.

Upon creation of the XML documentation, the Generate Source Code button is

enabled, the user may click it to create the source code in the directory specified in the

General tabbed pane.

Executing from the Command Line

In order to generate source code from the command line the user must supply a

valid XML specification document. The document may either be generated by hand

according to the DTD described in chapter three of this thesis. Users may also generate

the specification document using PPPGui and then further customize the generated






28


specification file using any text or XML editor. In other to run the PPPG tool from the

command line the user must enter the following at the command prompt:

pppgcmdrun

The generated files will be stored in the target directory specified in the XML

specification file. If a target directory is not supplied, the generated source code is placed

in the current working directory.















CHAPTER 5
IMPLEMENTATION DETAILS

Chapter 4 presents an overview of PPPG from the user's perspective. This

chapter discusses the underlying details from a programmer's perspective. Using an

example problem, this chapter walks through code generation process and explains the

implementation methodologies that are utilized within the process. In addition, the main

modules that make up PPPG are discussed along with their respective functions.

A Walk through the Code-Generation Process

Consider the example of an application programmer who wishes to develop a

parallel/concurrent mergesort procedure for use within his/her particular application. The

programmer decides to use the PPPG tool. After careful analysis of the requirements for

the procedure, the programmer creates the XML specification file shown in Figure 5-1.







two way






Figure 5-1 Specification file for mergesort procedure

The tool begins its work after the XML file containing the specifications is passed

as an input, either via the command line or through the GUI tool. PPPG attempts to open

the specification file, if the file does not exist, an appropriate error message is generated









and the tool stops execution. However, if the specification file does exist, the file is

opened and the XML specification is parsed using IBM's XML4J XML parser to ensure

the validity of the XML. The next step is to ensure that the XML specification document

is well formed. This is done by validating the document against the DTD that is defined

for the application. The DTD ensures that the specifications are in the format required by

the application. If this is not the case a message indicating an error is generated and the

tool stops execution. If the XML specification is both valid and well formed, the XML

parser is used to create a DOM data structure. The DOM data structure presents the

XML specification as a tree where each node contains data from the specification

document. The next series of steps start with the creation of the Data capsule. The Data

capsule is an application specific data structure that facilitates the transportation of data

within the application. Upon creation of the data capsule object, the DOM data structure

is traversed, and at each node specification information (originally from the user XML

specification) is copied into the data capsule object. When the DOM data structure has

been traversed and all relevant data copied to the data capsule the actual process of code

generation begins. Before code generation begins a new file (name is specified in the

specifications by the user) is created by PPPG. The source code will be generated into

this file. The generation of code takes place as the decision tree shown in Figure 5-2 is

traversed in a top down manner. The generated code at the end of the tree traversal

process corresponds to an instance of one of the terminal patterns shown in the diagram.

Starting at the top of the tree, PPPG must determine what kind of top-level organization

is desired for concurrency. There are three major branches that can be taken from the

root of the decision tree. They each correspond to the types of top-level organization










available. Concurrency can be organized by the ordering of task groups, decomposition

of tasks, or by decomposition of data [9]. The information on which type of top-level

organization was specified in the XML specifications. All specification information is

now available in the data capsule object. PPPG gets the top-level information from the

data capsule at run time. Source code is generated based on the type of organization the

user specified. In the case of our earlier example, merge sort's concurrency can be

organized in terms of task decomposition and thus the second branch is taken. Since

there are no commonalities for which code can be generated at this level, boilerplate code

indicating the class name and user information is generated as shown in Figure 5-3.


I st I


Orga-d-eE _yOldeng OOanim^EyTa5sk


R7ula Ing r Lr ? e ve


i I I ,, A ,:-It IrPa. r <, 11 fi


r---L-
Sq.m I I ,yData


FL-.--.,] F R wez ivl?


Balaned II DivideAn
T.eV1 Conquer

Deciionct '

Ihnrmdiate Patten Key

TennuialPattem IJ


Figure 5-2 Decision tree










package mergeSort;


Title: JaygoSoft mergeSort Procedure
SDescription: This class implements Concurrent HergeSort Procedure
Copyright: Copyright (c) 2002
Company: JaygoSoft Corporation
@author Renee A. Williamson
@version 1.0


public class mergeSort extends


Figure 5-3 Boilerplate code generated to mergeSort.java file

At the first level a decision must be made about how the previously selected

ordering is structured. For both the second and third major branches, the ordering can be

either linear or recursive. This depends on whether the tasks (branch two) or the data

(branch three) is ordered linearly or recursively.

At level one after taking branch one; a decision must be made on whether the

ordering is structured regularly or irregularly. PPPG makes this decision based on data

from the data capsule. Regular orderings are those that do not change during execution

of the algorithm, while irregular orderings refer to orderings that change dynamically

during algorithm execution [7].

In our example the merge sort algorithm is organized recursively by task. In this

particular situation PPPG does not generate code because of inadequate commonalities

between recursive and linearly partitioned tasks.

On the second level, for branch one the choice (based on data capsule data) of

regular ordering corresponds to the pipeline processing terminal pattern, at this point

PPPG generates the remainder of the code corresponding to the afore mentioned pattern.

If at the same level and branch the choice of the ordering is irregular, then the code

corresponding to the asynchronous decomposition pattern is generated.









The second major branch (Order by Tasks) is more involved than the other two

branches. At the second level within this branch, PPPG must make either of the

following choices based on the information in the data capsule. The choice of linear

ordering, which indicates that the tasks are structured as linear collections, leads to the

partitioning intermediate pattern. All programs that have the partitioning pattern as an

intermediate pattern share the characteristic that the initial problem can be spilt into tasks.

At this point, if linear ordering is indicated in the data capsule, PPPG generates the code

for splitting the initial problem into tasks.

At the same level and branch, if the choice of recursive ordering was specified by

the user, indicating that the tasks are structured recursively, we arrive at the tree

intermediate pattern. At this point PPPG cannot generate any source code until further

distinctions can be made. At level four within the second branch a decision must be

made based on whether the tasks are independent of each other or not. If the tasks are

independent PPPG arrives at the Embarrassingly Parallel terminal pattern and the rest of

the code corresponding to this particular pattern is generated. If the tasks are dependent

then PPPG must verify whether the dependencies are separable or inseparable between

the tasks. If the dependencies are separable PPPG generates the source code for the

Reduction terminal pattern. In the case that the dependencies are not separable, the

source code corresponding to the ,\//,i eJ Memory pattern is generated.

At level three still within the second branch, if PPPG has an instance of the tree

intermediate pattern, as is the case with the mergesort example, a decision must be made

about the nature of the recursion. PPPG must decide whether the recursion in one-way or

two-way. If the recursion is one-way, source code corresponding to Balanced Tree









pattern is generated. On the other hand if PPPG is dealing with a two-way recursion the

Divide and Conquer pattern is generated. In our example, the recursion is two-way and

thus code for the divide and conquer terminal pattern is generated.

public Object merge Object [] solutions )



public boolean baseCase Object p



public Object baseSolve ( Object p





Figure 5-4 Remainder of code generated for mergeSort.java class

Since it is now known that the code being generated is an instance of the divide

and conquer pattern. The buffer is modified to make the mergeSort class extend the

DivideAndConquer class. At this point PPPG generates the source code for

DivideAndConquer.java. The source code generated for this class and all other code

generated is attached as appendix A.

It is important to mention that PPPG provides genericity. Genericity is a

generalization mechanism that allows a single definition to apply to a whole set of classes

with different behaviors. Genericity is the ability to parameterize modules. It is

applicable when the implementation behavior is constant but the datatype can change. If

the user had supplied a more detailed specification that included the initial, intermediate,

and final datatypes, PPPG would have generated different parameter and return types for

the methods shown in Figure 5-4. The datatypes would have changed but the

implementation behavior for each of the methods would stay the same.









At the first level within the third major branch PPPG examines the data capsule to

see if the data structures are linear or recursive. If PPPG encounters a situation in which

the data structures are linear then source code corresponding to the Geometric

Decomposition pattern is generated. Otherwise, if the data structures are found to be

recursive, source code corresponding to the Reference Following pattern is generated.

Modules and Class Detail

PPPG performs the following tasks.

* Validates the XML input specifications and reports errors and warnings where
applicable
* Completes the specification using default settings where necessary
* Generates the solution implementation

These tasks are implemented as two consecutive and separate modules. When

PPPG receives the specification in a textual form from the command line it parses the file

to transform the data into the DataCapsule representation. If the PPPGUI is used to

create the specification the information is directly inserted into a DataCapsule object and

the parsing stage is bypassed.

PPPG consists of two main modules, the parse and package module and the code

generator module. The relationships and interactions between these modules are shown

in Figure 5-4.

Parse and Package Module

This module as its name implies is responsible for reading and validating the

XML input specifications against the DTD. After validation of the specification, the input

data is analyzed and packaged into a data capsule object. The data capsule object is now

ready to be passed to the code generator module.










The Syntax Analyzer object implements the parse and package module. When

the syntax analyzer object is instantiated, it expects an input string containing the

filename of the XML input specifications. If the input file can be opened, an instance of

an XML parser is created; the parser checks the input for syntax errors and then validates

it against the DTD. If syntax analysis and validation are successful, the parser will create

a document object model (DOM) document. The syntax analyzer completes its work by

iterating through the DOM document, collecting data and storing it in a user defined data

structure called the data capsule. Upon completion the data capsule containing the

specifications for the program generator is passed to the generator module.



XML Input
Specifcation



-- -- -- ---- -- -- -- -



Parse and Package Module



Program Generator



Code Generation Module






Generated Program
Java source code)


Figure 5-4 Structure of PPPG




















XML Parser




I Parse and Package
Validate Module




Package



Data Capsule to Code
Generator Module




Figure 5-5 Parse and package module

SyntaxAnalyzer Class Detail. The SyntaxAnalyzer class contains two very important

methods. They are the verify and extractData methods. The verify method is responsible

for validating the XML specification and initiating the creation of the DOM document.

The extractData method extracts the data from the DOM document and populates the

DataCapsule.

Datacapsule

The data capsule module is a user defined data structure used to store data from

the XML input specification. The data capsule allows easier transportation of data

between the two main modules. It not as bulky as the DOM document and allows easier

access to the specification data. The data capsule contains fields representing the entities










and their respective attributes as defined in the DTD. For more information on the DTD

please see Chapter 3.

SyntaxAnalyzer

doc:Document
errcount:int
ONE CHILD:int
ERROR:int

+SyntaxAnalyzer
+verify:void
+ extractData:DataCapsule
+main:void


Figure 5-6 SyntaxAnalyzer UML diagram

DataCapsule Class Detail. The DataCapsule class contains several variables to store

specification information. It also provides the generateXml method which is responsible

for transforming the current contents of the DataCapsule into its equivalent XML

specification. This method is used primarily by PPPGUI.

Code Generator Module

The code generator module upon receipt of the data capsule begins the work of

creating the desired output program based on the data contained data capsule object. The

information in the DataCapsule usually represents a path down the tree given in Figure 5-

2. The CodeGenerator object contains the implementation of the Code Generator module

as described above. The code generator expects a data capsule object and a string

containing the path for the destination file when it is initialized. The generation process

itself involves making decisions at each level of the tree. At each non-terminal tree node,

code corresponding to the particular path taken is generated and added to the output file

until a terminal pattern is reached. Traversing the tree in Figure 5-2 from the root to any

of the leaf nodes generates the code.











DataCapsule


Figure 5-7 DataCapsule UML diagram

CodeGenerator Class Detail. The CodeGenerator class contains the various methods for

generating the different terminal patterns available. It also contains methods to handle


generation of either C++ or Java source code.


+DECOMPOSITION:int
+RELATIONSHIP:int
classname:String
taskgroupname:String
grp struct: String
resdatatype:String
subval:String
deptype:String
datatype:String
tagd ir:String
probdatatype:String
hassubstruct:boolean
hasdependency:boolean
subtype:int
UNITS:int
stages:int

+DataCapsule
+toString:String
+generateXml:StringBuffer
+generateXml:void











CodeGenerator

PIPELINE:int
ASYNCH DEC:int
EMB PAR:int
REDUCTION:int
SHARED MEM:int
GEO DEC:int
BAL TREE:int
DIV N CONQ:int
REF FOL:int
INVALID:int
-JAVA:int
-CPP:int
-dcap:DataCapsule
-out1 :PrintWriter
-out2:PrintWriter
path:String
datatype:String
mypattern:int
num_ues:int

+CodeGenerator
+CodeGenerator
+CodeGenerator
-initDatatypes:void
-determineTerminalPattern:void
+generate:void
+generate:void
-createJavaCode:void
-createCPPCode:void
-jDivideAndConquer:void
-generateAbstractDivideAndConqu
-jSepDepend:void
-jProDepend:void
-jEmbParallel:void
-jPipeProc:void
-generatejBarrier:void
-jAsynchDecomp:void
-generateWorkerThread:void


Figure 5-8 CodeGenerator UML diagram














CHAPTER 6
GENERATED PROGRAMS

This chapter focuses on several example programs that were developed based on

patterns generated by PPPG. Three sample programs are discussed. These programs

illustrate the functionality and usability of PPPG and the efficiency of the generated

programs. The first program is a concurrent implementation of the classic mergesort

algorithm. The second is an implementation of the game of life and the final program

simulates an assembly line. Each of these programs and their corresponding base

patterns will be discussed in this chapter.

Concurrent Implementation of Mergesort

The sorting algorithm Mergesort produces a sorted sequence by sorting its two

halves and merging them. With a time complexity of O(n log(n)) mergesort is optimal.

In order to generate a concurrent mergesort algorithm using PPPG a valid specification

file describing the algorithm was created. For this particular instance the specification

file contained information about the datatype in which the problem instance would be

supplied to the program. It also contained information about the user defined structure

Task that the threads would manipulate while solving the problem. The specification1 file

was passed as input into PPPG and an instance of the DivideAndConquer terminal pattern

was generated. The file generated is shown in Figure 6-1.





1 The complete specification file for the concurrent mergesort algorithm can be found in
appendix B of this thesis paper.


































Figure 6-1 Concurrent MergeSort algorithm

The next step is to implement the abstract methods that define how the problem is

to be solved. It is important to note that all the details about concurrency and thread

scheduling are not visible to the programmer. These details are contained in the

superclass DivideAndConquer generated by PPPG. The programmer need only worry

about how to implement the methods provided in the generated file.

In this particular example the programmer will need to define a new class Task.

The methods within the Mergesort.java file shown in Figure 6-1. should be implemented

as follows, the baseSolve method is responsible for solving an atomic instance of the

problem and returning the result a Task object. The baseCase method examines a Task

object and returns a true or false value based on whether the Task can be divided into

smaller tasks or not. The split method divides a Task object into smaller Tasks and

returns and array of Tasks. The merge method accepts an array of Tasks and merges

them into a single Task.


public class MergeSort extends DivideAndConquer {

public MergeSort() {
}
public Task baseSolve(Task p)
/**Ptodo: implement this DivideAndConquer abstract method*/

public Task[] split(Task problem)
/'t@todo: implement this DivideAndConquer abstract method*/

public boolean baseCase(Task p) {
/t-ttodo: implement this DivideAndConquer abstract method*/

public Task merge(Task[] parml) {
/**Ptodo: implement this DivideAndConquer abstract method*/

public static void main(String[] args) {
HergeSort mergeSortl = new MergeSortI);
}










An implementation of the split method is shown in Figure 6-2. The complete

implementation of the concurrent MergeSort can be found in appendix A.

public Task[] split ( Task problem


Task [ ] retarray = new Task [SPLITSIZE];
// pick pivot
int midpoint = problem.myArray.length / SPLIT_SIZE;
int end_point = problem.myArray.length- 1;

Integer [] tempi = new Integer[mid_point];
Integer [] temp2 = new Integer[end_point+l-mid_point];

for (int i = 0; i < midpoint; i++)
templ[i] = problem.myArray[i];

for (int i = midpoint; i <= end_point; i++)
temp2[i-mid_point] = problem.myArray[i];

retarray[0] = new Task temple) ;
retarray[l] = new Task (temp2);

return retarray;



Figure 6-2 Implementation of the split method

Assembly Line Simulation

This example creates an assembly line simulation called the Math Factory. The

math factory performs sequence of identical operations on an input number and returns

the results after completion. Each unique operation represents a stage, and the stages

together form a pipeline. The key here is to have the maximum number of stages

executing concurrently at any given time during program execution. To accomplish this

task, a specification2 file containing details about the initial problem representation,

classes representing input into the factory, the number of stages and other information



2 The complete specification file for the math factory simulation can be found in
appendix B of this thesis paper.











concerning the problem was created. This specification was passed as input to PPPG and


an instance of the PipelineProcessing pattern was generated. A portion of the generated


program is shown in Figure 6-3.

inmort edu.ufl. cise. joladele.pDpcflib, .:

public class anthFactory

SharedQueue sharedOueue;
pipeTlrcea [] itreacl_poot;
Stage [] pipeline;
public static int NUHIUE = 5:
ptllc static rnt OYFTET = i;
public Ktatic int NTUMSTAGES = 6;
private static long TIME OUT = 2000: /' 90 seconds
private Barrier b;
private volatile static lnt cla = D;
ptlic HathFactory()

// CLeate pipeline
pipeline = ncw Stage[HUI_3TAGEE];
// CEeate thread pocl
thread_pool = new pipeThread[NUH_UE];
sharedOueue = new 5haredQueue |);
initialize () ;


pWllc vola coipleteL(

/tEt3odo: inrlenom. this netbodt/I


prlic SharedQueue split (Object problem)

SharedQueue nsq = new sharedQueue ();
try{
//ADD CODE TO BREAR UP INTTIAI PPOHLEN AiTi PTT IM QOUFUF
/"@trodo: inplenent this method*/



Figure 6-3 MathFactory code snippet.

In order to complete the Math factory, the programmer needs to create an


implementation of the Event class that was supplied as the intermediate data type in the


XML specification file. In the MathFactory class two methods will need to be


implemented. The split method is responsible for dividing the initial problem into


instances of the intermediate datatype and then placing them into a shared queue object.










This method returns a shared queue containing the objects to be worked on my individual

threads. The complete method should contain any operations to be performed after

processing of the Event object. Such processing may include but is not limited to

displaying the end result after all pipeline stages have been cleared.

The Math Factory class also contains a Stage object. This object contains all the

operations corresponding to the different stages of the pipeline. A code snippet from the

inner class Stage is shown in Figure 6-4.

class Stage

private int id;
public Stage (int id)

this.id = id;

public synchronized void performComputation (pipeThread p)

switch (id)

case 1:
/**@todo: implement this method*/
// Stage 1 computation go here
// Access thread Data by using p.my_data
break;
case 2:
/t*@todo: implement this method*/
// Stage 2 computation go here

Figure 6-4 Inner Class Stage code snippet

Implementation of the Game of Life

The game of life is an example of cell automaton, which is any system in which

rules are applied to cells and their neighbors in a regular grid. Life is played on a grid of

square cells, like a chess board but extending infinitely in every direction. A cell can be

live or dead. A live cell is shown by putting a marker on its square. A dead cell is shown

by leaving the square empty. Each cell in the grid has a neighborhood consisting of the









eight cells in every direction including diagonals. The rules of the game of life are as

follows:

For a space that contains a live cell:

* Each cell with one or no neighbors dies, as if by loneliness.
* Each cell with four or more neighbors dies, as if by overpopulation.
* Each cell with two or three neighbors survives.

For a space that is empty:

* Each cell with three neighbors becomes populated.

To continue our implementation of the game of life, we need to create a

specification file describing the nature of the problem and details specific to this

particular implementation. A completed specification is provided in appendix B. Based

on the input to PPPG an instance of the EmbarrassinglyParallel pattern was generated.

The generated pattern is shown in Figure 6-5.

The generated file shown above shields the programmer from the details of

concurrency. The programmer need only concern themselves with the details of the

problem solution alone. In the game of life example the initial problem is represented in

a multi dimensional array. The split method is responsible for dividing up portions of the

array into Task objects which are then inserted into a shared queue. The processResults

method will retrieve objects from the result queue and possibly update the display or

perform any other similar actions. The taskProcessing method will process a Task object

and update the result queue.

In this chapter we have examined three programs created based on patterns

generated by PPPG. These patterns have enabled the programmer to focus on the task of

what the program needs to do, rather than worry about details on how to make the











program run concurrently and verifying thread safety and other related issues. By using

PPPG to generate concurrent/parallel versions of the program a lot of development time

is saved.

import edu.ufl.cise.joladele.pppglib.*;
public class Life extends EmbarrassinglyParallel
{
void split(int [] [] problem)
{
/Rt@todo: implement this EmbarrassinglyParallel abstract method*/
/ R
This function should split the initial problem into smaller components
which can be handled by individual units of execution.
All the subproblems should be placed in the work queue "q"
**/
}
Object processResults()
{
/Rt@todo: implement this EmbarrassinglyParallel abstract method*/

This function should combine all the individual results
contained in the "result" queue

}
Task taskProcessing(Task task)
{
/Rt@todo: implement this EmbarrassinglyParallel abstract method*/


Figure 6-5 Game oflife

Figure 6-5 Game of life














CHAPTER 7
CONCLUSION

From the onset of this research project, the desired purpose was to create a

program generator that enables the user to create portable and efficient

parallel/concurrent programs while minimizing overall development time. This research

project has been able to accomplish these goals. This chapter highlights the features of

PPPG and their significance to end-users. This chapter also discusses some limitations of

PPPG and corresponding suggestions for improvement.

Summary of Work Done

A program generator is very ineffective if there is no way for the user to specify

what kind of programs are to be generated. Therefore, the need arose to create a

specification language that can adequately and robustly communicate the details of the

user's problem in a manner that the PPPG tool can understand and generate the

appropriate source code to solve the problem. The decision was made to use XML. A

DTD to represent the algorithm design space of Figure 2-2. was created to help the user

map their problem to one of the terminal patterns within the domain. This DTD not only

helped describe the user's problem but was used to constrain and validate input XML

specifications into the PPPG tool.

The creation of the program generator involved developing several modules

responsible for parsing and validation of the input specification, extracting the data from

the specification, and generating the appropriate terminal pattern corresponding to the

information obtained from the user. A significant amount of development time went into









the creation of the Asynchronous Decomposition, Divide and Conquer, Embarrassingly

Parallel, Pipeline Processing, Protected and Separable Dependencies terminal patterns,

as the patterns had to be initially created by hand before automating their creation using

PPPG.

The development of the PPPG was completed with the creation of a graphical tool

that simplifies the specification creation process and removes the burden of specification

correctness from the user. This tool also permitted code generation directly from

graphical interface.

Future Work

While this research effort has achieved the initial goals of simplifying the creation

of parallel programs, and portability of the generated program, there are some

improvements that can be made to increase the functionality and usability of the system.

Two of the terminal patterns within the algorithm structure design space are not

included in this initial version of PPPG. Since this work is based on ongoing research,

enough information on the Reference Following and Balanced Tree terminal patterns

were not available at the time of development. As research uncovers more information

about these patterns and their implementations, adding the pattern implementations to

PPPG will provide completeness and allow the user to be able to generate a broader range

of parallel programs.

With several of the patterns generated by PPPG, if information about the specific

platform on which the generated program will used is made available, optimizations may

be made to make the generated program more efficient by generating a more specialized

version of the given pattern. It is however important to note that while any such change









may increase efficiency, the portability of the generated source code may be significantly

affected.

An added suggestion is to include functionality that permits PPPG to generate its

target programs in programming languages other than the Java language. Such

functionality will give the user freedom to generate their solution in languages that they

may be more familiar with. This functionality while increasing usability will add

additional complexity to the generated programs and greatly decrease portability. Using

the Java programming language for the generated programs provides a language with in-

built multithreading and allows the JVM to handle thread scheduling issues. Not all

programming languages support built-in multithreading and thus PPPG will have to use

operating system function manually and may also have to worry about thread scheduling

issues, thus greatly increasing the complexity of the generated programs.

Finally, while PPPG provides genericity, there are specific situations in which a

user defined class may need to be cast into a primitive type or vice-versa. Such situations

currently require that the programmer manually modify the generated code to ensure that

these type conversions do not result in compilation errors. Improvements may be made

so that this sort of occurrences can be effectively handled within the program generator.













APPENDIX A
EXAMPLE PROGRAMS SOURCE CODE LISTINGS

Source Listing for MergeSort.java (Pre Implematation)

package MergeSort;
public class MergeSort extends DivideAndConquer
{
static int SPLIT SIZE = 2;
public Task[] split ( Integer [ ] problem)
{

}
public Integer [] merge (Task [] solutions)
{

}
public boolean baseCase ( Task p )
{

}
public Object baseSolve ( Task p )
{
}
}

Source Listing for MergeSort.java (postimplementation)

public class MergeSort extends DivideAndConquer
{
static int SPLIT SIZE = 2;
public Task[] split ( Task problem)
{
Task [ ] retarray = new Task [SPLIT_SIZE];
// pick pivot
int midpoint = problem.myArray.length / SPLIT_SIZE;
int end_point = problem.myArray.length 1;

Integer [] temple = new Integer[mid_point];
Integer [] temp2 = new Integer[endpoint+1-midpoint];









for (int i = 0; i < midpoint; i++)
temp [i] = problem.myArray[i];

for (int i = midpoint; i <= end_point; i++)
temp2[i-mid_point] = problem.myArray[i];

retarray[0] = new Task temple) ;
retarray[l] = new Task (temp2);

return retarray;
}
public Task merge ( Task [] solutions)
{
//return new Task ();
// basic case when even
int totelem =0, ret index=0, first=0, send = 0;
int num_elem = solutions.length;
for ( int i = 0; i < num_elem;++i )
totelem += solutions[i].size;

Integer [ ] ret = new Integer[totelem];

while ( first < solutions[0].myArray.length ||
send < solutions[l].myArray.length)
{
if( first < solutions[0].myArray.length && send < solutions[1].myArray.length)
{
if (solutions[0].myArray [first].intValue0 <
solutions[1].myArray[scnd].intValue())
ret[retindex++] = solutions[0].myArray [first++];
else
ret[retindex++] = solutions[1].myArray[scnd++];
}
else
{
if (scnd == solutions[1].myArray.length) // sec array finished
ret[retindex++] = solutions[0].myArray [first++];
else if( first == solutions[0].myArray.length)
ret[retindex++] = solutions[1].myArray[scnd++];
} //end else
} // end while

return new Task (ret);
}
public boolean baseCase ( Task p)
{









if (p.myArray.length == 1)
return true;
else
return false;
public Task baseSolve ( Task p
public Task baseSolve ( Task p )


return p;
}
public static void main(String [] args)
{
Task probtask;
if( args.length != 0){
Integer [] numbers = new Integer [args.length];
for ( int i = 0; i < args.length; i++)
numbers[i] = new Integer ( args[i]);
probtask = new Task(numbers);
}
else
{
Integer [] prob = {new Integer(13), new Integer(6), new Integer(4),
new Integer(14), new Integer(3), new Integer(12),
new Integer(1 1), new Integer(7), new Integer(15),
new Integer(9), new Integer(16), new Integer(5),
new Integer(2), new Integer(l), new Integer(8),
new Integer(1O)};
probtask = new Task (prob);
}
MergeSort x = new MergeSort);
Object y = x. solve (probtask);
System. out. print(y);


Source Listing for DivideandConquer.java


import edu.ufl.cise.joladele.pppglib.*;
public abstract class DivideAndConquer {
public abstract Task[] split ( Task problem);
public abstract Task merge ( Task [] solutions);
public abstract boolean baseCase ( Task p );
public abstract Task baseSolve ( Task p );
public Object solve ( Task p)
{
if (baseCase (p))
return baseSolve(p);
else
{








Task [] subproblems = split (p);
int N = subproblems.length;
Task [] subsolutions = new Task [N];
Barrier b = new Barrier(N + 1);

// start threads to solve subproblems
for ( int i = 0; i < N; i++ )
(new solverThread(b, i, subproblems, subsolutions)).start);

// wait for all subsolutions to be completed
try { b.barriero; }
catch ( InterruptedException e)
{

}
I merge all subsolutions and return result
return merge ( subsolutions);
}
}
class solverThread extends Thread {

Barrier passedbarrier;
int number;
Task [] subproblems;
Task [] subsolution;

public solverThreado
{
passedbarrier = null;
}

public solverThread(Barrier b, int num, Task [] subp, Task [] subsol)
{
passedbarrier = b;
number = num;
subproblems = subp;
subsolution = subsol;
}
public void run ()
{
subsolution[number] = (Task)solve(subproblems[number]);
try
{
passed_barrier.barrier();
}
catch ( InterruptedException e)






55

{
}
}
}
}














APPENDIX B
SPECIFICATIONS FOR EXAMPLE PROGRAMS

Specification for MergeSort Example


"http://www.cise.ufl.edu/-joladele/PPPG/taskDecomposition.dtd">




two way



.


Specification for Assembly Line Simulation


"http://www.cise.ufl.edu/-joladele/PPPG/taskDecomposition.dtd">







Specification for Game of Life


"http://www.cise.ufl.edu/~joladele/PPPG/taskDecomposition.dtd">









57























LIST OF REFERENCES


[1] S. Bromling, S. MacDonald, J. Anvik, J. Schaeffer, D. Szafron, and K. Tan,
"Pattern-based Parallel Programming." Proceedings of the 2002 International
Conference on Parallel Processing (ICPP2002), Toronto, Canada, August 2002.

[2] C.J. Cleaveland. "Program Generators with XML and Java." New-Jersey:
Prentice-Hall, 2001.

[3] K. Czarnecki, and U.W. Eisenecker. "Generative Programming Methods, Tools,
and Applications." New York: Addison-Wesley, 2000.

[4] The Hillside Group. "Patterns Home Page." October 2001. Accessed May 2002.
http://www.hillside.net/patternsnavigation.htm

[5] J.F. Jaja. "Fundamentals of Parallel Algorithms." In Albert Y. H. Zomaya, editor,
Parallel and Distributed Computing Handbook. New York: McGraw-Hill, 1995,
333-354.

[6] D. Lea. "Concurrent Programming in Java: Design Principles and Patterns."
Boston: Addison-Wesley, 2000.

[7] B.L. Massingill, T.G. Mattson, and B.A. Sanders. "A Pattern Language for
Parallel Application Programming." Proceedings of the Six\il Pattern Languages
ofPrograms Workshop (PLoP 1999), Monticello, Illinois, August 1999.

[8] B. Meyer. "Genericity versus Inheritance." Proceedings of thefirst conference
on Object-Oriented Programming Systems, Languages, and Applications
(OOPSLA 1986), Portland, Oregon, November 1986.

[9] L. Patterson. "Using the IBM XML Parser (XML4J): Find & Replace Elements
in an XML Document." January 2000. IBM Corporation. Accessed May 2002.
http://www.ibm.com/servers/eserver/iseries/developer/java/xml/xmlparser2.html

[10] S. Sarkar, and C.J. Cleaveland. "Code Generation using XML based Document
Transformation." November 2001. The Middleware Company. Accessed July
2002. http://www2.theserverside.com/resources/article.jsp?l=XMLCodeGen

[11] Gary Shute. "Table Driven Design." Accessed May2002.
http://www.d.umn.edu /-~shute/softene/table-driven.html






59


[12] T. Wilmarth. "PPL:Load Balancing." Accessed June 2002.
http://charm.cs.uiuc.edu/ppl_research/ldbal/

[13] World Wide Web Consortium. "W3C Document Object Model." March 2002.
W3C. Accessed June 2002. http://www.w3c.org/DOM















BIOGRAPHICAL SKETCH

Jean-David Oladele was born June 25, 1976 in Lyon, France. He received his

Bachelor of Engineering degree in computer engineering from the University of Florida,

Gainesville, Florida in May 1999. He worked as a junior consultant for Software

Architects Inc. in Tampa, Florida, for about a year and a half. In the fall of 2000, he

began graduate study in the Department of Computer and Information Science and

Engineering at the University of Florida for the Master of Engineering degree in

computer engineering. He received the degree in December 2002.