LIS_INT lis_matrix_split2_csr(LIS_MATRIX A) { LIS_INT i,j,n; LIS_INT nnzl,nnzu; LIS_INT err; LIS_INT *lptr,*lindex,*uptr,*uindex; LIS_SCALAR *lvalue,*uvalue; #ifdef _OPENMP LIS_INT kl,ku; LIS_INT *liw,*uiw; #endif LIS_DEBUG_FUNC_IN; n = A->n; nnzl = 0; nnzu = 0; lptr = NULL; lindex = NULL; lvalue = NULL; uptr = NULL; uindex = NULL; uvalue = NULL; #ifdef _OPENMP liw = (LIS_INT *)lis_malloc((n+1)*sizeof(LIS_INT),"lis_matrix_split2_csr::liw"); if( liw==NULL ) { LIS_SETERR_MEM((n+1)*sizeof(LIS_INT)); return LIS_OUT_OF_MEMORY; } uiw = (LIS_INT *)lis_malloc((n+1)*sizeof(LIS_INT),"lis_matrix_split2_csr::uiw"); if( uiw==NULL ) { LIS_SETERR_MEM((n+1)*sizeof(LIS_INT)); lis_free(liw); return LIS_OUT_OF_MEMORY; } #pragma omp parallel for private(i) for(i=0;i<n+1;i++) { liw[i] = 0; uiw[i] = 0; } #pragma omp parallel for private(i,j) for(i=0;i<n;i++) { for(j=A->ptr[i];j<A->ptr[i+1];j++) { if( A->index[j]<n ) { liw[i+1]++; } else { uiw[i+1]++; } } } for(i=0;i<n;i++) { liw[i+1] += liw[i]; uiw[i+1] += uiw[i]; } nnzl = liw[n]; nnzu = uiw[n]; #else for(i=0;i<n;i++) { for(j=A->ptr[i];j<A->ptr[i+1];j++) { if( A->index[j]<n ) { nnzl++; } else { nnzu++; } } } #endif err = lis_matrix_LU_create(A); if( err ) { return err; } err = lis_matrix_malloc_csr(n,nnzl,&lptr,&lindex,&lvalue); if( err ) { return err; } err = lis_matrix_malloc_csr(n,nnzu,&uptr,&uindex,&uvalue); if( err ) { lis_free2(6,lptr,lindex,lvalue,uptr,uindex,uvalue); return err; } #ifdef _OPENMP #pragma omp parallel for private(i) for(i=0;i<n+1;i++) { lptr[i] = liw[i]; uptr[i] = uiw[i]; } #pragma omp parallel for private(i,j,kl,ku) for(i=0;i<n;i++) { kl = lptr[i]; ku = uptr[i]; for(j=A->ptr[i];j<A->ptr[i+1];j++) { if( A->index[j]<n ) { lindex[kl] = A->index[j]; lvalue[kl] = A->value[j]; kl++; } else { uindex[ku] = A->index[j]; uvalue[ku] = A->value[j]; ku++; } } } lis_free2(2,liw,uiw); #else nnzl = 0; nnzu = 0; lptr[0] = 0; uptr[0] = 0; for(i=0;i<n;i++) { for(j=A->ptr[i];j<A->ptr[i+1];j++) { if( A->index[j]<n ) { lindex[nnzl] = A->index[j]; lvalue[nnzl] = A->value[j]; nnzl++; } else { uindex[nnzu] = A->index[j]; uvalue[nnzu] = A->value[j]; nnzu++; } } lptr[i+1] = nnzl; uptr[i+1] = nnzu; } #endif A->L->nnz = nnzl; A->L->ptr = lptr; A->L->index = lindex; A->L->value = lvalue; A->U->nnz = nnzu; A->U->ptr = uptr; A->U->index = uindex; A->U->value = uvalue; A->is_splited = LIS_TRUE; LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }
LIS_INT lis_matrix_split_msr(LIS_MATRIX A) { LIS_INT i,j,n; LIS_INT lnnz,unnz; LIS_INT lndz,undz; LIS_INT err; LIS_INT *lindex,*uindex; LIS_SCALAR *lvalue,*uvalue; #ifdef _OPENMP LIS_INT kl,ku; LIS_INT *liw,*uiw; #endif LIS_MATRIX_DIAG D; LIS_DEBUG_FUNC_IN; n = A->n; lnnz = 0; unnz = 0; lndz = n; undz = n; D = NULL; lindex = NULL; lvalue = NULL; uindex = NULL; uvalue = NULL; #ifdef _OPENMP liw = (LIS_INT *)lis_malloc((n+1)*sizeof(LIS_INT),"lis_matrix_split_msr::liw"); if( liw==NULL ) { LIS_SETERR_MEM((n+1)*sizeof(LIS_INT)); return LIS_OUT_OF_MEMORY; } uiw = (LIS_INT *)lis_malloc((n+1)*sizeof(LIS_INT),"lis_matrix_split_msr::uiw"); if( uiw==NULL ) { LIS_SETERR_MEM((n+1)*sizeof(LIS_INT)); lis_free(liw); return LIS_OUT_OF_MEMORY; } #pragma omp parallel for private(i) for(i=0;i<n+1;i++) { liw[i] = 0; uiw[i] = 0; } #pragma omp parallel for private(i,j) for(i=0;i<n;i++) { for(j=A->index[i];j<A->index[i+1];j++) { if( A->index[j]<i ) { liw[i+1]++; } else if( A->index[j]>i ) { uiw[i+1]++; } } } liw[0] = n+1; uiw[0] = n+1; for(i=0;i<n;i++) { liw[i+1] += liw[i]; uiw[i+1] += uiw[i]; } lnnz = liw[n]; unnz = uiw[n]; #else for(i=0;i<n;i++) { for(j=A->index[i];j<A->index[i+1];j++) { if( A->index[j]<i ) { lnnz++; } else if( A->index[j]>i ) { unnz++; } } } #endif err = lis_matrix_LU_create(A); if( err ) { return err; } err = lis_matrix_malloc_msr(n,lnnz,lndz,&lindex,&lvalue); if( err ) { return err; } err = lis_matrix_malloc_msr(n,unnz,undz,&uindex,&uvalue); if( err ) { lis_free2(4,lindex,lvalue,uindex,uvalue); return err; } err = lis_matrix_diag_duplicateM(A,&D); if( err ) { lis_free2(4,lindex,lvalue,uindex,uvalue); return err; } #ifdef _OPENMP #pragma omp parallel for private(i) for(i=0;i<n+1;i++) { lindex[i] = liw[i]; uindex[i] = uiw[i]; } #pragma omp parallel for private(i,j,kl,ku) for(i=0;i<n;i++) { kl = lindex[i]; ku = uindex[i]; D->value[i] = A->value[i]; for(j=A->index[i];j<A->index[i+1];j++) { if( A->index[j]<i ) { lindex[kl] = A->index[j]; lvalue[kl] = A->value[j]; kl++; } else if( A->index[j]>i ) { uindex[ku] = A->index[j]; uvalue[ku] = A->value[j]; ku++; } } } lis_free2(2,liw,uiw); #else lnnz = n+1; unnz = n+1; lindex[0] = n+1; uindex[0] = n+1; for(i=0;i<n;i++) { D->value[i] = A->value[i]; for(j=A->index[i];j<A->index[i+1];j++) { if( A->index[j]<i ) { lindex[lnnz] = A->index[j]; lvalue[lnnz] = A->value[j]; lnnz++; } else if( A->index[j]>i ) { uindex[unnz] = A->index[j]; uvalue[unnz] = A->value[j]; unnz++; } } lindex[i+1] = lnnz; uindex[i+1] = unnz; } #endif A->L->nnz = lnnz - (n+1); A->L->ndz = lndz; A->L->index = lindex; A->L->value = lvalue; A->U->nnz = unnz - (n+1); A->U->ndz = undz; A->U->index = uindex; A->U->value = uvalue; A->D = D; A->is_splited = LIS_TRUE; LIS_DEBUG_FUNC_OUT; return LIS_SUCCESS; }