new matrix multiply
authorjihoonl <jihoonl>
Wed, 14 Apr 2010 15:59:34 +0000 (15:59 +0000)
committerjihoonl <jihoonl>
Wed, 14 Apr 2010 15:59:34 +0000 (15:59 +0000)
Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/GlobalQueue.java [new file with mode: 0644]
Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/MatrixMultiply.java
Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/Task.java [new file with mode: 0644]
Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/TaskSet.java [new file with mode: 0644]
Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/Worker.java [new file with mode: 0644]
Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/makefile

diff --git a/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/GlobalQueue.java b/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/GlobalQueue.java
new file mode 100644 (file)
index 0000000..275d946
--- /dev/null
@@ -0,0 +1,187 @@
+/* =============================================================================
+ *
+ * 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
+ *
+ * =============================================================================
+ */
index 815297fb2c4d1fd80b6550db9054bd65809ad96a..e8420430fa129050173bd507e756040f42bf25f1 100644 (file)
@@ -9,37 +9,14 @@ public class MatrixMultiply extends Task {
   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() {
@@ -48,7 +25,6 @@ public class MatrixMultiply extends Task {
     double lb[][];
     double rowA[];
     double colB[];
-    Segment seg;
 
     double innerproduct;
     int i,j;
@@ -56,20 +32,17 @@ public class MatrixMultiply extends Task {
     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];
@@ -79,14 +52,16 @@ public class MatrixMultiply extends Task {
           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)
@@ -111,10 +86,9 @@ public class MatrixMultiply extends Task {
     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]);
@@ -127,55 +101,72 @@ public class MatrixMultiply extends Task {
     }
 
     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();
@@ -260,13 +251,4 @@ public class MMul{
   }
 }
 
-public class Segment {
-  int x0;
-  int x1;
-
-  Segment (int x0, int x1) {
-    this.x0 = x0;
-    this.x1 = x1;
-  }
-}
 
diff --git a/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/Task.java b/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/Task.java
new file mode 100644 (file)
index 0000000..219b1f1
--- /dev/null
@@ -0,0 +1,15 @@
+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();
+}
diff --git a/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/TaskSet.java b/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/TaskSet.java
new file mode 100644 (file)
index 0000000..c88182d
--- /dev/null
@@ -0,0 +1,13 @@
+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;
+}
diff --git a/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/Worker.java b/Robust/src/Benchmarks/Recovery/MatrixMultiply/recovery/Worker.java
new file mode 100644 (file)
index 0000000..954ac6d
--- /dev/null
@@ -0,0 +1,62 @@
+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();
+}
index f7d4e012076a1ea6de54be23dc52702a7013d855..07e173bed87263f5c169cc36f4a35fffa389627a 100644 (file)
@@ -3,10 +3,12 @@ SRC1=${MAINCLASS}.java \
 
 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