@@ -60,6 +60,39 @@ struct GenericKernelTy;
6060struct GenericDeviceTy ;
6161struct RecordReplayTy ;
6262
63+ namespace Plugin {
64+ // / Create a success error. This is the same as calling Error::success(), but
65+ // / it is recommended to use this one for consistency with Plugin::error() and
66+ // / Plugin::check().
67+ static inline Error success () { return Error::success (); }
68+
69+ // / Create an Offload error.
70+ template <typename ... ArgsTy>
71+ static Error error (error::ErrorCode Code, const char *ErrFmt, ArgsTy... Args) {
72+ return error::createOffloadError (Code, ErrFmt, Args...);
73+ }
74+
75+ inline Error error (error::ErrorCode Code, const char *S) {
76+ return make_error<error::OffloadError>(Code, S);
77+ }
78+
79+ inline Error error (error::ErrorCode Code, Error &&OtherError,
80+ const char *Context) {
81+ return error::createOffloadError (Code, std::move (OtherError), Context);
82+ }
83+
84+ // / Check the plugin-specific error code and return an error or success
85+ // / accordingly. In case of an error, create a string error with the error
86+ // / description. The ErrFmt should follow the format:
87+ // / "Error in <function name>[<optional info>]: %s"
88+ // / The last format specifier "%s" is mandatory and will be used to place the
89+ // / error code's description. Notice this function should be only called from
90+ // / the plugin-specific code.
91+ // / TODO: Refactor this, must be defined individually by each plugin.
92+ template <typename ... ArgsTy>
93+ static Error check (int32_t ErrorCode, const char *ErrFmt, ArgsTy... Args);
94+ } // namespace Plugin
95+
6396// / Class that wraps the __tgt_async_info to simply its usage. In case the
6497// / object is constructed without a valid __tgt_async_info, the object will use
6598// / an internal one and will synchronize the current thread with the pending
@@ -1219,6 +1252,20 @@ struct GenericPluginTy {
12191252 virtual Expected<bool > isELFCompatible (uint32_t DeviceID,
12201253 StringRef Image) const = 0;
12211254
1255+ virtual Error flushQueueImpl (omp_interop_val_t *Interop) {
1256+ return Plugin::success ();
1257+ }
1258+
1259+ virtual Error syncBarrierImpl (omp_interop_val_t *Interop) {
1260+ return Plugin::error (error::ErrorCode::UNSUPPORTED,
1261+ " sync_barrier not supported" );
1262+ }
1263+
1264+ virtual Error asyncBarrierImpl (omp_interop_val_t *Interop) {
1265+ return Plugin::error (error::ErrorCode::UNSUPPORTED,
1266+ " async_barrier not supported" );
1267+ }
1268+
12221269protected:
12231270 // / Indicate whether a device id is valid.
12241271 bool isValidDeviceId (int32_t DeviceId) const {
@@ -1370,31 +1417,54 @@ struct GenericPluginTy {
13701417 // / Create OpenMP interop with the given interop context
13711418 omp_interop_val_t *create_interop (int32_t ID, int32_t InteropContext,
13721419 interop_spec_t *InteropSpec) {
1420+ assert (InteropSpec && " Interop spec is null" );
13731421 auto &Device = getDevice (ID);
13741422 return Device.createInterop (InteropContext, *InteropSpec);
13751423 }
13761424
13771425 // / Release OpenMP interop object
13781426 int32_t release_interop (int32_t ID, omp_interop_val_t *Interop) {
1427+ assert (Interop && " Interop is null" );
1428+ assert (Interop->DeviceId == ID && " Interop does not match device id" );
13791429 auto &Device = getDevice (ID);
13801430 return Device.releaseInterop (Interop);
13811431 }
13821432
13831433 // / Flush the queue associated with the interop object if necessary
1384- virtual int32_t flush_queue (omp_interop_val_t *Interop) {
1434+ int32_t flush_queue (omp_interop_val_t *Interop) {
1435+ assert (Interop && " Interop is null" );
1436+ auto Err = flushQueueImpl (Interop);
1437+ if (Err) {
1438+ REPORT (" Failure to flush interop object " DPxMOD " queue: %s\n " ,
1439+ DPxPTR (Interop), toString (std::move (Err)).c_str ());
1440+ return OFFLOAD_FAIL;
1441+ }
13851442 return OFFLOAD_SUCCESS;
13861443 }
1387-
1388- // / Queue a synchronous barrier in the queue associated with the interop
1444+ // / Perform a host synchronization with the queue associated with the interop
13891445 // / object and wait for it to complete.
1390- virtual int32_t sync_barrier (omp_interop_val_t *Interop) {
1391- return OFFLOAD_FAIL;
1446+ int32_t sync_barrier (omp_interop_val_t *Interop) {
1447+ assert (Interop && " Interop is null" );
1448+ auto Err = syncBarrierImpl (Interop);
1449+ if (Err) {
1450+ REPORT (" Failure to synchronize interop object " DPxMOD " : %s\n " ,
1451+ DPxPTR (Interop), toString (std::move (Err)).c_str ());
1452+ return OFFLOAD_FAIL;
1453+ }
1454+ return OFFLOAD_SUCCESS;
13921455 }
13931456
13941457 // / Queue an asynchronous barrier in the queue associated with the interop
13951458 // / object and return immediately.
1396- virtual int32_t async_barrier (omp_interop_val_t *Interop) {
1397- return OFFLOAD_FAIL;
1459+ int32_t async_barrier (omp_interop_val_t *Interop) {
1460+ assert (Interop && " Interop is null" );
1461+ auto Err = asyncBarrierImpl (Interop);
1462+ if (Err) {
1463+ REPORT (" Failure to queue barrier in interop object " DPxMOD " : %s\n " ,
1464+ DPxPTR (Interop), toString (std::move (Err)).c_str ());
1465+ return OFFLOAD_FAIL;
1466+ }
1467+ return OFFLOAD_SUCCESS;
13981468 }
13991469
14001470private:
@@ -1429,39 +1499,6 @@ struct GenericPluginTy {
14291499 RecordReplayTy *RecordReplay;
14301500};
14311501
1432- namespace Plugin {
1433- // / Create a success error. This is the same as calling Error::success(), but
1434- // / it is recommended to use this one for consistency with Plugin::error() and
1435- // / Plugin::check().
1436- static inline Error success () { return Error::success (); }
1437-
1438- // / Create an Offload error.
1439- template <typename ... ArgsTy>
1440- static Error error (error::ErrorCode Code, const char *ErrFmt, ArgsTy... Args) {
1441- return error::createOffloadError (Code, ErrFmt, Args...);
1442- }
1443-
1444- inline Error error (error::ErrorCode Code, const char *S) {
1445- return make_error<error::OffloadError>(Code, S);
1446- }
1447-
1448- inline Error error (error::ErrorCode Code, Error &&OtherError,
1449- const char *Context) {
1450- return error::createOffloadError (Code, std::move (OtherError), Context);
1451- }
1452-
1453- // / Check the plugin-specific error code and return an error or success
1454- // / accordingly. In case of an error, create a string error with the error
1455- // / description. The ErrFmt should follow the format:
1456- // / "Error in <function name>[<optional info>]: %s"
1457- // / The last format specifier "%s" is mandatory and will be used to place the
1458- // / error code's description. Notice this function should be only called from
1459- // / the plugin-specific code.
1460- // / TODO: Refactor this, must be defined individually by each plugin.
1461- template <typename ... ArgsTy>
1462- static Error check (int32_t ErrorCode, const char *ErrFmt, ArgsTy... Args);
1463- } // namespace Plugin
1464-
14651502// / Auxiliary interface class for GenericDeviceResourceManagerTy. This class
14661503// / acts as a reference to a device resource, such as a stream, and requires
14671504// / some basic functions to be implemented. The derived class should define an
0 commit comments