Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
dgetPartialInv.c
Go to the documentation of this file.
1 /*======================================================================
2  Copyright (C) 2016 Peter Rakyta, Ph.D.
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see http://www.gnu.org/licenses/.
16 
17 ======================================================================*/
18 
29 #include "mex.h"
30 #include <stdio.h>
31 #include <omp.h>
32 
33 #ifdef __cplusplus
34 extern "C"
35 #endif
36 
38 #ifdef MIC
39 __declspec( target(mic) ) void getpartialinv_mp_dgetpartialinv_(int *sizeA, int *nonzerosA, double *a, int *ia, int *ja, int *sizeInv, double *invA, int *error);
40 #else
41 void getpartialinv_mp_dgetpartialinv_(int *sizeA, int *nonzerosA, double *a, int *ia, int *ja, int *sizeInv, double *invA, int *error);
42 #endif
43 
44 
45 
52 void mexFunction(int nlhs, mxArray *plhs[],
53  int nrhs, const mxArray *prhs[])
54 {
55 /* Array information: */
56  mwSize nonzerosA; /*number of nonzeros elements in A*/
57  mwSize sizeAm;
58  mwSize sizeAn; /*size of the matrix A (rows, and cols) */
59  mwSize sizeInv; /*Size of the Schur complement to be calculated*/
60  int sizeAn_fort, nonzerosA_fort, sizeInv_fort; /*fortran compatible matrix dimensions*/
61 
62  mwSize *ia, *ja;
63  int *ia_fort, *ja_fort; /* fortran compatible indices */
64  int error;
65  double* a, *invA_fort;
66 
67 
68 /*-----------------------------------------------------------------------*/
69 /* Check for proper number of arguments. */
70  if(nrhs != 2) {
71  mexErrMsgIdAndTxt ("MATLAB:timestwo:nInput", "Two inputs required.");
72  }
73  else if (nlhs > 1) {
74  mexErrMsgIdAndTxt ("MATLAB:timestwo:nOutput", "Too many output arguments.");
75  }
76 
77 /* Validate inputs */
78 
79 /* Check that the input is a double.*/
80  if ((mxIsDouble(prhs[0]) == 0)) {
81  mexErrMsgIdAndTxt ("MATLAB:timestwo:NonDouble", "Input must be a double.");
82  }
83 
84 /* Check if inputs are real.*/
85  if ((mxIsComplex(prhs[0]) != 0) ) {
86  mexErrMsgIdAndTxt ("MATLAB:convec:NonReal", "Inputs must be real.");
87  }
88 
89 /* Get the size of the input array. (MATLAB) */
90  nonzerosA = mxGetNzmax(prhs[0]);
91  sizeAm = mxGetM(prhs[0]);
92  sizeAn = mxGetN(prhs[0]);
93 
94  ia = mxGetJc(prhs[0]);
95  ja = mxGetIr(prhs[0]);
96  a = mxGetPr(prhs[0]);
97 
98  ia_fort = (int*)malloc( (sizeAm+1)*sizeof(int) );
99  ja_fort = (int*)malloc( nonzerosA*sizeof(int) );
100 
101  mwSize idx;
102  for( idx=1; idx<=sizeAm+1; idx++ ) {
103  ia_fort[idx-1] = (int)ia[idx-1] + 1;
104  }
105 
106  for( idx=1; idx<=nonzerosA; idx++ ) {
107  ja_fort[idx-1] = (int)ja[idx-1] + 1;
108  }
109 
110 /* getting the size of the partial inverse */
111  sizeInv = *mxGetPr(prhs[1]);
112 
113 
114  plhs[0] = mxCreateDoubleMatrix(sizeInv, sizeInv, mxREAL); /* invA */
115 
116  invA_fort = (double *)mxGetData(plhs[0]);
117 
118  sizeAn_fort = (int)sizeAn;
119  nonzerosA_fort = (int)nonzerosA;
120  sizeInv_fort = (int)sizeInv;
121 
122 #ifdef MIC
123 #pragma offload target(mic) \
124  in(sizeAn_fort, nonzerosA_fort, sizeInv_fort) \
125  in(a:length(nonzerosA)) \
126  in(ia_fort:length(sizeAn+1)) \
127  in(ja_fort:length(nonzerosA)) \
128  out(invA_fort:length(sizeInv_fort*sizeInv_fort)) \
129  out(error)
130  {
131 #endif
132 
133 #ifdef __INTEL_COMPILER
134  getpartialinv_mp_dgetpartialinv_(&sizeAn_fort, &nonzerosA_fort, a, ia_fort, ja_fort, &sizeInv_fort, invA_fort, &error);
135 #else
136  __getpartialinv_MOD_dgetpartialinv(&sizeAn_fort, &nonzerosA_fort, a, ia_fort, ja_fort, &sizeInv_fort, invA_fort, &error);
137 #endif
138 
139 #ifdef MIC
140  }
141 #endif
142 
143  free(ia_fort);
144  free(ja_fort);
145 
146 /* Check the error flag .*/
147  if ((error != 0) ) {
148  char output[100];
149  sprintf(output, "PARDISO solver ended with error flag: %i\n", error);
150  mexErrMsgIdAndTxt ("EQuUs:dgetPartialInv:PardisoError", output);
151  }
152 
153 #ifdef DEBUG
154  mexPrintf("Pardiso calculations finished for real matrix\n");
155 #endif
156 
157 }
158 
159 
void getpartialinv_mp_dgetpartialinv_(int *sizeA, int *nonzerosA, double *a, int *ia, int *ja, int *sizeInv, double *invA, int *error)
For specification see getpartialinv::dgetpartialinv.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Gateway routine to call the dgetpartialinv subroutine from the mkl_EQuUs package.