Skip to content

Commit 3b13421

Browse files
committed
[OpenMP] fix issues defining external emissary APIs by defining weak references for EmissaryMPI, EmissaryReserved, and EmissaryHDF5
1 parent 49d15cc commit 3b13421

File tree

9 files changed

+93
-108
lines changed

9 files changed

+93
-108
lines changed

offload/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,8 @@ if(OFFLOAD_ENABLE_EMISSARY_APIS)
436436
add_definitions(-DOFFLOAD_ENABLE_EMISSARY_APIS)
437437
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/DeviceRTL/include/EmissaryIds.h
438438
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/clang/${LLVM_VERSION_MAJOR}/include)
439+
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/DeviceRTL/include/EmissaryMPI.h
440+
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/clang/${LLVM_VERSION_MAJOR}/include)
439441
endif()
440442

441443
# Build offloading plugins and device RTLs if they are available.

offload/DeviceRTL/include/EmissaryIds.h

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ typedef enum {
2020
EMIS_ID_PRINT,
2121
EMIS_ID_MPI,
2222
EMIS_ID_HDF5,
23+
EMIS_ID_RESERVE,
2324
} offload_emis_id_t;
2425

2526
typedef enum {
@@ -29,12 +30,6 @@ typedef enum {
2930
_ockl_asan_report_idx,
3031
} offload_emis_print_t;
3132

32-
typedef enum {
33-
_MPI_INVALID,
34-
_MPI_Send_idx,
35-
_MPI_Recv_idx,
36-
} offload_emis_mpi_t;
37-
3833
/// The vargs function used by emissary API device stubs
3934
unsigned long long _emissary_exec(unsigned long long, ...);
4035

@@ -59,28 +54,23 @@ typedef enum {
5954
_FortranAStopStatementText_idx,
6055
} offload_emis_fortrt_idx;
6156

62-
// mpi.h (needed for MPI types) will not compile while building DeviceRTL,
63-
// So emissary stubs for MPI functions can NOT be in libomptarget.bc.
64-
// These are skipped whild building DeviceRTL because compilation of DeviceRTL
65-
// does not have include mpi.h. The user will build these stubs on their
66-
// device pass when they include EmissaryIds.h.
57+
/// This structure is created by emisExtractArgBuf to make it easier
58+
/// to get values from the data buffer passed by rpc.
59+
typedef struct {
60+
unsigned int DataLen;
61+
unsigned int NumArgs;
62+
unsigned int emisid;
63+
unsigned int emisfnid;
64+
unsigned long long data_not_used;
65+
char *keyptr;
66+
char *argptr;
67+
char *strptr;
68+
} emisArgBuf_t;
69+
70+
typedef unsigned long long emis_return_t;
71+
typedef unsigned long long emis_argptr_t;
72+
typedef emis_return_t emisfn_t(void *, ...);
6773

68-
#if defined(__NVPTX__) || defined(__AMDGCN__)
69-
#if defined(__has_include)
70-
#if __has_include("mpi.h")
71-
#include "mpi.h"
72-
extern "C" int MPI_Send(const void *buf, int count, MPI_Datatype datatype,
73-
int dest, int tag, MPI_Comm comm) {
74-
return (int)_emissary_exec(_PACK_EMIS_IDS(EMIS_ID_MPI, _MPI_Send_idx), buf,
75-
count, datatype, dest, tag, comm);
76-
}
77-
extern "C" int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source,
78-
int tag, MPI_Comm comm, MPI_Status *st) {
79-
return (int)_emissary_exec(_PACK_EMIS_IDS(EMIS_ID_MPI, _MPI_Recv_idx), buf,
80-
count, datatype, source, tag, comm, st);
81-
}
82-
#endif
83-
#endif
84-
#endif
74+
#define MAXVARGS 32
8575

8676
#endif // OFFLOAD_EMISSARY_IDS_H

offload/plugins-nextgen/common/src/EmissaryMPI.cpp renamed to offload/DeviceRTL/include/EmissaryMPI.h

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
1-
//===---- offload/plugins-nextgen/common/src/EmissaryFortrt.cpp ----------===//
1+
//===--------------- offload/DeviceRTL/include/EmissaryMPI.h --------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// Host support for Fortran runtime Emissary API
9+
// EmissaryMPI.h This include must be included by MPI application
1010
//
1111
//===----------------------------------------------------------------------===//
12-
#include "PluginInterface.h"
13-
#include "RPC.h"
14-
#include "Shared/Debug.h"
15-
#include "Shared/RPCOpcodes.h"
16-
#include "shared/rpc.h"
17-
#include "shared/rpc_opcodes.h"
18-
#include "../../../DeviceRTL/include/EmissaryIds.h"
19-
#include "Emissary.h"
20-
#include <assert.h>
21-
#include <cstring>
22-
#include <ctype.h>
23-
#include <list>
24-
#include <mpi.h>
12+
#include "EmissaryIds.h"
2513
#include <stdarg.h>
26-
#include <stdbool.h>
27-
#include <stddef.h>
28-
#include <stdint.h>
29-
#include <stdio.h>
30-
#include <stdlib.h>
31-
#include <string.h>
32-
#include <tuple>
33-
#include <vector>
3414

15+
typedef enum {
16+
_MPI_INVALID,
17+
_MPI_Send_idx,
18+
_MPI_Recv_idx,
19+
} offload_emis_mpi_t;
20+
21+
/// Device stubs that call _emissary_exec using identical host API interface
22+
#if defined(__NVPTX__) || defined(__AMDGCN__)
23+
extern "C" int MPI_Send(const void *buf, int count, MPI_Datatype datatype,
24+
int dest, int tag, MPI_Comm comm) {
25+
return (int)_emissary_exec(_PACK_EMIS_IDS(EMIS_ID_MPI, _MPI_Send_idx), buf,
26+
count, datatype, dest, tag, comm);
27+
}
28+
extern "C" int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source,
29+
int tag, MPI_Comm comm, MPI_Status *st) {
30+
return (int)_emissary_exec(_PACK_EMIS_IDS(EMIS_ID_MPI, _MPI_Recv_idx), buf,
31+
count, datatype, source, tag, comm, st);
32+
}
33+
#endif
34+
35+
/// Host variadic wrapper functions.
3536
extern "C" {
3637
extern int V_MPI_Send(void *fnptr, ...) {
3738
va_list args;
@@ -61,11 +62,8 @@ extern int V_MPI_Recv(void *fnptr, ...) {
6162
return rval;
6263
}
6364

64-
emis_return_t EmissaryMPI(char *data, emisArgBuf_t *ab) {
65-
uint64_t *a[MAXVARGS];
66-
if (EmissaryBuildVargs(ab->NumArgs, ab->keyptr, ab->argptr, ab->strptr,
67-
&ab->data_not_used, &a[0]) != _RC_SUCCESS)
68-
return (emis_return_t)0;
65+
/// EmissaryMPI function selector
66+
emis_return_t EmissaryMPI(char *data, emisArgBuf_t *ab, emis_argptr_t *a[]) {
6967

7068
switch (ab->emisfnid) {
7169
case _MPI_Send_idx: {

offload/libomptarget/exports

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ VERS1.0 {
9797
__llvmPushCallConfiguration;
9898
__llvmPopCallConfiguration;
9999
llvmLaunchKernel;
100+
EmissaryBuildVargs;
101+
EmissaryHDF5;
102+
EmissaryReserve;
103+
EmissaryMPI;
100104
local:
101105
*;
102106
};

offload/plugins-nextgen/common/CMakeLists.txt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,6 @@ if(OFFLOAD_ENABLE_EMISSARY_APIS)
55
src/EmissaryFortrt.cpp
66
src/EmissaryPrint.cpp
77
)
8-
set(OFFLOAD_EMISSARY_MPI_INCLUDE ""
9-
CACHE STRING "MPI include directory for building MPI Emissary API")
10-
# dont enable the MPI Emissary api unless we have an MPI include dir
11-
# that contains mpi.h needed to build the variadic wrappers.
12-
if(OFFLOAD_EMISSARY_MPI_INCLUDE)
13-
list(APPEND emissary_sources src/EmissaryMPI.cpp)
14-
endif()
158
endif()
169

1710
# NOTE: Don't try to build `PluginInterface` using `add_llvm_library` because we
@@ -44,9 +37,6 @@ target_link_libraries(PluginCommon PRIVATE llvm-libc-common-utilities)
4437
if(OFFLOAD_ENABLE_EMISSARY_APIS)
4538
target_link_libraries(PluginCommon PRIVATE flang_rt.runtime
4639
-L${CMAKE_BINARY_DIR}/../../lib -L${CMAKE_INSTALL_PREFIX}/lib)
47-
if(OFFLOAD_EMISSARY_MPI_INCLUDE)
48-
target_include_directories(PluginCommon PUBLIC ${OFFLOAD_EMISSARY_MPI_INCLUDE})
49-
endif()
5040
endif()
5141
if(TARGET llvmlibc_rpc_server AND ${LIBOMPTARGET_GPU_LIBC_SUPPORT})
5242
target_link_libraries(PluginCommon PRIVATE llvmlibc_rpc_server)

offload/plugins-nextgen/common/include/Emissary.h

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,7 @@
1414
#ifndef OFFLOAD_EMISSARY_H
1515
#define OFFLOAD_EMISSARY_H
1616

17-
/// This structure is created by emisExtractArgBuf to make it easier
18-
/// to get values from the data buffer passed by rpc.
19-
typedef struct {
20-
unsigned int DataLen;
21-
unsigned int NumArgs;
22-
unsigned int emisid;
23-
unsigned int emisfnid;
24-
size_t data_not_used;
25-
char *keyptr;
26-
char *argptr;
27-
char *strptr;
28-
} emisArgBuf_t;
29-
30-
typedef unsigned long long emis_return_t;
31-
typedef emis_return_t emisfn_t(void *, ...);
32-
33-
// MAXVARGS is the maximum number of args in an emissary function
34-
// To increase this number, update EmissaryCallFnptr below
35-
#define MAXVARGS 32
17+
#include "../../../DeviceRTL/include/EmissaryIds.h"
3618

3719
extern "C" {
3820

@@ -46,10 +28,16 @@ emis_return_t EmissaryFortrt(char *data, emisArgBuf_t *ab);
4628
emis_return_t EmissaryPrint(char *data, emisArgBuf_t *ab);
4729

4830
/// Called by Emissary for all MPI emissary API functions
49-
emis_return_t EmissaryMPI(char *data, emisArgBuf_t *ab);
31+
__attribute((weak)) emis_return_t EmissaryMPI(char *data, emisArgBuf_t *ab,
32+
emis_argptr_t *arg[MAXVARGS]);
5033

5134
/// Called by Emissary for all HDF5 Emissary API functions
52-
emis_return_t EmissaryHDF5(char *data, emisArgBuf_t *ab);
35+
__attribute((weak)) emis_return_t EmissaryHDF5(char *data, emisArgBuf_t *ab,
36+
emis_argptr_t *arg[MAXVARGS]);
37+
38+
/// Support externally supplied emissary API
39+
__attribute((weak)) emis_return_t EmissaryReserve(char *data, emisArgBuf_t *ab,
40+
emis_argptr_t *arg[MAXVARGS]);
5341

5442
/// Called by Emissary to build the emisArgBuf_t structure from the emissary
5543
/// data buffer sent to the CPU by rpc. This buffer is created by clang CodeGen
@@ -66,15 +54,15 @@ void *getfnptr(char *val);
6654

6755
/// Builds the array of pointers passed to V_ functions
6856
uint32_t EmissaryBuildVargs(int NumArgs, char *keyptr, char *dataptr,
69-
char *strptr, size_t *data_not_used,
70-
uint64_t *a[MAXVARGS]);
57+
char *strptr, unsigned long long *data_not_used,
58+
emis_argptr_t *a[MAXVARGS]);
7159

7260
} // end extern "C"
7361

7462
/// Call the associated V_ function
7563
template <typename T, typename FT>
7664
extern T EmissaryCallFnptr(uint32_t NumArgs, void *fnptr,
77-
uint64_t *a[MAXVARGS]);
65+
emis_argptr_t *a[MAXVARGS]);
7866

7967
// Error return codes (deprecated)
8068
typedef enum service_rc {
@@ -140,7 +128,7 @@ enum TypeID {
140128

141129
template <typename T, typename FT>
142130
extern T EmissaryCallFnptr(uint32_t NumArgs, void *fnptr,
143-
uint64_t *a[MAXVARGS]) {
131+
emis_argptr_t *a[MAXVARGS]) {
144132
T rv;
145133
FT *vfnptr = (FT *)fnptr;
146134
switch (NumArgs) {

offload/plugins-nextgen/common/src/Emissary.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ extern "C" emis_return_t Emissary(char *data) {
2323
emisArgBuf_t ab;
2424
emisExtractArgBuf(data, &ab);
2525
emis_return_t result = 0;
26+
emis_argptr_t *args[MAXVARGS]; // FIXME use malloc here
2627

2728
switch (ab.emisid) {
2829
case EMIS_ID_INVALID: {
@@ -39,13 +40,24 @@ extern "C" emis_return_t Emissary(char *data) {
3940
break;
4041
}
4142
case EMIS_ID_MPI: {
42-
result = EmissaryMPI(data, &ab);
43+
if (EmissaryBuildVargs(ab.NumArgs, ab.keyptr, ab.argptr, ab.strptr,
44+
&ab.data_not_used, &args[0]) != _RC_SUCCESS)
45+
return (emis_return_t)0;
46+
result = EmissaryMPI(data, &ab, args);
4347
break;
4448
}
4549
case EMIS_ID_HDF5: {
46-
// result = EmissaryHDF5(data, &ab);
47-
result = 0;
48-
fprintf(stderr, "Support for HDF5 Emissary API is in development\n");
50+
if (EmissaryBuildVargs(ab.NumArgs, ab.keyptr, ab.argptr, ab.strptr,
51+
&ab.data_not_used, &args[0]) != _RC_SUCCESS)
52+
return (emis_return_t)0;
53+
result = EmissaryHDF5(data, &ab, args);
54+
break;
55+
}
56+
case EMIS_ID_RESERVE: {
57+
if (EmissaryBuildVargs(ab.NumArgs, ab.keyptr, ab.argptr, ab.strptr,
58+
&ab.data_not_used, &args[0]) != _RC_SUCCESS)
59+
return (emis_return_t)0;
60+
result = EmissaryReserve(data, &ab, args);
4961
break;
5062
}
5163
default:
@@ -114,8 +126,9 @@ extern "C" void *getfnptr(char *val) {
114126

115127
// build argument array
116128
extern "C" uint32_t EmissaryBuildVargs(int NumArgs, char *keyptr, char *dataptr,
117-
char *strptr, size_t *data_not_used,
118-
uint64_t *a[MAXVARGS]) {
129+
char *strptr,
130+
unsigned long long *data_not_used,
131+
emis_argptr_t *a[MAXVARGS]) {
119132
size_t num_bytes;
120133
size_t bytes_consumed;
121134
size_t strsz;
@@ -145,9 +158,9 @@ extern "C" uint32_t EmissaryBuildVargs(int NumArgs, char *keyptr, char *dataptr,
145158
return _RC_DATA_USED_ERROR;
146159

147160
if (num_bytes == 4)
148-
a[argcount] = (uint64_t *)getuint32(dataptr);
161+
a[argcount] = (emis_argptr_t *)getuint32(dataptr);
149162
else
150-
a[argcount] = (uint64_t *)getuint64(dataptr);
163+
a[argcount] = (emis_argptr_t *)getuint64(dataptr);
151164

152165
break;
153166

@@ -163,9 +176,9 @@ extern "C" uint32_t EmissaryBuildVargs(int NumArgs, char *keyptr, char *dataptr,
163176
return _RC_DATA_USED_ERROR;
164177

165178
if (num_bytes == 4)
166-
a[argcount] = (uint64_t *)getuint32(dataptr);
179+
a[argcount] = (emis_argptr_t *)getuint32(dataptr);
167180
else
168-
a[argcount] = (uint64_t *)getuint64(dataptr);
181+
a[argcount] = (emis_argptr_t *)getuint64(dataptr);
169182

170183
break;
171184

@@ -176,7 +189,7 @@ extern "C" uint32_t EmissaryBuildVargs(int NumArgs, char *keyptr, char *dataptr,
176189
strsz = (size_t)*(unsigned int *)dataptr;
177190
if ((*data_not_used) < bytes_consumed)
178191
return _RC_DATA_USED_ERROR;
179-
a[argcount] = (uint64_t *)((char *)strptr);
192+
a[argcount] = (emis_argptr_t *)((char *)strptr);
180193

181194
} else {
182195
num_bytes = 8;
@@ -189,7 +202,7 @@ extern "C" uint32_t EmissaryBuildVargs(int NumArgs, char *keyptr, char *dataptr,
189202
if ((*data_not_used) < bytes_consumed)
190203
return _RC_DATA_USED_ERROR;
191204

192-
a[argcount] = (uint64_t *)getuint64(dataptr);
205+
a[argcount] = (emis_argptr_t *)getuint64(dataptr);
193206
}
194207
break;
195208

offload/plugins-nextgen/common/src/EmissaryFortrt.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ extern "C" emis_return_t EmissaryFortrt(char *data, emisArgBuf_t *ab) {
232232
if (ab->NumArgs <= 0)
233233
return _RC_ERROR_INVALID_REQUEST;
234234

235-
uint64_t *a[MAXVARGS];
235+
emis_argptr_t *a[MAXVARGS];
236236
if (EmissaryBuildVargs(ab->NumArgs, ab->keyptr, ab->argptr, ab->strptr,
237237
&ab->data_not_used, a) != _RC_SUCCESS)
238238
return _RC_ERROR_INVALID_REQUEST;
@@ -254,7 +254,7 @@ extern "C" emis_return_t EmissaryFortrt(char *data, emisArgBuf_t *ab) {
254254
fprintf(stderr, "MALLOC FAILED for c_ptr size:%ld \n", slen);
255255
std::strncpy(c_ptr, (char *)a[5], slen - 1);
256256
c_ptr[slen - 1] = (char)0;
257-
a[5] = (uint64_t *)c_ptr;
257+
a[5] = (emis_argptr_t *)c_ptr;
258258
break;
259259
}
260260
case _FortranAioOutputAscii_idx: {
@@ -266,7 +266,7 @@ extern "C" emis_return_t EmissaryFortrt(char *data, emisArgBuf_t *ab) {
266266
fprintf(stderr, "MALLOC FAILED for c_ptr size:%ld \n", slen);
267267
std::strncpy(c_ptr, (char *)a[5], slen - 1);
268268
c_ptr[slen - 1] = (char)0;
269-
a[5] = (uint64_t *)c_ptr;
269+
a[5] = (emis_argptr_t *)c_ptr;
270270

271271
break;
272272
}
@@ -378,7 +378,7 @@ extern "C" emis_return_t EmissaryFortrt(char *data, emisArgBuf_t *ab) {
378378
for (auto q : *_deferred_fns_ptr) {
379379
if ((thread_num == q->thread_num) && (team_num == q->team_num)) {
380380
for (uint32_t i = 0; i < q->NumArgs; i++)
381-
a[i] = (uint64_t *)q->arg_array[i];
381+
a[i] = (emis_argptr_t *)q->arg_array[i];
382382
q->return_value = EmissaryCallFnptr<emis_return_t, emisfn_t>(
383383
q->NumArgs, q->fnptr, a);
384384
}

offload/plugins-nextgen/common/src/EmissaryPrint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ static service_rc emissary_pfAddFloat(emissary_ValistExt_t *valist,
212212
static service_rc emissary_pfBuildValist(emissary_ValistExt_t *valist,
213213
int NumArgs, char *keyptr,
214214
char *dataptr, char *strptr,
215-
size_t *data_not_used) {
215+
unsigned long long *data_not_used) {
216216
emissary_pfRegSaveArea_t *regs;
217217
size_t regs_size = sizeof(*regs);
218218
regs = (emissary_pfRegSaveArea_t *)malloc(regs_size);

0 commit comments

Comments
 (0)