#include <unistd.h>
#include <limits.h>
#include "worker_help.h"
#include "icomm.h"
Defines | |
#define | _XOPEN_SOURCE 500 |
#define | MAX_RESULT_COUNT 1000000 |
#define | STARTUP_COST 50000 |
Functions | |
int | get_test_params (int myid, int numprocs, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
int | send_recv_work_req (int myid, int *wait_status_p, struct work_info_s *work_info_p, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
static int | compare_results (const void *ptr_1, const void *ptr_2) |
void | print_result (struct result_s *cur_result_p) |
int | do_work (int myid, struct work_info_s *work_info_p, struct isend_info_s **query_frag_isend_matrix, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
int | merge_results (int myid, struct work_info_s *work_info_p, struct query_result_s *query_result_list, struct isend_info_s **query_frag_isend_matrix, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
int | worker_isend_results (int myid, struct work_info_s *work_info_p, int *last_query_offset_recv_p, struct isend_info_s **query_frag_isend_matrix, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
static int | increment_work (int myid, struct work_info_s *last_query_result_sent_p, struct work_info_s *last_query_result_comp_p, struct test_params_s *test_params_p) |
static int | decrement_work (int myid, struct work_info_s *last_query_result_comp_p, struct test_params_s *test_params_p) |
int | worker_check_isend_results (int myid, int wait_status, struct work_info_s *last_query_result_sent_p, struct work_info_s *last_query_result_comp_p, struct query_result_s *query_result_list, struct isend_info_s **query_frag_isend_matrix, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
int | worker_post_irecv (int myid, struct work_info_s *work_info_p, struct query_result_s *query_result_list, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
int | worker_check_irecv_offsets (int myid, int wait_status, int last_query_offset_recv, int *last_query_offset_comp_p, struct query_result_s *query_result_list, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
static int | worker_do_dummy_io (int myid, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
static int | worker_do_io (int myid, int cur_io_query, struct query_result_s *query_result_list, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
int | do_all_worker_io (int myid, int wait_status, int last_io_ready, int *last_io_comp_p, struct query_result_s *query_result_list, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
void | worker_check_all_irecv (int myid, int numprocs, struct query_result_s *query_result_list, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
void | worker_check_all_isend (int myid, int numprocs, struct isend_info_s **query_frag_isend_matrix, struct mpe_events_s *mpe_events_p, struct test_params_s *test_params_p) |
Variables | |
char * | decode_worker_state [MAX_WORKER_STATE] |
#define _XOPEN_SOURCE 500 |
#define MAX_RESULT_COUNT 1000000 |
#define STARTUP_COST 50000 |
static int compare_results | ( | const void * | ptr_1, | |
const void * | ptr_2 | |||
) | [static] |
Results are compared so that they can be placed in a sorted linked list. This is the comparator function which is used by qsort.
ptr_1 | Void pointer 1 to result structure. | |
ptr_2 | Void pointer 2 to result structure. |
static int decrement_work | ( | int | myid, | |
struct work_info_s * | last_query_result_comp_p, | |||
struct test_params_s * | test_params_p | |||
) | [static] |
Used by worker_check_isend_results() to back off to the previous (query,frag) since it was not complete.
myid | MPI myid. | |
last_query_result_comp_p | Pointer to the work_info structure of the next (query,frag) to be checked (changed in this function). | |
test_params_p | Pointer to test_params. |
int do_all_worker_io | ( | int | myid, | |
int | wait_status, | |||
int | last_io_ready, | |||
int * | last_io_comp_p, | |||
struct query_result_s * | query_result_list, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
This function will only be called if the worker-writing method is used. When the master notifies the worker of getting ready to write, the worker will try to do I/O to the queries which it has received offset arrays for. If collective I/O is used, the worker will be careful about when to call this function to ensure that all processes write together.
myid | MPI myid. | |
wait_status_p | Pointer to the wait status of the worker. | |
last_io_ready | Last I/O operation possible | |
last_io_comp_p | Pointer to the I/O query operation to try next (modified in this function). | |
query_result_list | The head of the result list for a query. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
int do_work | ( | int | myid, | |
struct work_info_s * | work_info_p, | |||
struct isend_info_s ** | query_frag_isend_matrix, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
The work is calculated based on a very simple model for determining the actual computational time of comparing each (query,frag). The results are generated and saved in the query_frag_isend_matrix in an array before sending to the master. After the compute time has been generated, it is simulated through usleep().
myid | MPI myid. | |
work_info_p | Pointer to work_info structure. | |
query_frag_isend_matrix | Pointer to matrix of isend request information. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
int get_test_params | ( | int | myid, | |
int | numprocs, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
Before any work begins, the master distributes the test parameters to the workers through this function.
myid | MPI myid. | |
numprocs | Number of processes used. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
static int increment_work | ( | int | myid, | |
struct work_info_s * | last_query_result_sent_p, | |||
struct work_info_s * | last_query_result_comp_p, | |||
struct test_params_s * | test_params_p | |||
) | [static] |
Used by worker_check_isend_results() to check on the next possible piece of work that was completed. All (query,frag) tuples which were not checked by this worker are skipped in the worker_check_isend_results() function.
myid | MPI myid. | |
last_query_result_sent_p | Pointer to the work_info structure of the last (query,frag) sent. | |
last_query_result_comp_p | Pointer to the work_info structure of the next (query,frag) to be checked (changed in this function). | |
test_params_p | Pointer to test_params. |
int merge_results | ( | int | myid, | |
struct work_info_s * | work_info_p, | |||
struct query_result_s * | query_result_list, | |||
struct isend_info_s ** | query_frag_isend_matrix, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
The results in the query_frag_isend_matrix are first converted to a linked list. Then this linked list is merged with the previous results (if there are any), which are also in a linked list.
myid | MPI myid. | |
work_info_p | Pointer to work_info structure. | |
query_result_list | The head of the result list for a query. | |
query_frag_isend_matrix | Pointer to matrix of isend request information. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
void print_result | ( | struct result_s * | cur_result_p | ) |
Debugging function to print out the member variables of the result structure.
cur_result_p | Result which will have its member variables printed. |
int send_recv_work_req | ( | int | myid, | |
int * | wait_status_p, | |||
struct work_info_s * | work_info_p, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
The worker uses this function to send a request to the master process to request work. The wait_status is encoded in the frag section if the query is done or all queries are done. Otherwise the worker gets the (query,frag) information.
myid | MPI myid. | |
wait_status_p | Pointer to the wait status of the worker. | |
work_info_p | Pointer to work information structure. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
void worker_check_all_irecv | ( | int | myid, | |
int | numprocs, | |||
struct query_result_s * | query_result_list, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
Do a final check on the query_result_list for any uncompleted irecvs. None should exist.
myid | MPI myid. | |
numprocs | Number of processes used. | |
query_result_list | The head of the result list for a query. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
void worker_check_all_isend | ( | int | myid, | |
int | numprocs, | |||
struct isend_info_s ** | query_frag_isend_matrix, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
Do a final check on the query_frag_isend_matrix for any uncompleted isends. None should exist.
myid | MPI myid. | |
numprocs | Number of processes used. | |
query_frag_isend_matrix | Pointer to matrix of isend request information. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
int worker_check_irecv_offsets | ( | int | myid, | |
int | wait_status, | |||
int | last_query_offset_recv, | |||
int * | last_query_offset_comp_p, | |||
struct query_result_s * | query_result_list, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
Check for all the irecvs from all queries that had results from this worker. Post irecvs for the actual offset array when the size irecv is completed. Check for both the sizes and the actual offset arrays.
myid | MPI myid. | |
wait_status_p | Pointer to the wait status of the worker. | |
last_query_offset_recv | Last query to look for offset irecv. | |
last_query_offset_comp_p | Pointer to information set in this function of the last query to look for offset irecvs. | |
query_result_list | The head of the result list for a query. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
int worker_check_isend_results | ( | int | myid, | |
int | wait_status, | |||
struct work_info_s * | last_query_result_sent_p, | |||
struct work_info_s * | last_query_result_comp_p, | |||
struct query_result_s * | query_result_list, | |||
struct isend_info_s ** | query_frag_isend_matrix, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
The worker occasionally uses this function to check on the state of all its isends to the master for every (query,frag) it has processed. It checks the isends in order so that it can avoid checking a large amount of isend requests every time it is called.
myid | MPI myid. | |
wait_status_p | Pointer to the wait status of the worker. | |
last_query_result_sent_p | Pointer to the work_info structure of the last (query,frag) sent. | |
last_query_result_comp_p | Pointer to the work_info structure of the next (query,frag) to be checked (changed in this function). | |
query_result_list | The head of the result list for a query. | |
query_frag_isend_matrix | Pointer to matrix of isend request information. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
static int worker_do_dummy_io | ( | int | myid, | |
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) | [static] |
If the worker-writing mode is chosen with collective I/O, the all workers must participate since it is in the same communication group. When it does not actually write any data, the worker will also call MPI_File_write_all().
myid | MPI myid. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
static int worker_do_io | ( | int | myid, | |
int | cur_io_query, | |||
struct query_result_s * | query_result_list, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) | [static] |
The noncontiguous memory regions of the result data for a completed query with the master's offset array are copied to a contiguous memory buffer. Disp is offset by the first offset to be written. A hindexed MPI Datatype is created for the possibly noncontiguous file regions. The write operation may be collective or individual depending on the test_params. This function is used by do_all_worker_io().
myid | MPI myid. | |
cur_io_query | The query for which we are going to write results. | |
query_result_list | The head of the result list for a query. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
int worker_isend_results | ( | int | myid, | |
struct work_info_s * | work_info_p, | |||
int * | last_query_offset_recv_p, | |||
struct isend_info_s ** | query_frag_isend_matrix, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
Given work info (query,frag), the worker sends the results to the master. The results are first copied into a contiguous buffer. The size is sent in a first isend and then the actual result is sent in the next isend. The result data is sent only in the master-writing mode.
myid | MPI myid. | |
work_info_p | Pointer to work information structure. | |
last_query_offset_recv_p | Pointer to information set in this function of the last query to look for offset irecv. | |
query_frag_isend_matrix | Pointer to matrix of isend request information. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
int worker_post_irecv | ( | int | myid, | |
struct work_info_s * | work_info_p, | |||
struct query_result_s * | query_result_list, | |||
struct mpe_events_s * | mpe_events_p, | |||
struct test_params_s * | test_params_p | |||
) |
If the worker is using parallel I/O, it will have to receive the offset array from the master. It posts a irecv here for this query. Since it is possible that a irecv was already posted for this query, this function should not be called in that case.
myid | MPI myid. | |
work_info_p | Pointer to work information structure. | |
query_result_list | The head of the result list for a query. | |
mpe_events_p | Pointer to timing structure. | |
test_params_p | Pointer to test_params. |
char* decode_worker_state[MAX_WORKER_STATE] |
Initial value:
{ "NOT_USED", "WAIT_RESULT_SIZE", "WAIT_RESULT", "DONE_RESULT", "START_IRECV", "WAIT_OFFSET_LIST_COUNT", "WAIT_OFFSET_LIST", "DONE_OFFSET_LIST", "IO_FINISHED" }