1function klu_make (metis_path) 2%KLU_MAKE compiles the KLU mexFunctions 3% 4% Example: 5% klu_make 6% 7% KLU relies on AMD, COLAMD, and BTF for its ordering options, and can 8% optionally use CHOLMOD, CCOLAMD, CAMD, and METIS as well. 9% 10% You must type the klu_make command while in the KLU/MATLAB directory. 11% 12% See also klu. 13 14% Copyright 2004-2016, Univ. of Florida 15 16if (nargin < 1) 17 metis_path = '../../metis-5.1.0' ; 18end 19with_cholmod = exist (metis_path, 'dir') ; 20 21details = 0 ; % if 1, print details of each command 22 23d = '' ; 24if (~isempty (strfind (computer, '64'))) 25 % 64-bit MATLAB 26 d = '-largeArrayDims' ; 27end 28 29% MATLAB 8.3.0 now has a -silent option to keep 'mex' from burbling too much 30if (~verLessThan ('matlab', '8.3.0')) 31 d = ['-silent ' d] ; 32end 33 34fprintf ('Compiling KLU ') ; 35kk = 0 ; 36 37include = '-I. -I../../AMD/Include -I../../COLAMD/Include -I../Include -I../../SuiteSparse_config -I../../BTF/Include' ; 38 39if (with_cholmod) 40 include = [include ' -I../../CCOLAMD/Include -I../../CAMD/Include -I../../CHOLMOD/Include -I../../SuiteSparse_config -I../User'] ; 41 include = [include ' -I' metis_path '/include'] ; 42 include = [include ' -I' metis_path '/GKlib'] ; 43 include = [include ' -I' metis_path '/libmetis'] ; 44end 45 46% do not attempt to compile CHOLMOD with large file support (not needed) 47include = [include ' -DNLARGEFILE'] ; 48 49% fix the METIS 4.0.1 rename.h file 50if (with_cholmod) 51 fprintf ('with CHOLMOD, CAMD, CCOLAMD, and METIS\n') ; 52 include = ['-DNSUPERNODAL -DNMODIFY -DNMATRIXOPS -DNCHECK ' include] ; 53else 54 fprintf ('without CHOLMOD, CAMD, CCOLAMD, and METIS\n') ; 55 include = ['-DNCHOLMOD ' include] ; 56end 57 58suitesparse_src = { '../../SuiteSparse_config/SuiteSparse_config' } ; 59 60amd_src = { ... 61 '../../AMD/Source/amd_1', ... 62 '../../AMD/Source/amd_2', ... 63 '../../AMD/Source/amd_aat', ... 64 '../../AMD/Source/amd_control', ... 65 '../../AMD/Source/amd_defaults', ... 66 '../../AMD/Source/amd_dump', ... 67 '../../AMD/Source/amd_global', ... 68 '../../AMD/Source/amd_info', ... 69 '../../AMD/Source/amd_order', ... 70 '../../AMD/Source/amd_postorder', ... 71 '../../AMD/Source/amd_post_tree', ... 72 '../../AMD/Source/amd_preprocess', ... 73 '../../AMD/Source/amd_valid' } ; 74 75colamd_src = { 76 '../../COLAMD/Source/colamd' } ; 77 78if (with_cholmod) 79 80 camd_src = { ... 81 '../../CAMD/Source/camd_1', ... 82 '../../CAMD/Source/camd_2', ... 83 '../../CAMD/Source/camd_aat', ... 84 '../../CAMD/Source/camd_control', ... 85 '../../CAMD/Source/camd_defaults', ... 86 '../../CAMD/Source/camd_dump', ... 87 '../../CAMD/Source/camd_global', ... 88 '../../CAMD/Source/camd_info', ... 89 '../../CAMD/Source/camd_order', ... 90 '../../CAMD/Source/camd_postorder', ... 91 '../../CAMD/Source/camd_preprocess', ... 92 '../../CAMD/Source/camd_valid' } ; 93 94 ccolamd_src = { 95 '../../CCOLAMD/Source/ccolamd' } ; 96 97 metis_src = { 98 'GKlib/b64', ... 99 'GKlib/blas', ... 100 'GKlib/csr', ... 101 'GKlib/error', ... 102 'GKlib/evaluate', ... 103 'GKlib/fkvkselect', ... 104 'GKlib/fs', ... 105 'GKlib/getopt', ... 106 'GKlib/gkregex', ... 107 'GKlib/graph', ... 108 'GKlib/htable', ... 109 'GKlib/io', ... 110 'GKlib/itemsets', ... 111 'GKlib/mcore', ... 112 'GKlib/memory', ... 113 'GKlib/omp', ... 114 'GKlib/pdb', ... 115 'GKlib/pqueue', ... 116 'GKlib/random', ... 117 'GKlib/rw', ... 118 'GKlib/seq', ... 119 'GKlib/sort', ... 120 'GKlib/string', ... 121 'GKlib/timers', ... 122 'GKlib/tokenizer', ... 123 'GKlib/util', ... 124 'libmetis/auxapi', ... 125 'libmetis/balance', ... 126 'libmetis/bucketsort', ... 127 'libmetis/checkgraph', ... 128 'libmetis/coarsen', ... 129 'libmetis/compress', ... 130 'libmetis/contig', ... 131 'libmetis/debug', ... 132 'libmetis/fm', ... 133 'libmetis/fortran', ... 134 'libmetis/frename', ... 135 'libmetis/gklib', ... 136 'libmetis/graph', ... 137 'libmetis/initpart', ... 138 'libmetis/kmetis', ... 139 'libmetis/kwayfm', ... 140 'libmetis/kwayrefine', ... 141 'libmetis/mcutil', ... 142 'libmetis/mesh', ... 143 'libmetis/meshpart', ... 144 'libmetis/minconn', ... 145 'libmetis/mincover', ... 146 'libmetis/mmd', ... 147 'libmetis/ometis', ... 148 'libmetis/options', ... 149 'libmetis/parmetis', ... 150 'libmetis/pmetis', ... 151 'libmetis/refine', ... 152 'libmetis/separator', ... 153 'libmetis/sfm', ... 154 'libmetis/srefine', ... 155 'libmetis/stat', ... 156 'libmetis/timing', ... 157 'libmetis/util', ... 158 'libmetis/wspace', ... 159 } ; 160 161 for i = 1:length (metis_src) 162 metis_src {i} = [metis_path '/' metis_src{i}] ; 163 end 164 165 cholmod_src = { 166 '../../CHOLMOD/Core/cholmod_aat', ... 167 '../../CHOLMOD/Core/cholmod_add', ... 168 '../../CHOLMOD/Core/cholmod_band', ... 169 '../../CHOLMOD/Core/cholmod_change_factor', ... 170 '../../CHOLMOD/Core/cholmod_common', ... 171 '../../CHOLMOD/Core/cholmod_complex', ... 172 '../../CHOLMOD/Core/cholmod_copy', ... 173 '../../CHOLMOD/Core/cholmod_dense', ... 174 '../../CHOLMOD/Core/cholmod_error', ... 175 '../../CHOLMOD/Core/cholmod_factor', ... 176 '../../CHOLMOD/Core/cholmod_memory', ... 177 '../../CHOLMOD/Core/cholmod_sparse', ... 178 '../../CHOLMOD/Core/cholmod_transpose', ... 179 '../../CHOLMOD/Core/cholmod_triplet', ... 180 '../../CHOLMOD/Cholesky/cholmod_amd', ... 181 '../../CHOLMOD/Cholesky/cholmod_analyze', ... 182 '../../CHOLMOD/Cholesky/cholmod_colamd', ... 183 '../../CHOLMOD/Cholesky/cholmod_etree', ... 184 '../../CHOLMOD/Cholesky/cholmod_postorder', ... 185 '../../CHOLMOD/Cholesky/cholmod_rowcolcounts', ... 186 '../../CHOLMOD/Partition/cholmod_ccolamd', ... 187 '../../CHOLMOD/Partition/cholmod_csymamd', ... 188 '../../CHOLMOD/Partition/cholmod_camd', ... 189 '../../CHOLMOD/Partition/cholmod_metis', ... 190 '../../CHOLMOD/Partition/cholmod_nesdis' } ; 191 192else 193 camd_src = { } ; 194 ccolamd_src = { } ; 195 metis_src = { } ; 196 cholmod_src = { } ; 197end 198 199btf_src = { 200 '../../BTF/Source/btf_maxtrans', ... 201 '../../BTF/Source/btf_order', ... 202 '../../BTF/Source/btf_strongcomp' } ; 203 204klu_src = { 205 '../Source/klu_free_symbolic', ... 206 '../Source/klu_defaults', ... 207 '../Source/klu_analyze_given', ... 208 '../Source/klu_analyze', ... 209 '../Source/klu_memory' } ; 210 211if (with_cholmod) 212 klu_src = [klu_src { '../User/klu_l_cholmod' }] ; %#ok 213end 214 215klu_zlsrc = { 216 '../Source/klu', ... 217 '../Source/klu_kernel', ... 218 '../Source/klu_dump', ... 219 '../Source/klu_factor', ... 220 '../Source/klu_free_numeric', ... 221 '../Source/klu_solve', ... 222 '../Source/klu_scale', ... 223 '../Source/klu_refactor', ... 224 '../Source/klu_tsolve', ... 225 '../Source/klu_diagnostics', ... 226 '../Source/klu_sort', ... 227 '../Source/klu_extract', ... 228 } ; 229 230klu_lobj = { 231 'klu_l', ... 232 'klu_l_kernel', ... 233 'klu_l_dump', ... 234 'klu_l_factor', ... 235 'klu_l_free_numeric', ... 236 'klu_l_solve', ... 237 'klu_l_scale', ... 238 'klu_l_refactor', ... 239 'klu_l_tsolve', ... 240 'klu_l_diagnostics', ... 241 'klu_l_sort', ... 242 'klu_l_extract', ... 243 } ; 244 245klu_zlobj = { 246 'klu_zl', ... 247 'klu_zl_kernel', ... 248 'klu_zl_dump', ... 249 'klu_zl_factor', ... 250 'klu_zl_free_numeric', ... 251 'klu_zl_solve', ... 252 'klu_zl_scale', ... 253 'klu_zl_refactor', ... 254 'klu_zl_tsolve', ... 255 'klu_zl_diagnostics', ... 256 'klu_zl_sort', ... 257 'klu_zl_extract', ... 258 } ; 259 260try 261 % ispc does not appear in MATLAB 5.3 262 pc = ispc ; 263catch 264 % if ispc fails, assume we are on a Windows PC if it's not unix 265 pc = ~isunix ; 266end 267 268if (pc) 269 % Windows does not have drand48 and srand48, required by METIS. Use 270 % drand48 and srand48 in CHOLMOD/MATLAB/Windows/rand48.c instead. 271 obj_extension = '.obj' ; 272 cholmod_src = [cholmod_src {'../../CHOLMOD/MATLAB/Windows/rand48'}] ; 273 include = [include ' -I../../CHOLMOD/MATLAB/Windows'] ; 274else 275 obj_extension = '.o' ; 276end 277 278% compile each library source file 279obj = ' ' ; 280 281source = [suitesparse_src amd_src btf_src klu_src colamd_src] ; 282if (with_cholmod) 283 source = [metis_src ccolamd_src camd_src cholmod_src source] ; 284end 285 286for f = source 287 ff = f {1} ; 288 if (isequal (ff, [metis_path '/GKlib/util'])) 289 % special case, since a file with the same name also exists in libmetis 290 copyfile ([ff '.c'], 'GKlib_util.c', 'f') ; 291 ff = 'GKlib_util' ; 292 o = 'GKlib_util' ; 293 elseif (isequal (ff, [metis_path '/GKlib/graph'])) 294 % special case, since a file with the same name also exist in libmetis 295 copyfile ([ff '.c'], 'GKlib_graph.c', 'f') ; 296 ff = 'GKlib_graph' ; 297 o = 'GKlib_graph' ; 298 else 299 slash = strfind (ff, '/') ; 300 if (isempty (slash)) 301 slash = 1 ; 302 else 303 slash = slash (end) + 1 ; 304 end 305 o = ff (slash:end) ; 306 end 307 % fprintf ('%s\n', o) ; 308 o = [o obj_extension] ; 309 obj = [obj ' ' o] ; %#ok 310 s = sprintf ('mex %s -DDLONG -O %s -c %s.c', d, include, ff) ; 311 kk = do_cmd (s, kk, details) ; 312end 313 314for k = 1:length(klu_zlsrc) 315 ff = klu_zlsrc {k} ; 316 slash = strfind (ff, '/') ; 317 if (isempty (slash)) 318 slash = 1 ; 319 else 320 slash = slash (end) + 1 ; 321 end 322 o = ff (slash:end) ; 323 s = sprintf ('mex %s -DDLONG -O %s -c %s.c', d, include, ff) ; 324 kk = do_cmd (s, kk, details) ; 325 lobj = klu_lobj {k} ; 326 obj = [obj ' ' lobj obj_extension] ; %#ok 327 mvfile ([o obj_extension], [lobj obj_extension]) ; 328 s = sprintf ('mex %s -DDLONG -DCOMPLEX -O %s -c %s.c', d, include, ff) ; 329 kk = do_cmd (s, kk, details) ; 330 zlobj = klu_zlobj {k} ; 331 obj = [obj ' ' zlobj obj_extension] ; %#ok 332 mvfile ([o obj_extension], [zlobj obj_extension]) ; 333end 334 335% compile the KLU mexFunction 336s = sprintf ('mex %s -DDLONG -O %s -output klu klu_mex.c', d, include) ; 337s = [s obj] ; %#ok 338 339if (~(ispc || ismac)) 340 % for POSIX timing routine 341 s = [s ' -lrt'] ; 342end 343 344kk = do_cmd (s, kk, details) ; 345 346% clean up 347s = ['delete ' obj] ; 348do_cmd (s, kk, details) ; 349 350rmfile ('GKlib_util.c') ; 351rmfile ('GKlib_graph.c') ; 352 353fprintf ('\nKLU successfully compiled\n') ; 354 355%------------------------------------------------------------------------------- 356 357function rmfile (file) 358% rmfile: delete a file, but only if it exists 359if (length (dir (file)) > 0) %#ok 360 delete (file) ; 361end 362 363%------------------------------------------------------------------------------- 364 365function cpfile (src, dst) 366% cpfile: copy the src file to the filename dst, overwriting dst if it exists 367rmfile (dst) 368if (length (dir (src)) == 0) %#ok 369 fprintf ('File does not exist: %s\n', src) ; 370 error ('File does not exist') ; 371end 372try 373 copyfile (src, dst) ; 374catch ME 375 % ignore errors of the form "cp: preserving permissions: ... 376 % Operation not supported". rethrow all other errors. 377 if (isempty (strfind (ME.message, 'Operation not supported'))) 378 rethrow (ME) ; 379 end 380end 381 382%------------------------------------------------------------------------------- 383 384function mvfile (src, dst) 385% mvfile: move the src file to the filename dst, overwriting dst if it exists 386cpfile (src, dst) ; 387rmfile (src) ; 388 389%------------------------------------------------------------------------------- 390function kk = do_cmd (s, kk, details) 391%DO_CMD: evaluate a command, and either print it or print a "." 392if (details) 393 fprintf ('%s\n', s) ; 394else 395 if (mod (kk, 60) == 0) 396 fprintf ('\n') ; 397 end 398 kk = kk + 1 ; 399 fprintf ('.') ; 400end 401eval (s) ; 402 403