Lineáris egyenletrendszerek megoldása GPGPU Alkalmazások Lineáris egyenletrendszerek megoldása
Gauss-Jordan elimináció // TODO // // ID := get_local_id(0) // LOOP ma := 0 .. m DO: // pivot := A[ma + ma * n] // coeff := A[ma + ID * n] / pivot // BARRIER // IF ID != ma DO: // LOOP na := 0 .. n DO: // A[na + id * n] := A[na + id * n] - coeff * A[na + n * ma]; // ENDIF // END LOOP // coeff := A[ID + ID * n] // LOOP na := 0 .. n DO: // A[na + id * n] = A[na + id * n] / coeff __kernel void gaussian(const int n, const int m, __global float* A){ }
Minta egyenletrendszer int n = 4; int m = 3; float A[] = {2, 1, -1, 8, -3, -1, 2, -11, -2, 1, 2, -3};
Mátrix invertálás int n = 6; int m = 3; float A[] = { 2, -1, 0, 1, 0, 0, -1, 2, -1, 0, 1, 0, 0, -1, 2, 0, 0, 1};
Mátrix vektor szorzás CPU implementáció void scalarMV(int n, int m, float* y, const float* A, const float* x, const float* b){ for(int i=0; i<n; ++i){ float yi = b[i]; for(int j=0; j<m; ++j){ yi += A[i * m + j] * x[j]; } y[i] = yi;
Mátrix vektor szorzás GPU implementáció I // TODO // // i := get_global_id(0) // IF ID < n DO: // yi := b[i] // LOOP j := 0 .. m DO: // yi += A[j + i * m] * x[j] // END LOOP // y[i] := yi // END IF __kernel void simpleMV(const int n, const int m, __global float* y, __global float* A, __global float* x, __global float* b){ }
Mátrix vektor szorzás GPU implementáció II // TODO // // i = get_group_id(0) // j = get_local_id(0) // Q[j] := A[i * M + j] * x[j] // BARRIER // Sum scan on Q (reduction) // IF j = 0 THEN: // y[i] = Q[0] + b[i] __kernel void reduceMV(const int n, __global float* y, __global float* A, __global float* x, __global float* b, const int M, __local float* Q){ }
Mátrix vektor szorzás GPU implementáció III // TODO // // t := get_local_id(0) / Z // z := get_local_id(0) % Z // FOR i := t ; i < n ; i := i + T : // Q[t * Z + z] = 0 // FOR j := z ; j < m ; j += Z : // Q[t * Z + z] += A[j + i * m] * x[j] // END FOR // END FOR // Sum scan on Q (reduction) // IF z = 0 THEN: // y[i] = Q[t * Z + 0] + b[i] __kernel void largeMV(const int n, const int m, __global float* y, __global float* A, __global float* x, __global float* b, const int T, const int Z, __local float* Q){ }
Mátrix vektor szorzás Terjesszük valamely megoldást több munkacsoportra!
Jacobi iteráció void jacobi(){ int n = 8; float* x[2] = {NULL, NULL}; x[0] = new float[n]; x[1] = new float[n]; for(int i = 0; i < n; ++i){ x[0][i] = 0.0f; x[1][i] = 0.0f; } float* A = new float[n * n]; for(int j = 0; j < n; ++j){ float v = 0.0f; if( i == j){ v = 0.5f; A[i + j * n] = v; float* b = new float[n]; b[i] = 1.0f; int inputBuffer = 0; const int iterations = 20; for(int i = 0; i < iterations; ++i){ largeMV(n, n, x[(inputBuffer + 1) % 2], A, x[inputBuffer], b); inputBuffer = (inputBuffer + 1) % 2; printResult(n, x[inputBuffer], "Jakobi"); delete x[0]; delete x[1]; delete A; delete b; Jacobi iteráció
Jacobi iteráció Próbáljuk ki más egyenlet rendszerre is! Próbáljuk ki, hogy mi történik, ha nem megoldható az egyenlet rendszer!