1 /* Support for Direct Nocopy API (Generic Implementation)
2 * Specific implementations are in arch/layer/machine-onesided.{h,c}
6 // Methods required to keep the Nocopy Direct API functional on non-LRTS layers
8 void CmiSetRdmaCommonInfo(void *info
, const void *ptr
, int size
) {
11 int CmiGetRdmaCommonInfoSize() {
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
];
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
,
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
),
84 CmiSetHandler(getReqMsg
, get_request_handler_idx
);
85 CmiSyncSendAndFree(ncpyOpInfo
->srcPe
, sizeof(ConverseRdmaMsg
) + ncpyOpInfoSize
, getReqMsg
);
87 // free original 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
),
104 // copy the large array into the recvMsg
105 memcpy((char *)payloadMsg
+ sizeof(ConverseRdmaMsg
) + ncpyOpInfoSize
,
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
,
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
) {}
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
];
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
));
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
));
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
));
200 CmiSetHandler(msg
, ncpy_bcast_post_handler_idx
);
201 CmiSyncSendAndFree(pe
, sizeof(ackEntryMethodMsg
), msg
);