diff --git a/dune/istl/io.hh b/dune/istl/io.hh index bb4b402afa4ebc426dd1150908887a5b35413bb2..cc7eb215f4b8531477910025be0e88325660a663 100644 --- a/dune/istl/io.hh +++ b/dune/istl/io.hh @@ -23,7 +23,7 @@ namespace Dune { /** - @addtogroup ISTL_SPMV + @addtogroup ISTL_IO @{ */ diff --git a/dune/istl/matrixmarket.hh b/dune/istl/matrixmarket.hh index 66aabe27a6410b0beedb3a683c5dc6a9e76f5249..6c49ce31ae6e4e53979125a5df83366499090f11 100644 --- a/dune/istl/matrixmarket.hh +++ b/dune/istl/matrixmarket.hh @@ -671,7 +671,7 @@ namespace Dune template<typename T, typename A, int brows, int bcols, typename D> void readSparseEntries(Dune::BCRSMatrix<Dune::FieldMatrix<T,brows,bcols>,A>& matrix, std::istream& file, std::size_t entries, - const MMHeader& mmHeader, D) + const MMHeader& mmHeader, const D&) { typedef Dune::BCRSMatrix<Dune::FieldMatrix<T,brows,bcols>,A> Matrix; // First path @@ -834,9 +834,7 @@ namespace Dune if(header.type==array_type) DUNE_THROW(Dune::NotImplemented, "Array format currently not supported for matrices!"); - NumericWrapper<double> d; - - readSparseEntries(matrix, istr, entries, header,d); + readSparseEntries(matrix, istr, entries, header, NumericWrapper<double>()); } template<typename M> @@ -940,6 +938,41 @@ namespace Dune writeMatrixMarket(matrix,ostr,integral_constant<int,IsMatrix<M>::value>()); } + + /** + * @brief Stores a parallel matrix/vector in matrix market format in a file. + * + * More about the matrix market exchange format can be found + * <a href="http://math.nist.gov/MatrixMarket/formats.html">here</a>. + * + * @param matrix The matrix/vector to store. + * @param filename the name of the filename (without suffix and rank!) + * rank i will write the file filename_i.mm + */ + template<typename M> + void storeMatrixMarket(const M& matrix, + std::string filename) + { + std::ofstream file(filename.c_str()); + file.setf(std::ios::scientific,std::ios::floatfield); + writeMatrixMarket(matrix, file); + file.close(); + } + +#if HAVE_MPI + /** + * @brief Stores a parallel matrix/vector in matrix market format in a file. + * + * More about the matrix market exchange format can be found + * <a href="http://math.nist.gov/MatrixMarket/formats.html">here</a>. + * + * @param matrix The matrix/vector to store. + * @param filename the name of the filename (without suffix and rank!) + * rank i will write the file filename_i.mm + * @param comm The information about the data distribution. + * @param storeIndices Whether to store the parallel index information. + * If true rank i writes the index information to file filename_i.idx. + */ template<typename M, typename G, typename L> void storeMatrixMarket(const M& matrix, std::string filename, @@ -985,6 +1018,9 @@ namespace Dune /** * @brief Load a parallel matrix/vector stored in matrix market format. * + * More about the matrix market exchange format can be found + * <a href="http://math.nist.gov/MatrixMarket/formats.html">here</a>. + * * @param matrix Where to store the matrix/vector. * @param filename the name of the filename (without suffix and rank!) * rank i will read the file filename_i.mm @@ -1058,6 +1094,31 @@ namespace Dune } comm.ri.template rebuild<false>(); } + + #endif + + /** + * @brief Load a matrix/vector stored in matrix market format. + * + * More about the matrix market exchange format can be found + * <a href="http://math.nist.gov/MatrixMarket/formats.html">here</a>. + * + * @param matrix Where to store the matrix/vector. + * @param filename the name of the filename (without suffix and rank!) + * rank i will read the file filename_i.mm + */ + template<typename M> + void loadMatrixMarket(M& matrix, + const std::string& filename) + { + std::ifstream file; + file.open(filename.c_str(), std::ios::in); + if(!file) + DUNE_THROW(IOError, "Could not open file" << filename); + readMatrixMarket(matrix,file); + file.close(); + } + /** @} */ } #endif diff --git a/dune/istl/test/Makefile.am b/dune/istl/test/Makefile.am index 5f8f2cf5e4be57d0d76db5a8571b1b143ab8a788..a440168a756cd3bed69c2ed8aaf64555ae64baff 100644 --- a/dune/istl/test/Makefile.am +++ b/dune/istl/test/Makefile.am @@ -1,7 +1,7 @@ # $Id$ if MPI - MPITESTS = vectorcommtest + MPITESTS = vectorcommtest matrixmarkettest endif if MPI @@ -18,7 +18,7 @@ endif # which tests where program to build and run are equal NORMALTESTS = basearraytest matrixutilstest matrixtest bvectortest vbvectortest \ - bcrsbuildtest matrixiteratortest mv iotest scaledidmatrixtest + bcrsbuildtest matrixiteratortest mv iotest scaledidmatrixtest seqmatrixmarkettest # list of tests to run (indicestest is special case) TESTS = $(NORMALTESTS) $(MPITESTS) $(SUPERLUTESTS) $(PARDISOTEST) $(PARMETISTESTS) @@ -74,8 +74,23 @@ if MPI vectorcommtest_LDADD = \ $(DUNEMPILIBS) \ $(LDADD) + matrixmarkettest_SOURCES = matrixmarkettest.cc + matrixmarkettest_CPPFLAGS = $(AM_CPPFLAGS) \ + $(DUNEMPICPPFLAGS) + matrixmarkettest_LDFLAGS = $(AM_LDFLAGS) \ + $(DUNEMPILDFLAGS) + matrixmarkettest_LDADD = \ + $(DUNEMPILIBS) \ + $(LDADD) endif +seqmatrixmarkettest_SOURCES = matrixmarkettest.cc +seqmatrixmarkettest_CPPFLAGS = $(AM_CPPFLAGS) \ + $(DUNEMPICPPFLAGS) -DMM_SEQUENTIAL +seqmatrixmarkettest_LDFLAGS = $(AM_LDFLAGS) +seqmatrixmarkettest_LDADD = \ + $(LDADD) + if MPI matrixredisttest_SOURCES = matrixredisttest.cc matrixredisttest_CPPFLAGS = $(AM_CPPFLAGS) \ diff --git a/dune/istl/test/matrixmarkettest.cc b/dune/istl/test/matrixmarkettest.cc index 2ce84c9fc3169e94b9ad7d1061e75b390028dffe..e82d55c2e536eba8779ebf49f8a875b28457110b 100644 --- a/dune/istl/test/matrixmarkettest.cc +++ b/dune/istl/test/matrixmarkettest.cc @@ -1,14 +1,19 @@ // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // vi: set et ts=4 sw=2 sts=2: #include "config.h" -#include "mpi.h" #include <dune/istl/io.hh> #include <dune/istl/bvector.hh> -#include <dune/istl/schwarz.hh> #include <dune/common/fmatrix.hh> #include <dune/common/fvector.hh> #include <dune/common/float_cmp.hh> +#ifndef MM_SEQUENTIAL #include <dune/istl/paamg/test/anisotropic.hh> +#include "mpi.h" +#include <dune/istl/schwarz.hh> +#else +#include <dune/istl/operators.hh> +#include <laplacian.hh> +#endif #include <dune/common/timer.hh> #include <dune/istl/matrixmarket.hh> @@ -16,10 +21,12 @@ int main(int argc, char** argv) { - +#ifndef MM_SEQUENTIAL MPI_Init(&argc, &argv); int size; MPI_Comm_size(MPI_COMM_WORLD, &size); +#else +#endif const int BS=1; int N=100; @@ -32,15 +39,20 @@ int main(int argc, char** argv) typedef Dune::BCRSMatrix<MatrixBlock> BCRSMat; typedef Dune::FieldVector<double,BS> VectorBlock; typedef Dune::BlockVector<VectorBlock> BVector; + +#ifndef MM_SEQUENTIAL typedef int GlobalId; typedef Dune::OwnerOverlapCopyCommunication<GlobalId> Communication; Communication comm(MPI_COMM_WORLD); - int n; - std::cout<<comm.communicator().rank()<<" "<<comm.communicator().size()<< " "<<size<<std::endl; - + int n; BCRSMat mat = setupAnisotropic2d<BS,double>(N, comm.indexSet(), comm.communicator(), &n, .011); +#else + BCRSMat mat; + setupLaplacian(mat, N); +#endif + BVector bv(mat.N()), cv(mat.N()); typedef BVector::iterator VIter; @@ -51,23 +63,38 @@ int main(int argc, char** argv) for(SIter sentry=entry->begin(); sentry != entry->end(); ++sentry,++i) *sentry=i; } + +#ifndef MM_SEQUENTIAL comm.remoteIndices().rebuild<false>(); comm.copyOwnerToAll(bv,bv); Dune::OverlappingSchwarzOperator<BCRSMat,BVector,BVector,Communication> op(mat, comm); op.apply(bv, cv); - - storeMatrixMarket(mat, std::string("testmat"), comm); storeMatrixMarket(bv, std::string("testvec"), comm, false); +#else + typedef Dune::MatrixAdapter<BCRSMat,BVector,BVector> Operator; + Operator op(mat); + op.apply(bv, cv); + + storeMatrixMarket(mat, std::string("testmat")); + storeMatrixMarket(bv, std::string("testvec")); +#endif + BCRSMat mat1; BVector bv1,cv1; +#ifndef MM_SEQUENTIAL Communication comm1(MPI_COMM_WORLD); loadMatrixMarket(mat1, std::string("testmat"), comm1); loadMatrixMarket(bv1, std::string("testvec"), comm1, false); +#else + loadMatrixMarket(mat1, std::string("testmat")); + loadMatrixMarket(bv1, std::string("testvec")); +#endif + int ret=0; if(mat.N()!=mat1.N() || mat.M()!=mat1.M()) { @@ -98,21 +125,32 @@ int main(int argc, char** argv) } cv1.resize(mat1.M()); + +#ifndef MM_SEQUENTIAL Dune::OverlappingSchwarzOperator<BCRSMat,BVector,BVector,Communication> op1(mat1, comm1); op1.apply(bv1, cv1); + + if(comm1.indexSet()!=comm.indexSet()) + { + std::cerr<<"written and read idxset do not match"<<std::endl; + ++ret; + } +#else + typedef Dune::MatrixAdapter<BCRSMat,BVector,BVector> Operator; + Operator op1(mat1); + op1.apply(bv1, cv1); +#endif + for(VIter entry=cv.begin(), entry1=cv1.begin(); cv.end() != entry; ++entry, ++entry1) if(*entry!=*entry1) { std::cerr<<"computed vectors do not match"<<std::endl; ++ret; } - if(comm1.indexSet()!=comm.indexSet()) - { - std::cerr<<"written and read idxset do not match"<<std::endl; - ++ret; - } - storeMatrixMarket(mat1, std::string("testmat1"), comm1); + +#ifndef MM_SEQUENTIAL if(ret!=0) MPI_Abort(MPI_COMM_WORLD, ret); MPI_Finalize(); +#endif }