use of edu.rit.util.LongRange in project ffx by mjschnie.
the class ParallelRegion method execute.
/**
* Execute a parallel for loop within this parallel region. For further
* information, see class {@linkplain LongStrideForLoop}. The loop index
* goes from <TT>first</TT> (inclusive) to <TT>last</TT> (inclusive) in
* steps of <TT>stride</TT>. The stride must be positive. If <TT>first</TT>
* is greater than <TT>last</TT>, then no loop iterations are performed. At
* the end of the parallel for loop, the parallel team threads encounter a
* barrier, and their behavior depends on the given {@linkplain
* BarrierAction}.
* <P>
* <I>Note:</I> Either all threads in the parallel team must call the
* <TT>execute()</TT> method with identical arguments, or none of the
* threads must call the <TT>execute()</TT> method.
*
* @param first First loop index.
* @param last Last loop index.
* @param stride Loop index stride, >= 1.
* @param theLoop Parallel for loop.
* @param action Barrier action.
* @exception IllegalArgumentException (unchecked exception) Thrown if
* <TT>stride</TT> < 1.
* @exception NullPointerException (unchecked exception) Thrown if
* <TT>theLoop</TT> is null. Thrown if
* <TT>action</TT> is null.
* @exception IllegalStateException (unchecked exception) Thrown if no
* parallel team is executing this parallel region.
* @exception Exception Thrown if one of <TT>theLoop</TT>'s methods throws
* an exception.
* @throws java.lang.Exception if any.
*/
public final void execute(long first, long last, long stride, LongStrideForLoop theLoop, BarrierAction action) throws Exception {
// Verify preconditions.
if (stride <= 0) {
throw new IllegalArgumentException("ParallelRegion.execute(): Stride = " + stride + " illegal");
}
if (theLoop == null) {
throw new NullPointerException("ParallelRegion.execute(): Parallel for loop is null");
}
if (action == null) {
throw new NullPointerException("ParallelRegion.execute(): Barrier action is null");
}
if (myTeam == null) {
throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing");
}
try {
// Record parallel team.
theLoop.myTeam = this.myTeam;
// Get current parallel team thread.
ParallelTeamThread currentThread = getCurrentThread();
int currentIndex = currentThread.myIndex;
// Do top-of-parallel-construct processing.
LongSchedule schedule = null;
if (currentThread.arriveAtParallelConstruct()) {
// each team thread.
try {
schedule = theLoop.schedule();
schedule.commonStart(myTeam.K, new LongRange(first, last, stride));
for (ParallelTeamThread thread : myTeam.myThread) {
thread.setLongSchedule(schedule);
}
} catch (Throwable exc) {
for (ParallelTeamThread thread : myTeam.myThread) {
thread.setConstructException(exc);
}
}
}
// Get the shared parallel for loop schedule object.
schedule = currentThread.getLongSchedule();
theLoop.mySchedule = schedule;
// Prepare to catch exceptions thrown by the parallel for loop body.
Throwable runException = null;
try {
// Perform per-thread initialization.
theLoop.start();
// Repeatedly get and process a chunk of loop iterations.
LongRange chunk;
while ((chunk = schedule.commonNext(currentIndex)) != null) {
theLoop.commonRun(chunk.lb(), chunk.ub(), chunk.stride());
}
// Perform per-thread finalization.
theLoop.finish();
} catch (Throwable exc) {
runException = exc;
schedule.myBreak = true;
}
// Barrier synchronization.
action.doBarrier(currentThread);
// Propagate any exception thrown by the run() method.
ParallelTeam.rethrow(runException);
} finally {
// Forget parallel team.
theLoop.myTeam = null;
theLoop.mySchedule = null;
}
}
use of edu.rit.util.LongRange in project ffx by mjschnie.
the class WorkerRegion method execute.
/**
* Execute a worker for loop within this worker region. For further
* information, see class {@linkplain WorkerLongForLoop}. The loop index
* goes from <TT>first</TT> (inclusive) to <TT>last</TT> (inclusive) in
* steps of +1. If <TT>first</TT> is greater than <TT>last</TT>, then no
* loop iterations are performed.
* <P>
* <I>Note:</I> Either all threads in the worker team must call the
* <TT>execute()</TT> method with identical arguments, or none of the
* threads must call the <TT>execute()</TT> method.
*
* @param first First loop index.
* @param last Last loop index.
* @param theLoop Worker for loop.
* @exception NullPointerException (unchecked exception) Thrown if
* <TT>theLoop</TT> is null.
* @exception IllegalStateException (unchecked exception) Thrown if no
* worker team is executing this worker region.
* @exception Exception Thrown if one of <TT>theLoop</TT>'s methods throws
* an exception.
* @throws java.lang.Exception if any.
*/
public final void execute(long first, long last, WorkerLongForLoop theLoop) throws Exception {
// Verify preconditions.
if (theLoop == null) {
throw new NullPointerException("WorkerRegion.execute(): Worker for loop is null");
}
if (myTeam == null) {
throw new IllegalStateException("WorkerRegion.execute(): No parallel team executing");
}
try {
// Record parallel team.
theLoop.myTeam = this.myTeam;
// Get current parallel team thread.
WorkerTeamThread currentThread = getCurrentThread();
int w = currentThread.myIndex;
// Do master or worker thread processing.
LongRange range = new LongRange(first, last);
if (w == -1) {
theLoop.masterExecute(range);
} else {
theLoop.workerExecute(w, range);
}
} finally {
// Forget parallel team.
theLoop.myTeam = null;
}
}
use of edu.rit.util.LongRange in project ffx by mjschnie.
the class WorkerLongForLoop method workerExecuteNonFixed.
/**
* Execute this worker for loop in a worker thread using a non-fixed
* schedule.
*
* @param w Worker index.
*
* @exception Exception This method may throw any exception.
*/
void workerExecuteNonFixed(int w) throws Exception {
Comm comm = myTeam.comm;
int r = myTeam.masterRank();
int tag = tagFor(w);
start();
ObjectItemBuf<LongRange> buf = ObjectBuf.buffer();
for (; ; ) {
comm.receive(r, tag, buf);
LongRange range = buf.item;
if (range == null) {
break;
}
receiveTaskInput(range, comm, r, tag);
run(range.lb(), range.ub());
// messages, or the master can deadlock.
synchronized (myTeam) {
comm.send(r, tag, buf);
sendTaskOutput(range, comm, r, tag);
}
}
finish();
}
use of edu.rit.util.LongRange in project ffx by mjschnie.
the class WorkerLongForLoop method masterExecuteFixed.
/**
* Execute this worker for loop in the master thread with a fixed schedule.
*
* @param range Loop index range.
* @param sch Schedule.
*
* @exception IOException Thrown if an I/O error occurred.
*/
void masterExecuteFixed(LongRange range, LongSchedule sch) throws IOException {
int count = myTeam.count;
Comm comm = myTeam.comm;
// Send additional task input to each worker.
sch.start(count, range);
for (int w = 0; w < count; ++w) {
LongRange chunk = sch.next(w);
if (chunk != null) {
sendTaskInput(chunk, comm, myTeam.workerRank(w), tagFor(w));
}
}
// Receive additional task output from each worker.
sch.start(count, range);
for (int w = 0; w < count; ++w) {
LongRange chunk = sch.next(w);
if (chunk != null) {
receiveTaskOutput(chunk, comm, myTeam.workerRank(w), tagFor(w));
}
}
}
use of edu.rit.util.LongRange in project ffx by mjschnie.
the class WorkerLongForLoop method masterExecuteNonFixed.
/**
* Execute this worker for loop in the master thread with a non-fixed
* schedule.
*
* @param range Loop index range.
* @param sch Schedule.
*
* @exception IOException Thrown if an I/O error occurred.
*/
void masterExecuteNonFixed(LongRange range, LongSchedule sch) throws IOException {
int count = myTeam.count;
sch.start(count, range);
int remaining = count;
ObjectItemBuf<LongRange> buf = ObjectBuf.buffer();
Range tagRange = new Range(tagFor(0), tagFor(count - 1));
Comm comm = myTeam.comm;
// Send initial task to each worker.
for (int w = 0; w < count; ++w) {
LongRange chunk = sch.next(w);
buf.item = chunk;
buf.reset();
int r = myTeam.workerRank(w);
int tag = tagFor(w);
comm.send(r, tag, buf);
if (chunk == null) {
--remaining;
} else {
sendTaskInput(chunk, comm, r, tag);
}
}
// that worker.
while (remaining > 0) {
CommStatus status = comm.receive(null, tagRange, buf);
LongRange chunk = buf.item;
int r = status.fromRank;
int tag = status.tag;
int w = workerFor(tag);
receiveTaskOutput(chunk, comm, r, tag);
chunk = sch.next(w);
buf.item = chunk;
buf.reset();
comm.send(r, tag, buf);
if (chunk == null) {
--remaining;
} else {
sendTaskInput(chunk, comm, r, tag);
}
}
}