Beispiel #1
0
/**
 * Called by the master and will start awaiting processes (signal to them to start) if required.
 * By default this works as a process pool, so if there are not enough processes to workers then it will quit
 * but this can be changed by modifying options in the pool.
 * It takes in the awaiting worker number to send rank data to/from, the parent rank of the process to start
 * and returns the process rank that this awaiting worker was on. In the default case of #workers > pool capacity
 * causing an abort, then this will only be called to start single workers and as such the parent ID and return rank
 * will match perfectly. If you change the options to allow for workers to queue up if there is not enough MPI
 * capacity then the parent and return rank will be -1 for all workers started which do not match the provided awaiting Id
 */
static int startAwaitingProcessesIfNeeded(int awaitingId, int parent) {
    int awaitingProcessMPIRank=-1;
    if(PP_processesAwaitingStart) {
        int i;
        for(i=0; i<PP_numProcs-1; i++) {
            if(!PP_active[i]) {
                PP_active[i]=1;
                PP_numActive++;
                struct PP_Control_Package out_command = createCommandPackage(PP_WAKE);
                out_command.data = awaitingId == PP_processesAwaitingStart ? parent : -1;
                if (PP_DEBUG) printf("[Master] Starting process %d\n", i+1);
                MPI_Send(&out_command, 1, PP_COMMAND_TYPE, i+1, PP_CONTROL_TAG, MPI_COMM_WORLD);
                if (awaitingId == PP_processesAwaitingStart) awaitingProcessMPIRank = i+1;	// Will return this rank to the caller
                PP_processesAwaitingStart--;
                if (PP_processesAwaitingStart == 0) break;
            }
            if(i==PP_numProcs-2) {
                //If I reach this point, I must have looped through the whole array and found no available processes
                if(PP_QuitOnNoProcs) {
                    errorMessage("No more processes available");
                }

                if(PP_IgnoreOnNoProcs) {
                    fprintf(stderr,"[ProcessPool] Warning. No processes available. Ignoring launch request.\n");
                    PP_processesAwaitingStart--;
                }
                // otherwise, do nothing; a process may become available on the next iteration of the loop
            }
        }
    }
    return awaitingProcessMPIRank;
}
Beispiel #2
0
/**
 * A worker can instruct the master to shutdown the process pool. The master can also call this
 * but it does nothing (they just need to call the finalisation step)
 */
void shutdownPool() {
    if (PP_myRank != 0) {
        if (PP_DEBUG) printf("[Worker] Commanding a pool shutdown\n");
        struct PP_Control_Package out_command = createCommandPackage(PP_RUNCOMPLETE);
        MPI_Ssend(&out_command, 1, PP_COMMAND_TYPE, 0, PP_CONTROL_TAG, MPI_COMM_WORLD);
    }
}
Beispiel #3
0
// Отправка серверу уведомленя о том, что клиент готов к получению данных
int Client::slotSendClientIsReady()
{
    if (mClientSocket == 0)
	return -1;

    mClientSocket->write(createCommandPackage(CommandType::IsReady));
    return 0;
}
Beispiel #4
0
/**
 * Each process calls this to finalise the process pool
 */
void processPoolFinalise() {
    if (PP_myRank == 0) {
        if (PP_active != NULL) free(PP_active);
        int i;
        for(i=0; i<PP_numProcs-1; i++) {
            if (PP_DEBUG) printf("[Master] Shutting down process %d\n", i);
            struct PP_Control_Package out_command = createCommandPackage(PP_STOP);
            MPI_Send(&out_command, 1, PP_COMMAND_TYPE, i+1, PP_CONTROL_TAG, MPI_COMM_WORLD);
            //printf("MASTER SENT STOP TO %d\n", i+1);
        }
    }
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Type_free(&PP_COMMAND_TYPE);
}
Beispiel #5
0
/**
 * A worker or the master can instruct to start another worker process
 */
int startWorkerProcess() {
    if (PP_myRank == 0) {
        PP_processesAwaitingStart++;
        return startAwaitingProcessesIfNeeded(PP_processesAwaitingStart, 0);
    } else {
        int workerRank;
        struct PP_Control_Package out_command = createCommandPackage(PP_STARTPROCESS);
        MPI_Send(&out_command, 1, PP_COMMAND_TYPE, 0, PP_CONTROL_TAG, MPI_COMM_WORLD);
        // Receive the rank that this worker has been placed on - if you change the default option from aborting when
        // there are not enough MPI processes then this may be -1
        MPI_Recv(&workerRank, 1, MPI_INT, 0, PP_PID_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        return workerRank;
    }
}
Beispiel #6
0
/**
 * Called by the worker at the end of each task when it has finished and is to sleep. Will be interrupted from
 * sleeping when given a command from the master, which might be to do more work of shutdown
 * Returns one (true) if the caller should do some more work or zero (false) if it is to quit
 */
int workerSleep() {
    if (PP_myRank != 0) {
        if (in_command.command==PP_WAKE) {
            // The command was to wake up, it has done the work and now it needs to switch to sleeping mode
            struct PP_Control_Package out_command = createCommandPackage(PP_SLEEPING);
            MPI_Send(&out_command, 1, PP_COMMAND_TYPE, 0, PP_CONTROL_TAG, MPI_COMM_WORLD);
            if (PP_pollRecvCommandRequest != MPI_REQUEST_NULL)
                MPI_Wait(&PP_pollRecvCommandRequest, MPI_STATUS_IGNORE);
        }
        return handleRecievedCommand();
    } else {
        errorMessage("Master process called worker poll");
        return 0;
    }
}
Beispiel #7
0
// Слот - "Превышено время ожидания ответа от сервера"
int Client::slotCheckActivity()
{
    mClientSocket->write(createCommandPackage(CommandType::IsAlive));

    return 0;
}