This commit is contained in:
khodowany
2026-10-04 15:51:18 -05:00
parent 405066eb43
commit f234dd6d51
54 changed files with 2104 additions and 330 deletions
+21 -1
View File
@@ -1,6 +1,7 @@
from __future__ import annotations
import argparse
import json
import pathlib
import shutil
import tempfile
@@ -44,6 +45,8 @@ def parse_args() -> argparse.Namespace:
parser.add_argument("--composition-jobs", type=int, default=2, choices=range(1, 17), metavar="1-16")
parser.add_argument("--composition-cache", type=pathlib.Path)
parser.add_argument("--export-solo-xml", action="store_true", help="Export completed solo roles as comparison MusicXML, without recomposing.")
parser.add_argument("--trace-level",choices=("summary","full"),default="summary",help="Diagnostic detail only; does not seed composition.")
parser.add_argument("--profile-output",type=pathlib.Path,help="Write build and per-role elapsed timings (not a search timeout).")
parser.add_argument("--progress", action="store_true")
args = parser.parse_args()
if not args.renderer_fingerprint and (args.data_dir is None or args.output_dir is None):
@@ -65,8 +68,12 @@ def generate_assets(args: argparse.Namespace) -> None:
raise ValueError('composition cache and generated assets must not overlap')
progress = getattr(args, 'progress', False)
started = time.monotonic()
timings=[];stages=[];last_stage=started
def report(message):
nonlocal last_stage
now=time.monotonic()
stages.append({'completed_before':message,'seconds':now-last_stage});last_stage=now
if progress:
print(f'Assets [{time.monotonic() - started:.0f}s]: {message}', flush=True)
@@ -90,7 +97,14 @@ def generate_assets(args: argparse.Namespace) -> None:
copy_runtime_fonts(static_assets_dir, staged)
report('generating performance parts')
performance_count = generator.arrange.generate.generate_performance_scores(data_dir / 'songs', staged / 'songs', rhythms=rhythms, scales=scales, sequences=sequences,
composition_jobs=getattr(args,'composition_jobs',2), cache_dir=getattr(args,'composition_cache',None), progress=progress)
composition_jobs=getattr(args,'composition_jobs',2), cache_dir=getattr(args,'composition_cache',None), progress=progress,timings=timings)
if getattr(args,'trace_level','summary')=='summary':
for path in (staged/'analysis').glob('*.roles'):
roles=json.loads(path.read_text())
for role in roles.values():
trace=role.get('details',{}).get('selection_trace',{})
trace.pop('evaluations',None);trace.pop('source_candidate_pools',None)
path.write_text(json.dumps(roles,sort_keys=True,indent=2))
if getattr(args, 'export_solo_xml', False):
from generator.solo.export import export_tree
export_tree(staged)
@@ -110,6 +124,12 @@ def generate_assets(args: argparse.Namespace) -> None:
with modulus.filesystem.publish_directories([(staged, output_dir)]):
pass
report('publishing complete')
profile_path=getattr(args,'profile_output',None)
if profile_path:
import platform,os
profile_path.parent.mkdir(parents=True,exist_ok=True)
profile_path.write_text(json.dumps({'total_seconds':time.monotonic()-started,'stages':stages,'roles':timings,
'platform':platform.platform(),'cpus':os.cpu_count(),'workers':getattr(args,'composition_jobs',2)},indent=2))
print(f'Generated Product Vamp assets: {performance_count} performance scores.')
if args.check:
print('Generator check passed.')