We have several multiprocessor machines with Intel's Math Kernel Library (MLK), processor specific compilers, and threading libraries (e.g., OMP). The examples below show how to set up your data structures (e.g., vectors and matrices) and make calls to the MKL's BLAS and LAPACK Fortran libraries from C++. Some of the examples also make use of the R standalone math library for random number generation.
Example 1
Example 2
Example 1: code and Makefile
/************************************************************************************/ //Example of Cholesky square root and subsequent inverse, along with the log //determinant along the way. Also, the use of the random number generators in Rmath. //Make with "make -f Makefile-example-1" /************************************************************************************/ #include <iostream> #include <omp.h> using namespace std; #include <mkl.h> #define MATHLIB_STANDALONE #include <Rmath.h> int main(){ int i,j; int info; char *lower = "L"; char *upper = "U"; char *ntran = "N"; char *ytran = "T"; char *rside = "R"; char *lside = "L"; const double one = 1.0; const double negOne = -1.0; const double zero = 0.0; const int incOne = 1; //set seed set_seed(123,456); //set threads omp_set_num_threads(4); int n = 1000; int nn = n*n; double logDet = 0; double traceSum = 0; double *A = new double[nn]; double *B = new double[nn]; double *C = new double[nn]; for(i = 0; i < n*n; i++) A[i] = rnorm(0,1); //make a pd matrix dgemm(ntran, ytran, &n, &n, &n, &one, A, &n, A, &n, &zero, B, &n); //make a copy dcopy(&nn, B, &incOne, C, &incOne); //take the Cholesky square root dpotrf(lower, &n, C, &n, &info); if(info != 0){cout << "c++ error: Cholesky failed" << endl;} //get the log determinant for(i = 0; i < n; i++) logDet += 2*log(C[i*n+i]); //take the inverse dpotri(lower, &n, C, &n, &info); if(info != 0){cout << "c++ error: Cholesky inverse failed" << endl;} //check the inverse for fun dsymm(lside, lower, &n, &n, &one, C, &n, B, &n, &zero, A, &n); for(i = 0; i < n; i++) traceSum += A[i*n+i]; cout << "Log determinant: " << logDet << endl; cout << "Should be " << n << ": " << traceSum << endl; exit(0); } |
Example 2: code, A and B matrix, and Makefile
/************************************************************************************/ //More simple examples. //Make with "make -f Makefile-example-2" /************************************************************************************/ #include <iostream> #include <string> #include <fstream> #include <omp.h> using namespace std; #include <mkl.h> #define MATHLIB_STANDALONE #include <Rmath.h> void fReadMtrx(string f, double *mtrx, int nrow, int ncol); void showMtrx(double *mtrx, int nrow, int ncol); int main(){ int i,j; int info; char *lower = "L"; char *upper = "U"; char *ntran = "N"; char *ytran = "T"; char *rside = "R"; char *lside = "L"; const double one = 1.0; const double negOne = -1.0; const double zero = 0.0; const int incOne = 1; //set seed set_seed(123,456); //set threads, not that we really need (or will use) 4 CPUs for //these matricies omp_set_num_threads(4); int dim=3, length=dim*dim;//, dim1=3, dim2=3, dim4, dim5, dim6, dimvec, rows, cols, rowd,c old; double *a, *b, *c, *d, *I, *sum, *e, *q, *r,*qrf, *t, *perm; int *ipiv; //double *u, *s, *vt, *x, *inv, *chol, *qrmat; //double alpha, det, logdet; //allocate and read in a a = new double[dim*dim]; fReadMtrx("a", a, dim, dim); cout << endl << "a:" << endl; showMtrx(a, dim, dim); //allocate and read in a b = new double[dim*dim]; cout << endl << "b:" << endl; fReadMtrx("b", b, dim, dim); showMtrx(b, dim, dim); //allocate c c = new double[dim*dim]; //operation 1 dgemm(ntran, ntran, &dim, &dim, &dim, &one, a, &dim, b, &dim, &zero, c, &dim); cout << endl << "The product of the matrix A and B:" << endl; showMtrx(c, dim, dim); //operation 2 dcopy(&length, b, &incOne, c, &incOne); daxpy(&length, &one, a, &incOne, c, &incOne); cout << endl << "The sum of the matrix A and B:" << endl; showMtrx(c, dim, dim); //operation 3 dcopy(&length, b, &incOne, c, &incOne); dscal(&length, &negOne, c, &incOne); daxpy(&length, &one, a, &incOne, c, &incOne); cout << endl << "The difference between matrix A and B:" << endl; showMtrx(c, dim, dim); //operation 4 I = new double[dim*dim];//make identity matrix for(i = 0; i < length; i++) I[i] = 0.0; for(i = 0; i < dim; i++) I[i*dim+i] = 1.0; dgemm(ytran, ntran, &dim, &dim, &dim, &one, a, &dim, I, &dim, &zero, c, &dim); cout << endl << "The transpose of matrix A is:" << endl; showMtrx(c, dim, dim); //operation 5 ipiv = new int[dim]; dcopy(&length, a, &incOne, c, &incOne); dgetrf(&dim, &dim, c, &dim, ipiv, &info);if(info != 0){cout << "c++ error: dgetrf failed" << endl;} cout << endl << "The LU decomposition A=PLU (L has unit diagnoal elements):" << endl; showMtrx(c, dim, dim); exit(0); } void fReadMtrx(string f, double *mtrx, int nrow, int ncol){ ifstream data(f.c_str(), ios::in); if (!data) { cerr << "File " << f << " could not be opened." << endl; exit(1); } for(int i = 0; i < nrow; i++) for(int j = 0; j < ncol; j++) data >> mtrx[j*nrow+i]; } void showMtrx(double *mtrx, int nrow, int ncol){ for (int i = 0; i < nrow; i++) { for (int j = 0; j < ncol; j++) { cout << mtrx[j*nrow+i] << "\t"; } cout << endl; } } |