uvnote-book-explore / causal_conv1d /impls /torch_causal_conv1d.html
drbh's picture
drbh HF Staff
Upload folder using huggingface_hub
b17c1a4 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>torch_causal_conv1d</title>
<script>
// Iframe-friendly navigation router
(function() {
const isIframe = window.self !== window.top;
if (!isIframe) return; // Only activate in iframe context
// On load: if hash points to a different page, navigate there
const hash = window.location.hash;
if (hash && hash.startsWith('#/')) {
const targetPath = hash.slice(2); // Remove '#/'
const currentPath = window.location.pathname.split('/').pop();
// Only navigate if we're not already on the target page
if (targetPath !== currentPath) {
window.location.href = targetPath;
return; // Stop execution, we're navigating away
}
}
// Intercept all link clicks for hash-based navigation
document.addEventListener('click', function(e) {
const link = e.target.closest('a');
if (!link) return;
const href = link.getAttribute('href');
// Skip external links, anchors, and javascript: links
if (!href || href.startsWith('#') || href.startsWith('http') || href.startsWith('javascript:')) {
return;
}
e.preventDefault();
// Convert relative/absolute path to hash-based navigation
const url = new URL(href, window.location.href);
let fullPath = url.pathname;
// Remove leading slash if present for cleaner paths
if (fullPath.startsWith('/')) {
fullPath = fullPath.slice(1);
}
// Update parent URL hash
window.location.hash = '#/' + fullPath;
// For HTML files, navigate within iframe
if (fullPath.endsWith('.html') || fullPath.endsWith('/')) {
const pathParts = fullPath.split('/').filter(p => p);
const targetFile = pathParts[pathParts.length - 1] || 'index.html';
window.location.href = targetFile;
} else {
// For non-HTML files (raw .py, etc), open directly
window.open(href, '_blank');
}
});
})();
// Apply theme and widget visibility immediately to prevent flicker
(function() {
const configTheme = 'dark';
const hasConfigUi = false;
const configUi = hasConfigUi ? 'None' : null;
const hasWidgetsConfig = false;
const widgetsOn = hasWidgetsConfig ? false : true;
let theme;
if (configTheme === 'auto') {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
} else {
theme = localStorage.getItem('uvnote-theme') || configTheme;
}
document.documentElement.setAttribute('data-theme', theme);
// Initialize UI theme (css theme)
let ui = hasConfigUi ? configUi : (localStorage.getItem('uvnote-ui') || 'default');
if (ui !== 'default' && ui !== 'none' && ui !== 'monocolor') { ui = 'default'; }
document.documentElement.setAttribute('data-ui', ui);
// Apply widgets visibility
document.documentElement.setAttribute('data-widgets', widgetsOn ? 'on' : 'off');
})();
</script>
<style>
:root[data-theme="light"] {
--bg-primary: #ffffff;
--bg-secondary: #f6f8fa;
--bg-tertiary: #f8f9fa;
--bg-code: #f8f9fa;
--bg-error: #fdf2f2;
--bg-artifact: #e6f3ff;
--bg-artifact-hover: #d0e7ff;
--text-primary: #333;
--text-secondary: #656d76;
--text-error: #c53030;
--text-link: #0969da;
--border-primary: #e1e5e9;
--border-error: #e53e3e;
--border-cell-failed: #d73a49;
--shadow: rgba(0, 0, 0, 0.1);
}
:root[data-theme="dark"] {
--bg-primary: #0a0a0a;
--bg-secondary: #121212;
--bg-tertiary: #181818;
--bg-code: #0d0d0d;
--bg-error: #1a0f0f;
--bg-artifact: #151515;
--bg-artifact-hover: #1a1a1a;
--text-primary: #e0e0e0;
--text-secondary: #888888;
--text-error: #ff6b6b;
--text-link: #64b5f6;
--border-primary: #2a2a2a;
--border-error: #ff6b6b;
--border-cell-failed: #ff6b6b;
--shadow: rgba(255, 255, 255, 0.05);
}
/* Monocolor UI theme: black/white background, all text/borders single blue */
:root[data-ui="monocolor"] { --mono-color: #0a66ff; }
:root[data-ui="monocolor"][data-theme="light"] {
--bg-primary: #ffffff;
}
:root[data-ui="monocolor"][data-theme="dark"] {
--bg-primary: #000000;
}
:root[data-ui="monocolor"] {
--bg-secondary: var(--bg-primary);
--bg-tertiary: var(--bg-primary);
--bg-code: var(--bg-primary);
--bg-error: var(--bg-primary);
--bg-artifact: var(--bg-primary);
--bg-artifact-hover: var(--bg-primary);
--text-primary: var(--mono-color);
--text-secondary: var(--mono-color);
--text-error: var(--mono-color);
--text-link: var(--mono-color);
--border-primary: var(--mono-color);
--border-error: var(--mono-color);
--border-cell-failed: var(--mono-color);
--shadow: none;
}
:root[data-ui="monocolor"] a { color: var(--mono-color); }
:root[data-ui="monocolor"] .menu-button,
:root[data-ui="monocolor"] .theme-toggle,
:root[data-ui="monocolor"] .reset-toggle,
:root[data-ui="monocolor"] .back-button { background: var(--bg-primary); color: var(--mono-color); border-color: var(--mono-color); }
:root[data-ui="monocolor"] .menu-button:hover,
:root[data-ui="monocolor"] .theme-toggle:hover,
:root[data-ui="monocolor"] .reset-toggle:hover,
:root[data-ui="monocolor"] .back-button:hover { background: var(--bg-primary); color: var(--mono-color); border-color: var(--mono-color); }
:root[data-ui="monocolor"] .menu-dropdown { background: var(--bg-primary); border-color: var(--mono-color); box-shadow: none; }
:root[data-ui="monocolor"] .menu-item { color: var(--mono-color); border-bottom-color: var(--mono-color); }
:root[data-ui="monocolor"] .system-info { background: var(--bg-primary); border-color: var(--mono-color); }
:root[data-ui="monocolor"] .cell { border-color: var(--mono-color); background: var(--bg-primary); }
:root[data-ui="monocolor"] .cell-header { background: var(--bg-primary); border-bottom-color: var(--mono-color); }
:root[data-ui="monocolor"] .artifact { background: var(--bg-primary); border-color: var(--mono-color); color: var(--mono-color); }
:root[data-ui="monocolor"] .artifact:hover { background: var(--bg-primary); }
:root[data-ui="monocolor"] .artifact-preview img,
:root[data-ui="monocolor"] .artifact-preview svg { border-color: var(--mono-color); }
:root[data-ui="monocolor"] .status-widget { background: var(--bg-primary); border-color: var(--mono-color); color: var(--mono-color); }
:root[data-ui="monocolor"] .minimap,
:root[data-ui="monocolor"] .file-explorer,
:root[data-ui="monocolor"] .tools-widget {
background: var(--bg-primary);
border-color: var(--mono-color);
color: var(--mono-color);
}
:root[data-ui="monocolor"] .cell-code {
background: var(--bg-primary);
border-bottom-color: var(--mono-color);
}
:root[data-ui="monocolor"] .tools-title,
:root[data-ui="monocolor"] .file-explorer-section-title,
:root[data-ui="monocolor"] .minimap-title { color: var(--mono-color); border-bottom-color: var(--mono-color); }
:root[data-ui="monocolor"] .tool-button { background: var(--bg-primary); border-color: var(--mono-color); color: var(--mono-color); }
:root[data-ui="monocolor"] .tool-button.active { border-color: var(--mono-color); }
:root[data-ui="monocolor"] .file-explorer-item,
:root[data-ui="monocolor"] .minimap-item { color: var(--mono-color); }
/* Force Pygments code to mono blue on mono bg */
:root[data-ui="monocolor"] .highlight { background: var(--bg-primary) !important; color: var(--mono-color) !important; }
:root[data-ui="monocolor"] .highlight *,
:root[data-ui="monocolor"] .highlight .hll { color: var(--mono-color) !important; background: transparent !important; border-color: var(--mono-color) !important; }
/* Default code font + metrics (overridable via frontmatter) */
:root { --code-font-size: 0.95rem; --code-line-height: 1.5; --code-pad-y: 0.75rem; }
/* Minimal UI theme overrides base variables for a flatter, 90s look */
:root[data-ui="none"] {
--bg-primary: #ffffff;
--bg-secondary: transparent;
--bg-tertiary: transparent;
--bg-code: #f9f9f9;
--bg-error: #fff0f0;
--bg-artifact: #f0f7ff;
--bg-artifact-hover: #e5f1ff;
--text-primary: #000000;
--text-secondary: #222222;
--text-error: #a00000;
--text-link: #0000ee;
--border-primary: #cccccc;
--border-error: #cc0000;
--border-cell-failed: #cc0000;
--shadow: none;
}
html {
overscroll-behavior: none;
}
body {
font-family: 'Cascadia Mono', 'Cascadia Code', 'JetBrains Mono', 'SF Mono', Monaco, 'Consolas', monospace;
line-height: 1.4;
max-width: 1000px;
margin: 0 auto;
padding: 15px;
color: var(--text-primary);
background: var(--bg-primary);
transition: background-color 0.2s ease, color 0.2s ease;
overscroll-behavior: none;
}
/* Minimal "none" UI theme overrides */
:root[data-ui="none"] body {
font-family: 'Times New Roman', Times, serif;
line-height: 1.5;
max-width: 860px;
padding: 12px;
background: #ffffff;
color: #000000;
transition: none;
}
/* Two panel layout removed */
.controls {
position: fixed;
top: 20px;
right: 20px;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 0.25rem;
z-index: 1000;
}
.controls-buttons { display: flex; gap: 0.5rem; }
.menu-button {
position: relative;
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
padding: 8px 12px;
border-radius: 2px;
color: var(--text-secondary);
cursor: pointer;
font-family: inherit;
font-size: 0.9rem;
user-select: none;
}
/* Keep default control styling when widgets are enabled, even in minimal UI */
:root[data-ui="none"][data-widgets="on"] .menu-button,
:root[data-ui="none"][data-widgets="on"] .theme-toggle,
:root[data-ui="none"][data-widgets="on"] .reset-toggle,
:root[data-ui="none"][data-widgets="on"] .back-button {
background: #f6f6f6;
border: 1px solid #cccccc;
color: #222222;
}
.menu-button:hover {
color: var(--text-primary);
background: var(--bg-tertiary);
}
/* Controls state indicator (top-right) */
/* Status widget (bottom-right) */
.status-widget {
position: fixed;
right: 20px;
bottom: 20px;
width: auto;
max-width: 260px;
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 2px;
padding: 6px 8px;
font-size: 0.8rem;
color: var(--text-secondary);
z-index: 100;
}
.status-widget strong { color: var(--text-primary); }
:root[data-ui="none"][data-widgets="on"] .status-widget { background: #f6f6f6; border-color: #ccc; color: #222; }
:root[data-ui="none"][data-widgets="on"] .menu-button:hover,
:root[data-ui="none"][data-widgets="on"] .theme-toggle:hover,
:root[data-ui="none"][data-widgets="on"] .reset-toggle:hover,
:root[data-ui="none"][data-widgets="on"] .back-button:hover {
background: #ededed;
border-color: #bbbbbb;
color: #000000;
}
.menu-dropdown {
position: absolute;
top: 100%;
right: 0;
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 4px;
box-shadow: 0 4px 12px var(--shadow);
min-width: 160px;
opacity: 0;
visibility: hidden;
transform: translateY(-8px);
transition: all 0.2s ease;
z-index: 1001;
margin-top: 4px;
}
:root[data-ui="none"][data-widgets="on"] .menu-dropdown { background: #ffffff; border: 1px solid #cccccc; box-shadow: none; }
.menu-button.active .menu-dropdown {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.menu-item {
display: block;
padding: 8px 12px;
color: var(--text-secondary);
text-decoration: none;
font-size: 0.85rem;
border-bottom: 1px solid var(--border-primary);
cursor: pointer;
}
:root[data-ui="none"] .menu-item { color: #000; border-bottom: 1px solid #eee; }
.menu-item:last-child {
border-bottom: none;
}
.menu-item:hover {
background: var(--bg-tertiary);
color: var(--text-primary);
}
.menu-checkbox {
display: inline-block;
width: 16px;
font-family: monospace;
color: var(--text-link);
}
.theme-toggle,
.reset-toggle,
.back-button {
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
padding: 8px 12px;
border-radius: 4px;
color: var(--text-secondary);
cursor: pointer;
font-family: inherit;
font-size: 0.9rem;
user-select: none;
}
.back-button {
text-decoration: none;
display: inline-block;
}
.theme-toggle:hover,
.reset-toggle:hover,
.back-button:hover {
color: var(--text-primary);
background: var(--bg-tertiary);
}
.system-info {
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 4px;
padding: 8px 12px;
margin-bottom: 16px;
font-size: 0.85em;
color: var(--text-secondary);
}
.system-info-header {
font-weight: 600;
color: var(--text-primary);
margin-bottom: 2px;
}
.system-info-content {
font-family: monospace;
}
.theme-toggle, .reset-toggle {
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 2px;
/* padding: 0.4rem 0.6rem; */
cursor: pointer;
font-family: inherit;
font-size: 0.8rem;
color: var(--text-secondary);
user-select: none;
transition: all 0.2s ease;
text-transform: lowercase;
letter-spacing: 0;
}
.theme-toggle:hover, .reset-toggle:hover {
background: var(--bg-tertiary);
border-color: var(--text-secondary);
color: var(--text-primary);
}
.minimap {
position: fixed;
bottom: 20px;
right: 20px;
width: 220px;
max-height: 400px;
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 2px;
padding: 0.5rem;
font-size: 0.7rem;
overflow-y: auto;
z-index: 100;
opacity: 0.9;
transition: opacity 0.2s ease;
}
/* Hide widgets and controls when disabled via frontmatter */
:root[data-widgets="off"] .controls,
:root[data-widgets="off"] .minimap,
:root[data-widgets="off"] .file-explorer,
:root[data-widgets="off"] .tools-widget,
:root[data-widgets="off"] .status-widget { display: none !important; }
.file-explorer {
position: fixed;
bottom: 20px; /* default; JS will stack */
right: 20px;
left: auto;
top: auto;
width: 220px;
max-height: 400px;
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 2px;
padding: 0.5rem;
font-size: 0.7rem;
overflow-y: auto;
z-index: 100;
opacity: 0.9;
transition: opacity 0.2s ease;
}
/* Drawing overlay */
.draw-overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 80; /* under widgets (100) and controls (1000) */
display: block;
pointer-events: none; /* enabled only when a tool is active */
}
/* Tools widget */
.tools-widget {
position: fixed;
bottom: 20px; /* default; JS will stack */
right: 20px;
left: auto;
top: auto;
width: 220px;
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 2px;
padding: 0.5rem;
font-size: 0.7rem;
z-index: 100;
opacity: 0.95;
}
.tools-title {
font-weight: bold;
color: var(--text-secondary);
margin-bottom: 0.5rem;
padding-bottom: 0.25rem;
border-bottom: 1px solid var(--border-primary);
cursor: grab;
user-select: none;
}
.tools-row { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.tool-button {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
border-radius: 2px;
padding: 0.25rem 0.4rem;
cursor: pointer;
color: var(--text-secondary);
font-family: inherit;
font-size: 0.75rem;
user-select: none;
}
.tool-button:hover { color: var(--text-primary); }
.tool-button.active { color: var(--text-primary); border-color: var(--text-secondary); background: var(--bg-secondary); }
.minimap:hover, .file-explorer:hover {
opacity: 1;
}
.minimap-title {
font-weight: bold;
color: var(--text-secondary);
margin-bottom: 0.5rem;
padding-bottom: 0.25rem;
border-bottom: 1px solid var(--border-primary);
cursor: grab; /* drag handle */
user-select: none;
}
.minimap-item {
display: block;
color: var(--text-secondary);
text-decoration: none;
padding: 0.15rem 0;
border-left: 2px solid transparent;
padding-left: 0.5rem;
transition: all 0.2s ease;
cursor: pointer;
}
.minimap-item:hover {
color: var(--text-primary);
border-left-color: var(--text-secondary);
}
.minimap-item.active {
color: var(--text-primary);
border-left-color: var(--text-link);
}
.minimap-heading {
font-weight: normal;
}
.minimap-heading.h1 { padding-left: 0.5rem; }
.minimap-heading.h2 { padding-left: 1rem; }
.minimap-heading.h3 { padding-left: 1.5rem; }
.minimap-heading.h4 { padding-left: 2rem; }
.minimap-heading.h5 { padding-left: 2.5rem; }
.minimap-heading.h6 { padding-left: 3rem; }
.minimap-cell {
color: var(--text-link);
opacity: 0.8;
font-style: italic;
}
.minimap-cell:hover {
opacity: 1;
}
.file-explorer-title {
font-weight: bold;
color: var(--text-secondary);
margin-bottom: 0.5rem;
padding-bottom: 0.25rem;
border-bottom: 1px solid var(--border-primary);
cursor: grab; /* drag handle */
user-select: none;
}
.file-explorer-section {
margin-bottom: 0.75rem;
}
.file-explorer-section-title {
font-weight: bold;
color: var(--text-secondary);
font-size: 0.65rem;
margin-bottom: 0.25rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.file-explorer-item {
display: block;
color: var(--text-secondary);
text-decoration: none;
padding: 0.1rem 0;
margin-left: 0.5rem;
transition: color 0.2s ease;
cursor: pointer;
font-family: monospace;
}
.file-explorer-item:hover {
color: var(--text-primary);
}
.file-explorer-item.script {
color: var(--text-link);
}
.file-explorer-item.artifact {
color: var(--text-secondary);
opacity: 0.8;
}
/* Hide widgets on smaller screens */
@media (max-width: 768px) {
.minimap, .file-explorer, .tools-widget {
display: none;
}
}
.cell {
margin: 1rem 0;
border: 1px solid var(--border-primary);
border-radius: 2px;
overflow: hidden;
background: var(--bg-secondary);
}
:root[data-ui="none"] .cell { margin: 1em 0; border: none; background: transparent; }
.cell-header {
background: var(--bg-secondary);
padding: 0.5rem 1rem;
border-bottom: 1px solid var(--border-primary);
font-family: inherit;
font-size: 0.85rem;
}
:root[data-ui="none"] .cell-header { background: transparent; border: none; padding: 0; font-weight: bold; }
:root[data-ui="none"] .cell-content { padding: 0; }
:root[data-ui="none"] .copy-button,
:root[data-ui="none"] .collapse-indicators,
:root[data-ui="none"] .cell-meta,
:root[data-ui="none"] .cell-outputs-header { display: none !important; }
:root[data-ui="none"] pre, :root[data-ui="none"] code { font-family: Menlo, Monaco, 'Courier New', monospace; }
:root[data-ui="none"] .code-content pre { background: #f9f9f9; border: 1px solid #ddd; padding: 8px; }
:root[data-ui="none"] .output { background: transparent; border: none; padding: 0.25em 0; }
color: var(--text-secondary);
cursor: pointer;
user-select: none;
transition: background-color 0.2s ease;
}
.cell-header:hover {
background: var(--bg-tertiary);
}
.collapse-indicators {
color: var(--text-secondary);
font-size: 0.8rem;
opacity: 0.7;
}
.collapse-indicators span:hover {
color: var(--text-primary);
opacity: 1;
}
.cell-code {
display: block;
background: var(--bg-code);
}
.cell-code.collapsed {
display: none;
}
.cell-code pre {
margin: 0;
padding: 0.75rem;
background: var(--bg-code);
overflow-x: auto;
color: var(--text-primary);
}
.cell-output {
padding: 0.75rem;
/* background: var(--bg-primary); */
background: var(--bg-secondary);
}
.cell-output.collapsed {
display: none;
}
.cell-stdout {
background: var(--bg-tertiary);
padding: 0.75rem;
border-radius: 1px;
/* margin: 0.25rem 0; */
font-family: inherit;
font-size: 0.9rem;
white-space: pre-wrap;
color: var(--text-primary);
}
.cell-stdout {
background: var(--bg-tertiary);
padding: 0.75rem;
border-radius: 1px;
font-family: inherit;
font-size: 0.9rem;
color: var(--text-primary);
/* key bits */
overflow: auto; /* show scrollbars when needed */
max-width: 100%; /* respects whatever layout width you give it */
}
.cell-stdout .stdout-text {
margin: 0; /* reset pre default margin */
white-space: pre; /* keep line breaks, NO wrapping */
display: inline-block; /* shrink-to-content */
min-width: max-content; /* allow very long lines to define intrinsic width */
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
tab-size: 2;
}
.cell-stderr {
background: var(--bg-error);
border-left: 2px solid var(--border-error);
padding: 1rem;
margin: 0.5rem 0;
font-family: inherit;
font-size: 0.9rem;
color: var(--text-error);
white-space: pre-wrap;
}
.uv-install-logs {
margin: 0.5rem 0;
}
.uv-logs-header {
cursor: pointer;
padding: 0.75rem;
border-left: 3px solid var(--border-color);
font-family: inherit;
font-size: 0.85rem;
color: var(--text-secondary);
user-select: none;
}
.uv-logs-content {
background: var(--bg-secondary);
padding: 1rem;
border-left: 3px solid var(--border-color);
white-space: pre-wrap;
font-family: monospace;
font-size: 0.85rem;
color: var(--text-secondary);
overflow-x: auto;
}
.cell-artifacts {
margin: 1rem 0;
}
.cell-artifacts h4 {
margin: 0 0 0.5rem 0;
color: var(--text-secondary);
font-size: 0.9rem;
}
.artifact {
display: inline-block;
background: var(--bg-artifact);
padding: 0.25rem 0.5rem;
border-radius: 1px;
margin: 0.25rem 0.5rem 0.25rem 0;
font-family: inherit;
font-size: 0.8rem;
color: var(--text-link);
text-decoration: none;
transition: background-color 0.2s ease;
border: 1px solid var(--border-primary);
}
.artifact:hover {
background: var(--bg-artifact-hover);
}
.artifact-preview {
margin-top: 1rem;
}
.artifact-preview img {
max-width: 100%;
height: auto;
border: 1px solid var(--border-primary);
border-radius: 1px;
}
.artifact-preview svg {
max-width: 100%;
height: auto;
border: 1px solid var(--border-primary);
border-radius: 1px;
display: block;
}
/* Style SVG text elements */
.artifact-preview svg g {
fill: var(--text-primary) !important;
}
/* Auto-theme SVG elements */
.artifact-preview svg {
background: transparent;
}
/* CSV table styling */
.artifact-csv {
margin-top: 1rem;
overflow-x: auto;
}
.csv-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 1px;
}
.csv-table th,
.csv-table td {
padding: 0.5rem 0.75rem;
text-align: left;
border: 1px solid var(--border-primary);
}
.csv-table th {
background: var(--bg-tertiary);
font-weight: 600;
color: var(--text-primary);
}
.csv-table tbody tr:hover {
background: var(--bg-artifact-hover);
}
.artifact-csv-error {
margin-top: 1rem;
padding: 1rem;
background: var(--bg-error);
color: var(--text-error);
border: 1px solid var(--border-error);
border-radius: 1px;
}
.cell-failed {
border-color: var(--border-cell-failed);
}
.cell-failed .cell-header {
background: var(--bg-error);
color: var(--text-error);
}
.cell-commented {
opacity: 0.6;
border-style: dashed;
}
.cell-commented .cell-header {
background: var(--bg-secondary);
color: var(--text-secondary);
font-style: italic;
}
.run-btn {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
padding: 2px 6px;
border-radius: 2px;
color: var(--text-secondary);
cursor: pointer;
font-size: 0.75em;
font-family: inherit;
margin-left: 4px;
}
.run-btn:hover {
color: var(--text-primary);
background: var(--bg-primary);
}
.run-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.copy-btn {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
padding: 2px 6px;
border-radius: 2px;
color: var(--text-secondary);
cursor: pointer;
font-size: 0.75em;
font-family: inherit;
margin-left: 4px;
}
.copy-btn:hover {
color: var(--text-primary);
background: var(--bg-primary);
}
.copy-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.copy-btn.copied {
color: #4caf50;
background: var(--bg-primary);
border-color: #4caf50;
transition: all 0.2s ease;
}
.raw-btn {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
padding: 2px 6px;
border-radius: 2px;
color: var(--text-secondary);
cursor: pointer;
font-size: 0.75em;
font-family: inherit;
margin-left: 4px;
text-decoration: none;
display: inline-block;
}
.raw-btn:hover {
color: var(--text-primary);
background: var(--bg-primary);
text-decoration: none;
}
.github-btn {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
padding: 2px 6px;
border-radius: 2px;
color: var(--text-secondary);
cursor: pointer;
font-size: 0.75em;
font-family: inherit;
margin-left: 4px;
text-decoration: none;
display: inline-block;
}
.github-btn:hover {
color: var(--text-primary);
background: var(--bg-primary);
text-decoration: none;
}
.hf-btn {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
padding: 2px 6px;
border-radius: 2px;
color: var(--text-secondary);
cursor: pointer;
font-size: 0.75em;
font-family: inherit;
margin-left: 4px;
text-decoration: none;
display: inline-block;
}
.hf-btn:hover {
color: var(--text-primary);
background: var(--bg-primary);
text-decoration: none;
}
.output-stale {
opacity: 0.5;
position: relative;
}
.output-stale::after {
content: '⏳ updating...';
position: absolute;
top: 8px;
right: 8px;
background: var(--bg-secondary);
padding: 4px 8px;
border-radius: 2px;
font-size: 0.75em;
color: var(--text-secondary);
border: 1px solid var(--border-primary);
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.5rem;
margin-bottom: 0.75rem;
color: var(--text-primary);
}
h1 {
margin-top: 0;
margin-bottom: 1rem;
}
p {
margin: 0.75rem 0;
color: var(--text-primary);
}
a {
color: var(--text-link);
}
img {
max-width: 100%;
height: auto;
border-radius: 1px;
box-shadow: none;
}
pre, code {
font-family: 'Cascadia Mono', 'Cascadia Code', 'JetBrains Mono', 'SF Mono', Monaco, 'Consolas', monospace;
font-size: var(--code-font-size);
}
.code-wrap { position: relative; }
.code-line-highlight { display: none; position: absolute; left: 0; right: 0; height: 1.5em; background: rgba(255, 235, 170, 0.35); pointer-events: none; border-left: 3px solid #f4c542; }
.line-number { cursor: pointer; text-decoration: none; color: var(--text-secondary); padding: 0 0.25rem; }
.line-number.selected { background: rgba(255, 235, 170, 0.4); color: var(--text-primary); }
/* Line numbers */
.highlight-with-lines {
display: flex;
}
.line-numbers {
background: var(--bg-tertiary);
padding: var(--code-pad-y) 0.5rem;
font-family: 'Cascadia Mono', 'Cascadia Code', 'JetBrains Mono', 'SF Mono', Monaco, 'Consolas', monospace;
font-size: var(--code-font-size);
line-height: var(--code-line-height);
color: var(--text-secondary);
user-select: none;
text-align: right;
border-right: 1px solid var(--border-primary);
}
.line-numbers .line-number {
display: block;
line-height: var(--code-line-height);
}
.highlight-with-lines .highlight {
flex: 1;
}
.highlight .hll { background-color: transparent; } /* don't conflict with our highlight */
.highlight pre {
white-space: pre;
margin: 0;
padding: var(--code-pad-y) 0.75rem;
line-height: var(--code-line-height);
}
/* Collapsed code styling */
.cell-code.collapsed {
display: none;
}
.cell-code.expanded {
display: block;
}
.cell-code {
display: block;
border-bottom: 1px solid var(--border-primary);
}
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
[data-theme="light"] .highlight .hll { background-color: #ffffcc }
[data-theme="light"] .highlight { background: #f8f8f8; }
[data-theme="light"] .highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
[data-theme="light"] .highlight .err { border: 1px solid #F00 } /* Error */
[data-theme="light"] .highlight .k { color: #008000; font-weight: bold } /* Keyword */
[data-theme="light"] .highlight .o { color: #666 } /* Operator */
[data-theme="light"] .highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
[data-theme="light"] .highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
[data-theme="light"] .highlight .cp { color: #9C6500 } /* Comment.Preproc */
[data-theme="light"] .highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
[data-theme="light"] .highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
[data-theme="light"] .highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
[data-theme="light"] .highlight .gd { color: #A00000 } /* Generic.Deleted */
[data-theme="light"] .highlight .ge { font-style: italic } /* Generic.Emph */
[data-theme="light"] .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
[data-theme="light"] .highlight .gr { color: #E40000 } /* Generic.Error */
[data-theme="light"] .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
[data-theme="light"] .highlight .gi { color: #008400 } /* Generic.Inserted */
[data-theme="light"] .highlight .go { color: #717171 } /* Generic.Output */
[data-theme="light"] .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
[data-theme="light"] .highlight .gs { font-weight: bold } /* Generic.Strong */
[data-theme="light"] .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
[data-theme="light"] .highlight .gt { color: #04D } /* Generic.Traceback */
[data-theme="light"] .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
[data-theme="light"] .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
[data-theme="light"] .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
[data-theme="light"] .highlight .kp { color: #008000 } /* Keyword.Pseudo */
[data-theme="light"] .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
[data-theme="light"] .highlight .kt { color: #B00040 } /* Keyword.Type */
[data-theme="light"] .highlight .m { color: #666 } /* Literal.Number */
[data-theme="light"] .highlight .s { color: #BA2121 } /* Literal.String */
[data-theme="light"] .highlight .na { color: #687822 } /* Name.Attribute */
[data-theme="light"] .highlight .nb { color: #008000 } /* Name.Builtin */
[data-theme="light"] .highlight .nc { color: #00F; font-weight: bold } /* Name.Class */
[data-theme="light"] .highlight .no { color: #800 } /* Name.Constant */
[data-theme="light"] .highlight .nd { color: #A2F } /* Name.Decorator */
[data-theme="light"] .highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
[data-theme="light"] .highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
[data-theme="light"] .highlight .nf { color: #00F } /* Name.Function */
[data-theme="light"] .highlight .nl { color: #767600 } /* Name.Label */
[data-theme="light"] .highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */
[data-theme="light"] .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
[data-theme="light"] .highlight .nv { color: #19177C } /* Name.Variable */
[data-theme="light"] .highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */
[data-theme="light"] .highlight .w { color: #BBB } /* Text.Whitespace */
[data-theme="light"] .highlight .mb { color: #666 } /* Literal.Number.Bin */
[data-theme="light"] .highlight .mf { color: #666 } /* Literal.Number.Float */
[data-theme="light"] .highlight .mh { color: #666 } /* Literal.Number.Hex */
[data-theme="light"] .highlight .mi { color: #666 } /* Literal.Number.Integer */
[data-theme="light"] .highlight .mo { color: #666 } /* Literal.Number.Oct */
[data-theme="light"] .highlight .sa { color: #BA2121 } /* Literal.String.Affix */
[data-theme="light"] .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
[data-theme="light"] .highlight .sc { color: #BA2121 } /* Literal.String.Char */
[data-theme="light"] .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
[data-theme="light"] .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
[data-theme="light"] .highlight .s2 { color: #BA2121 } /* Literal.String.Double */
[data-theme="light"] .highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
[data-theme="light"] .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
[data-theme="light"] .highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
[data-theme="light"] .highlight .sx { color: #008000 } /* Literal.String.Other */
[data-theme="light"] .highlight .sr { color: #A45A77 } /* Literal.String.Regex */
[data-theme="light"] .highlight .s1 { color: #BA2121 } /* Literal.String.Single */
[data-theme="light"] .highlight .ss { color: #19177C } /* Literal.String.Symbol */
[data-theme="light"] .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
[data-theme="light"] .highlight .fm { color: #00F } /* Name.Function.Magic */
[data-theme="light"] .highlight .vc { color: #19177C } /* Name.Variable.Class */
[data-theme="light"] .highlight .vg { color: #19177C } /* Name.Variable.Global */
[data-theme="light"] .highlight .vi { color: #19177C } /* Name.Variable.Instance */
[data-theme="light"] .highlight .vm { color: #19177C } /* Name.Variable.Magic */
[data-theme="light"] .highlight .il { color: #666 } /* Literal.Number.Integer.Long */
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
[data-theme="dark"] .highlight .hll { background-color: #49483e }
[data-theme="dark"] .highlight { background: #272822; color: #F8F8F2 }
[data-theme="dark"] .highlight .c { color: #959077 } /* Comment */
[data-theme="dark"] .highlight .err { color: #ED007E; background-color: #1E0010 } /* Error */
[data-theme="dark"] .highlight .esc { color: #F8F8F2 } /* Escape */
[data-theme="dark"] .highlight .g { color: #F8F8F2 } /* Generic */
[data-theme="dark"] .highlight .k { color: #66D9EF } /* Keyword */
[data-theme="dark"] .highlight .l { color: #AE81FF } /* Literal */
[data-theme="dark"] .highlight .n { color: #F8F8F2 } /* Name */
[data-theme="dark"] .highlight .o { color: #FF4689 } /* Operator */
[data-theme="dark"] .highlight .x { color: #F8F8F2 } /* Other */
[data-theme="dark"] .highlight .p { color: #F8F8F2 } /* Punctuation */
[data-theme="dark"] .highlight .ch { color: #959077 } /* Comment.Hashbang */
[data-theme="dark"] .highlight .cm { color: #959077 } /* Comment.Multiline */
[data-theme="dark"] .highlight .cp { color: #959077 } /* Comment.Preproc */
[data-theme="dark"] .highlight .cpf { color: #959077 } /* Comment.PreprocFile */
[data-theme="dark"] .highlight .c1 { color: #959077 } /* Comment.Single */
[data-theme="dark"] .highlight .cs { color: #959077 } /* Comment.Special */
[data-theme="dark"] .highlight .gd { color: #FF4689 } /* Generic.Deleted */
[data-theme="dark"] .highlight .ge { color: #F8F8F2; font-style: italic } /* Generic.Emph */
[data-theme="dark"] .highlight .ges { color: #F8F8F2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
[data-theme="dark"] .highlight .gr { color: #F8F8F2 } /* Generic.Error */
[data-theme="dark"] .highlight .gh { color: #F8F8F2 } /* Generic.Heading */
[data-theme="dark"] .highlight .gi { color: #A6E22E } /* Generic.Inserted */
[data-theme="dark"] .highlight .go { color: #66D9EF } /* Generic.Output */
[data-theme="dark"] .highlight .gp { color: #FF4689; font-weight: bold } /* Generic.Prompt */
[data-theme="dark"] .highlight .gs { color: #F8F8F2; font-weight: bold } /* Generic.Strong */
[data-theme="dark"] .highlight .gu { color: #959077 } /* Generic.Subheading */
[data-theme="dark"] .highlight .gt { color: #F8F8F2 } /* Generic.Traceback */
[data-theme="dark"] .highlight .kc { color: #66D9EF } /* Keyword.Constant */
[data-theme="dark"] .highlight .kd { color: #66D9EF } /* Keyword.Declaration */
[data-theme="dark"] .highlight .kn { color: #FF4689 } /* Keyword.Namespace */
[data-theme="dark"] .highlight .kp { color: #66D9EF } /* Keyword.Pseudo */
[data-theme="dark"] .highlight .kr { color: #66D9EF } /* Keyword.Reserved */
[data-theme="dark"] .highlight .kt { color: #66D9EF } /* Keyword.Type */
[data-theme="dark"] .highlight .ld { color: #E6DB74 } /* Literal.Date */
[data-theme="dark"] .highlight .m { color: #AE81FF } /* Literal.Number */
[data-theme="dark"] .highlight .s { color: #E6DB74 } /* Literal.String */
[data-theme="dark"] .highlight .na { color: #A6E22E } /* Name.Attribute */
[data-theme="dark"] .highlight .nb { color: #F8F8F2 } /* Name.Builtin */
[data-theme="dark"] .highlight .nc { color: #A6E22E } /* Name.Class */
[data-theme="dark"] .highlight .no { color: #66D9EF } /* Name.Constant */
[data-theme="dark"] .highlight .nd { color: #A6E22E } /* Name.Decorator */
[data-theme="dark"] .highlight .ni { color: #F8F8F2 } /* Name.Entity */
[data-theme="dark"] .highlight .ne { color: #A6E22E } /* Name.Exception */
[data-theme="dark"] .highlight .nf { color: #A6E22E } /* Name.Function */
[data-theme="dark"] .highlight .nl { color: #F8F8F2 } /* Name.Label */
[data-theme="dark"] .highlight .nn { color: #F8F8F2 } /* Name.Namespace */
[data-theme="dark"] .highlight .nx { color: #A6E22E } /* Name.Other */
[data-theme="dark"] .highlight .py { color: #F8F8F2 } /* Name.Property */
[data-theme="dark"] .highlight .nt { color: #FF4689 } /* Name.Tag */
[data-theme="dark"] .highlight .nv { color: #F8F8F2 } /* Name.Variable */
[data-theme="dark"] .highlight .ow { color: #FF4689 } /* Operator.Word */
[data-theme="dark"] .highlight .pm { color: #F8F8F2 } /* Punctuation.Marker */
[data-theme="dark"] .highlight .w { color: #F8F8F2 } /* Text.Whitespace */
[data-theme="dark"] .highlight .mb { color: #AE81FF } /* Literal.Number.Bin */
[data-theme="dark"] .highlight .mf { color: #AE81FF } /* Literal.Number.Float */
[data-theme="dark"] .highlight .mh { color: #AE81FF } /* Literal.Number.Hex */
[data-theme="dark"] .highlight .mi { color: #AE81FF } /* Literal.Number.Integer */
[data-theme="dark"] .highlight .mo { color: #AE81FF } /* Literal.Number.Oct */
[data-theme="dark"] .highlight .sa { color: #E6DB74 } /* Literal.String.Affix */
[data-theme="dark"] .highlight .sb { color: #E6DB74 } /* Literal.String.Backtick */
[data-theme="dark"] .highlight .sc { color: #E6DB74 } /* Literal.String.Char */
[data-theme="dark"] .highlight .dl { color: #E6DB74 } /* Literal.String.Delimiter */
[data-theme="dark"] .highlight .sd { color: #E6DB74 } /* Literal.String.Doc */
[data-theme="dark"] .highlight .s2 { color: #E6DB74 } /* Literal.String.Double */
[data-theme="dark"] .highlight .se { color: #AE81FF } /* Literal.String.Escape */
[data-theme="dark"] .highlight .sh { color: #E6DB74 } /* Literal.String.Heredoc */
[data-theme="dark"] .highlight .si { color: #E6DB74 } /* Literal.String.Interpol */
[data-theme="dark"] .highlight .sx { color: #E6DB74 } /* Literal.String.Other */
[data-theme="dark"] .highlight .sr { color: #E6DB74 } /* Literal.String.Regex */
[data-theme="dark"] .highlight .s1 { color: #E6DB74 } /* Literal.String.Single */
[data-theme="dark"] .highlight .ss { color: #E6DB74 } /* Literal.String.Symbol */
[data-theme="dark"] .highlight .bp { color: #F8F8F2 } /* Name.Builtin.Pseudo */
[data-theme="dark"] .highlight .fm { color: #A6E22E } /* Name.Function.Magic */
[data-theme="dark"] .highlight .vc { color: #F8F8F2 } /* Name.Variable.Class */
[data-theme="dark"] .highlight .vg { color: #F8F8F2 } /* Name.Variable.Global */
[data-theme="dark"] .highlight .vi { color: #F8F8F2 } /* Name.Variable.Instance */
[data-theme="dark"] .highlight .vm { color: #F8F8F2 } /* Name.Variable.Magic */
[data-theme="dark"] .highlight .il { color: #AE81FF } /* Literal.Number.Integer.Long */
/* Ensure our code metrics override Pygments defaults */
.highlight pre {
white-space: pre;
margin: 0;
padding: var(--code-pad-y) 0.75rem !important;
line-height: var(--code-line-height) !important;
font-size: var(--code-font-size) !important;
font-family: 'Cascadia Mono', 'Cascadia Code', 'JetBrains Mono', 'SF Mono', Monaco, 'Consolas', monospace !important;
border: none;
}
.line-numbers { line-height: var(--code-line-height) !important; }
.line-numbers .line-number { line-height: var(--code-line-height) !important; }
/* Custom CSS from frontmatter */
/* Cursor for tools */
body[data-tool="arrow"] .main-content {
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="%23e53935" stroke-width="2"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/><circle cx="11" cy="11" r="2"/></svg>') 12 12, crosshair;
}
body[data-tool="pen"] .main-content {
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="%23e53935" stroke-width="2"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><circle cx="4" cy="20" r="2" fill="%23e53935"/></svg>') 4 20, pointer;
}
body[data-tool="eraser"] .main-content {
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="%23e53935" stroke-width="2"><path d="M20 20H7l-7-7 7-7h13v14z"/><path d="M13 13l7-7"/><path d="M13 13L9 9"/></svg>') 12 12, auto;
}
/* Color picker styles */
.tools-section-title {
font-weight: bold;
color: var(--text-secondary);
font-size: 0.65rem;
margin: 0.75rem 0 0.5rem 0;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.color-row {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 0.25rem;
margin-bottom: 0.5rem;
}
.color-swatch {
width: 18px;
height: 18px;
border: 2px solid var(--border-primary);
border-radius: 3px;
cursor: pointer;
transition: all 0.2s ease;
position: relative;
}
.color-swatch:hover {
transform: scale(1.1);
border-color: var(--text-secondary);
}
.color-swatch.selected {
border-color: var(--text-primary);
box-shadow: 0 0 0 2px var(--text-link);
}
.color-swatch.selected::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 10px;
font-weight: bold;
text-shadow: 1px 1px 1px black;
}
.color-input {
width: 24px;
height: 24px;
border: 2px solid var(--border-primary);
border-radius: 3px;
cursor: pointer;
background: none;
padding: 0;
grid-column: span 2;
justify-self: center;
}
.color-input:hover {
border-color: var(--text-secondary);
}
/* Thickness slider styles */
.thickness-row {
display: flex;
align-items: center;
gap: 0.5rem;
margin-top: 0.75rem;
}
.thickness-slider {
flex: 1;
-webkit-appearance: none;
appearance: none;
height: 4px;
background: var(--border-primary);
border-radius: 2px;
outline: none;
opacity: 0.7;
transition: opacity 0.2s;
}
.thickness-slider:hover {
opacity: 1;
}
.thickness-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 12px;
height: 12px;
background: var(--text-link);
border-radius: 50%;
cursor: pointer;
}
.thickness-slider::-moz-range-thumb {
width: 12px;
height: 12px;
background: var(--text-link);
border-radius: 50%;
cursor: pointer;
border: none;
}
.thickness-value {
font-size: 0.7rem;
color: var(--text-secondary);
min-width: 20px;
text-align: right;
}
.highlight {
background: none !important;
}
/* Loading animations */
.loading-spinner {
display: inline-block;
width: 16px;
height: 16px;
border: 2px solid var(--border-primary);
border-radius: 50%;
border-top-color: var(--text-link);
animation: spin 1s linear infinite;
margin-right: 8px;
vertical-align: middle;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.loading-skeleton {
display: inline-block;
background: var(--bg-tertiary);
background: linear-gradient(
90deg,
var(--bg-tertiary) 25%,
var(--bg-secondary) 50%,
var(--bg-tertiary) 75%
);
background-size: 200% 100%;
animation: loading-shimmer 2s ease-in-out infinite;
border-radius: 2px;
height: 1em;
width: 80px;
vertical-align: middle;
}
@keyframes loading-shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* Loading state for cell output */
.cell-output:has(.loading-spinner) {
opacity: 0.7;
background: var(--bg-secondary);
/* border-left: 3px solid var(--text-link); */
}
</style>
<script>
// --- Drag utilities ---
function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); }
function restorePosition(el, storageKey) {
try {
const raw = localStorage.getItem(storageKey);
if (!raw) return;
const pos = JSON.parse(raw);
if (typeof pos.left === 'number' && typeof pos.top === 'number') {
el.style.left = pos.left + 'px';
el.style.top = pos.top + 'px';
el.style.right = 'auto';
el.style.bottom = 'auto';
}
} catch (_) {}
}
function savePosition(el, storageKey) {
try {
const left = parseFloat(el.style.left || 'NaN');
const top = parseFloat(el.style.top || 'NaN');
if (!Number.isNaN(left) && !Number.isNaN(top)) {
localStorage.setItem(storageKey, JSON.stringify({ left, top }));
}
} catch (_) {}
}
function makeDraggable(el, storageKey, handleEl) {
let dragging = false;
let startX = 0, startY = 0; // cursor
let origLeft = 0, origTop = 0; // element
const onMove = (e) => {
if (!dragging) return;
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
const clientY = e.touches ? e.touches[0].clientY : e.clientY;
const dx = clientX - startX;
const dy = clientY - startY;
const w = el.offsetWidth;
const h = el.offsetHeight;
const maxX = window.innerWidth - w;
const maxY = window.innerHeight - h;
const newLeft = clamp(origLeft + dx, 0, maxX);
const newTop = clamp(origTop + dy, 0, maxY);
el.style.left = newLeft + 'px';
el.style.top = newTop + 'px';
el.style.right = 'auto';
el.style.bottom = 'auto';
};
const endDrag = () => {
if (!dragging) return;
dragging = false;
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', endDrag);
document.removeEventListener('touchmove', onMove);
document.removeEventListener('touchend', endDrag);
handleEl && (handleEl.style.cursor = 'grab');
savePosition(el, storageKey);
// ensure no-overlap constraint after a drag
try { layoutWidgetsStackedBottomRight(); } catch (_) {}
};
const startDrag = (e) => {
// Start from element's current on-screen rect
const elRect = el.getBoundingClientRect();
el.style.left = elRect.left + 'px';
el.style.top = elRect.top + 'px';
el.style.right = 'auto';
el.style.bottom = 'auto';
dragging = true;
startX = e.touches ? e.touches[0].clientX : e.clientX;
startY = e.touches ? e.touches[0].clientY : e.clientY;
origLeft = elRect.left;
origTop = elRect.top;
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', endDrag);
document.addEventListener('touchmove', onMove, { passive: false });
document.addEventListener('touchend', endDrag);
handleEl && (handleEl.style.cursor = 'grabbing');
e.preventDefault();
};
(handleEl || el).addEventListener('mousedown', startDrag);
(handleEl || el).addEventListener('touchstart', startDrag, { passive: false });
// Apply any saved position on init
restorePosition(el, storageKey);
}
function toggleCell(cellId) {
const codeElement = document.getElementById('code-' + cellId);
const outputElement = document.getElementById('output-' + cellId);
if (codeElement) {
codeElement.classList.toggle('collapsed');
}
if (outputElement) {
outputElement.classList.toggle('collapsed');
}
updateIndicators(cellId);
encodeToolStateToUrl();
}
function toggleCode(cellId) {
const codeElement = document.getElementById('code-' + cellId);
if (codeElement) {
codeElement.classList.toggle('collapsed');
updateIndicators(cellId);
encodeToolStateToUrl();
}
}
function toggleOutput(cellId) {
const outputElement = document.getElementById('output-' + cellId);
if (outputElement) {
outputElement.classList.toggle('collapsed');
updateIndicators(cellId);
encodeToolStateToUrl();
}
}
function toggleUvLogs(headerElement) {
const contentElement = headerElement.nextElementSibling;
if (contentElement) {
const isCollapsed = contentElement.style.display === 'none';
contentElement.style.display = isCollapsed ? 'block' : 'none';
headerElement.textContent = isCollapsed ? '▼ UV Install Logs' : '▶ UV Install Logs';
// Update the header indicator if it exists
const uvLogsDiv = headerElement.parentElement;
if (uvLogsDiv && uvLogsDiv.id && uvLogsDiv.id.startsWith('uv-logs-')) {
const cellId = uvLogsDiv.id.replace('uv-logs-', '');
const indicatorElement = document.getElementById('uv-indicator-' + cellId);
if (indicatorElement) {
indicatorElement.textContent = isCollapsed ? '▼ uv-logs' : '▶ uv-logs';
}
}
}
}
function toggleUvLogsFromHeader(cellId) {
const uvLogsElement = document.getElementById('uv-logs-' + cellId);
const indicatorElement = document.getElementById('uv-indicator-' + cellId);
if (uvLogsElement) {
const headerElement = uvLogsElement.querySelector('.uv-logs-header');
const contentElement = uvLogsElement.querySelector('.uv-logs-content');
if (contentElement && headerElement) {
const isCollapsed = contentElement.style.display === 'none';
contentElement.style.display = isCollapsed ? 'block' : 'none';
headerElement.textContent = isCollapsed ? '▼ UV Install Logs' : '▶ UV Install Logs';
if (indicatorElement) {
indicatorElement.textContent = isCollapsed ? '▼ uv-logs' : '▶ uv-logs';
}
}
}
}
function updateIndicators(cellId) {
const codeElement = document.getElementById('code-' + cellId);
const outputElement = document.getElementById('output-' + cellId);
const indicators = document.querySelector(`[onclick*="${cellId}"]`)?.closest('.cell-header')?.querySelector('.collapse-indicators');
if (indicators) {
const codeCollapsed = codeElement && codeElement.classList.contains('collapsed');
const outputCollapsed = outputElement && outputElement.classList.contains('collapsed');
const codeIcon = codeCollapsed ? '▶' : '▼';
const outputIcon = outputCollapsed ? '▶' : '▼';
const codeSpan = indicators.querySelector('[onclick*="toggleCode"]');
const outputSpan = indicators.querySelector('[onclick*="toggleOutput"]');
if (codeSpan) codeSpan.innerHTML = `${codeIcon} code`;
if (outputSpan) outputSpan.innerHTML = `${outputIcon} output`;
}
}
function toggleTheme() {
const html = document.documentElement;
const currentTheme = html.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', newTheme);
localStorage.setItem('uvnote-theme', newTheme);
updateThemeIcon();
updateUiDebug();
}
// Two panel code removed
function updateThemeIcon() {
const theme = document.documentElement.getAttribute('data-theme');
const toggle = document.querySelector('.theme-toggle');
if (toggle) {
toggle.textContent = theme === 'dark' ? 'light' : 'dark';
}
}
function setUiTheme(newUi) {
if (newUi !== 'default' && newUi !== 'none' && newUi !== 'monocolor') return;
const html = document.documentElement;
html.setAttribute('data-ui', newUi);
try { localStorage.setItem('uvnote-ui', newUi); } catch (_) {}
updateUiMenu();
updateUiDebug();
}
function updateUiMenu() {
const ui = document.documentElement.getAttribute('data-ui') || 'default';
const checks = {
default: document.getElementById('checkbox-ui-default'),
none: document.getElementById('checkbox-ui-none'),
monocolor: document.getElementById('checkbox-ui-monocolor')
};
if (checks.default) checks.default.textContent = ui === 'default' ? '☑' : '☐';
if (checks.none) checks.none.textContent = ui === 'none' ? '☑' : '☐';
if (checks.monocolor) checks.monocolor.textContent = ui === 'monocolor' ? '☑' : '☐';
}
function updateUiDebug() {
const ui = document.documentElement.getAttribute('data-ui') || 'default';
const color = document.documentElement.getAttribute('data-theme') || 'light';
const el = document.getElementById('ui-debug');
if (el) {
el.textContent = `UI: ${ui} | Color: ${color}`;
}
}
// Line selection and deep-linking
function clearLineSelections() {
try {
document.querySelectorAll('.code-line-highlight').forEach(el => { el.style.display = 'none'; });
document.querySelectorAll('.line-number.selected').forEach(el => el.classList.remove('selected'));
} catch (_) {}
}
let _selection = null; // { cellId, a, b }
function clearSelection(updateUrl) {
clearLineSelections();
_selection = null;
if (updateUrl) {
try {
const url = new URL(window.location.href);
url.searchParams.delete('cell');
url.searchParams.delete('line');
history.replaceState(null, '', url.toString());
} catch (_) {}
}
updateStateIndicator();
}
function selectCellLine(cellId, line, updateUrl) {
try {
// Ensure only one selection across the whole document
clearLineSelections();
const codeBox = document.getElementById(`code-${cellId}`);
if (!codeBox) return;
const pre = codeBox.querySelector('.highlight pre');
const overlay = document.getElementById(`line-highlight-${cellId}`);
const numbers = document.getElementById(`lines-${cellId}`);
if (!pre || !overlay) return;
// Measure line height directly from computed style
const preStyle = getComputedStyle(pre);
const padTop = parseFloat(preStyle.paddingTop || '0');
const lh = parseFloat(preStyle.lineHeight || '20');
// Position overlay
overlay.style.display = 'block';
overlay.style.height = `${lh}px`;
overlay.style.top = `${pre.offsetTop + padTop + (line - 1) * lh}px`;
// Update selected class in line numbers
if (numbers) {
numbers.querySelectorAll('.line-number').forEach(a => a.classList.remove('selected'));
const sel = numbers.querySelector(`.line-number[data-line="${line}"]`);
if (sel) sel.classList.add('selected');
}
if (updateUrl) {
const url = new URL(window.location.href);
url.searchParams.set('cell', cellId);
url.searchParams.set('line', String(line));
history.replaceState(null, '', url.toString());
}
_selection = { cellId, a: line, b: line };
updateStateIndicator();
} catch (e) { console.warn('selectCellLine error', e); }
}
function selectCellLines(cellId, startLine, endLine, updateUrl) {
try {
// normalize order
const a = Math.min(startLine, endLine);
const b = Math.max(startLine, endLine);
clearLineSelections();
const codeBox = document.getElementById(`code-${cellId}`);
if (!codeBox) return;
const pre = codeBox.querySelector('.highlight pre');
const overlay = document.getElementById(`line-highlight-${cellId}`);
const numbers = document.getElementById(`lines-${cellId}`);
if (!pre || !overlay) return;
const preStyle = getComputedStyle(pre);
const padTop = parseFloat(preStyle.paddingTop || '0');
const lh = parseFloat(preStyle.lineHeight || '20');
overlay.style.display = 'block';
overlay.style.top = `${pre.offsetTop + padTop + (a - 1) * lh}px`;
overlay.style.height = `${(b - a + 1) * lh}px`;
if (numbers) {
numbers.querySelectorAll('.line-number').forEach(a => a.classList.remove('selected'));
for (let i = a; i <= b; i++) {
const el = numbers.querySelector(`.line-number[data-line="${i}"]`);
if (el) el.classList.add('selected');
}
}
if (updateUrl) {
const url = new URL(window.location.href);
url.searchParams.set('cell', cellId);
if (a === b) url.searchParams.set('line', String(a));
else url.searchParams.set('line', `${a}-${b}`);
history.replaceState(null, '', url.toString());
}
_selection = { cellId, a, b };
updateStateIndicator();
} catch (e) { console.warn('selectCellLines error', e); }
}
// Drag-to-select support on line numbers
let _lineDrag = { active: false, cellId: null, start: 0 };
function onLineNumberMouseDown(e) {
const a = e.target.closest('.line-number');
if (!a) return;
e.preventDefault();
const cellId = a.dataset.cell;
const line = parseInt(a.dataset.line || '1', 10) || 1;
// Toggle off if this exact single line is already the only selection
const numbers = document.getElementById(`lines-${cellId}`);
if (numbers) {
const selected = Array.from(numbers.querySelectorAll('.line-number.selected')).map(n => parseInt(n.dataset.line||'0',10)).filter(Boolean);
if (selected.length === 1 && selected[0] === line) {
clearSelection(true);
return;
}
}
_lineDrag.active = true;
_lineDrag.cellId = cellId;
_lineDrag.start = line;
selectCellLines(_lineDrag.cellId, _lineDrag.start, _lineDrag.start, false);
}
function onDocMouseMove(e) {
if (!_lineDrag.active) return;
const el = document.elementFromPoint(e.clientX, e.clientY);
if (!el) return;
const a = el.closest && el.closest('.line-number');
if (!a) return;
if (a.dataset.cell !== _lineDrag.cellId) return;
const cur = parseInt(a.dataset.line || '1', 10) || 1;
selectCellLines(_lineDrag.cellId, _lineDrag.start, cur, false);
}
function onDocMouseUp(e) {
if (!_lineDrag.active) return;
const last = document.querySelector('.line-number.selected:last-of-type');
// finalize URL using the current selected range
const numbers = document.getElementById(`lines-${_lineDrag.cellId}`);
if (numbers) {
const selected = Array.from(numbers.querySelectorAll('.line-number.selected')).map(n => parseInt(n.dataset.line||'0',10)).filter(Boolean);
if (selected.length) {
const a = Math.min(...selected); const b = Math.max(...selected);
selectCellLines(_lineDrag.cellId, a, b, true);
}
}
_lineDrag.active = false; _lineDrag.cellId = null; _lineDrag.start = 0;
}
function applyLocationFromUrl() {
try {
const url = new URL(window.location.href);
const cell = url.searchParams.get('cell');
const lineParam = url.searchParams.get('line');
if (cell && lineParam) {
if (lineParam.includes('-')) {
const [a, b] = lineParam.split('-').map(x => parseInt(x, 10));
if (!Number.isNaN(a) && !Number.isNaN(b)) selectCellLines(cell, a, b, false);
} else {
const l = parseInt(lineParam, 10);
if (!Number.isNaN(l)) selectCellLine(cell, l, false);
}
}
// Apply tool parameters from URL
applyToolsFromUrl(url.searchParams);
// Cell states will be applied later in DOMContentLoaded with proper timing
const encodedCellStates = url.searchParams.get('cells');
console.log('Encoded cell states from URL:', encodedCellStates);
} catch (_) {}
}
function applyToolsFromUrl(params) {
try {
// Check if tools widget should be shown
const showTools = params.get('tools');
if (showTools === '1') {
// Mark that tool was loaded from URL
_urlLoadedTool = true;
// Apply color
const color = params.get('color');
if (color && /^[0-9a-fA-F]{6}$/.test(color)) {
setStoredArrowColor('#' + color);
}
// Apply thickness
const thickness = params.get('thickness');
if (thickness) {
const value = parseInt(thickness, 10);
if (value >= 1 && value <= 10) {
setStoredLineThickness(value);
}
}
// Don't override fadeout time for URL-loaded tools - let individual shapes decide
// Load shapes from URL
const encodedShapes = params.get('shapes');
if (encodedShapes) {
const decodedShapes = decodeShapesFromUrl(encodedShapes);
if (decodedShapes.length > 0) {
_shapes = decodedShapes;
saveShapes();
// Trigger render after overlay is initialized
setTimeout(() => {
renderOverlay();
}, 300);
}
}
// Wait for widgets to be initialized before showing tools
setTimeout(() => {
const toolsWidget = document.querySelector('.tools-widget');
const checkbox = document.getElementById('checkbox-tools');
if (toolsWidget && checkbox) {
toolsWidget.style.display = 'block';
checkbox.textContent = '☑';
localStorage.setItem('uvnote-widget-tools', 'visible');
}
// Apply active tool
const activeTool = params.get('tool');
if (activeTool && ['arrow', 'pen', 'eraser', 'spotlight'].includes(activeTool)) {
const toolBtn = Array.from(document.querySelectorAll('.tool-button')).find(btn => btn.textContent === activeTool);
if (toolBtn) {
toolBtn.click();
}
}
// Re-layout widgets after showing tools
layoutWidgetsStackedBottomRight();
}, 200);
}
} catch (_) {}
}
function captureInitialCellStates() {
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
const cellId = cell.id.replace('cell-', '');
const codeEl = document.getElementById('code-' + cellId);
const outputEl = document.getElementById('output-' + cellId);
if (codeEl || outputEl) {
const state = {};
if (codeEl) {
state.c = codeEl.classList.contains('collapsed') ? 0 : 1;
}
if (outputEl) {
state.o = outputEl.classList.contains('collapsed') ? 0 : 1;
}
_initialCellStates[cellId] = state;
}
});
console.log('Captured initial cell states:', _initialCellStates);
}
function encodeCellStatesToUrl() {
// Get all cells and their collapse states
const cells = document.querySelectorAll('.cell');
const cellStates = {};
console.log('Found cells:', cells.length);
cells.forEach(cell => {
const cellId = cell.id.replace('cell-', '');
const codeEl = document.getElementById('code-' + cellId);
const outputEl = document.getElementById('output-' + cellId);
const initialState = _initialCellStates[cellId] || {};
console.log(`Encoding cell ${cellId}:`, {
codeEl: !!codeEl,
outputEl: !!outputEl,
codeCollapsed: codeEl ? codeEl.classList.contains('collapsed') : 'N/A',
outputCollapsed: outputEl ? outputEl.classList.contains('collapsed') : 'N/A',
initialState: initialState
});
if (codeEl || outputEl) {
const state = {};
let hasChanges = false;
if (codeEl) {
const currentCodeState = codeEl.classList.contains('collapsed') ? 0 : 1;
const initialCodeState = initialState.c;
// Only encode if different from initial state
if (initialCodeState !== undefined && currentCodeState !== initialCodeState) {
state.c = currentCodeState;
hasChanges = true;
}
}
if (outputEl) {
const currentOutputState = outputEl.classList.contains('collapsed') ? 0 : 1;
const initialOutputState = initialState.o;
// Only encode if different from initial state
if (initialOutputState !== undefined && currentOutputState !== initialOutputState) {
state.o = currentOutputState;
hasChanges = true;
}
}
// Only include cell if it has changes from initial state
if (hasChanges) {
cellStates[cellId] = state;
console.log(`Added cell ${cellId}:`, state);
}
}
});
console.log('Final cell states to encode:', cellStates);
// Return empty string if no changed cells
if (Object.keys(cellStates).length === 0) return '';
// Encode as compact base64 string
const encoded = btoa(JSON.stringify(cellStates));
console.log('Encoded cell states:', encoded);
return encoded;
}
function decodeCellStatesFromUrl(encodedStates) {
if (!encodedStates) return {};
try {
return JSON.parse(atob(encodedStates));
} catch (e) {
console.error('Failed to decode cell states:', e);
return {};
}
}
function applyCellStatesFromUrl(cellStates) {
console.log('Applying cell states from URL:', cellStates);
Object.entries(cellStates).forEach(([cellId, state]) => {
const codeEl = document.getElementById('code-' + cellId);
const outputEl = document.getElementById('output-' + cellId);
console.log(`Cell ${cellId}:`, {
codeEl: !!codeEl,
outputEl: !!outputEl,
state: state
});
if (codeEl && state.c !== undefined) {
if (state.c === 0) {
codeEl.classList.add('collapsed');
console.log(`Collapsed code for cell ${cellId}`, {
hasCollapsedClass: codeEl.classList.contains('collapsed'),
computedDisplay: getComputedStyle(codeEl).display,
classList: Array.from(codeEl.classList),
elementId: codeEl.id
});
} else {
codeEl.classList.remove('collapsed');
codeEl.classList.add('expanded'); // Explicitly add expanded class
console.log(`Expanded code for cell ${cellId}`, {
hasCollapsedClass: codeEl.classList.contains('collapsed'),
hasExpandedClass: codeEl.classList.contains('expanded'),
computedDisplay: getComputedStyle(codeEl).display,
classList: Array.from(codeEl.classList),
elementId: codeEl.id
});
}
}
if (outputEl && state.o !== undefined) {
if (state.o === 0) {
outputEl.classList.add('collapsed');
console.log(`Collapsed output for cell ${cellId}`);
} else {
outputEl.classList.remove('collapsed');
console.log(`Expanded output for cell ${cellId}`);
}
}
// Update visual indicators and force style recalculation
try {
updateIndicators(cellId);
// Force browser to recalculate styles
if (codeEl) {
codeEl.offsetHeight; // Force reflow
console.log(`After indicators update - code visible: ${getComputedStyle(codeEl).display !== 'none'}`);
}
if (outputEl) {
outputEl.offsetHeight; // Force reflow
console.log(`After indicators update - output visible: ${getComputedStyle(outputEl).display !== 'none'}`);
}
} catch (e) {
console.error(`Error updating indicators for cell ${cellId}:`, e);
}
});
}
function encodeShapesToUrl() {
// Encode shapes as compact base64 string
if (_shapes.length === 0) return '';
const shapeData = _shapes.map(shape => {
const baseData = {
ct: shape.createdAt, // creation timestamp
fo: shape.fadeoutTime || getFadeoutTime() // fadeout time for this shape
};
if (shape.type === 'arrow') {
return {
...baseData,
t: 'a',
x1: Math.round(shape.x1),
y1: Math.round(shape.y1),
x2: Math.round(shape.x2),
y2: Math.round(shape.y2),
c: shape.color.substring(1), // remove #
w: shape.width
};
} else if (shape.type === 'pen') {
return {
...baseData,
t: 'p',
pts: shape.points.map(p => [Math.round(p.x), Math.round(p.y)]),
c: shape.color.substring(1),
w: shape.width
};
} else if (shape.type === 'spotlight') {
return {
...baseData,
t: 's',
x: Math.round(shape.x),
y: Math.round(shape.y),
r: Math.round(shape.radius)
};
}
}).filter(Boolean);
return btoa(JSON.stringify(shapeData));
}
function decodeShapesFromUrl(encodedShapes) {
if (!encodedShapes) return [];
try {
const shapeData = JSON.parse(atob(encodedShapes));
return shapeData.map(data => {
const base = {
createdAt: data.ct || Date.now(), // use encoded timestamp or current time
fadeoutTime: data.fo || 0, // use encoded fadeout time or 0 (never fade)
opacity: 1.0
};
if (data.t === 'a') {
return {
...base,
type: 'arrow',
x1: data.x1,
y1: data.y1,
x2: data.x2,
y2: data.y2,
color: '#' + data.c,
width: data.w
};
} else if (data.t === 'p') {
return {
...base,
type: 'pen',
points: data.pts.map(([x, y]) => ({ x, y })),
color: '#' + data.c,
width: data.w
};
} else if (data.t === 's') {
return {
...base,
type: 'spotlight',
x: data.x,
y: data.y,
radius: data.r,
color: '#000000'
};
}
}).filter(Boolean);
} catch (e) {
console.error('Failed to decode shapes:', e);
return [];
}
}
function encodeToolStateToUrl() {
// Don't update URL during initialization
if (_isInitializing) {
return window.location.href;
}
const params = new URLSearchParams(window.location.search);
// Check if tools widget is visible and has an active tool
const toolsWidget = document.querySelector('.tools-widget');
const activeTool = document.body.dataset.tool;
const hasActiveTool = activeTool && activeTool !== 'none';
const toolsWidgetVisible = toolsWidget && getComputedStyle(toolsWidget).display !== 'none';
// Always handle shapes regardless of tool state
const encodedShapes = encodeShapesToUrl();
if (encodedShapes) {
params.set('shapes', encodedShapes);
} else {
params.delete('shapes');
}
// Always preserve existing cell states from URL if present
const existingCellStates = params.get('cells');
if (existingCellStates) {
// Keep existing cell states - don't re-encode from DOM
params.set('cells', existingCellStates);
} else {
// Only encode new cell states if none exist in URL
const encodedCellStates = encodeCellStatesToUrl();
if (encodedCellStates) {
params.set('cells', encodedCellStates);
}
}
if (toolsWidgetVisible && hasActiveTool) {
// Include tool params when widget is visible AND tool is active
params.set('tools', '1');
params.set('tool', activeTool);
// Get color (without # prefix)
const color = getArrowColor();
if (color && color.startsWith('#')) {
params.set('color', color.substring(1));
}
// Get thickness
const thickness = getLineThickness();
params.set('thickness', thickness.toString());
} else {
// Remove tool state params but keep shapes
params.delete('tools');
params.delete('tool');
params.delete('color');
params.delete('thickness');
params.delete('fadeout');
}
// Update URL without reloading
const newUrl = window.location.pathname + (params.toString() ? '?' + params.toString() : '') + window.location.hash;
window.history.replaceState(null, '', newUrl);
return window.location.href;
}
function resetLayout() {
try {
// Clear all uvnote-* keys
const allKeys = Object.keys(localStorage);
const uvnoteKeys = allKeys.filter(key => key.startsWith('uvnote-'));
uvnoteKeys.forEach(k => localStorage.removeItem(k));
} catch (_) {}
// Clear any active selection and remove URL params
try { clearSelection(true); } catch(_) {}
// Reset active tool if any
try { window.setActiveTool('none'); } catch(_) {}
// Clear shapes
try { _shapes = []; saveShapes(); } catch(_) {}
// Reset URL-loaded tool flag
try { _urlLoadedTool = false; } catch(_) {}
// Reset all cells to expanded state
try {
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
const cellId = cell.id.replace('cell-', '');
const codeEl = document.getElementById('code-' + cellId);
const outputEl = document.getElementById('output-' + cellId);
if (codeEl) codeEl.classList.remove('collapsed');
if (outputEl) outputEl.classList.remove('collapsed');
updateIndicators(cellId);
});
} catch(_) {}
// Clear ALL URL parameters and reload with clean URL
try {
const cleanUrl = window.location.pathname + window.location.hash;
window.location.href = cleanUrl; // Use window.location.href instead of history.replaceState + reload
} catch (_) {
// Fallback - reload current page
location.reload();
}
}
function toggleMenu() {
const menuButton = document.querySelector('.menu-button');
if (menuButton) {
menuButton.classList.toggle('active');
}
}
function toggleWidget(widgetName) {
let widget;
let checkbox;
// Close the menu first
const menuButton = document.querySelector('.menu-button');
if (menuButton) {
menuButton.classList.remove('active');
}
switch(widgetName) {
case 'tools':
widget = document.querySelector('.tools-widget');
checkbox = document.getElementById('checkbox-tools');
break;
case 'file-explorer':
widget = document.querySelector('.file-explorer');
checkbox = document.getElementById('checkbox-file-explorer');
break;
case 'minimap':
widget = document.querySelector('.minimap');
checkbox = document.getElementById('checkbox-minimap');
break;
case 'status':
widget = document.querySelector('.status-widget');
checkbox = document.getElementById('checkbox-status');
break;
default:
return;
}
if (widget && checkbox) {
const isVisible = getComputedStyle(widget).display !== 'none';
widget.style.display = isVisible ? 'none' : 'block';
checkbox.textContent = isVisible ? '☐' : '☑';
// Save state to localStorage
try {
localStorage.setItem(`uvnote-widget-${widgetName}`, isVisible ? 'hidden' : 'visible');
} catch (_) {}
// Re-layout widgets after visibility change
try {
layoutWidgetsStackedBottomRight();
} catch (_) {}
// Update URL when tools widget visibility changes
if (widgetName === 'tools') {
encodeToolStateToUrl();
}
}
}
function initializeWidgetVisibility() {
const widgets = [
{ name: 'tools', selector: '.tools-widget' },
{ name: 'file-explorer', selector: '.file-explorer' },
{ name: 'minimap', selector: '.minimap' },
{ name: 'status', selector: '.status-widget' }
];
widgets.forEach(({ name, selector }) => {
const defaultState = name === 'status' ? 'visible' : 'hidden';
const savedState = localStorage.getItem(`uvnote-widget-${name}`) || defaultState;
const widget = document.querySelector(selector);
const checkbox = document.getElementById(`checkbox-${name}`);
if (widget && checkbox) {
const isVisible = savedState === 'visible';
widget.style.display = isVisible ? 'block' : 'none';
checkbox.textContent = isVisible ? '☑' : '☐';
}
});
}
// Close menu when clicking outside
document.addEventListener('click', function(event) {
const menuButton = document.querySelector('.menu-button');
// Don't close if clicking on a menu item (let the item handler close it)
if (menuButton && !menuButton.contains(event.target)) {
menuButton.classList.remove('active');
}
});
// Layout: stack widgets bottom-right and equalize widths
function hasCustomWidgetPositions() {
try {
return (
localStorage.getItem('uvnote-minimap-pos') ||
localStorage.getItem('uvnote-file-explorer-pos') ||
localStorage.getItem('uvnote-tools-pos')
);
} catch (_) { return false; }
}
function rectsOverlap(r1, r2) {
return !(r1.right <= r2.left || r2.right <= r1.left || r1.bottom <= r2.top || r2.bottom <= r1.top);
}
function widgetsOverlap(widgets) {
for (let i = 0; i < widgets.length; i++) {
const a = widgets[i];
const ra = a.getBoundingClientRect();
for (let j = i + 1; j < widgets.length; j++) {
const b = widgets[j];
const rb = b.getBoundingClientRect();
if (rectsOverlap(ra, rb)) return true;
}
}
return false;
}
function applyStackLayout(widgets, order) {
if (!widgets.length) return;
// Fixed equal width
const fixedWidth = 220;
widgets.forEach(el => { el.style.width = fixedWidth + 'px'; });
// Fit heights if needed to avoid overflow
const gap = 12;
const available = Math.max(0, window.innerHeight - 40 - gap * (order.length - 1));
const eachMax = Math.floor(available / order.length);
order.forEach(el => {
el.style.maxHeight = eachMax + 'px';
el.style.overflowY = 'auto';
});
// Stack bottom-up in the requested order
let bottomOffset = 20; // base gutter
order.forEach(el => {
el.style.left = 'auto';
el.style.top = 'auto';
el.style.right = '20px';
el.style.bottom = bottomOffset + 'px';
bottomOffset += el.offsetHeight + gap;
});
}
function layoutWidgetsStackedBottomRight() {
const minimap = document.querySelector('.minimap');
const fileExplorer = document.querySelector('.file-explorer');
const tools = document.querySelector('.tools-widget');
const status = document.querySelector('.status-widget');
const widgets = [minimap, fileExplorer, tools, status].filter(el => el && getComputedStyle(el).display !== 'none');
if (!widgets.length) return;
const order = [minimap, fileExplorer, tools, status].filter(Boolean).filter(el => getComputedStyle(el).display !== 'none');
// If user placed custom positions and there is no overlap, respect them.
if (hasCustomWidgetPositions() && !widgetsOverlap(widgets)) return;
applyStackLayout(widgets, order);
}
// Panel icon removed
let _minimapScrollContainer = null;
let _minimapScrollHandler = null;
function initMinimap() {
// Generate minimap content
const minimap = createMinimap();
document.body.appendChild(minimap);
// Make draggable (use title as handle)
const mTitle = minimap.querySelector('.minimap-title');
makeDraggable(minimap, 'uvnote-minimap-pos', mTitle);
// Attach scroll listener to window (two-panel removed)
_minimapScrollContainer = window;
if (_minimapScrollContainer) {
_minimapScrollHandler = () => updateMinimapActive();
if (_minimapScrollContainer === window) {
window.addEventListener('scroll', _minimapScrollHandler);
} else {
_minimapScrollContainer.addEventListener('scroll', _minimapScrollHandler);
}
}
updateMinimapActive();
}
function teardownMinimap() {
const minimap = document.querySelector('.minimap');
if (minimap && minimap.parentNode) minimap.parentNode.removeChild(minimap);
if (_minimapScrollContainer && _minimapScrollHandler) {
if (_minimapScrollContainer === window) {
window.removeEventListener('scroll', _minimapScrollHandler);
} else {
_minimapScrollContainer.removeEventListener('scroll', _minimapScrollHandler);
}
}
_minimapScrollContainer = null;
_minimapScrollHandler = null;
}
function initFileExplorer() {
// Generate file explorer content
const fileExplorer = createFileExplorer();
document.body.appendChild(fileExplorer);
}
function createMinimap() {
const minimap = document.createElement('div');
minimap.className = 'minimap';
const title = document.createElement('div');
title.className = 'minimap-title';
title.textContent = 'navigation';
minimap.appendChild(title);
// Find all headings and cells
const root = document.querySelector('.main-content') || document;
const headings = root.querySelectorAll('h1, h2, h3, h4, h5, h6');
const cells = root.querySelectorAll('.cell');
// Combine and sort by position
const items = [];
headings.forEach(heading => {
const id = heading.id || generateId(heading.textContent);
if (!heading.id) heading.id = id;
items.push({
element: heading,
type: 'heading',
level: parseInt(heading.tagName.charAt(1)),
text: heading.textContent.trim(),
id: id,
position: heading.getBoundingClientRect().top + window.scrollY
});
});
cells.forEach(cell => {
const header = cell.querySelector('.cell-header');
if (header) {
const id = cell.id || `cell-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
if (!cell.id) cell.id = id;
items.push({
element: cell,
type: 'cell',
text: header.textContent.trim(),
id: id,
position: cell.getBoundingClientRect().top + window.scrollY
});
}
});
// Sort by position
items.sort((a, b) => a.position - b.position);
// Create minimap items
items.forEach(item => {
const link = document.createElement('a');
link.className = `minimap-item ${item.type === 'heading' ? 'minimap-heading' : 'minimap-cell'}`;
if (item.type === 'heading') {
link.classList.add(`h${item.level}`);
}
link.textContent = item.text.length > 25 ? item.text.substring(0, 22) + '...' : item.text;
link.href = `#${item.id}`;
link.onclick = function(e) {
e.preventDefault();
item.element.scrollIntoView({ behavior: 'smooth', block: 'start' });
};
minimap.appendChild(link);
});
return minimap;
}
function generateId(text) {
return text.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '')
.substring(0, 20);
}
function updateMinimapActive() {
const minimapItems = document.querySelectorAll('.minimap-item');
const container = _minimapScrollContainer || window;
const containerRect = container === window ? null : container.getBoundingClientRect();
const scrollPos = (container === window ? window.scrollY : container.scrollTop) + 100; // Offset for better detection
let activeItem = null;
minimapItems.forEach(item => {
const targetId = item.getAttribute('href').substring(1);
const target = document.getElementById(targetId);
if (target) {
const rectTop = target.getBoundingClientRect().top;
const targetPos = (container === window)
? rectTop + window.scrollY
: rectTop - containerRect.top + container.scrollTop;
if (targetPos <= scrollPos) {
activeItem = item;
}
}
item.classList.remove('active');
});
if (activeItem) {
activeItem.classList.add('active');
}
}
function createFileExplorer() {
const fileExplorer = document.createElement('div');
fileExplorer.className = 'file-explorer';
const title = document.createElement('div');
title.className = 'file-explorer-title';
title.textContent = 'files';
fileExplorer.appendChild(title);
// Make draggable (use title as handle)
makeDraggable(fileExplorer, 'uvnote-file-explorer-pos', title);
// Scripts section
const scriptsSection = document.createElement('div');
scriptsSection.className = 'file-explorer-section';
const scriptsTitle = document.createElement('div');
scriptsTitle.className = 'file-explorer-section-title';
scriptsTitle.textContent = 'scripts';
scriptsSection.appendChild(scriptsTitle);
// Find all cells and list their script files (single panel)
const root = document.querySelector('.main-content') || document;
const cells = root.querySelectorAll('.cell');
cells.forEach(cell => {
const header = cell.querySelector('.cell-header');
if (header) {
const cellText = header.textContent.trim();
const cellMatch = cellText.match(/Cell: ([a-zA-Z_][a-zA-Z0-9_]*)/);
if (cellMatch) {
const cellId = cellMatch[1];
const scriptItem = document.createElement('div');
scriptItem.className = 'file-explorer-item script';
scriptItem.textContent = `${cellId}.py`;
scriptItem.onclick = function() {
cell.scrollIntoView({ behavior: 'smooth', block: 'start' });
};
scriptsSection.appendChild(scriptItem);
}
}
});
fileExplorer.appendChild(scriptsSection);
// Artifacts section
const artifactsSection = document.createElement('div');
artifactsSection.className = 'file-explorer-section';
const artifactsTitle = document.createElement('div');
artifactsTitle.className = 'file-explorer-section-title';
artifactsTitle.textContent = 'artifacts';
artifactsSection.appendChild(artifactsTitle);
// Find all artifact links (single panel)
const artifactsRoot = document.querySelector('.main-content') || document;
const artifacts = artifactsRoot.querySelectorAll('.artifact');
if (artifacts.length === 0) {
const noArtifacts = document.createElement('div');
noArtifacts.className = 'file-explorer-item artifact';
noArtifacts.textContent = '(none)';
noArtifacts.style.opacity = '0.5';
artifactsSection.appendChild(noArtifacts);
} else {
artifacts.forEach(artifact => {
const artifactItem = document.createElement('div');
artifactItem.className = 'file-explorer-item artifact';
artifactItem.textContent = artifact.textContent;
artifactItem.onclick = function() {
artifact.click();
};
artifactsSection.appendChild(artifactItem);
});
}
fileExplorer.appendChild(artifactsSection);
return fileExplorer;
}
function initStatusWidget() {
let el = document.querySelector('.status-widget');
if (!el) {
el = document.createElement('div');
el.className = 'status-widget';
el.id = 'status-widget';
el.textContent = 'ready — Esc';
document.body.appendChild(el);
}
}
// Tools widget
let _cursorX = 0;
let _cursorY = 0;
let _cursorVisible = false;
function setActiveTool(tool) {
if (!tool || tool === 'none') {
document.body.dataset.tool = 'none';
localStorage.setItem('uvnote-active-tool', 'none');
setOverlayActive(false);
_cursorVisible = false;
// Remove active class from all tool buttons when deactivating
const toolButtons = document.querySelectorAll('.tools-widget .tool-button');
toolButtons.forEach(btn => btn.classList.remove('active'));
updateStateIndicator();
encodeToolStateToUrl();
return;
}
document.body.dataset.tool = tool;
localStorage.setItem('uvnote-active-tool', tool);
setOverlayActive(true);
_cursorVisible = true;
updateStateIndicator();
encodeToolStateToUrl();
}
// Make setActiveTool globally accessible for ESC key handler
window.setActiveTool = setActiveTool;
function getArrowColor() {
const saved = localStorage.getItem('uvnote-arrow-color');
if (saved) return saved;
return '#e53935'; // Default red color
}
function setStoredArrowColor(color) {
try { localStorage.setItem('uvnote-arrow-color', color); } catch (_) {}
}
function getLineThickness() {
const saved = localStorage.getItem('uvnote-line-thickness');
if (saved) return parseInt(saved, 10);
return 6; // default thickness
}
function setStoredLineThickness(thickness) {
try { localStorage.setItem('uvnote-line-thickness', thickness); } catch (_) {}
}
function getFadeoutTime() {
const saved = localStorage.getItem('uvnote-fadeout-time');
if (saved) return parseInt(saved, 10);
return 5; // default 5 seconds
}
function setStoredFadeoutTime(seconds) {
try { localStorage.setItem('uvnote-fadeout-time', seconds); } catch (_) {}
}
function createToolsWidget() {
const tools = document.createElement('div');
tools.className = 'tools-widget';
const title = document.createElement('div');
title.className = 'tools-title';
title.textContent = 'tools';
tools.appendChild(title);
const row = document.createElement('div');
row.className = 'tools-row';
tools.appendChild(row);
// Arrow tool
const arrowBtn = document.createElement('div');
arrowBtn.className = 'tool-button';
arrowBtn.textContent = 'arrow';
arrowBtn.onclick = function() {
const isActive = arrowBtn.classList.contains('active');
if (isActive) {
arrowBtn.classList.remove('active');
setActiveTool('none');
} else {
tools.querySelectorAll('.tool-button').forEach(b => b.classList.remove('active'));
arrowBtn.classList.add('active');
setActiveTool('arrow');
}
};
row.appendChild(arrowBtn);
// Pen tool
const penBtn = document.createElement('div');
penBtn.className = 'tool-button';
penBtn.textContent = 'pen';
penBtn.onclick = function() {
const isActive = penBtn.classList.contains('active');
if (isActive) {
penBtn.classList.remove('active');
setActiveTool('none');
} else {
tools.querySelectorAll('.tool-button').forEach(b => b.classList.remove('active'));
penBtn.classList.add('active');
setActiveTool('pen');
}
};
row.appendChild(penBtn);
// Eraser tool
const eraseBtn = document.createElement('div');
eraseBtn.className = 'tool-button';
eraseBtn.textContent = 'eraser';
eraseBtn.onclick = function() {
const isActive = eraseBtn.classList.contains('active');
if (isActive) {
eraseBtn.classList.remove('active');
setActiveTool('none');
} else {
tools.querySelectorAll('.tool-button').forEach(b => b.classList.remove('active'));
eraseBtn.classList.add('active');
setActiveTool('eraser');
}
};
row.appendChild(eraseBtn);
// Spotlight tool
const spotlightBtn = document.createElement('div');
spotlightBtn.className = 'tool-button';
spotlightBtn.textContent = 'spotlight';
spotlightBtn.onclick = function() {
const isActive = spotlightBtn.classList.contains('active');
if (isActive) {
spotlightBtn.classList.remove('active');
setActiveTool('none');
} else {
tools.querySelectorAll('.tool-button').forEach(b => b.classList.remove('active'));
spotlightBtn.classList.add('active');
setActiveTool('spotlight');
}
};
row.appendChild(spotlightBtn);
// Clear all
const clearBtn = document.createElement('div');
clearBtn.className = 'tool-button';
clearBtn.textContent = 'clear';
clearBtn.onclick = function() {
_shapes = [];
saveShapes();
renderOverlay();
};
row.appendChild(clearBtn);
// We'll add the copy button at the end of the widget
// Restore active state from storage
const saved = localStorage.getItem('uvnote-active-tool') || 'none';
if (saved === 'arrow') {
arrowBtn.classList.add('active');
setActiveTool('arrow');
} else if (saved === 'pen') {
penBtn.classList.add('active');
setActiveTool('pen');
} else if (saved === 'eraser') {
eraseBtn.classList.add('active');
setActiveTool('eraser');
} else if (saved === 'spotlight') {
spotlightBtn.classList.add('active');
setActiveTool('spotlight');
}
// Color selector
const colorTitle = document.createElement('div');
colorTitle.className = 'tools-section-title';
colorTitle.textContent = 'color';
tools.appendChild(colorTitle);
const colorRow = document.createElement('div');
colorRow.className = 'tools-row color-row';
tools.appendChild(colorRow);
const swatchColors = [
// Primary colors
'#e53935', '#fb8c00', '#fdd835', '#43a047', '#1e88e5', '#8e24aa',
// Additional useful colors
'#ff5722', '#795548', '#607d8b', '#9c27b0',
// Grayscale
'#000000', '#424242', '#9e9e9e', '#ffffff'
];
const swatches = [];
swatchColors.forEach(c => {
const s = document.createElement('div');
s.className = 'color-swatch';
s.style.backgroundColor = c;
s.title = c;
s.onclick = () => {
setStoredArrowColor(c);
refreshColorUI(c);
if (_cursorVisible) renderOverlay();
encodeToolStateToUrl();
};
colorRow.appendChild(s);
swatches.push(s);
});
const colorInput = document.createElement('input');
colorInput.type = 'color';
colorInput.className = 'color-input';
colorInput.oninput = () => {
setStoredArrowColor(colorInput.value);
refreshColorUI(colorInput.value);
if (_cursorVisible) renderOverlay();
encodeToolStateToUrl();
};
colorRow.appendChild(colorInput);
function refreshColorUI(selected) {
const selectedHex = selected.startsWith('#') ? selected.toLowerCase() : rgbToHex(selected);
swatches.forEach((s, i) => {
const swatchHex = swatchColors[i].toLowerCase();
if (swatchHex === selectedHex) {
s.classList.add('selected');
} else {
s.classList.remove('selected');
}
});
try {
colorInput.value = selectedHex;
} catch (_) {}
}
function rgbToHex(rgb) {
const m = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)\)/i);
if (!m) return '#000000';
const r = parseInt(m[1]).toString(16).padStart(2, '0');
const g = parseInt(m[2]).toString(16).padStart(2, '0');
const b = parseInt(m[3]).toString(16).padStart(2, '0');
return `#${r}${g}${b}`;
}
// Restore color selection
refreshColorUI(getArrowColor());
// Thickness slider
const thicknessTitle = document.createElement('div');
thicknessTitle.className = 'tools-section-title';
thicknessTitle.textContent = 'thickness';
tools.appendChild(thicknessTitle);
const thicknessRow = document.createElement('div');
thicknessRow.className = 'thickness-row';
tools.appendChild(thicknessRow);
const thicknessSlider = document.createElement('input');
thicknessSlider.type = 'range';
thicknessSlider.className = 'thickness-slider';
thicknessSlider.min = '1';
thicknessSlider.max = '10';
thicknessSlider.value = getLineThickness();
const thicknessValue = document.createElement('span');
thicknessValue.className = 'thickness-value';
thicknessValue.textContent = thicknessSlider.value + 'px';
thicknessSlider.oninput = function() {
const value = parseInt(thicknessSlider.value, 10);
setStoredLineThickness(value);
thicknessValue.textContent = value + 'px';
if (_cursorVisible) renderOverlay();
encodeToolStateToUrl();
};
thicknessRow.appendChild(thicknessSlider);
thicknessRow.appendChild(thicknessValue);
// Fadeout time slider
const fadeoutTitle = document.createElement('div');
fadeoutTitle.className = 'tools-section-title';
fadeoutTitle.textContent = 'fadeout time';
tools.appendChild(fadeoutTitle);
const fadeoutRow = document.createElement('div');
fadeoutRow.className = 'thickness-row';
tools.appendChild(fadeoutRow);
const fadeoutSlider = document.createElement('input');
fadeoutSlider.type = 'range';
fadeoutSlider.className = 'thickness-slider';
fadeoutSlider.min = '0';
fadeoutSlider.max = '30';
fadeoutSlider.value = getFadeoutTime();
const fadeoutValue = document.createElement('span');
fadeoutValue.className = 'thickness-value';
fadeoutValue.textContent = fadeoutSlider.value === '0' ? 'never' : fadeoutSlider.value + 's';
fadeoutSlider.oninput = function() {
const value = parseInt(fadeoutSlider.value, 10);
setStoredFadeoutTime(value);
fadeoutValue.textContent = value === 0 ? 'never' : value + 's';
encodeToolStateToUrl();
};
fadeoutRow.appendChild(fadeoutSlider);
fadeoutRow.appendChild(fadeoutValue);
// Draggable behavior
makeDraggable(tools, 'uvnote-tools-pos', title);
return tools;
}
function initTools() {
const widget = createToolsWidget();
document.body.appendChild(widget);
}
function teardownTools() {
const w = document.querySelector('.tools-widget');
if (w && w.parentNode) w.parentNode.removeChild(w);
}
// --- Canvas overlay for tools ---
let _overlay = null;
let _overlayCtx = null;
let _overlayContainer = null; // window
let _overlayMode = 'single';
let _overlayResizeHandler = null;
let _overlayScrollHandler = null;
let _drawing = null; // current in-progress arrow {x1,y1,x2,y2}
let _shapes = []; // committed shapes for current mode
let _fadeTimer = null; // timer for fade animation
let _urlLoadedTool = false; // track if tool was loaded from URL
let _isInitializing = true; // prevent URL updates during initialization
let _initialCellStates = {}; // track initial cell states from page load
function getOverlayStorageKey() { return 'uvnote-shapes'; }
function loadShapes() {
try {
const raw = localStorage.getItem(getOverlayStorageKey());
_shapes = raw ? JSON.parse(raw) : [];
} catch (_) { _shapes = []; }
}
function saveShapes() {
try {
localStorage.setItem(getOverlayStorageKey(), JSON.stringify(_shapes));
// Always update URL when shapes change
encodeToolStateToUrl();
} catch (_) {}
}
function updateShapesFade() {
const now = Date.now();
let needsUpdate = false;
for (let i = _shapes.length - 1; i >= 0; i--) {
const shape = _shapes[i];
if (!shape.createdAt) continue; // Skip old shapes without timestamps
// Use individual shape's fadeout time, or global if not set
const shapesFadeoutSeconds = shape.fadeoutTime !== undefined ? shape.fadeoutTime : getFadeoutTime();
// Skip fading if fadeout is disabled for this shape
if (shapesFadeoutSeconds === 0) continue;
const fadeStartTime = Math.max(0, (shapesFadeoutSeconds - 2) * 1000); // Start fading 2s before end
const fadeEndTime = shapesFadeoutSeconds * 1000; // Fully gone after specified time
const age = now - shape.createdAt;
if (age >= fadeEndTime) {
// Remove completely faded shapes
_shapes.splice(i, 1);
needsUpdate = true;
} else if (age >= fadeStartTime) {
// Update opacity for fading shapes
const fadeProgress = (age - fadeStartTime) / (fadeEndTime - fadeStartTime);
const newOpacity = 1 - fadeProgress;
if (Math.abs(shape.opacity - newOpacity) > 0.01) {
shape.opacity = newOpacity;
needsUpdate = true;
}
}
}
if (needsUpdate) {
saveShapes();
renderOverlay();
// Update URL to remove faded shapes
encodeToolStateToUrl();
}
}
function getContentContainer() { return window; }
function updateOverlayModeAndContainer() {
_overlayContainer = window;
_overlayMode = 'single';
}
function updateOverlayBounds() {
if (!_overlay) return;
if (_overlayContainer === window) {
_overlay.style.position = 'fixed';
_overlay.style.left = '0px';
_overlay.style.top = '0px';
_overlay.width = window.innerWidth;
_overlay.height = window.innerHeight;
} else {
const rect = _overlayContainer.getBoundingClientRect();
_overlay.style.position = 'fixed';
_overlay.style.left = rect.left + 'px';
_overlay.style.top = rect.top + 'px';
_overlay.width = Math.max(0, Math.floor(rect.width));
_overlay.height = Math.max(0, Math.floor(rect.height));
}
renderOverlay();
}
function containerScrollLeft() {
return (_overlayContainer === window) ? (window.scrollX || 0) : (_overlayContainer.scrollLeft || 0);
}
function containerScrollTop() {
return (_overlayContainer === window) ? (window.scrollY || 0) : (_overlayContainer.scrollTop || 0);
}
function toCanvasCoords(clientX, clientY) {
const rect = _overlay.getBoundingClientRect();
return { x: clientX - rect.left, y: clientY - rect.top };
}
function onPointerDown(e) {
const tool = document.body.dataset.tool;
if (tool === 'arrow') {
startDrawArrow(e);
} else if (tool === 'pen') {
startDrawPen(e);
} else if (tool === 'eraser') {
eraseAt(e);
} else if (tool === 'spotlight') {
startDrawSpotlight(e);
}
}
function onPointerMove(e) {
// Update cursor position
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
_cursorX = pt.x;
_cursorY = pt.y;
if (!_drawing) {
// Just update cursor position and re-render
if (_cursorVisible) {
renderOverlay();
}
return;
}
if (_drawing.type === 'pen') {
moveDrawPen(e);
} else if (_drawing.type === 'spotlight') {
moveDrawSpotlight(e);
} else {
moveDrawArrow(e);
}
}
function onPointerEnter(e) {
_cursorVisible = document.body.dataset.tool !== 'none';
if (_cursorVisible) {
renderOverlay();
}
}
function onPointerLeave(e) {
_cursorVisible = false;
renderOverlay();
}
function onPointerUp(e) {
if (!_drawing) return;
if (_drawing.type === 'pen') {
endDrawPen();
} else if (_drawing.type === 'spotlight') {
endDrawSpotlight();
} else {
endDrawArrow();
}
}
function startDrawArrow(e) {
if (document.body.dataset.tool !== 'arrow') return;
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
_drawing = {
x1: pt.x + containerScrollLeft(),
y1: pt.y + containerScrollTop(),
x2: pt.x + containerScrollLeft(),
y2: pt.y + containerScrollTop(),
color: getArrowColor(),
width: getLineThickness()
};
renderOverlay();
e.preventDefault();
}
function moveDrawArrow(e) {
if (!_drawing) return;
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
_drawing.x2 = pt.x + containerScrollLeft();
_drawing.y2 = pt.y + containerScrollTop();
renderOverlay();
e.preventDefault();
}
function endDrawArrow() {
if (!_drawing) return;
_shapes.push({
type: 'arrow',
..._drawing,
createdAt: Date.now(),
fadeoutTime: getFadeoutTime(),
opacity: 1.0
});
_drawing = null;
saveShapes();
renderOverlay();
}
function startDrawPen(e) {
if (document.body.dataset.tool !== 'pen') return;
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
_drawing = {
type: 'pen',
points: [{
x: pt.x + containerScrollLeft(),
y: pt.y + containerScrollTop()
}],
color: getArrowColor(),
width: getLineThickness()
};
renderOverlay();
e.preventDefault();
}
function moveDrawPen(e) {
if (!_drawing || _drawing.type !== 'pen') return;
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
_drawing.points.push({
x: pt.x + containerScrollLeft(),
y: pt.y + containerScrollTop()
});
renderOverlay();
e.preventDefault();
}
function endDrawPen() {
if (!_drawing || _drawing.type !== 'pen') return;
if (_drawing.points.length > 1) {
_shapes.push({
..._drawing,
createdAt: Date.now(),
fadeoutTime: getFadeoutTime(),
opacity: 1.0
});
}
_drawing = null;
saveShapes();
renderOverlay();
}
function startDrawSpotlight(e) {
if (document.body.dataset.tool !== 'spotlight') return;
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
_drawing = {
type: 'spotlight',
x: pt.x + containerScrollLeft(),
y: pt.y + containerScrollTop(),
radius: getLineThickness() * 20, // Use thickness to control spotlight size (bigger default)
color: getArrowColor()
};
renderOverlay();
e.preventDefault();
}
function moveDrawSpotlight(e) {
if (!_drawing || _drawing.type !== 'spotlight') return;
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
const dx = pt.x + containerScrollLeft() - _drawing.x;
const dy = pt.y + containerScrollTop() - _drawing.y;
_drawing.radius = Math.max(20, Math.sqrt(dx * dx + dy * dy)); // Minimum radius of 20
renderOverlay();
e.preventDefault();
}
function endDrawSpotlight() {
if (!_drawing || _drawing.type !== 'spotlight') return;
_shapes.push({
..._drawing,
createdAt: Date.now(),
fadeoutTime: getFadeoutTime(),
opacity: 1.0
});
_drawing = null;
saveShapes();
renderOverlay();
}
function distPointToSegment(px, py, x1, y1, x2, y2) {
const dx = x2 - x1, dy = y2 - y1;
if (dx === 0 && dy === 0) return Math.hypot(px - x1, py - y1);
const t = Math.max(0, Math.min(1, ((px - x1) * dx + (py - y1) * dy) / (dx*dx + dy*dy)));
const cx = x1 + t * dx, cy = y1 + t * dy;
return Math.hypot(px - cx, py - cy);
}
function eraseAt(e) {
const pt = toCanvasCoords(e.touches ? e.touches[0].clientX : e.clientX, e.touches ? e.touches[0].clientY : e.clientY);
const x = pt.x + containerScrollLeft();
const y = pt.y + containerScrollTop();
const threshold = 10; // pixels
for (let i = _shapes.length - 1; i >= 0; i--) {
const s = _shapes[i];
if (s.type === 'arrow') {
const d = distPointToSegment(x, y, s.x1, s.y1, s.x2, s.y2);
if (d <= threshold) {
_shapes.splice(i, 1);
saveShapes();
renderOverlay();
break;
}
} else if (s.type === 'pen' && s.points) {
// Check if click is near any line segment in the pen stroke
let minDist = Infinity;
for (let j = 1; j < s.points.length; j++) {
const d = distPointToSegment(x, y, s.points[j-1].x, s.points[j-1].y, s.points[j].x, s.points[j].y);
minDist = Math.min(minDist, d);
}
if (minDist <= threshold) {
_shapes.splice(i, 1);
saveShapes();
renderOverlay();
break;
}
}
}
e.preventDefault();
}
function drawArrow(ctx, x1, y1, x2, y2, color, width, opacity = 1.0) {
// Set opacity
const oldAlpha = ctx.globalAlpha;
ctx.globalAlpha = opacity;
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.lineWidth = width;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
// Check if points are too close (initial state)
const dx = x2 - x1;
const dy = y2 - y1;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 5) {
// Draw just a small arrowhead pointing down-right when first clicked
const defaultAngle = Math.PI / 4; // 45 degrees (down-right)
const headLength = Math.min(15 + width * 1.5, 25);
const headAngle = Math.PI / 6;
// Calculate arrowhead points
const hx1 = x1 + headLength * Math.cos(defaultAngle - headAngle);
const hy1 = y1 + headLength * Math.sin(defaultAngle - headAngle);
const hx2 = x1 + headLength * Math.cos(defaultAngle + headAngle);
const hy2 = y1 + headLength * Math.sin(defaultAngle + headAngle);
// Draw arrowhead only
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(hx1, hy1);
ctx.lineTo(hx2, hy2);
ctx.closePath();
ctx.fill();
} else {
// Normal arrow drawing - head at x1,y1, tail at x2,y2
const angle = Math.atan2(y1 - y2, x1 - x2);
const headLength = Math.min(15 + width * 1.5, 25);
const headAngle = Math.PI / 6;
// Calculate where the line should end (before the arrowhead)
const lineEndX = x1 - headLength * 0.8 * Math.cos(angle);
const lineEndY = y1 - headLength * 0.8 * Math.sin(angle);
// Draw the line from tail to near the head
ctx.beginPath();
ctx.moveTo(x2, y2);
ctx.lineTo(lineEndX, lineEndY);
ctx.stroke();
// Calculate arrowhead points
const hx1 = x1 - headLength * Math.cos(angle - headAngle);
const hy1 = y1 - headLength * Math.sin(angle - headAngle);
const hx2 = x1 - headLength * Math.cos(angle + headAngle);
const hy2 = y1 - headLength * Math.sin(angle + headAngle);
// Draw arrowhead
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(hx1, hy1);
ctx.lineTo(hx2, hy2);
ctx.closePath();
ctx.fill();
}
// Restore opacity
ctx.globalAlpha = oldAlpha;
}
function drawPen(ctx, points, color, width, offX, offY, opacity = 1.0) {
if (!points || points.length < 2) return;
// Set opacity
const oldAlpha = ctx.globalAlpha;
ctx.globalAlpha = opacity;
ctx.strokeStyle = color;
ctx.lineWidth = width;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(points[0].x - offX, points[0].y - offY);
for (let i = 1; i < points.length; i++) {
ctx.lineTo(points[i].x - offX, points[i].y - offY);
}
ctx.stroke();
// Restore opacity
ctx.globalAlpha = oldAlpha;
}
function drawAllSpotlights(ctx, spotlights, offX, offY) {
if (!spotlights || spotlights.length === 0) return;
ctx.save();
// Calculate the overall opacity based on all spotlights
const maxOpacity = Math.max(...spotlights.map(s => s.opacity || 1.0));
// Fill entire canvas with dark overlay
ctx.fillStyle = `rgba(0, 0, 0, ${0.7 * maxOpacity})`;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// Cut out completely transparent holes for all spotlights
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(0, 0, 0, 1)'; // Solid black to ensure complete removal
for (const spotlight of spotlights) {
ctx.beginPath();
ctx.arc(spotlight.x - offX, spotlight.y - offY, spotlight.radius, 0, 2 * Math.PI);
ctx.fill();
}
ctx.restore();
}
function renderOverlay() {
if (!_overlay || !_overlayCtx) return;
_overlayCtx.clearRect(0, 0, _overlay.width, _overlay.height);
const offX = containerScrollLeft();
const offY = containerScrollTop();
// Draw non-spotlight shapes first
for (const s of _shapes) {
const opacity = s.opacity !== undefined ? s.opacity : 1.0;
if (s.type === 'arrow') {
drawArrow(_overlayCtx, s.x1 - offX, s.y1 - offY, s.x2 - offX, s.y2 - offY, s.color || '#f00', s.width || 2, opacity);
} else if (s.type === 'pen') {
drawPen(_overlayCtx, s.points, s.color || '#f00', s.width || 2, offX, offY, opacity);
}
}
// Draw current drawing (non-spotlight)
if (_drawing) {
if (_drawing.type === 'pen') {
drawPen(_overlayCtx, _drawing.points, _drawing.color, _drawing.width, offX, offY);
} else if (_drawing.type !== 'spotlight') {
drawArrow(_overlayCtx, _drawing.x1 - offX, _drawing.y1 - offY, _drawing.x2 - offX, _drawing.y2 - offY, _drawing.color, _drawing.width);
}
}
// Collect all spotlights (existing + current drawing + cursor preview)
const spotlights = [];
// Add existing spotlight shapes
for (const s of _shapes) {
if (s.type === 'spotlight') {
spotlights.push({
x: s.x,
y: s.y,
radius: s.radius,
opacity: s.opacity !== undefined ? s.opacity : 1.0
});
}
}
// Add current spotlight being drawn
if (_drawing && _drawing.type === 'spotlight') {
spotlights.push({
x: _drawing.x,
y: _drawing.y,
radius: _drawing.radius,
opacity: 1.0
});
}
// Add cursor preview spotlight if tool is active
if (_cursorVisible && !_drawing) {
const tool = document.body.dataset.tool;
if (tool === 'spotlight') {
const thickness = getLineThickness();
const radius = thickness * 20;
const cursorWorldX = _cursorX + containerScrollLeft();
const cursorWorldY = _cursorY + containerScrollTop();
spotlights.push({
x: cursorWorldX,
y: cursorWorldY,
radius: radius,
opacity: 0.8
});
}
}
// Draw all spotlights as a single overlay with multiple holes
drawAllSpotlights(_overlayCtx, spotlights, offX, offY);
// Draw cursor indicators for non-spotlight tools
if (_cursorVisible && !_drawing) {
const tool = document.body.dataset.tool;
const color = getArrowColor();
const thickness = getLineThickness();
if (tool !== 'spotlight') {
_overlayCtx.save();
_overlayCtx.fillStyle = color;
_overlayCtx.globalAlpha = 0.7;
if (tool === 'eraser') {
// Draw eraser indicator
_overlayCtx.strokeStyle = color;
_overlayCtx.lineWidth = 2;
_overlayCtx.beginPath();
_overlayCtx.arc(_cursorX, _cursorY, 10, 0, 2 * Math.PI);
_overlayCtx.stroke();
} else {
// Draw dot for pen/arrow
_overlayCtx.beginPath();
_overlayCtx.arc(_cursorX, _cursorY, thickness / 2, 0, 2 * Math.PI);
_overlayCtx.fill();
}
_overlayCtx.restore();
}
}
}
function setOverlayActive(active) {
if (!_overlay) initOverlay();
_overlay.style.pointerEvents = active ? 'auto' : 'none';
_overlay.style.cursor = active ? 'none' : 'auto';
// Re-render to ensure visibility aligns with content
renderOverlay();
}
function initOverlay() {
if (_overlay) return;
updateOverlayModeAndContainer();
_overlay = document.createElement('canvas');
_overlay.className = 'draw-overlay';
_overlayCtx = _overlay.getContext('2d');
document.body.appendChild(_overlay);
updateOverlayBounds();
loadShapes();
renderOverlay();
// Events
_overlay.addEventListener('mousedown', onPointerDown);
_overlay.addEventListener('mousemove', onPointerMove);
_overlay.addEventListener('mouseenter', onPointerEnter);
_overlay.addEventListener('mouseleave', onPointerLeave);
document.addEventListener('mouseup', onPointerUp);
_overlay.addEventListener('touchstart', onPointerDown, { passive: false });
_overlay.addEventListener('touchmove', onPointerMove, { passive: false });
document.addEventListener('touchend', onPointerUp);
_overlayResizeHandler = () => updateOverlayBounds();
window.addEventListener('resize', _overlayResizeHandler);
_overlayScrollHandler = () => renderOverlay();
window.addEventListener('scroll', _overlayScrollHandler);
// Start fade animation timer
_fadeTimer = setInterval(updateShapesFade, 100); // Update every 100ms for smooth fade
}
function rebindOverlayContainer() {
if (!_overlay) return;
// Remove old scroll handler
if (_overlayScrollHandler) { window.removeEventListener('scroll', _overlayScrollHandler); }
updateOverlayModeAndContainer();
updateOverlayBounds();
loadShapes();
renderOverlay();
_overlayScrollHandler = () => renderOverlay();
window.addEventListener('scroll', _overlayScrollHandler);
}
function teardownOverlay() {
if (!_overlay) return;
_overlay.removeEventListener('mousedown', onPointerDown);
_overlay.removeEventListener('mousemove', onPointerMove);
_overlay.removeEventListener('mouseenter', onPointerEnter);
_overlay.removeEventListener('mouseleave', onPointerLeave);
document.removeEventListener('mouseup', onPointerUp);
_overlay.removeEventListener('touchstart', onPointerDown);
_overlay.removeEventListener('touchmove', onPointerMove);
document.removeEventListener('touchend', onPointerUp);
if (_overlayResizeHandler) window.removeEventListener('resize', _overlayResizeHandler);
if (_overlayScrollHandler) {
if (_overlayContainer === window) {
window.removeEventListener('scroll', _overlayScrollHandler);
} else if (_overlayContainer) {
_overlayContainer.removeEventListener('scroll', _overlayScrollHandler);
}
}
if (_fadeTimer) {
clearInterval(_fadeTimer);
_fadeTimer = null;
}
if (_overlay.parentNode) _overlay.parentNode.removeChild(_overlay);
_overlay = null; _overlayCtx = null; _overlayContainer = null; _overlayResizeHandler = null; _overlayScrollHandler = null; _drawing = null;
}
function teardownFileExplorer() {
const fe = document.querySelector('.file-explorer');
if (fe && fe.parentNode) fe.parentNode.removeChild(fe);
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function runCell(cellId){
const btn=document.querySelector('.run-btn[onclick*="'+cellId+'"]');
const output=document.getElementById('output-'+cellId);
if(btn){btn.textContent='⏳ running...';btn.disabled=true;}
if(output){output.classList.add('output-stale');}
fetch('/run/'+cellId,{method:'POST'}).then(r=>r.json()).then(data=>{
if(output){
output.classList.remove('output-stale');
let html='';
if (data.stdout) {
html += '<div class="cell-stdout"><pre class="stdout-text">'
+ escapeHtml(data.stdout)
+ '</pre></div>';
}
console.log('UV Logs:', data);
if(data.stderr) {
// Split UV logs from regular stderr
const lines = data.stderr.split('\\n');
let uvLogs = [];
let regularLogs = [];
let inUvSection = true;
for (const line of lines) {
if (inUvSection) {
uvLogs.push(line);
if (line.startsWith('Installed ')) {
inUvSection = false;
}
} else {
regularLogs.push(line);
}
}
// If we never found "Installed", treat it all as regular stderr
if (inUvSection) {
html+='<div class="cell-stderr">'+escapeHtml(data.stderr)+'</div>';
} else {
const uvLogsStr = uvLogs.join('\\n');
const regularLogsStr = regularLogs.join('\\n').trim();
if (uvLogsStr) {
html+='<div class="uv-install-logs">';
html+='<div class="uv-logs-header" onclick="toggleUvLogs(this)">▶ UV Install Logs</div>';
html+='<div class="uv-logs-content" style="display: none;">'+escapeHtml(uvLogsStr)+'</div>';
html+='</div>';
}
if (regularLogsStr) {
html+='<div class="cell-stderr">'+escapeHtml(regularLogsStr)+'</div>';
}
}
}
output.innerHTML=html;
}
if(btn){btn.textContent='▶ run';btn.disabled=false;}
}).catch(e=>{
console.error('Run failed:',e);
if(output){output.classList.remove('output-stale');}
if(btn){btn.textContent='▶ run';btn.disabled=false;}
});
}
function copyCell(cellId){
// Try multiple selectors to find the code element
// Pygments generates .highlight > pre with spans, not wrapped in <code>
let codeElement = document.querySelector('#code-'+cellId+' .highlight pre');
if (!codeElement) {
codeElement = document.querySelector('#code-'+cellId+' pre');
}
if (!codeElement) {
codeElement = document.querySelector('#code-'+cellId+' code');
}
if (!codeElement) {
// Fallback to the code div itself
codeElement = document.getElementById('code-'+cellId);
}
const btn = document.querySelector('.copy-btn[onclick*="'+cellId+'"]');
if (!codeElement) {
console.error('Code element not found for cell:', cellId);
return;
}
if (!btn) {
console.error('Copy button not found for cell:', cellId);
return;
}
const codeText = codeElement.textContent;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(codeText).then(function() {
console.log('Clipboard copy successful');
btn.textContent = '✓ Copied!';
btn.classList.add('copied');
setTimeout(function() {
btn.textContent = 'Copy';
btn.classList.remove('copied');
}, 2000);
}).catch(function(err) {
console.warn('Clipboard copy failed:', err);
fallbackCopy();
});
} else {
console.log('Using fallback copy method');
fallbackCopy();
}
function fallbackCopy() {
const textarea = document.createElement('textarea');
textarea.value = codeText;
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
try {
const success = document.execCommand('copy');
console.log('Fallback copy success:', success);
btn.textContent = '✓ Copied!';
btn.classList.add('copied');
setTimeout(function() {
btn.textContent = 'Copy';
btn.classList.remove('copied');
}, 2000);
} catch (err) {
console.error('Fallback copy failed:', err);
btn.textContent = 'Copy failed';
setTimeout(function() {
btn.textContent = 'Copy';
}, 2000);
}
document.body.removeChild(textarea);
}
}
// // Live reload functionality (robust SSE handling)
// (function(){
// if (!('EventSource' in window)) {
// console.warn('SSE not supported in this browser');
// return;
// }
// let source = new EventSource('/events');
// let isOpen = false;
// source.onopen = function(){ isOpen = true; console.log('SSE connected'); };
// source.onmessage = function(e){
// const msg=(e.data||'').trim(); if(!msg) return;
// console.log('SSE message:', msg);
// if (msg==='reload' || msg==='incremental') { location.reload(); }
// // Ignore 'loading' to avoid premature reload loops
// };
// source.onerror = function(e){
// // Let EventSource auto-reconnect instead of forcing a reload
// if (isOpen) console.warn('SSE error after open, retrying...', e);
// };
// window.addEventListener('beforeunload', function(){ try{source.close();}catch(_){} });
// })();
document.addEventListener('DOMContentLoaded', function() {
// Capture initial cell states before any modifications
captureInitialCellStates();
updateThemeIcon();
updateUiMenu();
updateUiDebug();
const widgetsEnabled = (document.documentElement.getAttribute('data-widgets') || 'on') === 'on';
if (widgetsEnabled) {
initMinimap();
initFileExplorer();
initTools();
initOverlay();
initStatusWidget();
initializeWidgetVisibility();
layoutWidgetsStackedBottomRight();
window.addEventListener('resize', layoutWidgetsStackedBottomRight);
}
// Apply deep-link selection if present
applyLocationFromUrl();
updateStateIndicator();
// Apply cell states from URL immediately
const url = new URL(window.location.href);
const encodedCellStates = url.searchParams.get('cells');
if (encodedCellStates) {
console.log('Applying cell states from URL...');
const cellStates = decodeCellStatesFromUrl(encodedCellStates);
// Use requestAnimationFrame to ensure DOM is ready
requestAnimationFrame(() => {
applyCellStatesFromUrl(cellStates);
// Clear initialization flag after cell states are applied
if (typeof _isInitializing !== 'undefined') {
_isInitializing = false;
}
});
} else {
// Clear initialization flag even if no cell states
if (typeof _isInitializing !== 'undefined') {
requestAnimationFrame(() => {
_isInitializing = false;
});
}
}
// Bind drag selection on line numbers
document.addEventListener('mousedown', onLineNumberMouseDown);
document.addEventListener('mousemove', onDocMouseMove);
document.addEventListener('mouseup', onDocMouseUp);
// Add ESC key handler to exit tools
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' || e.keyCode === 27) {
const currentTool = document.body.dataset.tool;
if (currentTool && currentTool !== 'none') {
// Deactivate the current tool
window.setActiveTool('none');
}
// Also clear any active line selection
clearSelection(true);
}
});
});
function updateStateIndicator() {
try {
const el = document.getElementById('status-widget');
if (!el) return;
const tool = document.body.dataset.tool || 'none';
if (tool && tool !== 'none') {
el.textContent = `tool: ${tool} — Esc`;
return;
}
if (_selection) {
const t = _selection.a === _selection.b ? `L${_selection.a}` : `L${_selection.a}-${_selection.b}`;
el.textContent = `selected: ${t} — Esc`;
return;
}
el.textContent = 'ready — Esc';
} catch (_) {}
}
</script>
</head>
<body>
<div class="controls">
<div class="controls-buttons">
<a href="index.html" class="back-button">← back</a>
<div class="theme-toggle" onclick="toggleTheme()">light</div>
<div class="reset-toggle" onclick="resetLayout()">reset</div>
<div class="menu-button" onclick="toggleMenu()">
menu ▼
<div class="menu-dropdown">
<div class="menu-item" onclick="setUiTheme('default')">
<span class="menu-checkbox" id="checkbox-ui-default"></span> Theme: default
</div>
<div class="menu-item" onclick="setUiTheme('none')">
<span class="menu-checkbox" id="checkbox-ui-none"></span> Theme: none
</div>
<div class="menu-item" onclick="setUiTheme('monocolor')">
<span class="menu-checkbox" id="checkbox-ui-monocolor"></span> Theme: monocolor
</div>
<div class="menu-item" onclick="toggleWidget('tools')">
<span class="menu-checkbox" id="checkbox-tools"></span> Tools
</div>
<div class="menu-item" onclick="toggleWidget('file-explorer')">
<span class="menu-checkbox" id="checkbox-file-explorer"></span> File Explorer
</div>
<div class="menu-item" onclick="toggleWidget('minimap')">
<span class="menu-checkbox" id="checkbox-minimap"></span> Table of Contents
</div>
<div class="menu-item" onclick="toggleWidget('status')">
<span class="menu-checkbox" id="checkbox-status"></span> Status Indicator
</div>
</div>
</div>
</div>
</div>
<div class="system-info">
<div class="system-info-header">Generated on:</div>
<div class="system-info-content">
Linux x86_64 | Linux-5.10.244-240.970.amzn2.x86_64-x86_64-with-glibc2.35
</div>
</div>
<div class="main-content">
<h1>PyTorch Native - Causal Conv1D</h1>
<h2>GPU Info</h2>
<div class="cell" id="cell-nv">
<div class="cell-header">
<span class="collapse-indicators">
<span onclick="toggleCode('nv')" style="cursor: pointer;">▼ code</span>
<span onclick="toggleOutput('nv')" style="cursor: pointer;">▼ output</span>
<span id="uv-indicator-nv" style="cursor: default; opacity: 0.3;">▶ uv-logs</span>
</span> |
Cell: nv | 0.25s
| <button class="run-btn" onclick="runCell('nv')">▶ run</button>
<button class="copy-btn" onclick="copyCell('nv')">Copy</button>
<a href="cells/nv.py" target="_blank" class="raw-btn">Raw</a>
<a href="https://github.com/huggingface/kernels-uvnotes/blob/main/causal_conv1d/impls/torch_causal_conv1d.md" target="_blank" class="github-btn">GitHub</a>
</div>
<div id="code-nv" class="cell-code" data-lines="2">
<div class="code-wrap">
<div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">subprocess</span>
<span class="nb">print</span><span class="p">(</span><span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">&quot;nvidia-smi&quot;</span><span class="p">],</span> <span class="n">capture_output</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="o">.</span><span class="n">stdout</span><span class="p">)</span>
</pre></div>
<div class="code-line-highlight" id="line-highlight-nv"></div>
</div>
</div>
<div id="output-nv" class="cell-output">
<div class="cell-stdout"><pre class="stdout-text">Wed Oct 29 04:14:16 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.195.03 Driver Version: 570.195.03 CUDA Version: 12.8 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA L40S On | 00000000:4D:00.0 Off | 0 |
| N/A 35C P0 121W / 350W | 0MiB / 46068MiB | 100% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
</pre></div>
</div>
</div>
<h2>Causal Conv1D Benchmark (PyTorch Native)</h2>
<div class="cell" id="cell-benchmark">
<div class="cell-header">
<span class="collapse-indicators">
<span onclick="toggleCode('benchmark')" style="cursor: pointer;">▼ code</span>
<span onclick="toggleOutput('benchmark')" style="cursor: pointer;">▼ output</span>
<span id="uv-indicator-benchmark" onclick="toggleUvLogsFromHeader('benchmark')" style="cursor: pointer;">▶ uv-logs</span>
</span> |
Cell: benchmark | 7.31s
| <button class="run-btn" onclick="runCell('benchmark')">▶ run</button>
<button class="copy-btn" onclick="copyCell('benchmark')">Copy</button>
<a href="cells/benchmark.py" target="_blank" class="raw-btn">Raw</a>
<a href="https://github.com/huggingface/kernels-uvnotes/blob/main/causal_conv1d/impls/torch_causal_conv1d.md" target="_blank" class="github-btn">GitHub</a>
</div>
<div id="code-benchmark" class="cell-code" data-lines="40">
<div class="code-wrap">
<div class="highlight"><pre><span></span><span class="c1"># /// script</span>
<span class="c1"># requires-python = &quot;&gt;=3.10&quot;</span>
<span class="c1"># dependencies = [</span>
<span class="c1"># &quot;numpy&quot;,</span>
<span class="c1"># &quot;torch==2.8.0&quot;,</span>
<span class="c1"># &quot;kernels-benchmark-tools&quot;,</span>
<span class="c1"># ]</span>
<span class="c1">#</span>
<span class="c1"># [tool.uv.sources]</span>
<span class="c1"># kernels-benchmark-tools = { path = &quot;../../../../../tools&quot;, editable = true }</span>
<span class="c1"># ///</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">torch</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">torch.nn.functional</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">F</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">kernels_benchmark_tools</span><span class="w"> </span><span class="kn">import</span> <span class="n">KernelTypeEnum</span><span class="p">,</span> <span class="n">run_benchmark</span>
<span class="k">def</span><span class="w"> </span><span class="nf">torch_causal_conv1d</span><span class="p">(</span><span class="n">input_tensor</span><span class="p">,</span> <span class="n">weight</span><span class="p">,</span> <span class="n">bias</span><span class="p">):</span>
<span class="c1"># Convert to weight dtype for computation</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">input_tensor</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="n">weight</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span>
<span class="n">dim</span> <span class="o">=</span> <span class="n">weight</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">width</span> <span class="o">=</span> <span class="n">weight</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="n">seqlen</span> <span class="o">=</span> <span class="n">input_tensor</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="c1"># Depthwise causal conv1d using PyTorch</span>
<span class="n">out</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">conv1d</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">weight</span><span class="o">.</span><span class="n">unsqueeze</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">bias</span><span class="p">,</span> <span class="n">padding</span><span class="o">=</span><span class="n">width</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">groups</span><span class="o">=</span><span class="n">dim</span><span class="p">)</span>
<span class="c1"># Truncate to original sequence length</span>
<span class="n">out</span> <span class="o">=</span> <span class="n">out</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="p">:</span><span class="n">seqlen</span><span class="p">]</span>
<span class="c1"># Convert back to original dtype</span>
<span class="k">return</span> <span class="n">out</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="n">input_tensor</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span>
<span class="n">run_benchmark</span><span class="p">(</span>
<span class="n">kernel_type</span><span class="o">=</span><span class="n">KernelTypeEnum</span><span class="o">.</span><span class="n">CAUSAL_CONV1D</span><span class="p">,</span>
<span class="n">impl_name</span><span class="o">=</span><span class="s2">&quot;torch_eager&quot;</span><span class="p">,</span>
<span class="n">impl_tags</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;family&quot;</span><span class="p">:</span> <span class="s2">&quot;pytorch&quot;</span><span class="p">,</span> <span class="s2">&quot;backend&quot;</span><span class="p">:</span> <span class="s2">&quot;eager&quot;</span><span class="p">},</span>
<span class="n">impl_func</span><span class="o">=</span><span class="n">torch_causal_conv1d</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
<div class="code-line-highlight" id="line-highlight-benchmark"></div>
</div>
</div>
<div id="output-benchmark" class="cell-output">
<div class="cell-stdout"><pre class="stdout-text">Running causal_conv1d benchmark on cuda with 24 workloads.
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D64_S128_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 467.679us 2403.78% 467.679us 467.679us 1
torch_eager 10.81% 233.756us 99.62% 2.155ms 2.155ms 0.000us 0.00% 21.792us 21.792us 1
aten::to 0.55% 11.919us 78.64% 1.701ms 283.539us 0.000us 0.00% 14.304us 2.384us 6
aten::_to_copy 2.04% 44.223us 78.09% 1.689ms 281.553us 0.000us 0.00% 14.304us 2.384us 6
aten::copy_ 3.07% 66.360us 73.27% 1.585ms 264.169us 11.968us 61.51% 14.304us 2.384us 6
aten::conv1d 0.40% 8.600us 7.96% 172.134us 57.378us 0.000us 0.00% 7.488us 2.496us 3
aten::convolution 0.76% 16.533us 7.56% 163.534us 54.511us 0.000us 0.00% 7.488us 2.496us 3
aten::_convolution 1.65% 35.660us 6.80% 147.001us 49.000us 0.000us 0.00% 7.488us 2.496us 3
aten::_conv_depthwise2d 1.78% 38.520us 4.15% 89.871us 29.957us 7.488us 38.49% 7.488us 2.496us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 7.488us 38.49% 7.488us 2.496us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 6.272us 32.24% 6.272us 2.091us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.696us 29.28% 5.696us 1.899us 3
Activity Buffer Request 67.06% 1.451ms 67.06% 1.451ms 1.451ms 2.336us 12.01% 2.336us 2.336us 1
aten::empty_strided 2.78% 60.080us 2.78% 60.080us 10.013us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 4.39% 95.004us 4.39% 95.004us 10.556us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 1.49% 32.209us 1.86% 40.319us 4.480us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.61% 13.180us 0.61% 13.180us 0.879us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.57% 12.310us 0.57% 12.310us 4.103us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.56% 12.130us 0.56% 12.130us 4.043us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.40% 8.601us 0.48% 10.281us 3.427us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.163ms
Self CUDA time total: 19.456us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D64_S128_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 345.183us 1768.26% 345.183us 345.183us 1
torch_eager 6.79% 129.712us 99.69% 1.904ms 1.904ms 0.000us 0.00% 21.633us 21.633us 1
aten::to 0.35% 6.752us 84.92% 1.622ms 270.359us 0.000us 0.00% 13.697us 2.283us 6
aten::_to_copy 1.29% 24.629us 84.57% 1.615ms 269.234us 0.000us 0.00% 13.697us 2.283us 6
aten::copy_ 2.57% 49.181us 81.04% 1.548ms 258.016us 11.585us 59.35% 13.697us 2.283us 6
aten::conv1d 0.34% 6.520us 6.51% 124.283us 41.428us 0.000us 0.00% 7.936us 2.645us 3
aten::convolution 0.52% 9.860us 6.16% 117.763us 39.254us 0.000us 0.00% 7.936us 2.645us 3
aten::_convolution 1.28% 24.503us 5.65% 107.903us 35.968us 0.000us 0.00% 7.936us 2.645us 3
aten::_conv_depthwise2d 1.17% 22.379us 3.49% 66.751us 22.250us 7.936us 40.65% 7.936us 2.645us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 7.936us 40.65% 7.936us 2.645us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 6.080us 31.15% 6.080us 2.027us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.505us 28.20% 5.505us 1.835us 3
Activity Buffer Request 75.86% 1.449ms 75.86% 1.449ms 1.449ms 2.112us 10.82% 2.112us 2.112us 1
aten::empty_strided 2.23% 42.682us 2.23% 42.682us 7.114us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 3.91% 74.643us 3.91% 74.643us 8.294us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.96% 18.249us 1.26% 24.119us 2.680us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.50% 9.600us 0.50% 9.600us 0.640us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.51% 9.750us 0.51% 9.750us 3.250us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.51% 9.801us 0.51% 9.801us 3.267us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.31% 5.930us 0.39% 7.450us 2.483us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 1.910ms
Self CUDA time total: 19.521us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D64_S512_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 350.236us 1887.05% 350.236us 350.236us 1
torch_eager 6.95% 131.684us 99.72% 1.889ms 1.889ms 0.000us 0.00% 20.481us 20.481us 1
aten::to 0.32% 5.979us 84.80% 1.606ms 267.646us 0.000us 0.00% 13.570us 2.262us 6
aten::_to_copy 1.26% 23.830us 84.48% 1.600ms 266.649us 0.000us 0.00% 13.570us 2.262us 6
aten::copy_ 3.12% 59.102us 81.66% 1.546ms 257.734us 11.649us 62.76% 13.570us 2.262us 6
aten::conv1d 0.33% 6.189us 6.49% 122.822us 40.941us 0.000us 0.00% 6.911us 2.304us 3
aten::convolution 0.53% 10.011us 6.16% 116.633us 38.878us 0.000us 0.00% 6.911us 2.304us 3
aten::_convolution 1.28% 24.209us 5.63% 106.622us 35.541us 0.000us 0.00% 6.911us 2.304us 3
aten::_conv_depthwise2d 1.23% 23.239us 3.44% 65.172us 21.724us 6.911us 37.24% 6.911us 2.304us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 6.911us 37.24% 6.911us 2.304us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 5.921us 31.90% 5.921us 1.974us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.728us 30.86% 5.728us 1.909us 3
Activity Buffer Request 75.86% 1.437ms 75.86% 1.437ms 1.437ms 1.921us 10.35% 1.921us 1.921us 1
aten::empty_strided 1.57% 29.661us 1.57% 29.661us 4.944us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 3.93% 74.492us 3.93% 74.492us 8.277us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.98% 18.470us 1.28% 24.221us 2.691us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.50% 9.492us 0.50% 9.492us 0.633us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.52% 9.761us 0.52% 9.761us 3.254us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.44% 8.371us 0.44% 8.371us 2.790us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.31% 5.870us 0.39% 7.390us 2.463us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 1.894ms
Self CUDA time total: 18.560us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D64_S512_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 349.473us 1781.39% 349.473us 349.473us 1
torch_eager 6.11% 131.525us 99.75% 2.146ms 2.146ms 0.000us 0.00% 21.795us 21.795us 1
aten::to 0.31% 6.681us 86.66% 1.864ms 310.738us 0.000us 0.00% 14.148us 2.358us 6
aten::_to_copy 1.14% 24.510us 86.35% 1.858ms 309.625us 0.000us 0.00% 14.148us 2.358us 6
aten::copy_ 2.35% 50.532us 83.71% 1.801ms 300.153us 11.971us 61.02% 14.148us 2.358us 6
aten::conv1d 0.29% 6.159us 5.69% 122.482us 40.827us 0.000us 0.00% 7.647us 2.549us 3
aten::convolution 0.45% 9.650us 5.41% 116.323us 38.774us 0.000us 0.00% 7.647us 2.549us 3
aten::_convolution 1.16% 25.049us 4.96% 106.673us 35.558us 0.000us 0.00% 7.647us 2.549us 3
aten::_conv_depthwise2d 1.06% 22.843us 3.03% 65.182us 21.727us 7.647us 38.98% 7.647us 2.549us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 7.647us 38.98% 7.647us 2.549us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 6.211us 31.66% 6.211us 2.070us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.760us 29.36% 5.760us 1.920us 3
Activity Buffer Request 68.59% 1.476ms 68.59% 1.476ms 1.476ms 2.177us 11.10% 2.177us 2.177us 1
aten::empty_strided 1.50% 32.320us 1.50% 32.320us 5.387us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 13.84% 297.685us 13.84% 297.685us 33.076us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.81% 17.433us 1.07% 22.952us 2.550us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.42% 9.029us 0.42% 9.029us 0.602us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.47% 10.100us 0.47% 10.100us 3.367us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.44% 9.389us 0.44% 9.389us 3.130us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.30% 6.350us 0.36% 7.690us 2.563us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.151ms
Self CUDA time total: 19.618us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D64_S2048_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 348.958us 1429.22% 348.958us 348.958us 1
torch_eager 6.64% 139.433us 99.75% 2.094ms 2.094ms 0.000us 0.00% 26.656us 26.656us 1
aten::to 0.30% 6.349us 85.85% 1.803ms 300.420us 0.000us 0.00% 15.136us 2.523us 6
aten::_to_copy 1.17% 24.664us 85.55% 1.796ms 299.362us 0.000us 0.00% 15.136us 2.523us 6
aten::copy_ 2.46% 51.670us 82.81% 1.739ms 289.779us 12.896us 52.82% 15.136us 2.523us 6
aten::conv1d 0.30% 6.230us 5.89% 123.663us 41.221us 0.000us 0.00% 11.520us 3.840us 3
aten::convolution 0.49% 10.211us 5.59% 117.433us 39.144us 0.000us 0.00% 11.520us 3.840us 3
aten::_convolution 1.21% 25.350us 5.11% 107.222us 35.741us 0.000us 0.00% 11.520us 3.840us 3
aten::_conv_depthwise2d 1.07% 22.551us 3.09% 64.932us 21.644us 11.520us 47.18% 11.520us 3.840us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 11.520us 47.18% 11.520us 3.840us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 6.592us 27.00% 6.592us 2.197us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 6.304us 25.82% 6.304us 2.101us 3
Activity Buffer Request 67.91% 1.426ms 67.91% 1.426ms 1.426ms 2.240us 9.17% 2.240us 2.240us 1
aten::empty_strided 1.56% 32.829us 1.56% 32.829us 5.472us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 13.56% 284.686us 13.56% 284.686us 31.632us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.89% 18.631us 1.15% 24.041us 2.671us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.44% 9.180us 0.44% 9.180us 0.612us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.47% 9.871us 0.47% 9.871us 3.290us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.43% 8.930us 0.43% 8.930us 2.977us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.31% 6.480us 0.38% 7.900us 2.633us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.100ms
Self CUDA time total: 24.416us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D64_S2048_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 350.300us 1353.19% 350.300us 350.300us 1
torch_eager 6.16% 129.673us 99.74% 2.100ms 2.100ms 0.000us 0.00% 28.127us 28.127us 1
aten::to 0.30% 6.400us 86.28% 1.817ms 302.813us 0.000us 0.00% 15.135us 2.522us 6
aten::_to_copy 1.17% 24.572us 85.97% 1.810ms 301.746us 0.000us 0.00% 15.135us 2.522us 6
aten::copy_ 2.32% 48.831us 83.30% 1.754ms 292.358us 12.895us 49.81% 15.135us 2.522us 6
aten::conv1d 0.30% 6.370us 5.91% 124.553us 41.518us 0.000us 0.00% 12.992us 4.331us 3
aten::convolution 0.48% 10.021us 5.61% 118.183us 39.394us 0.000us 0.00% 12.992us 4.331us 3
aten::_convolution 1.13% 23.790us 5.14% 108.162us 36.054us 0.000us 0.00% 12.992us 4.331us 3
aten::_conv_depthwise2d 1.15% 24.221us 3.16% 66.582us 22.194us 12.992us 50.19% 12.992us 4.331us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 12.992us 50.19% 12.992us 4.331us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 6.592us 25.46% 6.592us 2.197us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 6.303us 24.35% 6.303us 2.101us 3
Activity Buffer Request 68.95% 1.452ms 68.95% 1.452ms 1.452ms 2.240us 8.65% 2.240us 2.240us 1
aten::empty_strided 1.51% 31.759us 1.51% 31.759us 5.293us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 13.13% 276.435us 13.13% 276.435us 30.715us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.91% 19.219us 1.21% 25.491us 2.832us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.48% 10.094us 0.48% 10.094us 0.673us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.47% 9.932us 0.47% 9.932us 3.311us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.44% 9.289us 0.44% 9.289us 3.096us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.33% 6.860us 0.40% 8.350us 2.783us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.106ms
Self CUDA time total: 25.887us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D2048_S128_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 344.670us 904.34% 344.670us 344.670us 1
torch_eager 6.27% 130.413us 99.73% 2.076ms 2.076ms 0.000us 0.00% 40.673us 40.673us 1
aten::conv1d 0.29% 6.011us 5.81% 120.902us 40.301us 0.000us 0.00% 22.369us 7.456us 3
aten::convolution 0.46% 9.579us 5.52% 114.891us 38.297us 0.000us 0.00% 22.369us 7.456us 3
aten::_convolution 1.17% 24.271us 5.06% 105.312us 35.104us 0.000us 0.00% 22.369us 7.456us 3
aten::_conv_depthwise2d 1.07% 22.281us 3.10% 64.540us 21.513us 22.369us 58.69% 22.369us 7.456us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 22.369us 58.69% 22.369us 7.456us 3
aten::to 0.30% 6.240us 86.29% 1.796ms 299.368us 0.000us 0.00% 18.304us 3.051us 6
aten::_to_copy 1.19% 24.702us 86.00% 1.790ms 298.328us 0.000us 0.00% 18.304us 3.051us 6
aten::copy_ 2.32% 48.271us 83.37% 1.735ms 289.226us 15.744us 41.31% 18.304us 3.051us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 8.352us 21.91% 8.352us 2.784us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 7.392us 19.39% 7.392us 2.464us 3
Activity Buffer Request 69.09% 1.438ms 69.09% 1.438ms 1.438ms 2.560us 6.72% 2.560us 2.560us 1
aten::empty_strided 1.44% 29.909us 1.44% 29.909us 4.985us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 13.10% 272.705us 13.10% 272.705us 30.301us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.90% 18.821us 1.17% 24.281us 2.698us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.43% 8.910us 0.43% 8.910us 0.594us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.47% 9.769us 0.47% 9.769us 3.256us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.42% 8.830us 0.42% 8.830us 2.943us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.30% 6.180us 0.36% 7.570us 2.523us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.081ms
Self CUDA time total: 38.113us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D2048_S128_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 339.324us 829.06% 339.324us 339.324us 1
torch_eager 6.37% 130.712us 99.71% 2.046ms 2.046ms 0.000us 0.00% 43.521us 43.521us 1
aten::conv1d 0.29% 5.880us 5.94% 121.953us 40.651us 0.000us 0.00% 25.216us 8.405us 3
aten::convolution 0.47% 9.711us 5.66% 116.073us 38.691us 0.000us 0.00% 25.216us 8.405us 3
aten::_convolution 1.26% 25.911us 5.18% 106.362us 35.454us 0.000us 0.00% 25.216us 8.405us 3
aten::_conv_depthwise2d 1.09% 22.379us 3.16% 64.832us 21.611us 25.216us 61.61% 25.216us 8.405us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 25.216us 61.61% 25.216us 8.405us 3
aten::to 0.29% 5.930us 86.07% 1.766ms 294.313us 0.000us 0.00% 18.305us 3.051us 6
aten::_to_copy 1.14% 23.292us 85.79% 1.760ms 293.325us 0.000us 0.00% 18.305us 3.051us 6
aten::copy_ 2.44% 50.149us 83.18% 1.707ms 284.430us 15.713us 38.39% 18.305us 3.051us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 8.320us 20.33% 8.320us 2.773us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 7.393us 18.06% 7.393us 2.464us 3
Activity Buffer Request 69.04% 1.416ms 69.04% 1.416ms 1.416ms 2.592us 6.33% 2.592us 2.592us 1
aten::empty_strided 1.47% 30.081us 1.47% 30.081us 5.013us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 12.82% 263.078us 12.82% 263.078us 29.231us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.84% 17.161us 1.08% 22.249us 2.472us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.43% 8.738us 0.43% 8.738us 0.583us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.52% 10.621us 0.52% 10.621us 3.540us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.43% 8.801us 0.43% 8.801us 2.934us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.28% 5.670us 0.35% 7.160us 2.387us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.052ms
Self CUDA time total: 40.929us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D2048_S512_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 346.587us 339.00% 346.587us 346.587us 1
torch_eager 6.07% 126.382us 99.75% 2.075ms 2.075ms 0.000us 0.00% 108.223us 108.223us 1
aten::conv1d 0.27% 5.689us 5.84% 121.563us 40.521us 0.000us 0.00% 70.111us 23.370us 3
aten::convolution 0.45% 9.432us 5.57% 115.874us 38.625us 0.000us 0.00% 70.111us 23.370us 3
aten::_convolution 1.15% 23.992us 5.12% 106.442us 35.481us 0.000us 0.00% 70.111us 23.370us 3
aten::_conv_depthwise2d 1.13% 23.510us 3.19% 66.451us 22.150us 70.111us 68.58% 70.111us 23.370us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 70.111us 68.58% 70.111us 23.370us 3
aten::to 0.33% 6.762us 86.49% 1.799ms 299.916us 0.000us 0.00% 38.112us 6.352us 6
aten::_to_copy 1.17% 24.419us 86.17% 1.793ms 298.789us 0.000us 0.00% 38.112us 6.352us 6
aten::copy_ 2.24% 46.671us 83.54% 1.738ms 289.665us 32.128us 31.42% 38.112us 6.352us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 17.568us 17.18% 17.568us 5.856us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 14.560us 14.24% 14.560us 4.853us 3
Activity Buffer Request 69.85% 1.453ms 69.85% 1.453ms 1.453ms 5.984us 5.85% 5.984us 5.984us 1
aten::empty_strided 1.46% 30.330us 1.46% 30.330us 5.055us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 12.58% 261.816us 12.58% 261.816us 29.091us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.87% 18.161us 1.14% 23.661us 2.629us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.44% 9.119us 0.44% 9.119us 0.608us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.48% 9.940us 0.48% 9.940us 3.313us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.45% 9.280us 0.45% 9.280us 3.093us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.27% 5.680us 0.34% 7.119us 2.373us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.081ms
Self CUDA time total: 102.239us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D2048_S512_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 340.895us 303.69% 340.895us 340.895us 1
torch_eager 5.96% 121.922us 99.72% 2.040ms 2.040ms 0.000us 0.00% 118.204us 118.204us 1
aten::conv1d 0.29% 5.851us 5.96% 121.923us 40.641us 0.000us 0.00% 80.190us 26.730us 3
aten::convolution 0.47% 9.659us 5.67% 116.072us 38.691us 0.000us 0.00% 80.190us 26.730us 3
aten::_convolution 1.15% 23.552us 5.20% 106.413us 35.471us 0.000us 0.00% 80.190us 26.730us 3
aten::_conv_depthwise2d 1.14% 23.240us 3.13% 64.041us 21.347us 80.190us 71.44% 80.190us 26.730us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 80.190us 71.44% 80.190us 26.730us 3
aten::to 0.30% 6.190us 86.45% 1.769ms 294.821us 0.000us 0.00% 38.014us 6.336us 6
aten::_to_copy 1.15% 23.531us 86.15% 1.763ms 293.790us 0.000us 0.00% 38.014us 6.336us 6
aten::copy_ 2.44% 49.841us 83.49% 1.708ms 284.726us 32.062us 28.56% 38.014us 6.336us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 17.503us 15.59% 17.503us 5.834us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 14.559us 12.97% 14.559us 4.853us 3
Activity Buffer Request 69.71% 1.426ms 69.71% 1.426ms 1.426ms 5.952us 5.30% 5.952us 5.952us 1
aten::empty_strided 1.51% 30.850us 1.51% 30.850us 5.142us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 12.43% 254.276us 12.43% 254.276us 28.253us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.92% 18.780us 1.20% 24.600us 2.733us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.47% 9.541us 0.47% 9.541us 0.636us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.49% 10.090us 0.49% 10.090us 3.363us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.42% 8.680us 0.42% 8.680us 2.893us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.34% 6.870us 0.41% 8.300us 2.767us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.046ms
Self CUDA time total: 112.252us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D2048_S2048_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 6.19% 128.263us 98.22% 2.035ms 2.035ms 0.000us 0.00% 432.800us 432.800us 1
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 422.880us 107.61% 422.880us 422.880us 1
aten::conv1d 0.31% 6.390us 5.89% 122.123us 40.708us 0.000us 0.00% 250.976us 83.659us 3
aten::convolution 0.46% 9.601us 5.59% 115.733us 38.578us 0.000us 0.00% 250.976us 83.659us 3
aten::_convolution 1.21% 25.079us 5.12% 106.132us 35.377us 0.000us 0.00% 250.976us 83.659us 3
aten::_conv_depthwise2d 1.14% 23.570us 3.11% 64.391us 21.464us 250.976us 63.87% 250.976us 83.659us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 250.976us 63.87% 250.976us 83.659us 3
aten::to 0.32% 6.560us 84.78% 1.757ms 292.786us 0.000us 0.00% 181.824us 30.304us 6
aten::_to_copy 1.18% 24.419us 84.47% 1.750ms 291.693us 0.000us 0.00% 181.824us 30.304us 6
aten::copy_ 2.44% 50.653us 81.84% 1.696ms 282.633us 141.984us 36.13% 181.824us 30.304us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 102.336us 26.04% 102.336us 34.112us 3
Activity Buffer Request 68.54% 1.420ms 68.54% 1.420ms 1.420ms 39.840us 10.14% 39.840us 39.840us 1
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 39.648us 10.09% 39.648us 13.216us 3
aten::empty_strided 1.44% 29.940us 1.44% 29.940us 4.990us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 11.90% 246.595us 11.90% 246.595us 27.399us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.85% 17.582us 1.11% 22.961us 2.551us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.44% 9.098us 0.44% 9.098us 0.607us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.47% 9.750us 0.47% 9.750us 3.250us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.45% 9.420us 0.45% 9.420us 3.140us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.32% 6.712us 0.39% 8.162us 2.721us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.072ms
Self CUDA time total: 392.960us
======================================================================
PROFILE TRACE: torch_eager | cuda_B2_D2048_S2048_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 5.97% 128.995us 95.86% 2.073ms 2.073ms 0.000us 0.00% 487.835us 487.835us 1
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 481.723us 107.54% 481.723us 481.723us 1
aten::conv1d 0.29% 6.320us 5.75% 124.323us 41.441us 0.000us 0.00% 300.092us 100.031us 3
aten::convolution 0.47% 10.180us 5.46% 118.003us 39.334us 0.000us 0.00% 300.092us 100.031us 3
aten::_convolution 1.09% 23.583us 4.99% 107.823us 35.941us 0.000us 0.00% 300.092us 100.031us 3
aten::_conv_depthwise2d 1.05% 22.771us 3.07% 66.451us 22.150us 300.092us 67.00% 300.092us 100.031us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 300.092us 67.00% 300.092us 100.031us 3
aten::to 0.32% 6.900us 82.82% 1.791ms 298.496us 0.000us 0.00% 187.743us 31.290us 6
aten::_to_copy 1.13% 24.450us 82.50% 1.784ms 297.346us 0.000us 0.00% 187.743us 31.290us 6
aten::copy_ 2.37% 51.149us 79.94% 1.729ms 288.123us 147.839us 33.00% 187.743us 31.290us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 107.872us 24.08% 107.872us 35.957us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 39.967us 8.92% 39.967us 13.322us 3
Activity Buffer Request 67.34% 1.456ms 67.34% 1.456ms 1.456ms 39.904us 8.91% 39.904us 39.904us 1
aten::empty_strided 1.43% 30.891us 1.43% 30.891us 5.149us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 11.33% 245.015us 11.33% 245.015us 27.224us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.88% 18.930us 1.15% 24.910us 2.768us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.45% 9.739us 0.45% 9.739us 0.649us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.47% 10.080us 0.47% 10.080us 3.360us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.46% 9.870us 0.46% 9.870us 3.290us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.30% 6.460us 0.36% 7.889us 2.630us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.162ms
Self CUDA time total: 447.931us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D64_S128_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 336.383us 1799.90% 336.383us 336.383us 1
torch_eager 14.70% 125.222us 99.35% 846.539us 846.539us 0.000us 0.00% 20.577us 20.577us 1
aten::to 0.73% 6.218us 67.41% 574.433us 95.739us 0.000us 0.00% 13.344us 2.224us 6
aten::_to_copy 2.79% 23.792us 66.68% 568.215us 94.702us 0.000us 0.00% 13.344us 2.224us 6
aten::copy_ 6.26% 53.310us 60.38% 514.471us 85.745us 11.456us 61.30% 13.344us 2.224us 6
aten::conv1d 0.70% 5.960us 14.03% 119.583us 39.861us 0.000us 0.00% 7.233us 2.411us 3
aten::convolution 1.15% 9.760us 13.33% 113.623us 37.874us 0.000us 0.00% 7.233us 2.411us 3
aten::_convolution 2.80% 23.881us 12.19% 103.863us 34.621us 0.000us 0.00% 7.233us 2.411us 3
aten::_conv_depthwise2d 2.66% 22.671us 7.54% 64.252us 21.417us 7.233us 38.70% 7.233us 2.411us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 7.233us 38.70% 7.233us 2.411us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 5.856us 31.33% 5.856us 1.952us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.600us 29.96% 5.600us 1.867us 3
Activity Buffer Request 28.19% 240.205us 28.19% 240.205us 240.205us 1.888us 10.10% 1.888us 1.888us 1
aten::empty_strided 3.52% 29.952us 3.52% 29.952us 4.992us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 28.71% 244.666us 28.71% 244.666us 27.185us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.06% 17.560us 2.66% 22.660us 2.518us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.01% 8.590us 1.01% 8.590us 0.573us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.10% 9.390us 1.10% 9.390us 3.130us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.00% 8.481us 1.00% 8.481us 2.827us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.71% 6.030us 0.87% 7.390us 2.463us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 852.119us
Self CUDA time total: 18.689us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D64_S128_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 337.210us 1736.14% 337.210us 337.210us 1
torch_eager 14.23% 122.135us 99.33% 852.339us 852.339us 0.000us 0.00% 21.279us 21.279us 1
aten::to 0.69% 5.930us 67.81% 581.931us 96.989us 0.000us 0.00% 13.375us 2.229us 6
aten::_to_copy 2.77% 23.810us 67.12% 576.001us 96.000us 0.000us 0.00% 13.375us 2.229us 6
aten::copy_ 5.94% 51.010us 60.80% 521.760us 86.960us 11.519us 59.31% 13.375us 2.229us 6
aten::conv1d 0.66% 5.690us 14.16% 121.503us 40.501us 0.000us 0.00% 7.904us 2.635us 3
aten::convolution 1.11% 9.501us 13.50% 115.813us 38.604us 0.000us 0.00% 7.904us 2.635us 3
aten::_convolution 3.02% 25.902us 12.39% 106.312us 35.437us 0.000us 0.00% 7.904us 2.635us 3
aten::_conv_depthwise2d 2.72% 23.320us 7.45% 63.940us 21.313us 7.904us 40.69% 7.904us 2.635us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 7.904us 40.69% 7.904us 2.635us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 5.855us 30.14% 5.855us 1.952us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.664us 29.16% 5.664us 1.888us 3
Activity Buffer Request 28.95% 248.446us 28.95% 248.446us 248.446us 1.856us 9.56% 1.856us 1.856us 1
aten::empty_strided 3.55% 30.431us 3.55% 30.431us 5.072us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 28.34% 243.224us 28.34% 243.224us 27.025us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 1.98% 16.978us 2.58% 22.140us 2.460us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.00% 8.573us 1.00% 8.573us 0.572us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.13% 9.660us 1.13% 9.660us 3.220us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.17% 10.040us 1.17% 10.040us 3.347us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.78% 6.699us 0.93% 7.990us 2.663us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 858.129us
Self CUDA time total: 19.423us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D64_S512_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 340.632us 1762.47% 340.632us 340.632us 1
torch_eager 14.22% 122.814us 99.35% 857.879us 857.879us 0.000us 0.00% 21.503us 21.503us 1
aten::to 0.71% 6.160us 68.06% 587.732us 97.955us 0.000us 0.00% 14.304us 2.384us 6
aten::_to_copy 2.69% 23.228us 67.35% 581.572us 96.929us 0.000us 0.00% 14.304us 2.384us 6
aten::copy_ 5.95% 51.401us 60.88% 525.681us 87.614us 12.128us 62.75% 14.304us 2.384us 6
aten::conv1d 0.72% 6.190us 13.86% 119.652us 39.884us 0.000us 0.00% 7.199us 2.400us 3
aten::convolution 1.11% 9.620us 13.14% 113.462us 37.821us 0.000us 0.00% 7.199us 2.400us 3
aten::_convolution 2.71% 23.420us 12.03% 103.842us 34.614us 0.000us 0.00% 7.199us 2.400us 3
aten::_conv_depthwise2d 2.67% 23.041us 7.39% 63.831us 21.277us 7.199us 37.25% 7.199us 2.400us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 7.199us 37.25% 7.199us 2.400us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 6.272us 32.45% 6.272us 2.091us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.856us 30.30% 5.856us 1.952us 3
Activity Buffer Request 29.60% 255.626us 29.60% 255.626us 255.626us 2.176us 11.26% 2.176us 2.176us 1
aten::empty_strided 3.78% 32.663us 3.78% 32.663us 5.444us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 27.93% 241.174us 27.93% 241.174us 26.797us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.07% 17.891us 2.69% 23.211us 2.579us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.04% 8.951us 1.04% 8.951us 0.597us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.14% 9.880us 1.14% 9.880us 3.293us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.97% 8.390us 0.97% 8.390us 2.797us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.77% 6.630us 0.93% 8.000us 2.667us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 863.509us
Self CUDA time total: 19.327us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D64_S512_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 334.363us 1661.27% 334.363us 334.363us 1
torch_eager 14.65% 121.213us 99.39% 822.628us 822.628us 0.000us 0.00% 22.271us 22.271us 1
aten::to 0.73% 6.022us 66.87% 553.441us 92.240us 0.000us 0.00% 14.239us 2.373us 6
aten::_to_copy 2.76% 22.839us 66.14% 547.419us 91.237us 0.000us 0.00% 14.239us 2.373us 6
aten::copy_ 6.10% 50.480us 59.81% 495.040us 82.507us 12.095us 60.09% 14.239us 2.373us 6
aten::conv1d 0.71% 5.911us 14.57% 120.603us 40.201us 0.000us 0.00% 8.032us 2.677us 3
aten::convolution 1.15% 9.530us 13.86% 114.692us 38.231us 0.000us 0.00% 8.032us 2.677us 3
aten::_convolution 2.90% 23.998us 12.71% 105.162us 35.054us 0.000us 0.00% 8.032us 2.677us 3
aten::_conv_depthwise2d 2.69% 22.281us 7.85% 64.952us 21.651us 8.032us 39.91% 8.032us 2.677us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 8.032us 39.91% 8.032us 2.677us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 6.207us 30.84% 6.207us 2.069us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 5.888us 29.25% 5.888us 1.963us 3
Activity Buffer Request 27.45% 227.155us 27.45% 227.155us 227.155us 2.144us 10.65% 2.144us 2.144us 1
aten::empty_strided 3.57% 29.540us 3.57% 29.540us 4.923us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 29.06% 240.556us 29.06% 240.556us 26.728us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.13% 17.627us 2.77% 22.910us 2.546us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.09% 9.014us 1.09% 9.014us 0.601us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.17% 9.710us 1.17% 9.710us 3.237us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.19% 9.810us 1.19% 9.810us 3.270us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.72% 5.931us 0.90% 7.422us 2.474us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 827.669us
Self CUDA time total: 20.127us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D64_S2048_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 335.875us 933.82% 335.875us 335.875us 1
torch_eager 14.86% 122.213us 99.37% 816.978us 816.978us 0.000us 0.00% 38.560us 38.560us 1
aten::conv1d 0.73% 6.020us 14.48% 119.072us 39.691us 0.000us 0.00% 20.064us 6.688us 3
aten::convolution 1.17% 9.589us 13.75% 113.052us 37.684us 0.000us 0.00% 20.064us 6.688us 3
aten::_convolution 2.85% 23.419us 12.58% 103.463us 34.488us 0.000us 0.00% 20.064us 6.688us 3
aten::_conv_depthwise2d 2.73% 22.441us 7.81% 64.191us 21.397us 20.064us 55.78% 20.064us 6.688us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 20.064us 55.78% 20.064us 6.688us 3
aten::to 0.74% 6.089us 66.65% 547.971us 91.328us 0.000us 0.00% 18.496us 3.083us 6
aten::_to_copy 2.81% 23.090us 65.91% 541.882us 90.314us 0.000us 0.00% 18.496us 3.083us 6
aten::copy_ 6.02% 49.484us 59.30% 487.602us 81.267us 15.904us 44.22% 18.496us 3.083us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 8.576us 23.84% 8.576us 2.859us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 7.328us 20.37% 7.328us 2.443us 3
Activity Buffer Request 27.35% 224.865us 27.35% 224.865us 224.865us 2.592us 7.21% 2.592us 2.592us 1
aten::empty_strided 3.79% 31.190us 3.79% 31.190us 5.198us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 28.67% 235.693us 28.67% 235.693us 26.188us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.17% 17.820us 2.82% 23.212us 2.579us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.10% 9.012us 1.10% 9.012us 0.601us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.17% 9.620us 1.17% 9.620us 3.207us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.18% 9.690us 1.18% 9.690us 3.230us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.68% 5.572us 0.85% 6.952us 2.317us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 822.198us
Self CUDA time total: 35.968us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D64_S2048_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 370.623us 978.21% 370.623us 370.623us 1
torch_eager 6.18% 128.993us 99.74% 2.082ms 2.082ms 0.000us 0.00% 40.448us 40.448us 1
aten::conv1d 0.30% 6.311us 5.92% 123.493us 41.164us 0.000us 0.00% 22.177us 7.392us 3
aten::convolution 0.50% 10.340us 5.61% 117.182us 39.061us 0.000us 0.00% 22.177us 7.392us 3
aten::_convolution 1.15% 24.110us 5.12% 106.842us 35.614us 0.000us 0.00% 22.177us 7.392us 3
aten::_conv_depthwise2d 1.14% 23.742us 3.15% 65.742us 21.914us 22.177us 58.53% 22.177us 7.392us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 22.177us 58.53% 22.177us 7.392us 3
aten::to 1.13% 23.681us 86.31% 1.802ms 300.273us 0.000us 0.00% 18.271us 3.045us 6
aten::_to_copy 1.20% 24.951us 85.17% 1.778ms 296.326us 0.000us 0.00% 18.271us 3.045us 6
aten::copy_ 2.41% 50.250us 82.40% 1.720ms 286.684us 15.711us 41.47% 18.271us 3.045us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 8.321us 21.96% 8.321us 2.774us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 7.390us 19.50% 7.390us 2.463us 3
Activity Buffer Request 69.33% 1.447ms 69.33% 1.447ms 1.447ms 2.560us 6.76% 2.560us 2.560us 1
aten::empty_strided 1.58% 32.901us 1.58% 32.901us 5.484us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 11.73% 244.945us 11.73% 244.945us 27.216us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.87% 18.191us 1.14% 23.770us 2.641us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.44% 9.210us 0.44% 9.210us 0.614us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.48% 9.930us 0.48% 9.930us 3.310us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.46% 9.680us 0.46% 9.680us 3.227us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.32% 6.640us 0.38% 7.960us 2.653us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 2.088ms
Self CUDA time total: 37.888us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D2048_S128_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 339.324us 532.86% 339.324us 339.324us 1
torch_eager 14.96% 124.364us 99.38% 826.288us 826.288us 0.000us 0.00% 67.776us 67.776us 1
aten::conv1d 0.74% 6.121us 14.48% 120.383us 40.128us 0.000us 0.00% 41.409us 13.803us 3
aten::convolution 1.31% 10.850us 13.74% 114.262us 38.087us 0.000us 0.00% 41.409us 13.803us 3
aten::_convolution 2.80% 23.271us 12.44% 103.412us 34.471us 0.000us 0.00% 41.409us 13.803us 3
aten::_conv_depthwise2d 2.86% 23.801us 7.77% 64.610us 21.537us 41.409us 65.03% 41.409us 13.803us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 41.409us 65.03% 41.409us 13.803us 3
aten::to 0.72% 5.961us 66.69% 554.441us 92.407us 0.000us 0.00% 26.367us 4.395us 6
aten::_to_copy 2.84% 23.608us 65.97% 548.480us 91.413us 0.000us 0.00% 26.367us 4.395us 6
aten::copy_ 6.26% 52.010us 59.41% 493.909us 82.318us 22.271us 34.97% 26.367us 4.395us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 11.935us 18.74% 11.935us 3.978us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 10.336us 16.23% 10.336us 3.445us 3
Activity Buffer Request 27.47% 228.425us 27.47% 228.425us 228.425us 4.096us 6.43% 4.096us 4.096us 1
aten::empty_strided 3.72% 30.963us 3.72% 30.963us 5.160us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 28.31% 235.354us 28.31% 235.354us 26.150us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.06% 17.130us 2.64% 21.981us 2.442us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.00% 8.352us 1.00% 8.352us 0.557us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.18% 9.829us 1.18% 9.829us 3.276us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.09% 9.100us 1.09% 9.100us 3.033us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.71% 5.910us 0.88% 7.280us 2.427us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 831.408us
Self CUDA time total: 63.680us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D2048_S128_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 341.884us 492.57% 341.884us 341.884us 1
torch_eager 14.66% 124.263us 99.38% 842.608us 842.608us 0.000us 0.00% 73.472us 73.472us 1
aten::conv1d 0.69% 5.810us 14.06% 119.183us 39.728us 0.000us 0.00% 47.072us 15.691us 3
aten::convolution 1.10% 9.331us 13.37% 113.373us 37.791us 0.000us 0.00% 47.072us 15.691us 3
aten::_convolution 2.98% 25.231us 12.27% 104.042us 34.681us 0.000us 0.00% 47.072us 15.691us 3
aten::_conv_depthwise2d 2.57% 21.770us 7.47% 63.341us 21.114us 47.072us 67.82% 47.072us 15.691us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 47.072us 67.82% 47.072us 15.691us 3
aten::to 0.71% 6.042us 67.35% 571.062us 95.177us 0.000us 0.00% 26.400us 4.400us 6
aten::_to_copy 2.91% 24.658us 66.64% 565.020us 94.170us 0.000us 0.00% 26.400us 4.400us 6
aten::copy_ 5.98% 50.742us 60.23% 510.651us 85.108us 22.336us 32.18% 26.400us 4.400us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 11.967us 17.24% 11.967us 3.989us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 10.369us 14.94% 10.369us 3.456us 3
Activity Buffer Request 28.69% 243.255us 28.69% 243.255us 243.255us 4.064us 5.86% 4.064us 4.064us 1
aten::empty_strided 3.50% 29.711us 3.50% 29.711us 4.952us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 28.24% 239.475us 28.24% 239.475us 26.608us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.11% 17.861us 2.71% 22.969us 2.552us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.01% 8.598us 1.01% 8.598us 0.573us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.13% 9.580us 1.13% 9.580us 3.193us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.08% 9.170us 1.08% 9.170us 3.057us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.70% 5.911us 0.85% 7.210us 2.403us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 847.859us
Self CUDA time total: 69.408us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D2048_S512_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 350.870us 189.71% 350.870us 350.870us 1
torch_eager 14.64% 124.941us 99.33% 847.778us 847.778us 0.000us 0.00% 194.907us 194.907us 1
aten::conv1d 0.69% 5.931us 14.37% 122.643us 40.881us 0.000us 0.00% 132.732us 44.244us 3
aten::convolution 1.16% 9.910us 13.67% 116.712us 38.904us 0.000us 0.00% 132.732us 44.244us 3
aten::_convolution 2.94% 25.098us 12.51% 106.802us 35.601us 0.000us 0.00% 132.732us 44.244us 3
aten::_conv_depthwise2d 2.63% 22.470us 7.66% 65.342us 21.781us 132.732us 71.76% 132.732us 44.244us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 132.732us 71.76% 132.732us 44.244us 3
aten::to 0.71% 6.042us 67.13% 572.943us 95.490us 0.000us 0.00% 62.175us 10.362us 6
aten::_to_copy 2.75% 23.470us 66.42% 566.901us 94.484us 0.000us 0.00% 62.175us 10.362us 6
aten::copy_ 6.00% 51.182us 60.05% 512.571us 85.428us 52.223us 28.24% 62.175us 10.362us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 29.343us 15.86% 29.343us 9.781us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 22.880us 12.37% 22.880us 7.627us 3
Activity Buffer Request 29.33% 250.295us 29.33% 250.295us 250.295us 9.952us 5.38% 9.952us 9.952us 1
aten::empty_strided 3.62% 30.860us 3.62% 30.860us 5.143us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 27.39% 233.736us 27.39% 233.736us 25.971us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.08% 17.752us 2.70% 23.071us 2.563us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.06% 9.008us 1.06% 9.008us 0.601us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.27% 10.820us 1.27% 10.820us 3.607us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.10% 9.410us 1.10% 9.410us 3.137us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.72% 6.112us 0.88% 7.511us 2.504us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 853.509us
Self CUDA time total: 184.955us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D2048_S512_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 355.227us 169.45% 355.227us 355.227us 1
torch_eager 15.18% 123.692us 99.29% 808.918us 808.918us 0.000us 0.00% 223.518us 223.518us 1
aten::conv1d 0.72% 5.860us 14.71% 119.853us 39.951us 0.000us 0.00% 153.470us 51.157us 3
aten::convolution 1.17% 9.541us 13.99% 113.993us 37.998us 0.000us 0.00% 153.470us 51.157us 3
aten::_convolution 3.03% 24.710us 12.82% 104.452us 34.817us 0.000us 0.00% 153.470us 51.157us 3
aten::_conv_depthwise2d 2.76% 22.461us 7.85% 63.951us 21.317us 153.470us 73.21% 153.470us 51.157us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 153.470us 73.21% 153.470us 51.157us 3
aten::to 0.75% 6.140us 65.95% 537.281us 89.547us 0.000us 0.00% 70.048us 11.675us 6
aten::_to_copy 2.84% 23.150us 65.19% 531.141us 88.524us 0.000us 0.00% 70.048us 11.675us 6
aten::copy_ 6.47% 52.731us 58.48% 476.471us 79.412us 56.160us 26.79% 70.048us 11.675us 6
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 33.184us 15.83% 33.184us 11.061us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 22.976us 10.96% 22.976us 7.659us 3
Activity Buffer Request 26.55% 216.325us 26.55% 216.325us 216.325us 13.888us 6.63% 13.888us 13.888us 1
aten::empty_strided 3.87% 31.520us 3.87% 31.520us 5.253us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 28.13% 229.215us 28.13% 229.215us 25.468us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 2.20% 17.931us 2.85% 23.181us 2.576us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 1.08% 8.800us 1.08% 8.800us 0.587us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 1.20% 9.790us 1.20% 9.790us 3.263us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 1.22% 9.900us 1.22% 9.900us 3.300us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.73% 5.980us 0.90% 7.360us 2.453us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 814.738us
Self CUDA time total: 209.630us
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D2048_S2048_W2
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 6.92% 128.362us 54.16% 1.005ms 1.005ms 0.000us 0.00% 1.522ms 1.522ms 1
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 1.421ms 100.42% 1.421ms 1.421ms 1
aten::to 0.36% 6.621us 38.84% 720.727us 120.121us 0.000us 0.00% 826.557us 137.760us 6
aten::_to_copy 1.58% 29.231us 38.49% 714.106us 119.018us 0.000us 0.00% 826.557us 137.760us 6
aten::copy_ 2.91% 54.020us 26.66% 494.611us 82.435us 719.869us 50.86% 826.557us 137.760us 6
aten::conv1d 0.33% 6.200us 6.83% 126.803us 42.268us 0.000us 0.00% 695.450us 231.817us 3
aten::convolution 0.54% 10.000us 6.50% 120.603us 40.201us 0.000us 0.00% 695.450us 231.817us 3
aten::_convolution 1.37% 25.370us 5.96% 110.603us 36.868us 0.000us 0.00% 695.450us 231.817us 3
aten::_conv_depthwise2d 1.27% 23.500us 3.66% 67.942us 22.647us 695.450us 49.14% 695.450us 231.817us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 695.450us 49.14% 695.450us 231.817us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 408.829us 28.89% 408.829us 136.276us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 311.040us 21.98% 311.040us 103.680us 3
Activity Buffer Request 12.21% 226.485us 12.21% 226.485us 226.485us 106.688us 7.54% 106.688us 106.688us 1
aten::empty_strided 2.00% 37.161us 10.25% 190.264us 31.711us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 12.87% 238.737us 12.87% 238.737us 26.526us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.97% 18.050us 1.30% 24.121us 2.680us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.54% 9.951us 0.54% 9.951us 0.663us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.54% 10.110us 0.54% 10.110us 3.370us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.52% 9.701us 0.52% 9.701us 3.234us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.37% 6.860us 0.45% 8.350us 2.783us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 1.855ms
Self CUDA time total: 1.415ms
======================================================================
PROFILE TRACE: torch_eager | cuda_B4_D2048_S2048_W4
======================================================================
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Name Self CPU % Self CPU CPU total % CPU total CPU time avg Self CUDA Self CUDA % CUDA total CUDA time avg # of Calls
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
torch_eager 4.16% 128.483us 66.51% 2.056ms 2.056ms 0.000us 0.00% 1.499ms 1.499ms 1
torch_eager 0.00% 0.000us 0.00% 0.000us 0.000us 1.430ms 100.42% 1.430ms 1.430ms 1
aten::to 0.21% 6.492us 57.40% 1.775ms 295.822us 0.000us 0.00% 760.863us 126.811us 6
aten::_to_copy 0.82% 25.449us 57.19% 1.768ms 294.739us 0.000us 0.00% 760.863us 126.811us 6
aten::copy_ 1.66% 51.471us 55.36% 1.712ms 285.278us 686.079us 48.17% 760.863us 126.811us 6
aten::conv1d 0.22% 6.820us 4.02% 124.423us 41.474us 0.000us 0.00% 738.336us 246.112us 3
aten::convolution 0.33% 10.111us 3.80% 117.603us 39.201us 0.000us 0.00% 738.336us 246.112us 3
aten::_convolution 0.82% 25.320us 3.48% 107.492us 35.831us 0.000us 0.00% 738.336us 246.112us 3
aten::_conv_depthwise2d 0.75% 23.320us 2.10% 65.022us 21.674us 738.336us 51.83% 738.336us 246.112us 3
void at::native::(anonymous namespace)::conv_depthwi... 0.00% 0.000us 0.00% 0.000us 0.000us 738.336us 51.83% 738.336us 246.112us 3
void at::native::elementwise_kernel&lt;128, 4, at::nati... 0.00% 0.000us 0.00% 0.000us 0.000us 395.071us 27.74% 395.071us 131.690us 3
void at::native::unrolled_elementwise_kernel&lt;at::nat... 0.00% 0.000us 0.00% 0.000us 0.000us 291.008us 20.43% 291.008us 97.003us 3
Activity Buffer Request 46.92% 1.451ms 46.92% 1.451ms 1.451ms 74.784us 5.25% 74.784us 74.784us 1
aten::empty_strided 1.01% 31.321us 1.01% 31.321us 5.220us 0.000us 0.00% 0.000us 0.000us 6
cudaLaunchKernel 7.49% 231.634us 7.49% 231.634us 25.737us 0.000us 0.00% 0.000us 0.000us 9
aten::unsqueeze 0.61% 18.861us 0.79% 24.350us 2.706us 0.000us 0.00% 0.000us 0.000us 9
aten::as_strided 0.29% 9.099us 0.29% 9.099us 0.607us 0.000us 0.00% 0.000us 0.000us 15
aten::empty 0.32% 9.981us 0.32% 9.981us 3.327us 0.000us 0.00% 0.000us 0.000us 3
aten::resize_ 0.31% 9.461us 0.31% 9.461us 3.154us 0.000us 0.00% 0.000us 0.000us 3
aten::squeeze 0.20% 6.260us 0.25% 7.650us 2.550us 0.000us 0.00% 0.000us 0.000us 3
------------------------------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
Self CPU time total: 3.092ms
Self CUDA time total: 1.424ms
impl wl p50(ms) ok
torch_eager cuda_B2_D2048_S128_W2 0.09 True
torch_eager cuda_B2_D2048_S128_W4 0.09 True
torch_eager cuda_B2_D2048_S2048_W2 0.14 True
torch_eager cuda_B2_D2048_S2048_W4 0.16 True
torch_eager cuda_B2_D2048_S512_W2 0.09 True
torch_eager cuda_B2_D2048_S512_W4 0.09 True
torch_eager cuda_B2_D64_S128_W2 0.07 True
torch_eager cuda_B2_D64_S128_W4 0.09 True
torch_eager cuda_B2_D64_S2048_W2 0.09 True
torch_eager cuda_B2_D64_S2048_W4 0.09 True
torch_eager cuda_B2_D64_S512_W2 0.09 True
torch_eager cuda_B2_D64_S512_W4 0.09 True
torch_eager cuda_B4_D2048_S128_W2 0.09 True
torch_eager cuda_B4_D2048_S128_W4 0.09 True
torch_eager cuda_B4_D2048_S2048_W2 0.49 True
torch_eager cuda_B4_D2048_S2048_W4 0.50 True
torch_eager cuda_B4_D2048_S512_W2 0.10 True
torch_eager cuda_B4_D2048_S512_W4 0.10 True
torch_eager cuda_B4_D64_S128_W2 0.09 True
torch_eager cuda_B4_D64_S128_W4 0.09 True
torch_eager cuda_B4_D64_S2048_W2 0.09 True
torch_eager cuda_B4_D64_S2048_W4 0.09 True
torch_eager cuda_B4_D64_S512_W2 0.09 True
torch_eager cuda_B4_D64_S512_W4 0.09 True
</pre></div>
<div class="uv-install-logs" id="uv-logs-benchmark">
<div class="uv-logs-header" onclick="toggleUvLogs(this)">▶ UV Install Logs</div>
<div class="uv-logs-content" style="display: none;">
Installed 37 packages in 218ms
</div>
</div>
<div class="cell-artifacts">
<h4>Artifacts:</h4>
<a href="artifacts/benchmark/causal_conv1d.jsonl" class="artifact" target="_blank">causal_conv1d.jsonl</a>
</div>
</div>
</div>
</div>
</body>
</html>