diff --git a/README.md b/README.md index 5e6eb90..c673adc 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ DEVICE=1 # 40 = Rauschfilter (Spawns a javafx window) # 50 = Mandelbrot (Spawns a javafx window) # 60 = RGBHistogramm (Spawns a javafx window) +# 70 = Radixsort +# 80 = Matrix Multiplication # DEFAULT = 0 TARGET=31 @@ -25,6 +27,8 @@ TARGET=31 # Target 4X (N to the left and right of x_0) # Target 50 Zoom Factor (20 should be used to get good results) # Target 60 filename of a picture (Place in folder $PROJECT_ROOT/pictures/my_pic.jpg) [jpg,bmp,png] +# Target 70 Array lenth (N) +# Target 80 Matrices height and width (NxN) # DEFAULT = 25 / "lena.bmp" MULTI_PARAM=3 diff --git a/src/main/java/edu/thi/phga/aparapi_test/App.java b/src/main/java/edu/thi/phga/aparapi_test/App.java index ead2b2c..1b8ca97 100644 --- a/src/main/java/edu/thi/phga/aparapi_test/App.java +++ b/src/main/java/edu/thi/phga/aparapi_test/App.java @@ -130,6 +130,12 @@ public class App { System.out.println("Spawning window RGBHistogramm"); Application.launch(RGBHistogramm.class); break; + case 70: + System.out.println("Radix Sort"); + RadixSort.start(); + case 80: + System.out.println("Matrix Mult"); + MatrixMult.start(); } } } diff --git a/src/main/java/edu/thi/phga/aparapi_test/MatrixMult.java b/src/main/java/edu/thi/phga/aparapi_test/MatrixMult.java new file mode 100644 index 0000000..8edcbd4 --- /dev/null +++ b/src/main/java/edu/thi/phga/aparapi_test/MatrixMult.java @@ -0,0 +1,85 @@ +package edu.thi.phga.aparapi_test; + +import java.util.Random; + +import com.aparapi.Kernel; +import com.aparapi.Range; + +public class MatrixMult { + private static int n = App.multiParam; + private static int[] a = new Random().ints(n * n, 1, 10).toArray(); + private static int[] b = new Random().ints(n * n, 1, 10).toArray(); + private static int[] c = new int[n * n]; + + public static void start() { + + Range r = Range.create(App.device, n); + MatMulKernel k = new MatMulKernel(a, b, c); + k.execute(r); + + if (n < 10) { + print(); + } else { + System.out.println("Success: Choose n < 10 to print matrices"); + + } + } + + private static void print() { + for (int i = 0; i < n; i++) { + for (int x = 0; x < n; x++) { + System.out.printf("%d ", a[i * n + x]); + } + + if (i == n/2) { + System.out.print(" * "); + } else { + System.out.print(" "); + } + + for (int x = 0; x < n; x++) { + System.out.printf("%d ", b[i * n + x]); + } + + if (i == n/2) { + System.out.print(" = "); + } else { + System.out.print(" "); + } + + for (int x = 0; x < n; x++) { + System.out.printf("%d ", c[i * n + x]); + } + System.out.println(""); + } + } + + private static class MatMulKernel extends Kernel { + private int[] a, b, c; + MatMulKernel(int[] a, int[] b, int[] c) { + this.a = a; + this.b = b; + this.c = c; + } + + @Override public void run() { + int i = getGlobalId(0); + int size = getGlobalSize(); + + for (int j = 0; j < size; j++) { + for (int k = 0; k < size; k++) { + c[i * size + j] += a[i * size + k] * b[k * size + j]; + } + } + + // int n = getGlobalSize(); + // int i = getGlobalId(); + + // for (int j = 0; j < n; j++) { + // for (int k = 0; k < n; k++) { + // c[i * n + j] += a[i *n + k] * b[k * n + j]; + // } + // } + } + } +} diff --git a/src/main/java/edu/thi/phga/aparapi_test/RadixSort.java b/src/main/java/edu/thi/phga/aparapi_test/RadixSort.java new file mode 100644 index 0000000..17d6975 --- /dev/null +++ b/src/main/java/edu/thi/phga/aparapi_test/RadixSort.java @@ -0,0 +1,86 @@ +package edu.thi.phga.aparapi_test; + +import java.util.Arrays; +import java.util.Random; + +import com.aparapi.Kernel; +import com.aparapi.Range; + +public class RadixSort { + private static final int N = 1 << App.multiParam; + // private static int[] input = new Random().ints(N, 0, Integer.MAX_VALUE).toArray(); + private static int[] input = new Random().ints(N, 0, 30).toArray(); + private static int[] output = new int[N]; + private static int[] flags = new int[N]; + private static int[] sums = new int[N]; + static int x; + + public static void start() { + Kerni k = new Kerni(); + Range r = Range.create(N); + System.out.println("Range: " + r); + + + System.out.print("BEFORE: "); + print(Math.min(20, N)); + + for (x = 0; x < 31; x++) { + System.out.printf("%d: %d\n", x, (1 << x)); + k.setParams(input, output, flags, sums, 1, 1 << x); + k.execute(r); + // Arrays.parallelSetAll(flags, (i) -> + // 1 - ((input[i] >> x) % 2) + // ); + sums = flags.clone(); + Arrays.parallelPrefix(sums, Integer::sum); + k.setParams(input, output, flags, sums, 0, 1 << x); + k.execute(r); + input = output.clone(); + } + + System.out.print("AFTER: "); + print(Math.min(20, N)); + + } + + private static void print(int n) { + for (int x = 0; x < n; x++) { + System.out.printf("%d, ", input[x]); + } + System.out.println(""); + } + + private static class Kerni extends Kernel { + private int[] input, output, flags, sums; + private int job, mask; + public void setParams(int[] input, int[] output, int[] flags, + int[] sums, int job, int mask) { + this.input = input; + this.output = output; + this.flags = flags; + this.sums = sums; + this.job = job; + this.mask = mask; + } + + @Override + public void run() { + if (job == 0) + sort(); + else + flag(); + } + + private void flag() { + int i = getGlobalId(0); + flags[i] = (input[i] & mask) != 0 ? 0 : 1; + } + + private void sort() { + int i = getGlobalId(0); + int N = getGlobalSize(0); + output[flags[i] == 1 ? sums[i] - 1 : + i - sums[i] + sums[N - 1]] = input[i]; + } + } +}