How to execute a lattice as an electron inside another lattice#
In this case we will treat a (sub)lattice as an electron and then dispatch it inside another (super)lattice.
[1]:
import covalent as ct
@ct.electron
def identity(x):
return x
@ct.electron
def root(x):
return x ** 0.5
@ct.electron
def square(x):
return x * x
@ct.electron
@ct.lattice
def multiply_3_and_square(x):
root(x=x)
return square(x=x * 3)
@ct.lattice
def workflow(a):
val_1 = identity(x=a)
return multiply_3_and_square(x=val_1)
Note
Ensure that the dispatcher server is running. Since the sublattice is also a lattice, you can pass constraints to it in the similar fashion as you would to a lattice mentioned here How to add constraints to lattices.
Now we will dispatch the superlattice workflow
and query the result.
[2]:
dispatch_id = ct.dispatch(workflow)(a=2)
print("Dispatch id:", dispatch_id)
result = ct.get_result(dispatch_id, wait=True)
print("Result of workflow:", result.result)
Dispatch id: fd6ba91a-d0cc-4a4e-aa0d-f208fe36c69c
Result of workflow: 36
Now, once you have result, you can use it to query the sublattice’s result as well. In order to do that we need to know the node id of the sublattice. We can find that out using get_all_node_outputs()
function of result
.
[3]:
result.get_all_node_outputs()
[3]:
{'identity(0)': 2,
':parameter:2(1)': 2,
':sublattice:multiply_3_and_square(2)': 36}
Note
The number in parenthesis denotes the node id, so for identity
node, the id is 0
.
Here we can see that our lattice’s node id is 2
. So we use get_node_result(2)
to get the result of the sublattice.
[4]:
result.get_node_result(2)
[4]:
{'node_id': 2,
'node_name': ':sublattice:multiply_3_and_square(2)',
'start_time': datetime.datetime(2022, 1, 23, 1, 3, 1, 739165, tzinfo=datetime.timezone.utc),
'end_time': datetime.datetime(2022, 1, 23, 1, 3, 1, 847243, tzinfo=datetime.timezone.utc),
'status': Status(STATUS='COMPLETED'),
'output': 36,
'error': None,
'sublattice_result': <covalent._results_manager.result.Result at 0x7ff520c1f100>,
'stdout': None,
'stderr': None}
As you can see in the sublattice_result
value, a Result
object is present. It behaves the same way as our result
variable did.
So we can do the following:
[5]:
sublattice_result = result.get_node_result(2)["sublattice_result"]
sublattice_result.result
[5]:
36
We can also access all of the node executions that the sublattice did using get_all_node_outputs()
function similarly.
[6]:
sublattice_result.get_all_node_outputs()
[6]:
{'root(0)': 1.4142135623730951,
':parameter:2(1)': 2,
'square(2)': 36,
':parameter:6(3)': 6}