fork download
  1. #include <mpi.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. void AlltoAll(char *sendbuf, char *recvbuf, int count, MPI_Comm comm) {
  7. int world_rank, world_size;
  8. MPI_Comm_rank(comm, &world_rank);
  9. MPI_Comm_size(comm, &world_size);
  10.  
  11. // Calculate the size of each message
  12. int message_size = count / world_size;
  13.  
  14. // Allocate memory for receiving data
  15. char *temp_recvbuf = (char *)malloc(count * sizeof(char));
  16.  
  17. // Scatter data to other processes using point-to-point communication
  18. for (int i = 0; i < world_size; i++) {
  19. if (i != world_rank) {
  20. MPI_Send(sendbuf + i * message_size, message_size, MPI_CHAR, i, 0, comm);
  21. }
  22. }
  23.  
  24. // Receive data from other processes using point-to-point communication
  25. for (int i = 0; i < world_size; i++) {
  26. if (i != world_rank) {
  27. MPI_Recv(temp_recvbuf + i * message_size, message_size, MPI_CHAR, i, 0, comm, MPI_STATUS_IGNORE);
  28. }
  29. }
  30.  
  31. // Copy received data to receive buffer
  32. memcpy(recvbuf, temp_recvbuf, count * sizeof(char));
  33.  
  34. free(temp_recvbuf);
  35. }
  36.  
  37. void Allgather(char *sendbuf, int sendcount, char *recvbuf, int recvcount, MPI_Comm comm) {
  38. int world_rank, world_size;
  39. MPI_Comm_rank(comm, &world_rank);
  40. MPI_Comm_size(comm, &world_size);
  41.  
  42. int total_send_count = sendcount * world_size;
  43.  
  44. // Allocate memory for temporary receive buffer
  45. char *temp_recvbuf = (char *)malloc(total_send_count * sizeof(char));
  46.  
  47. // Send data to all other processes
  48. for (int i = 0; i < world_size; i++) {
  49. if (i != world_rank) {
  50. MPI_Send(sendbuf, sendcount, MPI_CHAR, i, 0, comm);
  51. }
  52. }
  53.  
  54. // Copy own data to receive buffer
  55. memcpy(recvbuf + world_rank * recvcount, sendbuf, sendcount);
  56.  
  57. // Receive data from all other processes
  58. for (int i = 0; i < world_size; i++) {
  59. if (i != world_rank) {
  60. MPI_Recv(temp_recvbuf + i * recvcount, recvcount, MPI_CHAR, i, 0, comm, MPI_STATUS_IGNORE);
  61. }
  62. }
  63.  
  64. // Copy received data to receive buffer
  65. for (int i = 0; i < world_size; i++) {
  66. if (i != world_rank) {
  67. memcpy(recvbuf + i * recvcount, temp_recvbuf + i * recvcount, recvcount);
  68. }
  69. }
  70.  
  71. free(temp_recvbuf);
  72. }
  73.  
  74. void Allgatherv(char *sendbuf, int sendcount, char *recvbuf, int *recvcounts, int *displs, MPI_Comm comm) {
  75. int world_rank, world_size;
  76. MPI_Comm_rank(comm, &world_rank);
  77. MPI_Comm_size(comm, &world_size);
  78.  
  79. // Determine the total size of data to be received
  80. int total_recv_count = 0;
  81. for (int i = 0; i < world_size; ++i) {
  82. total_recv_count += recvcounts[i];
  83. }
  84.  
  85. // Allocate memory for temporary receive buffer
  86. char *temp_recvbuf = (char *)malloc(total_recv_count * sizeof(char));
  87.  
  88. // Receive data from each process and store in temporary buffer
  89. for (int i = 0; i < world_size; ++i) {
  90. MPI_Recv(temp_recvbuf + displs[i], recvcounts[i], MPI_CHAR, i, 0, comm, MPI_STATUS_IGNORE);
  91. }
  92.  
  93. // Copy data from temporary buffer to final receive buffer
  94. memcpy(recvbuf, temp_recvbuf, total_recv_count * sizeof(char));
  95.  
  96. // Free temporary buffer
  97. free(temp_recvbuf);
  98. }
  99.  
  100. void my_Alltoallv(char *sendbuf, int *sendcounts, int *sdispls, char *recvbuf, int *recvcounts, int *rdispls, MPI_Comm comm) {
  101. int world_rank, world_size;
  102. MPI_Comm_rank(comm, &world_rank);
  103. MPI_Comm_size(comm, &world_size);
  104.  
  105. // Calculate total send and receive counts
  106. int total_send_count = 0;
  107. int total_recv_count = 0;
  108. for (int i = 0; i < world_size; i++) {
  109. total_send_count += sendcounts[i];
  110. total_recv_count += recvcounts[i];
  111. }
  112.  
  113. // Allocate memory for temporary send and receive buffers
  114. char *temp_sendbuf = (char *)malloc(total_send_count * sizeof(char));
  115. char *temp_recvbuf = (char *)malloc(total_recv_count * sizeof(char));
  116.  
  117. // Copy data to temporary send buffer based on send counts and displacements
  118. int send_offset = 0;
  119. for (int i = 0; i < world_size; i++) {
  120. memcpy(temp_sendbuf + send_offset, sendbuf + sdispls[i], sendcounts[i]);
  121. send_offset += sendcounts[i];
  122. }
  123.  
  124. // Exchange data with all other processes using point-to-point communication
  125. for (int i = 0; i < world_size; i++) {
  126. if (i != world_rank) {
  127. // Send data to process i
  128. MPI_Sendrecv(temp_sendbuf + sdispls[i], sendcounts[i], MPI_CHAR, i, 0,
  129. temp_recvbuf + rdispls[i], recvcounts[i], MPI_CHAR, i, 0, comm, MPI_STATUS_IGNORE);
  130. }
  131. }
  132.  
  133. // Copy data from temporary receive buffer to receive buffer based on receive counts and displacements
  134. int recv_offset = 0;
  135. for (int i = 0; i < world_size; i++) {
  136. memcpy(recvbuf + rdispls[i], temp_recvbuf + recv_offset, recvcounts[i]);
  137. recv_offset += recvcounts[i];
  138. }
  139.  
  140. // Free temporary buffers
  141. free(temp_sendbuf);
  142. free(temp_recvbuf);
  143. }
  144.  
  145. int main(int argc, char *argv[]) {
  146. MPI_Init(&argc, &argv);
  147.  
  148. int world_rank, world_size;
  149. MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
  150. MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  151.  
  152. // Input data from user
  153. char sendbuf[100]; // Assuming a maximum of 100 characters
  154. if (world_rank == 0) {
  155. printf("Enter data to send: ");
  156. scanf("%s", sendbuf);
  157. }
  158.  
  159. // AlltoAll
  160. char recvbuf_alltoall[100 * world_size];
  161. AlltoAll(sendbuf, recvbuf_alltoall, 100, MPI_COMM_WORLD);
  162. if (world_rank == 0) {
  163. printf("AlltoAll received data: %s\n", recvbuf_alltoall);
  164. }
  165.  
  166. // Allgather
  167. char recvbuf_allgather[100 * world_size];
  168. Allgather(sendbuf, strlen(sendbuf) + 1, recvbuf_allgather, strlen(sendbuf) + 1, MPI_COMM_WORLD);
  169. if (world_rank == 0) {
  170. printf("Allgather received data: %s\n", recvbuf_allgather);
  171. }
  172.  
  173. // Allgatherv
  174. int *recvcounts_allgatherv = (int *)malloc(world_size * sizeof(int));
  175. int *displs_allgatherv = (int *)malloc(world_size * sizeof(int));
  176. int sendcount_allgatherv = strlen(sendbuf) + 1;
  177. for (int i = 0; i < world_size; ++i) {
  178. recvcounts_allgatherv[i] = strlen(sendbuf) + 1;
  179. displs_allgatherv[i] = i * (strlen(sendbuf) + 1);
  180. }
  181. char recvbuf_allgatherv[100 * world_size];
  182. Allgatherv(sendbuf, sendcount_allgatherv, recvbuf_allgatherv, recvcounts_allgatherv, displs_allgatherv, MPI_COMM_WORLD);
  183. if (world_rank == 0) {
  184. printf("Allgatherv received data: %s\n", recvbuf_allgatherv);
  185. }
  186.  
  187. // Alltoallv
  188. int sendcounts_alltoallv[world_size];
  189. int recvcounts_alltoallv[world_size];
  190. int sdispls_alltoallv[world_size];
  191. int rdispls_alltoallv[world_size];
  192. for (int i = 0; i < world_size; i++) {
  193. sendcounts_alltoallv[i] = strlen(sendbuf) + 1;
  194. recvcounts_alltoallv[i] = strlen(sendbuf) + 1;
  195. sdispls_alltoallv[i] = i * (strlen(sendbuf) + 1);
  196. rdispls_alltoallv[i] = i * (strlen(sendbuf) + 1);
  197. }
  198. char recvbuf_alltoallv[100 * world_size];
  199. my_Alltoallv(sendbuf, sendcounts_alltoallv, sdispls_alltoallv, recvbuf_alltoallv, recvcounts_alltoallv, rdispls_alltoallv, MPI_COMM_WORLD);
  200. if (world_rank == 0) {
  201. printf("Alltoallv received data: %s\n", recvbuf_alltoallv);
  202. }
  203.  
  204. // Finalize MPI
  205. MPI_Finalize();
  206. return 0;
  207. }
  208.  
Success #stdin #stdout #stderr 0.31s 40644KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected symbol in "void AlltoAll"
Execution halted