@@ -380,9 +380,7 @@ def generate_memory_html(
380380 }
381381
382382 .group-tag.user { background: rgba(73, 201, 99, 0.15); color: #49C963; }
383- .group-tag.torch { background: rgba(62, 147, 204, 0.15); color: #3E93CC; }
384- .group-tag.cpp { background: rgba(189, 147, 249, 0.15); color: #bd93f9; }
385- .group-tag.python { background: rgba(255, 255, 255, 0.06); color: var(--text-muted); }
383+ .group-tag.internal { background: rgba(255, 255, 255, 0.06); color: var(--text-muted); }
386384
387385 .stack-frame {
388386 padding: 3px 16px 3px 34px;
@@ -550,8 +548,15 @@ def generate_memory_html(
550548 '#C9CC3E', '#D9DB5B', '#B5B72E', '#E3E478',
551549];
552550
551+ function hashStr(s) {
552+ let h = 0;
553+ for (let i = 0; i < s.length; i++) h = ((h << 5) - h + s.charCodeAt(i)) | 0;
554+ return Math.abs(h);
555+ }
556+
553557function getColor(stackIdx) {
554- return PALETTE[(CATEGORIES[stackIdx] || 0) % PALETTE.length];
558+ const frame = bestFrame(stackIdx);
559+ return PALETTE[hashStr(frame) % PALETTE.length];
555560}
556561
557562const tooltipEl = document.getElementById('tooltip');
@@ -569,12 +574,24 @@ def generate_memory_html(
569574function hideTooltip() { tooltipEl.style.display = 'none'; }
570575
571576function classifyFrame(frame) {
572- if (!frame.includes(':') && frame.includes('::')) return 'cpp';
573- if (frame.includes('/site-packages/torch/') || frame.includes('/torch/')) return 'torch';
574- if (frame.includes('/lib/python') || frame.includes('/conda/') || frame.includes('lib/python')) return 'torch';
577+ if (frame.includes('::')) return 'internal';
578+ if (frame.includes('/site-packages/') || frame.includes('/torch/')) return 'internal';
579+ if (frame.includes('/lib/python') || frame.includes('/conda/') || frame.includes('lib/python')) return 'internal';
580+ if (frame.includes('.cpp:') || frame.includes('.c:')) return 'internal';
575581 return 'user';
576582}
577583
584+ function bestFrame(stackIdx) {
585+ const stack = STACKS[stackIdx] || [];
586+ for (const f of stack) {
587+ if (classifyFrame(f) === 'user') return f;
588+ }
589+ for (const f of stack) {
590+ if (f.includes('.py')) return f;
591+ }
592+ return stack[stack.length - 1] || '';
593+ }
594+
578595function renderFrame(frame) {
579596 const hasColon = frame.includes(':');
580597 const isCpp = !hasColon && frame.includes('::');
@@ -599,7 +616,7 @@ def generate_memory_html(
599616 return frame;
600617}
601618
602- const GROUP_LABELS = { user: 'Your Code', torch : 'PyTorch / Python', cpp: 'C++ Runtime ' };
619+ const GROUP_LABELS = { user: 'Your Code', internal : 'Internals ' };
603620
604621function renderStack(stackIdx, label) {
605622 const stack = STACKS[stackIdx] || [];
@@ -707,9 +724,10 @@ def generate_memory_html(
707724 .attr('fill', d => getColor(d.si))
708725 .attr('opacity', 0.85)
709726 .on('mousemove', function(event, d) {
727+ const bf = bestFrame(d.si);
710728 showTooltip(event, [
711729 `<div class="tt-row"><span class="tt-label">Size:</span><span class="tt-value">${formatBytes(d.s)}</span></div>`,
712- (STACKS[d.si]||[])[0] ? `<div class="tt-hint">${STACKS[d.si][0] }</div>` : '',
730+ bf ? `<div class="tt-hint">${bf }</div>` : '',
713731 ].join(''));
714732 })
715733 .on('mouseleave', hideTooltip)
@@ -763,15 +781,15 @@ def generate_memory_html(
763781 const zoomFactor = SPEEDS[speedIdx].zoom;
764782
765783 if (activeKeys.has('a') || activeKeys.has('arrowleft'))
766- t = t.translate(panPx, 0);
784+ t = t.translate(panPx / t.k , 0);
767785 if (activeKeys.has('d') || activeKeys.has('arrowright'))
768- t = t.translate(-panPx, 0);
786+ t = t.translate(-panPx / t.k , 0);
769787 if (activeKeys.has('w') || activeKeys.has('arrowup')) {
770- const cx = width / 2;
788+ const cx = ( width / 2 - t.x) / t.k ;
771789 t = t.translate(cx, 0).scale(zoomFactor).translate(-cx, 0);
772790 }
773791 if (activeKeys.has('s') || activeKeys.has('arrowdown')) {
774- const cx = width / 2;
792+ const cx = ( width / 2 - t.x) / t.k ;
775793 t = t.translate(cx, 0).scale(1 / zoomFactor).translate(-cx, 0);
776794 }
777795 return t;
0 commit comments