------------------------------------------------------------------------------ Helper function for RequestData. Reads one or more depth arrays from the netCDF file and sends sub-arrays out to all ranks that need that data
| 527 | // Helper function for RequestData. Reads one or more depth arrays from the |
| 528 | // netCDF file and sends sub-arrays out to all ranks that need that data |
| 529 | int vtkPNetCDFPOPReader::ReadAndSend(vtkInformation* outInfo, int varID) |
| 530 | { |
| 531 | int wholeExtent[6]; |
| 532 | outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExtent); |
| 533 | // Z & X dimensions have been swapped (see the comments at the top of the header |
| 534 | // file). All arrays in this function, however, should reflect the on-disk |
| 535 | // layout, so we'll 'un-swap' the X & Z extents. |
| 536 | swap(wholeExtent[0], wholeExtent[4]); |
| 537 | swap(wholeExtent[1], wholeExtent[5]); |
| 538 | |
| 539 | // this->Stride is also in the in-memory layout |
| 540 | ptrdiff_t rStride[3] = { this->Stride[2], this->Stride[1], this->Stride[0] }; |
| 541 | |
| 542 | int rank = this->Controller->GetLocalProcessId(); |
| 543 | |
| 544 | // We read one depth at a time, skipping over the depths that other reader processes will read |
| 545 | for (int curDepth = wholeExtent[0]; curDepth <= wholeExtent[1]; curDepth++) |
| 546 | { |
| 547 | if (ReaderForDepth(curDepth) == rank) |
| 548 | { |
| 549 | size_t start[3] = { static_cast<size_t>(curDepth * rStride[0]), |
| 550 | static_cast<size_t>(wholeExtent[2]), static_cast<size_t>(wholeExtent[4]) }; |
| 551 | size_t count[3] = { 1, static_cast<size_t>(wholeExtent[3] - wholeExtent[2] + 1), |
| 552 | static_cast<size_t>(wholeExtent[5] - wholeExtent[4] + 1) }; |
| 553 | |
| 554 | float* buffer = new float[count[1] * count[2]]; |
| 555 | this->Internals->SendBufs.push_back(buffer); |
| 556 | |
| 557 | int ncErr = nc_get_vars_float(this->NCDFFD, varID, start, count, rStride, buffer); |
| 558 | if (ncErr != NC_NOERR) |
| 559 | { |
| 560 | std::cerr << "!!!nc_get_vars_float() returned error code " << ncErr << endl; |
| 561 | } |
| 562 | |
| 563 | // Create sub arrays and send to all processes |
| 564 | for (int destRank = 0; destRank < this->Controller->GetNumberOfProcesses(); destRank++) |
| 565 | { |
| 566 | int destExtent[6]; |
| 567 | memcpy(destExtent, &this->Internals->AllExtents[destRank * 6], 6 * sizeof(int)); |
| 568 | // Note that AllExtents is also in in-memory layout order, so we need to swap |
| 569 | // the X & Z values |
| 570 | swap(destExtent[0], destExtent[4]); |
| 571 | swap(destExtent[1], destExtent[5]); |
| 572 | |
| 573 | // Verify that destRank does, in fact, receive an extent at this depth |
| 574 | // TODO: Don't use MPI to send data to ourself..... |
| 575 | if (curDepth >= destExtent[0] && curDepth <= destExtent[1]) |
| 576 | { |
| 577 | int subarray_sizes[2] = { |
| 578 | (wholeExtent[3] - wholeExtent[2] + 1), |
| 579 | (wholeExtent[5] - wholeExtent[4] + 1), |
| 580 | }; |
| 581 | int subarray_subsizes[2] = { (destExtent[3] - destExtent[2] + 1), |
| 582 | (destExtent[5] - destExtent[4] + 1) }; |
| 583 | int subarray_starts[2] = { destExtent[2], destExtent[4] }; |
| 584 | MPI_Datatype subArrayType; |
| 585 | vtkMPICommunicator::Request sendReq; |
| 586 | MPI_Type_create_subarray(2, subarray_sizes, subarray_subsizes, subarray_starts, |
nothing calls this directly
no test coverage detected