• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // (C) Copyright 2006 Douglas Gregor <doug.gregor -at- gmail.com>
2 
3 // Use, modification and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 //  Authors: Douglas Gregor
8 
9 /** @file status.cpp
10  *
11  *  This file reflects the Boost.MPI @c status class into
12  *  Python.
13  */
14 #include <boost/python.hpp>
15 #include <boost/mpi.hpp>
16 #include <boost/mpi/python/serialize.hpp>
17 
18 using namespace boost::python;
19 using namespace boost::mpi;
20 
21 namespace boost { namespace mpi { namespace python {
22 
23 extern const char* all_gather_docstring;
24 extern const char* all_reduce_docstring;
25 extern const char* all_to_all_docstring;
26 extern const char* broadcast_docstring;
27 extern const char* gather_docstring;
28 extern const char* reduce_docstring;
29 extern const char* scan_docstring;
30 extern const char* scatter_docstring;
31 
all_gather(const communicator & comm,object value)32 object all_gather(const communicator& comm, object value)
33 {
34   std::vector<object> values;
35   boost::mpi::all_gather(comm, value, values);
36 
37   boost::python::list l;
38   for (int i = 0; i < comm.size(); ++i)
39     l.append(values[i]);
40   return boost::python::tuple(l);
41 }
42 
all_to_all(const communicator & comm,object in_values)43 object all_to_all(const communicator& comm, object in_values)
44 {
45   // Build input values
46   std::vector<object> in_values_vec(comm.size());
47   object iterator = object(handle<>(PyObject_GetIter(in_values.ptr())));
48   for (int i = 0; i < comm.size(); ++i)
49     in_values_vec[i] = object(handle<>(PyIter_Next(iterator.ptr())));
50 
51   std::vector<object> out_values_vec(comm.size());
52   boost::mpi::all_to_all(comm, in_values_vec, out_values_vec);
53 
54   boost::python::list l;
55   for (int i = 0; i < comm.size(); ++i)
56     l.append(out_values_vec[i]);
57   return boost::python::tuple(l);
58 }
59 
broadcast(const communicator & comm,object value,int root)60 object broadcast(const communicator& comm, object value, int root)
61 {
62   boost::mpi::broadcast(comm, value, root);
63   return value;
64 }
65 
gather(const communicator & comm,object value,int root)66 object gather(const communicator& comm, object value, int root)
67 {
68   if (comm.rank() == root) {
69     std::vector<object> values;
70     boost::mpi::gather(comm, value, values, root);
71 
72     boost::python::list l;
73     for (int i = 0; i < comm.size(); ++i)
74       l.append(values[i]);
75     return boost::python::tuple(l);
76   } else {
77     boost::mpi::gather(comm, value, root);
78     return object();
79   }
80 }
81 
reduce(const communicator & comm,object value,object op,int root)82 object reduce(const communicator& comm, object value, object op, int root)
83 {
84   if (comm.rank() == root) {
85     object out_value;
86     boost::mpi::reduce(comm, value, out_value, op, root);
87     return out_value;
88   } else {
89     boost::mpi::reduce(comm, value, op, root);
90     return object();
91   }
92 }
93 
scatter(const communicator & comm,object values,int root)94 object scatter(const communicator& comm, object values, int root)
95 {
96   object result;
97 
98   if (comm.rank() == root) {
99     std::vector<object> values_vec(comm.size());
100     object iterator = object(handle<>(PyObject_GetIter(values.ptr())));
101     for (int i = 0; i < comm.size(); ++i)
102       values_vec[i] = object(handle<>(PyIter_Next(iterator.ptr())));
103 
104     boost::mpi::scatter(comm, values_vec, result, root);
105   } else {
106     boost::mpi::scatter(comm, result, root);
107   }
108   return result;
109 }
110 
export_collectives()111 void export_collectives()
112 {
113   using boost::python::arg;
114 
115   def("all_reduce",
116       (object (*)(const communicator&, const object&, object))&all_reduce,
117       (arg("comm") = communicator(), arg("value"), arg("op")),
118       all_reduce_docstring);
119   def("all_gather", &all_gather,
120       (arg("comm") = communicator(), arg("value") = object()),
121       all_gather_docstring);
122   def("all_to_all", &all_to_all,
123       (arg("comm") = communicator(), arg("values") = object()),
124       all_to_all_docstring);
125   def("broadcast", &broadcast,
126       (arg("comm") = communicator(), arg("value") = object(), arg("root")),
127       broadcast_docstring);
128   def("gather", &gather,
129       (arg("comm") = communicator(), arg("value") = object(), arg("root")),
130       gather_docstring);
131   def("reduce", &reduce,
132       (arg("comm") = communicator(), arg("value"), arg("op"),
133        arg("root")),
134       reduce_docstring);
135   def("scan",
136       (object (*)(const communicator&, const object&, object))&scan,
137       (arg("comm") = communicator(), arg("value"), arg("op")),
138       scan_docstring);
139   def("scatter", &scatter,
140       (arg("comm") = communicator(), arg("values") = object(), arg("root")),
141       scatter_docstring);
142 }
143 
144 } } } // end namespace boost::mpi::python
145