int HUD::calculateScoreOffset(float number, int fontHeight) { int offset = numberOfZeros(number); offset = offset * floor((float)fontHeight/2); return offset; }
int main(int argc, char *argv[]) { unsigned int power2[12] = {1,2,4,8,16,32,64,128,256,512,1024,2048}; int numMSG; int dim; int MASTER; /******************* Number of MSGs **********/ numMSG = atoi(argv[1]); dim = atoi(argv[2]); /******************* MPI Init ****************** */ unsigned int rank, size; int MPI_ERR; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); MASTER = size -1 ; /************************** MASTER ******************************/ if (rank == MASTER){ int *msg = (int *)calloc(MSGSIZE, sizeof(int)); int i=0; int numberOfPrints = (size-1) * (numMSG*2); int dest = 0; int next; int doneCounter = 0; int printCounter = 0; int treeDone = 0; makeMessage(msg, MASTER, ZERO, TREE, 0); MPI_Send(&msg[0], MSGSIZE, MPI_INT, ZERO, DATA_TAG, MPI_COMM_WORLD); while(1){ MPI_Recv(&msg[0], MSGSIZE, MPI_INT, ZERO, DATA_TAG, MPI_COMM_WORLD, &status); if(msg[TYPE] == TREEDONE){ treeDone += 1; if(treeDone < 2 ){ makeMessage(msg, MASTER, size-2, INITDONE, 0); MPI_Send(&msg[0], MSGSIZE, MPI_INT, size-2, DATA_TAG, MPI_COMM_WORLD); } } if(msg[TYPE] == PRINT){ printCounter += 1; print(msg, msg[SOURCEORIGINAL], dim, power2); } if(msg[TYPE] == DONE){ doneCounter += 1; } if(doneCounter == (size-1) && printCounter == ( (numMSG * 2) * (size-1) )){ break; } } // Send a STOP messages using Reduce Forward to Zero dest = ZERO; makeMessage(msg, MASTER, dest, REDUCEFORWARD, 0); next = compute_next_dest(rank, dest, power2); MPI_Send(&msg[0], MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); // printf("%d\n", printCounter); } /************************** Workers ******************************/ else{ int i; int x; int dest; int *msg = (int *)calloc(MSGSIZE, sizeof(int)); int *children = (int *)calloc(dim, sizeof(int)); int childCounter = 0; int msgno = 0; unsigned int next; int flag; int msgCounter = 0; int makeMsgCount = 0; int ackCounter = 0; int stopCount = 0; int parent = 0; int parentSent = 0; int parentCounter = 0; int initDone = 0; int forBcastCounter = 0; int bcastCouter = 0; int bSent = 0; int reduceForwardCount = 0; int reduceBackwardCount = 0; int reduceFlag = 1; int neighbor; int numOfZeros = 0; int firstOne; int valueSent = 0; int sumValue = rank; /* number of msgs you should get in Fast Reduce */ numOfZeros = numberOfZeros(rank); while(1){ MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if(flag == 1){ MPI_Recv(&msg[0] , MSGSIZE, MPI_INT, status.MPI_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); if(rank == ZERO){ if(msg[TYPE] == PRINT){ MPI_Send(&msg[0] , MSGSIZE, MPI_INT, MASTER, DATA_TAG, MPI_COMM_WORLD); } else if(msg[TYPE] == DONE){ MPI_Send(&msg[0] , MSGSIZE, MPI_INT, MASTER, DATA_TAG, MPI_COMM_WORLD); } else if(msg[TYPE] == TREEDONE){ msg[SOURCE] = ZERO; msg[DEST] = MASTER; MPI_Send(&msg[0] , MSGSIZE, MPI_INT, MASTER, DATA_TAG, MPI_COMM_WORLD); } } dest = msg[DEST]; /* If the message is for you */ if(dest == rank){ /* If you got an ACK, increament your counter */ if(msg[TYPE] == ACK){ ackCounter += 1; /* Send for Printing */ msg[SOURCE] = rank; msg[DEST] = ZERO; msg[TYPEORIGINAL] = ACK ; //msg[TYPE]; msg[TYPE] = PRINT; next = compute_next_dest(rank, ZERO, power2); if(rank == ZERO){ MPI_Send(&msg[0] , MSGSIZE, MPI_INT, MASTER, DATA_TAG, MPI_COMM_WORLD); }else{ MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); } } /* If you got a message destined to you, send an ACK */ else if(msg[TYPE] == MSG){ /* Send for printing */ msg[SOURCE] = rank; msg[DEST] = ZERO; msg[TYPEORIGINAL] = MSG ; msg[TYPE] = PRINT; next = compute_next_dest(rank, ZERO, power2); if(rank == ZERO){ MPI_Send(&msg[0] , MSGSIZE, MPI_INT, MASTER, DATA_TAG, MPI_COMM_WORLD); }else{ MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); } /* Send Ack */ dest = msg[SOURCEORIGINAL]; msgno = msg[MSGNO]; makeMessage(msg, rank, dest, ACK, msgno); next = compute_next_dest(rank, dest, power2); msg[HOPCNT] = 1; msg[SOURCEORIGINAL] = rank; MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); } else if(msg[TYPE] == TREE && msg[SOURCE] == ZERO){ parent = findParent(rank, dim); makeMessage(msg, rank, parent, PARENT, msgno); next = compute_next_dest(rank, parent, power2); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); // printf("Rank %d sending to %d \n", rank, msg[DEST]); } else if(msg[TYPE] == TREE && msg[SOURCE] == MASTER){ int layer = (int)(pow(2,dim)) - (((int)(pow(2,dim))) / 2); for(i = 0 ; i < layer ; i++){ makeMessage(msg, ZERO, i, TREE, 0); next = compute_next_dest(ZERO, i, power2); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); } } else if(msg[TYPE] == PARENT){ children[childCounter] = msg[SOURCE]; childCounter += 1; if(rank != size-2 && parentSent == 0){ parent = findParent(rank, dim); makeMessage(msg, rank, parent, PARENT, msgno); next = compute_next_dest(rank, parent, power2); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); parentSent = 1; } if(rank == size-2){ parentCounter += 1; if(parentCounter == ((int)pow(2,(dim-1)) - 1)){ dest = ZERO; makeMessage(msg, rank, dest, TREEDONE, msgno); next = compute_next_dest(rank, dest, power2); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); } } } else if(msg[TYPE] == STOP){ if(childCounter > 0){ for(i = 0 ; i < childCounter ; i++){ dest = children[i]; makeMessage(msg, rank, dest, STOP, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); } } break; } else if(msg[TYPE] == INITDONE){ if(childCounter > 0){ for(i = 0 ; i < childCounter ; i++){ dest = children[i]; makeMessage(msg, rank, dest, INITDONE, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); } } initDone = 1; } /* Only 11..1 gets this */ else if(msg[TYPE] == FORBCAST){ if(childCounter > 0){ for(i = 0 ; i < childCounter ; i++){ dest = children[i]; makeMessage(msg, rank, dest, BCAST, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); bcastCouter += 1; // printf("Rank %d send bcast type %d to %d - bcounter %d \n", rank, msg[TYPE], msg[DEST], bcastCouter); } // bcastCouter += childCounter; } /* FORBCASTACK immediately to Zero */ makeMessage(msg, rank, ZERO, FORBCASTACK, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, ZERO, DATA_TAG, MPI_COMM_WORLD); // printf("Rank %d send forbcastack type %d to %d - bcounter %d \n", rank, msg[TYPE], msg[DEST], bcastCouter); } else if(msg[TYPE] == BCAST){ if(childCounter > 0){ for(i = 0 ; i < childCounter ; i++){ dest = children[i]; makeMessage(msg, rank, dest, BCAST, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); bcastCouter += 1; // printf("Rank %d send bcast type %d to %d - bcounter %d \n", rank, msg[TYPE], msg[DEST], bcastCouter); } } else{ /* BCASTACK to parent only when you received as many acks as you sent bcasts */ makeMessage(msg, rank, parent, BCASTACK, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, parent, DATA_TAG, MPI_COMM_WORLD); // printf("BCAST ACK from %d to %d \n", rank, msg[DEST]); } } /* Only Zero receives this */ else if(msg[TYPE] == FORBCASTACK){ // printf("Rank %d got Type %d from %d \n",rank, msg[TYPE], msg[SOURCE] ); forBcastCounter -= 1; } else if(msg[TYPE] == BCASTACK){ bcastCouter -= 1; if(bcastCouter == 0 && rank != size-2){ /* BCASTACK to parent only when you received as many acks as you sent bcasts */ makeMessage(msg, rank, parent, BCASTACK, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, parent, DATA_TAG, MPI_COMM_WORLD); // printf("BCAST ACK from %d to %d \n", rank, msg[DEST]); } } else if(msg[TYPE] == REDUCEFORWARD){ int msgNumber = msg[MSGNO]; int source = msg[SOURCEORIGINAL]; dest = myNext(rank, dim); makeMessage(msg, rank, dest, REDUCEFORWARD, msgNumber); msg[SOURCEORIGINAL] = source; MPI_Send(&msg[0], MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); reduceFlag = 0; printf("HOP : Rank %d myNext : %d - Message Number : %d - TERMINATED !\n", rank, dest, msg[MSGNO]); break; } else if(msg[TYPE] == REDUCEBACKWARD){ if(msg[SOURCEORIGINAL] == rank){ reduceFlag = 0; printf("Returned to Source : %d - Loop Finished!\n", rank); } else{ int msgNumber = msg[MSGNO]; int source = msg[SOURCEORIGINAL]; dest = myPrev(rank, dim); makeMessage(msg, rank, dest, REDUCEBACKWARD, msgNumber); msg[SOURCEORIGINAL] = source; MPI_Send(&msg[0], MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); reduceFlag = 0; printf("HOP : Rank %d myPrev : %d - Message Number : %d \n", rank, dest, msg[MSGNO]); } } else if(msg[TYPE] == FASTREDUCE){ sumValue += msg[DATAFIELD]; numOfZeros -= 1; } } /* If you are not destination */ else{ /* MSG or ACK */ if(msg[TYPE] == MSG || msg[TYPE] == ACK){ /* add to number of hobs */ msg[HOPCNT] += 1; int nHubs = msg[HOPCNT]; msg[(HOPCNT + nHubs)] = rank; next = compute_next_dest(rank, dest, power2); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); } /* Pass it along : print, done, stop, parent, parentfound */ else{ next = compute_next_dest(rank, dest, power2); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); } } /* if you are done send a DONE message to Zero (forBcastCounter == 0 && bcastCouter == 0 && reduceFlag == 0) */ if(ackCounter == numMSG ){ // printf("Rank %d is DoNe !!!! \n", rank); dest = ZERO; makeMessage(msg, rank, dest, DONE, msgno); MPI_Send(&msg[0] , MSGSIZE, MPI_INT, dest, DATA_TAG, MPI_COMM_WORLD); ackCounter += 1; // printf("Rank %d TYPE %d to %d\n", rank, msg[TYPE], msg[DEST]); } } /* Flag = 0 */ else{ if(initDone == 1){ // if(valueSent == 0){ // /* Odd Ranks */ // if(rank % 2 == 1){ // /* Flip the last bit to 0 */ // neighbor = flip(rank, 0); // makeMessage(msg, rank, neighbor, FASTREDUCE, 0); // msg[DATAFIELD] = rank; // MPI_Send(&msg[0], MSGSIZE, MPI_INT, neighbor, DATA_TAG, MPI_COMM_WORLD); // valueSent = 1; // printf("Rank %d sends to %d \n", rank, neighbor); // } // /* Even Ranks */ // else if(rank % 2 == 0){ // if(numOfZeros == 0){ // firstOne = findFirst(rank); // neighbor = flip(rank, firstOne); // makeMessage(msg, rank, neighbor, FASTREDUCE, 0); // msg[DATAFIELD] = sumValue; // MPI_Send(&msg[0], MSGSIZE, MPI_INT, neighbor, DATA_TAG, MPI_COMM_WORLD); // valueSent = 1; // printf("Rank %d sends to %d \n", rank, neighbor); // } // } // } /* Still have to make your messages */ if(makeMsgCount < numMSG){ dest = randomGenerator(size-1) ; makeMessage(msg, rank, dest, MSG, msgno); next = compute_next_dest(rank, dest, power2); msg[HOPCNT] = 1; msg[SOURCEORIGINAL] = rank; MPI_Send(&msg[0] , MSGSIZE, MPI_INT, next, DATA_TAG, MPI_COMM_WORLD); makeMsgCount += 1; } } } } } MPI_Finalize(); return 0; }