OpenMP-Examples/devices/lambda_expressions.tex
2022-04-18 15:02:25 -07:00

53 lines
2.7 KiB
TeX

\pagebreak
\section{Lambda Expressions}
\label{sec:lambda_expressions}
\index{lambda expressions}
\cppspecificstart
The following example illustrates the usage of lambda expressions and their
corresponding closure objects within a \scode{target} region.
In CASE 1, a lambda expression is defined inside a \scode{target} construct
that implicitly maps the structure \textit{s}. Inside the construct, the
lambda captures (by reference) the corresponding \textit{s}, and the resulting
closure object is assigned to \textit{lambda1}. When the call operator is
invoked on \textit{lambda1}, the captured reference to \textit{s} is used in
the call. The modified \textit{s} is then copied back to the host device on
exit from the \scode{target} construct.
In CASE 2, a lambda expression is instead defined before the \scode{target}
construct and captures (by copy) the pointer \textit{sp}. A
\scode{target}~\scode{data} construct is used to first map the structure, and
then the \scode{target} construct implicitly maps the closure object
referenced by \textit{lambda2}, a zero-length array section based on the
structure pointer \textit{sp}, and a zero-length array section based on the
captured pointer in the closure object. The implicit maps result in attached
pointers to the corresponding structure. The call for \textit{lambda2} inside
the \scode{target} construct will access \textit{sp->a} and \textit{sp->b}
from the corresponding structure.
CASE 3 is similar to CASE 2, except \textit{s} is instead captured by
reference by the lambda expression. As for CASE 2, the structure is first
mapped by an enclosing \scode{target}~\scode{data} construct, and then the
\scode{target} construct implicitly maps \textit{s} and the closure object
referenced by \textit{lambda3}. The effect of the map is to make the
the call for \textit{lambda3} refer to the corresponding \textit{s} inside the
\scode{target} construct rather than the original \textit{s}.
In CASE 4, the program defines a static variable \textit{ss} of the same
structure type as \textit{s}. While the body of the lambda expression refers
to \textit{ss}, it is not captured. In order for \textit{lambda4} to be
callable in the \scode{target} region, the reference to \textit{ss} should be
to a device copy of \textit{ss} that also has static storage. This is achieved
with the use of the \scode{declare}~\scode{target} directive. Inside the
\scode{target} construct, all references to \textit{ss}, including in the
\textit{lambda4()} call, will refer to the corresponding \textit{ss} that
results from the \scode{declare}~\scode{target} directive. The \scode{always}
modifier is used on the \scode{map} clause to transfer the updated values for
the structure back to the host device.
\cppnexample[5.0]{lambda_expressions}{1}
\cppspecificend