Commit ·
dec4918
1
Parent(s): 6a17a0a
fix: enable validated ONNX export
Browse files- pyproject.toml +2 -0
- src/gnn4colliders/export/onnx.py +20 -15
- uv.lock +4 -0
pyproject.toml
CHANGED
|
@@ -36,6 +36,8 @@ dev = [
|
|
| 36 |
"pytest-cov>=5",
|
| 37 |
"ruff>=0.6",
|
| 38 |
"twine>=6,<7",
|
|
|
|
|
|
|
| 39 |
]
|
| 40 |
|
| 41 |
[tool.setuptools.packages.find]
|
|
|
|
| 36 |
"pytest-cov>=5",
|
| 37 |
"ruff>=0.6",
|
| 38 |
"twine>=6,<7",
|
| 39 |
+
"onnx>=1.16,<2",
|
| 40 |
+
"onnxruntime>=1.18,<2",
|
| 41 |
]
|
| 42 |
|
| 43 |
[tool.setuptools.packages.find]
|
src/gnn4colliders/export/onnx.py
CHANGED
|
@@ -106,23 +106,30 @@ def inputs_from_graph_batch(batch: Any) -> RootGNNExportInputs:
|
|
| 106 |
def _mean_by_group(
|
| 107 |
values: torch.Tensor, groups: torch.Tensor, count: int
|
| 108 |
) -> torch.Tensor:
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
0, groups, values.new_ones((values.shape[0], 1))
|
| 114 |
-
)
|
| 115 |
-
result = result / sizes.clamp_min(1)
|
| 116 |
-
return result
|
| 117 |
|
| 118 |
|
| 119 |
def _sum_by_group(
|
| 120 |
values: torch.Tensor, groups: torch.Tensor, count: int
|
| 121 |
) -> torch.Tensor:
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
|
| 127 |
|
| 128 |
class RootGNNExportAdapter(nn.Module):
|
|
@@ -169,9 +176,7 @@ class RootGNNExportAdapter(nn.Module):
|
|
| 169 |
1,
|
| 170 |
)
|
| 171 |
)
|
| 172 |
-
node_messages =
|
| 173 |
-
0, edge_dst, edge_h
|
| 174 |
-
)
|
| 175 |
node_h = self.backbone.node_update(
|
| 176 |
torch.cat((node_h, node_messages, global_h[node_batch]), 1)
|
| 177 |
)
|
|
|
|
| 106 |
def _mean_by_group(
|
| 107 |
values: torch.Tensor, groups: torch.Tensor, count: int
|
| 108 |
) -> torch.Tensor:
|
| 109 |
+
membership = _group_membership(groups, count, values)
|
| 110 |
+
result = membership @ values
|
| 111 |
+
sizes = membership.sum(dim=1, keepdim=True)
|
| 112 |
+
return result / sizes.clamp_min(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
|
| 115 |
def _sum_by_group(
|
| 116 |
values: torch.Tensor, groups: torch.Tensor, count: int
|
| 117 |
) -> torch.Tensor:
|
| 118 |
+
return _group_membership(groups, count, values) @ values
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def _group_membership(
|
| 122 |
+
groups: torch.Tensor, count: int, values: torch.Tensor
|
| 123 |
+
) -> torch.Tensor:
|
| 124 |
+
"""Return a dense group-membership matrix for export-safe reduction.
|
| 125 |
+
|
| 126 |
+
``index_add`` is efficient in native PyTorch but exports to ONNX scatter
|
| 127 |
+
operations whose behavior for duplicate indices is not reliable. A
|
| 128 |
+
boolean membership matrix has unambiguous reduction semantics for the
|
| 129 |
+
repeated node/edge group IDs used by batched graphs.
|
| 130 |
+
"""
|
| 131 |
+
labels = torch.arange(count, device=groups.device).unsqueeze(1)
|
| 132 |
+
return (labels == groups.unsqueeze(0)).to(dtype=values.dtype)
|
| 133 |
|
| 134 |
|
| 135 |
class RootGNNExportAdapter(nn.Module):
|
|
|
|
| 176 |
1,
|
| 177 |
)
|
| 178 |
)
|
| 179 |
+
node_messages = _sum_by_group(edge_h, edge_dst, node_h.shape[0])
|
|
|
|
|
|
|
| 180 |
node_h = self.backbone.node_update(
|
| 181 |
torch.cat((node_h, node_messages, global_h[node_batch]), 1)
|
| 182 |
)
|
uv.lock
CHANGED
|
@@ -239,6 +239,8 @@ root-gnn = [
|
|
| 239 |
[package.dev-dependencies]
|
| 240 |
dev = [
|
| 241 |
{ name = "matplotlib", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
|
|
|
|
|
|
| 242 |
{ name = "pytest", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
| 243 |
{ name = "pytest-cov", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
| 244 |
{ name = "ruff", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
|
@@ -262,6 +264,8 @@ provides-extras = ["root-gnn", "onnx"]
|
|
| 262 |
[package.metadata.requires-dev]
|
| 263 |
dev = [
|
| 264 |
{ name = "matplotlib", specifier = ">=3.8,<4" },
|
|
|
|
|
|
|
| 265 |
{ name = "pytest", specifier = ">=8" },
|
| 266 |
{ name = "pytest-cov", specifier = ">=5" },
|
| 267 |
{ name = "ruff", specifier = ">=0.6" },
|
|
|
|
| 239 |
[package.dev-dependencies]
|
| 240 |
dev = [
|
| 241 |
{ name = "matplotlib", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
| 242 |
+
{ name = "onnx", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
| 243 |
+
{ name = "onnxruntime", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
| 244 |
{ name = "pytest", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
| 245 |
{ name = "pytest-cov", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
| 246 |
{ name = "ruff", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
|
|
|
| 264 |
[package.metadata.requires-dev]
|
| 265 |
dev = [
|
| 266 |
{ name = "matplotlib", specifier = ">=3.8,<4" },
|
| 267 |
+
{ name = "onnx", specifier = ">=1.16,<2" },
|
| 268 |
+
{ name = "onnxruntime", specifier = ">=1.18,<2" },
|
| 269 |
{ name = "pytest", specifier = ">=8" },
|
| 270 |
{ name = "pytest-cov", specifier = ">=5" },
|
| 271 |
{ name = "ruff", specifier = ">=0.6" },
|