def ObjectAttributeTest1(workerID): """ Tests reading from a shared object before and after object value has been changed by another node. The value being changed is a TestObject2 object """ if (workerID == 0): TestObject(1) PyDOOMS.barrier() obj = PyDOOMS.get(1) oldObj = obj.objectAttr oldObjA = oldObj.a oldObjB = oldObj.b PyDOOMS.barrier() if (workerID == 0): obj.objectAttr = TestObject2() obj.objectAttr.a = 2 obj.objectAttr.b = 2 PyDOOMS.objectUpdated(obj, "objectAttr") PyDOOMS.barrier() obj = PyDOOMS.get(1) if not (isinstance(oldObj,TestObject2) and oldObjA == 0 and oldObjB == 1 and isinstance(obj, TestObject) and isinstance(obj.objectAttr,TestObject2) and obj.objectAttr.a == 2 and obj.objectAttr.b == 2): logging.critical("Worker " + str(workerID) + " Values are:" + str(oldObjA) + "," + str(oldObjB) + " " + str(PyDOOMS.get(1).objectAttr.a) + "," + str(obj.objectAttr.b)) raise Exception
def BarrierTest(workerID): """ Test barrier by incrementing a single value over multiple barriers """ loops = 10 increment = 1 results = [] if (workerID == 0): for i in range(PyDOOMS.getNumberOfWorkers()): TestObject(i) PyDOOMS.barrier() obj = PyDOOMS.get(workerID) PyDOOMS.barrier() for i in range(loops): results.append(obj.value) obj.value += increment PyDOOMS.objectUpdated(obj,"value") PyDOOMS.barrier() results.append(obj.value) if not (results[0] == 0*increment and results[1] == 1*increment and results[2] == 2*increment and results[3] == 3*increment and results[4] == 4*increment): logging.critical("Worker" + str(workerID) + ", results: " + str(results)) raise Exception
def ReadLoopTest1(workerID): """ Tests reading from a shared object before and after object value has been changed by another node """ if (workerID == 0): TestObject(1) PyDOOMS.barrier() obj = PyDOOMS.get(1) oldValue = obj.value PyDOOMS.barrier() if (workerID == 0): obj.value = 1 PyDOOMS.objectUpdated(obj, "value") PyDOOMS.barrier() obj = PyDOOMS.get(1) if not (oldValue == 0 and obj.value == 1): logging.critical("Worker " + str(workerID) + " Values are:" + str(oldValue) + "," + str(obj.value) + " ") raise Exception
def WriteLoopTest1(workerID): """ Test all nodes writing and reading to/from a single shared object, one at a time """ nodes = PyDOOMS.getNumberOfNodes() if (workerID == 0): TestObject(1) PyDOOMS.barrier() oldObjValue = PyDOOMS.get(1).value PyDOOMS.barrier() for i in range(nodes): if (workerID == i): obj = PyDOOMS.get(1) obj.value += 1 PyDOOMS.objectUpdated(obj,"value") PyDOOMS.barrier() if not (oldObjValue == 0 and PyDOOMS.get(1).value == nodes): logging.critical("Worker " + str(workerID) + " Values are:" + str(oldObjValue) + "," + str(PyDOOMS.get(1).value) + " ") raise Exception
def AttributeTest1(workerID): """ Tests adding a new attribute to a shared object """ if (workerID == 0): TestObject(1) PyDOOMS.barrier() obj = PyDOOMS.get(1) PyDOOMS.barrier() if (workerID == 0): obj.newAttr = 2 PyDOOMS.objectUpdated(obj,"newAttr") PyDOOMS.barrier() val = PyDOOMS.get(1).newAttr if not (val == 2): logging.critical("Worker " + str(workerID) + " Value is:" + str(val)) raise Exception
def WriteLoopTest3(workerID): """ Test writing and reading to/from multiple shared object from each node """ nodes = PyDOOMS.getNumberOfNodes() if (workerID == 0): TestObject(0) TestObject(1) TestObject(2) TestObject(3) PyDOOMS.barrier() oldObj0Value = PyDOOMS.get(0).value oldObj1Value = PyDOOMS.get(1).value oldObj2Value = PyDOOMS.get(2).value oldObj3Value = PyDOOMS.get(3).value PyDOOMS.barrier() for i in range(nodes): if (workerID == i): obj0 = PyDOOMS.get(0) obj1 = PyDOOMS.get(1) obj2 = PyDOOMS.get(2) obj3 = PyDOOMS.get(3) obj0.value += 1 obj1.value += 1 obj2.value += 1 obj3.value += 1 PyDOOMS.objectUpdated(obj0,"value") PyDOOMS.objectUpdated(obj1,"value") PyDOOMS.objectUpdated(obj2,"value") PyDOOMS.objectUpdated(obj3,"value") PyDOOMS.barrier() if not (oldObj0Value == 0 and oldObj1Value == 0 and oldObj2Value == 0 and oldObj3Value == 0 and PyDOOMS.get(0).value == nodes and PyDOOMS.get(1).value == nodes and PyDOOMS.get(2).value == nodes and PyDOOMS.get(3).value == nodes): logging.critical("Worker " + str(workerID) + " Values are:" + str(oldObj0Value) + "," + str(PyDOOMS.get(0).value) + " " + str(oldObj1Value) + "," + str(PyDOOMS.get(1).value) + " " + str(oldObj2Value) + "," + str(PyDOOMS.get(2).value) + " " + str(oldObj3Value) + "," + str(PyDOOMS.get(3).value) + " ") raise Exception
def monteCarlo(workerID, myDarts): if (workerID == 0): for boardID in range(PyDOOMS.getNumberOfWorkers()): Board(boardID) PyDOOMS.barrier() start = time.time() board = PyDOOMS.get(workerID) # Compute while (myDarts > 0): x = random.random() y = random.random() dist = math.sqrt((x*x)+(y*y)) if (dist <= 1.0): board.hit() else: board.miss() myDarts = myDarts - 1 board.ready = True PyDOOMS.objectUpdated(board, "hits") PyDOOMS.objectUpdated(board, "darts") PyDOOMS.objectUpdated(board, "ready") PyDOOMS.barrier() # Sum result if (workerID == 0): pi = 0.0 i = 0 while i < PyDOOMS.getNumberOfWorkers(): b = PyDOOMS.get(i) if b.ready: pi = pi + b.calc_pi() i = i + 1 else: logging.critical("Board: " + str(i) + " - " + str(b.ready)) time.sleep(1) logging.info("Pi: " + str(pi / PyDOOMS.getNumberOfWorkers()) + " calculated in " + str(time.time() - start) + " seconds.") logging.info("Worker: " + str(workerID) + " dead. Worked for " + str(time.time() - start) + " seconds.")
def ReadLoopTest2(workerID): """ Tests reading from multiple shared objects before and after an object value has been changed Changes are synchronized over several barriers """ if (workerID == 0): TestObject(1) TestObject(2) TestObject(3) PyDOOMS.barrier() oldObj1Value = PyDOOMS.get(1).value oldObj2Value = PyDOOMS.get(2).value oldObj3Value = PyDOOMS.get(3).value PyDOOMS.barrier() if (workerID is not 0): PyDOOMS.barrier() PyDOOMS.barrier() PyDOOMS.barrier() elif (workerID == 0): obj1 = PyDOOMS.get(1) obj1.value = obj1.value + 1 PyDOOMS.objectUpdated(obj1,"value") PyDOOMS.barrier() obj2 = PyDOOMS.get(2) obj2.value = obj2.value + 1 PyDOOMS.objectUpdated(obj2,"value") PyDOOMS.barrier() obj3 = PyDOOMS.get(3) obj3.value = obj3.value + 1 PyDOOMS.objectUpdated(obj3,"value") PyDOOMS.barrier() if not (oldObj1Value == 0 and oldObj2Value == 0 and oldObj3Value == 0 and PyDOOMS.get(1).value == 1 and PyDOOMS.get(2).value == 1 and PyDOOMS.get(3).value == 1): logging.critical("Worker " + str(workerID) + " Values are:" + str(oldObj1Value) + "," + str(PyDOOMS.get(1).value) + " " + str(oldObj2Value) + "," + str(PyDOOMS.get(2).value) + " " + str(oldObj3Value) + "," + str(PyDOOMS.get(3).value) + " ") raise Exception
def gaussSeidel(workerID, matrixSize): global numberOfWorkers, matrixOffset numberOfWorkers = PyDOOMS.getNumberOfWorkers() matrixOffset = 100 chunkSize = (matrixSize-2) / numberOfWorkers if workerID == 0: if ((matrixSize - 2) % numberOfWorkers) != 0: print "Warning: Matrix size incompatible with number of workers, some columns may not be calculated" matrix = generateMatrix(matrixSize) generateSharedRowChunks(matrix, chunkSize) for w in range(numberOfWorkers): WorkerInfo(w) PyDOOMS.barrier() logging.info("Worker: " + str(workerID) + " assigned chunk " + str(workerID+1)) start = time.time() for iteration in range(1): workerInfo = PyDOOMS.get(workerID) workerInfo.error = 0.0 for row in range(1,matrixSize-1): if (workerID != 0): while (PyDOOMS.get(workerID - 1).progress < row): PyDOOMS.barrier() workerChunk = workerID + 1 westChunk = PyDOOMS.get(getChunkRowIndex(row,workerChunk-1)) northChunk = PyDOOMS.get(getChunkRowIndex(row-1,workerChunk)) eastChunk = PyDOOMS.get(getChunkRowIndex(row,workerChunk+1)) southChunk = PyDOOMS.get(getChunkRowIndex(row+1,workerChunk)) centerChunk = PyDOOMS.get(getChunkRowIndex(row,workerChunk)) if chunkSize == 1: for column in range(len(centerChunk.rowChunk)): newValue = 0.25 * (northChunk.rowChunk[column] + southChunk.rowChunk[column] + eastChunk.rowChunk[column] + westChunk.rowChunk[column]) workerInfo.error += abs(centerChunk.rowChunk[column] - newValue) centerChunk.rowChunk[column] = newValue else: for column in range(len(centerChunk.rowChunk)): if column == 0: newValue = 0.25 * (northChunk.rowChunk[column] + southChunk.rowChunk[column] + westChunk.rowChunk[chunkSize-1] + centerChunk.rowChunk[column+1]) elif column == chunkSize-1: newValue = 0.25 * (northChunk.rowChunk[column] + southChunk.rowChunk[column] + centerChunk.rowChunk[column-1] + eastChunk.rowChunk[0]) else: newValue = 0.25 * (northChunk.rowChunk[column] + southChunk.rowChunk[column] + centerChunk.rowChunk[column-1] + centerChunk.rowChunk[column+1]) workerInfo.error += abs(centerChunk.rowChunk[column] - newValue) centerChunk.rowChunk[column] = newValue workerInfo.progress = row PyDOOMS.objectUpdated(workerInfo, "progress") PyDOOMS.objectUpdated(workerInfo, "error") PyDOOMS.objectUpdated(centerChunk, "rowChunk") PyDOOMS.barrier() if (workerID != 0): previousWorker = PyDOOMS.get(workerID - 1) previousWorker.progress = 0 #PyDOOMS._comm.addOutgoingUpdate(previousWorker.ID, "progress", previousWorker.progress) if (workerID == numberOfWorkers - 1): globalError = 0.0 for w in range(numberOfWorkers): globalError += PyDOOMS.get(w).error logging.info("GlobalError: " + str(globalError)) for i in range(workerID,numberOfWorkers): PyDOOMS.barrier() logging.info("Worker: " + str(workerID) + " done in " + str(time.time() - start) + " seconds")
def RedBlackGaussSeidel(workerID, matrixSize): global numberOfWorkers, matrixOffset numberOfWorkers = PyDOOMS.getNumberOfWorkers() matrixOffset = 100 chunkSize = (matrixSize-2) / numberOfWorkers if workerID == 0: if ((matrixSize - 2) % numberOfWorkers) != 0: print "Warning: Matrix size - 2 is not divisible with number of workers, some columns may not be calculated" start = time.time() generateSharedMatrixRows(matrixSize) logging.info("Time to generate shared matrix rows: " + str(time.time()-start)) for w in range(numberOfWorkers): WorkerInfo(w) PyDOOMS.barrier() logging.info("Worker: " + str(workerID) + " assigned rows " + str(workerID*chunkSize+1) + "-" + str(workerID*chunkSize + chunkSize + 1)) start = time.time() for iteration in range(1): workerInfo = PyDOOMS.get(workerID) workerInfo.error = 0.0 enum = dict(enumerate(['Red', 'Black'])) for color in enum: for row in range(workerID*chunkSize + 1,workerID*chunkSize + chunkSize + 1): northRow = PyDOOMS.get(matrixOffset + row - 1) centerRow = PyDOOMS.get(matrixOffset + row) southRow = PyDOOMS.get(matrixOffset + row + 1) for column in range((color + row) % 2 + 1, matrixSize-1, 2): newValue = 0.25 * (northRow.row[column] + southRow.row[column] + centerRow.row[column-1] + centerRow.row[column+1]) workerInfo.error += abs(centerRow.row[column] - newValue) centerRow.row[column] = newValue PyDOOMS. objectUpdated(centerRow, "row") PyDOOMS.objectUpdated(workerInfo, "error") PyDOOMS.barrier() if (workerID == numberOfWorkers - 1): globalError = 0.0 for w in range(numberOfWorkers): globalError += PyDOOMS.get(w).error logging.info("Iteration " + str(iteration+1) + " global error = " + str(globalError)) logging.info("Worker: " + str(workerID) + " done in " + str(time.time() - start) + " seconds")
def LUdecomp(workerID): if workerID==0: setupStart = time.time() generateSharedMatrixBlocks(size) print "Setup done in ", time.time() - setupStart, "seconds." #print "Matrix:" #printBlockMatrix(matrixOffset) start = time.time() for x in range(blocksPerSide): if workerID == workerList.pop(): logging.debug("Worker" +str(workerID) + "working on diagonal " + str(x) + str(",") + str(x)) A = getMatrixBlock(matrixOffset, x, x) L = getMatrixBlock(LOffset, x, x) U = getMatrixBlock(UOffset, x, x) l,u = betterLU(A.block) L.block = l U.block = u PyDOOMS.objectUpdated(L, "block") PyDOOMS.objectUpdated(U, "block") PyDOOMS.barrier() for i in range(x+1,blocksPerSide): if workerID == workerList.pop(): logging.debug("Worker" +str(workerID) + "working on U " + str(x) + str(",") + str(i)) A = getMatrixBlock(matrixOffset, x, i) L = getMatrixBlock(LOffset, x, x) U = getMatrixBlock(UOffset, x, i) U.block = multiplyMatrix(invertMatrix(L.block), A.block) PyDOOMS.objectUpdated(U, "block") for j in range(x+1,blocksPerSide): if workerID == workerList.pop(): logging.debug("Worker" +str(workerID) + "working on L " + str(j) + str(",") + str(x)) A = getMatrixBlock(matrixOffset, j, x) L = getMatrixBlock(LOffset, j, x) U = getMatrixBlock(UOffset, x, x) L.block = multiplyMatrix(A.block, invertMatrix(U.block)) PyDOOMS.objectUpdated(L, "block") PyDOOMS.barrier() for j in range(x+1, blocksPerSide): for k in range(x+1, blocksPerSide): if workerID == workerList.pop(): logging.debug("Worker" +str(workerID) + "working on sub-block " + str(k) + str(",") + str(j)) A = getMatrixBlock(matrixOffset, k, j) L = getMatrixBlock(LOffset, k, x) U = getMatrixBlock(UOffset, x, j) A.block = subtractMatrix(A.block, multiplyMatrix(L.block, U.block)) PyDOOMS.objectUpdated(A, "block") PyDOOMS.barrier() if workerID == 0: print "Done in ", time.time() - start, "seconds."