<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://justachetan.github.io/feed.xml" rel="self" type="application/atom+xml"/><link href="https://justachetan.github.io/" rel="alternate" type="text/html" hreflang="en"/><updated>2026-06-01T05:03:22+00:00</updated><id>https://justachetan.github.io/feed.xml</id><title type="html">Aditya Chetan</title><subtitle>I am a PhD student in the [Computer Science Department](https://www.cs.cornell.edu/) at [Cornell University](https://www.cornell.edu/), where I am advised by [Prof. Bharath Hariharan](https://www.cs.cornell.edu/~bharathh/). My research interests lie in the intersection of 3D Computer Vision and Graphics. </subtitle><entry><title type="html">Batching wrapper for PyTorch Tensors</title><link href="https://justachetan.github.io/blog/2025/code-snippet-batching/" rel="alternate" type="text/html" title="Batching wrapper for PyTorch Tensors"/><published>2025-01-25T00:00:00+00:00</published><updated>2025-01-25T00:00:00+00:00</updated><id>https://justachetan.github.io/blog/2025/code-snippet-batching</id><content type="html" xml:base="https://justachetan.github.io/blog/2025/code-snippet-batching/"><![CDATA[<p>Ever written a function to process PyTorch tensors that already does batch processing, but you didn’t want to write a whole loop to go over the full dataset?</p> <p>Me too! One fix is to change your function to process a single sample and use <a href="https://pytorch.org/docs/stable/generated/torch.vmap.html"><code class="language-plaintext highlighter-rouge">torch.vmap</code></a>. But your function might not be supported by <code class="language-plaintext highlighter-rouge">torch.vmap</code> (e.g. it has lots of conditionals or in-place operations).</p> <p>Another way is to write a wrapper function that processes your input in batches. I found myself writing such a wrapper many times so I prompted ChatGPT for a generic one.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">torch</span>
<span class="kn">from</span> <span class="n">torch.utils.data</span> <span class="kn">import</span> <span class="n">DataLoader</span><span class="p">,</span> <span class="n">TensorDataset</span>

<span class="k">def</span> <span class="nf">chunked_function_wrapper</span><span class="p">(</span><span class="n">function</span><span class="p">,</span> <span class="n">chunk_size</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="sh">'</span><span class="s">cuda</span><span class="sh">'</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sh">"""</span><span class="s">
    Wraps a function to process inputs in chunks using TensorDataset and supports multiple tensors,
    allowing both positional and named arguments while handling None values.

    Args:
        function (callable): The function to apply to the inputs.
        chunk_size (int): The size of each chunk to process.
        device (str): The device to process tensors on (default: </span><span class="sh">'</span><span class="s">cuda</span><span class="sh">'</span><span class="s">).
        **kwargs: Additional keyword arguments for the function.

    Returns:
        callable: A wrapped function that processes inputs in chunks.
    </span><span class="sh">"""</span>
    <span class="k">def</span> <span class="nf">wrapped_function</span><span class="p">(</span><span class="o">*</span><span class="n">tensor_args</span><span class="p">,</span> <span class="o">**</span><span class="n">tensor_kwargs</span><span class="p">):</span>
        <span class="c1"># Filter out None values from tensor_kwargs
</span>        <span class="n">tensor_kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="n">key</span><span class="p">:</span> <span class="n">val</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">tensor_kwargs</span><span class="p">.</span><span class="nf">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">val</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">}</span>
        
        <span class="n">all_tensors</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="n">tensor_args</span><span class="p">)</span> <span class="o">+</span> <span class="nf">list</span><span class="p">(</span><span class="n">tensor_kwargs</span><span class="p">.</span><span class="nf">values</span><span class="p">())</span>

        <span class="c1"># Ensure all tensors have the same size along the first dimension
</span>        <span class="k">if</span> <span class="ow">not</span> <span class="n">all_tensors</span><span class="p">:</span>
            <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">At least one tensor input is required.</span><span class="sh">"</span><span class="p">)</span>
        
        <span class="n">num_samples</span> <span class="o">=</span> <span class="n">all_tensors</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nf">size</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">tensor</span> <span class="ow">in</span> <span class="n">all_tensors</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">tensor</span><span class="p">.</span><span class="nf">size</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">!=</span> <span class="n">num_samples</span><span class="p">:</span>
                <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">All input tensors must have the same first dimension size.</span><span class="sh">"</span><span class="p">)</span>

        <span class="c1"># Create a TensorDataset and DataLoader
</span>        <span class="n">dataset</span> <span class="o">=</span> <span class="nc">TensorDataset</span><span class="p">(</span><span class="o">*</span><span class="n">all_tensors</span><span class="p">)</span>
        <span class="n">dataloader</span> <span class="o">=</span> <span class="nc">DataLoader</span><span class="p">(</span><span class="n">dataset</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="n">chunk_size</span><span class="p">)</span>

        <span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="k">for</span> <span class="n">batch</span> <span class="ow">in</span> <span class="n">dataloader</span><span class="p">:</span>
            <span class="n">batch_args</span> <span class="o">=</span> <span class="n">batch</span><span class="p">[:</span><span class="nf">len</span><span class="p">(</span><span class="n">tensor_args</span><span class="p">)]</span>
            <span class="n">batch_kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="n">key</span><span class="p">:</span> <span class="n">batch</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="nf">len</span><span class="p">(</span><span class="n">tensor_args</span><span class="p">)]</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">key</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">tensor_kwargs</span><span class="p">.</span><span class="nf">keys</span><span class="p">())}</span>
            
            <span class="c1"># Transfer the batch to the specified device
</span>            <span class="n">batch_args</span> <span class="o">=</span> <span class="p">[</span><span class="n">tensor</span><span class="p">.</span><span class="nf">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span> <span class="k">for</span> <span class="n">tensor</span> <span class="ow">in</span> <span class="n">batch_args</span><span class="p">]</span>
            <span class="n">batch_kwargs</span> <span class="o">=</span> <span class="p">{</span><span class="n">key</span><span class="p">:</span> <span class="n">tensor</span><span class="p">.</span><span class="nf">to</span><span class="p">(</span><span class="n">device</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">tensor</span> <span class="ow">in</span> <span class="n">batch_kwargs</span><span class="p">.</span><span class="nf">items</span><span class="p">()}</span>
            
            <span class="c1"># Apply the function to the batch
</span>            <span class="k">with</span> <span class="n">torch</span><span class="p">.</span><span class="nf">no_grad</span><span class="p">():</span>
                <span class="n">result</span> <span class="o">=</span> <span class="nf">function</span><span class="p">(</span><span class="o">*</span><span class="n">batch_args</span><span class="p">,</span> <span class="o">**</span><span class="n">batch_kwargs</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

            <span class="c1"># Collect the results (move to CPU if needed)
</span>            <span class="k">if</span> <span class="nf">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">torch</span><span class="p">.</span><span class="n">Tensor</span><span class="p">):</span>
                <span class="n">results</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="nf">cpu</span><span class="p">())</span>
            <span class="k">elif</span> <span class="nf">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)):</span>
                <span class="k">if</span> <span class="ow">not</span> <span class="n">results</span><span class="p">:</span>
                    <span class="c1"># Initialize lists for multiple outputs
</span>                    <span class="n">results</span> <span class="o">=</span> <span class="p">[[]</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="nf">len</span><span class="p">(</span><span class="n">result</span><span class="p">))]</span>
                <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">res</span> <span class="ow">in</span> <span class="nf">enumerate</span><span class="p">(</span><span class="n">result</span><span class="p">):</span>
                    <span class="n">results</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">append</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="nf">cpu</span><span class="p">())</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">raise</span> <span class="nc">ValueError</span><span class="p">(</span><span class="sh">"</span><span class="s">The function must return a Tensor or a tuple/list of Tensors.</span><span class="sh">"</span><span class="p">)</span>

        <span class="c1"># Concatenate results along the first dimension
</span>        <span class="k">if</span> <span class="nf">isinstance</span><span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">list</span><span class="p">):</span>
            <span class="k">return</span> <span class="p">[</span><span class="n">torch</span><span class="p">.</span><span class="nf">cat</span><span class="p">(</span><span class="n">res</span><span class="p">,</span> <span class="n">dim</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="k">for</span> <span class="n">res</span> <span class="ow">in</span> <span class="n">results</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">torch</span><span class="p">.</span><span class="nf">cat</span><span class="p">(</span><span class="n">results</span><span class="p">,</span> <span class="n">dim</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">wrapped_function</span>

<span class="c1"># Example usage
</span><span class="k">def</span> <span class="nf">example_function</span><span class="p">(</span><span class="n">tensor1</span><span class="p">,</span> <span class="n">tensor2</span><span class="p">,</span> <span class="n">tensor3</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">tensor3</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">tensor1</span> <span class="o">+</span> <span class="n">tensor2</span> <span class="o">+</span> <span class="n">tensor3</span><span class="p">,</span> <span class="n">tensor1</span> <span class="o">*</span> <span class="n">tensor2</span> <span class="o">*</span> <span class="n">tensor3</span>  <span class="c1"># Example: sum and product
</span>    <span class="k">return</span> <span class="n">tensor1</span> <span class="o">+</span> <span class="n">tensor2</span><span class="p">,</span> <span class="n">tensor1</span> <span class="o">*</span> <span class="n">tensor2</span>

<span class="c1"># Wrap the function
</span><span class="n">chunk_size</span> <span class="o">=</span> <span class="mi">1024</span>
<span class="n">wrapped_example_function</span> <span class="o">=</span> <span class="nf">chunked_function_wrapper</span><span class="p">(</span><span class="n">example_function</span><span class="p">,</span> <span class="n">chunk_size</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="sh">'</span><span class="s">cuda</span><span class="sh">'</span><span class="p">)</span>

<span class="c1"># Input tensors
</span><span class="n">inputs1</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="nf">randn</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="mi">128</span><span class="p">)</span>
<span class="n">inputs2</span> <span class="o">=</span> <span class="n">torch</span><span class="p">.</span><span class="nf">randn</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="mi">128</span><span class="p">)</span>
<span class="n">inputs3</span> <span class="o">=</span> <span class="bp">None</span>  <span class="c1"># Optional input
</span>
<span class="c1"># Use the wrapped function with both positional and named arguments
</span><span class="n">outputs</span> <span class="o">=</span> <span class="nf">wrapped_example_function</span><span class="p">(</span><span class="n">inputs1</span><span class="p">,</span> <span class="n">inputs2</span><span class="p">,</span> <span class="n">tensor3</span><span class="o">=</span><span class="n">inputs3</span><span class="p">)</span>

<span class="c1"># Results
</span><span class="n">output1</span><span class="p">,</span> <span class="n">output2</span> <span class="o">=</span> <span class="n">outputs</span>
<span class="nf">print</span><span class="p">(</span><span class="n">output1</span><span class="p">.</span><span class="n">shape</span><span class="p">)</span>  <span class="c1"># Should match inputs1/inputs2 shape
</span><span class="nf">print</span><span class="p">(</span><span class="n">output2</span><span class="p">.</span><span class="n">shape</span><span class="p">)</span>  <span class="c1"># Should match inputs1/inputs2 shape
</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="code"/><category term="pytorch"/><summary type="html"><![CDATA[code snippet for batching pytorch functions]]></summary></entry><entry><title type="html">Graduate School Applications</title><link href="https://justachetan.github.io/blog/2022/grad-school-apps/" rel="alternate" type="text/html" title="Graduate School Applications"/><published>2022-10-19T00:00:00+00:00</published><updated>2022-10-19T00:00:00+00:00</updated><id>https://justachetan.github.io/blog/2022/grad-school-apps</id><content type="html" xml:base="https://justachetan.github.io/blog/2022/grad-school-apps/"><![CDATA[<p>Hi! I am Aditya Chetan, a Ph.D. student in Computer Science at Cornell University.</p> <p>Here I have posted my application materials from my Graduate School Applications for PhD programs in Fall 2022. I applied to about 10 schools, interviewed at 7 schools and was admitted to 3. The materials in question are for Cornell University, where I eventually decided to go.</p> <p>Cornell requires a Statement of Purpose highlighting your research background and plans along with a Personal Statement which talks about how you would contribute to the student community at Cornell.</p> <ul> <li><a href="../../../assets/pdf/cornell_sop.pdf">Link to Statement of Purpose</a></li> <li><a href="../../../assets/pdf/cornell_ps.pdf">Link to Personal Statement</a></li> </ul> <h2 id="structure-for-sop">Structure for SoP</h2> <p>For the SoP, a broad overview of the structure that I followed based on advice from senior graduate students and faculty members is as follows:</p> <h3 id="introduction">Introduction</h3> <p>Start with a brief introduction, where you are from, which program you are applying to and what are your research interests and motivations.</p> <h3 id="optional-a-bit-more-introduction">[Optional] A bit more introduction</h3> <p>Give a slightly more detailed overview of your experience if required. In my case, I was switching fields, so it was important for me to highlight that I have past research experience.</p> <h3 id="about-your-research">About your research</h3> <p>Arguably the most important part of your statement.</p> <p>Take 2-3 core ideas/problems you have worked on or are excited about and write in detail about the problem, where were current solutions, what you proposed and how it might tie into your future goals.</p> <ol> <li>Note that while writing you use active voice, asserting the contributions you have made.</li> <li>Try not to be overtly technical but also not to be completely superficial. Your statement might be read by a general committee as well as by the faculty member you are applying to, and you want to appeal to either of them.</li> <li>It is okay to state ongoing projects here as well.</li> <li>Neatly categorizing the ideas just makes it look very nice. Trust me, my statement looked like a hot mess before I added headings!</li> </ol> <h3 id="optional-are-you-more-than-your-research">[Optional] Are you more than your research?</h3> <p>While it is not always necessary, I found it worthwhile to write about other responsibilities like teaching, and open source contributions that I had made as an undergraduate and how they have prepared me for graduate school.</p> <h3 id="sticking-the-landing">Sticking the landing</h3> <p>Lastly, write about 2-3 potential PIs from the university, and how their interests align with yours. This last part needs to be tailored to each university and requires some time where you go through the papers of each PI and figure out if you align with their research directions or not.</p> <ol> <li>Try not to be very strongly vocal about a particular niche direction of a PI as they might have moved on from it.</li> <li>A balanced assertion of how your work aligns with that of the PI will be better in my opinion.</li> </ol> <h2 id="a-bit-more-advice">A bit more advice</h2> <ul> <li>Go through multiple versions of your SoP, start with a bloated draft and start refining down.</li> <li>Focus on using active voice throughout the statement. It shows ownership, confidence and is concise. Eg. “<em>I proved P=NP</em>” instead of “<em>The proof for P=NP was developed by me</em>”.</li> </ul> <h2 id="some-more-materials">Some more materials</h2> <p>Aside from Cornell, I want to share a couple other statements of purpose that I enjoyed writing. Only the last paragraph differs for these universities as they were all written in the same year.</p> <ul> <li><a href="../../../assets/pdf/sop_toronto.pdf">SoP for the Univesity of Toronto</a> <em>(admitted)</em></li> <li><a href="../../../assets/pdf/sop_chicago.pdf">SoP for the University of Chicago</a> <em>(waitlisted, then rejected)</em></li> <li><a href="../../../assets/pdf/sop_uw.pdf">SoP for the University of Washington</a> <em>(admitted)</em></li> </ul> <hr/> <p>I would love to help out with reviewing application packets or discussing graduate school applications with prospective applicants. Please feel free to drop me an email with your questions and subject line starting with <strong>[grad-apps]</strong> at <a href="mailto:achetan40@gmail.com">achetan40@gmail.com</a></p> <p>This page is still a work in progress. I will keep updating it with any advice I find myself repeating or with any interesting questions I receive. So please don’t hesitate to shoot your emails!</p>]]></content><author><name></name></author><category term="misc"/><category term="grad-school"/><summary type="html"><![CDATA[some tips on applying to graduate school in Computer Science]]></summary></entry></feed>