butterfly.cc 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. #include <mpi.h>
  2. #include <cassert>
  3. #include <cmath>
  4. #include <iostream>
  5. int main(int argc, char *argv[]) {
  6. int rank, size;
  7. int send, recv;
  8. // MPI init
  9. MPI_Init(&argc, &argv);
  10. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  11. MPI_Comm_size(MPI_COMM_WORLD, &size);
  12. // check proc size is power of 2
  13. float steps_f = std::log2(size);
  14. int steps = (int)steps_f;
  15. assert(std::abs(steps - steps_f) < 1e-9);
  16. // init value
  17. send = rank;
  18. // sum
  19. int base = 1;
  20. for (int i = 0; i < steps; ++i) {
  21. int group = rank / base;
  22. int offset = rank % base;
  23. int target = (group % 2 ? group - 1 : group + 1) * base + offset;
  24. if (rank < target) {
  25. MPI_Send(reinterpret_cast<void*>(&send), 1, MPI_INT, target, target, MPI_COMM_WORLD);
  26. MPI_Recv(reinterpret_cast<void*>(&recv), 1, MPI_INT, target, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  27. } else {
  28. MPI_Recv(reinterpret_cast<void*>(&recv), 1, MPI_INT, target, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  29. MPI_Send(reinterpret_cast<void*>(&send), 1, MPI_INT, target, target, MPI_COMM_WORLD);
  30. }
  31. send += recv;
  32. base *= 2;
  33. }
  34. // print result
  35. std::cout << "rank:" << rank << ", sum:" << send << std::endl;
  36. MPI_Finalize();
  37. }