Changes between Version 10 and Version 11 of MessagePassing


Ignore:
Timestamp:
07/12/13 15:52:12 (13 years ago)
Author:
siegel
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MessagePassing

    v10 v11  
    200200 * `int $COMM_ANY_TAG`
    201201
    202 
     202Here is how these primitives could be used to implement an MPI program:
     203
     204{{{
     205#define MPI_ANY_SOURCE $COMM_ANY_SOURCE
     206#define MPI_ANY_TAG $COMM_ANY_TAG
     207#define MPI_INT 1
     208#define MPI_FLOAT 2
     209#define MPI_DOUBLE 3
     210// etc.
     211
     212$input int NPROCS;
     213$assume NPROCS >= 1;
     214$scope top;
     215$proc procs[NPROCS];
     216
     217typedef $comm *MPI_Comm;
     218$comm MPI_Comm_world_comm;
     219MPI_Comm *MPI_COMM_WORLD = &_MPI_COMM_WORLD;
     220boolean initialized = $false;
     221
     222/* This structure tells you the source and tag of a received message,
     223 * which you need if you used wildcards,  Also size.
     224 */
     225typedef struct MPI_Status {
     226  int source;
     227  int tag;
     228  int size;
     229} MPI_Status;
     230
     231typedef int MPI_Datatype;
     232
     233int sizeofDatatype(MPI_Datatype type) {
     234  switch (type) {
     235    case MPI_INT: return sizeof(int);
     236    case MPI_FLOAT: return sizeof(float);
     237    case MPI_DOUBLE: return sizeof(double);
     238    default: exit(-1); // not yet implemented
     239  }
     240}
     241
     242void MPI_Comm_init(MPI_Comm comm) {
     243  $when (initialized) ;
     244}
     245
     246void MPI_Send(int pid, void *buf, int count, MPI_Datatype type, int dest, int tag, MPI_Comm comm) {
     247  $message m = $message_pack(pid, dest, tag, buf, sizeofDatatype(type)*count);
     248
     249  $comm_enqueue(comm, &m);
     250}
     251
     252void MPI_Recv(int pid, void *buf, int count, MPI_Datataype type, int source, int tag, MPI_Comm comm, MPI_Status *status) {
     253  int size = sizeofDatatype(type)*count;
     254  // the following is a system function with built-in guard:
     255  $message m = $comm_dequeue(comm, source, pid, tag);
     256
     257  status->size = $message_size(&m);
     258  status->source = $message_source(&m);
     259  status->dest = $message_dest(&m);
     260  $message_unpack(&m, buf, size); // will throw exception if message too big
     261}
     262
     263void MPI_process(int pid) {
     264  ...
     265  MPI_Comm_init(MPI_COMM_WORLD);
     266  ...
     267}
     268
     269void main() {
     270  for (int i=0; i<NPROCS; i++) procs[i] = $spawn MPI_process(i);
     271  MPI_Comm_world_comm = $comm_create(NPROCS, &procs[0]);
     272  initialized = $true;
     273  for (int i=0; i<NPROCS; i++) $wait procs[i];
     274}
     275}}}
     276
     277