Onboarding Problem
Overview
Section titled “Overview”You will implement two components of a 2D heat diffusion solver:
- A grid class that stores the 2D temperature field in memory.
- The stencil kernel that advances the simulation by one time step.
Everything else, i.e., the time integrator, boundary conditions, initial conditions, and I/O, is provided. You DO NOT need to know any thermal physics or theory.
The Math
Section titled “The Math”The Governing Heat Equation
Section titled “The Governing Heat Equation”Heat spreads across a 2D surface according to the following Partial Differential Equation:
where is the temperature and is a constant. This is provided for context only.
Discretization onto a Grid
Section titled “Discretization onto a Grid”Replace the continuous derivatives with finite differences:
Given Constants
Section titled “Given Constants”With constants , , , and chosen for stability, the equation simplifies to the following:
Converting Equations to Code
Section titled “Converting Equations to Code”Notice how this is just a weighted average. In code, the above could look something like this:
new_arr[i][j] = 0.5 * old_arr[i][j] + 0.125 * (old_arr[i-1][j] + old_arr[i+1][j] + old_arr[i][j-1] + old_arr[i][j+1]);The Five-Point Stencil
Section titled “The Five-Point Stencil”To provide a more visual understanding and intuition of what is happening, consider the diagram below. You can picture the heat from each “bubble” (grid cell) leaking into its neighbors.
Applying that update over and over is the whole simulation. Below, a hot block at the centre of a grid spreads into the cells around it as the stencil is applied repeatedly:
Task 1: The Grid Class
Section titled “Task 1: The Grid Class”Design and implement a Grid class that stores a 2D field of double values
with rows rows and cols columns. In the notation above, index i selects
the row and index j selects the column.
Both this class and the stencil function go in src/submission.hpp, which
ships with the interface declared and no implementations:
#pragma once
#include <cstddef>
class Grid {private: std::size_t rows_; std::size_t cols_;
public: Grid(std::size_t rows, std::size_t cols);
double& operator()(std::size_t i, std::size_t j); double operator()(std::size_t i, std::size_t j) const;};The two operator() overloads give read/write and read-only access to the cell
at row i, column j. The evaluation harness uses only these overloads to set
initial conditions and read back your results, so they must work no matter how
you store the field internally. Keep this interface; everything else is yours.
Requirements:
- Default-initialized to zero.
- Implement both
operator()overloads. - You are free to choose the memory layout and overall design of the Grid class.
Note that the harness never asks your Grid for its dimensions, so no size
accessors are prescribed. Your stencil will still need the dimensions, which
makes exposing them part of your design.
Task 2: The Stencil Kernel
Section titled “Task 2: The Stencil Kernel”Implement the function that applies the five-point stencil over all interior grid points (, ). It is declared in the same file:
void apply_stencil(const Grid& old_grid, Grid& new_grid);When it returns, new_grid must hold a complete field:
- Every interior point is the weighted average given above, computed from
old_grid. - Every boundary point — the outermost row and column on each side — is copied
from
old_gridunchanged. You are not required to implement any boundary conditions.
old_grid must not be modified.
Evaluation
Section titled “Evaluation”Submissions are evaluated on correctness, implementation quality, design decisions, and performance (wall-clock execution time on a team benchmark machine). Correctness alone is not sufficient: applications are reviewed holistically, and advancement is not determined by benchmark score alone.
Clearing the score threshold means your code compiles, is correct, and runs at a reasonable speed. It is a floor, not a target. Once you are past it, the performance design guide covers where to look to improve your design.
Your submission must be C++17 — see Complete the exercise for the build details. Within C++17 you may use any standard library facility and add whatever methods, helper functions, or internal data structures you need.
Submission
Section titled “Submission”Fork the template, implement your solution in src/submission.hpp, and open
a pull request against UWHPC/onboarding-template. The evaluator runs
automatically on your pull request and, within about a minute, posts a result
comment with your build, test, and benchmark results and your score. A failing
comment names the category of failure (for example, “non-square grids”) but
never the specific hidden case. Push more commits to iterate; the comment
updates in place and the check turns green once your submission passes.
Your pull request is automatically converted to a draft — this is expected. Do not merge it; it stays open as your submission record for us to review.
After you submit, join the UWHPC Discord from our contact page and post in the onboarding forum channel with your name and a link to your pull request.
We will then invite you to a short virtual chat about your design. Be ready to explain how you interpreted the requirements, the design choices you made, how you verified correctness and evaluated the result, and the tradeoffs you considered. This is a discussion of your own reasoning, not a request for a particular implementation.
On Artificial Intelligence
Section titled “On Artificial Intelligence”We encourage using AI to learn and explore ideas. That said, your submission should be your own work; copy-pasting from AI will be obvious, especially during the chat.
Good luck.