00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #include <errno.h>
00041 #include <sys/types.h>
00042 #include <sys/socket.h>
00043 #include <arpa/inet.h>
00044 #include <netdb.h>
00045
00046 #include <mini_mpi.h>
00047 #include <mini_mpi-internal.h>
00048
00049
00050 extern int my_numprocs = 0;
00051 extern int my_taskid = 0;
00052 extern unsigned short my_init = 0;
00053 extern struct sockaddr_in head_addr;
00054 extern socket_ptr_t my_socket;
00055 extern task_t *task_array;
00056
00057 #define MY_SOCK (my_socket.fd)
00058
00059
00060 int MPI_Init(int *argc, char ***argv)
00061 {
00062 int error, bcast, numbytes, broadcast = 1;
00063 struct sockaddr_in their_addr;
00064 struct hostent *he;
00065 char msg_out[32];
00066 char msg_in[1024];
00067 int header;
00068 socklen_t head_size;
00069 char *table;
00070
00071 sprintf(msg_out, "%d", MINI_MPI_INIT);
00072
00073 if ((he = gethostbyname("255.255.255.255")) == NULL) {
00074 herror("gethostbyname");
00075 return h_errno;
00076 }
00077 if ((bcast = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00078 perror("socket");
00079 return bcast;
00080 }
00081 if ((error = setsockopt(bcast, SOL_SOCKET, SO_BROADCAST,
00082 &broadcast, sizeof(broadcast))) < 0) {
00083 perror("setsockopt (SO_BROADCAST)");
00084 return error;
00085 }
00086
00087 their_addr.sin_family = AF_INET;
00088 their_addr.sin_port = htons(MPI_INIT_PORT);
00089 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
00090 memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
00091
00092 if ((numbytes = sendto(bcast, msg_out, strlen(msg_out), 0,
00093 (struct sockaddr *)&their_addr,
00094 sizeof(struct sockaddr))) < 0) {
00095 perror("sendto");
00096 return numbytes;
00097 }
00098
00099 await_reply:
00100 if ((numbytes = recvfrom(bcast, msg_in, sizeof(msg_in), 0,
00101 (struct sockaddr *)&head_addr,
00102 &head_size)) < 0) {
00103 perror("recvfrom");
00104 return numbytes;
00105 }
00106 msg_in[num_bytes] = '\0';
00107 error = sscanf(msg_in, "%d::%d:%d::", &header, &my_numprocs,
00108 &my_taskid);
00109 if (error < 3 || header != MINI_MPI_HEAD) {
00110
00111 goto await_reply;
00112 }
00113
00114 if ((table = strstr(msg_in, "::::")) == NULL) {
00115 perror("strstr");
00116 return errno;
00117 }
00118 table += 2;
00119 string_to_tasks(my_numprocs, table, task_array);
00120
00121 if ((MY_SOCK = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
00122 perror("socket");
00123 return MY_SOCK;
00124 }
00125 if ((error = connect(MY_SOCK, (struct sockaddr *)&head_addr,
00126 sizeof(struct sockaddr))) < 0) {
00127 perror("connect");
00128 return error;
00129 }
00130
00131 my_init = 1;
00132 return MPI_SUCCESS;
00133 }
00134
00135
00136 int MPI_Comm_socket(MPI_Comm comm, int *sock)
00137 {
00138 if (comm != MPI_COMM_WORLD || my_init == 0)
00139 return EINVAL;
00140 *sock = MY_SOCK;
00141 return MPI_SUCCESS;
00142 }
00143
00144
00145 int MPI_Abort(MPI_Comm comm, int errorcode)
00146 {
00147 int error;
00148 char msg[32];
00149 sprintf(msg, "%d", MINI_MPI_ABORT);
00150
00151 if (comm != MPI_COMM_WORLD || my_init == 0)
00152 return EINVAL;
00153
00154 if ((error = send(MY_SOCK, msg, strlen(msg), 0)) < 0)
00155 return error;
00156 return MPI_SUCCESS;
00157 }
00158
00159
00160 int MPI_Finalize(void)
00161 {
00162 int error;
00163 char msg[32];
00164 sprintf(msg, "%d", MINI_MPI_FINAL);
00165
00166 if (my_init == 0)
00167 return EINVAL;
00168
00169 if ((error = send(MY_SOCK, msg, strlen(msg), 0)) < 0)
00170 return error;
00171
00172 my_init = 0;
00173 free(task_array);
00174 return MPI_SUCCESS;
00175 }
00176
00177
00178
00179 int MPI_Send(void *buf, int count, MPI_Datatype type, int dest,
00180 int tag, MPI_Comm comm)
00181 {
00182 int error, sock = task_array[dest].sock;
00183 int msg_len = (type_size(type) * count) + 1;
00184 char msg[msg_len], tracker[msg_len + 33];
00185
00186 if (comm != MPI_COMM_WORLD || my_init == 0)
00187 return EINVAL;
00188
00189 buffer_to_char(msg, msg_len, buf, count, type);
00190 if ((error = send(sock, msg, strlen(msg), 0)) < 0)
00191 return error;
00192
00193 sprintf(tracker, "%d:%s", MINI_MPI_SEND, msg);
00194 if ((error = send(MY_SOCK, tracker, strlen(tracker), 0)) < 0)
00195 return error;
00196
00197 return MPI_SUCCESS;
00198 }
00199
00200 int MPI_Recv(void *buf, int count, MPI_Datatype type, int source,
00201 int tag, MPI_Comm comm, MPI_Status *status)
00202 {
00203
00205 if (comm != MPI_COMM_WORLD || my_init == 0)
00206 return EINVAL;
00207
00208 return MPI_SUCCESS;
00209 }
00210
00211
00212
00213 int MPI_Isend(void *buf, int count, MPI_Datatype type, int dest,
00214 int tag, MPI_Comm comm, MPI_Request *request)
00215 {
00216 int error, sock = task_array[dest].sock;
00217 int msg_len = (type_size(type) * count) + 1;
00218 char msg[msg_len], tracker[msg_len + 33];
00219
00220 if (comm != MPI_COMM_WORLD || my_init == 0)
00221 return EINVAL;
00222
00223 buffer_to_char(msg, msg_len, buf, count, type);
00224 if ((error = send(sock, msg, strlen(msg), 0)) < 0)
00225 return error;
00226
00227 sprintf(tracker, "%d:%s", MINI_MPI_SEND, msg);
00228 if ((error = send(MY_SOCK, tracker, strlen(tracker), 0)) < 0)
00229 return error;
00230
00232 return MPI_SUCCESS;
00233 }
00234
00235 int MPI_Irecv(void *buf, int count, MPI_Datatype type, int source,
00236 int tag, MPI_Comm comm, MPI_Request *request)
00237 {
00238
00239
00240 if (comm != MPI_COMM_WORLD || my_init == 0)
00241 return EINVAL;
00242
00243 return MPI_SUCCESS;
00244 }
00245
00246 int MPI_Wait(MPI_Request *request, MPI_Status *status)
00247 {
00249
00250 return MPI_SUCCESS;
00251 }
00252
00253 int MPI_Waitall(int count, MPI_Request *request[], MPI_Status *status[])
00254 {
00255
00256 return MPI_SUCCESS;
00257 }
00258
00259
00260
00261 int MPI_Barrier(MPI_Comm comm)
00262 {
00263 int error;
00264 char msg_out[32], msg_in[64];
00265 sprintf(msg_out, "%d", MINI_MPI_BARRIER);
00266
00267 if (comm != MPI_COMM_WORLD || my_init == 0)
00268 return EINVAL;
00269
00270 if ((error = send(MY_SOCK, msg_out, strlen(msg_out), 0)) < 0)
00271 return error;
00272
00273 await_resume:
00274 if ((error = recv(MY_SOCK, msg_in, 64, 0)) < 0)
00275 return error;
00276
00277 if (atoi(msg_in) != MINI_MPI_RESUME) {
00278
00279 goto await_resume;
00280 }
00281 return MPI_SUCCESS;
00282 }
00283
00284 int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype,
00285 int root, MPI_Comm comm)
00286 {
00287
00288
00289 if (comm != MPI_COMM_WORLD || my_init == 0)
00290 return EINVAL;
00291
00292 return MPI_SUCCESS;
00293 }
00294
00295 int MPI_Scatter(void *sendbuffer, int sendcount, MPI_Datatype sendtype,
00296 void *recvbuffer, int recvcount, MPI_Datatype recvtype,
00297 int root, MPI_Comm comm)
00298 {
00299
00301 if (comm != MPI_COMM_WORLD || my_init == 0)
00302 return EINVAL;
00303
00304
00305
00306
00307 return MPI_SUCCESS;
00308 }
00309
00310 int MPI_Gather(void *sendbuffer, int sendcount, MPI_Datatype sendtype,
00311 void *recvbuffer, int recvcount, MPI_Datatype recvtype,
00312 int root, MPI_Comm comm)
00313 {
00314
00315
00316 if (comm != MPI_COMM_WORLD || my_init == 0)
00317 return EINVAL;
00318
00319 return MPI_SUCCESS;
00320 }