%\pagebreak \section{\kcode{interop} Construct} \label{sec:interop} \index{constructs!interop@\kcode{interop}} \index{interop construct@\kcode{interop} construct} The \kcode{interop} construct allows OpenMP to interoperate with foreign runtime environments. In the example below, asynchronous cuda memory copies and a \ucode{cublasDaxpy} routine are executed in a cuda stream. Also, an asynchronous target task execution (having a \kcode{nowait} clause) and two explicit tasks are executed through OpenMP directives. Scheduling dependences (synchronization) are imposed on the foreign stream and the OpenMP tasks through \kcode{depend} clauses. \index{interop construct@\kcode{interop} construct!init clause@\kcode{init} clause} \index{init clause@\kcode{init} clause} \index{clauses!init@\kcode{init}} \index{interop construct@\kcode{interop} construct!depend clause@\kcode{depend} clause} \index{depend clause@\kcode{depend} clause} \index{clauses!depend@\kcode{depend}} First, an interop object, \ucode{obj}, is initialized for synchronization by including the \kcode{targetsync} \plc{interop-type} in the interop \kcode{init} clause (\kcode{init(targetsync, \ucode{obj})}). The object provides access to the foreign runtime. The \kcode{depend} clause provides a dependence behavior for foreign tasks associated with a valid object. \index{routines!omp_get_interop_int@\kcode{omp_get_interop_int}} \index{omp_get_interop_int routine@\kcode{omp_get_interop_int} routine} Next, the \kcode{omp_get_interop_int} routine is used to extract the foreign runtime id (\kcode{omp_ipr_fr_id}), and a test in the next statement ensures that the cuda runtime (\kcode{omp_ifr_cuda}) is available. \index{routines!omp_get_interop_ptr@\kcode{omp_get_interop_ptr}} \index{omp_get_interop_ptr routine@\kcode{omp_get_interop_ptr} routine} \index{interop construct@\kcode{interop} construct!destroy clause@\kcode{destroy} clause} \index{destroy clause@\kcode{destroy} clause} \index{clauses!destroy@\kcode{destroy}} Within the block for executing the \ucode{cublasDaxpy} routine, a stream is acquired with the \kcode{omp_get_interop_ptr} routine, which returns a cuda stream (\ucode{s}). The stream is included in the cublas handle, and used directly in the asynchronous memory routines. The following \kcode{interop} construct, with the \kcode{destroy} clause, ensures that the foreign tasks have completed. \cexample[5.1]{interop}{1}