/* -*- Mode: c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ /* * (C) 2011 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */ /* this file should be included by the using device's mpidimpl.h */ #ifndef MPID_SCHED_H_INCLUDED #define MPID_SCHED_H_INCLUDED /* FIXME open questions: * - Should the schedule hold a pointer to the nbc request and the nbc request * hold a pointer to the schedule? This could cause MT issues. */ enum MPIDU_Sched_entry_type { MPIDU_SCHED_ENTRY_INVALID_LB = 0, MPIDU_SCHED_ENTRY_SEND, /* _SEND_DEFER is easily implemented via _SEND */ MPIDU_SCHED_ENTRY_RECV, /* _RECV_STATUS is easily implemented via _RECV */ MPIDU_SCHED_ENTRY_REDUCE, MPIDU_SCHED_ENTRY_COPY, MPIDU_SCHED_ENTRY_NOP, MPIDU_SCHED_ENTRY_CB, MPIDU_SCHED_ENTRY_INVALID_UB }; struct MPIDU_Sched_send { const void *buf; MPI_Aint count; const MPI_Aint *count_p; MPI_Datatype datatype; int dest; MPID_Comm *comm; MPID_Request *sreq; int is_sync; /* TRUE iff this send is an ssend */ }; struct MPIDU_Sched_recv { void *buf; MPI_Aint count; MPI_Datatype datatype; int src; MPID_Comm *comm; MPID_Request *rreq; MPI_Status *status; }; struct MPIDU_Sched_reduce { const void *inbuf; void *inoutbuf; MPI_Aint count; MPI_Datatype datatype; MPI_Op op; }; struct MPIDU_Sched_copy { const void *inbuf; MPI_Aint incount; MPI_Datatype intype; void *outbuf; MPI_Aint outcount; MPI_Datatype outtype; }; /* nop entries have no args, so no structure is needed */ enum MPIDU_Sched_cb_type { MPIDU_SCHED_CB_TYPE_1 = 0, /* single state arg type --> MPID_Sched_cb_t */ MPIDU_SCHED_CB_TYPE_2 /* double state arg type --> MPID_Sched_cb2_t */ }; struct MPIDU_Sched_cb { enum MPIDU_Sched_cb_type cb_type; union { MPID_Sched_cb_t *cb_p; MPID_Sched_cb2_t *cb2_p; } u; void *cb_state; void *cb_state2; /* unused for single-param callbacks */ }; enum MPIDU_Sched_entry_status { MPIDU_SCHED_ENTRY_STATUS_NOT_STARTED = 0, MPIDU_SCHED_ENTRY_STATUS_STARTED, MPIDU_SCHED_ENTRY_STATUS_COMPLETE, MPIDU_SCHED_ENTRY_STATUS_FAILED, /* indicates a failure occurred while executing the entry */ MPIDU_SCHED_ENTRY_STATUS_INVALID /* indicates an invalid entry, or invalid status value */ }; /* Use a tagged union for schedule entries. Not always space optimal, but saves * lots of error-prone pointer arithmetic and makes scanning the schedule easy. */ struct MPIDU_Sched_entry { enum MPIDU_Sched_entry_type type; enum MPIDU_Sched_entry_status status; int is_barrier; union { struct MPIDU_Sched_send send; struct MPIDU_Sched_recv recv; struct MPIDU_Sched_reduce reduce; struct MPIDU_Sched_copy copy; /* nop entries have no args */ struct MPIDU_Sched_cb cb; } u; }; struct MPIDU_Sched { size_t size; /* capacity (in entries) of the entries array */ size_t idx; /* index into entries array of first yet-outstanding entry */ int num_entries; /* number of populated entries, num_entries <= size */ int tag; MPID_Request *req; /* really needed? could cause MT problems... */ struct MPIDU_Sched_entry *entries; struct MPIDU_Sched *next; /* linked-list next pointer */ struct MPIDU_Sched *prev; /* linked-list next pointer */ }; /* prototypes */ int MPIDU_Sched_progress(int *made_progress); int MPIDU_Sched_are_pending(void); #endif /* !defined(MPID_SCHED_H_INCLUDED) */