Beispiel #1
0
 def solve(self, rand, problem):
   comm = problem.comm()
   n = problem.numVariables
   assert n < 63
   numPotentialSolutions = 2**n
   binaryAssignments = MpiCollection.makeRange(comm, numPotentialSolutions)
   currentAssignment = MpiKsatAssignment.emptyMpiKsatAssignment(problem.comm(), n)
   currentLocalAssignment = currentAssignment.localAssignment()
   #FIXME: collectEverywhere() probably should return a list, not an iterable.
   allClauses = list(problem.distributedClauses().values().collectEverywhere())
   
   if comm.rank == 0:
     print allClauses
   
   def checkBinaryAssignment(binaryAssignment):
     MpiKsatAssignment.unpackTo(binaryAssignment, currentLocalAssignment, n)
     return currentLocalAssignment.satisfiesClauses(allClauses)
   satisfyingBinaryAssignments = binaryAssignments.filter(checkBinaryAssignment)
   resultStatistics = (satisfyingBinaryAssignments
     .map(lambda elt: (1, elt))
     .reduce((0, -1), lambda countAndMaxA, countAndMaxB: (countAndMaxA[0] + countAndMaxB[0], max(countAndMaxA[1], countAndMaxB[1]))))
   
   def buildSolution():
     numSatisfyingAssignments, arbitrarySatisfyingAssignment = resultStatistics
     print "%d out of %d satisfying assignments." % (numSatisfyingAssignments, numPotentialSolutions)
     if arbitrarySatisfyingAssignment > -1:
       return KsatSolution.success(MpiKsatAssignment.unpack(arbitrarySatisfyingAssignment, n))
     else:
       return KsatSolution.failure()
   
   return onMaster(problem.comm(), buildSolution)
Beispiel #2
0
 def solve(self, rand, problem):
   comm = problem.comm()
   n = problem.numVariables
   numSamples = self.numSamples
   processorRand = MpiUtils.reseed(comm, rand)
   startingSeed = Utils.randLargeInt(rand)
   allClauses = list(problem.distributedClauses().values().collectEverywhere())
   satisfyingAssignments = (MpiCollection.makeRange(comm, numSamples)
     .map(lambda idx: MpiKsatAssignment.uniformRandomKsatAssignment(processorRand, n))
     .filter(lambda assignment: assignment.satisfiesClauses(allClauses)))
   
   #if comm.rank == 0:
     #print allClauses
   
   def reduceResultStatistics(countAndArbitraryElementA, countAndArbitraryElementB):
     newCount = countAndArbitraryElementA[0] + countAndArbitraryElementB[0]
     newArbitraryElement = countAndArbitraryElementA[1] if countAndArbitraryElementB[1] is None else countAndArbitraryElementB[1]
     return (newCount, newArbitraryElement)
   
   resultStatistics = (satisfyingAssignments
     .map(lambda elt: (1, elt))
     .reduce((0, None), reduceResultStatistics))
   
   def buildSolution():
     numSatisfyingAssignments, arbitrarySatisfyingAssignment = resultStatistics
     #print "%d out of %d satisfying assignments." % (numSatisfyingAssignments, numSamples)
     #if numSatisfyingAssignments*1.0/numSamples <= 0.0002 and numSatisfyingAssignments != 0:
     print "problem difficulty = " + str(numSatisfyingAssignments*1.0/numSamples)
     
     if arbitrarySatisfyingAssignment > -1:
       return KsatSolution.success(arbitrarySatisfyingAssignment)
     else:
       return KsatSolution.failure()
   
   return onMaster(problem.comm(), buildSolution)
Beispiel #3
0
def collectAndCombineLocalAssignments(comm, locallySatisfyingAssignments):
  allLocalAssignments = locallySatisfyingAssignments.collect()
  def findGloballySatisfyingAssignments():
    satisfyingAssignments = set(allLocalAssignments[0])
    for procAssignments in allLocalAssignments:
      satisfyingAssignments &= frozenset(procAssignments)
    return satisfyingAssignments
    
  return onMaster(comm, findGloballySatisfyingAssignments)
Beispiel #4
0
def collectAndCombineLocalAssignments(comm, locallySatisfyingAssignments):
    allLocalAssignments = locallySatisfyingAssignments.collect()

    def findGloballySatisfyingAssignments():
        satisfyingAssignments = set(allLocalAssignments[0])
        for procAssignments in allLocalAssignments:
            satisfyingAssignments &= frozenset(procAssignments)
        return satisfyingAssignments

    return onMaster(comm, findGloballySatisfyingAssignments)
Beispiel #5
0
    def solve(self, rand, problem):
        comm = problem.comm()

        allClauses = problem.distributedClauses().values().collectEverywhere()

        if comm.rank == 0:
            print list(allClauses)

        n = problem.numVariables
        assert n < 63
        numPotentialSolutions = 2**n
        locallySatisfyingAssignments = MpiChunks(problem.comm(), [])
        assignment = MpiKsatAssignment.emptyMpiKsatAssignment(
            problem.comm(), n)
        localAssignment = assignment.localAssignment()
        assignmentsSinceLastCommunication = 0
        satisfyingAssignment = None
        numSatisfyingAssignments = 0
        if comm.rank == 0:
            satisfyingAssignments = set()
        for binaryAssignment in xrange(numPotentialSolutions):
            MpiKsatAssignment.unpackTo(binaryAssignment, localAssignment, n)
            if localAssignment.satisfiesClauses(problem.localClauses()):
                locallySatisfyingAssignments.localData().append(
                    binaryAssignment)
            assignmentsSinceLastCommunication += 1
            if assignmentsSinceLastCommunication >= self.communicationFrequency or binaryAssignment == numPotentialSolutions - 1:
                newSatisfyingAssignments = collectAndCombineLocalAssignments(
                    comm, locallySatisfyingAssignments)
                if comm.rank == 0:
                    numSatisfyingAssignments += len(newSatisfyingAssignments)
                    if len(newSatisfyingAssignments
                           ) > 0 and satisfyingAssignment is None:
                        satisfyingAssignment = MpiKsatAssignment.unpack(
                            list(newSatisfyingAssignments)[0], n)
                locallySatisfyingAssignments = MpiChunks(comm, [])
                assignmentsSinceLastCommunication = 0

        def buildSolution():
            print "%d out of %d satisfying assignments." % (
                numSatisfyingAssignments, numPotentialSolutions)

            if satisfyingAssignment is not None:
                return KsatSolution.success(satisfyingAssignment)
            else:
                return KsatSolution.failure()

        return onMaster(comm, buildSolution)
Beispiel #6
0
    def solve(self, rand, problem):
        comm = problem.comm()
        n = problem.numVariables
        numSamples = self.numSamples
        processorRand = MpiUtils.reseed(comm, rand)
        startingSeed = Utils.randLargeInt(rand)
        allClauses = list(
            problem.distributedClauses().values().collectEverywhere())
        satisfyingAssignments = (
            MpiCollection.makeRange(
                comm,
                numSamples).map(lambda idx: MpiKsatAssignment.
                                uniformRandomKsatAssignment(processorRand, n)).
            filter(lambda assignment: assignment.satisfiesClauses(allClauses)))

        #if comm.rank == 0:
        #print allClauses

        def reduceResultStatistics(countAndArbitraryElementA,
                                   countAndArbitraryElementB):
            newCount = countAndArbitraryElementA[
                0] + countAndArbitraryElementB[0]
            newArbitraryElement = countAndArbitraryElementA[
                1] if countAndArbitraryElementB[
                    1] is None else countAndArbitraryElementB[1]
            return (newCount, newArbitraryElement)

        resultStatistics = (
            satisfyingAssignments.map(lambda elt: (1, elt)).reduce(
                (0, None), reduceResultStatistics))

        def buildSolution():
            numSatisfyingAssignments, arbitrarySatisfyingAssignment = resultStatistics
            #print "%d out of %d satisfying assignments." % (numSatisfyingAssignments, numSamples)
            #if numSatisfyingAssignments*1.0/numSamples <= 0.0002 and numSatisfyingAssignments != 0:
            print "problem difficulty = " + str(
                numSatisfyingAssignments * 1.0 / numSamples)

            if arbitrarySatisfyingAssignment > -1:
                return KsatSolution.success(arbitrarySatisfyingAssignment)
            else:
                return KsatSolution.failure()

        return onMaster(problem.comm(), buildSolution)
Beispiel #7
0
 def solve(self, rand, problem):
   comm = problem.comm()
   
   allClauses = problem.distributedClauses().values().collectEverywhere()
   
   if comm.rank == 0:
     print list(allClauses)
   
   n = problem.numVariables
   assert n < 63
   numPotentialSolutions = 2**n
   locallySatisfyingAssignments = MpiChunks(problem.comm(), [])
   assignment = MpiKsatAssignment.emptyMpiKsatAssignment(problem.comm(), n)
   localAssignment = assignment.localAssignment()
   assignmentsSinceLastCommunication = 0
   satisfyingAssignment = None
   numSatisfyingAssignments = 0
   if comm.rank == 0:
     satisfyingAssignments = set()
   for binaryAssignment in xrange(numPotentialSolutions):
     MpiKsatAssignment.unpackTo(binaryAssignment, localAssignment, n)
     if localAssignment.satisfiesClauses(problem.localClauses()):
       locallySatisfyingAssignments.localData().append(binaryAssignment)
     assignmentsSinceLastCommunication += 1
     if assignmentsSinceLastCommunication >= self.communicationFrequency or binaryAssignment == numPotentialSolutions-1:
       newSatisfyingAssignments = collectAndCombineLocalAssignments(comm, locallySatisfyingAssignments)
       if comm.rank == 0:
         numSatisfyingAssignments += len(newSatisfyingAssignments)
         if len(newSatisfyingAssignments) > 0 and satisfyingAssignment is None:
           satisfyingAssignment = MpiKsatAssignment.unpack(list(newSatisfyingAssignments)[0], n)
       locallySatisfyingAssignments = MpiChunks(comm, [])
       assignmentsSinceLastCommunication = 0
   
   def buildSolution():
     print "%d out of %d satisfying assignments." % (numSatisfyingAssignments, numPotentialSolutions)
     
     if satisfyingAssignment is not None:
       return KsatSolution.success(satisfyingAssignment)
     else:
       return KsatSolution.failure()
   
   return onMaster(comm, buildSolution)
Beispiel #8
0
    def solve(self, rand, problem):
        comm = problem.comm()
        n = problem.numVariables
        assert n < 63
        numPotentialSolutions = 2**n
        binaryAssignments = MpiCollection.makeRange(comm,
                                                    numPotentialSolutions)
        currentAssignment = MpiKsatAssignment.emptyMpiKsatAssignment(
            problem.comm(), n)
        currentLocalAssignment = currentAssignment.localAssignment()
        #FIXME: collectEverywhere() probably should return a list, not an iterable.
        allClauses = list(
            problem.distributedClauses().values().collectEverywhere())

        if comm.rank == 0:
            print allClauses

        def checkBinaryAssignment(binaryAssignment):
            MpiKsatAssignment.unpackTo(binaryAssignment,
                                       currentLocalAssignment, n)
            return currentLocalAssignment.satisfiesClauses(allClauses)

        satisfyingBinaryAssignments = binaryAssignments.filter(
            checkBinaryAssignment)
        resultStatistics = (
            satisfyingBinaryAssignments.map(lambda elt: (1, elt)).reduce(
                (0, -1), lambda countAndMaxA, countAndMaxB:
                (countAndMaxA[0] + countAndMaxB[0],
                 max(countAndMaxA[1], countAndMaxB[1]))))

        def buildSolution():
            numSatisfyingAssignments, arbitrarySatisfyingAssignment = resultStatistics
            print "%d out of %d satisfying assignments." % (
                numSatisfyingAssignments, numPotentialSolutions)
            if arbitrarySatisfyingAssignment > -1:
                return KsatSolution.success(
                    MpiKsatAssignment.unpack(arbitrarySatisfyingAssignment, n))
            else:
                return KsatSolution.failure()

        return onMaster(problem.comm(), buildSolution)
Beispiel #9
0
 def reduce(self, zero, plus):
   collectedValue = self.collect()
   return onMaster(self.comm, lambda : reduce(plus, collectedValue, zero))
Beispiel #10
0
 def reduce(self, zero, plus):
     collectedValue = self.collect()
     return onMaster(self.comm, lambda: reduce(plus, collectedValue, zero))
Beispiel #11
0
 def size(self):
   numElements = self.mapChunks(_chunkLen).reduce(0, operator.add)
   return onMaster(self.comm(), lambda : numElements)
Beispiel #12
0
 def collect(self):
   collectedChunks = self.distributedChunks.collect()
   return onMaster(self.comm(), lambda : itertools.chain.from_iterable(collectedChunks))
Beispiel #13
0
 def collect(self):
   dicts = self.dictChunks.collect()
   return onMaster(self.comm(), lambda : addAll_update(dicts))
Beispiel #14
0
    def solve(self, rand, problem):
        comm = problem.comm()
        n = problem.numVariables

        #broadcastStartTime = now()
        broadcastStartTime = datetime.datetime.now()
        broadcastProblem = problem.toBroadcast()
        broadcastEndTime = datetime.datetime.now()

        #graphCreationStartTime = now()
        graphCreationStartTime = datetime.datetime.now()
        graph = broadcastProblem.toDependencyGraph(comm)
        graphCreationEndTime = datetime.datetime.now()

        currentAssignment = MpiKsatAssignment.uniformRandomMpiKsatAssignment(
            comm, rand, n)
        maxNumIterations = self.independentSetFinder.calculateNumIterations(
            problem, graph)
        if comm.rank == 0:
            print "Solving problem with %s iterations." % maxNumIterations

        #initialMarkingsStartTime = now()
        initialMarkingsStartTime = datetime.datetime.now()
        independentSetFunc = self.independentSetFinder.buildFinderFunc(
            rand, graph)
        initialMarkingsEndTime = datetime.datetime.now()

        findIndependentSetAndResampleTotalTime = datetime.timedelta()
        broadcastModifiedVariablesTotalTime = datetime.timedelta()

        for i in xrange(maxNumIterations):
            # At the beginning of each iteration of this loop, @currentAssignment
            # is consistent across processors.
            localAssignment = currentAssignment.localAssignment()
            unsatSubgraph = graph.filter(
                lambda clauseIdx: not localAssignment.satisfiesClause(
                    broadcastProblem.clausesByIdx[clauseIdx]))
            # print "%d unsatisfied clauses on iteration %d on machine %d: %s." % (CollectionUtils.iterlen(unsatSubgraph.nodesIterator().localElements()), i, comm.rank, {clauseIdx: broadcastProblem.clausesByIdx[clauseIdx] for clauseIdx in unsatSubgraph.nodesIterator().localElements()})
            localIndependentSet = independentSetFunc(unsatSubgraph)
            locallyModifiedVariables = MpiCollection.dictFromLocal(comm, {})
            #FIXME
            localIndependentSetSize = 0

            #findIndependentSetAndResampleStartTime = now()
            findIndependentSetAndResampleStartTime = datetime.datetime.now()
            for clauseIdx in localIndependentSet.localElements():
                clause = broadcastProblem.clausesByIdx[clauseIdx]
                #TODO: Only communicate modified variables to machines that need them.
                # For now we assume all machines need to see all modified variables,
                # which is true when m*k/p >> n (i.e. when the number of literals per
                # machine is large).
                updates = {
                    variable: Utils.randBit(rand)
                    for variable in clause.literals
                }
                locallyModifiedVariables.localDict().update(updates)
                localIndependentSetSize += 1
            findIndependentSetAndResampleTotalTime += datetime.datetime.now(
            ) - findIndependentSetAndResampleStartTime
            # print "Using an independent set of size %d on iteration %d on machine %d." % (localIndependentSetSize, i, comm.rank)
            #TODO: Probably inefficient serialization here.  Should serialize as
            # a list of ints and a list of bools.

            #broadcastModifiedVariablesStartTime = now()
            broadcastModifiedVariablesStartTime = datetime.datetime.now()
            allModifiedVariables = locallyModifiedVariables.collectEverywhere()
            broadcastModifiedVariablesTotalTime += datetime.datetime.now(
            ) - broadcastModifiedVariablesStartTime

            if len(allModifiedVariables) == 0:
                if comm.rank == 0:
                    print "\nBroadcast time = " + str(
                        (broadcastEndTime -
                         broadcastStartTime).total_seconds())
                    print "Graph creation time = " + str(
                        (graphCreationEndTime -
                         graphCreationStartTime).total_seconds())
                    print "Initial markings time = " + str(
                        (initialMarkingsEndTime -
                         initialMarkingsStartTime).total_seconds())
                    print "Find independentSet and resample time = " + str(
                        findIndependentSetAndResampleTotalTime.total_seconds())
                    print "Boardcast modified variables time = " + str(
                        broadcastModifiedVariablesTotalTime.total_seconds())
                    print "\n"
                    print "Finished after %d iterations." % i
                return onMaster(comm,
                                lambda: KsatSolution.success(localAssignment))
            # Update modified variables from everywhere.
            for var, value in allModifiedVariables.items():
                localAssignment.values[var] = value
        return onMaster(comm, lambda: KsatSolution.failure())