Exemplo n.º 1
0
def _test_mpi_partition(comm):
    test_ranks = [0]
    if comm is not None:
        import mpi4py.MPI

        test_ranks = list(range(comm.size))
    for x in (
        [],
        ["a"],
        ["a", "b"],
        ["a", "b", "c"],
        ["a", "b", "c"] * 2,
        ["a", "b", "c"] * 4,
        ["a", "b", "c"] * 16,
        ["a", "b", "c"] * 32,
    ):
        for root in test_ranks:
            x_accessed_local = array.array("i", [0]) * len(x)
            for i, xi in mpi_partition(comm, list(enumerate(x)), root=root):
                assert x[i] == xi
                x_accessed_local[i] += 1
            x_accessed = array.array("i", [0]) * len(x)
            if comm is not None:
                comm.Allreduce(
                    [x_accessed_local, mpi4py.MPI.INT],
                    [x_accessed, mpi4py.MPI.INT],
                    op=mpi4py.MPI.SUM,
                )
                comm.Barrier()
            else:
                x_accessed[:] = x_accessed_local[:]
            for xi in x_accessed:
                assert xi == 1
Exemplo n.º 2
0
    def _tighten_bounds_impl(self, tmp_objective):
        objlist = self.range_reduction_get_objects()
        joblist = []
        objects = []
        lower_bounds = []
        upper_bounds = []
        objects_seen = set()
        for i, val in enumerate(objlist):
            obj = None
            include = False
            val = val if type(val) is tuple else (val, True, True)
            assert len(val) == 3
            obj = val[0]
            cid = self.problem.pyomo_object_to_cid[obj]
            if val[1]:
                include = True
                joblist.append((i, cid, 'L'))
            if val[2]:
                include = True
                joblist.append((i, cid, 'U'))
                joblist.append((i, cid, 'U'))
            if include:
                assert obj is not None
                assert id(obj) not in objects_seen
                objects_seen.add(id(obj))
                objects.append(obj)
                lower_bounds.append(pmo.value(obj.lb) \
                                    if obj.has_lb() else \
                                    -inf)
                upper_bounds.append(pmo.value(obj.ub) \
                                    if obj.has_ub() else \
                                    inf)
        lower_bounds = array.array('d', lower_bounds)
        upper_bounds = array.array('d', upper_bounds)

        # verify that everyone has the exact same list
        # (order and values), assumes everything in the list
        # has a well-defined hash
        if self._comm is not None:
            my_joblist_hash = hash_joblist(joblist)
            joblist_hash = self._comm.bcast(my_joblist_hash, root=0)
            assert joblist_hash == my_joblist_hash
        for i, cid, which in mpi_partition(self._comm, joblist):
            obj = self.problem.cid_to_pyomo_object[cid]
            tmp_objective.expr = obj
            if which == 'L':
                tmp_objective.sense = pmo.minimize
            else:
                assert which == 'U'
                tmp_objective.sense = pmo.maximize
            self.range_reduction_objective_changed(tmp_objective)
            bound = self.range_reduction_solve_for_object_bound(obj)
            if bound is not None:
                if which == 'L':
                    lower_bounds[i] = bound
                else:
                    assert which == 'U'
                    upper_bounds[i] = bound
        if self._comm is not None:
            lower_bounds_local = lower_bounds
            upper_bounds_local = upper_bounds
            lower_bounds = array.array('d', lower_bounds)
            upper_bounds = array.array('d', upper_bounds)
            self._comm.Allreduce([lower_bounds_local, mpi4py.MPI.DOUBLE],
                                 [lower_bounds, mpi4py.MPI.DOUBLE],
                                 op=mpi4py.MPI.MAX)
            self._comm.Allreduce([upper_bounds_local, mpi4py.MPI.DOUBLE],
                                 [upper_bounds, mpi4py.MPI.DOUBLE],
                                 op=mpi4py.MPI.MIN)

        return objects, lower_bounds, upper_bounds