From 072d4f7784d7b1faeb6d618e66625239cd1bbfc8 Mon Sep 17 00:00:00 2001 From: unknown <> Date: Thu, 6 Jul 2023 20:45:37 -0400 Subject: [PATCH] SIMD support --- pom.xml | 2 +- src/main/java/electrosphere/FluidSim.java | 289 +++++++++++++------ src/main/java/electrosphere/Main.java | 17 +- src/main/java/electrosphere/render/Mesh.java | 14 +- src/main/resources/Test1.cl | 76 ----- 5 files changed, 217 insertions(+), 181 deletions(-) delete mode 100644 src/main/resources/Test1.cl diff --git a/pom.xml b/pom.xml index 2b5933d..b1e600d 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 electrosphere - sample-cli-java + fluid-sim 1.0-SNAPSHOT jar diff --git a/src/main/java/electrosphere/FluidSim.java b/src/main/java/electrosphere/FluidSim.java index 385af5a..3eddf66 100644 --- a/src/main/java/electrosphere/FluidSim.java +++ b/src/main/java/electrosphere/FluidSim.java @@ -8,7 +8,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.Set; -// import jdk.incubator.vector.FloatVector; + +import jdk.incubator.foreign.MemorySegment; +import jdk.incubator.vector.FloatVector; +import jdk.incubator.vector.VectorMask; +import jdk.incubator.vector.VectorOperators; +import jdk.incubator.vector.VectorOperators.Associative; import org.joml.Vector2i; import org.lwjgl.BufferUtils; @@ -36,16 +41,15 @@ public class FluidSim { public static final int DIM = 18; - // float[][][][] data = new float[4][DIM][DIM][DIM]; - float[][][] x = new float[DIM][DIM][DIM]; - float[][][] x0 = new float[DIM][DIM][DIM]; - float[][][] u = new float[DIM][DIM][DIM]; - float[][][] v = new float[DIM][DIM][DIM]; - float[][][] w = new float[DIM][DIM][DIM]; - float[][][] u0 = new float[DIM][DIM][DIM]; - float[][][] v0 = new float[DIM][DIM][DIM]; - float[][][] w0 = new float[DIM][DIM][DIM]; - // float[][][][] oldData = new float[4][DIM][DIM][DIM]; + float[] x = new float[DIM * DIM * DIM]; + float[] x0 = new float[DIM * DIM * DIM]; + float[] u = new float[DIM * DIM * DIM]; + float[] v = new float[DIM * DIM * DIM]; + float[] w = new float[DIM * DIM * DIM]; + float[] u0 = new float[DIM * DIM * DIM]; + float[] v0 = new float[DIM * DIM * DIM]; + float[] w0 = new float[DIM * DIM * DIM]; + float[] jacobiAltArray = new float[DIM * DIM * DIM]; static final float DIFFUSION_CONSTANT = 0.0001f; static final float VISCOSITY_CONSTANT = 0.0001f; @@ -65,10 +69,10 @@ public class FluidSim { Math.abs(8 - j) < 4 && Math.abs(10 - k) < 4 ){ - x[i][j][k] = 1; - u[i][j][k] = rand.nextFloat() * 0.1f; - v[i][j][k] = -1f; - w[i][j][k] = rand.nextFloat() * 0.1f; + x[IX(i,j,k)] = 1; + u[IX(i,j,k)] = rand.nextFloat() * 0.1f; + v[IX(i,j,k)] = -1f; + w[IX(i,j,k)] = rand.nextFloat() * 0.1f; } } } @@ -108,13 +112,12 @@ public class FluidSim { if(step % 1500 == 0){ for(int i = 0; i < 4; i++){ for(int j = 0; j < 4; j++){ - x[15 - i][15][15 - j] = 1; - v[15 - i][15][15 - j] = -1; + x[IX(15 - i,15,15 - j)] = 1; + v[IX(15 - i,15,15 - j)] = -1; } } } - // x[16][16][16] = 1; vel_step(DIM, DIM, DIM, u, v, w, u0, v0, w0, VISCOSITY_CONSTANT, timestep); @@ -124,73 +127,74 @@ public class FluidSim { } - void lin_solve ( int M, int N, int O, int b, float[][][] x, float[][][] x0, float a, float c ){ + void lin_solve(int M, int N, int O, int b, float[] x, float[] x0, float a, float c){ int i, j, k, l; // iterate the solver for ( l=0 ; lM+0.5f) x=M+0.5f; i0=(int)x; i1=i0+1; if (y<0.5f) y=0.5f; if (y>N+0.5f) y=N+0.5f; j0=(int)y; j1=j0+1; if (z<0.5f) z=0.5f; if (z>O+0.5f) z=O+0.5f; k0=(int)z; k1=k0+1; @@ -214,43 +218,39 @@ public class FluidSim { if(k1 >= DIM){ k1 = DIM - 1; } - d[i][j][k] = s0*(t0*u0*d0[i0][j0][k0]+t1*u0*d0[i0][j1][k0]+t0*u1*d0[i0][j0][k1]+t1*u1*d0[i0][j1][k1])+ - s1*(t0*u0*d0[i1][j0][k0]+t1*u0*d0[i1][j1][k0]+t0*u1*d0[i1][j0][k1]+t1*u1*d0[i1][j1][k1]); + d[IX(i,j,k)] = s0*(t0*u0*d0[IX(i0,j0,k0)]+t1*u0*d0[IX(i0,j1,k0)]+t0*u1*d0[IX(i0,j0,k1)]+t1*u1*d0[IX(i0,j1,k1)])+ + s1*(t0*u0*d0[IX(i1,j0,k0)]+t1*u0*d0[IX(i1,j1,k0)]+t0*u1*d0[IX(i1,j0,k1)]+t1*u1*d0[IX(i1,j1,k1)]); }}} setBounds(d, b); } - void moveData(float[][][] set1, float[][][] set2){ + void moveData(float[] set1, float[] set2){ float tmp = 0; - for(int x = 0; x < DIM; x++){ - for(int y = 0; y < DIM; y++){ - for(int z = 0; z < DIM; z++){ - tmp = set1[x][y][z]; - set1[x][y][z] = set2[x][y][z]; - set2[x][y][z] = tmp; - } - } + for(int i = 0; i < set1.length; i++){ + tmp = set1[i]; + set1[i] = set2[i]; + set2[i] = tmp; } } - void project(int M, int N, int O, float[][][] u, float[][][] v, float[][][] w, float[][][] p, float[][][] div){ + void project(int M, int N, int O, float[] u, float[] v, float[] w, float[] p, float[] div){ int i, j, k; for ( i=1 ; i 0.0f){ - x[i][j][k] += dt * GRAVITY * density[i][j][k]; + if(density[IX(i,j,k)] > 0.0f){ + x[IX(i,j,k)] += dt * GRAVITY * density[IX(i,j,k)]; } }}} } - void vel_step(int M, int N, int O, float[][][] u, float[][][] v, float[][][] w, float[][][] u0, float[][][] v0, float[][][] w0, float visc, float dt ){ + void vel_step(int M, int N, int O, float[] u, float[] v, float[] w, float[] u0, float[] v0, float[] w0, float visc, float dt ){ // add_source ( M, N, O, u, u0, dt ); add_source ( M, N, O, v, v0, dt );add_source ( M, N, O, w, w0, dt ); - add_source ( M, N, O, v, x, dt ); - moveData ( u0, u ); diffuse ( M, N, O, 1, u, u0, visc, dt ); - moveData ( v0, v ); diffuse ( M, N, O, 2, v, v0, visc, dt ); - moveData ( w0, w ); diffuse ( M, N, O, 3, w, w0, visc, dt ); - project ( M, N, O, u, v, w, u0, v0 ); - moveData ( u0, u ); moveData ( v0, v );moveData ( w0, w ); - advect ( M, N, O, 1, u, u0, u0, v0, w0, dt ); advect ( M, N, O, 2, v, v0, u0, v0, w0, dt );advect ( M, N, O, 3, w, w0, u0, v0, w0, dt ); - project ( M, N, O, u, v, w, u0, v0 ); + add_source(M, N, O, v, x, dt); + moveData(u0, u); + diffuse(M, N, O, 1, u, u0, visc, dt); + moveData(v0, v); + diffuse(M, N, O, 2, v, v0, visc, dt); + moveData(w0, w); + diffuse(M, N, O, 3, w, w0, visc, dt); + project(M, N, O, u, v, w, u0, v0); + moveData(u0, u); + moveData(v0, v); + moveData(w0, w); + advect(M, N, O, 1, u, u0, u0, v0, w0, dt); + advect(M, N, O, 2, v, v0, u0, v0, w0, dt); + advect(M, N, O, 3, w, w0, u0, v0, w0, dt); + project(M, N, O, u, v, w, u0, v0); } void sum(){ @@ -292,18 +299,126 @@ public class FluidSim { for(int i = 0; i < DIM; i++){ for(int j = 0; j < DIM; j++){ for(int k = 0; k < DIM; k++){ - sum[0] = sum[0] + x[i][j][k]; - sum[1] = sum[1] + u[i][j][k]; - sum[2] = sum[2] + v[i][j][k]; - sum[3] = sum[3] + w[i][j][k]; + sum[0] = sum[0] + x[IX(i,j,k)]; + sum[1] = sum[1] + u[IX(i,j,k)]; + sum[2] = sum[2] + v[IX(i,j,k)]; + sum[3] = sum[3] + w[IX(i,j,k)]; } } } // System.out.println(sum[0] + " " + sum[1] + " " + sum[2] + " " + sum[3]); } - public float[][][] getData(){ + public float[] getData(){ return x; } + public static final int IX(int x, int y, int z){ + return ((x)+(DIM)*(y) + (DIM)*(DIM)*(z)); + } + + static final int[] vectorOffsetMap = new int[(DIM - 2) * (DIM - 2) * (DIM - 2)]; + static final int[] vectorOffsetMapXN = new int[(DIM - 2) * (DIM - 2) * (DIM - 2)]; + static final int[] vectorOffsetMapXP = new int[(DIM - 2) * (DIM - 2) * (DIM - 2)]; + static final int[] vectorOffsetMapYN = new int[(DIM - 2) * (DIM - 2) * (DIM - 2)]; + static final int[] vectorOffsetMapYP = new int[(DIM - 2) * (DIM - 2) * (DIM - 2)]; + static final int[] vectorOffsetMapZN = new int[(DIM - 2) * (DIM - 2) * (DIM - 2)]; + static final int[] vectorOffsetMapZP = new int[(DIM - 2) * (DIM - 2) * (DIM - 2)]; + static { + int i = 0; + for(int x = 1; x < DIM - 1; x++){ + for(int y = 1; y < DIM - 1; y++){ + for(int z = 1; z < DIM - 1; z++){ + // if(x != y || y != z){ + vectorOffsetMap[i] = IX(x,y,z); + vectorOffsetMapXN[i] = IX(x-1, y, z); + vectorOffsetMapXP[i] = IX(x+1, y, z); + vectorOffsetMapYN[i] = IX( x,y-1, z); + vectorOffsetMapYP[i] = IX( x,y+1, z); + vectorOffsetMapZN[i] = IX( x, y,z-1); + vectorOffsetMapZP[i] = IX( x, y,z+1); + i++; + // } + } + } + } + } + + static final int LANE_WIDTH = 8; + void linSolveJacobian(int M, int N, int O, int b, float[] x, float x0[], float a, float c){ + //x contains the solution to the problem + //x0 contains A + + // float[] a = new float[]{ + // 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 + // }; + // FloatVector vec = FloatVector.fromArray(FloatVector.SPECIES_128, a, 0); + // FloatVector finalVec = vec.add(3); + // float[] b = finalVec.toArray(); + // for(int i = 0; i < b.length; i++){ + // System.out.println(b[i]); + // } + float[] vectorArrView; + float[] srcArr, destArr; + for(int k = 0; k < LINEARSOLVERTIMES; k++){ + if(k / 2 == 0){ + srcArr = x; + destArr = jacobiAltArray; + } else { + srcArr = jacobiAltArray; + destArr = x; + } + for(int i = 0; i < vectorOffsetMap.length; i += LANE_WIDTH){ + if(i + LANE_WIDTH < vectorOffsetMap.length){ + + // for ( i=1 ; i mask = FloatVector.SPECIES_256.indexInRange(O, numLeft); + + // for ( i=1 ; i> 0) & 0xFF, - // (c >> 8) & 0xFF, - // (c >> 16) & 0xFF, - // 0xFF - // )); - // #else - // output[iy * width + ix] = colorMap[colorIndex]; - // #endif - // // monochrom - // //output[iy * width + ix] = 255*iteration/maxIterations; - // } -} \ No newline at end of file