int main(int argc, char **argv) { if (argc != 4) { printf("usage: %s <server-address> <server-port> <phase[-1 - 6]>\n", argv[0]); return EXIT_FAILURE; } int start_phase = atoi(argv[3]); bool res; test_state_t *state = NULL; rvm_cfg_t *cfg; if(start_phase >= 0) { /* Try to recover from server */ cfg = initialize_rvm(argv[1], argv[2], true, create_rmem_layer); /* Recover the state (if any) */ state = (test_state_t*)rvm_get_usr_data(cfg); } else { /* Starting from scratch */ cfg = initialize_rvm(argv[1], argv[2], false, create_rmem_layer); CHECK_ERROR(cfg == NULL, ("Failed to initialize rvm\n")); state = NULL; } rvm_txid_t txid; /*==================================================================== * TX 0 - Allocate and Initialize Arrays *===================================================================*/ /* If state is NULL then we are starting from scratch or recovering from an early error */ if(state == NULL) { LOG(1,("Phase 0:\n")); TX_START; /* Allocate a "state" structure to test pointers */ state = (test_state_t*)rvm_alloc(cfg, sizeof(test_state_t)); CHECK_ERROR(state == NULL, ("FAILURE: Couldn't allocate state\n")); /* Initialize the arrays */ res = phase0(cfg, state); CHECK_ERROR(!res, ("FAILURE: Phase 0 Failure\n")); if(start_phase == -1) { LOG(1, ("SUCCESS: Phase 0, simulating failure\n")); return EXIT_SUCCESS; } /* End of first txn */ state->phase = PHASE1; TX_COMMIT; } switch(state->phase) { case PHASE1: /*==================================================================== * TX 1 Increment arrays, don't mess with LL *===================================================================*/ LOG(1, ("Phase 1:\n")); TX_START; res = phase1(cfg, state); CHECK_ERROR(!res, ("FAILURE: Phase 1 failed\n")); /* Simulate Failure */ if(start_phase == 0) { LOG(1, ("SUCCESS: Phase 1, simulating failure\n")); return EXIT_SUCCESS; } state->phase = PHASE2; TX_COMMIT; case PHASE2: //Fallthrough /*==================================================================== * TX 2 Free Arrays *===================================================================*/ LOG(1, ("Phase 2:\n")); TX_START; res = phase2(cfg, state); CHECK_ERROR(!res, ("FAILURE: Phase 2 failed\n")); /* Simulate Failure */ if(start_phase == 1) { LOG(1, ("SUCCESS: Phase 2, simulating failure\n")); return EXIT_SUCCESS; } state->phase = PHASE3; TX_COMMIT; case PHASE3: //Fallthrough /*==================================================================== * TX 3 Fill in Linked list *===================================================================*/ LOG(1, ("Phase 3:\n")); TX_START; res = phase3(cfg, state); CHECK_ERROR(!res, ("FAILURE: Phase 3 failed\n")); /* Simulate Failure */ if(start_phase == 2) { LOG(1, ("SUCCESS: Phase 3, simulating failure\n")); return EXIT_SUCCESS; } state->phase = PHASE4; TX_COMMIT; case PHASE4: /*==================================================================== * TX 4 Free Half the linked list *===================================================================*/ LOG(1, ("Phase 4:\n")); TX_START; res = phase4(cfg, state); CHECK_ERROR(!res, ("FAILURE: Phase 4 failed\n")); /* Simulate Failure */ if(start_phase == 3) { LOG(1, ("SUCCESS: Phase 4, simulating failure\n")); return EXIT_SUCCESS; } state->phase = PHASE5; TX_COMMIT; case PHASE5: /*==================================================================== * TX 5 Re-allocate half of the linked list *===================================================================*/ LOG(1, ("Phase 5:\n")); TX_START; res = phase5(cfg, state); CHECK_ERROR(!res, ("FAILURE: Phase 5 failed\n")); /* Simulate Failure */ if(start_phase == 4) { LOG(1, ("SUCCESS: Phase5, simulating failure\n")); return EXIT_SUCCESS; } state->phase = PHASE6; TX_COMMIT; case PHASE6: /*==================================================================== * TX 6 Free whole linked list *===================================================================*/ LOG(1, ("Phase 6:\n")); TX_START; res = phase6(cfg, state); CHECK_ERROR(!res, ("FAILURE: Phase 6 failed\n")); /* Simulate Failure */ if(start_phase == 5) { LOG(1, ("SUCCESS: Phase 6, simulating failure\n")); return EXIT_SUCCESS; } state->phase = DONE; TX_COMMIT; case DONE: res = rvm_cfg_destroy(cfg); CHECK_ERROR(!res, ("FAILURE: Failed to destroy rvm state\n")); LOG(1, ("SUCCESS: Got through all phases\n")); break; default: LOG(1, ("FAILURE: Corrupted State, tried phase %d\n", state->phase)); return EXIT_FAILURE; } return EXIT_SUCCESS; }
void psrs(int size, int rank, int nInts, int *toSort, char *fname) { char hname[256]; double start, end, total = 0, algStart; int i, *privateInts, *regularSamples, *collectedSamples, *pivots, *partitionIndices, *localPartitionSizes, *incomingPartitionSizes, **partitions, *mergedPartitions, *partitionSizes, *sortedArray; FILE *fptr = NULL; if (rank == MASTER) fptr = fopen(fname, "a"); memset (hname, '\0', sizeof(unsigned char)*256); gethostname(hname, 255); DBPRINT(("%d of %d running on pid %d %s\n", rank, size, getpid(), hname)); if (rank == MASTER) { collectedSamples = calloc(1, sizeof(int)*size*size); if (!collectedSamples) { err(1,"Failed to allocate memory for collected samples " "array for master process"); MPI_Finalize(); exit(1); } } MPI_Barrier(MPI_COMM_WORLD); if (nInts < VALIDATION_THRESHOLD) validateResults = 1; /* * "Phase 0" in which the array is split into contiguous chunks * distributed amongst the processes. */ phase0(size, rank, nInts, toSort, &privateInts); /* Phase 1 */ algStart = MPI_Wtime(); START_TIMER((start)); phase1(size, rank, nInts, toSort, privateInts, ®ularSamples); MPI_Barrier(MPI_COMM_WORLD); STOP_TIMER((1), (start), (end), (total), (rank), (fptr)); /* Phase 2 */ START_TIMER((start)); phase2(size, rank, regularSamples, &collectedSamples, &pivots); MPI_Barrier(MPI_COMM_WORLD); STOP_TIMER((2), (start), (end), (total), (rank), (fptr)); /* Phase 3 */ START_TIMER((start)); phase3(size, rank, nInts, privateInts, pivots, &localPartitionSizes, &partitionIndices, &incomingPartitionSizes, &partitions); MPI_Barrier(MPI_COMM_WORLD); STOP_TIMER((3), (start), (end), (total), (rank), (fptr)); /* Phase 4 */ START_TIMER((start)); phase4(size, incomingPartitionSizes, partitions, &mergedPartitions); MPI_Barrier(MPI_COMM_WORLD); STOP_TIMER((4), (start), (end), (total), (rank), (fptr)); if (rank == MASTER) { total = end - algStart; fprintf(fptr, "The algorithm took %f seconds in total\n", total); } if (!validateResults) return; /* Run validation test */ /* "Phase 5" concatenate the lists back at the master */ phase5(size, rank, nInts, incomingPartitionSizes, mergedPartitions, &partitionSizes, &sortedArray); /* * Assert that the array is equivalent to the sorted original array * where we sort the original array using a known, proven, sequential, * method. */ if (rank == MASTER) { qsort(toSort, nInts, sizeof(int), intComp); } for (i = 0; i < nInts; i++) { if (rank == MASTER) { if (toSort[i] != sortedArray[i]) { printf("OH NO, got %d at pos %d, expected " "%d\n", sortedArray[i], i, toSort[i]); } } } if (rank == MASTER) fclose(fptr); }