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