Exemple #1
0
void kass_symbol(csptr mat, PASTIX_INT levelk, double rat, PASTIX_INT *perm, PASTIX_INT *iperm, PASTIX_INT snodenbr, PASTIX_INT *snodetab, PASTIX_INT *streetab, PASTIX_INT *cblknbr, PASTIX_INT **rangtab, SymbolMatrix *symbmtx, MPI_Comm pastix_comm)
{
  /**************************************************************************************/
  /* This function computes a symbolic factorization ILU(k) given a CSR matrix and an   */
  /* ordering. Then it computes a block partition of the factor to get BLAS3            */
  /* efficiency                                                                         */
  /* NOTE: the CSC matrix is given symmetrized and without the diagonal                 */
  /**************************************************************************************/

  PASTIX_INT i, j;
  PASTIX_INT nnzL;
  PASTIX_INT *iperm2  = NULL;
  PASTIX_INT *treetab = NULL;
  PASTIX_INT n;
  csptr P;
  Clock timer1;
  int procnum;

  MPI_Comm_rank(pastix_comm,&procnum);

  n = mat->n;
  MALLOC_INTERN(iperm2, n, PASTIX_INT);

  /*compact_graph(mat, NULL, NULL, NULL);*/

  /*** Compute the ILU(k) pattern of the quotient matrix ***/
  MALLOC_INTERN(P, 1, struct SparRow);
  initCS(P, n);
  print_one("Level of fill = %ld\nAmalgamation ratio = %d \n", (long)levelk, (int)(rat*100));
  clockInit(&timer1);
  clockStart(&timer1);

  if(levelk == -1)
    {

      /***** FACTORISATION DIRECT *******/
      /***** (Re)compute also the streetab (usefull when SCOTCH_SNODE
             is active) ***/
      SF_Direct(mat, snodenbr, snodetab, streetab, P);

      clockStop(&timer1);
      print_one("Time to compute scalar symbolic direct factorization  %.3g s \n", clockVal(&timer1));
#ifdef DEBUG_KASS
      print_one("non-zeros in P = %ld \n", (long)CSnnz(P));
#endif
      nnzL = 0;
      for(i=0;i<P->n;i++)
        {
          PASTIX_INT ncol;
          ncol = snodetab[i+1]-snodetab[i];
          nnzL += (ncol*(ncol+1))/2;
#ifdef DEBUG_KASS
          ASSERT(P->nnzrow[i] >= ncol, MOD_KASS);
          if(P->nnzrow[i] >= n)
            fprintf(stderr,"P->nnzrow[%ld] = %ld \n", (long)i, (long)P->nnzrow[i]);
          ASSERT(P->nnzrow[i] < n, MOD_KASS);
#endif
          nnzL += (P->nnzrow[i]-ncol)*ncol;
        }
#ifdef DEBUG_KASS
      print_one("NNZL = %ld \n", (long)nnzL);
#endif
    }
  else
    {
      /***** FACTORISATION INCOMPLETE *******/
      nnzL = SF_level(2, mat, levelk, P);

      clockStop(&timer1);
      print_one("Time to compute scalar symbolic factorization of ILU(%ld) %.3g s \n",
              (long)levelk, clockVal(&timer1));

    }
  print_one("Scalar nnza = %ld nnzlk = %ld, fillrate0 = %.3g \n",
            (long)( CSnnz(mat) + n)/2, (long)nnzL, (double)nnzL/(double)( (CSnnz(mat)+n)/2.0 ));



  /** Sort the rows of the symbolic matrix */
  sort_row(P);

  clockInit(&timer1);
  clockStart(&timer1);

  if(levelk != -1)
    {

      /********************************/
      /** Compute the "k-supernodes" **/
      /********************************/

#ifdef KS
      assert(levelk >= 0);
      KSupernodes(P, rat, snodenbr, snodetab, cblknbr, rangtab);
#else

#ifdef SCOTCH_SNODE
      if(rat == -1)
        assert(0); /** do not have treetab with this version of Scotch **/
#endif

      MALLOC_INTERN(treetab, P->n, PASTIX_INT);
      for(j=0;j<snodenbr;j++)
        {
          for(i=snodetab[j];i<snodetab[j+1]-1;i++)
            treetab[i] = i+1;

          /*** Version generale ****/
          if(streetab[j] == -1 || streetab[j] == j)
            treetab[i] = -1;
          else
            treetab[i]=snodetab[streetab[j]];
          /*** Version restricted inside the supernode (like KSupernodes) ***/
          /*treetab[snodetab[j+1]-1] = -1;*/  /** this should give the same results than
                                                  KSupernodes **/
        }

      /** NEW ILUK + DIRECT **/
      amalgamate(rat, P, -1, NULL, treetab, cblknbr, rangtab, iperm2, pastix_comm);

      memFree(treetab);
      for(i=0;i<n;i++)
        iperm2[i] = iperm[iperm2[i]];
      memcpy(iperm, iperm2, sizeof(PASTIX_INT)*n);
      for(i=0;i<n;i++)
        perm[iperm[i]] = i;
#endif
    }
  else{


    /*if(0)*/
      {
        amalgamate(rat, P, snodenbr, snodetab, streetab, cblknbr,
                   rangtab, iperm2, pastix_comm);

        /** iperm2 is the iperm vector of P **/
        for(i=0;i<n;i++)
          iperm2[i] = iperm[iperm2[i]];
        memcpy(iperm, iperm2, sizeof(PASTIX_INT)*n);
        for(i=0;i<n;i++)
          perm[iperm[i]] = i;
      }
      /*else
      {
        fprintf(stderr, "RAT = 0 SKIP amalgamation \n");
        *cblknbr = snodenbr;
        MALLOC_INTERN(*rangtab, snodenbr+1, PASTIX_INT);
        memcpy(*rangtab, snodetab, sizeof(PASTIX_INT)*(snodenbr+1));
        }*/
  }

  clockStop(&timer1);
  print_one("Time to compute the amalgamation of supernodes %.3g s\n", clockVal(&timer1));

  print_one("Number of cblk in the amalgamated symbol matrix = %ld \n", (long)*cblknbr);


  Build_SymbolMatrix(P, *cblknbr, *rangtab, symbmtx);


  print_one("Number of block in the non patched symbol matrix = %ld \n", (long)symbmtx->bloknbr);


  memFree(iperm2);
  cleanCS(P);
  memFree(P);

}
Exemple #2
0
/*
 * Check whether pointed patterns p and q notate the same ordinal.
 * Assumes working in scratch-space (see core.c)
 */
int same_point( pattern *p, pattern *q )
{
  amal *a = amalgamate( copy_pattern(p), copy_pattern(q) );

  return ( a->p1_in_p->position == a->p2_in_p->position );
}