示例#1
0
文件: Manager.cpp 项目: biddyweb/ewol
void ewol::object::Manager::timeCall(int64_t _localTime) {
	int64_t previousTime = m_lastPeriodicCallTime;
	m_lastPeriodicCallTime = _localTime;
	if (periodicCall.getNumberConnected() <= 0) {
		return;
	}
	float deltaTime = (float)(_localTime - previousTime)/1000000.0;
	ewol::event::Time myTime(_localTime, m_applWakeUpTime, deltaTime, deltaTime);
	periodicCall.emit(myTime);
}
//=========================================================================
RowMatrix_Transpose::NewTypeRef
RowMatrix_Transpose::
operator()( OriginalTypeRef orig )
{
  origObj_ = &orig;

  if( !TransposeRowMap_ )
  {
    if( IgnoreNonLocalCols_ )
      TransposeRowMap_ = (Epetra_Map *) &(orig.OperatorRangeMap()); // Should be replaced with refcount =
    else
      TransposeRowMap_ = (Epetra_Map *) &(orig.OperatorDomainMap()); // Should be replaced with refcount =
  }

  NumMyRows_ = orig.NumMyRows();
  NumMyCols_ = orig.NumMyCols();

  // This routine will work for any RowMatrix object, but will attempt cast the matrix to a CrsMatrix if
  // possible (because we can then use a View of the matrix and graph, which is much cheaper).

  // First get the local indices to count how many nonzeros will be in the
  // transpose graph on each processor
  Epetra_CrsMatrix * TempTransA1 = CreateTransposeLocal(orig);

  if(!TempTransA1->Exporter()) {
    // Short Circuit: There is no need to make another matrix since TransposeRowMap_== TransMap
    newObj_ = TransposeMatrix_ = TempTransA1;
    return *newObj_;
  }

#ifdef ENABLE_TRANSPOSE_TIMINGS
  Teuchos::Time myTime("global");
  Teuchos::TimeMonitor MM(myTime);
  Teuchos::RCP<Teuchos::Time> mtime;
  mtime=MM.getNewTimer("Transpose: Final FusedExport");
  mtime->start();
#endif

  // Now that transpose matrix with shared rows is entered, create a new matrix that will
  // get the transpose with uniquely owned rows (using the same row distribution as A).
  TransposeMatrix_ = new Epetra_CrsMatrix(*TempTransA1,*TempTransA1->Exporter(),NULL,0,TransposeRowMap_, false);

#ifdef ENABLE_TRANSPOSE_TIMINGS
  mtime->stop();
#endif

  newObj_ = TransposeMatrix_;
  delete TempTransA1;
  return *newObj_;
}
//=========================================================================
  Epetra_CrsMatrix* EpetraExt::RowMatrix_Transpose::CreateTransposeLocal(OriginalTypeRef orig)
{
#ifdef ENABLE_TRANSPOSE_TIMINGS
  Teuchos::Time myTime("global");
  Teuchos::TimeMonitor MM(myTime);
  Teuchos::RCP<Teuchos::Time> mtime;
  mtime=MM.getNewTimer("Transpose: CreateTransposeLocal 1");
  mtime->start();
#endif

  int i,j,err;
  const Epetra_CrsMatrix * OrigCrsMatrix = dynamic_cast<const Epetra_CrsMatrix*>(&orig);
  if(OrigCrsMatrix) OrigMatrixIsCrsMatrix_ = true;
  else OrigMatrixIsCrsMatrix_ = false;

  const Epetra_Map & TransMap      = orig.RowMatrixColMap();
  int TransNnz                     = orig.NumMyNonzeros();
  int NumIndices;

  Epetra_CrsMatrix *TempTransA1 = new Epetra_CrsMatrix(Copy, TransMap,orig.RowMatrixRowMap(),0);
  Epetra_IntSerialDenseVector & TransRowptr = TempTransA1->ExpertExtractIndexOffset();
  Epetra_IntSerialDenseVector & TransColind = TempTransA1->ExpertExtractIndices();
  double *&                     TransVals   = TempTransA1->ExpertExtractValues();
  NumMyRows_ = orig.NumMyRows();
  NumMyCols_ = orig.NumMyCols();

  TransRowptr.Resize(NumMyCols_+1);
  TransColind.Resize(TransNnz);
  resize_doubles(0,TransNnz,TransVals);
  std::vector<int> CurrentStart(NumMyCols_,0);

  // Count up nnz using the Rowptr to count the number of non-nonzeros.
  if (OrigMatrixIsCrsMatrix_)
  {
    const Epetra_CrsGraph & OrigGraph = OrigCrsMatrix->Graph(); // Get matrix graph

    for (i=0; i<NumMyRows_; i++)
    {
      err = OrigGraph.ExtractMyRowView(i, NumIndices, Indices_); // Get view of ith row
      if (err != 0) throw OrigGraph.ReportError("ExtractMyRowView failed",err);
      for (j=0; j<NumIndices; j++) ++CurrentStart[Indices_[j]];
    }
  }
  else // Original is not a CrsMatrix
  {
    MaxNumEntries_ = 0;
    MaxNumEntries_ = orig.MaxNumEntries();
    delete [] Indices_; delete [] Values_;
    Indices_ = new int[MaxNumEntries_];
    Values_  = new double[MaxNumEntries_];

    for (i=0; i<NumMyRows_; i++)
    {
      err = orig.ExtractMyRowCopy(i, MaxNumEntries_, NumIndices, Values_, Indices_);
      if (err != 0) {
        std::cerr << "ExtractMyRowCopy failed."<<std::endl;
        throw err;
      }
      for (j=0; j<NumIndices; j++) ++CurrentStart[Indices_[j]];
    }
  }

  // Scansum the rowptr; reset currentstart
  TransRowptr[0] = 0;
  for (i=1;i<NumMyCols_+1; i++)  TransRowptr[i]   = CurrentStart[i-1] + TransRowptr[i-1];
  for (i=0;i<NumMyCols_;   i++)  CurrentStart[i]  = TransRowptr[i];

  // Now copy values and global indices into newly create transpose storage
  for (i=0; i<NumMyRows_; i++)
  {
    if (OrigMatrixIsCrsMatrix_)
      err = OrigCrsMatrix->ExtractMyRowView(i, NumIndices, Values_, Indices_);
    else
      err = orig.ExtractMyRowCopy(i, MaxNumEntries_, NumIndices, Values_, Indices_);
    if (err != 0) {
      std::cerr << "ExtractMyRowCopy failed."<<std::endl;
      throw err;
    }

    for (j=0; j<NumIndices; j++)
    {
      int idx = CurrentStart[Indices_[j]];
      TransColind[idx] = i;
      TransVals[idx]    = Values_[j];
      ++CurrentStart[Indices_[j]];// increment the counter into the local row
    }
  }

#ifdef ENABLE_TRANSPOSE_TIMINGS
  mtime->stop();
  mtime=MM.getNewTimer("Transpose: CreateTransposeLocal 2");
  mtime->start();
#endif

  // Prebuild the importers and exporters the no-communication way, flipping the importers
  // and exporters around.
  Epetra_Import * myimport = 0;
  Epetra_Export * myexport = 0;
  if(OrigMatrixIsCrsMatrix_ && OrigCrsMatrix->Importer())
    myexport = new Epetra_Export(*OrigCrsMatrix->Importer());
  if(OrigMatrixIsCrsMatrix_ && OrigCrsMatrix->Exporter())
    myimport = new Epetra_Import(*OrigCrsMatrix->Exporter());

#ifdef ENABLE_TRANSPOSE_TIMINGS
  mtime->stop();
  mtime=MM.getNewTimer("Transpose: CreateTransposeLocal 3");
  mtime->start();
#endif

  // Call ExpertStaticFillComplete
  err = TempTransA1->ExpertStaticFillComplete(orig.OperatorRangeMap(),orig.OperatorDomainMap(),myimport,myexport);
  if (err != 0) {
    throw TempTransA1->ReportError("ExpertStaticFillComplete failed.",err);
  }

#ifdef ENABLE_TRANSPOSE_TIMINGS
  mtime->stop();
#endif

  return TempTransA1;
}
int main(int argc, char* argv[])
{

    typedef long           Int;
    typedef double         Entry;
    typedef Kokkos::OpenMP Exe_Space;

    if(argc < 2)
    {
        std::cout << "Inputs nthreads matrix.mtx (optional rhs.mtx)" << std::endl;
        return -1;
    }

    Int nthreads = atoi(argv[1]);
    std::string mname = std::string(argv[2]);
    std::string vname;


    //Load inital information
    //Matrix
    Int m, n, nnz;
    m = n = nnz = 0;
    Int *col_ptr, *row_idx;
    Entry *val;
    col_ptr = NULL;

    std::cout << "Matrix read" << std::endl;
    double rmatrix = myTime();
    readMatrix<Int,Entry>(mname, m, n, nnz,
                          &col_ptr, &row_idx, &val);
    std::cout << "Read Matrix, Time: "
              << totalTime(rmatrix,myTime()) << std::endl;

    //RHS
    Int vn, vm;
    vn = vm = 0;
    Entry *x, *xhat, *y;
    x = xhat = y = NULL;
    vn = n;
    x = new Entry[vn]();
    xhat = new Entry[vn]();

    if(argc == 4)
    {

        vname = std::string(argv[3]);
        //std::cout << "reading vector " << vname << std::endl;
        readVector<Int,Entry>(vname, vm, &y);
    }
    else
    {
        vm = m;
        y = new Entry[m]();
        for(Int i = 0; i < vm; i++)
        {
            xhat[i] = (Entry) i;
        }
        multiply<Int,Entry>(m,n,col_ptr,row_idx,val, xhat, y);
        for(Int i = 0; i < vm; i++)
        {
            //std::cout  << "y " << y[i] << std::endl;
            xhat[i] = (Entry) 0.0;
        }
    }

    //Starting up Kokkos
    Exe_Space::initialize(nthreads);
    std::cout << "Kokkos Settings" << std::endl;
    std::cout << "hwloc aval: "
              << Kokkos::hwloc::available()<< std::endl;
    std::cout << "numa count: "
              << Kokkos::hwloc::get_available_numa_count()
              << std::endl;
    std::cout << "thrd numa:  "
              << Kokkos::hwloc::get_available_cores_per_numa()
              << std::endl;

    //Start Basker
    {
//    int result = 0; // NDE warning unused
        BaskerNS::Basker<Int, Entry, Exe_Space> mybasker;
        //---Options
        mybasker.Options.same_pattern       = BASKER_FALSE;
        mybasker.Options.verbose            = BASKER_FALSE;
        mybasker.Options.verbose_matrix_out = BASKER_FALSE;
        mybasker.Options.realloc            = BASKER_TRUE;
        mybasker.Options.transpose          = BASKER_FALSE;
        mybasker.Options.symmetric          = BASKER_FALSE;
        mybasker.Options.AtA                = BASKER_TRUE;
        mybasker.Options.A_plus_At          = BASKER_TRUE;
        mybasker.Options.matching           = BASKER_TRUE;
        mybasker.Options.matching_type      = BASKER_MATCHING_BN;
        mybasker.Options.btf                = BASKER_TRUE;
        mybasker.Options.btf_max_percent    = BASKER_BTF_MAX_PERCENT;
        mybasker.Options.btf_large          = BASKER_BTF_LARGE;
        mybasker.Options.no_pivot           = BASKER_FALSE;
        //mybasker.Options.pivot_tol          = .001;
        //mybasker.Options.pivot_bias         = .001;
        //mybasker.Options.btf_prune_size      = 2;


        mybasker.SetThreads(nthreads);
        std::cout << "Setting Threads:" << nthreads << std::endl;
        double stime = myTime();
        mybasker.Symbolic(m,n,nnz,col_ptr,row_idx,val);
        std::cout << "Done with Symbolic, Time: "
                  << totalTime(stime, myTime()) << std::endl;
        double ftime = myTime();
        mybasker.Factor(m,n,nnz,col_ptr,row_idx,val);
        std::cout << "Done with Factor, Time: "
                  << totalTime(ftime, myTime()) << std::endl;
        //mybasker.DEBUG_PRINT();
        double ttime = myTime();
        mybasker.SolveTest();
        Int *lperm;
        Int *rperm;
        mybasker.GetPerm(&lperm,&rperm);

        mybasker.Solve(y,x);
        std::cout << "Done with Solve, Time: "
                  << totalTime(ttime, myTime()) << std::endl;

        multiply<Int,Entry>(m,n,col_ptr,row_idx,val, x, xhat);
        for(Int i = 0; i < m; i++)
        {
            xhat[i] = y[i] - xhat[i];
        }

        /*
        for(Int i = 0; i < n; i++)
          {
        std::cout << "idx: " << i
                  << "x: " << x[i]
        	  << " xhat: " << xhat[i]
        	  << " y: " << y[i]
        	  << std::endl;
          }
        */

        std::cout << "||X||: " << norm2<Int,Entry>(n,x)
                  << " ||Y-AX||: " << norm2<Int,Entry>(m,xhat)
                  << std::endl;


        /*
        //Refactor
        double rftime = myTime();
        mybasker.Factor(m,n,nnz,col_ptr,row_idx,val);
        std::cout << "Done with Refactor Factor, Time: "
              << totalTime(rftime, myTime()) << std::endl;
        //ReSolve
        double rttime = myTime();
        mybasker.Solve(y,x);
        std::cout << "Done with Refactor Solve, Time: "
              << totalTime(rttime, myTime()) << std::endl;

        multiply<Int,Entry>(m,n,col_ptr,row_idx,val, x, xhat);
        for(Int i = 0; i < m; i++)
          {
        xhat[i] = y[i] - xhat[i];
          }

        std::cout << "||X||: " << norm2<Int,Entry>(n,x)
              << " ||Y-AX||: " << norm2<Int,Entry>(m,xhat)
              << std::endl;

        */
        //mybasker.GetPerm()
        mybasker.Finalize();
    }

    Kokkos::finalize();

}//end main