PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/extlibs/taucs-2.2--my-fix/progs/superlu.c

https://code.google.com/p/inla/
C | 471 lines | 339 code | 73 blank | 59 comment | 90 complexity | 593555d626ae44b9ace9c2d7aec24d04 MD5 | raw file
  1. /*********************************************************/
  2. /* TAUCS */
  3. /* Author: Sivan Toledo */
  4. /*********************************************************/
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <assert.h>
  11. #include <taucs.h>
  12. /*********************************************************/
  13. /* */
  14. /*********************************************************/
  15. #define max(x,y) ( ((x) > (y)) ? (x) : (y) )
  16. int M,N; /* Size of matrix */
  17. /*********************************************************/
  18. /* */
  19. /*********************************************************/
  20. static double twonorm(int n, double* v)
  21. {
  22. /*
  23. double norm;
  24. int i;
  25. for (i=0, norm=0.0; i<n; i++) norm += v[i]*v[i];
  26. norm = sqrt(norm);
  27. return norm;
  28. */
  29. double norm, ssq, scale, absvi;
  30. int i;
  31. if (n==1) return fabs(v[0]);
  32. scale = 0.0;
  33. ssq = 1.0;
  34. for (i=0; i<n; i++) {
  35. if ( v[i] != 0 ) {
  36. absvi = fabs(v[i]);
  37. if (scale < absvi) {
  38. ssq = 1.0 + ssq * (scale/absvi)*(scale/absvi);
  39. scale = absvi;
  40. } else
  41. ssq = ssq + (absvi/scale)*(absvi/scale);
  42. }
  43. }
  44. return scale * sqrt( ssq );
  45. }
  46. /*********************************************************/
  47. /* */
  48. /*********************************************************/
  49. void usage(int argc, char* argv[])
  50. {
  51. printf("%s OPTIONS\n",argv[0]);
  52. printf(" -help or -h or no arguments at all\n");
  53. printf(" this help\n");
  54. printf(" MATRIX OPTIONS:\n");
  55. printf(" -hb Harwll-Boeing-filename (matrix from file)\n");
  56. printf(" -ijv ijvfilename (matrix from file)\n");
  57. printf(" -mtx mtxfilename (matrix from file)\n");
  58. printf(" -ccs ccsfilename (matrix from file)\n");
  59. printf(" -mesh3d X Y Z (X-by-Y-by-Z poisson problem)\n");
  60. printf(" -mesh2d n (n-by-n poisson problem)\n");
  61. printf(" -mat_type [anisotropic_y/anisotropic_x/dirichlet/neumann]\n");
  62. printf(" mat_type only applicable to -mesh2d\n");
  63. printf(" (3D meshes are always Neumann BC)\n");
  64. printf(" anisotropic problems are Neumann\n");
  65. printf(" RIGHT-HAND SIDE OPTIONS:\n");
  66. printf(" -n+rhs filename (order n followed by rhs, ascii)\n");
  67. printf(" FACTOR/SOLVE OPTIONS:\n");
  68. printf(" -snmf\n");
  69. printf(" supernodal-multifrontal\n");
  70. printf(" -snll\n");
  71. printf(" supernodal-left-looking\n");
  72. printf(" -symb\n");
  73. printf(" supernodal-multifrontal, separate symbolic & numeric phases\n");
  74. printf(" -ooc\n");
  75. printf(" out-of-core supernodal left-looking\n");
  76. printf(" OOC OPTIONS:\n");
  77. printf(" -matrixfile basename\n");
  78. printf(" base name for files; default is /tmp/taucs\n");
  79. printf(" -memory M\n");
  80. printf(" amount of memory in megabytes to use;\n");
  81. printf(" if not given, TAUCS tries to figure an optimal amount;\n");
  82. printf(" OTHER OPTIONS:\n");
  83. printf(" -log filename\n");
  84. printf(" write log into filename; can be stdout and stderr\n");
  85. exit(0);
  86. }
  87. /*********************************************************/
  88. /* */
  89. /*********************************************************/
  90. main(int argc, char* argv[])
  91. {
  92. double wtime_order;
  93. double wtime_permute;
  94. double wtime_factor;
  95. double wtime_solve;
  96. double wtime_precond_create;
  97. double ctime_factor;
  98. int i,j;
  99. double NormErr;
  100. taucs_ccs_matrix* A;
  101. taucs_ccs_matrix* PAPT;
  102. taucs_ccs_matrix* L;
  103. double* X = NULL;
  104. double* B = NULL;
  105. double* PX;
  106. double* PB;
  107. double* NX;
  108. char* ordering = "metis";
  109. char* mat_type = "neumann";
  110. int* perm;
  111. int* invperm;
  112. int superlu_flag = 0;
  113. int snmf_flag = 0;
  114. int snll_flag = 0;
  115. int symb_flag = 0;
  116. int mesh2d_flag = 0,mesh2d_size = 0;
  117. int ooc_flag = 0;
  118. int panelize = 0;
  119. double memory_mb = -1.0;
  120. char* matrixfile = "/tmp/taucs.L";
  121. taucs_io_handle* oocL;
  122. int (*precond_fn)(void*,double* x,double* b);
  123. void* precond_args;
  124. /***********************************************************/
  125. /* Read arguments: log file, matrix, memory size, ooc name */
  126. /***********************************************************/
  127. if ((argc == 1) ||((argc == 2) && !strncmp(argv[1],"-h",2)))
  128. usage(argc,argv);
  129. A = NULL;
  130. for (i=1; i<argc; i++) {
  131. if (!strcmp(argv[i],"-superlu")) superlu_flag = 1;
  132. if (!strcmp(argv[i],"-snmf")) snmf_flag = 1;
  133. if (!strcmp(argv[i],"-snll")) snll_flag = 1;
  134. if (!strcmp(argv[i],"-symb")) symb_flag = 1;
  135. if (!strcmp(argv[i],"-ooc")) ooc_flag = 1;
  136. if (!strcmp(argv[i],"-log") && i <= argc-1 ) {
  137. i++;
  138. taucs_logfile(argv[i]);
  139. }
  140. if (!strcmp(argv[i],"-panelize") && i <= argc-1) {
  141. i++;
  142. if (sscanf(argv[i],"%d",&panelize) != 1) {
  143. taucs_printf("0 (smart), 1 (in-core), or 2 (single supernode) follow -panelize argument\n");
  144. exit(1);
  145. }
  146. }
  147. if (!strcmp(argv[i],"-memory") && i <= argc-1) {
  148. i++;
  149. if (sscanf(argv[i],"%lf",&memory_mb) != 1) {
  150. taucs_printf("memory size in MB must follow -memory argument\n");
  151. exit(1);
  152. }
  153. }
  154. if (!strcmp(argv[i],"-matrixfile") && i <= argc-1 ) {
  155. i++;
  156. matrixfile = argv[i];
  157. }
  158. if (!strcmp(argv[i],"-ordering") && i <= argc-1 ) {
  159. i++;
  160. ordering = argv[i];
  161. }
  162. if (!strcmp(argv[i],"-mat_type") && i <= argc-1 ) {
  163. i++;
  164. mat_type = argv[i];
  165. }
  166. if (!strcmp(argv[i],"-hb") && i <= argc-1 ) {
  167. int nrows,ncols,nnz,j;
  168. char fname[256];
  169. char type[3];
  170. i++;
  171. for (j=0; j<256; j++) fname[j] = ' ';
  172. strcpy(fname,argv[i]);
  173. taucs_printf("main: reading HB matrix %s\n",argv[i]);
  174. ireadhb_(fname,type,&nrows,&ncols,&nnz);
  175. A = taucs_ccs_create(nrows,ncols,nnz);
  176. if (type[1] == 's' || type[1] == 'S')
  177. A->flags = TAUCS_SYMMETRIC | TAUCS_LOWER;
  178. dreadhb_(fname,&nrows,&ncols,&nnz,
  179. A->colptr,A->rowind,A->values);
  180. /* make indices 0-based */
  181. for (j=0; j<=ncols; j++) ((A->colptr)[j])--;
  182. for (j=0; j<nnz; j++) ((A->rowind)[j])--;
  183. taucs_printf("main: done reading\n");
  184. }
  185. if (!strcmp(argv[i],"-mtx") && i <= argc-1) {
  186. i++;
  187. taucs_printf("main: reading mtx matrix %s\n",argv[i]);
  188. A = taucs_ccs_read_mtx (argv[i],TAUCS_SYMMETRIC);
  189. taucs_printf("main: done reading\n");
  190. }
  191. if (!strcmp(argv[i],"-ijv") && i <= argc-1) {
  192. i++;
  193. taucs_printf("main: reading ijv matrix %s\n",argv[i]);
  194. A = taucs_ccs_read_ijv (argv[i],TAUCS_SYMMETRIC);
  195. taucs_printf("main: done reading\n");
  196. }
  197. if (!strcmp(argv[i],"-ccs") && i <= argc-1) {
  198. i++;
  199. taucs_printf("main: reading ccs matrix %s\n",argv[i]);
  200. A = taucs_ccs_read_ccs (argv[i],TAUCS_SYMMETRIC);
  201. taucs_printf("main: done reading\n");
  202. }
  203. if (!strcmp(argv[i],"-mesh2d") && i <= argc-1) {
  204. mesh2d_flag = 1;
  205. taucs_printf("A is a mesh2d\n");
  206. i++;
  207. if (sscanf(argv[i],"%d",&mesh2d_size) != 1) {
  208. taucs_printf("mesh size (n, where the mesh is n-by-n) must follow -mesh2d argument\n");
  209. exit(1);
  210. }
  211. }
  212. if (!strcmp(argv[i],"-mesh3d") && i <= argc-3) {
  213. int X,Y,Z;
  214. taucs_printf("A is a mesh3d\n");
  215. if (sscanf(argv[i+1],"%d",&X) != 1
  216. || sscanf(argv[i+2],"%d",&Y) != 1
  217. || sscanf(argv[i+3],"%d",&Z) != 1) {
  218. taucs_printf("mesh size (X Y Z must follow -mesh3d argument\n");
  219. exit(1);
  220. }
  221. i += 3;
  222. taucs_printf("main: creating mesh\n");
  223. A = taucs_ccs_generate_mesh3d(X,Y,Z);
  224. }
  225. if (!strcmp(argv[i],"-n+rhs") && i <= argc-1) {
  226. FILE* f;
  227. int n,j,nnz;
  228. i++;
  229. taucs_printf("main: reading right-hand side %s\n",argv[i]);
  230. f=fopen(argv[i],"r");
  231. assert(f);
  232. fscanf(f,"%d",&n);
  233. B=(double*) malloc(n*sizeof(double));
  234. nnz = 0;
  235. for (j=0; j<n; j++) {
  236. fscanf(f,"%lg",B+j);
  237. if (B[j]) nnz++;
  238. }
  239. fclose(f);
  240. taucs_printf("main: done reading rhs, %d nonzeros\n",nnz);
  241. }
  242. }
  243. taucs_printf("Chosen Ordering: %s\n",ordering);
  244. if (mesh2d_flag)
  245. {
  246. taucs_printf("Matrix type is %s\n",mat_type);
  247. taucs_printf("Grid Size is %d\n",mesh2d_size);
  248. A = taucs_ccs_generate_mesh2d(mesh2d_size,mat_type);
  249. }
  250. if (!A) {
  251. taucs_printf("matrix argument not given or matrix file not found\n");
  252. usage(argc,argv);
  253. }
  254. N = M = A->n;
  255. /***********************************************************/
  256. /* Create exact solution, compute right-hand-side */
  257. /***********************************************************/
  258. if (!X) {
  259. X=(double*)malloc(N*sizeof(double));
  260. for(i=0; i<N; i++) X[i]=(double)random()/RAND_MAX;
  261. } else
  262. taucs_printf("iter: not using a random X, already allocated\n");
  263. if (!B) {
  264. B=(double*)malloc(N*sizeof(double));
  265. taucs_ccs_times_vec(A,X,B);
  266. } else {
  267. for(i=0; i<N; i++) X[i]= 0.0 / 0.0;
  268. }
  269. NX=(double*)malloc(N*sizeof(double));
  270. PX=(double*)malloc(N*sizeof(double));
  271. PB=(double*)malloc(N*sizeof(double));
  272. /***********************************************************/
  273. /* Compute column ordering */
  274. /***********************************************************/
  275. /***********************************************************/
  276. /* factor */
  277. /***********************************************************/
  278. {
  279. int n;
  280. double unit,curr;
  281. n = A->n;
  282. unit = (n-1.)+n;
  283. wtime_order = taucs_wtime();
  284. taucs_ccs_order(A,&perm,&invperm,ordering);
  285. wtime_order = taucs_wtime() - wtime_order;
  286. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_order);
  287. if (!perm) {
  288. taucs_printf("\tOrdering Failed\n");
  289. exit(1);
  290. }
  291. if (0) {
  292. int i;
  293. FILE* f;
  294. f=fopen("p.ijv","w");
  295. for (i=0; i<n; i++) fprintf(f,"%d\n",perm[i]+1);
  296. fclose(f);
  297. }
  298. wtime_permute = taucs_wtime();
  299. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  300. wtime_permute = taucs_wtime() - wtime_permute;
  301. taucs_printf("\tPermute time = % 10.3f seconds\n",wtime_permute);
  302. wtime_factor = taucs_wtime();
  303. ctime_factor = taucs_ctime();
  304. if (superlu_flag) {
  305. void* taucs_ccs_factor_superlu(void*);
  306. int taucs_ccs_solve_superlu(void*,double*,double*);
  307. L = taucs_ccs_factor_superlu(PAPT);
  308. precond_args = L;
  309. precond_fn = taucs_ccs_solve_superlu;
  310. }
  311. else if (snmf_flag) {
  312. taucs_ccs_matrix* C;
  313. L = taucs_ccs_factor_llt_mf(PAPT);
  314. precond_args = L;
  315. precond_fn = taucs_supernodal_solve_llt;
  316. /*
  317. C = taucs_supernodal_factor_to_ccs(L);
  318. taucs_ccs_write_ijv(C,"C.ijv");
  319. precond_args = C;
  320. precond_fn = taucs_ccs_solve_llt;
  321. */
  322. } else if (ooc_flag) {
  323. #define TESTING
  324. #ifdef TESTING
  325. int taucs_ooc_factor_llt_panelchoice(taucs_ccs_matrix* A,
  326. taucs_io_handle* handle,
  327. double memory,
  328. int panelization_method);
  329. int c;
  330. oocL = taucs_io_create_multifile(matrixfile);
  331. assert(oocL);
  332. if (memory_mb == -1.0) memory_mb = taucs_available_memory_size()/1048576.0;
  333. taucs_ooc_factor_llt_panelchoice(PAPT, oocL, memory_mb*1048576.0,panelize);
  334. precond_args = oocL;
  335. precond_fn = taucs_ooc_solve_llt;
  336. #else
  337. int c;
  338. oocL = taucs_io_create_multifile(matrixfile);
  339. assert(oocL);
  340. if (memory_mb == -1.0) memory_mb = taucs_available_memory_size()/1048576.0;
  341. taucs_ooc_factor_llt(PAPT, oocL, memory_mb*1048576.0);
  342. precond_args = oocL;
  343. precond_fn = taucs_ooc_solve_llt;
  344. #endif
  345. } else if (snll_flag) {
  346. L = taucs_ccs_factor_llt_ll(PAPT);
  347. precond_args = L;
  348. precond_fn = taucs_supernodal_solve_llt;
  349. } else if (symb_flag) {
  350. L = taucs_ccs_factor_llt_symbolic(PAPT);
  351. taucs_ccs_factor_llt_numeric(PAPT,L); /* should check error code */
  352. precond_args = L;
  353. precond_fn = taucs_supernodal_solve_llt;
  354. } else {
  355. L = taucs_ccs_factor_llt(PAPT,0.0,0);
  356. precond_args = L;
  357. precond_fn = taucs_ccs_solve_llt;
  358. }
  359. wtime_factor = taucs_wtime() - wtime_factor;
  360. ctime_factor = taucs_ctime() - ctime_factor;
  361. taucs_printf("\tFactor time = % 10.3f seconds ",wtime_factor);
  362. taucs_printf("(%.3f cpu time)\n",ctime_factor);
  363. }
  364. if (!L && !ooc_flag /* no L in ooc */) {
  365. taucs_printf("\tFactorization Failed\n");
  366. exit(1);
  367. }
  368. /*taucs_ccs_write_ijv(PAPT,"A.ijv",1);*/ /* 1 = complete the upper part */
  369. /*taucs_ccs_write_ijv(L,"L.ijv",0);*/
  370. /***********************************************************/
  371. /* solve */
  372. /***********************************************************/
  373. taucs_vec_permute(A->n,B,PB,perm);
  374. wtime_solve = taucs_wtime();
  375. precond_fn(precond_args,PX,PB); /* direct solver */
  376. wtime_solve = taucs_wtime() - wtime_solve;
  377. taucs_printf("\tSolve time = % 10.3f seconds\n",wtime_solve);
  378. taucs_vec_ipermute(A->n,PX,NX,perm);
  379. /***********************************************************/
  380. /* delete out-of-core matrices */
  381. /***********************************************************/
  382. if (ooc_flag) {
  383. taucs_io_delete(oocL);
  384. /*taucs_io_close(oocL);*/
  385. }
  386. /***********************************************************/
  387. /* Compute norm of forward error */
  388. /***********************************************************/
  389. NormErr = 0.0;
  390. for(i=0; i<N; i++) NormErr = max(NormErr,fabs((NX[i]-X[i])/X[i]));
  391. taucs_printf("main: max relative error = %1.6e \n",NormErr);
  392. /***********************************************************/
  393. /* Exit */
  394. /***********************************************************/
  395. taucs_printf("main: done\n");
  396. }