1 // -*- c++ -*-
2 //
3 // Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4 //                         University Research and Technology
5 //                         Corporation.  All rights reserved.
6 // Copyright (c) 2004-2005 The University of Tennessee and The University
7 //                         of Tennessee Research Foundation.  All rights
8 //                         reserved.
9 // Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10 //                         University of Stuttgart.  All rights reserved.
11 // Copyright (c) 2004-2005 The Regents of the University of California.
12 //                         All rights reserved.
13 // Copyright (c) 2006-2009 Cisco Systems, Inc.  All rights reserved.
14 // Copyright (c) 2011      FUJITSU LIMITED.  All rights reserved.
15 // $COPYRIGHT$
16 //
17 // Additional copyrights may follow
18 //
19 // $HEADER$
20 //
21 
22 class Comm_Null {
23 #if 0 /* OMPI_ENABLE_MPI_PROFILING */
24   //  friend class PMPI::Comm_Null;
25 #endif
26 public:
27 
28 #if 0 /* OMPI_ENABLE_MPI_PROFILING */
29 
30   // construction
31   inline Comm_Null() { }
32   // copy
33   inline Comm_Null(const Comm_Null& data) : pmpi_comm(data.pmpi_comm) { }
34   // inter-language operability
35   inline Comm_Null(MPI_Comm data) : pmpi_comm(data) { }
36 
37   inline Comm_Null(const PMPI::Comm_Null& data) : pmpi_comm(data) { }
38 
39   // destruction
40   virtual inline ~Comm_Null() { }
41 
42   inline Comm_Null& operator=(const Comm_Null& data) {
43     pmpi_comm = data.pmpi_comm;
44     return *this;
45   }
46 
47   // comparison
48   inline bool operator==(const Comm_Null& data) const {
49     return (bool) (pmpi_comm == data.pmpi_comm); }
50 
51   inline bool operator!=(const Comm_Null& data) const {
52     return (bool) (pmpi_comm != data.pmpi_comm);}
53 
54   // inter-language operability (conversion operators)
55   inline operator MPI_Comm() const { return pmpi_comm; }
56   //  inline operator MPI_Comm*() /*const JGS*/ { return pmpi_comm; }
57   inline operator const PMPI::Comm_Null&() const { return pmpi_comm; }
58 
59 #else
60 
61   // construction
Comm_Null()62   inline Comm_Null() : mpi_comm(MPI_COMM_NULL) { }
63   // copy
Comm_Null(const Comm_Null & data)64   inline Comm_Null(const Comm_Null& data) : mpi_comm(data.mpi_comm) { }
65   // inter-language operability
Comm_Null(MPI_Comm data)66   inline Comm_Null(MPI_Comm data) : mpi_comm(data) { }
67 
68   // destruction
~Comm_Null()69   virtual inline ~Comm_Null() { }
70 
71  // comparison
72   // JGS make sure this is right (in other classes too)
73   inline bool operator==(const Comm_Null& data) const {
74     return (bool) (mpi_comm == data.mpi_comm); }
75 
76   inline bool operator!=(const Comm_Null& data) const {
77     return (bool) !(*this == data);}
78 
79   // inter-language operability (conversion operators)
MPI_Comm()80   inline operator MPI_Comm() const { return mpi_comm; }
81 
82 #endif
83 
84 
85 protected:
86 
87 #if 0 /* OMPI_ENABLE_MPI_PROFILING */
88   PMPI::Comm_Null pmpi_comm;
89 #else
90   MPI_Comm mpi_comm;
91 #endif
92 
93 
94 };
95 
96 
97 class Comm : public Comm_Null {
98 public:
99 
100   typedef void Errhandler_function(Comm&, int*, ...);
101   typedef Errhandler_function Errhandler_fn
102         __mpi_interface_deprecated__("MPI::Comm::Errhandler_fn was deprecated in MPI-2.2; use MPI::Comm::Errhandler_function instead");
103   typedef int Copy_attr_function(const Comm& oldcomm, int comm_keyval,
104 				 void* extra_state, void* attribute_val_in,
105 				 void* attribute_val_out,
106 				 bool& flag);
107   typedef int Delete_attr_function(Comm& comm, int comm_keyval,
108 				   void* attribute_val,
109 				   void* extra_state);
110 #if !0 /* OMPI_ENABLE_MPI_PROFILING */
111 #define _MPI2CPP_ERRHANDLERFN_ Errhandler_function
112 #define _MPI2CPP_COPYATTRFN_ Copy_attr_function
113 #define _MPI2CPP_DELETEATTRFN_ Delete_attr_function
114 #endif
115 
116   // construction
117   Comm();
118 
119   // copy
120   Comm(const Comm_Null& data);
121 
122 #if 0 /* OMPI_ENABLE_MPI_PROFILING */
123   Comm(const Comm& data) :
124     Comm_Null(data),
125     pmpi_comm((const PMPI::Comm&) data) { }
126 
127   // inter-language operability
128   Comm(MPI_Comm data) : Comm_Null(data), pmpi_comm(data) { }
129 
130   Comm(const PMPI::Comm& data) :
131     Comm_Null((const PMPI::Comm_Null&)data),
132     pmpi_comm(data) { }
133 
134   operator const PMPI::Comm&() const { return pmpi_comm; }
135 
136   // assignment
137   Comm& operator=(const Comm& data) {
138     this->Comm_Null::operator=(data);
139     pmpi_comm = data.pmpi_comm;
140     return *this;
141   }
142   Comm& operator=(const Comm_Null& data) {
143     this->Comm_Null::operator=(data);
144     MPI_Comm tmp = data;
145     pmpi_comm = tmp;
146     return *this;
147   }
148   // inter-language operability
149   Comm& operator=(const MPI_Comm& data) {
150     this->Comm_Null::operator=(data);
151     pmpi_comm = data;
152     return *this;
153   }
154 
155 #else
Comm(const Comm & data)156   Comm(const Comm& data) : Comm_Null(data.mpi_comm) { }
157   // inter-language operability
Comm(MPI_Comm data)158   Comm(MPI_Comm data) : Comm_Null(data) { }
159 #endif
160 
161 
162   //
163   // Point-to-Point
164   //
165 
166   virtual void Send(const void *buf, int count,
167 		    const Datatype & datatype, int dest, int tag) const;
168 
169   virtual void Recv(void *buf, int count, const Datatype & datatype,
170 		    int source, int tag, Status & status) const;
171 
172 
173   virtual void Recv(void *buf, int count, const Datatype & datatype,
174 		    int source, int tag) const;
175 
176   virtual void Bsend(const void *buf, int count,
177 		     const Datatype & datatype, int dest, int tag) const;
178 
179   virtual void Ssend(const void *buf, int count,
180 		     const Datatype & datatype, int dest, int tag) const ;
181 
182   virtual void Rsend(const void *buf, int count,
183 		     const Datatype & datatype, int dest, int tag) const;
184 
185   virtual Request Isend(const void *buf, int count,
186 			const Datatype & datatype, int dest, int tag) const;
187 
188   virtual Request Ibsend(const void *buf, int count, const
189 			 Datatype & datatype, int dest, int tag) const;
190 
191   virtual Request Issend(const void *buf, int count,
192 			 const Datatype & datatype, int dest, int tag) const;
193 
194   virtual Request Irsend(const void *buf, int count,
195 			 const Datatype & datatype, int dest, int tag) const;
196 
197   virtual Request Irecv(void *buf, int count,
198 			const Datatype & datatype, int source, int tag) const;
199 
200   virtual bool Iprobe(int source, int tag, Status & status) const;
201 
202   virtual bool Iprobe(int source, int tag) const;
203 
204   virtual void Probe(int source, int tag, Status & status) const;
205 
206   virtual void Probe(int source, int tag) const;
207 
208   virtual Prequest Send_init(const void *buf, int count,
209 			     const Datatype & datatype, int dest,
210 			     int tag) const;
211 
212   virtual Prequest Bsend_init(const void *buf, int count,
213 			      const Datatype & datatype, int dest,
214 			      int tag) const;
215 
216   virtual Prequest Ssend_init(const void *buf, int count,
217 			      const Datatype & datatype, int dest,
218 			      int tag) const;
219 
220   virtual Prequest Rsend_init(const void *buf, int count,
221 			      const Datatype & datatype, int dest,
222 			      int tag) const;
223 
224   virtual Prequest Recv_init(void *buf, int count,
225 			     const Datatype & datatype, int source,
226 			     int tag) const;
227 
228   virtual void Sendrecv(const void *sendbuf, int sendcount,
229 			const Datatype & sendtype, int dest, int sendtag,
230 			void *recvbuf, int recvcount,
231 			const Datatype & recvtype, int source,
232 			int recvtag, Status & status) const;
233 
234   virtual void Sendrecv(const void *sendbuf, int sendcount,
235 			const Datatype & sendtype, int dest, int sendtag,
236 			void *recvbuf, int recvcount,
237 			const Datatype & recvtype, int source,
238 			int recvtag) const;
239 
240   virtual void Sendrecv_replace(void *buf, int count,
241 				const Datatype & datatype, int dest,
242 				int sendtag, int source,
243 				int recvtag, Status & status) const;
244 
245   virtual void Sendrecv_replace(void *buf, int count,
246 				const Datatype & datatype, int dest,
247 				int sendtag, int source,
248 				int recvtag) const;
249 
250   //
251   // Groups, Contexts, and Communicators
252   //
253 
254   virtual Group Get_group() const;
255 
256   virtual int Get_size() const;
257 
258   virtual int Get_rank() const;
259 
260   static int Compare(const Comm & comm1, const Comm & comm2);
261 
262   virtual Comm& Clone() const = 0;
263 
264   virtual void Free(void);
265 
266   virtual bool Is_inter() const;
267 
268 
269   //
270   // Collective Communication
271   //
272   // Up in Comm because as of MPI-2, they are common to intracomm and
273   // intercomm -- with the exception of Scan and Exscan, which are not
274   // defined on intercomms.
275   //
276 
277   virtual void
278   Barrier() const;
279 
280   virtual void
281   Bcast(void *buffer, int count,
282 	const Datatype& datatype, int root) const;
283 
284   virtual void
285   Gather(const void *sendbuf, int sendcount,
286 	 const Datatype & sendtype,
287 	 void *recvbuf, int recvcount,
288 	 const Datatype & recvtype, int root) const;
289 
290   virtual void
291   Gatherv(const void *sendbuf, int sendcount,
292 	  const Datatype & sendtype, void *recvbuf,
293 	  const int recvcounts[], const int displs[],
294 	  const Datatype & recvtype, int root) const;
295 
296   virtual void
297   Scatter(const void *sendbuf, int sendcount,
298 	  const Datatype & sendtype,
299 	  void *recvbuf, int recvcount,
300 	  const Datatype & recvtype, int root) const;
301 
302   virtual void
303   Scatterv(const void *sendbuf, const int sendcounts[],
304 	   const int displs[], const Datatype & sendtype,
305 	   void *recvbuf, int recvcount,
306 	   const Datatype & recvtype, int root) const;
307 
308   virtual void
309   Allgather(const void *sendbuf, int sendcount,
310 	    const Datatype & sendtype, void *recvbuf,
311 	    int recvcount, const Datatype & recvtype) const;
312 
313   virtual void
314   Allgatherv(const void *sendbuf, int sendcount,
315 	     const Datatype & sendtype, void *recvbuf,
316 	     const int recvcounts[], const int displs[],
317 	     const Datatype & recvtype) const;
318 
319   virtual void
320   Alltoall(const void *sendbuf, int sendcount,
321 	   const Datatype & sendtype, void *recvbuf,
322 	   int recvcount, const Datatype & recvtype) const;
323 
324   virtual void
325   Alltoallv(const void *sendbuf, const int sendcounts[],
326 	    const int sdispls[], const Datatype & sendtype,
327 	    void *recvbuf, const int recvcounts[],
328 	    const int rdispls[], const Datatype & recvtype) const;
329 
330   virtual void
331   Alltoallw(const void *sendbuf, const int sendcounts[],
332             const int sdispls[], const Datatype sendtypes[],
333             void *recvbuf, const int recvcounts[],
334             const int rdispls[], const Datatype recvtypes[]) const;
335 
336   virtual void
337   Reduce(const void *sendbuf, void *recvbuf, int count,
338 	 const Datatype & datatype, const Op & op,
339 	 int root) const;
340 
341 
342   virtual void
343   Allreduce(const void *sendbuf, void *recvbuf, int count,
344 	    const Datatype & datatype, const Op & op) const;
345 
346   virtual void
347   Reduce_scatter(const void *sendbuf, void *recvbuf,
348 		 int recvcounts[],
349 		 const Datatype & datatype,
350 		 const Op & op) const;
351 
352   //
353   // Process Creation
354   //
355 
356   virtual void Disconnect();
357 
358   static Intercomm Get_parent();
359 
360   static Intercomm Join(const int fd);
361 
362   //
363   // External Interfaces
364   //
365 
366   virtual void Get_name(char * comm_name, int& resultlen) const;
367 
368   virtual void Set_name(const char* comm_name);
369 
370   //
371   // Process Topologies
372   //
373 
374   virtual int Get_topology() const;
375 
376   //
377   // Environmental Inquiry
378   //
379 
380   virtual void Abort(int errorcode);
381 
382   //
383   // Errhandler
384   //
385 
386   static Errhandler Create_errhandler(Comm::Errhandler_function* function);
387 
388   virtual void Set_errhandler(const Errhandler& errhandler);
389 
390   virtual Errhandler Get_errhandler() const;
391 
392   void Call_errhandler(int errorcode) const;
393 
394   //
395   // Keys and Attributes
396   //
397 
398   // Need 4 overloaded versions of this function because per the
399   // MPI-2 spec, you can mix-n-match the C predefined functions with
400   // C++ functions.
401   static int Create_keyval(Copy_attr_function* comm_copy_attr_fn,
402                            Delete_attr_function* comm_delete_attr_fn,
403                            void* extra_state);
404   static int Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn,
405                            MPI_Comm_delete_attr_function* comm_delete_attr_fn,
406                            void* extra_state);
407   static int Create_keyval(Copy_attr_function* comm_copy_attr_fn,
408                            MPI_Comm_delete_attr_function* comm_delete_attr_fn,
409                            void* extra_state);
410   static int Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn,
411                            Delete_attr_function* comm_delete_attr_fn,
412                            void* extra_state);
413 
414 protected:
415   static int do_create_keyval(MPI_Comm_copy_attr_function* c_copy_fn,
416                               MPI_Comm_delete_attr_function* c_delete_fn,
417                               Copy_attr_function* cxx_copy_fn,
418                               Delete_attr_function* cxx_delete_fn,
419                               void* extra_state, int &keyval);
420 
421 public:
422 
423   static void Free_keyval(int& comm_keyval);
424 
425   virtual void Set_attr(int comm_keyval, const void* attribute_val) const;
426 
427   virtual bool Get_attr(int comm_keyval, void* attribute_val) const;
428 
429   virtual void Delete_attr(int comm_keyval);
430 
431   static int NULL_COPY_FN(const Comm& oldcomm, int comm_keyval,
432 			  void* extra_state, void* attribute_val_in,
433 			  void* attribute_val_out, bool& flag);
434 
435   static int DUP_FN(const Comm& oldcomm, int comm_keyval,
436 		    void* extra_state, void* attribute_val_in,
437 		    void* attribute_val_out, bool& flag);
438 
439   static int NULL_DELETE_FN(Comm& comm, int comm_keyval, void* attribute_val,
440 			    void* extra_state);
441 
442 
443 private:
444 #if 0 /* OMPI_ENABLE_MPI_PROFILING */
445   PMPI::Comm pmpi_comm;
446 #endif
447 
448 #if ! 0 /* OMPI_ENABLE_MPI_PROFILING */
449 public:
450 
451     // Data that is passed through keyval create when C++ callback
452     // functions are used
453     struct keyval_intercept_data_t {
454         MPI_Comm_copy_attr_function *c_copy_fn;
455         MPI_Comm_delete_attr_function *c_delete_fn;
456         Copy_attr_function* cxx_copy_fn;
457         Delete_attr_function* cxx_delete_fn;
458         void *extra_state;
459     };
460 
461     // Protect the global list from multiple thread access
462     static opal_mutex_t cxx_extra_states_lock;
463 #endif
464 
465 };
466