Skip to content

Commit 653bf37

Browse files
awoll-bdaiexploy-bot
authored andcommitted
Fix progress bar (#30)
# Pull Request ### What change is being made One line progress bar. ### Why this change is being made Better user experience. ### Tested Run evaluator. GitOrigin-RevId: 7c91a507c1dc1817da990f265a3eb762988e8490
1 parent 97fb78a commit 653bf37

3 files changed

Lines changed: 80 additions & 55 deletions

File tree

exporter/exporter/evaluator.py

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ def _print_progress_bar(
4646
extra_str = " | ".join(extra_info)
4747

4848
print(
49-
f"\r{status_emoji} {bar} {step_ctr + 1}/{num_steps} | Failed: {failed_steps} | {extra_str} \n",
50-
end="",
49+
f"\r{status_emoji} {bar} {step_ctr + 1}/{num_steps} | Failed: {failed_steps} | {extra_str}",
50+
end="\n" if not step_export_ok else "",
5151
flush=True,
5252
)
5353

@@ -61,10 +61,9 @@ def _compare_step_outputs(
6161
env_outputs: dict[str, torch.Tensor],
6262
ort_outputs: dict[str, torch.Tensor] | None,
6363
output_names: list[str],
64-
verbose: bool,
6564
atol: float,
6665
rtol: float,
67-
) -> bool:
66+
) -> tuple[bool, str]:
6867
"""Compare outputs from environment and ONNX model.
6968
7069
Args:
@@ -76,60 +75,64 @@ def _compare_step_outputs(
7675
env_outputs: Environment outputs.
7776
ort_outputs: ONNX model outputs (None if session not run yet).
7877
output_names: Names of output components.
79-
verbose: Whether to print comparison results.
8078
atol: Absolute tolerance.
8179
rtol: Relative tolerance.
8280
8381
Returns:
84-
True if all comparisons passed, False otherwise.
82+
A tuple of (is_step_export_ok, message), where `is_step_export_ok` is a boolean indicating whether the step's outputs are close within the specified tolerances, and `message` is a string describing the comparison results, including details of any mismatches and troubleshooting checklists.
8583
"""
8684
step_export_ok = True
87-
88-
if verbose:
89-
print("\n")
90-
91-
obs_ok = compare_tensors(
92-
vec_a=env_obs.view(1, -1),
93-
vec_b=ort_obs.to(env_obs.device).view(1, -1),
85+
msg = ""
86+
87+
# Check observation comparison
88+
obs_env = env_obs.view(1, -1)
89+
obs_ort = ort_obs.to(env_obs.device).view(1, -1)
90+
obs_ok, obs_message = compare_tensors(
91+
vec_a=obs_env,
92+
vec_b=obs_ort,
9493
name_a="env",
9594
name_b="ort",
9695
vec_name="observation",
9796
index_names=observation_names,
98-
verbose=verbose,
9997
atol=atol,
10098
rtol=rtol,
10199
)
102100

103-
if not obs_ok and verbose:
104-
print("\n📋 Observation Troubleshooting Checklist:")
105-
print(" • Verify all observation data sources have corresponding input components")
106-
print(
107-
" • Ensure input components reference the same data sources as observation computation"
101+
if not obs_ok:
102+
msg += "\n\n📋 Observation comparison failed!"
103+
msg += f"\n{obs_message}"
104+
msg += "\n📋 Observation Troubleshooting Checklist:"
105+
msg += "\n • Verify all observation data sources have corresponding input components"
106+
msg += "\n • Ensure input components reference the same data sources as observation computation"
107+
msg += (
108+
"\n • For memory-based observations, confirm memory components are properly registered"
108109
)
109-
print(
110-
" • For memory-based observations, confirm memory components are properly registered"
111-
)
112-
print(" • Review compute_observation() implementation for data flow correctness")
113-
return False
110+
msg += "\n • Review compute_observation() implementation for data flow correctness"
111+
return False, msg
114112

115113
step_export_ok = step_export_ok and obs_ok
116114

117-
actions_ok = compare_tensors(
118-
vec_a=env_actions.view(1, -1),
119-
vec_b=ort_actions.to(env_actions.device).view(1, -1),
115+
# Check actions comparison
116+
actions_env = env_actions.view(1, -1)
117+
actions_ort = ort_actions.to(env_actions.device).view(1, -1)
118+
actions_ok, actions_message = compare_tensors(
119+
vec_a=actions_env,
120+
vec_b=actions_ort,
120121
name_a="env",
121122
name_b="ort",
122123
vec_name="actions",
123-
verbose=verbose,
124+
index_names=None,
124125
atol=atol,
125126
rtol=rtol,
126127
)
127128

128-
if not actions_ok and verbose:
129-
print("\n📋 Actions Troubleshooting Checklist:")
130-
print(" • Verify actor network matches between env and ONNX")
131-
print(" • Ensure action normalizer parameters are correctly exported")
132-
return False
129+
if not actions_ok:
130+
msg += "\n\n🎯 Actions comparison failed!"
131+
msg += f"\n{actions_message}"
132+
msg += "\n📋 Actions Troubleshooting Checklist:"
133+
msg += "\n • Verify actor network matches between env and ONNX"
134+
msg += "\n • Ensure action normalizer parameters are correctly exported"
135+
return False, msg
133136

134137
step_export_ok = step_export_ok and actions_ok
135138

@@ -148,28 +151,32 @@ def _compare_step_outputs(
148151
output_size = env_outputs[name].view(1, -1).shape[1]
149152
expanded_index_names.extend([f"{name}[{i}]" for i in range(output_size)])
150153

151-
outputs_ok = compare_tensors(
154+
# Check outputs comparison
155+
outputs_ok, outputs_message = compare_tensors(
152156
vec_a=env_outputs_cat,
153157
vec_b=ort_outputs_cat,
154158
name_a="env",
155159
name_b="ort",
156160
vec_name="outputs",
157161
index_names=expanded_index_names,
158-
verbose=verbose,
159162
atol=atol,
160163
rtol=rtol,
161164
)
162165

163-
if not outputs_ok and verbose:
164-
print("\n📋 Outputs Troubleshooting Checklist:")
165-
print(" • Verify output components are registered for all expected outputs")
166-
print(" • Ensure the correct processed actions are included in memory")
167-
print(" • Review process_action() and apply_action() implementations for consistency")
168-
return False
166+
if not outputs_ok:
167+
msg += "\n\n📊 Outputs comparison failed!"
168+
msg += f"\n{outputs_message}"
169+
msg += "\n📋 Outputs Troubleshooting Checklist:"
170+
msg += "\n • Verify output components are registered for all expected outputs"
171+
msg += "\n • Ensure the correct processed actions are included in memory"
172+
msg += (
173+
"\n • Review process_action() and apply_action() implementations for consistency"
174+
)
175+
return False, msg
169176

170177
step_export_ok = step_export_ok and outputs_ok
171178

172-
return step_export_ok
179+
return step_export_ok, msg
173180

174181

175182
def evaluate(
@@ -215,6 +222,10 @@ def evaluate(
215222

216223
obs = observations.clone() if observations is not None else env.observations_reset()
217224

225+
# Print ONNX graph structure if verbose
226+
if verbose:
227+
session_wrapper.print_graph()
228+
218229
step_ctr = 0
219230
export_ok = True
220231
failed_steps = 0
@@ -313,7 +324,7 @@ def reset():
313324
}
314325

315326
# Compare outputs from environment and ONNX model.
316-
step_export_ok = _compare_step_outputs(
327+
step_export_ok, msg = _compare_step_outputs(
317328
env_obs=obs,
318329
ort_obs=ort_observations,
319330
env_actions=env_actions,
@@ -322,7 +333,6 @@ def reset():
322333
ort_outputs=ort_outputs,
323334
observation_names=env.get_observation_names(),
324335
output_names=context_manager.get_output_names(),
325-
verbose=verbose,
326336
atol=atol,
327337
rtol=rtol,
328338
)
@@ -333,6 +343,10 @@ def reset():
333343

334344
# Display progress bar.
335345
if verbose:
346+
if step_ctr == 0:
347+
print("\n\nStarting evaluation...")
348+
if not step_export_ok:
349+
print(msg)
336350
_print_progress_bar(
337351
step_ctr=step_ctr,
338352
num_steps=num_steps,
@@ -347,5 +361,6 @@ def reset():
347361
input()
348362

349363
step_ctr += 1
350-
364+
if verbose:
365+
print("\nEvaluation complete.")
351366
return export_ok, next_obs

exporter/exporter/session_wrapper.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import pathlib
44

55
import numpy as np
6+
import onnx
67
import onnxruntime as ort
78
import torch
9+
from onnx import helper
810

911
from exporter.utils.paths import prepare_onnx_paths
1012

@@ -108,3 +110,14 @@ def get_output_value(self, output_name: str):
108110
def reset(self):
109111
"""Reset the internal results to zeros to avoid stale data at environment reset."""
110112
self._results = [np.zeros_like(output) for output in self._results]
113+
114+
def print_graph(self) -> None:
115+
"""Print the ONNX graph structure in a readable format."""
116+
try:
117+
print("\n📊 ONNX Graph Structure:")
118+
print("=" * 50)
119+
onnx_model = onnx.load(str(self._onnx_file_path))
120+
print(helper.printable_graph(onnx_model.graph))
121+
print("=" * 50)
122+
except Exception as e:
123+
print(f"⚠️ Could not load ONNX graph: {e}")

exporter/exporter/utils/math.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ def compare_tensors(
1313
name_b: str = None,
1414
atol: float = 1.0e-5,
1515
rtol: float = 1.0e-5,
16-
verbose: bool = False,
17-
) -> bool:
16+
) -> tuple[bool, str]:
1817
"""Compare two tensors, and print a message showing the differences.
1918
2019
Args:
@@ -23,18 +22,19 @@ def compare_tensors(
2322
vec_name: A name identifying the compared tensors.
2423
index_names: A list of names, one for each element of the input tensors.
2524
name_a: A name identifying the source of the first input tensor.
26-
name_a: A name identifying the source of the second input tensor.
25+
name_b: A name identifying the source of the second input tensor.
2726
atol : Absolute tolerance.
2827
rtol : Relative tolerance.
29-
verbose: If true, print information about the tensor difference to console.
28+
29+
Returns:
30+
A tuple of (is_close, message), where `is_close` is a boolean indicating whether the tensors are close within the specified tolerances, and `message` is a string describing the comparison results, including details of any mismatches.
3031
"""
3132
is_close = torch.isclose(vec_a, vec_b, atol=atol, rtol=rtol)
3233

3334
msg = f"Comparing {vec_name}: "
3435
if torch.all(is_close):
3536
msg += "\033[92mall elements are close.\033[0m"
36-
print(msg)
37-
return True
37+
return True, msg
3838

3939
mismatched_indices = (torch.logical_not(is_close)).nonzero(as_tuple=False)
4040

@@ -52,7 +52,4 @@ def compare_tensors(
5252
f"{name_b}={val_b:+.5f}\t"
5353
f"Δ={np.abs(val_a - val_b):.5f}"
5454
)
55-
56-
if verbose:
57-
print(msg)
58-
return False
55+
return False, msg

0 commit comments

Comments
 (0)