| 554 | } |
| 555 | |
| 556 | Matrix<> InnerProductD (const MultiVector & v2) const override |
| 557 | { |
| 558 | Matrix<double> res(v2.Size(), Size()); |
| 559 | if (res.Height()*res.Width()==0) return res; |
| 560 | |
| 561 | auto status1 = (*this)[0] -> GetParallelStatus(); |
| 562 | auto status2 = (v2)[0] -> GetParallelStatus(); |
| 563 | |
| 564 | if (auto pv2 = dynamic_cast<const ParallelMultiVector*>(&v2)) |
| 565 | if ( ((status1 == CUMULATED) && (status2 == DISTRIBUTED)) || |
| 566 | ((status2 == CUMULATED) && (status1 == DISTRIBUTED)) ) |
| 567 | { |
| 568 | ArrayMem<double*,32> ptrs1(Size()); |
| 569 | ArrayMem<double*,32> ptrs2(v2.Size()); |
| 570 | MakeSameStatus(); |
| 571 | pv2->MakeSameStatus(); |
| 572 | |
| 573 | for (int i = 0; i < Size(); i++) |
| 574 | ptrs1[i] = (*this)[i]->FVDouble().Data(); |
| 575 | for (int i = 0; i < v2.Size(); i++) |
| 576 | ptrs2[i] = v2[i]->FVDouble().Data(); |
| 577 | |
| 578 | ngbla::PairwiseInnerProduct((*this)[0]->FVDouble().Size(), ptrs2, ptrs1, res); |
| 579 | |
| 580 | paralleldofs->GetCommunicator() |
| 581 | .AllReduce(FlatArray(res.Height()*res.Width(), res.Data()), NG_MPI_SUM); |
| 582 | |
| 583 | return res; |
| 584 | } |
| 585 | |
| 586 | // fallback |
| 587 | return MultiVector::InnerProductD(v2); |
| 588 | } |
| 589 | |
| 590 | |
| 591 | }; |