package hj.array.view.test;

import hj.lang.*;
import hj.array.*;
import hj.array.view.*;

import edu.rice.cs.mint.runtime.Code;
import edu.rice.cs.mint.runtime.SafeCode;
import edu.rice.cs.mint.util.Benchmark;

public class SDoubleArrayViewMatrixTranspose {
    public static void transpose(DoubleArrayView a, DoubleArrayView output, int m, int n) {
        for(int i = 0; i < m; i++)
            for(int j = 0; j < m; j++) {
            output.set(a.get(i,j),j,i);
        }
    }
    
    public static separable Code<Void> stranspose(final SDoubleArrayView a, SDoubleArrayView output, int m, int n) {
        Code<Void> stats = <| { } |>;
        for(int i = 0; i < m; i++)
            for(int j = 0; j < m; j++) {
            stats = <| { `stats; `(output.set(a.get(i,j),j,i)); } |>;
        }
        return stats;
    }
    
    public static double[][] A = {{4.0, 7.0, 3.0, 0.2},
        {5.5, 8.2, 4.4, 0.0},
        {0.0, 5.6, 1.0, 5.7},
        {4.8, 3.8, 4.2, 3.4}};
    public static int m = 4;
    public static int n = 4;
    public static double[] Abase;
    public static double[] Bbase;
    public static DoubleArrayView Aview;
    public static DoubleArrayView Bview;
    public static SDoubleArrayView SAview;
    public static SDoubleArrayView SBview;
    
    public static void main(String[] args) {
        String fileName = "../misc/Tina_DisCal.mtx";
        if (args.length!=0) {
            fileName = args[0];
        }
        java.io.File f = new java.io.File(fileName);
        if (f.exists()) {
            System.out.println(fileName);
            A = mintTestUtil.MatrixMarket.load(f);
        }
        else {
            System.out.println("built-in matrix");
        }
        m = A.length;
        n = A[0].length;
        
        Abase = new double[m*n];
        int aIndex = 0;
        for(int i = 0; i < m; i++) for(int k = 0; k < n; k++) Abase[aIndex++] = A[i][k];
        
        Bbase = new double[n*m];
        int bIndex = 0;
        for(int i = 0; i < n; i++) for(int k = 0; k < m; k++) Bbase[bIndex++] = 0;
        
        Aview = new DoubleArrayView(Abase, 0, new RegionRectangular(new int[] { 0, m-1, 0, n-1 }, 0));
        Bview = new DoubleArrayView(Bbase, 0, new RegionRectangular(new int[] { 0, n-1, 0, m-1 }, 0));
        SAview = new SDoubleArrayView(<| Abase |>, 0, new SRegionRectangular(new int[] { 0, m-1, 0, n-1 }, 0));
        SBview = new SDoubleArrayView(<| Bbase |>, 0, new SRegionRectangular(new int[] { 0, n-1, 0, m-1 }, 0));
        
        System.out.println("transpose(a) m="+m+", n="+n); //+", "+f);
        Benchmark.TimedTask[] results =
            Benchmark.benchmark(Benchmark.stagingTasks(new Benchmark.Task() {
            public void run() {
                //
                // call unstaged code here
                //
                transpose(Aview, Bview, m, n);
                //
                //
                //
            }
        }, new Benchmark.Thunk<Code<? extends Benchmark.Task>>() {
            public Code<? extends Benchmark.Task> value() {
                return <| new Benchmark.Task() {
                    public void run() {
                        //
                        // splice in staged code here
                        //
                        `(stranspose(SAview, SBview, m, n));
                        //
                        //
                        //
                    }
                } |>;
            }
        }));
        
//        Benchmark.print(0, results); // relative to unstaged
//        System.out.println();
        Benchmark.print(results.length-1, results); // relative to staged
    }
}
