--- /dev/null
+/* =============================================================================
+ *
+ * queue.java
+ *
+ * =============================================================================
+ *
+ * Copyright (C) Stanford University, 2006. All Rights Reserved.
+ * Author: Chi Cao Minh
+ *
+ * Ported to Java
+ * Author:Alokika Dash
+ * University of California, Irvine
+ *
+ * =============================================================================
+ *
+ * Unless otherwise noted, the following license applies to STAMP files:
+ *
+ * Copyright (c) 2007, Stanford University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Stanford University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * =============================================================================
+ */
+
+public class GlobalQueue{
+ int pop; /* points before element to pop */
+ int push;
+ int capacity;
+ int size;
+ int QUEUE_GROWTH_FACTOR;
+ Object[] elements;
+
+ public GlobalQueue() {
+ GlobalQueue(10);
+ }
+
+ /* =============================================================================
+ * queue_alloc
+ * =============================================================================
+ */
+ public GlobalQueue (int initCapacity)
+ {
+ QUEUE_GROWTH_FACTOR = 2;
+ capacity = ((initCapacity < 2) ? 2 : initCapacity);
+
+ elements = global new Object[capacity];
+ size = 0;
+ pop = capacity - 1;
+ push = 0;
+ capacity = capacity;
+ }
+
+ /* =============================================================================
+ * queue_isEmpty
+ * =============================================================================
+ */
+ public boolean
+ isEmpty ()
+ {
+ return (((pop + 1) % capacity == push) ? true : false);
+ }
+
+
+ /* =============================================================================
+ * queue_clear
+ * =============================================================================
+ */
+ public void
+ queue_clear ()
+ {
+ pop = capacity - 1;
+ push = 0;
+ }
+
+ /* =============================================================================
+ * queue_push
+ * =============================================================================
+ */
+ public boolean
+ push (Object dataPtr)
+ {
+ if(pop == push) {
+// System.out.println("push == pop in Queue.java");
+ return false;
+ }
+
+ /* Need to resize */
+ int newPush = (push + 1) % capacity;
+ if (newPush == pop) {
+
+ int newCapacity = capacity * QUEUE_GROWTH_FACTOR;
+ Object[] newElements = global new Object[newCapacity];
+
+ if (newElements == null) {
+ return false;
+ }
+
+ int dst = 0;
+ Object[] tmpelements = elements;
+ if (pop < push) {
+ int src;
+ for (src = (pop + 1); src < push; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ } else {
+ int src;
+ for (src = (pop + 1); src < capacity; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ for (src = 0; src < push; src++, dst++) {
+ newElements[dst] = elements[src];
+ }
+ }
+
+ //elements = null;
+ elements = newElements;
+ pop = newCapacity - 1;
+ capacity = newCapacity;
+ push = dst;
+ newPush = push + 1; /* no need modulo */
+ }
+ size++;
+ elements[push] = dataPtr;
+ push = newPush;
+
+ return true;
+ }
+
+
+ /* =============================================================================
+ * queue_pop
+ * =============================================================================
+ */
+ public Object
+ pop ()
+ {
+ int newPop = (pop + 1) % capacity;
+ if (newPop == push) {
+ return null;
+ }
+
+ //Object dataPtr = queuePtr.elements[newPop];
+ //queuePtr.pop = newPop;
+ Object dataPtr = elements[newPop];
+ pop = newPop;
+ size--;
+ return dataPtr;
+ }
+ public int size()
+ {
+ return size;
+ }
+
+}
+/* =============================================================================
+ *
+ * End of queue.java
+ *
+ * =============================================================================
+ */
MMul mmul;
int SIZE;
int increment;
+ int x0;
+ int x1;
- public MatrixMultiply(MMul mmul, int num_threads, int size,int increment) {
+ public MatrixMultiply(MMul mmul, int num_threads,int size,int x0,int x1) {
this.mmul = mmul;
-
- SIZE = size;
- this.increment = increment;
-
- init();
- }
-
- public void init() {
- todoList = global new GlobalQueue();
-
- fillTodoList();
- }
-
- // fill up the Work Pool
- public void fillTodoList() {
- Segment seg;
- int i;
-
- for(i = 0; i < SIZE; i +=increment) {
-
- if(i+increment > SIZE) {
- seg = global new Segment(i,SIZE);
- }
- else {
- seg = global new Segment(i, i + increment);
- }
- todoList.push(seg);
- }
+ this.SIZE = size;
+ this.x0 = x0;
+ this.x1 = x1;
}
public void execute() {
double lb[][];
double rowA[];
double colB[];
- Segment seg;
double innerproduct;
int i,j;
int x1;
int size;
-
// get matrix
atomic {
- seg = (Segment)myWork;
- x0 = seg.x0; // x start row
- x1 = seg.x1; // x end row
+ x0 = this.x0;
+ x1 = this.x1;
la = mmul.a; // first mat
lb = mmul.btranspose; // second mat
size = SIZE;
- }
+
lc = new double[size][size];
- atomic {
for(i = x0; i < x1 ; i++) {
rowA = la[i]; // grab first mat's row
double c[] = lc[i];
c[j] = innerproduct; // store in dest mat
} // end of for j
}
- }
- atomic {
for (i = x0; i < x1; i++) {
for (j = 0; j < size; j++) {
mmul.c[i][j] = lc[i][j];
}
}
}
+
+ atomic {
+ dequeueTask();
+ }
}
public double computeProduct(double[] rowA,double[] colB, int size)
int SIZE = 1600;
int increment = 80;
int i,j;
- Work[] works;
MMul matrix;
MatrixMultiply mm;
- Segment[] currentWorkList;
+ TaskSet ts;
if (args.length == 3) {
NUM_THREADS = Integer.parseInt(args[0]);
}
int[] mid = new int[8];
- /* mid[0] = (128<<24)|(195<<16)|(180<<8)|21; //dw-2
- mid[1] = (128<<24)|(195<<16)|(180<<8)|26; //dw-7*/
- mid[2] = (128<<24)|(195<<16)|(180<<8)|26; //dw-7
- mid[0] = (128<<24)|(195<<16)|(180<<8)|20; //dw-1
- mid[0] = (128<<24)|(195<<16)|(136<<8)|162; //dc1
+ /*
+ mid[0] = (128<<24)|(195<<16)|(180<<8)|21; //dw-2
+ mid[1] = (128<<24)|(195<<16)|(180<<8)|26; //dw-7
+ mid[2] = (128<<24)|(195<<16)|(180<<8)|24; //dw-5
+*/
+
+// mid[0] = (128<<24)|(195<<16)|(180<<8)|20; //dw-1
+/* mid[0] = (128<<24)|(195<<16)|(136<<8)|162; //dc1
mid[1] = (128<<24)|(195<<16)|(136<<8)|163; //dc2
mid[2] = (128<<24)|(195<<16)|(136<<8)|164; //dc3
- mid[3] = (128<<24)|(195<<16)|(136<<8)|165; //dc4
- mid[4] = (128<<24)|(195<<16)|(136<<8)|166; //dc5
- mid[5] = (128<<24)|(195<<16)|(136<<8)|167; //dc6
- mid[6] = (128<<24)|(195<<16)|(136<<8)|168; //dc7
- mid[7] = (128<<24)|(195<<16)|(136<<8)|169; //dc8
+ mid[3] = (128<<24)|(195<<16)|(136<<8)|165; //dc4*/
+ mid[0] = (128<<24)|(195<<16)|(136<<8)|166; //dc5
+ mid[1] = (128<<24)|(195<<16)|(136<<8)|167; //dc6
+ mid[2] = (128<<24)|(195<<16)|(136<<8)|168; //dc7
+ mid[3] = (128<<24)|(195<<16)|(136<<8)|169; //dc8
+
+
+ atomic {
+ ts = global new TaskSet(NUM_THREADS);
+
+ for( i = 0; i< NUM_THREADS; i++) {
+ ts.threads[i] = global new Worker(ts,i);
+ }
+ }
atomic {
matrix = global new MMul(SIZE, SIZE, SIZE);
matrix.setValues();
matrix.transpose();
- mm = global new MatrixMultiply(matrix, NUM_THREADS, SIZE,increment);
-
- works = global new Work[NUM_THREADS];
- currentWorkList = global new Segment[NUM_THREADS];
- for(i = 0; i < NUM_THREADS; i++) {
- works[i] = global new Work(mm, NUM_THREADS, i,currentWorkList);
+ for(i = 0; i < SIZE; i +=increment) {
+ if(i+increment > SIZE) {
+ mm = global new MatrixMultiply(matrix, NUM_THREADS,SIZE,i, SIZE);
+ }
+ else {
+ mm = global new MatrixMultiply(matrix, NUM_THREADS,SIZE, i, i + increment);
+ }
+ ts.todo.push(mm);
}
+
}
//long st = System.currentTimeMillis();
//long fi;
- Work tmp;
+ Worker tmp;
for (i = 0; i < NUM_THREADS; i++) {
atomic {
- tmp = works[i];
+ tmp = ts.threads[i];
}
Thread.myStart(tmp,mid[i]);
}
- fi = System.currentTimeMillis();
- System.out.println("Time Elapse = " + (double)((fi-st)/1000));
+ while(true) {
+ Thread.sleep(200000);
+ }
for (i = 0; i < NUM_THREADS; i++) {
atomic {
- tmp = works[i];
+ tmp = ts.threads[i];
}
tmp.join();
}
//fi = System.currentTimeMillis();
+// System.out.println("Time Elapse = " + (double)((fi-st)/1000));
double sum= 0;
atomic {
sum = matrix.getSum();
}
}
-public class Segment {
- int x0;
- int x1;
-
- Segment (int x0, int x1) {
- this.x0 = x0;
- this.x1 = x1;
- }
-}
--- /dev/null
+public class Task {
+ //Current worker thread
+ Worker w;
+ public void execute();
+ public void setWorker(Worker w) {
+ this.w = w;
+ }
+ public void dequeueTask() {
+ w.workingtask=null;
+ }
+ public void enqueueTask(Task t) {
+ w.tasks.todo.push(t);
+ }
+ public native void execution();
+}
--- /dev/null
+public class TaskSet {
+ public TaskSet(int nt) {
+ numthreads=nt;
+ threads=global new Worker[nt];
+ todo=global new GlobalQueue();
+ }
+
+ //Tasks to be executed
+ GlobalQueue todo;
+ //Vector of worker threads
+ Worker threads[];
+ int numthreads;
+}
--- /dev/null
+public class Worker extends Thread {
+ Object[] currentWorkList;
+ int mid;
+ TaskSet tasks;
+ Task workingtask;
+
+ Worker(TaskSet tasks, int mid) {
+ this.tasks = tasks;
+ this.currentWorkList = currentWorkList;
+ mid = mid;
+ }
+
+ public void run() {
+ boolean notdone=true;
+
+ while(notdone) {
+ Task t=null;
+ atomic {
+ if (!tasks.todo.isEmpty()) {
+ //grab segment from todo list
+ t=workingtask=(Task) tasks.todo.pop();
+ t.setWorker(this);
+ }
+ else {
+ //steal work from dead threads
+ Worker[] threads=tasks.threads;
+ boolean shouldexit=true;
+
+ for(int i=0;i<threads.length;i++) {
+ Worker w=(Worker)threads[i];
+
+ if (w.workingtask!=null)
+ shouldexit=false;
+
+ if (w.getStatus(i)==-1&&w.workingtask!=null) {
+ //steal work from this thread
+ t=workingtask=w.workingtask;
+ w.workingtask=null;
+ t.setWorker(this);
+ break;
+ }
+ }
+
+ if (shouldexit)
+ notdone=false;
+ }
+ }
+
+ if (t!=null) {
+ t.execution();
+ continue;
+ }
+ else if(notdone)
+ {
+ sleep(500000);
+ }
+ }
+
+ System.out.println("done");
+ }
+ public static native void printRecoveryStat();
+}
FLAGS=-recovery -recoverystats -dsm -dsmtask -transstats -prefetch -dsmcaching -32bit -optimize -mainclass ${MAINCLASS} -excprefetch Task.isTodoListEmpty -excprefetch MatrixMultiply.output -excprefetch GlobalQueue.push -excprefetch MatrixMultiply.fillTodoList -excprefetch GlobalQueue.pop -excprefetch MatrixMultiply.main -excprefetch MMul.setValues -excprefetch MMul.transpose -excprefetch Work.checkCurrentWorkList -excprefetch MMul.getSum -excprefetch Task.grabTask
DSMFLAGS= -dsm -dsmtask -transstats -prefetch -dsmcaching -32bit -optimize -mainclass ${MAINCLASS} -excprefetch Task.isTodoListEmpty -excprefetch MatrixMultiply.output -excprefetch GlobalQueue.push -excprefetch MatrixMultiply.fillTodoList -excprefetch GlobalQueue.pop -excprefetch MatrixMultiply.main -excprefetch MMul.setValues -excprefetch MMul.transpose -excprefetch Work.checkCurrentWorkList -excprefetch MMul.getSum -excprefetch Task.grabTask
+RECOVERYFLAGS=-recovery -dsm -dsmtask -nooptimize -debug -mainclass ${MAINCLASS}
default:
- ../../../../buildscript ${FLAGS} -o ${MAINCLASS} ${SRC1}
- ../../../../buildscript ${DSMFLAGS} -o ${MAINCLASS}DSM ${SRC1}
+# ../../../../buildscript ${FLAGS} -o ${MAINCLASS} ${SRC1}
+# ../../../../buildscript ${DSMFLAGS} -o ${MAINCLASS}DSM ${SRC1}
+ ../../../../buildscript ${RECOVERYFLAGS} -o ${MAINCLASS} ${SRC1}
clean:
rm -rf tmpbuilddirectory