#ifndef VDOP_FILE #define VDOP_FILE #include #include // MPI #include #include /** @brief Element-wise vector divison x_k = y_k/z_k. * * @param[out] x target vector * @param[in] y source vector * @param[in] z source vector * */ void vddiv(std::vector &x, std::vector const &y, std::vector const &z); /** @brief Element-wise daxpy operation x(k) = y(k) + alpha*z(k). * * @param[out] x target vector * @param[in] y source vector * @param[in] alpha scalar * @param[in] z source vector * */ void vdaxpy(std::vector &x, std::vector const &y, double alpha, std::vector const &z ); /** @brief Calculates the Euclidean inner product of two vectors. * * @param[in] x vector * @param[in] y vector * @return Euclidean inner product @f$\langle x,y \rangle@f$ * */ double dscapr(std::vector const &x, std::vector const &y); inline double L2_scapr(std::vector const &x, std::vector const &y) { return dscapr(x, y) / x.size(); } /** Parallel inner product @param[in] x vector @param[in] y vector @param[in] icomm MPI communicator @return resulting Euclidian inner product */ double par_scalar(std::vector const &x, std::vector const &y, MPI_Comm const& icomm=MPI_COMM_WORLD); /* ReadId : Input and broadcast of an integer */ inline int ReadIn(std::string const &ss = std::string(), MPI_Comm const &icomm = MPI_COMM_WORLD) { MPI_Barrier(icomm); int myrank; /* my rank number */ MPI_Comm_rank(icomm, &myrank); int id; if (myrank == 0) { std::cout << "\n\n " << ss << " : Which process do you want to debug ? \n"; std::cin >> id; } MPI_Bcast(&id, 1, MPI_INT, 0, icomm); return id; } /** * Print entries of a vector to standard output. * * @param[in] v vector values * @param[in] ss string containing the vector name * @param[in] icomm communicator group for MPI * */ //void DebugVector(std::vector const &v); template void DebugVector(std::vector const &v, std::string const &ss = std::string(), MPI_Comm const &icomm = MPI_COMM_WORLD) { MPI_Barrier(icomm); int numprocs; /* # processes */ MPI_Comm_size(icomm, &numprocs); int myrank; /* my rank number */ MPI_Comm_rank(icomm, &myrank); int readid = ReadIn(ss); /* Read readid */ while ( (0 <= readid) && (readid < numprocs) ) { if (myrank == readid) { std::cout << "\n\n process " << readid; std::cout << "\n .... " << ss << " (nnode = " << v.size() << ")\n"; for (size_t j = 0; j < v.size(); ++j) { std::cout.setf(std::ios::right, std::ios::adjustfield); std::cout << v[j] << " "; } std::cout << std::endl; fflush(stdout); } readid = ReadIn(ss, icomm); /* Read readid */ } MPI_Barrier(icomm); return; } /** @brief Compares an STL vector with POD vector. * * The accuracy criteria @f$ |x_k-y_k| < \varepsilon \left({1+0.5(|x_k|+|y_k|)}\right) @f$ * follows the book by * Stoyan/Baran, p.8. * * @param[in] x STL vector * @param[in] n length of POD vector * @param[in] y POD vector * @param[in] eps relative accuracy criteria (default := 0.0). * @return true iff pairwise vector elements are relatively close to each other. * */ bool CompareVectors(std::vector const &x, int n, double const y[], double const eps = 0.0); /** Output operator for vector * @param[in,out] s output stream, e.g. @p cout * @param[in] v vector * * @return output stream */ template std::ostream &operator<<(std::ostream &s, std::vector const &v) { for (auto vp : v) { s << vp << " "; } return s; } /** Exchanges equal size partions of vector @p xin with all MPI processes. * The received data are return in vector @p yout . * * @param[in] xin input vector * @param[out] yout output vector * @param[in] icomm MPI communicator * */ void ExchangeAll(std::vector const &xin, std::vector &yout, MPI_Comm const &icomm = MPI_COMM_WORLD); /** Exchanges equal size partions of vector @p xin with all MPI processes. * The received data are return in vector @p xin . * * @param[in,out] xin input/output vector * @param[in] icomm MPI communicator * */ void ExchangeAllInPlace(std::vector &xin, MPI_Comm const &icomm = MPI_COMM_WORLD); #endif