[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
# Copyright (C) 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)
# Test all_gather() collective.
import boost.parallel.mpi as mpi
from generators import *
def all_gather_test(comm, generator, kind):
if comm.rank == 0: print ("Gathering %s..." % (kind,)),
my_value = generator(comm.rank)
result = mpi.all_gather(comm, my_value)
for p in range(0, comm.size):
assert result[p] == generator(p)
if comm.rank == 0: print "OK."
return
all_gather_test(mpi.world, int_generator, "integers")
all_gather_test(mpi.world, gps_generator, "GPS positions")
all_gather_test(mpi.world, string_generator, "strings")
all_gather_test(mpi.world, string_list_generator, "list of strings")

View File

@@ -0,0 +1,29 @@
# Copyright (C) 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)
# Test all_reduce() collective.
import boost.parallel.mpi as mpi
from generators import *
def all_reduce_test(comm, generator, kind, op, op_kind):
if comm.rank == 0:
print ("Reducing to %s of %s..." % (op_kind, kind)),
my_value = generator(comm.rank)
result = mpi.all_reduce(comm, my_value, op)
expected_result = generator(0);
for p in range(1, comm.size):
expected_result = op(expected_result, generator(p))
assert result == expected_result
if comm.rank == 0:
print "OK."
return
all_reduce_test(mpi.world, int_generator, "integers", lambda x,y:x + y, "sum")
all_reduce_test(mpi.world, int_generator, "integers", lambda x,y:x * y, "product")
all_reduce_test(mpi.world, string_generator, "strings", lambda x,y:x + y, "concatenation")
all_reduce_test(mpi.world, string_list_generator, "list of strings", lambda x,y:x + y, "concatenation")

View File

@@ -0,0 +1,30 @@
# Copyright (C) 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)
# Test all_to_all() collective.
import boost.parallel.mpi as mpi
from generators import *
def all_to_all_test(comm, generator, kind):
if comm.rank == 0:
print ("All-to-all transmission of %s..." % (kind,)),
values = list()
for p in range(0, comm.size):
values.append(generator(p))
result = mpi.all_to_all(comm, values)
for p in range(0, comm.size):
assert result[p] == generator(comm.rank)
if comm.rank == 0: print "OK."
return
all_to_all_test(mpi.world, int_generator, "integers")
all_to_all_test(mpi.world, gps_generator, "GPS positions")
all_to_all_test(mpi.world, string_generator, "strings")
all_to_all_test(mpi.world, string_list_generator, "list of strings")

View File

@@ -0,0 +1,29 @@
# Copyright (C) 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)
# Test broadcast() collective.
import boost.parallel.mpi as mpi
def broadcast_test(comm, value, kind, root):
if comm.rank == root:
print ("Broadcasting %s from root %d..." % (kind, root)),
got_value = mpi.broadcast(comm, value, root)
assert got_value == value
if comm.rank == root:
print "OK."
return
broadcast_test(mpi.world, 17, 'integer', 0)
broadcast_test(mpi.world, 17, 'integer', 1)
broadcast_test(mpi.world, 'Hello, World!', 'string', 0)
broadcast_test(mpi.world, 'Hello, World!', 'string', 1)
broadcast_test(mpi.world, ['Hello', 'MPI', 'Python', 'World'],
'list of strings', 0)
broadcast_test(mpi.world, ['Hello', 'MPI', 'Python', 'World'],
'list of strings', 1)

View File

@@ -0,0 +1,32 @@
# Copyright (C) 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)
# Test gather() collective.
import boost.parallel.mpi as mpi
from generators import *
def gather_test(comm, generator, kind, root):
if comm.rank == root:
print ("Gathering %s to root %d..." % (kind, root)),
my_value = generator(comm.rank)
result = mpi.gather(comm, my_value, root)
if comm.rank == root:
for p in range(0, comm.size):
assert result[p] == generator(p)
print "OK."
else:
assert result == None
return
gather_test(mpi.world, int_generator, "integers", 0)
gather_test(mpi.world, int_generator, "integers", 1)
gather_test(mpi.world, gps_generator, "GPS positions", 0)
gather_test(mpi.world, gps_generator, "GPS positions", 1)
gather_test(mpi.world, string_generator, "strings", 0)
gather_test(mpi.world, string_generator, "strings", 1)
gather_test(mpi.world, string_list_generator, "list of strings", 0)
gather_test(mpi.world, string_list_generator, "list of strings", 1)

View File

@@ -0,0 +1,23 @@
# Copyright (C) 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)
# Value generators used in the Boost.MPI Python regression tests
def int_generator(p):
return 17 + p
def gps_generator(p):
return (39 + p, 16, 20.2799)
def string_generator(p):
result = "%d rosebud" % p;
if p != 1: result = result + 's'
return result
def string_list_generator(p):
result = list()
for i in range(0,p):
result.append(str(i))
return result

View File

@@ -0,0 +1,131 @@
# (C) Copyright 2007
# Andreas Kloeckner <inform -at- tiker.net>
#
# 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: Andreas Kloeckner
import boost.mpi as mpi
import random
import sys
MAX_GENERATIONS = 20
TAG_DEBUG = 0
TAG_DATA = 1
TAG_TERMINATE = 2
TAG_PROGRESS_REPORT = 3
class TagGroupListener:
"""Class to help listen for only a given set of tags.
This is contrived: Typicallly you could just listen for
mpi.any_tag and filter."""
def __init__(self, comm, tags):
self.tags = tags
self.comm = comm
self.active_requests = {}
def wait(self):
for tag in self.tags:
if tag not in self.active_requests:
self.active_requests[tag] = self.comm.irecv(tag=tag)
requests = mpi.RequestList(self.active_requests.values())
data, status, index = mpi.wait_any(requests)
del self.active_requests[status.tag]
return status, data
def cancel(self):
for r in self.active_requests.itervalues():
r.cancel()
#r.wait()
self.active_requests = {}
def rank0():
sent_histories = (mpi.size-1)*15
print "sending %d packets on their way" % sent_histories
send_reqs = mpi.RequestList()
for i in range(sent_histories):
dest = random.randrange(1, mpi.size)
send_reqs.append(mpi.world.isend(dest, TAG_DATA, []))
mpi.wait_all(send_reqs)
completed_histories = []
progress_reports = {}
dead_kids = []
tgl = TagGroupListener(mpi.world,
[TAG_DATA, TAG_DEBUG, TAG_PROGRESS_REPORT, TAG_TERMINATE])
def is_complete():
for i in progress_reports.values():
if i != sent_histories:
return False
return len(dead_kids) == mpi.size-1
while True:
status, data = tgl.wait()
if status.tag == TAG_DATA:
#print "received completed history %s from %d" % (data, status.source)
completed_histories.append(data)
if len(completed_histories) == sent_histories:
print "all histories received, exiting"
for rank in range(1, mpi.size):
mpi.world.send(rank, TAG_TERMINATE, None)
elif status.tag == TAG_PROGRESS_REPORT:
progress_reports[len(data)] = progress_reports.get(len(data), 0) + 1
elif status.tag == TAG_DEBUG:
print "[DBG %d] %s" % (status.source, data)
elif status.tag == TAG_TERMINATE:
dead_kids.append(status.source)
else:
print "unexpected tag %d from %d" % (status.tag, status.source)
if is_complete():
break
print "OK"
def comm_rank():
while True:
data, status = mpi.world.recv(return_status=True)
if status.tag == TAG_DATA:
mpi.world.send(0, TAG_PROGRESS_REPORT, data)
data.append(mpi.rank)
if len(data) >= MAX_GENERATIONS:
dest = 0
else:
dest = random.randrange(1, mpi.size)
mpi.world.send(dest, TAG_DATA, data)
elif status.tag == TAG_TERMINATE:
from time import sleep
mpi.world.send(0, TAG_TERMINATE, 0)
break
else:
print "[DIRECTDBG %d] unexpected tag %d from %d" % (mpi.rank, status.tag, status.source)
def main():
# this program sends around messages consisting of lists of visited nodes
# randomly. After MAX_GENERATIONS, they are returned to rank 0.
if mpi.rank == 0:
rank0()
else:
comm_rank()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,31 @@
# Copyright (C) 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)
# Test reduce() collective.
import boost.parallel.mpi as mpi
from generators import *
def reduce_test(comm, generator, kind, op, op_kind, root):
if comm.rank == root:
print ("Reducing to %s of %s at root %d..." % (op_kind, kind, root)),
my_value = generator(comm.rank)
result = mpi.reduce(comm, my_value, op, root)
if comm.rank == root:
expected_result = generator(0);
for p in range(1, comm.size):
expected_result = op(expected_result, generator(p))
assert result == expected_result
print "OK."
else:
assert result == None
return
reduce_test(mpi.world, int_generator, "integers", lambda x,y:x + y, "sum", 0)
reduce_test(mpi.world, int_generator, "integers", lambda x,y:x * y, "product", 1)
reduce_test(mpi.world, int_generator, "integers", min, "minimum", 0)
reduce_test(mpi.world, string_generator, "strings", lambda x,y:x + y, "concatenation", 0)
reduce_test(mpi.world, string_list_generator, "list of strings", lambda x,y:x + y, "concatenation", 0)

View File

@@ -0,0 +1,42 @@
# Copyright (C) 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)
# Test basic communication.
import boost.parallel.mpi as mpi
def ring_test(comm, value, kind, root):
next_peer = (comm.rank + 1) % comm.size;
prior_peer = (comm.rank + comm.size - 1) % comm.size;
if comm.rank == root:
print ("Passing %s around a ring from root %d..." % (kind, root)),
comm.send(next_peer, 0, value)
(other_value, stat) = comm.recv(return_status = True)
assert value == other_value
assert stat.source == prior_peer
assert stat.tag == 0
else:
msg = comm.probe()
other_value = comm.recv(msg.source, msg.tag)
assert value == other_value
comm.send(next_peer, 0, other_value)
comm.barrier()
if comm.rank == root:
print "OK"
pass
if mpi.world.size < 2:
print "ERROR: ring_test.py must be executed with more than one process"
mpi.world.abort(-1);
ring_test(mpi.world, 17, 'integers', 0)
ring_test(mpi.world, 17, 'integers', 1)
ring_test(mpi.world, 'Hello, World!', 'string', 0)
ring_test(mpi.world, 'Hello, World!', 'string', 1)
ring_test(mpi.world, ['Hello', 'MPI', 'Python', 'World'], 'list of strings', 0)
ring_test(mpi.world, ['Hello', 'MPI', 'Python', 'World'], 'list of strings', 1)

View File

@@ -0,0 +1,29 @@
# Copyright (C) 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)
# Test scan() collective.
import boost.parallel.mpi as mpi
from generators import *
def scan_test(comm, generator, kind, op, op_kind):
if comm.rank == 0:
print ("Prefix reduction to %s of %s..." % (op_kind, kind)),
my_value = generator(comm.rank)
result = mpi.scan(comm, my_value, op)
expected_result = generator(0);
for p in range(1, comm.rank+1):
expected_result = op(expected_result, generator(p))
assert result == expected_result
if comm.rank == 0:
print "OK."
return
scan_test(mpi.world, int_generator, "integers", lambda x,y:x + y, "sum")
scan_test(mpi.world, int_generator, "integers", lambda x,y:x * y, "product")
scan_test(mpi.world, string_generator, "strings", lambda x,y:x + y, "concatenation")
scan_test(mpi.world, string_list_generator, "list of strings", lambda x,y:x + y, "concatenation")

View File

@@ -0,0 +1,36 @@
# Copyright (C) 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)
# Test scatter() collective.
import boost.parallel.mpi as mpi
from generators import *
def scatter_test(comm, generator, kind, root):
if comm.rank == root:
print ("Scattering %s from root %d..." % (kind, root)),
if comm.rank == root:
values = list()
for p in range(0, comm.size):
values.append(generator(p))
result = mpi.scatter(comm, values, root = root)
else:
result = mpi.scatter(comm, root = root);
assert result == generator(comm.rank)
if comm.rank == root: print "OK."
return
scatter_test(mpi.world, int_generator, "integers", 0)
scatter_test(mpi.world, int_generator, "integers", 1)
scatter_test(mpi.world, gps_generator, "GPS positions", 0)
scatter_test(mpi.world, gps_generator, "GPS positions", 1)
scatter_test(mpi.world, string_generator, "strings", 0)
scatter_test(mpi.world, string_generator, "strings", 1)
scatter_test(mpi.world, string_list_generator, "list of strings", 0)
scatter_test(mpi.world, string_list_generator, "list of strings", 1)

View File

@@ -0,0 +1,37 @@
// (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
#include <boost/parallel/mpi/python.hpp>
#include <boost/python.hpp>
#include <boost/serialization/list.hpp>
using namespace boost::python;
template<typename T>
boost::python::list list_to_python(const std::list<T>& value) {
boost::python::list result;
for (typename std::list<T>::const_iterator i = value.begin();
i != value.end(); ++i)
result.append(*i);
return result;
}
BOOST_PYTHON_MODULE(skeleton_content)
{
using boost::python::arg;
class_<std::list<int> >("list_int")
.def("push_back", &std::list<int>::push_back, arg("value"))
.def("pop_back", &std::list<int>::pop_back)
.def("reverse", &std::list<int>::reverse)
.def(boost::python::self == boost::python::self)
.def(boost::python::self != boost::python::self)
.add_property("size", &std::list<int>::size)
.def("to_python", &list_to_python<int>);
boost::parallel::mpi::python::register_skeleton_and_content<std::list<int> >();
}

View File

@@ -0,0 +1,75 @@
# Copyright (C) 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)
# Test skeleton/content
import boost.parallel.mpi as mpi
import skeleton_content
def test_skeleton_and_content(comm, root, manual_broadcast = True):
assert manual_broadcast
# Setup data
list_size = comm.size + 7
original_list = skeleton_content.list_int()
for i in range(0,list_size):
original_list.push_back(i)
if comm.rank == root:
# Broadcast skeleton
print ("Broadcasting integer list skeleton from root %d..." % (root)),
if manual_broadcast:
for p in range(0,comm.size):
if p != comm.rank:
comm.send(p, 0, value = mpi.skeleton(original_list))
print "OK."
# Broadcast content
print ("Broadcasting integer list content from root %d..." % (root)),
if manual_broadcast:
for p in range(0,comm.size):
if p != comm.rank:
comm.send(p, 0, value = mpi.get_content(original_list))
print "OK."
# Broadcast reversed content
original_list.reverse()
print ("Broadcasting reversed integer list content from root %d..." % (root)),
if manual_broadcast:
for p in range(0,comm.size):
if p != comm.rank:
comm.send(p, 0, value = mpi.get_content(original_list))
print "OK."
else:
# Allocate some useless data, to try to get the addresses of
# the underlying lists used later to be different across
# processors.
junk_list = skeleton_content.list_int()
for i in range(0,comm.rank * 3 + 1):
junk_list.push_back(i)
# Receive the skeleton of the list
if manual_broadcast:
transferred_list_skeleton = comm.recv(root, 0)
assert transferred_list_skeleton.object.size == list_size
# Receive the content and check it
transferred_list = transferred_list_skeleton.object
if manual_broadcast:
comm.recv(root, 0, mpi.get_content(transferred_list))
assert transferred_list == original_list
# Receive the content (again) and check it
original_list.reverse()
if manual_broadcast:
comm.recv(root, 0, mpi.get_content(transferred_list))
assert transferred_list == original_list
test_skeleton_and_content(mpi.world, 0)
test_skeleton_and_content(mpi.world, 1)