Fix parallel build of examples/charm++/user-driven-interop
[charm.git] / src / conv-core / conv-rdma.c
blobdcc90ce55e0042ba8de712850de738015abc7be1
1 /* Support for Direct Nocopy API (Generic Implementation)
2 * Specific implementations are in arch/layer/machine-onesided.{h,c}
3 */
4 #include "converse.h"
6 // Methods required to keep the Nocopy Direct API functional on non-LRTS layers
7 #if !CMK_USE_LRTS
8 void CmiSetRdmaCommonInfo(void *info, const void *ptr, int size) {
11 int CmiGetRdmaCommonInfoSize() {
12 return 0;
14 #endif
16 #if !CMK_ONESIDED_IMPL
17 /* Support for generic implementation */
19 // Function Pointer to Acknowledement handler function for the Direct API
20 RdmaAckCallerFn ncpyDirectAckHandlerFn;
22 // An Rget initiator PE sends this message to the target PE that will be the source of the data
23 typedef struct _converseRdmaMsg {
24 char cmicore[CmiMsgHeaderSizeBytes];
25 } ConverseRdmaMsg;
27 static int get_request_handler_idx;
28 static int put_data_handler_idx;
30 // Invoked when this PE has to send a large array for an Rget
31 static void getRequestHandler(ConverseRdmaMsg *getReqMsg){
33 NcpyOperationInfo *ncpyOpInfo = (NcpyOperationInfo *)((char *)(getReqMsg) + sizeof(ConverseRdmaMsg));
35 resetNcpyOpInfoPointers(ncpyOpInfo);
37 ncpyOpInfo->freeMe = CMK_DONT_FREE_NCPYOPINFO;
39 // Get is implemented internally using a call to Put
40 CmiIssueRput(ncpyOpInfo);
43 // Invoked when this PE receives a large array as the target of an Rput or the initiator of an Rget
44 static void putDataHandler(ConverseRdmaMsg *payloadMsg) {
46 NcpyOperationInfo *ncpyOpInfo = (NcpyOperationInfo *)((char *)payloadMsg + sizeof(ConverseRdmaMsg));
48 resetNcpyOpInfoPointers(ncpyOpInfo);
50 // copy the received messsage into the user's destination address
51 memcpy((char *)ncpyOpInfo->destPtr,
52 (char *)payloadMsg + sizeof(ConverseRdmaMsg) + ncpyOpInfo->ncpyOpInfoSize,
53 ncpyOpInfo->srcSize);
55 // Invoke the destination ack
56 ncpyOpInfo->ackMode = CMK_DEST_ACK; // Only invoke the destination ack
57 ncpyOpInfo->freeMe = CMK_DONT_FREE_NCPYOPINFO;
58 ncpyDirectAckHandlerFn(ncpyOpInfo);
61 // Rget/Rput operations are implemented as normal converse messages
62 // This method is invoked during converse initialization to initialize these message handlers
63 void CmiOnesidedDirectInit(void) {
64 get_request_handler_idx = CmiRegisterHandler((CmiHandler)getRequestHandler);
65 put_data_handler_idx = CmiRegisterHandler((CmiHandler)putDataHandler);
68 void CmiSetDirectNcpyAckHandler(RdmaAckCallerFn fn) {
69 ncpyDirectAckHandlerFn = fn;
72 void CmiIssueRget(NcpyOperationInfo *ncpyOpInfo) {
74 int ncpyOpInfoSize = ncpyOpInfo->ncpyOpInfoSize;
76 // Send a ConverseRdmaMsg to other PE requesting it to send the array
77 ConverseRdmaMsg *getReqMsg = (ConverseRdmaMsg *)CmiAlloc(sizeof(ConverseRdmaMsg) + ncpyOpInfoSize);
79 // copy the additional Info into the getReqMsg
80 memcpy((char *)getReqMsg + sizeof(ConverseRdmaMsg),
81 (char *)ncpyOpInfo,
82 ncpyOpInfoSize);
84 CmiSetHandler(getReqMsg, get_request_handler_idx);
85 CmiSyncSendAndFree(ncpyOpInfo->srcPe, sizeof(ConverseRdmaMsg) + ncpyOpInfoSize, getReqMsg);
87 // free original ncpyOpinfo
88 CmiFree(ncpyOpInfo);
91 void CmiIssueRput(NcpyOperationInfo *ncpyOpInfo) {
93 int ncpyOpInfoSize = ncpyOpInfo->ncpyOpInfoSize;
94 int size = ncpyOpInfo->srcSize;
96 // Send a ConverseRdmaMsg to the other PE sending the array
97 ConverseRdmaMsg *payloadMsg = (ConverseRdmaMsg *)CmiAlloc(sizeof(ConverseRdmaMsg) + ncpyOpInfoSize + size);
99 // copy the ncpyOpInfo into the recvMsg
100 memcpy((char *)payloadMsg + sizeof(ConverseRdmaMsg),
101 (char *)ncpyOpInfo,
102 ncpyOpInfoSize);
104 // copy the large array into the recvMsg
105 memcpy((char *)payloadMsg + sizeof(ConverseRdmaMsg) + ncpyOpInfoSize,
106 ncpyOpInfo->srcPtr,
107 size);
109 // Invoke the source ack
110 ncpyOpInfo->ackMode = CMK_SRC_ACK; // only invoke the source ack
112 ncpyDirectAckHandlerFn(ncpyOpInfo);
114 CmiSetHandler(payloadMsg, put_data_handler_idx);
115 CmiSyncSendAndFree(ncpyOpInfo->destPe,
116 sizeof(ConverseRdmaMsg) + ncpyOpInfoSize + size,
117 payloadMsg);
120 void CmiSetRdmaBufferInfo(void *info, const void *ptr, int size, unsigned short int mode) {}
122 void CmiDeregisterMem(const void *ptr, void *info, int pe, unsigned short int mode) {}
124 #else
126 // Support for sending an ack message for the Entry Method API
128 RdmaEMAckCallerFn ncpyEMAckHandlerFn; // P2P API ack handler function
130 RdmaAckCallerFn ncpyEMBcastAckHandlerFn; // BCast API ack handler function
132 RdmaAckCallerFn ncpyEMBcastPostAckHandlerFn; // BCast API ack handler function
134 static int invoke_entry_method_ack_handler_idx, ncpy_bcast_ack_handler_idx;
135 static int ncpy_bcast_post_handler_idx;
137 // Ack Message is typically used in case of reverse operation (when a reverse put is used instead of a get)
138 typedef struct _ackEntryMethodMsg{
139 char cmicore[CmiMsgHeaderSizeBytes];
140 void *ref;
141 } ackEntryMethodMsg;
143 // Handler invoked on receiving a ackEntryMethodMsg
144 // This handler invokes the ncpyEMAckHandler on the receiver side
145 static void ackEntryMethodHandler(ackEntryMethodMsg *msg) {
146 // Invoke the charm handler
147 ncpyEMAckHandlerFn(CmiMyPe(), msg->ref);
150 // This handler invokes the ncpyEMBcastAckHandler on the source (root node or intermediate nodes)
151 static void bcastAckHandler(ackEntryMethodMsg *msg) {
152 ncpyEMBcastAckHandlerFn(msg->ref);
155 static void bcastPostAckArrayHandler(ackEntryMethodMsg *msg) {
156 ncpyEMBcastPostAckHandlerFn(msg->ref);
159 // Method to create a ackEntryMethodMsg and send it
160 void CmiInvokeRemoteAckHandler(int pe, void *ref) {
161 ackEntryMethodMsg *msg = (ackEntryMethodMsg *)CmiAlloc(sizeof(ackEntryMethodMsg));
162 msg->ref = ref;
164 CmiSetHandler(msg, invoke_entry_method_ack_handler_idx);
165 CmiSyncSendAndFree(pe, sizeof(ackEntryMethodMsg), msg);
168 // Register converse handler for invoking ack on reverse operation
169 void CmiOnesidedDirectInit(void) {
170 invoke_entry_method_ack_handler_idx = CmiRegisterHandler((CmiHandler)ackEntryMethodHandler);
171 ncpy_bcast_ack_handler_idx = CmiRegisterHandler((CmiHandler)bcastAckHandler);
173 ncpy_bcast_post_handler_idx = CmiRegisterHandler((CmiHandler)bcastPostAckArrayHandler);
176 void CmiSetEMNcpyAckHandler(RdmaEMAckCallerFn fn, RdmaAckCallerFn bcastFn, RdmaAckCallerFn bcastArrayFn) {
177 // set the EM Ack caller function
178 ncpyEMAckHandlerFn = fn;
180 // set the EM Bcast Ack caller function
181 ncpyEMBcastAckHandlerFn = bcastFn;
183 // set the EM Bcast Post Ack caller function
184 ncpyEMBcastPostAckHandlerFn = bcastArrayFn;
187 void CmiInvokeBcastAckHandler(int pe, void *ref) {
189 ackEntryMethodMsg *msg = (ackEntryMethodMsg *)CmiAlloc(sizeof(ackEntryMethodMsg));
190 msg->ref = ref;
192 CmiSetHandler(msg, ncpy_bcast_ack_handler_idx);
193 CmiSyncSendAndFree(pe, sizeof(ackEntryMethodMsg), msg);
196 void CmiInvokeBcastPostAckHandler(int pe, void *ref) {
197 ackEntryMethodMsg *msg = (ackEntryMethodMsg *)CmiAlloc(sizeof(ackEntryMethodMsg));
198 msg->ref = ref;
200 CmiSetHandler(msg, ncpy_bcast_post_handler_idx);
201 CmiSyncSendAndFree(pe, sizeof(ackEntryMethodMsg), msg);
203 #endif