Programming Model

COMP Superscalar aims to provide an easy-to-use programming model to enable Java applications for the Grid. The so-called `Grid-unaware applications' are those that have no prior knowledge about the Grid, and they are usually programmed in a sequential fashion. Nevertheless, by means of COMP Superscalar they can be run on the Grid and exploit its resources, while increasing the performance if possible. COMPS Superscalar identifies the tasks that compose the application, detects task precedence, decides when tasks are submitted to the Grid and controls their remote execution.

The following subsections explain, through a simple example, how to make an application use COMP Superscalar.

1. Original Sequential Code

Consider a Java application which generates random numbers and cumulatively sums them, called Sum. Figure 1 shows its main code, which we will take as the starting point of this usage example.

initialize(f1);

for (int i = 0; i < 2; i++) {

genRandom(f2);
add(f1, f2); // f1 <- f1 + f2

}

print(f2);

Figure 1. Original code of Sum. All method parameters (f1, f2) are file names.
After setting f1 to zero (initialize), random numbers are generated (genRandom)
and then added to the accumulated sum stored in f1 (add).
print opens a stream on f2 and prints its final value.

2. First Step: Selecting the Tasks

The first step consists in telling COMP Superscalar which tasks it must take into account, that is, which methods called from the application code will be actually executed on the Grid. This is done by providing a Java interface which declares these methods, along with Java annotations that specify necessary metadata about the tasks. These metadata can be of three different kinds:


1. For each parameter of each method, its type (currently, we support the file type, the primitive types and the string type) and its direction (IN, OUT or INOUT).
2. The Java class that contains the code of the method.
3. The constraints that a given resource must fulfil to execute a certain method, such as the required operating system or storage capacity.

Figure 2 corresponds to the annotated interface of Sum, with the mentioned metadata.
 

public interface SumItf {

 

@ClassName("example.Sum")
@MethodConstraints(OSType = "Linux")
void genRandom(

@ParamMetadata(type = Type.FILE, direction = Direction.OUT)
String f

);

@ClassName("example.Sum")
@MethodConstraints(procArch = "Intel", procSpeed = 1.8f)
void add(

@ParamMetadata(type = Type.FILE, direction = Direction.INOUT)
String f1,
@ParamMetadata(type = Type.FILE, direction = Direction.IN)
String f2

);

 

}

Figure 2. Annotated interface for Sum. The two declared methods,
genRandom and add, have been selected to be executed on the Grid.

3. Second Step: Preparing the Application

The second step involves making the application invoke the runtime of COMP Superscalar. For that purpose, the user can choose between two options, explained in the next two subsections.

3.1 Using the API

The first option consists in modifying a bit the original application code by including some calls to the COMP Superscalar API. More precisely, the programmer can use up to 3 API methods, which are:

  • start: starts the runtime.
  • stop: stops the runtime.
  • openFile: it must invoked before accessing a file from the application in order to get the last version of the file transferred to the application local host.

Figure 3 shows the modified code of Sum, resulting from the inclusion of the API calls.

initialize(f1);

COMPSuperscalar css = new COMPSuperscalarImpl();
css.start();

for (int i = 0; i < 2; i++) {

genRandom(f2);
add(f1, f2);

}

String rF2 = css.openFile(f2, OpenMode.READ);
print(rF2);

css.stop(true);

Figure 3. Code of Sum with calls to the COMP Superscalar API

Using the API gives the programmer more control over the application, more precisely in two ways: on the one hand, the runtime can be stopped at any point of the application and optionally restarted again later, which allows the programmer to execute some parts of the application locally and sequentially if she wants to; on the other hand, when working with a file, the exact mode in which it will accessed can be specified so that COMP Superscalar can know if another version of that file is going to be generated.

3.2 Leaving the Application Unchanged

As a second possibility, COMP Superscalar also allows the user to leave the application completely unchanged, i.e. with no Grid-related calls in it.

COMP Superscalar, with the help of a custom Java class loader, is able to take a sequential Java application and run a set of selected methods on the Grid. The loader will be responsible to include, automatically and on the fly, the necessary invocations to the API. Therefore, the user is only required to provide the annotated interface with the selected methods and the original sequential code of the Java application.

The main advantage of this option is that it frees the programmer from worrying about editing the application code at all. An original sequential Java code, like the one in Figure 1 , can be directly parallelized on the Grid by means of COMP Superscalar.