/**
* DPJ implementation of list ranking
* Robert L. Bocchino Jr.
* June 2008
*/
import DPJRuntime.*;
/**
* Class for a list node, parameterized by a parent region
*/
class ListNode<region Parent> {
/**
* Region for storing rank information
*/
region Rank;
/**
* Region for storing rank information we read out of the rank
* neighbor.
*/
region NbrRank;
/**
* The next node in the list containing this node. Initially,
* next=this (a self loop), indicating this is a terminal node of
* the list.
*/
public ListNode<*> next in Parent : Rank = this;
/**
* The neighbor node for the pointer-jumping algorithm: initially,
* it is equal to this; then it is modified by the algorithm.
*/
public ListNode<*> rankNbr in Parent : Rank;
/**
* The rank information for this node.
*/
public int rank in Parent : Rank;
/**
* A place to store the value of rankNbr.rank.
*/
public int savedRank in Parent : NbrRank;
/**
* A place to store the value of rankNbr.rankNbr.
*/
public ListNode<*> savedRankNext in Parent : NbrRank;
/**
* Rank initialization: rank starts out as 1 unless this is a
* self-loop (terminal node), in which case it's 0. rankNbr
* initially points to this.next.
*/
void initRank() writes Parent : * {
rank = (next == this) ? 0 : 1;
rankNbr = next;
}
/**
* Save rankNbr.rank to this.rank and rankNbr.rankNbr to
* this.rankNbr.
*/
void updateNbrRank()
reads * : Rank writes Parent : NbrRank {
savedRank = rankNbr.rank;
savedRankNext = rankNbr.rankNbr;
}
/**
* Use the saved rank information to Update the rank of this node.
*/
void updateRank() writes Parent : * {
if (rankNbr != savedRankNext) {
rank += savedRank;
rankNbr = savedRankNext;
}
}
}
/**
* A List composed of ListNodes.
*/
class List {
/**
* An array storing the nodes. Cell nodes[i] lies in region
* Root:[i] and has type ListNode<Root:[i]>.
*/
ListNode<[i]>[]<[i]>#i nodes;
/**
* Construct a new list, of specified size.
*/
List(int size) {
nodes = new ListNode<[i]>[size]<[i]>#i;
foreach (int i in 0, size) {
nodes[i] = new ListNode<Root:[i]>();
}
}
/**
* Rank the list.
*/
public void rank() {
// Initialize the nodes for ranking
foreach (int i in 0, nodes.length) {
nodes[i].initRank();
}
// Repeat log2(nodes.length) times
int i = Utils.log2(nodes.length);
while (i-- > 0) {
// Get the rank information from the rank neighbor
foreach (int j in 0, nodes.length) {
nodes[j].updateNbrRank();
}
// Update the rank information
foreach (int j in 0, nodes.length) {
nodes[j].updateRank();
}
}
}
}
/**
* A test class for list ranking.
*/
class ListRanking extends Harness {
/**
* The list to rank
*/
private List list;
/**
*
*/
private int[] idxs;
/**
* Utility method: swap two values in array A.
*/
private static void swap(int[] A, int i, int j) {
int tmp = A[j];
A[j] = A[i];
A[i] = tmp;
}
/**
* Utility method: create an array containing a random permutation
* of the values 0..size-1.
*/
public static int[] permutation(int size) {
java.util.Random rand = new java.util.Random(10);
int[] result = new int[size];
for (int i = 0; i < size; ++i) {
result[i] = i;
}
for (int i = 0; i < size; ++i) {
int j = (int) (rand.nextFloat() * size);
int k = (int) (rand.nextFloat() * size);
swap(result, j, k);
}
return result;
}
public ListRanking(String[] args) {
super("ListRanking", args, 2, 3);
}
@Override
public void initialize() {
list = new List(size);
idxs = permutation(size);
for (int i = 0; i < size-1; ++i) {
list.nodes[idxs[i]].next = list.nodes[idxs[i+1]];
}
list.nodes[idxs[size-1]].next = list.nodes[idxs[size-1]];
}
@Override
public void runTest() {
for (int i = 0; i < size; ++i) {
assert (list.nodes[idxs[i]].rank == size-i-1);
}
}
@Override
public void runWork() {
list.rank();
}
@Override
public void usage() {
System.err.println("Usage: java " + progName + ".java [mode] [size] [iter_size]");
System.err.println("mode = TEST, IDEAL, TASK_GRAPH");
System.err.println("size = problem size (int)");
System.err.println("iter_size = foreach iterations per task (int)");
}
public static void main(String[] args) {
ListRanking lr = new ListRanking(args);
lr.run();
}
}