Skip to content

Instantly share code, notes, and snippets.

@bbrelje
Created April 22, 2020 21:47
Show Gist options
  • Save bbrelje/f0d57f6311655e46d90c0055ac3dee7f to your computer and use it in GitHub Desktop.
Save bbrelje/f0d57f6311655e46d90c0055ac3dee7f to your computer and use it in GitHub Desktop.
get_val on distributed output - incorrect behavior
import openmdao.api as om
import numpy as np
from openmdao.utils.array_utils import evenly_distrib_idxs
import mpi4py.MPI as MPI
N = 3
class DistribComp(om.ExplicitComponent):
def initialize(self):
self.options['distributed'] = True
def setup(self):
self.add_input('x', shape=1)
rank = self.comm.rank
sizes, offsets = evenly_distrib_idxs(self.comm.size, N)
self.add_output('y', shape=sizes[rank])
rows = np.arange(0, sizes[rank])
cols = np.zeros((sizes[rank],))
#self.declare_partials('y', 'x', rows=rows, cols=cols)
if sizes[rank] > 0:
self.declare_partials('y', 'x', rows=np.arange(0, sizes[rank]), cols=np.zeros((sizes[rank],)))
else:
self.declare_partials('y', 'x', val=1.0)
def compute(self, inputs, outputs):
rank = self.comm.rank
sizes, offsets = evenly_distrib_idxs(self.comm.size, N)
outputs['y'] = inputs['x']*np.ones((sizes[rank],))
if rank == 0:
outputs['y'][0] = 2.3
def compute_partials(self, inputs, J):
rank = self.comm.rank
sizes, offsets = evenly_distrib_idxs(self.comm.size, N)
if MPI.COMM_WORLD.rank == 0:
J['y','x'] = np.ones((sizes[rank],))
J['y','x'][0] = 0.0
else:
J['y','x'] = np.ones((sizes[rank],))
class GroupThatDoesWork(om.Group):
def setup(self):
dvs = om.IndepVarComp()
dvs.add_output('x', val=6.0)
self.add_subsystem('dvs', dvs, promotes_outputs=['*'])
self.add_subsystem('distcomp',DistribComp(), promotes_inputs=['*'])
self.add_subsystem('execcomp',om.ExecComp('z = sum(y)', y=np.zeros((N,)), z=0.0))
self.connect('distcomp.y', 'execcomp.y')
def mainfunc():
prob = om.Problem()
prob.model = GroupThatDoesWork()
prob.setup(mode='fwd')
prob['dvs.x'] = 7.0
prob.run_model()
print(prob['execcomp.z'])
# this should fail because remote=False
# or it should gather all the entries by default
# but it shouldn't be printing just the entries on each proc
print(prob['distcomp.y'])
if __name__ == "__main__":
mainfunc()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment