/*************************************************************************/ /* */ /* Copyright (c) 1994 Stanford University */ /* */ /* All rights reserved. */ /* */ /* Permission is given to use, copy, and modify this software for any */ /* non-commercial purpose as long as this copyright notice is not */ /* removed. All other uses, including redistribution in whole or in */ /* part, are forbidden without prior written permission. */ /* */ /* This software is provided with absolutely no warranty and no */ /* support. */ /* */ /*************************************************************************/ EXTERN_ENV #include "matrix.h" #include #include #define AddMember(set, new) { long s, n; s = set; n = new; \ lc->link[n] = lc->link[s]; lc->link[s] = n; } extern BMatrix LB; extern struct GlobalMemory *Global; extern long *node; /* global */ void FactorLLDomain(long which_domain, long MyNum, struct LocalCopies *lc) { long i, start, root; long j, j_last, j_len, dest_super; long k, k_length, update_size; long theFirst, theLast; long *relative, *indices; double *domain_update; extern long *firstchild, *child; relative = (long *) MyMalloc(LB.n*sizeof(long), MyNum); indices = (long *) MyMalloc(LB.n*sizeof(long), MyNum); root = LB.domains[which_domain]; start = root; while (firstchild[start] != firstchild[start+1]) start = child[firstchild[start]]; lc->link[root+1] = -1; /* compute domain columns */ for (j=start; j<=root; j+=node[j]) { j_last = j+node[j]; j_len = LB.col[j+1]-LB.col[j]; SetDestIndices(j, indices); while (lc->link[j] != -1) { k = lc->link[j]; lc->link[j] = lc->link[k]; k_length = LB.col[k+1]-LB.col[k]; theFirst = lc->first[k]; theLast = theFirst+1; while (theLast < k_length && LB.row[LB.col[k]+theLast] < j_last) theLast++; if (theLast-theFirst == node[j] && k_length-theFirst == j_len) { ModifySuperBySuper(k, theFirst, theLast, k_length, (double *) &LB.entry[LB.col[j]].nz); } else if (node[k] > 1) { ModifySuperBySuper(k, theFirst, theLast, k_length, lc->storage); FindRelativeIndicesLeft(&LB.row[LB.col[k]+theFirst], k_length-theFirst, 0, indices, relative); ScatterSuperUpdate(lc->storage, theLast-theFirst, k_length-theFirst, (double *) &LB.entry[LB.col[j]].nz, j_len, relative); } else { FindRelativeIndicesLeft(&LB.row[LB.col[k]+theFirst], k_length-theFirst, 0, indices, relative); ModifySuperByColumn((double *) &LB.entry[LB.col[k]+theFirst].nz, theLast-theFirst, k_length-theFirst, (double *) &LB.entry[LB.col[j]].nz, j_len, relative); } lc->first[k] = theLast; /* move on */ if (theLast < k_length) { dest_super = LB.row[LB.col[k]+theLast]; if (dest_super > root) dest_super = root+1; else if (node[dest_super] < 0) dest_super += node[dest_super]; AddMember(dest_super, k); } } CompleteSupernodeB(j); lc->first[j] = node[j]; if (lc->first[j] < j_len) { dest_super = LB.row[LB.col[j]+lc->first[j]]; if (dest_super > root) dest_super = root+1; else if (node[dest_super] < 0) dest_super += node[dest_super]; AddMember(dest_super, j); } } /* compute update matrix */ j_len = LB.col[root+1]-LB.col[root]-1; update_size = j_len*(j_len+1)/2; if (update_size == 0) domain_update = NULL; else if (LB.proc_domain_storage[which_domain]) domain_update = LB.proc_domain_storage[which_domain]; else { domain_update = (double *) MyMalloc(update_size*sizeof(double), MyNum); LB.proc_domain_storage[which_domain] = domain_update; } for (i=0; ilink[root+1] != -1) { k = lc->link[root+1]; lc->link[root+1] = lc->link[k]; k_length = LB.col[k+1] - LB.col[k]; theFirst = lc->first[k]; theLast = k_length; if (theLast-theFirst == j_len) { ModifySuperBySuper(k, theFirst, theLast, k_length, domain_update); } else if (node[k] > 1) { ModifySuperBySuper(k, theFirst, theLast, k_length, lc->storage); FindRelativeIndicesLeft(&LB.row[LB.col[k]+theFirst], k_length-theFirst, 0, indices, relative); ScatterSuperUpdate(lc->storage, k_length-theFirst, k_length-theFirst, domain_update, j_len, relative); } else { FindRelativeIndicesLeft(&LB.row[LB.col[k]+theFirst], k_length-theFirst, 0, indices, relative); ModifySuperByColumn((double *) &LB.entry[LB.col[k]+theFirst].nz, theLast-theFirst, k_length-theFirst, domain_update, j_len, relative); } } if (domain_update) { DistributeUpdateFO(which_domain, MyNum, lc); } MyFree(relative); MyFree(indices); } void CompleteSupernodeB(long super) { long i, length, fits, first, last; if (node[super] == 1) { CompleteColumnB(super); return; } length = LB.col[super+1]-LB.col[super]; fits = FitsInCache/length; if (fits > 4) fits &= 0xfffffffc; else if (fits < 2) fits = node[super]; first = super; while (first super+node[super]) last = super+node[super]; i = first; for (; i 4) fits &= 0xfffffffc; else if (fits < 2) fits = node[src]; lastcol = src+node[src]; last = src; while (last < lastcol) { first = last; last = first + fits; if (last > lastcol) last = lastcol; destination = dest; this_length = length-theFirst; i = theFirst; for (; i