void LUSOL_free(LUSOLrec *LUSOL) { LUSOL_realloc_a(LUSOL, 0); LUSOL_realloc_r(LUSOL, 0); LUSOL_realloc_c(LUSOL, 0); if(LUSOL->L0 != NULL) LUSOL_matfree(&(LUSOL->L0)); if(LUSOL->U != NULL) LUSOL_matfree(&(LUSOL->U)); if(!is_nativeBLAS()) unload_BLAS(); LUSOL_FREE(LUSOL); }
MYBOOL load_BLAS(char *libname) { MYBOOL result = TRUE; #ifdef LoadableBlasLib if(hBLAS != NULL) { my_FreeLibrary(hBLAS); } #endif if(libname == NULL) { if(!mustinitBLAS && is_nativeBLAS()) return( FALSE ); BLAS_dscal = my_dscal; BLAS_dcopy = my_dcopy; BLAS_daxpy = my_daxpy; BLAS_dswap = my_dswap; BLAS_ddot = my_ddot; BLAS_idamax = my_idamax; BLAS_idamin = my_idamin; BLAS_dload = my_dload; BLAS_dnormi = my_dnormi; if(mustinitBLAS) mustinitBLAS = FALSE; } else { #ifdef LoadableBlasLib #if (defined LPWINAPP) || (defined WIN64) char *blasname = libname; #else /* First standardize UNIX .SO library name format. */ char blasname[260]; if(!so_stdname(blasname, libname, 260)) return( FALSE ); #endif /* Get a handle to the Windows DLL module. */ hBLAS = my_LoadLibrary(blasname); /* If the handle is valid, try to get the function addresses. */ result = (MYBOOL) (hBLAS != NULL); if(result) { BLAS_dscal = (BLAS_dscal_func *) my_GetProcAddress(hBLAS, BLAS_prec "scal"); BLAS_dcopy = (BLAS_dcopy_func *) my_GetProcAddress(hBLAS, BLAS_prec "copy"); BLAS_daxpy = (BLAS_daxpy_func *) my_GetProcAddress(hBLAS, BLAS_prec "axpy"); BLAS_dswap = (BLAS_dswap_func *) my_GetProcAddress(hBLAS, BLAS_prec "swap"); BLAS_ddot = (BLAS_ddot_func *) my_GetProcAddress(hBLAS, BLAS_prec "dot"); BLAS_idamax = (BLAS_idamax_func *) my_GetProcAddress(hBLAS, "i" BLAS_prec "amax"); BLAS_idamin = (BLAS_idamin_func *) my_GetProcAddress(hBLAS, "i" BLAS_prec "amin"); #if 0 BLAS_dload = (BLAS_dload_func *) my_GetProcAddress(hBLAS, BLAS_prec "load"); BLAS_dnormi = (BLAS_dnormi_func *) my_GetProcAddress(hBLAS, BLAS_prec "normi"); #endif } #endif /* Do validation */ if(!result || ((BLAS_dscal == NULL) || (BLAS_dcopy == NULL) || (BLAS_daxpy == NULL) || (BLAS_dswap == NULL) || (BLAS_ddot == NULL) || (BLAS_idamax == NULL) || (BLAS_idamin == NULL) || (BLAS_dload == NULL) || (BLAS_dnormi == NULL)) ) { load_BLAS(NULL); result = FALSE; } } return( result ); }
MYBOOL load_BLAS(char *libname) { MYBOOL result = TRUE; #ifdef LoadableBlasLib if(hBLAS != NULL) { #ifdef WIN32 FreeLibrary(hBLAS); #else dlclose(hBLAS); #endif hBLAS = NULL; } #endif if(libname == NULL) { if(!mustinitBLAS && is_nativeBLAS()) return( FALSE ); BLAS_dscal = my_dscal; BLAS_dcopy = my_dcopy; BLAS_daxpy = my_daxpy; BLAS_dswap = my_dswap; BLAS_ddot = my_ddot; BLAS_idamax = my_idamax; BLAS_dload = my_dload; BLAS_dnormi = my_dnormi; if(mustinitBLAS) mustinitBLAS = FALSE; } else { #ifdef LoadableBlasLib #ifdef WIN32 /* Get a handle to the Windows DLL module. */ hBLAS = LoadLibrary(libname); /* If the handle is valid, try to get the function addresses. */ result = (MYBOOL) (hBLAS != NULL); if(result) { BLAS_dscal = (BLAS_dscal_func *) GetProcAddress(hBLAS, BLAS_prec "scal"); BLAS_dcopy = (BLAS_dcopy_func *) GetProcAddress(hBLAS, BLAS_prec "copy"); BLAS_daxpy = (BLAS_daxpy_func *) GetProcAddress(hBLAS, BLAS_prec "axpy"); BLAS_dswap = (BLAS_dswap_func *) GetProcAddress(hBLAS, BLAS_prec "swap"); BLAS_ddot = (BLAS_ddot_func *) GetProcAddress(hBLAS, BLAS_prec "dot"); BLAS_idamax = (BLAS_idamax_func *) GetProcAddress(hBLAS, "i" BLAS_prec "amax"); #if 0 BLAS_dload = (BLAS_dload_func *) GetProcAddress(hBLAS, BLAS_prec "load"); BLAS_dnormi = (BLAS_dnormi_func *) GetProcAddress(hBLAS, BLAS_prec "normi"); #endif } #else /* First standardize UNIX .SO library name format. */ char blasname[260], *ptr; strcpy(blasname, libname); if((ptr = strrchr(libname, '/')) == NULL) ptr = libname; else ptr++; blasname[(int) (ptr - libname)] = 0; if(strncmp(ptr, "lib", 3)) strcat(blasname, "lib"); strcat(blasname, ptr); if(strcmp(blasname + strlen(blasname) - 3, ".so")) strcat(blasname, ".so"); /* Get a handle to the module. */ hBLAS = dlopen(blasname, RTLD_LAZY); /* If the handle is valid, try to get the function addresses. */ result = (MYBOOL) (hBLAS != NULL); if(result) { BLAS_dscal = (BLAS_dscal_func *) dlsym(hBLAS, BLAS_prec "scal"); BLAS_dcopy = (BLAS_dcopy_func *) dlsym(hBLAS, BLAS_prec "copy"); BLAS_daxpy = (BLAS_daxpy_func *) dlsym(hBLAS, BLAS_prec "axpy"); BLAS_dswap = (BLAS_dswap_func *) dlsym(hBLAS, BLAS_prec "swap"); BLAS_ddot = (BLAS_ddot_func *) dlsym(hBLAS, BLAS_prec "dot"); BLAS_idamax = (BLAS_idamax_func *) dlsym(hBLAS, "i" BLAS_prec "amax"); #if 0 BLAS_dload = (BLAS_dload_func *) dlsym(hBLAS, BLAS_prec "load"); BLAS_dnormi = (BLAS_dnormi_func *) dlsym(hBLAS, BLAS_prec "normi"); #endif } #endif #endif /* Do validation */ if(!result || ((BLAS_dscal == NULL) || (BLAS_dcopy == NULL) || (BLAS_daxpy == NULL) || (BLAS_dswap == NULL) || (BLAS_ddot == NULL) || (BLAS_idamax == NULL) || (BLAS_dload == NULL) || (BLAS_dnormi == NULL)) ) { load_BLAS(NULL); result = FALSE; } } return( result ); }
/* MUST MODIFY */ MYBOOL BFP_CALLMODEL bfp_resize(lprec *lp, int newsize) { INVrec *lu; lu = lp->invB; /* Increment dimensionality since we put the objective row at the top */ newsize = newsize + bfp_rowoffset(lp); lu->dimalloc = newsize; /* Allocate index tracker arrays, LU matrices and various work vectors */ if(!allocREAL(lp, &(lu->value), newsize+MATINDEXBASE, AUTOMATIC)) return( FALSE ); /* Data specific to the factorization engine */ if(lu->LUSOL != NULL) { if(newsize > 0 || 1) LUSOL_sizeto(lu->LUSOL, newsize, newsize, 0); else { LUSOL_free(lu->LUSOL); lu->LUSOL = NULL; } } else if(newsize > 0 || 1) { int asize; REAL bsize; lu->LUSOL = LUSOL_create(NULL, 0, LUSOL_PIVMOD_TPP, bfp_pivotmax(lp)*0); #if 1 lu->LUSOL->luparm[LUSOL_IP_ACCELERATION] = LUSOL_AUTOORDER; lu->LUSOL->parmlu[LUSOL_RP_SMARTRATIO] = 0.50; #endif #if 0 lu->timed_refact = DEF_TIMEDREFACT; #else lu->timed_refact = FALSE; #endif /* The following adjustments seem necessary to make the really tough NETLIB models perform reliably and still performant (e.g. cycle.mps) */ #if 0 lu->LUSOL->parmlu[LUSOL_RP_SMALLDIAG_U] = lu->LUSOL->parmlu[LUSOL_RP_EPSDIAG_U] = lp->epsprimal; #endif #if 0 lu->LUSOL->parmlu[LUSOL_RP_ZEROTOLERANCE] = lp->epsvalue; #endif #if 1 LUSOL_setpivotmodel(lu->LUSOL, LUSOL_PIVMOD_NOCHANGE, LUSOL_PIVTOL_SLIM); #else LUSOL_setpivotmodel(lu->LUSOL, LUSOL_PIVMOD_NOCHANGE, LUSOL_PIVTOL_TIGHT); #endif #ifdef LUSOL_UseBLAS /* if(fileSearchPath("PATH", "myBLAS.DLL", NULL) && load_BLAS("myBLAS")) */ if(is_nativeBLAS() && load_BLAS(libnameBLAS)) lp->report(lp, NORMAL, "Optimized BLAS was successfully loaded for bfp_LUSOL.\n"); #endif /* Try to minimize memory allocation if we have a large number of unit columns */ bsize = (REAL) lp->get_nonzeros(lp); if(newsize > lp->columns) bsize += newsize; else bsize = bsize/lp->columns*newsize; /* Add a "reasonable" delta to allow for B and associated factorizations that are denser than average; this makes reallocations less frequent. Values between 1.2 and 1.5 appear to be reasonable. */ asize = (int) (bsize*MAX_DELTAFILLIN*1.3333); if(!LUSOL_sizeto(lu->LUSOL, newsize, newsize, asize)) return( FALSE ); } lu->dimcount = newsize; return( TRUE ); }