Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPI version of SimpleCaseIterDriver #1962

Merged
merged 11 commits into from
Apr 9, 2015
34 changes: 19 additions & 15 deletions contrib/testmpi/test_distribcomp.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
from openmdao.main.api import Assembly, Component, set_as_top, Driver
from openmdao.main.datatypes.api import Float, Array
from openmdao.main.interfaces import implements, ISolver
from openmdao.main.mpiwrap import MPI, make_idx_array, to_idx_array, evenly_distrib_idxs
from openmdao.main.mpiwrap import MPI, make_idx_array, to_idx_array, \
evenly_distrib_idxs, MPIContext
from openmdao.main.test.simpledriver import SimpleDriver
from openmdao.test.execcomp import ExecComp
from openmdao.test.mpiunittest import MPITestCase, MPIContext
from openmdao.test.mpiunittest import MPITestCase
from openmdao.util.testutil import assert_rel_error

def take_nth(rank, size, seq):
Expand All @@ -38,7 +39,6 @@ class InOutArrayComp(Component):

def __init__(self, arr_size=10):
super(InOutArrayComp, self).__init__()
self.mpi.requested_cpus = 2

self.add_trait('invec', Array(np.ones(arr_size, float), iotype='in'))
self.add_trait('outvec', Array(np.ones(arr_size, float), iotype='out'))
Expand All @@ -51,7 +51,6 @@ class DistribCompSimple(Component):
"""Uses 2 procs but takes full input vars"""
def __init__(self, arr_size=10):
super(DistribCompSimple, self).__init__()
self.mpi.requested_cpus = 2

self.add_trait('invec', Array(np.ones(arr_size, float), iotype='in'))
self.add_trait('outvec', Array(np.ones(arr_size, float), iotype='out'))
Expand All @@ -73,7 +72,7 @@ def execute(self):
self.outvec = both[0,:] + both[1,:]

def get_req_cpus(self):
return 2
return (2, 2)


class DistribInputComp(Component):
Expand Down Expand Up @@ -102,7 +101,9 @@ def get_distrib_idxs(self):
comm = self.mpi.comm
rank = comm.rank

start, end, self.sizes, self.offsets = evenly_distrib_idxs(comm, self.arr_size)
self.sizes, self.offsets = evenly_distrib_idxs(comm.size, self.arr_size)
start = self.offsets[rank]
end = start + self.sizes[rank]

#need to re-initialize the variable to have the correct local size
self.invec = np.ones(self.sizes[rank], dtype=float)
Expand All @@ -114,7 +115,7 @@ def get_distrib_idxs(self):
}

def get_req_cpus(self):
return 2
return (2, 2)


class DistribOverlappingInputComp(Component):
Expand Down Expand Up @@ -168,7 +169,7 @@ def get_distrib_idxs(self):
}

def get_req_cpus(self):
return 2
return (2, 2)

class DistribInputDistribOutputComp(Component):
"""Uses 2 procs and takes input var slices and has output var slices as well"""
Expand All @@ -195,20 +196,20 @@ def get_distrib_idxs(self):
comm = self.mpi.comm
rank = comm.rank

start, end, sizes, offsets = evenly_distrib_idxs(comm, self.arr_size)
sizes, offsets = evenly_distrib_idxs(comm.size, self.arr_size)
start = offsets[rank]
end = start + sizes[rank]

self.invec = np.ones(sizes[rank], dtype=float)
self.outvec = np.ones(sizes[rank], dtype=float)

print self.name,".outvec",self.outvec

return {
'invec': make_idx_array(start, end),
'outvec': make_idx_array(start, end)
}

def get_req_cpus(self):
return 2
return (2, 2)

class DistribNoncontiguousComp(Component):
"""Uses 2 procs and takes non-contiguous input var slices and has output
Expand Down Expand Up @@ -247,7 +248,7 @@ def get_distrib_idxs(self):
}

def get_req_cpus(self):
return 2
return (2, 2)

class DistribGatherComp(Component):
"""Uses 2 procs gathers a distrib input into a full output"""
Expand All @@ -274,15 +275,18 @@ def get_distrib_idxs(self):
comm = self.mpi.comm
rank = comm.rank

start, end, self.sizes, self.offsets = evenly_distrib_idxs(comm, self.arr_size)
self.sizes, self.offsets = evenly_distrib_idxs(comm.size,
self.arr_size)
start = self.offsets[rank]
end = start + self.sizes[rank]

#need to re-initialize the variable to have the correct local size
self.invec = np.ones(self.sizes[comm.rank], dtype=float)

return { 'invec': make_idx_array(start, end) }

def get_req_cpus(self):
return 2
return (2, 2)

class NonDistribGatherComp(Component):
"""Uses 2 procs gathers a distrib input into a full output"""
Expand Down
54 changes: 51 additions & 3 deletions contrib/testmpi/test_mpi.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
from openmdao.lib.optproblems import sellar

from openmdao.main.api import Assembly, Component, set_as_top, Driver
from openmdao.main.datatypes.api import Float, Array
from openmdao.main.datatypes.api import Float, Array, Str, List
from openmdao.main.interfaces import implements, ISolver
from openmdao.main.mpiwrap import MPI
from openmdao.main.mpiwrap import MPI, MPIContext
from openmdao.main.test.simpledriver import SimpleDriver
from openmdao.test.execcomp import ExecComp
from openmdao.test.mpiunittest import MPITestCase, MPIContext
from openmdao.test.mpiunittest import MPITestCase
from openmdao.util.testutil import assert_rel_error


Expand All @@ -34,6 +34,10 @@ def execute(self):

class ABCDArrayComp(Component):
delay = Float(0.01, iotype='in')
in_string = Str(iotype='in')
out_string = Str(iotype='out')
in_list = List(iotype='in')
out_list = List(iotype='out')

def __init__(self, arr_size=9):
super(ABCDArrayComp, self).__init__()
Expand All @@ -46,6 +50,8 @@ def execute(self):
time.sleep(self.delay)
self.c = self.a + self.b
self.d = self.a - self.b
self.out_string = self.in_string + '_' + self.name
self.out_list = self.in_list[:]+[1.5]

def dump(self, comm):
print "%d: %s.a = %s" % (comm.rank, self.name, self.a)
Expand Down Expand Up @@ -509,6 +515,48 @@ def test_sellar_Newton_parallel(self):
self.fail("not all expected values were found")


class MPITests3(MPITestCase):

N_PROCS = 3

def test_fan_out_in_noflats(self):
size = 5 # array var size

# a comp feeds 3 parallel comps which feed
# another comp
top = set_as_top(Assembly())
top.add("C1", ABCDArrayComp(size))
top.add("C2", ABCDArrayComp(size))
top.add("C3", ABCDArrayComp(size))
top.add("C4", ABCDArrayComp(size))
top.add("C5", ABCDArrayComp(size))
top.driver.workflow.add(['C1', 'C2', 'C3', 'C4', 'C5'])
top.connect('C1.c', 'C2.a')
top.connect('C1.out_string', 'C2.in_string')
top.connect('C1.out_list', 'C4.in_list')

top.connect('C1.d', 'C3.b')
top.connect('C1.c', 'C4.a')
top.connect('C2.out_string', 'C5.in_string')
top.connect('C3.d', 'C5.b')
top.connect('C4.c', 'C5.a')
top.connect('C4.out_list', 'C5.in_list')

top.C1.a = np.ones(size, float) * 3.0
top.C1.b = np.ones(size, float) * 7.0

top.C1.in_string = 'foo'
top.C1.in_list = [1, 1, 1]

top.run()

self.assertTrue(all(top.C5.a==np.ones(size, float)*11.))
self.assertTrue(all(top.C5.b==np.ones(size, float)*5.))

self.assertEqual(top.C5.out_string, 'foo_C1_C2_C5')
self.assertEqual(top.C5.out_list, [1, 1, 1, 1.5, 1.5, 1.5])


class TestCaseSerial(TestCase):
def test_sellar_p_serial(self):

Expand Down
3 changes: 2 additions & 1 deletion contrib/testmpi/test_mpi_derivatives.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
import numpy as np
import sys

from openmdao.main.mpiwrap import MPIContext
from openmdao.test.mpiunittest import MPITestCase
from openmdao.util.testutil import assert_rel_error
from openmdao.test.mpiunittest import MPITestCase, MPIContext
from openmdao.main.api import Assembly, Component, set_as_top, Driver
from openmdao.main.datatypes.api import Float, Array
from openmdao.main.test.simpledriver import SimpleDriver
Expand Down
Loading