36 template <
class IT,
class NT>
37 template <
typename _BinaryOperation>
47 int colneighs = commGrid->GetGridRows();
48 int colrank = commGrid->GetRankInProcCol();
50 IT * loclens =
new IT[colneighs];
51 IT * lensums =
new IT[colneighs+1]();
53 IT n_perproc = n / colneighs;
54 if(colrank == colneighs-1)
55 loclens[colrank] = n - (n_perproc*colrank);
57 loclens[colrank] = n_perproc;
59 MPI_Allgather(MPI_IN_PLACE, 0, MPIType<IT>(), loclens, 1, MPIType<IT>(), commGrid->GetColWorld());
60 std::partial_sum(loclens, loclens+colneighs, lensums+1);
62 std::vector<NT> trarr(loclens[colrank]);
63 NT * sendbuf =
new NT[n];
64 for(
int j=0; j < n; ++j)
66 sendbuf[j] = identity;
67 for(
int i=0; i < m; ++i)
69 sendbuf[j] = __binary_op(array[i][j], sendbuf[j]);
81 IT trlen = trarr.size();
82 int diagneigh = commGrid->GetComplementRank();
84 MPI_Sendrecv(&trlen, 1, MPIType<IT>(), diagneigh,
TRNNZ, &reallen, 1, MPIType<IT>(), diagneigh,
TRNNZ, commGrid->GetWorld(), &status);
88 assert((parvec.arr.size() == reallen));
89 MPI_Sendrecv(trarr.data(), trlen, MPIType<NT>(), diagneigh,
TRX, parvec.arr.data(), reallen, MPIType<NT>(), diagneigh,
TRX, commGrid->GetWorld(), &status);
100 NT * sendbuf =
new NT[m];
101 for(
int i=0; i < m; ++i)
103 sendbuf[i] = std::accumulate( array[i], array[i]+n, identity, __binary_op);
105 NT * recvbuf = parvec.arr.data();
108 int rowneighs = commGrid->GetGridCols();
109 int rowrank = commGrid->GetRankInProcRow();
110 IT * recvcounts =
new IT[rowneighs];
111 recvcounts[rowrank] = parvec.MyLocLength();
112 MPI_Allgather(MPI_IN_PLACE, 0, MPIType<IT>(), recvcounts, 1, MPIType<IT>(), commGrid->GetRowWorld());
119 delete [] recvcounts;
125 std::cout <<
"Unknown reduction dimension, returning empty vector" << std::endl;
132 template <
class IT,
class NT>
133 template <
typename DER>
136 if(*commGrid == *rhs.commGrid)
138 (rhs.spSeq)->UpdateDense(array, std::plus<double>());
142 std::cout <<
"Grids are not comparable elementwise addition" << std::endl;
149 template <
class IT,
class NT>
159 if(rhs.array != NULL)
161 array = SpHelper::allocate2D<NT>(m, n);
162 for(
int i=0; i< m; ++i)
163 std::copy(array[i], array[i]+n, rhs.array[i]);
165 commGrid.reset(
new CommGrid(*(rhs.commGrid)));
DenseParMat< IT, NT > & operator+=(const SpParMat< IT, NT, DER > &rhs)
DenseParMat< IT, NT > & operator=(const DenseParMat< IT, NT > &rhs)
static void deallocate2D(T **array, I m)
FullyDistVec< IT, NT > Reduce(Dim dim, _BinaryOperation __binary_op, NT identity) const