lynxkite / lynxkite-graph-analytics /tests /test_pytorch_model_ops.py
darabos's picture
Rename core/ops to pytorch_core/pytorch_ops.
51eb575
from lynxkite.core import workspace
from lynxkite_graph_analytics.pytorch import pytorch_core
import torch
import pytest
def make_ws(env, nodes: dict[str, dict], edges: list[tuple[str, str]]):
ws = workspace.Workspace(env=env)
for id, data in nodes.items():
title = data["title"]
del data["title"]
ws.nodes.append(
workspace.WorkspaceNode(
id=id,
type="basic",
data=workspace.WorkspaceNodeData(title=title, params=data),
position=workspace.Position(
x=data.get("x", 0),
y=data.get("y", 0),
),
)
)
ws.edges = [
workspace.WorkspaceEdge(
id=f"{source}->{target}",
source=source.split(":")[0],
target=target.split(":")[0],
sourceHandle=source.split(":")[1],
targetHandle=target.split(":")[1],
)
for source, target in edges
]
return ws
def summarize_layers(m: pytorch_core.ModelConfig) -> str:
return "".join(str(e)[0] for e in m.model)
def summarize_connections(m: pytorch_core.ModelConfig) -> str:
return " ".join(
"".join(n[0] for n in c.param_names) + "->" + "".join(n[0] for n in c.return_names)
for c in m.model._children
)
async def test_build_model():
ws = make_ws(
pytorch_core.ENV,
{
"input": {"title": "Input: tensor"},
"lin": {"title": "Linear", "output_dim": 4},
"act": {"title": "Activation", "type": "Leaky_ReLU"},
"output": {"title": "Output"},
"label": {"title": "Input: tensor"},
"loss": {"title": "MSE loss"},
"optim": {"title": "Optimizer", "type": "SGD", "lr": 0.1},
},
[
("input:output", "lin:x"),
("lin:output", "act:x"),
("act:output", "output:x"),
("output:x", "loss:x"),
("label:output", "loss:y"),
("loss:output", "optim:loss"),
],
)
x = torch.rand(100, 4)
y = x + 1
m = pytorch_core.build_model(ws)
for i in range(1000):
loss = m.train({"input_output": x, "label_output": y})
assert loss < 0.1
o = m.inference({"input_output": x[:1]})
error = torch.nn.functional.mse_loss(o["output_x"], x[:1] + 1)
assert error < 0.1
async def test_build_model_with_repeat():
def repeated_ws(times):
return make_ws(
pytorch_core.ENV,
{
"input": {"title": "Input: tensor"},
"lin": {"title": "Linear", "output_dim": 8},
"act": {"title": "Activation", "type": "Leaky_ReLU"},
"output": {"title": "Output"},
"label": {"title": "Input: tensor"},
"loss": {"title": "MSE loss"},
"optim": {"title": "Optimizer", "type": "SGD", "lr": 0.1},
"repeat": {"title": "Repeat", "times": times, "same_weights": False},
},
[
("input:output", "lin:x"),
("lin:output", "act:x"),
("act:output", "output:x"),
("output:x", "loss:x"),
("label:output", "loss:y"),
("loss:output", "optim:loss"),
("repeat:output", "lin:x"),
("act:output", "repeat:input"),
],
)
# 1 repetition
m = pytorch_core.build_model(repeated_ws(1))
assert summarize_layers(m) == "IL<III"
assert summarize_connections(m) == "i->S S->l l->a a->E E->o o->o"
# 2 repetitions
m = pytorch_core.build_model(repeated_ws(2))
assert summarize_layers(m) == "IL<IL<III"
assert summarize_connections(m) == "i->S S->l l->a a->S S->l l->a a->E E->o o->o"
# 3 repetitions
m = pytorch_core.build_model(repeated_ws(3))
assert summarize_layers(m) == "IL<IL<IL<III"
assert summarize_connections(m) == "i->S S->l l->a a->S S->l l->a a->S S->l l->a a->E E->o o->o"
if __name__ == "__main__":
pytest.main()