<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Harsha Raj Kumar</title>
    <description>The latest articles on DEV Community by Harsha Raj Kumar (@harsha_rajkumar_60fb1245).</description>
    <link>https://dev.to/harsha_rajkumar_60fb1245</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3893542%2Fa7a56ad9-97d9-4f79-8f0d-6145541fc14f.png</url>
      <title>DEV Community: Harsha Raj Kumar</title>
      <link>https://dev.to/harsha_rajkumar_60fb1245</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harsha_rajkumar_60fb1245"/>
    <language>en</language>
    <item>
      <title>PyTorch Open-Source Contribution — Fixing a Zero-Dimension Edge Case in `torch.unravel_index`</title>
      <dc:creator>Harsha Raj Kumar</dc:creator>
      <pubDate>Mon, 24 Aug 2026 17:12:58 +0000</pubDate>
      <link>https://dev.to/harsha_rajkumar_60fb1245/pytorch-open-source-contribution-fixing-a-zero-dimension-edge-case-in-torchunravelindex-1c95</link>
      <guid>https://dev.to/harsha_rajkumar_60fb1245/pytorch-open-source-contribution-fixing-a-zero-dimension-edge-case-in-torchunravelindex-1c95</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;I contributed a fix to the PyTorch codebase addressing an edge case in &lt;code&gt;torch.unravel_index&lt;/code&gt;, and the change was reviewed and merged into PyTorch's main branch.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;torch.unravel_index&lt;/code&gt; converts flat indices into coordinates for a tensor of a given shape. While investigating its behavior around zero-sized dimensions, I found a case where invalid input could propagate into the underlying computation and result in division/modulo by zero rather than being rejected with a meaningful validation error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merged PR:&lt;/strong&gt; &lt;a href="https://github.com/pytorch/pytorch/pull/191092" rel="noopener noreferrer"&gt;https://github.com/pytorch/pytorch/pull/191092&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Consider a tensor shape containing a zero-sized dimension while providing non-empty indices.&lt;/p&gt;

&lt;p&gt;A shape containing a zero dimension represents a tensor with zero total elements. Therefore, there cannot be a valid non-empty flat index into that shape.&lt;/p&gt;

&lt;p&gt;However, this edge case could make it into the coordinate computation performed by &lt;code&gt;torch.unravel_index&lt;/code&gt;. Because the implementation relies on arithmetic involving the dimensions of the shape, a zero dimension could eventually result in a division or modulo-by-zero operation.&lt;/p&gt;

&lt;p&gt;Instead of clearly communicating that the supplied indices were invalid for the requested shape, the operation could therefore fail with an unexpected runtime error.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;I added explicit validation for this case before the coordinate calculation takes place.&lt;/p&gt;

&lt;p&gt;The resulting behavior distinguishes between two important cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-sized shape + non-empty indices:&lt;/strong&gt; The input is invalid and now raises a clear &lt;code&gt;ValueError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-sized shape + empty indices:&lt;/strong&gt; The operation remains valid and produces empty coordinate tensors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Preserving the second case was important because an empty collection of indices does not attempt to reference an element that doesn't exist. It also maintains behavior consistent with NumPy for the corresponding edge case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reasoning Through the Edge Case
&lt;/h2&gt;

&lt;p&gt;One of the most interesting parts of the contribution came during code review.&lt;/p&gt;

&lt;p&gt;A question was raised about whether the validation should depend on all dimensions or whether the presence of any zero-sized dimension was sufficient to make non-empty indices invalid.&lt;/p&gt;

&lt;p&gt;Working through the implementation made the answer clearer.&lt;/p&gt;

&lt;p&gt;If any dimension of a tensor's shape is zero, then:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;numel = shape[0] × shape[1] × ... × shape[n] = 0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The tensor therefore contains no elements.&lt;/p&gt;

&lt;p&gt;Consequently, there is no valid flat index into that tensor, regardless of where the zero appears in its shape.&lt;/p&gt;

&lt;p&gt;Tracing the implementation also required thinking through the coefficient calculations, broadcasting behavior, division, and modulo operations used to transform flat indices into multidimensional coordinates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Along with the validation change, I added regression coverage for the edge case to ensure that invalid non-empty indices are rejected while the valid empty-index behavior continues to work correctly.&lt;/p&gt;

&lt;p&gt;The change then went through PyTorch's upstream review and CI process before being approved and merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The code change itself is relatively small, but working in a production ML framework made the surrounding engineering particularly valuable.&lt;/p&gt;

&lt;p&gt;I gained experience with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigating a large open-source codebase like PyTorch&lt;/li&gt;
&lt;li&gt;Understanding implementation details behind a familiar tensor API&lt;/li&gt;
&lt;li&gt;Reasoning carefully about tensor shapes and zero-sized dimensions&lt;/li&gt;
&lt;li&gt;Designing validation around API semantics rather than simply preventing a crash&lt;/li&gt;
&lt;li&gt;Writing regression tests for unusual edge cases&lt;/li&gt;
&lt;li&gt;Responding to technical feedback during upstream code review&lt;/li&gt;
&lt;li&gt;Working through the contribution and CI process of a major open-source project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of my biggest takeaways was that robustness in foundational libraries often comes from handling seemingly tiny edge cases correctly. When an API is used as widely as PyTorch, even input validation deserves careful consideration around semantics, compatibility, and existing behavior.&lt;/p&gt;

&lt;p&gt;I'm excited to continue contributing to open source and exploring more of the systems and infrastructure behind machine learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PyTorch PR #191092:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/pytorch/pytorch/pull/191092" rel="noopener noreferrer"&gt;https://github.com/pytorch/pytorch/pull/191092&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technologies:&lt;/strong&gt; Python · PyTorch · NumPy · Git · GitHub · Open Source · Testing&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>python</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Proofdesk — The IDE for Open-Source Math Textbook Publishing</title>
      <dc:creator>Harsha Raj Kumar</dc:creator>
      <pubDate>Thu, 23 Apr 2026 05:50:48 +0000</pubDate>
      <link>https://dev.to/harsha_rajkumar_60fb1245/proofdesk-the-ide-for-open-source-math-textbook-publishing-lbn</link>
      <guid>https://dev.to/harsha_rajkumar_60fb1245/proofdesk-the-ide-for-open-source-math-textbook-publishing-lbn</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/harsharajkumar/proofdesk" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://proofdesk.duckdns.org/" rel="noopener noreferrer"&gt;proofdesk&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;Math professors who write open-source textbooks are stuck in a painful loop: edit XML in a text editor → open a terminal → run a Docker build that takes 15 minutes → refresh a browser → realize one equation is wrong → repeat. There's no integrated workspace for it. Tools like Overleaf exist for LaTeX, but nothing exists for PreTeXt — the modern XML-based format used by university textbooks at Georgia Tech, MIT, and dozens of other institutions.&lt;/p&gt;

&lt;p&gt;I'm a CS grad student at Vanderbilt. A professor in our math department showed me their workflow. I couldn't believe how broken it was for a format that produces genuinely beautiful output. So I built Proofdesk.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;Proofdesk is a full-stack browser workspace that lets math professors write, build, preview, and publish PreTeXt textbooks without ever leaving their browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write&lt;/strong&gt; — Monaco editor (the engine behind VS Code) with PreTeXt XML syntax highlighting, full-text search across every file in the repository, and a LaTeX/PreTeXt snippet library for common blocks like theorems, definitions, and proofs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build&lt;/strong&gt; — one click triggers the full PreTeXt → HTML pipeline inside a Docker container: TeX Live compiles LaTeX equations to PDF, fontforge extracts font metrics, Inkscape converts each equation to a crisp inline SVG. Every equation in the textbook renders as real vector math — not MathJax approximations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preview&lt;/strong&gt; — a live side-by-side preview updates after each build. 31 interactive 3D visualizations built with MathBox.js (GPU-accelerated WebGL) let students explore eigenspaces, row reduction, orthogonal projection, and least-squares problems in real time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collaborate&lt;/strong&gt; — WebSocket-powered real-time collaboration, in-browser terminal (node-pty + xterm.js), Git history browser, and one-click shareable preview links with a 7-day TTL. Send a draft chapter to a reviewer without them needing a GitHub account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Publish&lt;/strong&gt; — Export the entire built textbook as a self-contained ZIP. Deploy to any static host. No runtime dependencies.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I built it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt; React + TypeScript, Monaco editor, xterm.js, MathBox.js (WebGL), Playwright for E2E tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend:&lt;/strong&gt; Node.js + Express, GitHub OAuth, WebSocket (ws), node-pty for real TTY terminal sessions, BullMQ + Redis for build job queuing, archiver for ZIP export.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build pipeline:&lt;/strong&gt; The hardest part. PreTeXt's toolchain was written for a specific era — Python 2, Ruby 2-era gems, Inkscape 0.9x CLI syntax, CoffeeScript 1.12.7, a custom SCons pipeline. I wrote a 720-line Docker build script that patches Python 2 idioms at build time without modifying the source repo permanently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sed&lt;/code&gt; replaces &lt;code&gt;unichr()&lt;/code&gt; → &lt;code&gt;chr()&lt;/code&gt; across Python files&lt;/li&gt;
&lt;li&gt;Rewrites the Inkscape &lt;code&gt;inkscape_script()&lt;/code&gt; method for 1.x action syntax&lt;/li&gt;
&lt;li&gt;Falls back from &lt;code&gt;compass&lt;/code&gt; to &lt;code&gt;sass-embedded&lt;/code&gt; when Ruby 3.2 rejects it&lt;/li&gt;
&lt;li&gt;Patches SCons builder suffix declarations to fix cache-busting in the demo pipeline&lt;/li&gt;
&lt;li&gt;Wraps &lt;code&gt;git hash-object&lt;/code&gt; calls in try/except so missing intermediate files don't abort&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result: a fully reproducible Docker image that builds a 40-chapter math textbook with 750+ rendered equation SVGs from a completely unmodified upstream PreTeXt repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure:&lt;/strong&gt; EC2 t3.small, docker-compose, Nginx reverse proxy, DuckDNS, GitHub Actions for CI/CD with Playwright sanity tests on every deploy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges I ran into
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The legacy dependency maze&lt;/strong&gt; was the biggest one. The PreTeXt build toolchain spans four languages (Python, Ruby, CoffeeScript, XSL), three incompatible major versions of key tools, and a build system (SCons) that almost nobody uses anymore. Making all of this work reproducibly inside a modern Docker container on Ubuntu 24.04 required reverse-engineering error messages I had never seen before and patching code I didn't write.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The math rendering pipeline&lt;/strong&gt; was non-trivial. Each equation takes a round-trip through pdflatex → fontforge → Inkscape before becoming an SVG. Getting fontforge to extract the right font metrics for the Charter typeface, and getting Inkscape 1.x to accept the rewritten CLI flags, took more debugging time than the entire React frontend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker-in-Docker orchestration&lt;/strong&gt; — the backend mounts the Docker socket and spawns isolated PreTeXt build containers on demand. Handling container lifecycle, cleanup on user disconnect, concurrent session limits, and OOM kills on a t3.small with 2GB RAM required careful resource management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Localhost vs EC2 rendering differences&lt;/strong&gt; — the deployed site has a text overlap bug I'm still actively debugging. My current theory is a Nginx MIME type misconfiguration for &lt;code&gt;.woff2&lt;/code&gt; font files causing the browser to fall back to a system font with different metrics. Working on it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Accomplishments I'm proud of
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A 720-line build orchestration script that makes a Python 2 / Ruby 2 / Inkscape 0.9x toolchain work on modern infrastructure with zero permanent source modifications&lt;/li&gt;
&lt;li&gt;31 GPU-accelerated interactive math visualizations running in the browser via MathBox.js&lt;/li&gt;
&lt;li&gt;A real TTY terminal session inside the browser using node-pty — same behavior as SSH, not a fake shell&lt;/li&gt;
&lt;li&gt;Full Playwright E2E test suite including GitHub OAuth smoke tests and multi-browser sanity checks&lt;/li&gt;
&lt;li&gt;A shareable preview link system that lets non-technical reviewers see a built textbook without any GitHub account&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;Legacy compatibility is underrated as an engineering skill. The ability to make old code run on new infrastructure — without breaking the original — is something most CS programs don't teach but every production engineering team deals with constantly.&lt;/p&gt;

&lt;p&gt;I also learned that the hardest bugs are the ones that only reproduce in production. The font rendering overlap on EC2 taught me that "it works on my machine" is not a deployment strategy, and that Nginx configuration deserves as much attention as application code.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fix the EC2 font rendering bug (actively working)&lt;/li&gt;
&lt;li&gt;Multi-textbook support — paste any PreTeXt GitHub URL and get a full workspace&lt;/li&gt;
&lt;li&gt;Student mode — read-only workspace with a purpose-limited AI tutor that can answer questions about the material but cannot do homework&lt;/li&gt;
&lt;li&gt;CRDT-based real-time collaboration for simultaneous multi-author editing&lt;/li&gt;
&lt;li&gt;Incremental builds — only rebuild changed chapters, cutting build time from 15 min to under 2 min&lt;/li&gt;
&lt;li&gt;LMS integration (Canvas, Blackboard) with SSO for institutional deployment&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Built with
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;React&lt;/code&gt; &lt;code&gt;TypeScript&lt;/code&gt; &lt;code&gt;Node.js&lt;/code&gt; &lt;code&gt;Express&lt;/code&gt; &lt;code&gt;Docker&lt;/code&gt; &lt;code&gt;Nginx&lt;/code&gt; &lt;code&gt;Redis&lt;/code&gt; &lt;code&gt;BullMQ&lt;/code&gt; &lt;code&gt;Monaco Editor&lt;/code&gt; &lt;code&gt;xterm.js&lt;/code&gt; &lt;code&gt;MathBox.js&lt;/code&gt; &lt;code&gt;WebGL&lt;/code&gt; &lt;code&gt;node-pty&lt;/code&gt; &lt;code&gt;Playwright&lt;/code&gt; &lt;code&gt;GitHub OAuth&lt;/code&gt; &lt;code&gt;AWS EC2&lt;/code&gt; &lt;code&gt;PreTeXt&lt;/code&gt; &lt;code&gt;TeX Live&lt;/code&gt; &lt;code&gt;Inkscape&lt;/code&gt; &lt;code&gt;fontforge&lt;/code&gt; &lt;code&gt;SCons&lt;/code&gt; &lt;code&gt;Python&lt;/code&gt; &lt;code&gt;Ruby&lt;/code&gt; &lt;code&gt;CoffeeScript&lt;/code&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
