Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Gears MPI Accelerator Service
[palacios.git] / gears / services / mpi / mpi_preload.c
1 #include <mpi/mpi.h>
2 #include <stdio.h>
3 #include <dlfcn.h>
4 #include <stdlib.h>
5 #include "mpi_hc.h"
6
7 static int (*mpi_init)(int *argc, char ***argv) = NULL;
8 static int (*mpi_deinit)() = NULL;
9 static int (*mpi_comm_rank)(MPI_Comm, int *) = NULL;
10 static int (*mpi_send)(void *, int, MPI_Datatype, int, int, MPI_Comm) = NULL;
11 static int (*mpi_recv)(void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status *) = NULL;
12
13 static int hcall_enabled=0;
14
15 int connect_handler(void)
16 {
17   void * handle;
18   char * err;
19
20   handle = dlopen("/usr/local/lib/libmpich.so", RTLD_LAZY);
21   if (!handle){
22     fputs(dlerror(), stderr);
23     return -1;
24   } 
25   mpi_init = dlsym(handle, "MPI_Init");
26   if ((err = dlerror()) != NULL) {
27     fprintf(stderr, "%s\n", err);
28     return -1;
29   }
30   mpi_deinit = dlsym(handle, "MPI_Finalize");
31   if ((err = dlerror()) != NULL) {
32     fprintf(stderr, "%s\n", err);
33     return -1;
34   }
35   mpi_comm_rank = dlsym(handle, "MPI_Comm_rank");
36   if ((err = dlerror()) != NULL) {
37     fprintf(stderr, "%s\n", err);
38     return -1;
39   }
40   mpi_recv = dlsym(handle, "MPI_Recv");
41   if ((err = dlerror()) != NULL) {
42     fprintf(stderr, "%s\n", err);
43     return -1;
44   }
45   mpi_send = dlsym(handle, "MPI_Send");
46   if ((err = dlerror()) != NULL) {
47     fprintf(stderr, "%s\n", err);
48     return -1;
49   }
50   
51   return 0;
52 }
53
54
55 int MPI_Init(int *argc, char ***argv)
56 {
57   int rc;
58   volatile char temp;
59
60   if (mpi_init == NULL){
61     connect_handler();
62   }
63   
64   // Make sure that ***argv is in memory
65   temp = ***argv;
66
67   rc = mpi_init(argc,argv);
68
69   if (rc<0) { 
70     return rc;
71   }
72
73   fprintf(stderr,"Invoking mpi_init_hcall(%p,%p)\n",argc,argv);
74   
75   if (mpi_init_hcall(argc,argv)<0) {
76     // not connected
77     hcall_enabled=0;
78     fprintf(stderr,"No connection to V3VEE MPI accelerator\n");
79   } else {
80     // connected
81     hcall_enabled=1;
82     fprintf(stderr,"Connected to V3VEE MPI accelerator\n");
83   }
84   
85   return rc;
86 }
87
88 int MPI_Finalize()
89 {
90   if (mpi_deinit == NULL){
91     connect_handler();
92   }
93   
94   if (hcall_enabled) { 
95     if (mpi_deinit_hcall()<0) {
96       fprintf(stderr,"Could not disconnect from V3VEE MPI accelerator\n");
97     }
98     hcall_enabled=0;
99   }
100   
101   return mpi_deinit();
102   
103 }
104
105
106 int MPI_Comm_rank(MPI_Comm comm, int *rank)
107 {
108   int rc;
109   volatile int temp;
110
111   if (mpi_comm_rank == NULL){
112     connect_handler();
113   }
114
115
116   rc=mpi_comm_rank(comm,rank);
117   
118   if (rc<0) {
119     return rc;
120   }
121
122   // Make sure *rank is in memory
123   temp=*rank;
124
125   if (hcall_enabled) { 
126     if (mpi_comm_rank_hcall(comm,rank)<0) {
127       fprintf(stderr,"Could not invoke mpi_comm_rank on V3VEE MPI accelerator\n");
128     }
129   }
130
131   return rc;
132
133 }
134
135 int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
136 {
137   if (mpi_send == NULL){
138     connect_handler();
139   }
140
141   if (hcall_enabled) {
142     int i;
143     volatile char temp;
144     int rc;
145
146     // Force into memory
147     for (i=0;i<count;i+=4096) { 
148       temp=((char*)buf)[i];
149     }
150
151     if ((rc=mpi_send_hcall(buf,count,datatype,dest,tag,comm))<0) { 
152       fprintf(stderr, "Could not send using V3VEE MPI accelerator - Trying Slow Path\n");
153       return mpi_send(buf, count, datatype, dest, tag, comm);
154     } else {
155       return rc;
156     }
157   } else {
158     return mpi_send(buf, count, datatype, dest, tag, comm);
159   }
160 }
161
162 int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag,
163              MPI_Comm comm, MPI_Status *status)
164 {
165   if (mpi_recv == NULL){
166     connect_handler();
167   }
168
169   if (hcall_enabled) {
170     int rc;
171     int i;
172     volatile char temp=93;
173
174     // Force into memory
175     for (i=0;i<count;i+=4096) { 
176       ((char*)buf)[i]=temp;
177     }
178     if ((rc=mpi_recv_hcall(buf,count,datatype,source,tag,comm,status))<0) { 
179       fprintf(stderr, "Could not receive using V3VEE MPI accelerator - Trying Slow Path\n");
180       return mpi_recv(buf, count, datatype, source, tag, comm, status);
181     } else {
182       return rc;
183     }
184   } else {
185     return mpi_recv(buf, count, datatype, source, tag, comm, status);
186   }
187 }
188