[C - MPI] Esercizio parallelismo
Per la prossima lezione di esercizi abbiamo da completare il seguente codice.
Per chi non ha voglia di leggere tutto, dobbiamo completare da soli le funzioni in rosso.
Non ho capito cosa devo fare con i tipi di dato "unit_of_work_t" e "unit_result_t".
Devo definirli con una struct/classe?
Per chi non ha voglia di leggere tutto, dobbiamo completare da soli le funzioni in rosso.
#include <mpi.h> #define WORKTAG 1 #define DIETAG 2 /* Local functions */ static void master(void); static void slave(void); static unit_of_work_t get_next_work_item(void); static void process_results(unit_result_t result); static unit_result_t do_work(unit_of_work_t work); int main(int argc, char **argv) { int myrank; /* Initialize MPI */ MPI_Init(&argc, &argv); /* Find out my identity in the default communicator */ MPI_Comm_rank(MPI_COMM_WORLD, &myrank); if (myrank == 0) { master(); } else { slave(); } /* Shut down MPI */ MPI_Finalize(); return 0; } static void master(void) { int ntasks, rank; unit_of_work_t work; unit_result_t result; MPI_Status status; /* Find out how many processes there are in the default communicator */ MPI_Comm_size(MPI_COMM_WORLD, &ntasks); /* Seed the slaves; send one unit of work to each slave. */ for (rank = 1; rank < ntasks; ++rank) { /* Find the next item of work to do */ work = get_next_work_item(); /* Send it to each rank */ MPI_Send(&work, /* message buffer */ 1, /* one data item */ MPI_INT, /* data item is an integer */ rank, /* destination process rank */ WORKTAG, /* user chosen message tag */ MPI_COMM_WORLD); /* default communicator */ } /* Loop over getting new work requests until there is no more work to be done */ work = get_next_work_item(); while (work != NULL) { /* Receive results from a slave */ MPI_Recv(&result, /* message buffer */ 1, /* one data item */ MPI_DOUBLE, /* of type double real */ MPI_ANY_SOURCE, /* receive from any sender */ MPI_ANY_TAG, /* any type of message */ MPI_COMM_WORLD, /* default communicator */ &status); /* info about the received message */ /* Send the slave a new work unit */ MPI_Send(&work, /* message buffer */ 1, /* one data item */ MPI_INT, /* data item is an integer */ status.MPI_SOURCE, /* to who we just received from */ WORKTAG, /* user chosen message tag */ MPI_COMM_WORLD); /* default communicator */ /* Get the next unit of work to be done */ work = get_next_work_item(); } /* There's no more work to be done, so receive all the outstanding results from the slaves. */ for (rank = 1; rank < ntasks; ++rank) { MPI_Recv(&result, 1, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); } /* Tell all the slaves to exit by sending an empty message with the DIETAG. */ for (rank = 1; rank < ntasks; ++rank) { MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD); } } static void slave(void) { unit_of_work_t work; unit_result_t results; MPI_Status status; while (1) { /* Receive a message from the master */ MPI_Recv(&work, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); /* Check the tag of the received message. */ if (status.MPI_TAG == DIETAG) { return; } /* Do the work */ result = do_work(work); /* Send the result back */ MPI_Send(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); } } static unit_of_work_t get_next_work_item(void) { /* Fill in with whatever is relevant to obtain a new unit of work suitable to be given to a slave. */ } static void process_results(unit_result_t result) { /* Fill in with whatever is relevant to process the results returned by the slave */ } static unit_result_t do_work(unit_of_work_t work) { /* Fill in with whatever is necessary to process the work and generate a result */ } Link: http://www.lam-mpi.org/tutorials/one-step/ezstart.php
Non ho capito cosa devo fare con i tipi di dato "unit_of_work_t" e "unit_result_t".
Devo definirli con una struct/classe?
Risposte
Il codice del precedente post è quello originale.
Prima dei prototipi delle funzioni in rosso (quindi fuori dal main), ho definito i tipi di dato con due struct.
Riporto gli errori che ottengo:
Dopo aver risolto gli errori, mi basta definire il comportamento delle tre funzioni ed ho finito?
Prima dei prototipi delle funzioni in rosso (quindi fuori dal main), ho definito i tipi di dato con due struct.
struct unit_of_work_t { ... struct unit_result_t { ...
Riporto gli errori che ottengo:
[LIST] Riga codice: static unit_of_work_t get_next_work_item(void); Errore: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘get_next_work_item[/LIST] [LIST] Riga: static void process_results(unit_result_t result); Errore: expected ‘)’ before ‘result’[/LIST] [LIST] Riga: unit_of_work_t work; Errore: in function Master ‘unit_of_work_t’ undeclared (first use in this function) (Each undeclared identifier is reported only once for each function it appears in.) expected ‘;’ before ‘work’[/LIST]
Dopo aver risolto gli errori, mi basta definire il comportamento delle tre funzioni ed ho finito?
Se stai programmando in C, allora devi sempre scrivere "struct" davanti al tag della struttura oppure usare un typedef. Cioè
oppure
static struct unit_of_work_t get_next_work_item(void)
oppure
typedef struct unit_of_work_t unit_of_work_t; struct unit_of_work_t { // ... };
"apatriarca":
Se stai programmando in C, allora devi sempre scrivere "struct" davanti al tag della struttura oppure usare un typedef. Cioè
static struct unit_of_work_t get_next_work_item(void)
oppure
typedef struct unit_of_work_t unit_of_work_t; struct unit_of_work_t { // ... };
Risolto!

Grazie