update debug_deployment
This commit is contained in:
parent
36c710416e
commit
f45c56d529
@ -483,9 +483,9 @@ class MFlowConverter:
|
||||
port_ids = [int(p.strip()) for p in port_id_str.split(',') if p.strip()]
|
||||
except ValueError:
|
||||
print(f"Warning: Invalid port_id format '{port_id_str}', using default [28]")
|
||||
port_ids = [28] # Default port
|
||||
port_ids = [32] # Default port
|
||||
else:
|
||||
port_ids = [28] # Default port
|
||||
port_ids = [32] # Default port
|
||||
|
||||
# Model path
|
||||
model_path = properties.get('model_path', '')
|
||||
|
||||
273
cluster4npu_ui/debug_deployment.py
Normal file
273
cluster4npu_ui/debug_deployment.py
Normal file
@ -0,0 +1,273 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Debug script to trace deployment pipeline data flow.
|
||||
This script helps identify where data flow breaks during deployment.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from typing import Dict, Any
|
||||
|
||||
# Add the project root to the Python path
|
||||
project_root = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, project_root)
|
||||
sys.path.insert(0, os.path.join(project_root, 'core', 'functions'))
|
||||
|
||||
try:
|
||||
from core.functions.mflow_converter import MFlowConverter
|
||||
from core.functions.workflow_orchestrator import WorkflowOrchestrator
|
||||
from core.functions.InferencePipeline import InferencePipeline
|
||||
IMPORTS_AVAILABLE = True
|
||||
except ImportError as e:
|
||||
print(f"❌ Import error: {e}")
|
||||
IMPORTS_AVAILABLE = False
|
||||
|
||||
def create_test_pipeline_data() -> Dict[str, Any]:
|
||||
"""Create a minimal test pipeline that should work."""
|
||||
return {
|
||||
'project_name': 'Debug Test Pipeline',
|
||||
'description': 'Simple test pipeline for debugging data flow',
|
||||
'version': '1.0',
|
||||
'nodes': [
|
||||
{
|
||||
'id': 'input_1',
|
||||
'name': 'Camera Input',
|
||||
'type': 'ExactInputNode',
|
||||
'pos': [100, 100],
|
||||
'properties': {
|
||||
'source_type': 'camera', # lowercase to match WorkflowOrchestrator
|
||||
'device_id': 0,
|
||||
'resolution': '640x480', # smaller resolution for testing
|
||||
'fps': 10 # lower fps for testing
|
||||
}
|
||||
},
|
||||
{
|
||||
'id': 'model_1',
|
||||
'name': 'Test Model',
|
||||
'type': 'ExactModelNode',
|
||||
'pos': [300, 100],
|
||||
'properties': {
|
||||
'model_path': 'C:/Users/mason/AppData/Local/Kneron_Academy/utils/yolov5s/yolov5s/kl520_20005_yolov5-noupsample_w640h640.nef',
|
||||
'scpu_fw_path': 'C:/Users/mason/Downloads/kneron_plus_v3.1.2/kneron_plus/res/firmware/KL520/fw_scpu.bin',
|
||||
'ncpu_fw_path': 'C:/Users/mason/Downloads/kneron_plus_v3.1.2/kneron_plus/res/firmware/KL520/fw_ncpu.bin',
|
||||
'port_ids': '32',
|
||||
'upload_fw': True
|
||||
}
|
||||
},
|
||||
{
|
||||
'id': 'output_1',
|
||||
'name': 'Debug Output',
|
||||
'type': 'ExactOutputNode',
|
||||
'pos': [500, 100],
|
||||
'properties': {
|
||||
'output_type': 'console',
|
||||
'destination': './debug_output'
|
||||
}
|
||||
}
|
||||
],
|
||||
'connections': [
|
||||
{
|
||||
'input_node': 'input_1',
|
||||
'input_port': 'output',
|
||||
'output_node': 'model_1',
|
||||
'output_port': 'input'
|
||||
},
|
||||
{
|
||||
'input_node': 'model_1',
|
||||
'input_port': 'output',
|
||||
'output_node': 'output_1',
|
||||
'output_port': 'input'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
def trace_pipeline_conversion(pipeline_data: Dict[str, Any]):
|
||||
"""Trace the conversion process step by step."""
|
||||
print("🔍 DEBUGGING PIPELINE CONVERSION")
|
||||
print("=" * 60)
|
||||
|
||||
if not IMPORTS_AVAILABLE:
|
||||
print("❌ Cannot trace conversion - imports not available")
|
||||
return None, None, None
|
||||
|
||||
try:
|
||||
print("1️⃣ Creating MFlowConverter...")
|
||||
converter = MFlowConverter()
|
||||
|
||||
print("2️⃣ Converting pipeline data to config...")
|
||||
config = converter._convert_mflow_to_config(pipeline_data)
|
||||
|
||||
print(f"✅ Conversion successful!")
|
||||
print(f" Pipeline name: {config.pipeline_name}")
|
||||
print(f" Total stages: {len(config.stage_configs)}")
|
||||
|
||||
print("\n📊 INPUT CONFIG:")
|
||||
print(json.dumps(config.input_config, indent=2))
|
||||
|
||||
print("\n📊 OUTPUT CONFIG:")
|
||||
print(json.dumps(config.output_config, indent=2))
|
||||
|
||||
print("\n📊 STAGE CONFIGS:")
|
||||
for i, stage_config in enumerate(config.stage_configs, 1):
|
||||
print(f" Stage {i}: {stage_config.stage_id}")
|
||||
print(f" Port IDs: {stage_config.port_ids}")
|
||||
print(f" Model: {stage_config.model_path}")
|
||||
|
||||
print("\n3️⃣ Validating configuration...")
|
||||
is_valid, errors = converter.validate_config(config)
|
||||
if is_valid:
|
||||
print("✅ Configuration is valid")
|
||||
else:
|
||||
print("❌ Configuration validation failed:")
|
||||
for error in errors:
|
||||
print(f" - {error}")
|
||||
|
||||
return converter, config, is_valid
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Conversion failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return None, None, False
|
||||
|
||||
def trace_workflow_creation(converter, config):
|
||||
"""Trace the workflow orchestrator creation."""
|
||||
print("\n🔧 DEBUGGING WORKFLOW ORCHESTRATOR")
|
||||
print("=" * 60)
|
||||
|
||||
try:
|
||||
print("1️⃣ Creating InferencePipeline...")
|
||||
pipeline = converter.create_inference_pipeline(config)
|
||||
print("✅ Pipeline created")
|
||||
|
||||
print("2️⃣ Creating WorkflowOrchestrator...")
|
||||
orchestrator = WorkflowOrchestrator(pipeline, config.input_config, config.output_config)
|
||||
print("✅ Orchestrator created")
|
||||
|
||||
print("3️⃣ Checking data source creation...")
|
||||
data_source = orchestrator._create_data_source()
|
||||
if data_source:
|
||||
print(f"✅ Data source created: {type(data_source).__name__}")
|
||||
|
||||
# Check if the data source can initialize
|
||||
print("4️⃣ Testing data source initialization...")
|
||||
if hasattr(data_source, 'initialize'):
|
||||
init_result = data_source.initialize()
|
||||
print(f" Initialization result: {init_result}")
|
||||
else:
|
||||
print(" Data source has no initialize method")
|
||||
|
||||
else:
|
||||
print("❌ Data source creation failed")
|
||||
print(f" Source type: {config.input_config.get('source_type', 'MISSING')}")
|
||||
|
||||
print("5️⃣ Checking result handler creation...")
|
||||
result_handler = orchestrator._create_result_handler()
|
||||
if result_handler:
|
||||
print(f"✅ Result handler created: {type(result_handler).__name__}")
|
||||
else:
|
||||
print("⚠️ No result handler created (may be expected)")
|
||||
|
||||
return orchestrator, data_source, result_handler
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Workflow creation failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return None, None, None
|
||||
|
||||
def test_data_flow(orchestrator):
|
||||
"""Test the actual data flow without real dongles."""
|
||||
print("\n🌊 TESTING DATA FLOW")
|
||||
print("=" * 60)
|
||||
|
||||
# Set up result callback to track data
|
||||
results_received = []
|
||||
|
||||
def debug_result_callback(result_dict):
|
||||
print(f"🎯 RESULT RECEIVED: {result_dict}")
|
||||
results_received.append(result_dict)
|
||||
|
||||
def debug_frame_callback(frame):
|
||||
print(f"📸 FRAME RECEIVED: {type(frame)} shape={getattr(frame, 'shape', 'N/A')}")
|
||||
|
||||
try:
|
||||
print("1️⃣ Setting up callbacks...")
|
||||
orchestrator.set_result_callback(debug_result_callback)
|
||||
orchestrator.set_frame_callback(debug_frame_callback)
|
||||
|
||||
print("2️⃣ Starting orchestrator (this will fail with dongles, but should show data source activity)...")
|
||||
orchestrator.start()
|
||||
|
||||
print("3️⃣ Running for 5 seconds to capture any activity...")
|
||||
import time
|
||||
time.sleep(5)
|
||||
|
||||
print("4️⃣ Stopping orchestrator...")
|
||||
orchestrator.stop()
|
||||
|
||||
print(f"📊 Results summary:")
|
||||
print(f" Total results received: {len(results_received)}")
|
||||
|
||||
return len(results_received) > 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Data flow test failed: {e}")
|
||||
print(" This might be expected if dongles are not available")
|
||||
return False
|
||||
|
||||
def main():
|
||||
"""Main debugging function."""
|
||||
print("🚀 CLUSTER4NPU DEPLOYMENT DEBUG TOOL")
|
||||
print("=" * 60)
|
||||
|
||||
# Create test pipeline data
|
||||
pipeline_data = create_test_pipeline_data()
|
||||
|
||||
# Trace conversion
|
||||
converter, config, is_valid = trace_pipeline_conversion(pipeline_data)
|
||||
|
||||
if not converter or not config or not is_valid:
|
||||
print("\n❌ Cannot proceed - conversion failed or invalid")
|
||||
return
|
||||
|
||||
# Trace workflow creation
|
||||
orchestrator, data_source, result_handler = trace_workflow_creation(converter, config)
|
||||
|
||||
if not orchestrator:
|
||||
print("\n❌ Cannot proceed - workflow creation failed")
|
||||
return
|
||||
|
||||
# Test data flow (this will likely fail with dongle connection, but shows data source behavior)
|
||||
print("\n⚠️ Note: The following test will likely fail due to missing dongles,")
|
||||
print(" but it will help us see if the data source is working correctly.")
|
||||
|
||||
data_flowing = test_data_flow(orchestrator)
|
||||
|
||||
print("\n📋 DEBUGGING SUMMARY")
|
||||
print("=" * 60)
|
||||
print(f"✅ Pipeline conversion: {'SUCCESS' if converter else 'FAILED'}")
|
||||
print(f"✅ Configuration validation: {'SUCCESS' if is_valid else 'FAILED'}")
|
||||
print(f"✅ Workflow orchestrator: {'SUCCESS' if orchestrator else 'FAILED'}")
|
||||
print(f"✅ Data source creation: {'SUCCESS' if data_source else 'FAILED'}")
|
||||
print(f"✅ Result handler creation: {'SUCCESS' if result_handler else 'N/A'}")
|
||||
print(f"✅ Data flow test: {'SUCCESS' if data_flowing else 'FAILED (expected without dongles)'}")
|
||||
|
||||
if data_source and not data_flowing:
|
||||
print("\n🔍 DIAGNOSIS:")
|
||||
print("The issue appears to be that:")
|
||||
print("1. Pipeline configuration is working correctly")
|
||||
print("2. Data source can be created")
|
||||
print("3. BUT: Either the data source cannot initialize (camera not available)")
|
||||
print(" OR: The pipeline cannot start (dongles not available)")
|
||||
print(" OR: No data is being sent to the pipeline")
|
||||
|
||||
print("\n💡 RECOMMENDATIONS:")
|
||||
print("1. Check if a camera is connected at index 0")
|
||||
print("2. Check if dongles are properly connected")
|
||||
print("3. Add more detailed logging to WorkflowOrchestrator.start()")
|
||||
print("4. Verify the pipeline.put_data() callback is being called")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -3,7 +3,7 @@
|
||||
"description": "",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "0x1b8706d5710",
|
||||
"id": "0x1dffd7b5990",
|
||||
"name": "Input Node",
|
||||
"type": "ExactInputNode",
|
||||
"pos": [
|
||||
@ -19,7 +19,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "0x1b8706f4bd0",
|
||||
"id": "0x1dffd7d4f10",
|
||||
"name": "Model Node",
|
||||
"type": "ExactModelNode",
|
||||
"pos": [
|
||||
@ -32,11 +32,11 @@
|
||||
"model_path": "C:/Users/mason/AppData/Local/Kneron_Academy/utils/yolov5s/yolov5s/kl520_20005_yolov5-noupsample_w640h640.nef",
|
||||
"scpu_fw_path": "C:/Users/mason/Downloads/kneron_plus_v3.1.2/kneron_plus/res/firmware/KL520/fw_scpu.bin",
|
||||
"ncpu_fw_path": "C:/Users/mason/Downloads/kneron_plus_v3.1.2/kneron_plus/res/firmware/KL520/fw_ncpu.bin",
|
||||
"port_id": "6, 32"
|
||||
"port_id": "32"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "0x1b8706f6790",
|
||||
"id": "0x1dffd7d6c90",
|
||||
"name": "Output Node",
|
||||
"type": "ExactOutputNode",
|
||||
"pos": [
|
||||
@ -51,7 +51,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "0x1b8706f7950",
|
||||
"id": "0x1dffd7d7f50",
|
||||
"name": "Preprocess Node",
|
||||
"type": "ExactPreprocessNode",
|
||||
"pos": [
|
||||
@ -63,46 +63,25 @@
|
||||
"resize_height": 144,
|
||||
"operations": "resize,normalize"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "0x1b870700c90",
|
||||
"name": "Postprocess Node",
|
||||
"type": "ExactPostprocessNode",
|
||||
"pos": [
|
||||
272.09359134850405,
|
||||
474.2416550230502
|
||||
],
|
||||
"properties": {
|
||||
"output_format": "JSON",
|
||||
"confidence_threshold": 0.5,
|
||||
"nms_threshold": 0.4,
|
||||
"max_detections": 100
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"input_node": "0x1b8706f7950",
|
||||
"input_node": "0x1dffd7d7f50",
|
||||
"input_port": "input",
|
||||
"output_node": "0x1b8706d5710",
|
||||
"output_node": "0x1dffd7b5990",
|
||||
"output_port": "output"
|
||||
},
|
||||
{
|
||||
"input_node": "0x1b870700c90",
|
||||
"input_node": "0x1dffd7d6c90",
|
||||
"input_port": "input",
|
||||
"output_node": "0x1b8706f4bd0",
|
||||
"output_node": "0x1dffd7d4f10",
|
||||
"output_port": "output"
|
||||
},
|
||||
{
|
||||
"input_node": "0x1b8706f4bd0",
|
||||
"input_node": "0x1dffd7d4f10",
|
||||
"input_port": "input",
|
||||
"output_node": "0x1b8706f7950",
|
||||
"output_port": "output"
|
||||
},
|
||||
{
|
||||
"input_node": "0x1b8706f6790",
|
||||
"input_port": "input",
|
||||
"output_node": "0x1b870700c90",
|
||||
"output_node": "0x1dffd7d7f50",
|
||||
"output_port": "output"
|
||||
}
|
||||
],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user