import DPJRuntime.*;
import java.util.Random;
/**
* 8-way split version of merge sort
*/
public class MergeSort8 extends MergeSort {
public MergeSort8(String[] args) {
super("MergeSort8",args);
}
@Override
public <region R1,R2 | R1:* # R2:*>
void sort(ArraySliceInt<R1> A, ArraySliceInt<R2> B)
{
sort(A, B, true);
}
public <region R1,R2 | R1:* # R2:*>
boolean sort(ArraySliceInt<R1> A,
ArraySliceInt<R2> B,
boolean parity)
writes R1:*, R2:*
{
if (A.length <= QUICK_SIZE) {
if(parity)
quickSort(A);
else
quickSort(B);
return parity;
} else {
int q = A.length/8;
ArrayInt<Local> idxs =
new ArrayInt<Local>(7);
idxs[0] = q;
idxs[1] = 2*q;
idxs[2] = 3*q;
idxs[3] = 4*q;
idxs[4] = 5*q;
idxs[5] = 6*q;
idxs[6] = 7*q;
ArrayInt<Local> quart_idxs =
new ArrayInt<Local>(3);
quart_idxs[0] = 2*q;
quart_idxs[1] = 4*q;
quart_idxs[2] = 6*q;
final PartitionInt<R1> A_eighths =
new PartitionInt<R1>(A, idxs);
final PartitionInt<R2> B_eighths =
new PartitionInt<R2>(B, idxs);
final PartitionInt<R1> A_quarters =
new PartitionInt<R1>(A, quart_idxs);
final PartitionInt<R1> A_halves =
new PartitionInt<R1>(A, 4*q);
final PartitionInt<R2> B_quarters =
new PartitionInt<R2>(B, quart_idxs);
final PartitionInt<R2> B_halves =
new PartitionInt<R2>(B, 4*q);
boolean subparity;
cobegin {
subparity =
sort(A_eighths.get(0),
B_eighths.get(0),
parity);
sort(A_eighths.get(1),
B_eighths.get(1),
parity);
sort(A_eighths.get(2),
B_eighths.get(2),
parity);
sort(A_eighths.get(3),
B_eighths.get(3),
parity);
sort(A_eighths.get(4),
B_eighths.get(4),
parity);
sort(A_eighths.get(5),
B_eighths.get(5),
parity);
sort(A_eighths.get(6),
B_eighths.get(6),
parity);
sort(A_eighths.get(7),
B_eighths.get(7),
parity);
}
if (subparity) {
sort_quarters(A_eighths, B_quarters);
sort_halves(A_quarters, B_halves);
merge(A_halves.get(0), A_halves.get(1), B);
} else {
sort_quarters(B_eighths, A_quarters);
sort_halves(B_quarters, A_halves);
merge(B_halves.get(0), B_halves.get(1), A);
}
return !subparity;
}
}
private static <region R1,R2 | R1:* # R2:*>void
sort_quarters(final PartitionInt<R1> A_eighths,
final PartitionInt<R2> B_quarters)
reads R1:* writes R2:* {
cobegin {
merge(A_eighths.get(0),
A_eighths.get(1),
B_quarters.get(0));
merge(A_eighths.get(2),
A_eighths.get(3),
B_quarters.get(1));
merge(A_eighths.get(4),
A_eighths.get(5),
B_quarters.get(2));
merge(A_eighths.get(6),
A_eighths.get(7),
B_quarters.get(3));
}
}
private static <region R1,R2 | R1:*#R2:*>void
sort_halves(final PartitionInt<R1> quarters,
final PartitionInt<R2> halves)
reads R1:* writes R2:* {
cobegin {
merge(quarters.get(0),
quarters.get(1),
halves.get(0));
merge(quarters.get(2),
quarters.get(3),
halves.get(1));
}
}
public static void main(String[] args) {
MergeSort8 ms = new MergeSort8(args);
ms.run();
}
}