Communication¶
Classical communication between nodes is expressed as send/recv operations parameterized by a remote name. The SDK exposes both single-value and array forms.
Source: euqalyptus/operations/communication.py.
Importing¶
from euqalyptus.operations.communication import (
send_int, recv_int,
send_float, recv_float,
send_ints, recv_ints,
send_floats, recv_floats,
)
The corresponding class-style names (SendInt, RecvInt, SendInts, …) are also exported and behave identically — pick whichever style you prefer.
Single-value ops¶
| Op | Signature | HIR op |
|---|---|---|
send_int(remote, value) |
(Remote\|str, IntArray\|QoalaIntegerType\|int) -> None |
qnet.send_int |
recv_int(remote) |
(Remote\|str) -> Int |
qnet.recv_int |
send_float(remote, value) |
(Remote\|str, FloatArray\|QoalaFloatingPointType\|float) -> None |
qnet.send_float |
recv_float(remote) |
(Remote\|str) -> Float |
qnet.recv_float |
bob = Remote("Bob")
m = q.measure()
send_int(bob, m) # m is a Bit; auto-extended to i32
ack = recv_int(bob)
send_int accepts a Bit or a Python int literal, which is converted to a 32-bit value before being recorded.
Array ops¶
| Op | Signature | HIR op |
|---|---|---|
send_ints(remote, *values) |
variadic IntArray\|Int\|int arguments |
qnet.send_ints |
recv_ints(remote, length) |
(Remote\|str, int) -> IntArray |
qnet.recv_ints |
send_floats(remote, *values) |
variadic FloatArray\|Float\|float arguments |
qnet.send_floats |
recv_floats(remote, length) |
(Remote\|str, int) -> FloatArray |
qnet.recv_floats |
xs = recv_ints("Alice", 4) # IntArray of length 4
send_ints("Alice", xs[0], xs[1]) # cherry-pick and send back
The variadic send forms accept individual values, an IntArray/FloatArray, or any mixture — they are flattened during recording.
Single vs. multi-value forms¶
The single-value forms (send_int, recv_int, …) and the array forms (send_ints, recv_ints, …) coexist for two reasons:
- Convenience. Most user programs send/receive a small fixed number of classical values; single-value ops match that shape exactly.
- Tensor avoidance. The multi-value ops use
tensor<?xi32>andtensor<?xf32>types in HIR. Tensors are heavier to lower thani32/f32SSA values. If youcompile(singular_comm_ops=True), the SDK emits only single-value ops, sidestepping tensor lowering altogether.
If you compile with singular_comm_ops=False (the default), the array ops emit qnet.send_ints / qnet.recv_ints (etc.) in HIR. They are then unfolded into single-value ops at MIR level by unfold-comm-ops — unless you disable that pass via --lower-qoala-mir-to-lir=disable-unfold-comm-ops=true.
Errors¶
| Exception | Raised when |
|---|---|
UnknownRemoteError |
The named remote was not previously declared with Remote(...). |
InvalidArrayArgumentError |
A send_ints / send_floats argument is the wrong type for the array. |
OperandMismatchError |
An overload's argument count or type doesn't match. |
Recv operations don't take values, so they cannot raise type-mismatch errors at SDK level.
What ends up in HIR¶
A simple round-trip:
@QoalaProgram
def example():
alice = Remote("Alice")
q = Entangle("Alice")
m = q.measure()
send_int(alice, m)
ack = recv_int(alice)
becomes:
module {
qnet.remote @Alice
%ent = qnet.eprs { remote = @Alice } : !qnet.qubit
%m = qnet.measure %ent : i1
qnet.send_int %m, @Alice : i32
%ack = qnet.recv_int { remote = @Alice } : i32
}
API reference¶
communication ¶
recv_int
module-attribute
¶
recv_int = RecvInt
Lowercase alias of :class:RecvInt. Records qnet.recv_int.
recv_ints
module-attribute
¶
recv_ints = RecvInts
Lowercase alias of :class:RecvInts. Records qnet.recv_ints.
recv_float
module-attribute
¶
recv_float = RecvFloat
Lowercase alias of :class:RecvFloat. Records qnet.recv_float.
recv_floats
module-attribute
¶
recv_floats = RecvFloats
Lowercase alias of :class:RecvFloats. Records qnet.recv_floats.
send_int
module-attribute
¶
send_int = SendInts
Lowercase scalar alias of :class:SendInts. With
compile(singular_comm_ops=True), the SDK emits qnet.send_int for
a single-value send; with the default compile(), it emits
qnet.send_ints on a one-element tensor.
send_ints
module-attribute
¶
send_ints = SendInts
Lowercase alias of :class:SendInts. Records qnet.send_ints on a
tensor of values.
send_float
module-attribute
¶
send_float = SendFloats
Lowercase scalar alias of :class:SendFloats. With
compile(singular_comm_ops=True), the SDK emits qnet.send_float
for a single-value send; with the default compile(), it emits
qnet.send_floats on a one-element tensor.
send_floats
module-attribute
¶
send_floats = SendFloats
Lowercase alias of :class:SendFloats. Records qnet.send_floats
on a tensor of values.
RecvInt ¶
RecvInt(remote_name: Remote | str)
Bases: QoalaIntegerType, NumericOperandsOverload, BitwiseOperandsOverload
Record a single-value classical integer receive from a remote peer.
Calling RecvInt(remote) (or the alias recv_int(remote))
inside a @QoalaProgram body records a qnet.recv_int-shaped
AST node that, at execution time, blocks until the peer has sent
one integer value. Unlike the send side, the scalar receive is its
own first-class class — the compile(singular_comm_ops=True)
flag does not need to be set to use it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
remote_name
|
Remote | str
|
The remote peer to receive from. May be a
:class: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
value. The returned value supports the usual numeric and |
||
|
bitwise operators. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
RecvInts ¶
RecvInts(remote_name: Remote | str, length: int)
Bases: IntArray
Record a tensor-valued classical receive from a remote peer.
Calling RecvInts(remote, length) inside a @QoalaProgram body
records a qnet.recv_ints-shaped AST node that, at execution time,
blocks until the peer has sent length integer values. The result
behaves like an :class:~euqalyptus.types.classical.IntArray and can
be indexed and stored against.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
remote_name
|
Remote | str
|
The remote peer to receive from. May be a
:class: |
required |
length
|
int
|
The number of integer values to receive. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
An |
class: |
|
|
carrying the received values. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
RecvFloat ¶
RecvFloat(remote_name: Remote | str)
Bases: QoalaFloatingPointType
Record a single-value classical-float receive from a remote peer.
Calling RecvFloat(remote) (or the alias recv_float(remote))
inside a @QoalaProgram body records a qnet.recv_float-shaped
AST node that, at execution time, blocks until the peer has sent
one floating-point value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
remote_name
|
Remote | str
|
The remote peer to receive from. May be a
:class: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
received value. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
RecvFloats ¶
RecvFloats(remote_name: Remote | str, length: int)
Bases: FloatArray, NumericOperandsOverload, BitwiseOperandsOverload
Record a tensor-valued classical-float receive from a remote peer.
Calling RecvFloats(remote, length) inside a @QoalaProgram
body records a qnet.recv_floats-shaped AST node that, at
execution time, blocks until the peer has sent length
floating-point values. The result behaves like a
:class:~euqalyptus.types.classical.FloatArray.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
remote_name
|
Remote | str
|
The remote peer to receive from. May be a
:class: |
required |
length
|
int
|
The number of floating-point values to receive. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
carrying the received values. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
SendInts ¶
SendInts(remote_name: Remote | str, *args: IntArray | QoalaIntegerType | ScopedVar | int)
Record a (possibly variadic) classical-integer send to a remote peer.
Calling SendInts(remote, v1, v2, ...) inside a @QoalaProgram
body records a qnet.send_ints AST node that, at execution time,
sends the given integer values to remote as a single tensor
payload. The scalar aliases send_int and send_ints both
point at this class — the difference is whether
compile(singular_comm_ops=True) is set: with the flag, a single
value emits the scalar HIR op qnet.send_int; without it (the
default), a one-element tensor is emitted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
remote_name
|
Remote | str
|
The remote peer to send to. May be a
:class: |
required |
*args
|
IntArray | QoalaIntegerType | ScopedVar | int
|
One or more values to send. Each value must be an
:class: |
()
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |
SendFloats ¶
SendFloats(remote_name: Remote | str, *args: FloatArray | QoalaFloatingPointType | QoalaIntegerType | ScopedVar | float)
Record a (possibly variadic) classical-float send to a remote peer.
Calling SendFloats(remote, v1, v2, ...) inside a
@QoalaProgram body records a qnet.send_floats AST node
that, at execution time, sends the given values to remote as a
single tensor payload. As with :class:SendInts, the scalar
aliases send_float / send_floats both point at this class;
compile(singular_comm_ops=True) selects whether a single value
is emitted as the scalar HIR op qnet.send_float or as a
one-element tensor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
remote_name
|
Remote | str
|
The remote peer to send to. May be a
:class: |
required |
*args
|
FloatArray | QoalaFloatingPointType | QoalaIntegerType | ScopedVar | float
|
One or more values to send. Each value must be a
:class: |
()
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If |