Ticket #5245: boost_1_45_0.ssend.patch
File boost_1_45_0.ssend.patch, 40.2 KB (added by , 12 years ago) |
---|
-
boost/mpi/communicator.hpp
Only in boost_1_45_0: bjam diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/boost/mpi/communicator.hpp boost_1_45_0/boost/mpi/communicator.hpp
old new 296 296 * 297 297 * @param proxy The @c skeleton_proxy containing a reference to the 298 298 * object whose skeleton will be transmitted. 299 *300 299 */ 301 300 template<typename T> 302 301 void send(int dest, int tag, const skeleton_proxy<T>& proxy) const; … … 344 343 * @param tag The tag that will be associated with this message. Tags 345 344 * may be any integer between zero and an implementation-defined 346 345 * upper limit. This limit is accessible via @c environment::max_tag(). 347 *348 346 */ 349 347 void send(int dest, int tag) const; 350 348 351 349 /** 350 * @brief Synchronously send data to another process. 351 * 352 * This routine executes a potentially blocking synchronous send 353 * with tag @p tag to the process with rank @p dest. This routine 354 * is exactly equivalent to @ref send(int,int,const T&) (which see) 355 * but uses an MPI synchronous send (MPI_Ssend). 356 * 357 */ 358 template<typename T> 359 void ssend(int dest, int tag, const T& value) const; 360 361 /** 362 * @brief Synchronously send the skeleton of an object. 363 * 364 * This routine executes a potentially blocking send with tag @p 365 * tag to the process with rank @p dest. It can be received by the 366 * destination process with a matching @c recv call. This variation 367 * on @c ssend will be used when a synchronous send of a skeleton 368 * is explicitly requested via code such as: 369 * 370 * @code 371 * comm.ssend(dest, tag, skeleton(object)); 372 * @endcode 373 * 374 * This routine is exactly equivalent to @ref send(int,int,const 375 * skeleton_proxy<T>&) (which see) but uses an MPI synchronous send 376 * (MPI_Ssend). 377 * 378 */ 379 template<typename T> 380 void ssend(int dest, int tag, const skeleton_proxy<T>& proxy) const; 381 382 /** 383 * @brief Synchronously send an array of values to another process. 384 * 385 * This routine is equivalent to @ref send(int,int,const T*,int) 386 * (which see) but uses an MPI synchronous send (MPI_Ssend). 387 */ 388 template<typename T> 389 void ssend(int dest, int tag, const T* values, int n) const; 390 391 /** 392 * @brief Synchronously send a message to another process without 393 * any data. 394 * 395 * This routine is equivalent to @ref send(int,int) (which see) but 396 * uses an MPI synchronous send (MPI_Ssend). 397 */ 398 void ssend(int dest, int tag) const; 399 400 /** 352 401 * @brief Receive data from a remote process. 353 402 * 354 403 * This routine blocks until it receives a message from the process @p … … 586 635 * may be any integer between zero and an implementation-defined 587 636 * upper limit. This limit is accessible via @c environment::max_tag(). 588 637 * 589 *590 638 * @returns a @c request object that describes this communication. 591 639 */ 592 640 request isend(int dest, int tag) const; 593 641 594 642 /** 643 * @brief Synchronously send a message to a remote process without 644 * blocking. 645 * 646 * This routine is equivalent to @ref isend(int,int,const T&) 647 * (which see) but uses an MPI synchronous send (MPI_Ssend). 648 */ 649 template<typename T> 650 request issend(int dest, int tag, const T& value) const; 651 652 /** 653 * @brief Synchronously send the skeleton of an object without blocking. 654 * 655 * This routine is equivalent to @ref isend(int,int,const skeleton_proxy<T>&) 656 * (which see) but uses an MPI synchronous send (MPI_Ssend). 657 */ 658 template<typename T> 659 request issend(int dest, int tag, const skeleton_proxy<T>& proxy) const; 660 661 /** 662 * @brief Synchronously send an array of values to another process 663 * without blocking. 664 * 665 * This routine is equivalent to @ref isend(int,int,const T*,int) 666 * (which see) but uses an MPI synchronous send (MPI_Ssend). 667 */ 668 template<typename T> 669 request issend(int dest, int tag, const T* values, int n) const; 670 671 /** 672 * @brief Synchronously send a message to another process without 673 * any data without blocking. 674 * 675 * This routine is equivalent to @ref isend(int,int) 676 * (which see) but uses an MPI synchronous send (MPI_Ssend). 677 */ 678 request issend(int dest, int tag) const; 679 680 /** 595 681 * @brief Prepare to receive a message from a remote process. 596 682 * 597 683 * The @c irecv method is functionally identical to the @c recv … … 885 971 * map directly to that datatype. 886 972 */ 887 973 template<typename T> 888 void send_impl(int dest, int tag, const T& value, mpl::true_) const; 974 void send_impl(int dest, int tag, const T& value, mpl::true_, 975 const bool synchronous = false) const; 889 976 890 977 /** 891 978 * INTERNAL ONLY … … 895 982 * to be deserialized on the receiver side. 896 983 */ 897 984 template<typename T> 898 void send_impl(int dest, int tag, const T& value, mpl::false_) const; 985 void send_impl(int dest, int tag, const T& value, mpl::false_, 986 const bool synchronous = false) const; 987 988 /** 989 * INTERNAL ONLY 990 */ 991 template<typename T> 992 void send_impl(int dest, int tag, const skeleton_proxy<T>& proxy, 993 const bool synchronous) const; 899 994 900 995 /** 901 996 * INTERNAL ONLY … … 905 1000 */ 906 1001 template<typename T> 907 1002 void 908 array_send_impl(int dest, int tag, const T* values, int n, mpl::true_) const; 1003 array_send_impl(int dest, int tag, const T* values, int n, mpl::true_, 1004 const bool synchronous = false) const; 909 1005 910 1006 /** 911 1007 * INTERNAL ONLY … … 917 1013 template<typename T> 918 1014 void 919 1015 array_send_impl(int dest, int tag, const T* values, int n, 920 mpl::false_ ) const;1016 mpl::false_, const bool synchronous = false) const; 921 1017 922 1018 /** 923 1019 * INTERNAL ONLY … … 926 1022 * map directly to that datatype. 927 1023 */ 928 1024 template<typename T> 929 request isend_impl(int dest, int tag, const T& value, mpl::true_) const; 1025 request isend_impl(int dest, int tag, const T& value, mpl::true_, 1026 const bool synchronous = false) const; 930 1027 931 1028 /** 932 1029 * INTERNAL ONLY … … 936 1033 * to be deserialized on the receiver side. 937 1034 */ 938 1035 template<typename T> 939 request isend_impl(int dest, int tag, const T& value, mpl::false_) const; 1036 request isend_impl(int dest, int tag, const T& value, mpl::false_, 1037 const bool synchronous = false) const; 1038 1039 /** 1040 * INTERNAL ONLY 1041 */ 1042 template<typename T> 1043 request isend_impl(int dest, int tag, const skeleton_proxy<T>& proxy, 1044 const bool synchronous) const; 940 1045 941 1046 /** 942 1047 * INTERNAL ONLY … … 947 1052 template<typename T> 948 1053 request 949 1054 array_isend_impl(int dest, int tag, const T* values, int n, 950 mpl::true_ ) const;1055 mpl::true_, const bool synchronous = false) const; 951 1056 952 1057 /** 953 1058 * INTERNAL ONLY … … 959 1064 template<typename T> 960 1065 request 961 1066 array_isend_impl(int dest, int tag, const T* values, int n, 962 mpl::false_ ) const;1067 mpl::false_, const bool synchronous = false) const; 963 1068 964 1069 /** 965 1070 * INTERNAL ONLY … … 1105 1210 // map directly to that datatype. 1106 1211 template<typename T> 1107 1212 void 1108 communicator::send_impl(int dest, int tag, const T& value, mpl::true_) const 1213 communicator::send_impl(int dest, int tag, const T& value, mpl::true_, 1214 const bool synchronous) const 1109 1215 { 1216 if (synchronous) { 1217 BOOST_MPI_CHECK_RESULT(MPI_Ssend, 1218 (const_cast<T*>(&value), 1, get_mpi_datatype<T>(value), 1219 dest, tag, MPI_Comm(*this))); 1220 } else { 1110 1221 BOOST_MPI_CHECK_RESULT(MPI_Send, 1111 1222 (const_cast<T*>(&value), 1, get_mpi_datatype<T>(value), 1112 1223 dest, tag, MPI_Comm(*this))); 1224 }; 1113 1225 } 1114 1226 1115 1227 // We're sending a type that does not have an associated MPI … … 1117 1229 // to be deserialized on the receiver side. 1118 1230 template<typename T> 1119 1231 void 1120 communicator::send_impl(int dest, int tag, const T& value, mpl::false_) const 1232 communicator::send_impl(int dest, int tag, const T& value, mpl::false_, 1233 const bool synchronous) const 1121 1234 { 1122 1235 packed_oarchive oa(*this); 1123 1236 oa << value; 1237 if (synchronous) 1238 ssend(dest, tag, oa); 1239 else 1124 1240 send(dest, tag, oa); 1125 1241 } 1126 1242 … … 1129 1245 template<typename T> 1130 1246 void communicator::send(int dest, int tag, const T& value) const 1131 1247 { 1132 this->send_impl(dest, tag, value, is_mpi_datatype<T>()); 1248 send_impl(dest, tag, value, is_mpi_datatype<T>(), false); 1249 } 1250 1251 // Single-element receive may either send the element directly or 1252 // serialize it via a buffer. 1253 template<typename T> 1254 void communicator::ssend(int dest, int tag, const T& value) const 1255 { 1256 send_impl(dest, tag, value, is_mpi_datatype<T>(), true); 1133 1257 } 1134 1258 1135 1259 // We're sending an array of a type that has an associated MPI … … 1137 1261 template<typename T> 1138 1262 void 1139 1263 communicator::array_send_impl(int dest, int tag, const T* values, int n, 1140 mpl::true_ ) const1264 mpl::true_, const bool synchronous) const 1141 1265 { 1266 if (synchronous) { 1267 BOOST_MPI_CHECK_RESULT(MPI_Ssend, 1268 (const_cast<T*>(values), n, 1269 get_mpi_datatype<T>(*values), 1270 dest, tag, MPI_Comm(*this))); 1271 } else { 1142 1272 BOOST_MPI_CHECK_RESULT(MPI_Send, 1143 1273 (const_cast<T*>(values), n, 1144 1274 get_mpi_datatype<T>(*values), 1145 1275 dest, tag, MPI_Comm(*this))); 1276 }; 1146 1277 } 1147 1278 1148 1279 // We're sending an array of a type that does not have an associated … … 1151 1282 template<typename T> 1152 1283 void 1153 1284 communicator::array_send_impl(int dest, int tag, const T* values, int n, 1154 mpl::false_ ) const1285 mpl::false_, const bool synchronous) const 1155 1286 { 1156 1287 packed_oarchive oa(*this); 1157 1288 oa << n << boost::serialization::make_array(values, n); 1289 if (synchronous) 1290 ssend(dest, tag, oa); 1291 else 1158 1292 send(dest, tag, oa); 1159 1293 } 1160 1294 … … 1162 1296 template<typename T> 1163 1297 void communicator::send(int dest, int tag, const T* values, int n) const 1164 1298 { 1165 this->array_send_impl(dest, tag, values, n, is_mpi_datatype<T>()); 1299 this->array_send_impl(dest, tag, values, n, is_mpi_datatype<T>(), false); 1300 } 1301 1302 // Array ssend must send the elements directly 1303 template<typename T> 1304 void communicator::ssend(int dest, int tag, const T* values, int n) const 1305 { 1306 this->array_send_impl(dest, tag, values, n, is_mpi_datatype<T>(), true); 1166 1307 } 1167 1308 1168 1309 // We're receiving a type that has an associated MPI datatype, so we … … 1251 1392 // map directly to that datatype. 1252 1393 template<typename T> 1253 1394 request 1254 communicator::isend_impl(int dest, int tag, const T& value, mpl::true_) const 1395 communicator::isend_impl(int dest, int tag, const T& value, mpl::true_, 1396 const bool synchronous) const 1255 1397 { 1256 1398 request req; 1399 if (synchronous) { 1400 BOOST_MPI_CHECK_RESULT(MPI_Issend, 1401 (const_cast<T*>(&value), 1, 1402 get_mpi_datatype<T>(value), 1403 dest, tag, MPI_Comm(*this), &req.m_requests[0])); 1404 } else { 1257 1405 BOOST_MPI_CHECK_RESULT(MPI_Isend, 1258 1406 (const_cast<T*>(&value), 1, 1259 1407 get_mpi_datatype<T>(value), 1260 1408 dest, tag, MPI_Comm(*this), &req.m_requests[0])); 1409 }; 1261 1410 return req; 1262 1411 } 1263 1412 … … 1266 1415 // to be deserialized on the receiver side. 1267 1416 template<typename T> 1268 1417 request 1269 communicator::isend_impl(int dest, int tag, const T& value, mpl::false_) const 1418 communicator::isend_impl(int dest, int tag, const T& value, mpl::false_, 1419 const bool synchronous) const 1270 1420 { 1271 1421 shared_ptr<packed_oarchive> archive(new packed_oarchive(*this)); 1272 1422 *archive << value; 1273 request result = isend(dest, tag, *archive); 1423 request result = (synchronous? 1424 issend(dest, tag, *archive) 1425 : isend(dest, tag, *archive)); 1274 1426 result.m_data = archive; 1275 1427 return result; 1276 1428 } … … 1280 1432 template<typename T> 1281 1433 request communicator::isend(int dest, int tag, const T& value) const 1282 1434 { 1283 return this->isend_impl(dest, tag, value, is_mpi_datatype<T>()); 1435 return isend_impl(dest, tag, value, is_mpi_datatype<T>(), false); 1436 } 1437 1438 // Single-element receive may either send the element directly or 1439 // serialize it via a buffer. 1440 template<typename T> 1441 request communicator::issend(int dest, int tag, const T& value) const 1442 { 1443 return isend_impl(dest, tag, value, is_mpi_datatype<T>(), true); 1284 1444 } 1285 1445 1286 1446 template<typename T> 1287 1447 request 1288 1448 communicator::array_isend_impl(int dest, int tag, const T* values, int n, 1289 mpl::true_ ) const1449 mpl::true_, const bool synchronous) const 1290 1450 { 1291 1451 request req; 1452 if (synchronous) { 1453 BOOST_MPI_CHECK_RESULT(MPI_Issend, 1454 (const_cast<T*>(values), n, 1455 get_mpi_datatype<T>(*values), 1456 dest, tag, MPI_Comm(*this), &req.m_requests[0])); 1457 } else { 1292 1458 BOOST_MPI_CHECK_RESULT(MPI_Isend, 1293 1459 (const_cast<T*>(values), n, 1294 1460 get_mpi_datatype<T>(*values), 1295 1461 dest, tag, MPI_Comm(*this), &req.m_requests[0])); 1462 }; 1296 1463 return req; 1297 1464 } 1298 1465 1299 1466 template<typename T> 1300 1467 request 1301 1468 communicator::array_isend_impl(int dest, int tag, const T* values, int n, 1302 mpl::false_ ) const1469 mpl::false_, const bool synchronous) const 1303 1470 { 1304 1471 shared_ptr<packed_oarchive> archive(new packed_oarchive(*this)); 1305 1472 *archive << n << boost::serialization::make_array(values, n); 1306 request result = isend(dest, tag, *archive); 1473 request result = (synchronous? 1474 issend(dest, tag, *archive) 1475 : isend(dest, tag, *archive)); 1307 1476 result.m_data = archive; 1308 1477 return result; 1309 1478 } … … 1313 1482 template<typename T> 1314 1483 request communicator::isend(int dest, int tag, const T* values, int n) const 1315 1484 { 1316 return array_isend_impl(dest, tag, values, n, is_mpi_datatype<T>()); 1485 return array_isend_impl(dest, tag, values, n, is_mpi_datatype<T>(), false); 1486 } 1487 1488 // Array isend must send the elements directly 1489 template<typename T> 1490 request communicator::issend(int dest, int tag, const T* values, int n) const 1491 { 1492 return array_isend_impl(dest, tag, values, n, is_mpi_datatype<T>(), true); 1317 1493 } 1318 1494 1319 1495 namespace detail { … … 1615 1791 template<> 1616 1792 BOOST_MPI_DECL void 1617 1793 communicator::send<packed_skeleton_oarchive> 1618 (int dest, int tag, const packed_skeleton_oarchive& ar) const; 1794 (int dest, int tag, 1795 const packed_skeleton_oarchive& ar) const; 1619 1796 1620 1797 /** 1621 1798 * INTERNAL ONLY … … 1624 1801 BOOST_MPI_DECL void 1625 1802 communicator::send<content>(int dest, int tag, const content& c) const; 1626 1803 1804 1805 /** 1806 * INTERNAL ONLY 1807 */ 1808 template<> 1809 BOOST_MPI_DECL void 1810 communicator::ssend<packed_oarchive>(int dest, int tag, 1811 const packed_oarchive& ar) const; 1812 1813 /** 1814 * INTERNAL ONLY 1815 */ 1816 template<> 1817 BOOST_MPI_DECL void 1818 communicator::ssend<packed_skeleton_oarchive> 1819 (int dest, int tag, 1820 const packed_skeleton_oarchive& ar) const; 1821 1822 /** 1823 * INTERNAL ONLY 1824 */ 1825 template<> 1826 BOOST_MPI_DECL void 1827 communicator::ssend<content>(int dest, int tag, const content& c) const; 1828 1829 1627 1830 /** 1628 1831 * INTERNAL ONLY 1629 1832 */ … … 1664 1867 */ 1665 1868 template<> 1666 1869 BOOST_MPI_DECL request 1667 communicator::isend<packed_oarchive> (int dest, int tag,1668 1870 communicator::isend<packed_oarchive> 1871 (int dest, int tag, const packed_oarchive& ar) const; 1669 1872 1670 1873 /** 1671 1874 * INTERNAL ONLY … … 1684 1887 1685 1888 /** 1686 1889 * INTERNAL ONLY 1890 */ 1891 template<> 1892 BOOST_MPI_DECL request 1893 communicator::issend<packed_oarchive> 1894 (int dest, int tag, const packed_oarchive& ar) const; 1895 1896 /** 1897 * INTERNAL ONLY 1898 */ 1899 template<> 1900 BOOST_MPI_DECL request 1901 communicator::issend<packed_skeleton_oarchive> 1902 (int dest, int tag, const packed_skeleton_oarchive& ar) const; 1903 1904 /** 1905 * INTERNAL ONLY 1906 */ 1907 template<> 1908 BOOST_MPI_DECL request 1909 communicator::issend<content>(int dest, int tag, const content& c) const; 1910 1911 /** 1912 * INTERNAL ONLY 1687 1913 */ 1688 1914 template<> 1689 1915 BOOST_MPI_DECL request -
boost/mpi/detail/communicator_sc.hpp
diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/boost/mpi/detail/communicator_sc.hpp boost_1_45_0/boost/mpi/detail/communicator_sc.hpp
old new 15 15 16 16 template<typename T> 17 17 void 18 communicator::send(int dest, int tag, const skeleton_proxy<T>& proxy) const 18 communicator::send_impl(int dest, int tag, const skeleton_proxy<T>& proxy, 19 const bool synchronous) const 19 20 { 20 21 packed_skeleton_oarchive ar(*this); 21 22 ar << proxy.object; 23 if (synchronous) 24 ssend(dest, tag, ar); 25 else 22 26 send(dest, tag, ar); 23 27 } 24 28 25 29 template<typename T> 30 void 31 communicator::send(int dest, int tag, const skeleton_proxy<T>& proxy) const 32 { 33 send_impl(dest, tag, proxy, false); 34 } 35 36 template<typename T> 37 void 38 communicator::ssend(int dest, int tag, const skeleton_proxy<T>& proxy) const 39 { 40 send_impl(dest, tag, proxy, true); 41 } 42 43 template<typename T> 26 44 status 27 45 communicator::recv(int source, int tag, const skeleton_proxy<T>& proxy) const 28 46 { … … 43 61 44 62 template<typename T> 45 63 request 46 communicator::isend(int dest, int tag, const skeleton_proxy<T>& proxy) const 64 communicator::isend_impl(int dest, int tag, const skeleton_proxy<T>& proxy, 65 const bool synchronous) const 47 66 { 48 67 shared_ptr<packed_skeleton_oarchive> 49 68 archive(new packed_skeleton_oarchive(*this)); 50 69 51 70 *archive << proxy.object; 52 request result = isend(dest, tag, *archive); 71 request result = (synchronous? 72 issend(dest, tag, *archive) 73 : isend(dest, tag, *archive)); 53 74 result.m_data = archive; 54 75 return result; 55 76 } 56 77 78 template<typename T> 79 request 80 communicator::isend(int dest, int tag, const skeleton_proxy<T>& proxy) const 81 { 82 return isend_impl(dest, tag, proxy, false); 83 } 84 85 template<typename T> 86 request 87 communicator::issend(int dest, int tag, const skeleton_proxy<T>& proxy) const 88 { 89 return isend_impl(dest, tag, proxy, true); 90 } 91 57 92 namespace detail { 58 93 template<typename T> 59 94 struct serialized_irecv_data<const skeleton_proxy<T> > -
boost/mpi/detail/point_to_point.hpp
diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/boost/mpi/detail/point_to_point.hpp boost_1_45_0/boost/mpi/detail/point_to_point.hpp
old new 15 15 16 16 namespace boost { namespace mpi { namespace detail { 17 17 18 /** Sends a packed archive using MPI_Send . */18 /** Sends a packed archive using MPI_Send/MPI_Ssend. */ 19 19 BOOST_MPI_DECL void 20 20 packed_archive_send(MPI_Comm comm, int dest, int tag, 21 const packed_oarchive& ar); 21 const packed_oarchive& ar, 22 const bool synchronous = false); 22 23 23 /** Sends a packed archive using MPI_Isend .24 /** Sends a packed archive using MPI_Isend/MPI_Issend. 24 25 * 25 26 * This routine may split sends into multiple packets. The MPI_Request 26 27 * for each packet will be placed into the out_requests array, up to … … 32 33 BOOST_MPI_DECL int 33 34 packed_archive_isend(MPI_Comm comm, int dest, int tag, 34 35 const packed_oarchive& ar, 35 MPI_Request* out_requests, int num_out_requests); 36 MPI_Request* out_requests, int num_out_requests, 37 const bool synchronous = false); 36 38 37 39 /** 38 40 * \overload … … 40 42 BOOST_MPI_DECL int 41 43 packed_archive_isend(MPI_Comm comm, int dest, int tag, 42 44 const packed_iarchive& ar, 43 MPI_Request* out_requests, int num_out_requests); 45 MPI_Request* out_requests, int num_out_requests, 46 const bool synchronous = false); 44 47 45 48 /** Receives a packed archive using MPI_Recv. */ 46 49 BOOST_MPI_DECL void -
libs/mpi/src/broadcast.cpp
Only in boost_1_45_0: bootstrap.log diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/libs/mpi/src/broadcast.cpp boost_1_45_0/libs/mpi/src/broadcast.cpp
old new 35 35 if (dest != root) { 36 36 // Build up send requests for each child send. 37 37 num_requests += detail::packed_archive_isend(comm, dest, tag, oa, 38 &requests[num_requests], 2 );38 &requests[num_requests], 2, false); 39 39 } 40 40 } 41 41 … … 76 76 // Build up send requests for each child send. 77 77 num_requests += detail::packed_archive_isend(comm, dest, tag, ia, 78 78 &requests[num_requests], 79 2 );79 2, false); 80 80 } 81 81 } 82 82 -
libs/mpi/src/communicator.cpp
diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/libs/mpi/src/communicator.cpp boost_1_45_0/libs/mpi/src/communicator.cpp
old new 94 94 dest, tag, MPI_Comm(*this))); 95 95 } 96 96 97 void communicator::ssend(int dest, int tag) const 98 { 99 BOOST_MPI_CHECK_RESULT(MPI_Ssend, 100 (MPI_BOTTOM, 0, MPI_PACKED, 101 dest, tag, MPI_Comm(*this))); 102 } 103 97 104 status communicator::recv(int source, int tag) const 98 105 { 99 106 status stat; … … 192 199 communicator::send<packed_oarchive>(int dest, int tag, 193 200 const packed_oarchive& ar) const 194 201 { 195 detail::packed_archive_send(MPI_Comm(*this), dest, tag, ar); 202 detail::packed_archive_send(MPI_Comm(*this), dest, tag, ar, false); 203 } 204 205 template<> 206 void 207 communicator::ssend<packed_oarchive>(int dest, int tag, 208 const packed_oarchive& ar) const 209 { 210 detail::packed_archive_send(MPI_Comm(*this), dest, tag, ar, true); 211 } 212 213 template<> 214 void 215 communicator::send<packed_skeleton_oarchive>(int dest, int tag, 216 const packed_skeleton_oarchive& ar) const 217 { 218 send(dest, tag, ar.get_skeleton()); 196 219 } 197 220 198 221 template<> 199 222 void 200 communicator::s end<packed_skeleton_oarchive>201 (int dest, int tag,const packed_skeleton_oarchive& ar) const223 communicator::ssend<packed_skeleton_oarchive>(int dest, int tag, 224 const packed_skeleton_oarchive& ar) const 202 225 { 203 this->send(dest, tag, ar.get_skeleton());226 ssend(dest, tag, ar.get_skeleton()); 204 227 } 205 228 206 229 template<> … … 212 235 } 213 236 214 237 template<> 238 void communicator::ssend<content>(int dest, int tag, const content& c) const 239 { 240 BOOST_MPI_CHECK_RESULT(MPI_Ssend, 241 (MPI_BOTTOM, 1, c.get_mpi_datatype(), 242 dest, tag, MPI_Comm(*this))); 243 } 244 245 template<> 215 246 status 216 247 communicator::recv<packed_iarchive>(int source, int tag, 217 248 packed_iarchive& ar) const … … 251 282 { 252 283 request req; 253 284 detail::packed_archive_isend(MPI_Comm(*this), dest, tag, ar, 254 &req.m_requests[0] ,2);285 &req.m_requests[0], 2, false); 255 286 return req; 256 287 } 257 288 258 289 template<> 259 290 request 260 communicator::is end<packed_skeleton_oarchive>261 (int dest, int tag, const packed_skeleton_oarchive& ar) const291 communicator::issend<packed_oarchive>(int dest, int tag, 292 const packed_oarchive& ar) const 262 293 { 263 return this->isend(dest, tag, ar.get_skeleton()); 294 request req; 295 detail::packed_archive_isend(MPI_Comm(*this), dest, tag, ar, 296 &req.m_requests[0], 2, true); 297 return req; 298 } 299 300 template<> 301 request 302 communicator::isend<packed_skeleton_oarchive>(int dest, int tag, 303 const packed_skeleton_oarchive& ar) const 304 { 305 return isend(dest, tag, ar.get_skeleton()); 306 } 307 308 template<> 309 request 310 communicator::issend<packed_skeleton_oarchive>(int dest, int tag, 311 const packed_skeleton_oarchive& ar) const 312 { 313 return issend(dest, tag, ar.get_skeleton()); 264 314 } 265 315 266 316 template<> … … 273 323 return req; 274 324 } 275 325 326 template<> 327 request communicator::issend<content>(int dest, int tag, const content& c) const 328 { 329 request req; 330 BOOST_MPI_CHECK_RESULT(MPI_Issend, 331 (MPI_BOTTOM, 1, c.get_mpi_datatype(), 332 dest, tag, MPI_Comm(*this), &req.m_requests[0])); 333 return req; 334 } 335 276 336 request communicator::isend(int dest, int tag) const 277 337 { 278 338 request req; … … 280 340 (MPI_BOTTOM, 0, MPI_PACKED, 281 341 dest, tag, MPI_Comm(*this), &req.m_requests[0])); 282 342 return req; 343 } 344 345 request communicator::issend(int dest, int tag) const 346 { 347 request req; 348 BOOST_MPI_CHECK_RESULT(MPI_Issend, 349 (MPI_BOTTOM, 0, MPI_PACKED, 350 dest, tag, MPI_Comm(*this), &req.m_requests[0])); 351 return req; 283 352 } 284 353 285 354 template<> -
libs/mpi/src/point_to_point.cpp
diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/libs/mpi/src/point_to_point.cpp boost_1_45_0/libs/mpi/src/point_to_point.cpp
old new 26 26 27 27 void 28 28 packed_archive_send(MPI_Comm comm, int dest, int tag, 29 const packed_oarchive& ar) 29 const packed_oarchive& ar, 30 const bool synchronous) 30 31 { 31 32 const void* size = &ar.size(); 33 // size and content are sent in separate messages: since we only 34 // need a guarantee that the *content* has arrived when a 35 // synchronous call is done, we can send the content with MPI_Ssend 36 // and use a "standard send" for the size. 32 37 BOOST_MPI_CHECK_RESULT(MPI_Send, 33 38 (const_cast<void*>(size), 1, 34 39 get_mpi_datatype<std::size_t>(ar.size()), 35 40 dest, tag, comm)); 41 if (synchronous) { 42 BOOST_MPI_CHECK_RESULT(MPI_Ssend, 43 (const_cast<void*>(ar.address()), ar.size(), 44 MPI_PACKED, 45 dest, tag, comm)); 46 } else { 36 47 BOOST_MPI_CHECK_RESULT(MPI_Send, 37 48 (const_cast<void*>(ar.address()), ar.size(), 38 49 MPI_PACKED, 39 50 dest, tag, comm)); 51 }; 40 52 } 41 53 42 54 int 43 55 packed_archive_isend(MPI_Comm comm, int dest, int tag, 44 56 const packed_oarchive& ar, 45 MPI_Request* out_requests, int num_out_requests) 57 MPI_Request* out_requests, int num_out_requests, 58 const bool synchronous) 46 59 { 47 60 assert(num_out_requests >= 2); 48 61 const void* size = &ar.size(); 62 // size and content are sent in separate messages: since we only 63 // need a guarantee that the *content* has arrived when a 64 // synchronous call is done, we can send the content with MPI_Ssend 65 // and use a "standard send" for the size. 49 66 BOOST_MPI_CHECK_RESULT(MPI_Isend, 50 67 (const_cast<void*>(size), 1, 51 68 get_mpi_datatype<std::size_t>(ar.size()), 52 69 dest, tag, comm, out_requests)); 70 if (synchronous) { 71 BOOST_MPI_CHECK_RESULT(MPI_Issend, 72 (const_cast<void*>(ar.address()), ar.size(), 73 MPI_PACKED, 74 dest, tag, comm, out_requests + 1)); 75 } else { 53 76 BOOST_MPI_CHECK_RESULT(MPI_Isend, 54 77 (const_cast<void*>(ar.address()), ar.size(), 55 78 MPI_PACKED, 56 79 dest, tag, comm, out_requests + 1)); 80 }; 57 81 58 82 return 2; 59 83 } … … 61 85 int 62 86 packed_archive_isend(MPI_Comm comm, int dest, int tag, 63 87 const packed_iarchive& ar, 64 MPI_Request* out_requests, int num_out_requests) 88 MPI_Request* out_requests, int num_out_requests, 89 const bool synchronous) 65 90 { 66 91 assert(num_out_requests >= 2); 67 92 68 93 const void* size = &ar.size(); 94 // size and content are sent in separate messages: since we only 95 // need a guarantee that the *content* has arrived when a 96 // synchronous call is done, we can send the content with MPI_Ssend 97 // and use a "standard send" for the size. 69 98 BOOST_MPI_CHECK_RESULT(MPI_Isend, 70 99 (const_cast<void*>(size), 1, 71 100 get_mpi_datatype<std::size_t>(ar.size()), 72 101 dest, tag, comm, out_requests)); 102 if (synchronous) { 103 BOOST_MPI_CHECK_RESULT(MPI_Issend, 104 (const_cast<void*>(ar.address()), ar.size(), 105 MPI_PACKED, 106 dest, tag, comm, out_requests + 1)); 107 } else { 73 108 BOOST_MPI_CHECK_RESULT(MPI_Isend, 74 109 (const_cast<void*>(ar.address()), ar.size(), 75 110 MPI_PACKED, 76 111 dest, tag, comm, out_requests + 1)); 112 }; 77 113 78 114 return 2; 79 115 } -
libs/mpi/test/nonblocking_test.cpp
diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/libs/mpi/test/nonblocking_test.cpp boost_1_45_0/libs/mpi/test/nonblocking_test.cpp
old new 41 41 "test_some (keep results)" 42 42 }; 43 43 44 enum synch_behavior { synch_no, synch_yes, synch_both }; 45 44 46 45 47 template<typename T> 46 48 void 47 49 nonblocking_test(const communicator& comm, const T* values, int num_values, 48 const char* kind, method_kind method = mk_all) 50 const char* kind, method_kind method = mk_all, 51 synch_behavior synch = synch_both) 49 52 { 50 53 using boost::mpi::wait_any; 51 54 using boost::mpi::test_any; … … 54 57 using boost::mpi::wait_some; 55 58 using boost::mpi::test_some; 56 59 60 if (synch == synch_both) { 61 nonblocking_test(comm, values, num_values, kind, method, synch_no); 62 nonblocking_test(comm, values, num_values, kind, method, synch_yes); 63 return; 64 }; 65 const bool synchronous = (synch == synch_yes); 66 57 67 if (method == mk_all || method == mk_all_except_test_all) { 58 nonblocking_test(comm, values, num_values, kind, mk_wait_any );59 nonblocking_test(comm, values, num_values, kind, mk_test_any );60 nonblocking_test(comm, values, num_values, kind, mk_wait_all );61 nonblocking_test(comm, values, num_values, kind, mk_wait_all_keep );68 nonblocking_test(comm, values, num_values, kind, mk_wait_any, synch); 69 nonblocking_test(comm, values, num_values, kind, mk_test_any, synch); 70 nonblocking_test(comm, values, num_values, kind, mk_wait_all, synch); 71 nonblocking_test(comm, values, num_values, kind, mk_wait_all_keep, synch); 62 72 if (method == mk_all) { 63 nonblocking_test(comm, values, num_values, kind, mk_test_all );64 nonblocking_test(comm, values, num_values, kind, mk_test_all_keep );73 nonblocking_test(comm, values, num_values, kind, mk_test_all, synch); 74 nonblocking_test(comm, values, num_values, kind, mk_test_all_keep, synch); 65 75 } 66 nonblocking_test(comm, values, num_values, kind, mk_wait_some );67 nonblocking_test(comm, values, num_values, kind, mk_wait_some_keep );68 nonblocking_test(comm, values, num_values, kind, mk_test_some );69 nonblocking_test(comm, values, num_values, kind, mk_test_some_keep );76 nonblocking_test(comm, values, num_values, kind, mk_wait_some, synch); 77 nonblocking_test(comm, values, num_values, kind, mk_wait_some_keep, synch); 78 nonblocking_test(comm, values, num_values, kind, mk_test_some, synch); 79 nonblocking_test(comm, values, num_values, kind, mk_test_some_keep, synch); 70 80 } else { 81 71 82 if (comm.rank() == 0) { 72 83 std::cout << "Testing " << method_kind_names[method] 73 << " with " << kind << "..."; 84 << " with " << kind 85 << (synchronous ? " (ssend) " : "") 86 << "..."; 74 87 std::cout.flush(); 75 88 } 76 89 … … 82 95 83 96 std::vector<request> reqs; 84 97 // Send/receive the first value 85 reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 0, values[0]));86 98 reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), 87 99 0, incoming_value)); 100 if (synchronous) 101 reqs.push_back(comm.issend((comm.rank() + 1) % comm.size(), 0, values[0])); 102 else 103 reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 0, values[0])); 104 88 105 89 106 if (method != mk_wait_any && method != mk_test_any) { 90 107 #ifndef LAM_MPI … … 94 111 // when using shared memory, not TCP. 95 112 96 113 // Send/receive an empty message 114 if (synchronous) 115 reqs.push_back(comm.issend((comm.rank() + 1) % comm.size(), 1)); 116 else 97 117 reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 1)); 98 118 reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), 99 119 1)); 100 120 #endif 101 121 102 122 // Send/receive an array 123 if (synchronous) 124 reqs.push_back(comm.issend((comm.rank() + 1) % comm.size(), 2, values, 125 num_values)); 126 else 103 127 reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 2, values, 104 128 num_values)); 105 129 reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), … … 121 145 result = test_any(reqs.begin(), reqs.end()); 122 146 } while (!result); 123 147 if (result->second == reqs.begin()) 124 reqs[1].wait(); 148 reqs[1].wait(); // wait for the isend() 125 149 else 126 reqs[0].wait(); 127 break; 150 reqs[0].wait(); // wait for the irecv() 128 151 } 152 break; 129 153 130 154 case mk_wait_all: 131 155 wait_all(reqs.begin(), reqs.end()); -
libs/mpi/test/skeleton_content_test.cpp
diff -ruw -x '*~' -x '*.o' -x '*.a' boost_1_45_0.orig/libs/mpi/test/skeleton_content_test.cpp boost_1_45_0/libs/mpi/test/skeleton_content_test.cpp
old new 23 23 24 24 void 25 25 test_skeleton_and_content(const communicator& comm, int root, 26 bool manual_broadcast )26 bool manual_broadcast, bool synchronous) 27 27 { 28 28 using boost::mpi::skeleton; 29 29 using boost::mpi::content; … … 41 41 original_list.push_back(i); 42 42 43 43 std::cout << "Broadcasting integer list skeleton from root " << root 44 << (synchronous and manual_broadcast? " (ssend) " : "") 44 45 << "..."; 45 46 if (manual_broadcast) { 46 47 // Broadcast the skeleton (manually) 47 48 for (int p = 0; p < comm.size(); ++p) 48 if (p != root) comm.send(p, 0, skeleton(original_list)); 49 if (p != root) { 50 if (synchronous) 51 comm.ssend(p, 0, skeleton(original_list)); 52 else 53 comm.send(p, 0, skeleton(original_list)); 54 }; 49 55 } else { 50 56 broadcast(comm, skeleton(original_list), root); 51 57 } … … 53 59 54 60 // Broadcast the content (manually) 55 61 std::cout << "Broadcasting integer list content from root " << root 56 << "...";62 << (synchronous? " (ssend) " : "") << "..."; 57 63 { 58 64 content c = get_content(original_list); 59 65 for (int p = 0; p < comm.size(); ++p) 60 if (p != root) comm.send(p, 1, c); 66 if (p != root) { 67 if (synchronous) 68 comm.ssend(p, 1, c); 69 else 70 comm.send(p, 1, c); 71 }; 61 72 } 62 73 std::cout << "OK." << std::endl; 63 74 64 75 // Reverse the list, broadcast the content again 65 76 std::reverse(original_list.begin(), original_list.end()); 66 77 std::cout << "Broadcasting reversed integer list content from root " 67 << root << "...";78 << root << (synchronous? " (ssend) " : "") << "..."; 68 79 { 69 80 content c = get_content(original_list); 70 81 for (int p = 0; p < comm.size(); ++p) 71 if (p != root) comm.send(p, 2, c); 82 if (p != root) { 83 if (synchronous) 84 comm.ssend(p, 2, c); 85 else 86 comm.send(p, 2, c); 87 }; 72 88 } 73 89 std::cout << "OK." << std::endl; 74 90 } else { … … 101 117 (comm.barrier)(); 102 118 } 103 119 120 104 121 void 105 test_skeleton_and_content_nonblocking(const communicator& comm, int root) 122 test_skeleton_and_content_nonblocking(const communicator& comm, int root, 123 bool synchronous) 106 124 { 107 125 using boost::mpi::skeleton; 108 126 using boost::mpi::content; … … 122 140 original_list.push_back(i); 123 141 124 142 std::cout << "Non-blocking broadcast of integer list skeleton from root " << root 143 << (synchronous? " (ssend) " : "") 125 144 << "..."; 126 145 127 146 // Broadcast the skeleton (manually) 128 147 { 129 148 std::vector<request> reqs; 130 149 for (int p = 0; p < comm.size(); ++p) 131 if (p != root) 150 if (p != root) { 151 if (synchronous) 152 reqs.push_back(comm.issend(p, 0, skeleton(original_list))); 153 else 132 154 reqs.push_back(comm.isend(p, 0, skeleton(original_list))); 155 }; 133 156 wait_all(reqs.begin(), reqs.end()); 134 157 } 135 158 std::cout << "OK." << std::endl; 136 159 137 160 // Broadcast the content (manually) 138 161 std::cout << "Non-blocking broadcast of integer list content from root " << root 162 << (synchronous? " (ssend) " : "") 139 163 << "..."; 140 164 { 141 165 content c = get_content(original_list); 142 166 std::vector<request> reqs; 143 167 for (int p = 0; p < comm.size(); ++p) 144 if (p != root) reqs.push_back(comm.isend(p, 1, c)); 168 if (p != root) { 169 if (synchronous) 170 reqs.push_back(comm.issend(p, 1, c)); 171 else 172 reqs.push_back(comm.isend(p, 1, c)); 173 }; 145 174 wait_all(reqs.begin(), reqs.end()); 146 175 } 147 176 std::cout << "OK." << std::endl; … … 149 178 // Reverse the list, broadcast the content again 150 179 std::reverse(original_list.begin(), original_list.end()); 151 180 std::cout << "Non-blocking broadcast of reversed integer list content from root " 181 << (synchronous? " (ssend) " : "") 152 182 << root << "..."; 153 183 { 154 184 std::vector<request> reqs; 155 185 content c = get_content(original_list); 156 186 for (int p = 0; p < comm.size(); ++p) 157 if (p != root) reqs.push_back(comm.isend(p, 2, c)); 187 if (p != root) { 188 if (synchronous) 189 reqs.push_back(comm.issend(p, 2, c)); 190 else 191 reqs.push_back(comm.isend(p, 2, c)); 192 }; 158 193 wait_all(reqs.begin(), reqs.end()); 159 194 } 160 195 std::cout << "OK." << std::endl; … … 199 234 MPI_Abort(comm, -1); 200 235 } 201 236 202 test_skeleton_and_content(comm, 0, true); 203 test_skeleton_and_content(comm, 0, false); 204 test_skeleton_and_content(comm, 1, true); 205 test_skeleton_and_content(comm, 1, false); 206 test_skeleton_and_content_nonblocking(comm, 0); 207 test_skeleton_and_content_nonblocking(comm, 1); 237 // non-synchronous 238 test_skeleton_and_content(comm, 0, true, false); 239 test_skeleton_and_content(comm, 0, false, false); 240 test_skeleton_and_content(comm, 1, true, false); 241 test_skeleton_and_content(comm, 1, false, false); 242 // synchronous 243 test_skeleton_and_content(comm, 0, true, true); 244 test_skeleton_and_content(comm, 0, false, true); 245 test_skeleton_and_content(comm, 1, true, true); 246 test_skeleton_and_content(comm, 1, false, true); 247 248 test_skeleton_and_content_nonblocking(comm, 0, false); 249 test_skeleton_and_content_nonblocking(comm, 1, false); 250 test_skeleton_and_content_nonblocking(comm, 0, true); 251 test_skeleton_and_content_nonblocking(comm, 1, true); 208 252 209 253 return 0; 210 254 }