// performs backwards substitution on the linear system U*x = b, returning x as a new Mat; // leaves U and b untouched Mat BackSub(Mat &U, Mat &b) { // check that matrix sizes match if (U.Rows() != b.Rows() || U.Rows() != U.Cols() || b.Cols() != 1) { fprintf(stderr,"BackSub error, illegal matrix/vector dimensions\n"); fprintf(stderr," Mat is %li x %li, rhs is %li x %li\n", U.Rows(), U.Cols(), b.Rows(), b.Cols()); Mat *x = new Mat(0,0); return *x; } // create new Mat for output Mat *x = new Mat(U.Rows(),1); // call existing BackSub routine for computations if (BackSub(U, *x, b) != 0) fprintf(stderr,"BackSub Warning: error in BackSub call\n"); // return result return *x; }
int main(int argc, char *argv[]) { printf("WG size of kernel 1 = %d, WG size of kernel 2= %d X %d\n", BLOCK_SIZE_0, BLOCK_SIZE_1_X, BLOCK_SIZE_1_Y); float *a=NULL, *b=NULL, *finalVec=NULL; float *m=NULL; int size = -1; FILE *fp; // args char filename[200]; int quiet=1,timing=0,platform=-1,device=-1; // parse command line if (parseCommandline(argc, argv, filename, &quiet, &timing, &platform, &device, &size)) { printUsage(); return 0; } context = cl_init_context(platform,device,quiet); if(size < 1) { fp = fopen(filename, "r"); fscanf(fp, "%d", &size); a = (float *) malloc(size * size * sizeof(float)); InitMat(fp,size, a, size, size); b = (float *) malloc(size * sizeof(float)); InitAry(fp, b, size); fclose(fp); } else { printf("create input internally before create, size = %d \n", size); a = (float *) malloc(size * size * sizeof(float)); create_matrix(a, size); b = (float *) malloc(size * sizeof(float)); for (int i =0; i< size; i++) b[i]=1.0; } if (!quiet) { printf("The input matrix a is:\n"); PrintMat(a, size, size, size); printf("The input array b is:\n"); PrintAry(b, size); } // create the solution matrix m = (float *) malloc(size * size * sizeof(float)); // create a new vector to hold the final answer finalVec = (float *) malloc(size * sizeof(float)); InitPerRun(size,m); //begin timing // printf("The result of array b is before run: \n"); // PrintAry(b, size); // run kernels ForwardSub(context,a,b,m,size,timing); // printf("The result of array b is after run: \n"); // PrintAry(b, size); DIVIDEND_CL_WRAP(clFinish)(command_queue); //end timing if (!quiet) { printf("The result of matrix m is: \n"); PrintMat(m, size, size, size); printf("The result of matrix a is: \n"); PrintMat(a, size, size, size); printf("The result of array b is: \n"); PrintAry(b, size); BackSub(a,b,finalVec,size); printf("The final solution is: \n"); PrintAry(finalVec,size); } free(m); free(a); free(b); free(finalVec); cl_cleanup(); //OpenClGaussianElimination(context,timing); return 0; }
// solves a linear system A*x = b, filling in the input Mat x int Solve(Mat &A, Mat &x, Mat &b) { // create temporary variables long int i, j, k, p, n; double tmp, Amax; // check that matrix sizes match if (A.Rows() != b.Rows() || A.Rows() != A.Cols() || b.Cols() != 1 || x.Rows() != A.Rows() || x.Cols() != 1) { fprintf(stderr,"Solve error, illegal matrix/vector dimensions\n"); fprintf(stderr," Mat is %li x %li, sol is %li x %li, rhs is %li x %li\n", A.Rows(), A.Cols(), x.Rows(), x.Cols(), b.Rows(), b.Cols()); return 1; } // determine maximum absolute entry in A (for singularity check later) Amax = A.MaxNorm(); // perform Gaussian elimination to convert A,b to an upper-triangular system n = A.Rows(); for (k=0; k<n-1; k++) { // loop over diagonals // find the pivot row p p=k; for (i=k; i<n; i++) if (fabs(A(i,k)) > fabs(A(p,k))) p=i; // swap rows in A for (j=k; j<n; j++) { tmp = A(p,j); A(p,j) = A(k,j); A(k,j) = tmp; } // swap rows in b tmp = b(p); b(p) = b(k); b(k) = tmp; // check for singular matrix if (fabs(A(k,k)) < 1.e-13*Amax) { fprintf(stderr,"Solve error: numerically singular matrix!\n"); return 1; } // perform elimination on remaining submatrix of A using row k for (j=k+1; j<n; j++) for (i=k+1; i<n; i++) A(i,j) = A(i,j) - A(i,k)/A(k,k)*A(k,j); // perform elimination on remainder of b using row k for (i=k+1; i<n; i++) b(i) -= A(i,k)/A(k,k)*b(k); } // check for singularity at end (only need to check final diagonal entry) if (fabs(A(n-1,n-1)) < 1.e-13*Amax) { fprintf(stderr,"Solve error: numerically singular matrix!\n"); return 1; } // perform Backwards Substitution on result if (BackSub(A, x, b) != 0) { fprintf(stderr,"Solve error in BackSub call\n"); return 1; } // return success return 0; }