static void write(std::ofstream &file, const CrsMatrixType A, const std::string comment = "%% Tacho::MatrixMarket::Export", const int uplo = 0) { typedef typename CrsMatrixType::value_type value_type; typedef typename CrsMatrixType::ordinal_type ordinal_type; typedef typename CrsMatrixType::size_type size_type; std::streamsize prec = file.precision(); file.precision(8); file << std::scientific; file << "%%MatrixMarket matrix coordinate " << (Util::isComplex<value_type>() ? "complex " : "real ") << ((uplo == Uplo::Upper || uplo == Uplo::Lower) ? "symmetric " : "general ") << std::endl; file << comment << std::endl; // cnt nnz size_type nnz = 0; for (ordinal_type i=0;i<A.NumRows();++i) { const size_type jbegin = A.RowPtrBegin(i), jend = A.RowPtrEnd(i); for (size_type j=jbegin;j<jend;++j) { const auto aj = A.Col(j); if (uplo == Uplo::Upper && i <= aj) ++nnz; if (uplo == Uplo::Lower && i >= aj) ++nnz; if (!uplo) ++nnz; } } file << A.NumRows() << " " << A.NumCols() << " " << nnz << std::endl; const int w = 10; for (ordinal_type i=0;i<A.NumRows();++i) { const size_type jbegin = A.RowPtrBegin(i), jend = A.RowPtrEnd(i); for (size_type j=jbegin;j<jend;++j) { const auto aj = A.Col(j); bool flag = false; if (uplo == Uplo::Upper && i <= aj) flag = true; if (uplo == Uplo::Lower && i >= aj) flag = true; if (!uplo) flag = true; if (flag) { value_type val = A.Value(j); file << std::setw(w) << ( i+1) << " " << std::setw(w) << (aj+1) << " " << std::setw(w) << val << std::endl; } } } file.unsetf(std::ios::scientific); file.precision(prec); }
GraphHelper_Scotch(const CrsMatrixType& A, const int seed = GraphHelper::DefaultRandomSeed) { _label = "GraphHelper_Scotch::" + A.Label(); _is_ordered = false; _cblk = 0; // scotch does not allow self-contribution (diagonal term in sparse matrix) _base = 0; //A.BaseVal(); _m = A.NumRows(); _nnz = A.NumNonZeros(); _rptr = size_type_array(_label+"::RowPtrArray", _m+1); _cidx = ordinal_type_array(_label+"::ColIndexArray", _nnz); _perm = ordinal_type_array(_label+"::PermutationArray", _m); _peri = ordinal_type_array(_label+"::InvPermutationArray", _m); _range = ordinal_type_array(_label+"::RangeArray", _m); _tree = ordinal_type_array(_label+"::TreeArray", _m); // create a graph structure without diagonals A.convertGraph(_nnz, _rptr, _cidx); int ierr = 0; ordinal_type *rptr = reinterpret_cast<ordinal_type*>(_rptr.ptr_on_device()); ordinal_type *cidx = reinterpret_cast<ordinal_type*>(_cidx.ptr_on_device()); if (seed != GraphHelper::DefaultRandomSeed) { SCOTCH_randomSeed(seed); SCOTCH_randomReset(); } ierr = SCOTCH_graphInit(&_graph); CHKERR(ierr); ierr = SCOTCH_graphBuild(&_graph, // scotch graph _base, // base value _m, // # of vertices rptr, // column index array pointer begin rptr+1, // column index array pointer end NULL, // weights on vertices (optional) NULL, // label array on vertices (optional) _nnz, // # of nonzeros cidx, // column index array NULL); CHKERR(ierr); // edge load array (optional) ierr = SCOTCH_graphCheck(&_graph); CHKERR(ierr); }