Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function App() {
<Route path="/working-groups" element={<WorkingGroups />} />
<Route path="/lectures" element={<Lectures />} />
<Route path="/login" element={<Login />} />
// error handling page
{/* error handling page */}
{errorRoutes.map(({ path, code, title, description }) => (
<Route
key={path}
Expand Down
44 changes: 44 additions & 0 deletions frontend/src/components/markdown-renderer/MarkdownRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import rehypeRaw from "rehype-raw";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import { useTheme } from "@mui/material/styles";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { oneDark, oneLight } from "react-syntax-highlighter/dist/esm/styles/prism";
import "katex/dist/katex.min.css";

type MarkdownRendererProps = {
Expand Down Expand Up @@ -49,6 +51,7 @@ const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({
const mergedImageProps = { ...defaultImageProps, ...imageProps };
const { align, ...styleProps } = mergedImageProps;
const theme = useTheme();
const syntaxTheme = theme.palette.mode === "dark" ? oneDark : oneLight;
return (
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkMath]}
Expand Down Expand Up @@ -83,6 +86,47 @@ const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({
</div>
);
},
code: ({ node: _node, className, children, ...props }) => {
const langMatch = /language-(\w+)/.exec(className ?? "");
const code = String(children).replace(/\n$/, "");
const isBlock = !!langMatch || code.includes("\n");

if (isBlock) {
return (
<SyntaxHighlighter
language={langMatch?.[1] ?? "text"}
style={syntaxTheme}
customStyle={{
margin: "1rem 0",
borderRadius: "8px",
fontSize: "0.85rem",
}}
wrapLongLines
{...props}
>
{code}
</SyntaxHighlighter>
);
}

return (
<code
className={className}
style={{
backgroundColor:
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.08)"
: "rgba(0, 0, 0, 0.06)",
borderRadius: "4px",
padding: "0.15rem 0.35rem",
fontSize: "0.9em",
}}
{...props}
>
{children}
</code>
);
},
}}
>
{content}
Expand Down
36 changes: 29 additions & 7 deletions frontend/src/pages/home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { Box, Button, Typography } from "@mui/material";
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Typography,
} from "@mui/material";
import Grid from "@mui/material/Grid";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { fetchLeaderboardSummaries } from "../../api/api";
import { fetcherApiCallback } from "../../lib/hooks/useApi";
import { ErrorAlert } from "../../components/alert/ErrorAlert";
import LeaderboardTile from "./components/LeaderboardTile";
import Loading from "../../components/common/loading";
import { ConstrainedContainer } from "../../components/app-layout/ConstrainedContainer";
import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
import MarkdownRenderer from "../../components/markdown-renderer/MarkdownRenderer";
import quickStartMarkdown from "./quick-start.md?raw";

interface TopUser {
rank: number;
Expand All @@ -32,6 +41,7 @@ interface LeaderboardSummaries {

export default function Home() {
const [searchParams] = useSearchParams();
const [isQuickStartOpen, setIsQuickStartOpen] = useState(false);
const useV1 = searchParams.has("v1_query");

const { data, loading, error, errorStatus, call } = fetcherApiCallback<
Expand Down Expand Up @@ -63,10 +73,7 @@ export default function Home() {
<Box sx={{ mb: 4 }}>
<Button
variant="contained"
href="https://github.com/gpu-mode/popcorn-cli"
target="_blank"
rel="noopener"
endIcon={<ArrowOutwardIcon />}
onClick={() => setIsQuickStartOpen(true)}
sx={{
textTransform: "none",
fontWeight: 500,
Expand All @@ -78,6 +85,21 @@ export default function Home() {
</Button>
</Box>

<Dialog
open={isQuickStartOpen}
onClose={() => setIsQuickStartOpen(false)}
maxWidth="md"
fullWidth
>
<DialogTitle>Submit Your First Kernel</DialogTitle>
<DialogContent dividers>
<MarkdownRenderer content={quickStartMarkdown} />
</DialogContent>
<DialogActions>
<Button onClick={() => setIsQuickStartOpen(false)}>Close</Button>
</DialogActions>
</Dialog>

{leaderboards.length > 0 ? (
<Grid container spacing={3}>
{leaderboards.map((leaderboard) => (
Expand Down
25 changes: 25 additions & 0 deletions frontend/src/pages/home/quick-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## 1) Install `popcorn-cli`

```bash
curl -fsSL https://raw.githubusercontent.com/gpu-mode/popcorn-cli/main/install.sh | bash
```

## 2) Register your account

```bash
popcorn-cli register discord
```

## 3) Download a starter kernel

```bash
wget https://raw.githubusercontent.com/gpu-mode/reference-kernels/refs/heads/main/problems/pmpp_v2/grayscale_py/submission.py
```

## 4) Submit to leaderboard

```bash
popcorn-cli submit --gpu A100 --leaderboard grayscale_v2 --mode leaderboard submission.py
```

For a full overview of the commands, check out the [popcorn-cli repo](https://github.com/gpu-mode/popcorn-cli).
Loading