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