@@ -23,6 +23,62 @@ using namespace llvm;
2323using namespace omp ;
2424using namespace target ;
2525
26+ template <uint32_t NumLanes>
27+ rpc::Status handle_offload_opcodes (plugin::GenericDeviceTy &Device,
28+ rpc::Server::Port &Port) {
29+
30+ int Status = rpc::SUCCESS;
31+ switch (Port.get_opcode ()) {
32+ case RPC_MALLOC: {
33+ Port.recv_and_send ([&](rpc::Buffer *Buffer, uint32_t ) {
34+ Buffer->data [0 ] = reinterpret_cast <uintptr_t >(Device.allocate (
35+ Buffer->data [0 ], nullptr , TARGET_ALLOC_DEVICE_NON_BLOCKING));
36+ });
37+ break ;
38+ }
39+ case RPC_FREE: {
40+ Port.recv ([&](rpc::Buffer *Buffer, uint32_t ) {
41+ Device.free (reinterpret_cast <void *>(Buffer->data [0 ]),
42+ TARGET_ALLOC_DEVICE_NON_BLOCKING);
43+ });
44+ break ;
45+ }
46+ case OFFLOAD_HOST_CALL: {
47+ uint64_t Sizes[NumLanes] = {0 };
48+ unsigned long long Results[NumLanes] = {0 };
49+ void *Args[NumLanes] = {nullptr };
50+ Port.recv_n (Args, Sizes, [&](uint64_t Size) { return new char [Size]; });
51+ Port.recv ([&](rpc::Buffer *buffer, uint32_t ID) {
52+ using FuncPtrTy = unsigned long long (*)(void *);
53+ auto Func = reinterpret_cast <FuncPtrTy>(buffer->data [0 ]);
54+ Results[ID] = Func (Args[ID]);
55+ });
56+ Port.send ([&](rpc::Buffer *Buffer, uint32_t ID) {
57+ Buffer->data [0 ] = static_cast <uint64_t >(Results[ID]);
58+ delete[] reinterpret_cast <char *>(Args[ID]);
59+ });
60+ break ;
61+ }
62+ default :
63+ return rpc::UNHANDLED_OPCODE;
64+ break ;
65+ }
66+ return rpc::UNHANDLED_OPCODE;
67+ }
68+
69+ static rpc::Status handle_offload_opcodes (plugin::GenericDeviceTy &Device,
70+ rpc::Server::Port &Port,
71+ uint32_t NumLanes) {
72+ if (NumLanes == 1 )
73+ return handle_offload_opcodes<1 >(Device, Port);
74+ else if (NumLanes == 32 )
75+ return handle_offload_opcodes<32 >(Device, Port);
76+ else if (NumLanes == 64 )
77+ return handle_offload_opcodes<64 >(Device, Port);
78+ else
79+ return rpc::ERROR;
80+ }
81+
2682RPCServerTy::RPCServerTy (plugin::GenericPluginTy &Plugin)
2783 : Buffers(Plugin.getNumDevices()) {}
2884
@@ -78,43 +134,10 @@ Error RPCServerTy::runServer(plugin::GenericDeviceTy &Device) {
78134 if (!Port)
79135 return Error::success ();
80136
81- int Status = rpc::SUCCESS;
82- switch (Port->get_opcode ()) {
83- case RPC_MALLOC: {
84- Port->recv_and_send ([&](rpc::Buffer *Buffer, uint32_t ) {
85- Buffer->data [0 ] = reinterpret_cast <uintptr_t >(Device.allocate (
86- Buffer->data [0 ], nullptr , TARGET_ALLOC_DEVICE_NON_BLOCKING));
87- });
88- break ;
89- }
90- case RPC_FREE: {
91- Port->recv ([&](rpc::Buffer *Buffer, uint32_t ) {
92- Device.free (reinterpret_cast <void *>(Buffer->data [0 ]),
93- TARGET_ALLOC_DEVICE_NON_BLOCKING);
94- });
95- break ;
96- }
97- case OFFLOAD_HOST_CALL: {
98- uint64_t Sizes[64 ] = {0 };
99- unsigned long long Results[64 ] = {0 };
100- void *Args[64 ] = {nullptr };
101- Port->recv_n (Args, Sizes, [&](uint64_t Size) { return new char [Size]; });
102- Port->recv ([&](rpc::Buffer *buffer, uint32_t ID) {
103- using FuncPtrTy = unsigned long long (*)(void *);
104- auto Func = reinterpret_cast <FuncPtrTy>(buffer->data [0 ]);
105- Results[ID] = Func (Args[ID]);
106- });
107- Port->send ([&](rpc::Buffer *Buffer, uint32_t ID) {
108- Buffer->data [0 ] = static_cast <uint64_t >(Results[ID]);
109- delete[] reinterpret_cast <char *>(Args[ID]);
110- });
111- break ;
112- }
113- default :
114- // Let the `libc` library handle any other unhandled opcodes.
137+ int Status = handle_offload_opcodes (Device, *Port, Device.getWarpSize ());
138+ // Let the `libc` library handle any other unhandled opcodes.
139+ if (Status == rpc::UNHANDLED_OPCODE)
115140 Status = handle_libc_opcodes (*Port, Device.getWarpSize ());
116- break ;
117- }
118141 Port->close ();
119142
120143 if (Status != rpc::SUCCESS)
0 commit comments