charj: jacobi app with charm equivalent
authorAaron Becker <akbecker@gmail.com>
Fri, 22 Jun 2012 14:43:39 +0000 (09:43 -0500)
committerAaron Becker <akbecker@gmail.com>
Fri, 22 Jun 2012 14:43:39 +0000 (09:43 -0500)
17 files changed:
src/langs/charj/tests/jacobi/Makefile [new file with mode: 0644]
src/langs/charj/tests/jacobi/TODOS [new file with mode: 0644]
src/langs/charj/tests/jacobi/chunk.cj [new file with mode: 0644]
src/langs/charj/tests/jacobi/hand_translation/Makefile [new file with mode: 0644]
src/langs/charj/tests/jacobi/hand_translation/chunk.cj [new file with mode: 0644]
src/langs/charj/tests/jacobi/hand_translation/jacobi.cc [new file with mode: 0644]
src/langs/charj/tests/jacobi/hand_translation/jacobi.ci [new file with mode: 0644]
src/langs/charj/tests/jacobi/hand_translation/jacobi.cj [new file with mode: 0644]
src/langs/charj/tests/jacobi/hand_translation/jacobi.h [new file with mode: 0644]
src/langs/charj/tests/jacobi/jacobi.cj [new file with mode: 0644]
src/langs/charj/tests/jacobi/reference/Makefile [new file with mode: 0644]
src/langs/charj/tests/jacobi/reference/bg_config [new file with mode: 0644]
src/langs/charj/tests/jacobi/reference/jacobi [new file with mode: 0755]
src/langs/charj/tests/jacobi/reference/parallelJacobi.C [new file with mode: 0644]
src/langs/charj/tests/jacobi/reference/parallelJacobi.ci [new file with mode: 0644]
src/langs/charj/tests/jacobi/reference/parallelJacobi.h [new file with mode: 0644]
src/langs/charj/tests/jacobi/sendstrips.cj [new file with mode: 0644]

diff --git a/src/langs/charj/tests/jacobi/Makefile b/src/langs/charj/tests/jacobi/Makefile
new file mode 100644 (file)
index 0000000..4489b19
--- /dev/null
@@ -0,0 +1,17 @@
+
+CHARJC=../../bin/charjc
+#CJFLAGS=--debug --verbose --AST --stdout --translate-only
+#CJFLAGS=--translate-only --AST
+CJFLAGS=--translate-only
+
+.PHONY: all clean jacobi chunk
+all: jacobi chunk
+
+jacobi:
+       $(CHARJC) $(CJFLAGS) jacobi.cj
+
+chunk:
+       $(CHARJC) $(CJFLAGS) chunk.cj
+
+clean:
+       rm -rf *.gen *.h *.o charmrun jacobi jacobi_pre.cj 
diff --git a/src/langs/charj/tests/jacobi/TODOS b/src/langs/charj/tests/jacobi/TODOS
new file mode 100644 (file)
index 0000000..2abae13
--- /dev/null
@@ -0,0 +1,15 @@
+
+chunks and main in same file gives weird emitter bug
+(void) argument in sdag triggers codegen
+.decl.h include should come after other includes, not before
+    also after 'using' statements (for CharjArray::Array)
+multiple pointer types declared together are wrong
+    ie X x, y => X* x, y;, which is wrong
+single literal for array element index gives error
+we're dereferencing chare array ids as though they were local pointers
+only the first array access in an expression rhs gets translated correctly
+    eg, B[i] = 0.5 * (A[i] + A[j]) leaves A[j] untranslated to an access call
+    same problem for function arguments
+local pointers to arguments in entry methods omit template types
+sdag translator doesn't like extra set of braces around sdag func bodies
+    ie entry void x() {{ body text }}
diff --git a/src/langs/charj/tests/jacobi/chunk.cj b/src/langs/charj/tests/jacobi/chunk.cj
new file mode 100644 (file)
index 0000000..76203e2
--- /dev/null
@@ -0,0 +1,138 @@
+
+chare_array [1D] Chunk {
+    Array<double, 2> A, B;
+    double myMax;
+    int myxdim, myydim, total, counter;
+
+    entry Chunk(int t, int x, int y) {
+        int xdim,ydim;
+        xdim = x;
+        ydim = y;
+        total = t; 
+        myMax = 99999.999;
+
+        myxdim = (int)(xdim/total);
+        if(thisIndex == total-1) myxdim = xdim - myxdim*(total-1);    
+        myydim = ydim;
+        counter = 0;
+
+        if (thisIndex != 0 && thisIndex != total-1) {
+            xdim = myxdim+2;
+        } else {
+            xdim = myxdim+1;
+        }
+        A = new Array<double, 2>([xdim, myydim]);
+        B = new Array<double, 2>([xdim, myydim]);
+        A.fill(0);
+        B.fill(0);
+    }
+
+    void sendStrips() {
+        Array<double> strip = new Array<double>(myydim);
+
+        if(thisIndex > 0) {
+            for(int i=0;i<myydim;i++) strip[i] = A[1,i];
+            chunks[thisIndex-1]@getStripFromRight(strip);
+        } else {
+            //Send dummy if thisIndex==0 for dagger to work
+            chunks[total-1]@getStripFromRight(strip);
+        }
+
+        if(thisIndex < total-1) {
+            for(int i=0;i<myydim;i++) strip[i] = A[myxdim,i];
+            chunks[thisIndex+1]@getStripFromLeft(strip);
+        } else {
+            //Send dummy if thisIndex==total-1:For dagger to work
+            chunks[0+0]@getStripFromLeft(strip);
+        }
+    }
+
+    void doStencil() {
+        double maxChange = 0.0;
+        resetBoundary();
+
+        if((thisIndex !=0)&&(thisIndex != total-1))
+            for (int i=1; i<myxdim+1; i++)
+                for (int j=1; j<myydim-1; j++) {
+                    B[i,j] = (0.2)*(A[i,j] + A[i,j+1] + A[i,j-1] + A[i+1,j] + A[i-1,j]);
+                    double change = B[i,j] - A[i,j];
+                    if (change < 0) change = - change;
+                    if (change > maxChange) maxChange = change;
+                }
+
+        if(thisIndex == 0)
+            for (int i=1; i<myxdim; i++)
+                for (int j=1; j<myydim-1; j++) {
+                    B[i,j] = (0.2)*(A[i,j] + A[i,j+1] + A[i,j-1] + A[i+1,j] + A[i-1,j]);
+                    double change = B[i,j] - A[i,j];
+                    if (change < 0) change = - change;
+                    if (change > maxChange) maxChange = change;
+                }
+
+        if(thisIndex == total-1) {
+            for (int i=1; i<myxdim; i++)
+                for (int j=1; j<myydim-1; j++) {
+                    B[i,j] = (0.2)*(A[i,j] + A[i,j+1] + A[i,j-1] + A[i+1,j] + A[i-1,j]);
+                    double change =  B[i,j] - A[i,j];
+                    if (change < 0) change = - change;
+                    if (change > maxChange) maxChange = change;
+                }
+        }
+
+        Array<double, 2> tmp = A;
+        A = B;
+        B = tmp;  
+    }
+
+    void resetBoundary() {
+         if (thisIndex != 0)
+            if (thisIndex < (int)(total/2))
+                for (int i=1; i<myxdim+1; i++)
+                    A[i,0] = 1.0;
+
+        if (thisIndex ==0) {
+            for (int i=0; i<myxdim; i++)
+                A[i,0] = 1.0;
+
+            for (int i=0; 2*i<myydim; i++) 
+                A[0,i] = 1.0;
+        }
+    }
+
+    entry void processStripFromLeft(Array<double> s) {
+        if (thisIndex !=0) {
+            for (int i=0; i<myydim; i++)
+                A[0,i] = s[i];
+        }
+    }
+
+    entry void processStripFromRight(Array<double> s) {
+        if (thisIndex != total - 1) {
+            if (thisIndex != 0)
+                for (int i=0; i<myydim; i++)
+                    A[myxdim+1,i] = s[i];
+            else
+                for (int i=0; i<myydim; i++)
+                    A[myxdim,i] = s[i];
+        }
+    }
+    
+    entry void jacobi() {
+        for (int i=0; i<3; ++i) {
+            sendStrips();
+            overlap {
+                when getStripFromLeft(Array<double> s) {
+                    processStripFromLeft(s);
+                }
+                when getStripFromRight(Array<double> s) {
+                    processStripFromRight(s);
+                }
+            }
+            doStencil();
+            if (CkMyPe() == 0) {
+                CkPrintf("Numfin=%d, total=%d, Pes = %d\n",i,total,CkNumPes());
+            }
+        }
+        CkExit();
+    }
+}
diff --git a/src/langs/charj/tests/jacobi/hand_translation/Makefile b/src/langs/charj/tests/jacobi/hand_translation/Makefile
new file mode 100644 (file)
index 0000000..2d49344
--- /dev/null
@@ -0,0 +1,27 @@
+CHARMC = charmc
+BINARY = jacobi
+
+CHARMCFLAGS = $(OPTS) -g -I/Users/abecker/src/charm/src/langs/charj/src/charj/libs
+CHARMCLINKFLAGS = -language charm++
+TESTFLAGS = $(TESTOPTS)
+
+%.o: %.cc
+
+all: $(BINARY)
+$(BINARY): $(patsubst %.cc,%.o,$(wildcard *.cc))
+       $(CHARMC) $(CHARMCLINKFLAGS) -o $@ $+ 
+
+.SECONDARY: $(patsubst %.cc,%.decl.h,$(wildcard *.cc))
+.SECONDARY: $(patsubst %.cc,%.def.h,$(wildcard *.cc))
+
+%.o: %.cc %.decl.h %.def.h
+       $(CHARMC) $(CHARMCFLAGS) $<
+
+%.decl.h %.def.h: %.ci
+       $(CHARMC) $(CHARMCFLAGS) $<
+
+test: $(BINARY)
+       ./charmrun ./$(BINARY) $(TESTFLAGS)
+
+clean:
+       rm -f *.o *.decl.h *.def.h charmrun $(BINARY)
diff --git a/src/langs/charj/tests/jacobi/hand_translation/chunk.cj b/src/langs/charj/tests/jacobi/hand_translation/chunk.cj
new file mode 100644 (file)
index 0000000..7ed9a58
--- /dev/null
@@ -0,0 +1,136 @@
+
+chare_array [1D] Chunk {
+    Array<double, 2> A, B;
+    double myMax;
+    int myxdim, myydim, total, counter;
+
+    entry Chunk(int t, int x, int y) {
+        int xdim,ydim;
+        xdim = x;
+        ydim = y;
+        total = t; 
+        myMax = 99999.999;
+
+        myxdim = (int)(xdim/total);
+        if(thisIndex == total-1) myxdim = xdim - myxdim*(total-1);    
+        myydim = ydim;
+        counter = 0;
+
+        if (thisIndex != 0 && thisIndex != total-1) {
+            xdim = myxdim+2;
+        } else {
+            xdim = myxdim+1;
+        }
+        A = new Array<double, 2>([xdim, myydim]);
+        B = new Array<double, 2>([xdim, myydim]);
+        A.fill(0);
+        B.fill(0);
+    }
+
+    void sendStrips() {
+        Array<double, 2> s;
+        if(thisIndex > 0) {
+            s = A[1, 0:myydim];
+            chunks[thisIndex-1]@getStripfromright(s);
+        } else {
+            //Send dummy if thisIndex==0 for dagger to work
+        //    chunks[total-1]@getStripfromright(A[1, 0:1]);
+        }
+
+        if(thisIndex < total-1) {
+        //    chunks[thisIndex+1]@getStripfromleft(A[myxdim, 0:myydim]);
+        } else {
+            //Send dummy if thisIndex==total-1:For dagger to work
+        //    chunks[0+0]@getStripfromleft(A[myxdim, 0:1]);
+        }
+    }
+
+    void doStencil() {
+        double maxChange = 0.0;
+        resetBoundary();
+
+        if((thisIndex !=0)&&(thisIndex != total-1))
+            for (int i=1; i<myxdim+1; i++)
+                for (int j=1; j<myydim-1; j++) {
+                    B[i,j] = (0.2)*(A[i,j] + A[i,j+1] + A[i,j-1] + A[i+1,j] + A[i-1,j]);
+                    double change = B[i,j] - A[i,j];
+                    if (change < 0) change = - change;
+                    if (change > maxChange) maxChange = change;
+                }
+
+        if(thisIndex == 0)
+            for (int i=1; i<myxdim; i++)
+                for (int j=1; j<myydim-1; j++) {
+                    B[i,j] = (0.2)*(A[i,j] + A[i,j+1] + A[i,j-1] + A[i+1,j] + A[i-1,j]);
+                    double change = B[i,j] - A[i,j];
+                    if (change < 0) change = - change;
+                    if (change > maxChange) maxChange = change;
+                }
+
+        if(thisIndex == total-1) {
+            for (int i=1; i<myxdim; i++)
+                for (int j=1; j<myydim-1; j++) {
+                    B[i,j] = (0.2)*(A[i,j] + A[i,j+1] + A[i,j-1] + A[i+1,j] + A[i-1,j]);
+                    double change =  B[i,j] - A[i,j];
+                    if (change < 0) change = - change;
+                    if (change > maxChange) maxChange = change;
+                }
+        }
+
+        Array<double, 2> tmp = A;
+        A = B;
+        B = tmp;  
+    }
+
+    void resetBoundary() {
+         if (thisIndex != 0)
+            if (thisIndex < (int)(total/2))
+                for (int i=1; i<myxdim+1; i++)
+                    A[i,0] = 1.0;
+
+        if (thisIndex ==0) {
+            for (int i=0; i<myxdim; i++)
+                A[i,0] = 1.0;
+
+            for (int i=0; 2*i<myydim; i++) 
+                A[0,i] = 1.0;
+        }
+    }
+
+    entry void processStripFromLeft(Array<double> s) {
+        if (thisIndex !=0) {
+            for (int i=0; i<myydim; i++)
+                A[0,i] = s[i];
+        }
+    }
+
+    entry void processStripFromRight(Array<double> s) {
+        if (thisIndex != total - 1) {
+            if (thisIndex != 0)
+                for (int i=0; i<myydim; i++)
+                    A[myxdim+1,i] = s[i];
+            else
+                for (int i=0; i<myydim; i++)
+                    A[myxdim,i] = s[i];
+        }
+    }
+    
+    entry void jacobi() {
+        for (int i=0; i<3; ++i) {
+            sendStrips();
+            overlap {
+                when getStripFromLeft(Array<double> s) {
+                    processStripFromLeft(s);
+                }
+                when getStripFromRight(Array<double> s) {
+                    processStripFromRight(s);
+                }
+            }
+            doStencil();
+            if (CkMyPe() == 0) {
+                CkPrintf("Numfin=%d, total=%d, Pes = %d\n",i,total,CkNumPes());
+            }
+        }
+        CkExit();
+    }
+}
diff --git a/src/langs/charj/tests/jacobi/hand_translation/jacobi.cc b/src/langs/charj/tests/jacobi/hand_translation/jacobi.cc
new file mode 100644 (file)
index 0000000..3c38dd7
--- /dev/null
@@ -0,0 +1,264 @@
+#include "jacobi.h"
+
+/* Readonly variable support */
+CProxy_Main main_proxy;
+CProxy_Chunk chunks;
+int num_finished;
+double start_time;
+
+Main::Main(CkArgMsg* m)
+{
+    if (m->argc != 4) CkAbort("Wrong parameters\n");
+    int x = atoi((m->argv)[1]);
+    int y = atoi((m->argv)[2]);
+    int k = atoi((m->argv)[3]);
+    if (x < k) CkAbort("Xdim must be greater than k");
+    if (k < CkNumPes() || k % CkNumPes()) CkAbort("k must be a multiple of numPes.");
+    chunks = CProxy_Chunk::ckNew(k, x, y, k);
+    chunks.jacobi();
+    num_finished = 0;
+    start_time = CmiWallTimer();
+}
+//#include "Main.def.h"
+
+//#include "jacobi_readonly.def.h"
+
+//#include "Chunk.decl.h"
+#if _CHARJ_TRACE_ALL_METHODS || _CHARJ_TRACE_TRACED_METHODS
+#include <trace-projections.h>
+#endif
+Chunk::Chunk(int t, int x, int y)
+{
+    constructorHelper();
+    int xdim, ydim;
+    xdim = x;
+    ydim = y;
+    total = t;
+    myMax = 99999.999;
+    myxdim = (int)(xdim / total);
+    if (thisIndex == total - 1) {
+        myxdim = xdim - myxdim * (total - 1);
+    }
+    myydim = ydim;
+    counter = 0;
+    if (thisIndex != 0 && thisIndex != total - 1) {
+        xdim = myxdim + 2;
+    } else {
+        xdim = myxdim + 1;
+    }
+    A = new Array<double, 2>(Domain<2>(Range(xdim), Range(myydim)));
+    B = new Array<double, 2>(Domain<2>(Range(xdim), Range(myydim)));
+    A->fill(0);
+    B->fill(0);
+    strip = new Array<double>(Domain<1>(Range(myydim)));
+}
+
+void Chunk::sendStrips()
+{
+        //Array<double>* dummy = new Array<double>(Domain<1>(Range(myydim)));
+        //int left = thisIndex - 1;
+        //int right = thisIndex + 1;
+        //int max = total - 1;
+        //if (thisIndex > 0) {
+        //    chunks[left].getStripFromRight((A->access(1, Range(0,myydim))));
+        //} else {
+        //    chunks[max].getStripFromRight(*(dummy));
+        //}
+        //if (thisIndex < total - 1) {
+        //    chunks[right].getStripFromLeft((A->access(myxdim, Range(0,myydim))));
+        //} else {
+        //    chunks[0].getStripFromLeft(*(dummy));
+        //}
+
+        //Array<double>* strip = new Array<double>(Domain<1>(Range(myydim)));
+        if (thisIndex > 0) {
+            for (int i = 0; i < myydim; i++) {
+                (*(strip)).access(i) = (A->access(1, i));
+            }
+            chunks[thisIndex - 1].getStripFromRight(*(strip));
+        } else {
+            chunks[total - 1].getStripFromRight(*(strip));
+        }
+        if (thisIndex < total - 1) {
+            for (int i = 0; i < myydim; i++) {
+                (*(strip)).access(i) = (A->access(myxdim, i));
+            }
+            chunks[thisIndex + 1].getStripFromLeft(*(strip));
+        } else {
+            chunks[0].getStripFromLeft(*(strip));
+        }
+}
+
+void Chunk::doStencil()
+{
+    #if _CHARJ_TRACE_ALL_METHODS
+    int _charj_method_trace_timer = CkWallTimer();
+    #endif
+    {
+        double maxChange = 0.0;
+        resetBoundary();
+        if ((thisIndex != 0) && (thisIndex != total - 1)) {
+            for (int i = 1; i < myxdim + 1; i++) {
+                for (int j = 1; j < myydim - 1; j++) {
+                    (*(B)).access(i, j) = (0.2) * ((*(A)).access(i, j) + (A->access(i, j + 1)) + (A->access(i, j - 1)) + (A->access(i + 1, j)) + (A->access(i - 1, j)));
+                    double change = (*(B)).access(i, j) - (A->access(i, j));
+                    if (change < 0) {
+                        change = -change;
+                    }
+                    if (change > maxChange) {
+                        maxChange = change;
+                    }
+                }
+            }
+        }
+        if (thisIndex == 0) {
+            for (int i = 1; i < myxdim; i++) {
+                for (int j = 1; j < myydim - 1; j++) {
+                    (*(B)).access(i, j) = (0.2) * ((*(A)).access(i, j) + (A->access(i, j + 1)) + (A->access(i, j - 1)) + (A->access(i + 1, j)) + (A->access(i - 1, j)));
+                    double change = (*(B)).access(i, j) - (A->access(i, j));
+                    if (change < 0) {
+                        change = -change;
+                    }
+                    if (change > maxChange) {
+                        maxChange = change;
+                    }
+                }
+            }
+        }
+        if (thisIndex == total - 1) {
+            for (int i = 1; i < myxdim; i++) {
+                for (int j = 1; j < myydim - 1; j++) {
+                    (*(B)).access(i, j) = (0.2) * ((*(A)).access(i, j) + (A->access(i, j + 1)) + (A->access(i, j - 1)) + (A->access(i + 1, j)) + (A->access(i - 1, j)));
+                    double change = (*(B)).access(i, j) - (A->access(i, j));
+                    if (change < 0) {
+                        change = -change;
+                    }
+                    if (change > maxChange) {
+                        maxChange = change;
+                    }
+                }
+            }
+        }
+        Array<double, 2>* tmp = A;
+        A = B;
+        B = tmp;
+    }
+    #if _CHARJ_TRACE_ALL_METHODS
+    traceUserBracketEvent(192321988, _charj_method_trace_timer, CkWallTimer());
+    #endif
+}
+
+void Chunk::resetBoundary()
+{
+    #if _CHARJ_TRACE_ALL_METHODS
+    int _charj_method_trace_timer = CkWallTimer();
+    #endif
+    {
+        if (thisIndex != 0) {
+            if (thisIndex < (int)(total / 2)) {
+                for (int i = 1; i < myxdim + 1; i++) {
+                    (*(A)).access(i, 0) = 1.0;
+                }
+            }
+        }
+        if (thisIndex == 0) {
+            for (int i = 0; i < myxdim; i++) {
+                (*(A)).access(i, 0) = 1.0;
+            }
+            for (int i = 0; 2 * i < myydim; i++) {
+                (*(A)).access(0, i) = 1.0;
+            }
+        }
+    }
+    #if _CHARJ_TRACE_ALL_METHODS
+    traceUserBracketEvent(480493615, _charj_method_trace_timer, CkWallTimer());
+    #endif
+}
+
+void Chunk::processStripFromLeft(Array<double> __s)
+{
+    Array<double>* s = &__s;
+    #if _CHARJ_TRACE_ALL_METHODS
+    int _charj_method_trace_timer = CkWallTimer();
+    #endif
+    {
+        if (thisIndex != 0) {
+            for (int i = 0; i < myydim; i++) {
+                (*(A)).access(0, i) = (s->access(i));
+            }
+        }
+    }
+    #if _CHARJ_TRACE_ALL_METHODS
+    traceUserBracketEvent(186684624, _charj_method_trace_timer, CkWallTimer());
+    #endif
+}
+
+void Chunk::processStripFromRight(Array<double> __s)
+{
+    Array<double>* s = &__s;
+    #if _CHARJ_TRACE_ALL_METHODS
+    int _charj_method_trace_timer = CkWallTimer();
+    #endif
+    {
+        if (thisIndex != total - 1) {
+            if (thisIndex != 0) {
+                for (int i = 0; i < myydim; i++) {
+                    (*(A)).access(myxdim + 1, i) = (s->access(i));
+                }
+            } else {
+                for (int i = 0; i < myydim; i++) {
+                    (*(A)).access(myxdim, i) = (s->access(i));
+                }
+            }
+        }
+    }
+    #if _CHARJ_TRACE_ALL_METHODS
+    traceUserBracketEvent(993349832, _charj_method_trace_timer, CkWallTimer());
+    #endif
+}
+
+void Chunk::pup(PUP::er &p)
+{
+    A->pup(p);
+    B->pup(p);
+    p | myMax;
+    p | myxdim;
+    p | myydim;
+    p | total;
+    p | counter;
+    __sdag_pup(p);
+}
+
+Chunk::Chunk()
+{
+    constructorHelper();
+}
+void Chunk::constructorHelper()
+{
+    __sdag_init();
+}
+
+Chunk::Chunk(CkMigrateMessage *m)
+{
+    constructorHelper();
+}
+bool Chunk::_trace_registered = false;
+void Chunk::_initTrace() {
+    #if _CHARJ_TRACE_ALL_METHODS || _CHARJ_TRACE_TRACED_METHODS
+    if (_trace_registered) return;
+    traceRegisterUserEvent("Chunk.Chunk", 43910155);
+    traceRegisterUserEvent("Chunk.sendStrips", 253859300);
+    traceRegisterUserEvent("Chunk.doStencil", 192321988);
+    traceRegisterUserEvent("Chunk.resetBoundary", 480493615);
+    traceRegisterUserEvent("Chunk.processStripFromLeft", 186684624);
+    traceRegisterUserEvent("Chunk.processStripFromRight", 993349832);
+    traceRegisterUserEvent("Chunk.jacobi", 572453224);
+    _trace_registered = true;
+    #endif
+}
+
+
+//#include "Chunk.def.h"
+
+
+#include "jacobi.def.h"
diff --git a/src/langs/charj/tests/jacobi/hand_translation/jacobi.ci b/src/langs/charj/tests/jacobi/hand_translation/jacobi.ci
new file mode 100644 (file)
index 0000000..8847b8b
--- /dev/null
@@ -0,0 +1,60 @@
+mainmodule jacobi {
+
+// interface for jacobi
+//mainmodule Main {
+    //
+    mainchare Main {
+        entry Main(CkArgMsg* m);
+    };
+//}
+
+    readonly CProxy_Main main_proxy;
+    readonly CProxy_Chunk chunks;
+    readonly int num_finished;
+    readonly double start_time;
+
+
+// interface for chunk
+//module Chunk {
+    //
+    array [1D] Chunk {
+        entry Chunk(int t, int x, int y);
+        entry [reductiontarget] void jacobi(){
+            for (_sdag_jacobi_i = 0; _sdag_jacobi_i < 3; ++_sdag_jacobi_i) {
+                atomic {
+                    sendStrips();
+                }
+
+                overlap {
+                    when getStripFromLeft(Array<double> s) {
+                        atomic {
+                            processStripFromLeft(s);
+                        }
+
+                    }
+                    when getStripFromRight(Array<double> s) {
+                        atomic {
+                            processStripFromRight(s);
+                        }
+
+                    }
+                }
+                atomic {
+                    doStencil();
+                }
+
+            }
+            atomic {
+                if (CkMyPe() == 0) {
+                    double elapsed = CmiWallTimer() - start_time;
+                    CkPrintf("Finished in %fs %fs/step, %d iterations\n", elapsed, elapsed/_sdag_jacobi_i, _sdag_jacobi_i);
+                    CkPrintf("Numfin=%d, total=%d, Pes = %d\n", _sdag_jacobi_i, total, CkNumPes());
+                }
+                CkExit();
+            }
+        };
+        entry void getStripFromLeft(Array<double> s);
+        entry void getStripFromRight(Array<double> s);
+    };
+//}
+}
diff --git a/src/langs/charj/tests/jacobi/hand_translation/jacobi.cj b/src/langs/charj/tests/jacobi/hand_translation/jacobi.cj
new file mode 100644 (file)
index 0000000..5d11c86
--- /dev/null
@@ -0,0 +1,27 @@
+
+extern atoi;
+extern CkAbort;
+
+readonly Main@ main;
+readonly Chunk@ chunks;
+readonly int num_finished;
+readonly double start_time;
+
+mainchare Main {
+    public entry Main(CkArgMsg[~]@ m) {
+        if (m.argc != 4) CkAbort("Wrong parameters\n");
+
+        int x = atoi(m.argv[1]);
+        int y = atoi(m.argv[2]);
+        int k = atoi(m.argv[3]);
+
+        if (x < k) CkAbort("Xdim must be greater than k");
+        if (k < CkNumPes() || k % CkNumPes()) CkAbort("k must be a multiple of numPes.");
+        
+        chunks = new Chunk@(k, x, y, k);
+        chunks@jacobi();
+        num_finished = 0;
+        start_time = CmiWallTimer();
+    }
+}
+
diff --git a/src/langs/charj/tests/jacobi/hand_translation/jacobi.h b/src/langs/charj/tests/jacobi/hand_translation/jacobi.h
new file mode 100644 (file)
index 0000000..c4d7362
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef __jacobi__
+#define __jacobi__
+
+/**************************************************************************
+ * WARNING                                                                *
+ **************************************************************************
+ * This is a machine generated header file.                               *
+ * It is not meant to be edited by hand and may be overwritten by charjc. *
+ **************************************************************************/
+
+#include <charm++.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <Array.h>
+
+using std::string;
+using std::vector;
+using std::cout;
+using std::endl;
+using CharjArray::Array;
+using CharjArray::Domain;
+using CharjArray::Range;
+using CharjArray::Matrix;
+using CharjArray::Vector;
+
+#include "jacobi.decl.h"
+
+//#include "Main.decl.h"
+class Main: public CBase_Main {
+    public: Main(CkArgMsg* m);
+};
+
+/* Readonly variables */
+extern CProxy_Main main;
+extern CProxy_Chunk chunks;
+extern int num_finished;
+extern double start_time;
+//#include "jacobi_readonly.decl.h"
+
+class Chunk: public CBase_Chunk {
+    Chunk_SDAG_CODE
+    private: Array<double, 2>* A;
+    private: Array<double, 2>* B;
+    private: double myMax;
+    private: int myxdim, myydim, total, counter;
+    public: Chunk(int t, int x, int y);
+    private: void sendStrips();
+    private: void doStencil();
+    private: void resetBoundary();
+    public: void processStripFromLeft(Array<double> __s);
+    public: void processStripFromRight(Array<double> __s);
+    public: void pup(PUP::er& p);
+    public: Chunk();
+    protected: void constructorHelper();
+    public: Chunk(CkMigrateMessage*);
+    static bool _trace_registered;
+    void _initTrace();
+    int _sdag_jacobi_i;
+
+    Array<double>* strip;
+};
+#endif // __jacobi__
+
diff --git a/src/langs/charj/tests/jacobi/jacobi.cj b/src/langs/charj/tests/jacobi/jacobi.cj
new file mode 100644 (file)
index 0000000..d5c6dd2
--- /dev/null
@@ -0,0 +1,25 @@
+
+extern atoi;
+extern CkAbort;
+
+readonly Main@ main;
+readonly Chunk@ chunks;
+readonly int num_finished;
+
+mainchare Main {
+    public entry Main(CkArgMsg[~]@ m) {
+        if (m.argc != 4) CkAbort("Wrong parameters\n");
+
+        int x = atoi(m.argv[1]);
+        int y = atoi(m.argv[2]);
+        int k = atoi(m.argv[3]);
+
+        if (x < k) CkAbort("Xdim must be greater than k");
+        if (k < CkNumPes() || k % CkNumPes()) CkAbort("k must be a multiple of numPes.");
+        
+        chunks = new Chunk@(k, x, y, k);
+        chunks@jacobi();
+        num_finished = 0;
+    }
+}
+
diff --git a/src/langs/charj/tests/jacobi/reference/Makefile b/src/langs/charj/tests/jacobi/reference/Makefile
new file mode 100644 (file)
index 0000000..f474e35
--- /dev/null
@@ -0,0 +1,44 @@
+OPTS=-g
+CHARMC=charmc $(OPTS)
+
+all: jacobi
+
+jacobi: parallelJacobi.o
+       $(CHARMC) -language charm++ -o jacobi parallelJacobi.o
+
+parallelJacobi.o: parallelJacobi.decl.h parallelJacobi.def.h parallelJacobi.h parallelJacobi.C
+       $(CHARMC) -c parallelJacobi.C 
+
+parallelJacobi.decl.h parallelJacobi.def.h: parallelJacobi.ci
+       $(CHARMC) parallelJacobi.ci
+
+run:   jacobi
+       ./charmrun +p16 ./jacobi 2000 4 1000 +x10 +y10 +z10 +cth1 +wth1 +bgcorrect +stacksize 4000 +logsize 20000 #++debug-no-pause
+#+bgwalltime 
+
+tiny:  jacobi
+       ./charmrun +p1 ./jacobi 8 4 4 +x2 +y1 +z1 +cth1 +wth1 +bgcorrect +stacksize 4000 +logsize 20000
+
+
+small:         jacobi
+       ./charmrun +p2 ./jacobi 40 4 10 +x2 +y5 +z1 +cth1 +wth1 +bgcorrect +stacksize 4000 +logsize 20000
+
+medium: jacobi
+       ./charmrun +p5 ./jacobi 400 4 100 +x2 +y5 +z5 +cth1 +wth1 +stacksize 4000 +logsize 20000
+
+testnocorr:jacobi
+       ./charmrun +p8 ./jacobi 2000 4 1000 +x10 +y5 +z2 +cth1 +wth1 +bglog +stacksize 4000 +logsize 20000
+
+test: jacobi
+       ./charmrun +p4 ./jacobi 64 10 32 $(TESTOPTS)
+
+big: jacobi
+       ./charmrun +p10 ./jacobi 8000 4 4000 +x10 +y50 +z2 +cth1 +wth1 +bgcorrect +stacksize 4000 +logsize 20000
+
+large: jacobi
+        ./charmrun +p15 ./jacobi 40000 4 20000 +x50 +y20 +z20 +cth1 +wth1 +bgcorrect +stacksize 4000 +logsize 200000
+       prun ./jacobi 128000 4 128000 +x40 +y40 +z20 +cth1 +wth1 +bgcorrect +stacksize 10000 +logsize 800000
+
+clean:
+       rm -f *.sts *.log C *.o *.def.h *.decl.h *~ jacobi bgTraceFile
+       rm -f charmrun conv-host core charmrun.exe jacobi.exe jacobi.pdb jacobi.ilk
diff --git a/src/langs/charj/tests/jacobi/reference/bg_config b/src/langs/charj/tests/jacobi/reference/bg_config
new file mode 100644 (file)
index 0000000..7785ba7
--- /dev/null
@@ -0,0 +1,16 @@
+x 2
+y 2
+z 2
+cth 1
+wth 2
+#stacksize  4000
+#timing  walltime
+timing  elapse
+#timing  counter
+cpufactor   1.0
+fpfactor    5e-7
+traceroot     .
+log      no
+correct  no
+network   lemieux
+#projections 2,4-8
diff --git a/src/langs/charj/tests/jacobi/reference/jacobi b/src/langs/charj/tests/jacobi/reference/jacobi
new file mode 100755 (executable)
index 0000000..369b662
Binary files /dev/null and b/src/langs/charj/tests/jacobi/reference/jacobi differ
diff --git a/src/langs/charj/tests/jacobi/reference/parallelJacobi.C b/src/langs/charj/tests/jacobi/reference/parallelJacobi.C
new file mode 100644 (file)
index 0000000..c9278e8
--- /dev/null
@@ -0,0 +1,303 @@
+#include "parallelJacobi.h"
+
+#define ITER    3
+
+#define DEBUG   0
+
+#define indexof(i,j,ydim) ( ((i)*(ydim)) + (j))
+
+CProxy_Main globalMainProxy;
+CProxy_Chunk chunk_arr;
+
+double startTime;
+int numFinished;
+
+Chunk::Chunk(int t, int x, int y){
+
+  int xdim,ydim;
+  __sdag_init();
+  xdim = x;
+  ydim = y;
+  total = t; 
+  iterations =0;
+  myMax = 99999.999;
+
+
+  // CkPrintf("[%d] x is %d, y is %d, t is %d %f\n",CkMyPe(),x,y,t,BgGetTime());  
+  myxdim = int(xdim/total);
+  counter=0;
+
+  if(thisIndex == total-1) 
+    myxdim = xdim - myxdim*(total-1);    
+
+  myydim = ydim;
+
+  if((thisIndex != 0)&&(thisIndex != total-1)){
+    A = new double[(myxdim+2)*myydim];
+    B = new double[(myxdim+2)*myydim];
+      //Initialize everything to zero
+    for (int i=0; i<myxdim+2; i++)
+      for (int j=0; j<myydim; j++) 
+       A[indexof(i,j,ydim)] = B[indexof(i,j,ydim)] = 0.0;    
+  }
+  else {
+    A = new double[(myxdim+1)*myydim];
+    B = new double[(myxdim+1)*myydim];
+    //Initialize everything to zero
+  for (int i=0; i<myxdim+1; i++)
+    for (int j=0; j<myydim; j++) 
+      A[indexof(i,j,ydim)] = B[indexof(i,j,ydim)] = 0.0;  
+  }
+
+  usesAtSync = false;
+  //LBDatabase *lbdb = getLBDB();
+  //lbdb->SetLBPeriod(50);
+
+}
+
+
+Chunk::Chunk(CkMigrateMessage *m){
+}
+
+
+void Chunk::resetBoundary() {
+
+  if((thisIndex !=0))
+    if(thisIndex < (int)(total/2))
+      for(int i=1;i<myxdim+1;i++)
+       A[indexof(i,0,myydim)] = 1.0;
+
+  if(thisIndex ==0){
+    //if(thisIndex < (int)(total/2))
+      for(int i=0;i<myxdim;i++)
+       A[indexof(i,0,myydim)] = 1.0;
+    
+    for (int i = 0;2*i<myydim; i++) 
+       A[indexof(0,i,myydim)] = 1.0;
+  
+}
+}
+
+
+void Chunk::print() {
+
+  if ((myxdim>100)||(myydim>100)) return;
+
+#if 1
+  CkPrintf("thisIndex = %d,myxdim=%d,myydim=%d\n",thisIndex,myxdim,myydim);
+
+  if(thisIndex !=0)
+    for (int i=0; i<myydim; i++) {
+      for (int j=1; j<myxdim+1; j++) 
+       CkPrintf("%lf ", A[indexof(j,i,myydim)]) ;
+      CkPrintf("\n");
+    }
+  else
+    for (int i=0; i<myydim; i++) {
+      for (int j=0; j<myxdim; j++) 
+       CkPrintf("%lf ", A[indexof(j,i,myydim)]) ;
+      CkPrintf("\n");
+    }
+#endif
+}
+
+
+
+void Chunk::testEnd(){
+
+  if(iterations == ITER)  {
+                        
+    if(CkMyPe() != 0)
+      return;
+
+    if((CkMyPe()==0)&&(numFinished != total/CkNumPes()))
+      return;
+
+    double elapt = CmiWallTimer()-startTime;
+    CkPrintf("Finished in %fs %fs/step and iters is %d\n", elapt, elapt/iterations,iterations);
+    CkPrintf("Numfin=%d, total=%d, Pes = %d\n",numFinished,total,CkNumPes());
+    // BgPrint("ENDED at: %f\n");
+    CkExit();
+    return;
+  }
+
+}
+
+
+void Chunk::startWork(){
+
+  double* temp = (double*) malloc(sizeof(double)*myydim);
+
+  if(iterations == ITER)  {
+    //       BgPrint("FINISHED iterations at :%f\n");
+    if(CkMyPe() != 0)
+     return;
+
+    CkPrintf("Numfin=%d, total=%d, Pes = %d\n",numFinished,total,CkNumPes());
+    if((CkMyPe()==0)&&(numFinished != total/CkNumPes()))
+      return;
+
+    double elapt = CmiWallTimer()-startTime;
+    CkPrintf("Finished in %fs %fs/step and iters is %d\n", elapt, elapt/iterations,iterations);
+    //BgPrint0("ENDED at: %f\n");
+    CkExit();
+    return;
+  }
+
+     //CkPrintf("[%d]print in startWork %f\n", CkMyPe(), BgGetTime());
+
+  if(thisIndex >0){
+    for(int i=0;i<myydim;i++)
+      temp[i] = A[indexof(1,i,myydim)];
+    chunk_arr[thisIndex-1].getStripfromright(new (myydim,0) Msg(myydim,temp));
+  } 
+  else{
+    //Send dummy if thisIndex==0 for dagger to work
+    chunk_arr[total-1].getStripfromright(new (myydim,0) Msg(myydim,temp));
+  }
+
+
+  if(thisIndex < total-1){
+  
+      for(int i=0;i<myydim;i++)
+       temp[i] = A[indexof(myxdim,i,myydim)];
+      chunk_arr[thisIndex+1].getStripfromleft(new (myydim,0) Msg(myydim,temp));
+  }
+  else{
+    //Send dummy if thisIndex==total-1:For dagger to work
+    chunk_arr[0].getStripfromleft(new (myydim,0) Msg(myydim,temp));
+  }
+
+}
+
+
+void Chunk::doWork(){
+
+  double maxChange = 0.0;
+  double * temp;
+
+  iterations++;
+  if((iterations == ITER)&&(CkMyPe()==0))
+    numFinished++;
+  //if (thisIndex == 0)  
+  //  CkPrintf("Iteration: %d\n",iterations);
+
+  resetBoundary();
+
+    if((thisIndex !=0)&&(thisIndex != total-1))
+      for (int i=1; i<myxdim+1; i++)
+       for (int j=1; j<myydim-1; j++) {
+         B[indexof(i,j,myydim)] = 
+           (0.2)*(A[indexof(i,  j,  myydim)] +
+                  A[indexof(i,  j+1,myydim)] +
+                  A[indexof(i,  j-1,myydim)] +
+                  A[indexof(i+1,j,  myydim)] +
+                  A[indexof(i-1,j,  myydim)]);
+
+         double change =  B[indexof(i,j,myydim)] - A[indexof(i,j,myydim)];
+         if (change < 0) change = - change;
+         if (change > maxChange) maxChange = change;
+       }
+      
+    if(thisIndex == 0)
+      for (int i=1; i<myxdim; i++)
+       for (int j=1; j<myydim-1; j++) {
+         B[indexof(i,j,myydim)] = 
+           (0.2)*(A[indexof(i,  j,  myydim)] +
+                  A[indexof(i,  j+1,myydim)] +
+                  A[indexof(i,  j-1,myydim)] +
+                  A[indexof(i+1,j,  myydim)] +
+                  A[indexof(i-1,j,  myydim)]);
+
+         double change =  B[indexof(i,j,myydim)] - A[indexof(i,j,myydim)];
+         if (change < 0) change = - change;
+         if (change > maxChange) maxChange = change;
+       }
+      
+    if(thisIndex == total-1) {
+      for (int i=1; i<myxdim; i++)
+       for (int j=1; j<myydim-1; j++) {
+         B[indexof(i,j,myydim)] = 
+           (0.2)*(A[indexof(i,  j,  myydim)] +
+                  A[indexof(i,  j+1,myydim)] +
+                  A[indexof(i,  j-1,myydim)] +
+                  A[indexof(i+1,j,  myydim)] +
+                  A[indexof(i-1,j,  myydim)]);
+
+         double change =  B[indexof(i,j,myydim)] - A[indexof(i,j,myydim)];
+         if (change < 0) change = - change;
+         if (change > maxChange) maxChange = change;
+       }
+    }
+  
+  temp = A;
+  A =B;        
+  B=temp;  
+
+}
+
+
+void Chunk::processStripfromleft(Msg* aMessage){
+
+//Do nothing if this is 0 Pe because the message will be a dummy for the 0 Pe.
+
+ //BgPrint("%f:TEST STRING LEFT\n");
+  if(thisIndex !=0) {
+                               
+    for(int i=0;i<myydim;i++)
+      A[indexof(0,i,myydim)] = aMessage->strip[i];
+  }
+  
+}
+
+void Chunk::processStripfromright(Msg* aMessage){
+
+  //Do nothing if this is Pe number:(total-1) because this will be a dummy message for that Pe.
+
+ //BgPrint("%f:TEST STRING RIGHT\n");
+  if(thisIndex != total -1){
+    if(thisIndex != 0)
+      for(int i=0;i<myydim;i++)
+       A[indexof(myxdim+1,i,myydim)] = aMessage->strip[i];
+    else
+      for(int i=0;i<myydim;i++)
+       A[indexof(myxdim,i,myydim)] = aMessage->strip[i];
+  }
+}
+
+
+Main::Main(CkArgMsg *m)
+{
+  int x,y,k;
+
+  if(m->argc != 4) CkAbort("Wrong parameters\n");
+       
+  x = atoi(m->argv[1]);
+  y = atoi(m->argv[2]);
+  k = atoi(m->argv[3]);
+
+  if(x < k) CkAbort("Xdim must be greater than k");
+  if (k < CkNumPes() || k%CkNumPes()) CkAbort("k must be multiple of numPes.");
+
+  chunk_arr = CProxy_Chunk::ckNew(k,x,y,k);
+  //chunk_arr.setReductionClient(workover, (void*)NULL);
+  //   CkCallback *cb = new CkCallback(CkIndex_Chunk::workover(NULL), CkArrayIndex1D(0), chunk_arr);
+  //chunk_arr.ckSetReductionClient(cb);
+
+
+  //BgPrint0("STARTING FIRST STEP AT:%f\n");
+
+
+  //  chunk_arr.stepOver(new VoidMsg);
+  chunk_arr.singleStep(new VoidMsg());
+  startTime = CmiWallTimer();
+  numFinished = 0;
+}
+
+
+
+
+#include "parallelJacobi.def.h"
+
+
+
diff --git a/src/langs/charj/tests/jacobi/reference/parallelJacobi.ci b/src/langs/charj/tests/jacobi/reference/parallelJacobi.ci
new file mode 100644 (file)
index 0000000..fc91a56
--- /dev/null
@@ -0,0 +1,58 @@
+mainmodule parallelJacobi {
+
+    message Msg{
+       double strip[]; 
+    };
+
+    message MaxMsg;
+    message VoidMsg;
+
+    mainchare Main {
+        entry Main(CkArgMsg *m);
+       //entry void isFinished(int clientNo);
+    };
+
+    readonly CProxy_Main globalMainProxy;
+    readonly CProxy_Chunk chunk_arr;
+    readonly int numFinished;
+    readonly double startTime;
+
+   array[1D] Chunk{
+
+       entry Chunk(int,int,int);
+        entry void getStripfromleft(Msg* aMessage);
+        entry void getStripfromright(Msg* aMessage);   
+       entry void processStripfromleft(Msg* aMessage);
+       entry void processStripfromright(Msg* aMessage);
+       entry void startWork();
+       
+       entry void singleStep(VoidMsg* msg){
+               atomic "startwork" {                    
+                       /*delete msg;*/ 
+                       startWork();
+               }
+               overlap{
+                       when getStripfromleft(Msg *aMessage){
+                               atomic "fromLeft" {processStripfromleft(aMessage);}
+                       }
+                       when getStripfromright(Msg *aMessage){
+                               atomic "fromRight" {processStripfromright(aMessage);}
+                       }
+               }
+               atomic "doWork" {
+                       doWork();
+                       if(iterations == 3)
+                               { /*BgPrint0("Real Iter: %e\n"); */}
+                       else
+                               thisProxy[thisIndex].singleStep(new VoidMsg);
+                       testEnd();
+
+               }
+               };
+     };
+
+};
+
+
+
+
diff --git a/src/langs/charj/tests/jacobi/reference/parallelJacobi.h b/src/langs/charj/tests/jacobi/reference/parallelJacobi.h
new file mode 100644 (file)
index 0000000..a5eac1b
--- /dev/null
@@ -0,0 +1,66 @@
+#include <stdlib.h>
+#include "parallelJacobi.decl.h"
+     
+class Main: public Chare {
+  
+ public: 
+  int numElements, numFinished;
+  Main(CkArgMsg *m);
+};
+
+class Msg: public CMessage_Msg{
+
+ public:
+  int dim;
+  double* strip;
+
+  Msg(int n, double *inputStrip):dim(n){
+    memcpy(strip,inputStrip,n*(sizeof(double)));
+  }
+
+};
+
+
+class MaxMsg: public CMessage_MaxMsg{
+  
+ public:
+  double max;
+  MaxMsg(double m){
+    max = m; 
+  }
+};
+
+class VoidMsg: public CMessage_VoidMsg {
+  public:
+    int intVal;
+
+    VoidMsg(): intVal(-1) { }
+    VoidMsg(int val): intVal(val) { }
+};
+
+class Chunk: public CBase_Chunk {
+
+Chunk_SDAG_CODE
+
+private:
+ int  myxdim, myydim,total,counter,iterations;
+  double *A, *B;
+  double myMax;
+  void resetBoundary();
+  void print();
+  void doWork();
+  void testEnd();
+
+public:
+  Chunk(int,int,int);
+  Chunk(CkMigrateMessage *m);
+  void startWork();
+  void workover(CkReductionMsg* msg);
+
+  void processStripfromright(Msg* aMessage);
+  void processStripfromleft(Msg* aMessage);
+
+};
+
+
diff --git a/src/langs/charj/tests/jacobi/sendstrips.cj b/src/langs/charj/tests/jacobi/sendstrips.cj
new file mode 100644 (file)
index 0000000..7011ea2
--- /dev/null
@@ -0,0 +1,22 @@
+
+class sendStrips {
+    void sendStrips() {
+        Array<double> dummy = new Array<double>(0);
+        int left = thisIndex-1;
+        int right = thisIndex+1;
+        int max = total-1;
+
+        if(thisIndex > 0) {
+            chunks[left]@getStripfromright(A[1, 0:myydim]);
+        } else {
+            chunks[max]@getStripfromright(dummy);
+        }
+
+        if(thisIndex < total-1) {
+            chunks[right]@getStripfromleft(A[myxdim, 0:myydim]);
+        } else {
+            chunks[0]@getStripfromleft(dummy);
+        }
+    }
+}
+