Reference Page

From CSE231 Wiki
Jump to navigation Jump to search

This is a collection of all the the different tools we use in this course and their syntax.

While this page is here to assist you whenever you forget how to create a lambda or register a phaser, try not to become too reliant on it. If you learn and understand the syntax for the tools we build in this class, it will make the assignments easier and faster to get through. Also, this page will not be available during exams, and while there is always leniency with written code, there must be some demonstration of understanding how to use our parallel constructs!

Java Basics

Sometimes the problem isn't with doing things in parallel, but just getting Java to cooperate with what you want it to do. Here's the syntax for some of Java's base constructs and classes that you'll use throughout the semester.

Lambda

Runnable

V5/Habanero

Habanero is Rice's collection of parallel tools. When you watch the RiceX videos, it is the Habanero version of things you will be seeing. For this course, we've designed V5. It is similar to Habanero in most ways, but has small changes to hopefully make your lives easier when it comes to using the tools in this class. Listed below is the syntax for V5's version, but the differences between the two versions are noted to help clarify.

Async

Asyncs are our main tool in doing work in parallel. The execution of an async will spawn a new task, and any code written within the braces of an async will be done in that new task. The actual async method is called like this: async(Runnable body)

But as discussed above in the Syntax of 231#Runnable Runnable section, a Runnable can be defined just using a lambda. For the runnables in asyncs, there are no parameters passed in, so an async with the lambda is as follows:

async( () -> {
	doSomething();
});

It is also worth noting that with the V5 version of async, we can call it as async(Boolean isParallelDesired, Runnable body), where the boolean determines whether or not the body is run in a new thread or not. While you'll never need to use this for the assignments, it is a possibility.

Finish

Finish blocks will wait until everything within the brackets (no matter the number of tasks) executes and completes before moving on to any of the code after it. This is essential in preventing data races and will be used frequently in the course.

finish(Runnable body)

finish( () -> {
	async( () -> {
		doSomething();
	});
	asynch( () -> {
		doSomethingElse();
	});
});

Forall

A forall loop is a simplified way to do the following:

for(int i = minInclusive; i < maxExclusive; i++){
	async( () -> {
		doSomething(i);
	});
}<source>

To do that same code with a forall loop, we simply do

<source>forall(minInclusive, maxExclusive, (i) -> {
	doSomething(i);
});

Note how this time in the lambda, we are passing a parameter through in the parentheses. This 'i' passed through is the variable that is being incremented. You can also do a forall loop iterating through an iterable object, such as an array or list. That would look like this:

T[] array = new T[n];
forall(array, (item) -> {
	doSomething(item);
});

In this case, item is something of type T from the array. This loop will iterate through all the indicies in the array and spawn a new task for each one.

Forall Chunked

Sometimes, you don't want to make a task for each any everything in the iteratable object, as the overhead of spawning tasks outweighs the benefits from parallelism. Chunking allows the creation of the tasks to be manually decided (either by the user or the computer). To use chunking, just pass a ChunkedOption before the object/values to iterate over.

forall(chunked(), array, (item) -> {
	doSomething(item);
});


Java X10