.. _readme-remote: .. default-domain:: chpl Remote Variable Declarations ============================ .. warning:: This work is under active development. As such, the interface and behavior of remote variables is unstable and expected to change. .. contents:: Introduction ------------ Remote variable declarations make it possible to store a particular variable on locale different from the one currently executing the code. Unlike plain variable declarations in tandem with the ``on`` statement, remote variables do not introduce a new scope. Specifically, consider the following program: .. code-block:: chapel on someOtherLocale { var myVar = 42; } writeln(myVar); // Error: myVar is not in scope In the above program an ``on`` block is used to declare a variable on a different locale. However, because the ``on`` block creates a new scope, this variable is not visible to the ``writeln`` statement. The most straightforward way to return execution to the original locale is to use a second, nested ``on`` block: .. code-block:: chapel on someOtherLocale { var myVar = 42; on originalLocale { writeln(myVar); } } Remote variable declarations avoid this problem by allowing variables on different locales to be declared without creating a new scope. .. code-block:: chapel on someOtherLocale var myVar = 42; writeln(myVar); // Output: 42 Syntax and Semantics -------------------- Remote variable declarations are created by prefixing a regular variable declaration with ``on`` followed by the target locale. Declarations with only a type, only an initializer, or both are supported: .. code-block:: chapel on loc var myVar1 = 42; on loc var myVar2: 42; on loc var myVar3: int = 42; Remote variables are stored in the heap memory of the target locales. Currently, only ``var`` and ``const`` declarations are allowed. The semantics of the type-only form are the same as for the type-only form of regular variable declarations: the type's default value is used. The intended semantics of the remote variable declaration is to act similarly to two nested ``on`` blocks, with the exception of the scope changes. Thus, the following code: .. code-block:: chapel on loc var myVar = 42; doSomething(myVar); Should behave roughly the same as: .. code-block:: chapel on loc { var myVar = 42; on originalLocale { doSomething(myVar); } } Array types and promotion are supported, making the following code valid: .. code-block:: chapel on loc var A: [1..10] int; on loc var B = A + 1; A useful pattern with Chapel's `GPU Support <./gpu.html>`_ is to declare an array on the GPU using remote variable declarations, and copy a portion of a host array into it: .. code-block:: chapel on here.gpus[0] var GpuA = A[GpuPortion]; Since the initialization expression is executed on the target locale, if the array is initialized with a GPU-eligible expression, this expression is transformed into a GPU kernel as it would be in an ``on`` block. Thus, the following line of code generates a kernel launch: .. code-block:: chapel on here.gpus[0] var B = foreach i in 1..128 do i*i; As with ``on`` blocks, only GPU-eligible loops are transformed into GPU kernels. To assert that the initializer of a GPU-bound remote variable is transformed into a GPU kernel, you can use the ``@assertOnGpu`` attribute: .. code-block:: chapel @assertOnGpu on here.gpus[0] var B = foreach i in 1..128 do i*i; .. _remote-variables-implementation: Implementation Details ---------------------- As mentioned above, remote variables are declared in the heap memory of the target locale. This is done by desugaring the remote variable to the allocation of class-based Chapel wrapper. The following statement: .. code-block:: chapel on loc var myVar = 42; Is desugared to something like the following: .. code-block:: chapel class _remoteVarContainer { var containedValue; } record _remoteVarWrapper { type eltType; var tmp: owned _remoteVarContainer(eltType); proc ref get() ref { return tmp.containedValue; } } var wrapped_myVar = chpl__buildRemoteVarWrapper(loc, 42); ref myVar = wrapped_myVar.get(); When building the remote wrapper, the ``_remoteVarContainer`` is allocated on the heap in the target locale; since ``myVar`` becomes a reference to a part of that container, it also lives on the target locale. Limitations and Future Work --------------------------- Remote variable declarations generally work as expected, and support a variety of input types. However, there are still some limitations that are considered future work: * The heap-based container for the remote variable is always created, even when the variable is itself a heap-allocated class. This introduces an additional level of indirection in certain cases. * Because of the desugaring described in the :ref:`remote-variables-implementation` section, and because records and classes today don't support ``ref`` fields, remote variables cannot be used as fields of records or classes.