Files
cs249r_book/slides/Makefile
Vijay Janapa Reddi f24f1683da feat(slides): deploy slides portal to dev, add PPTX builds, fix all overfull warnings
- Wire up slides-preview-dev.yml to deploy via SSH (matching labs/kits pattern)
- Add slides/ URL rewrite in book-preview-dev.yml for landing page links
- Add pdf2pptx.py conversion script (pdftoppm + python-pptx, 300 DPI)
- Update Makefile with pptx targets (per-chapter, per-volume, all)
- Update slides-build-pdfs.yml and slides-publish-live.yml to build PPTX
  and include PDF+PPTX ZIP archives in GitHub releases
- Fix all 44 overfull box warnings across 17 Vol1 Beamer decks
- Update slides portal pages with direct per-deck PDF/PPTX download links,
  PPTX column in tables, and remove placeholder callouts
- Update teaching.qmd with PPTX build instructions
- Cross-link slides from instructors hub, getting-started, and both syllabi
2026-03-18 13:58:22 -04:00

305 lines
15 KiB
Makefile

# =============================================================================
# slides/Makefile — Build ML Systems lecture slides
# =============================================================================
# Usage:
# make ch01 Build Chapter 1 PDF
# make all Build all chapters (PDF)
# make pptx Build all PPTX from PDFs
# make pptx-vol1 Build Vol1 PPTX only
# make pptx-ch01 Build Chapter 1 PPTX only
# make svgs Convert all SVGs to PDFs
# make clean Remove build artifacts from source dirs
#
# Build outputs go to _build/vol{1,2}/ (source dirs stay clean).
# PPTX outputs go to _build/vol{1,2}/ alongside PDFs.
# SVG→PDF conversion happens automatically before LaTeX compilation.
# =============================================================================
SHELL := /bin/bash
# Directories
BUILD_DIR := _build
VOL1_SRC := vol1
VOL1_OUT := $(BUILD_DIR)/vol1
VOL2_SRC := vol2
VOL2_OUT := $(BUILD_DIR)/vol2
SCRIPTS := scripts
# All chapter directories (auto-detected)
VOL1_CHAPTERS := $(sort $(notdir $(wildcard $(VOL1_SRC)/*_*)))
VOL2_CHAPTERS := $(sort $(notdir $(wildcard $(VOL2_SRC)/*_*)))
# LaTeX engine
LATEX := xelatex
LATEX_FLAGS := -interaction=nonstopmode -halt-on-error
# SVG converter
SVG2PDF := inkscape --export-type=pdf
# PPTX converter
PDF2PPTX := python3 $(SCRIPTS)/pdf2pptx.py
PPTX_DPI := 300
# =============================================================================
# TARGETS
# =============================================================================
.PHONY: all clean svgs help pptx pptx-vol1 pptx-vol2
help:
@echo "Usage:"
@echo " make ch01 Build Vol1 Chapter 1 (PDF)"
@echo " make v2ch01 Build Vol2 Chapter 1 (PDF)"
@echo " make vol1 Build all Vol1 chapters (PDF)"
@echo " make vol2 Build all Vol2 chapters (PDF)"
@echo " make all Build all chapters (PDF, both volumes)"
@echo " make pptx Build all PPTX from PDFs (both volumes)"
@echo " make pptx-vol1 Build Vol1 PPTX only"
@echo " make pptx-vol2 Build Vol2 PPTX only"
@echo " make pptx-ch01 Build Chapter 1 PPTX only"
@echo " make check Build all + fail if overflows > 10pt"
@echo " make svgs Convert all SVGs to PDFs"
@echo " make clean Remove build artifacts from source dirs"
@echo ""
@echo "Volume I chapters:"
@for ch in $(VOL1_CHAPTERS); do echo " $$ch"; done
@echo ""
@echo "Volume II chapters:"
@for ch in $(VOL2_CHAPTERS); do echo " $$ch"; done
vol1: svgs $(addprefix build-,$(VOL1_CHAPTERS))
vol2: v2ch01 v2ch02 v2ch03 v2ch04 v2ch05 v2ch06 v2ch07 v2ch08 v2ch09 v2ch10 v2ch11 v2ch12 v2ch13 v2ch14 v2ch15 v2ch16 v2ch17
all: vol1 vol2
# =============================================================================
# SVG → PDF conversion (run before any LaTeX build)
# =============================================================================
svgs:
@echo "Converting SVGs to PDFs..."
@find $(VOL1_SRC) $(VOL2_SRC) -name "*.svg" 2>/dev/null | while read svg; do \
pdf="$${svg%.svg}.pdf"; \
if [ ! -f "$$pdf" ] || [ "$$svg" -nt "$$pdf" ]; then \
$(SVG2PDF) --export-filename="$$pdf" "$$svg" 2>/dev/null && echo "$$pdf" || echo "$$svg"; \
fi; \
done
@echo "Done."
# =============================================================================
# Per-chapter build rules
# =============================================================================
# Generic build rule for any chapter
build-%: svgs
@mkdir -p $(VOL1_OUT)
@ch_dir="$(VOL1_SRC)/$*"; \
tex_file=$$(ls $$ch_dir/*.tex 2>/dev/null | head -1); \
if [ -z "$$tex_file" ]; then \
echo "No .tex file found in $$ch_dir"; exit 1; \
fi; \
tex_name=$$(basename $$tex_file .tex); \
echo "Building $$tex_name..."; \
cd $$ch_dir && \
$(LATEX) $(LATEX_FLAGS) $$tex_name.tex > /dev/null 2>&1 && \
$(LATEX) $(LATEX_FLAGS) $$tex_name.tex > /dev/null 2>&1 && \
echo "$$tex_name.pdf (pass 2)" || \
{ echo " ✗ Build failed. Check $$ch_dir/$$tex_name.log"; exit 1; }; \
cd - > /dev/null; \
cp $$ch_dir/$$tex_name.pdf $(VOL1_OUT)/$$tex_name.pdf; \
echo "$(VOL1_OUT)/$$tex_name.pdf"; \
echo ""; \
overfull=$$(grep -c "Overfull" $$ch_dir/$$tex_name.log 2>/dev/null || echo 0); \
underfull=$$(grep -c "Underfull" $$ch_dir/$$tex_name.log 2>/dev/null || echo 0); \
if [ "$$overfull" -gt 0 ]; then \
echo "$$overfull overfull boxes:"; \
grep "Overfull" $$ch_dir/$$tex_name.log | sed 's/^/ /' | head -10; \
echo ""; \
fi; \
if [ "$$overfull" -eq 0 ] && [ "$$underfull" -eq 0 ]; then \
echo " ✓ No overflow warnings"; \
fi; \
cd $$ch_dir && rm -f *.aux *.nav *.out *.snm *.toc *.vrb *.fls *.fdb_latexmk *.synctex.gz $$tex_name.pdf && cd - > /dev/null; \
if [ "$$overfull" -gt 5 ]; then \
echo " ⛔ Too many overflows ($$overfull) — review slide content"; \
fi
# Convenience aliases: ch01, ch02, ..., ch16
ch01: build-01_introduction
ch02: build-02_ml_systems
ch03: build-03_ml_workflow
ch04: build-04_data_engineering
ch05: build-05_nn_computation
ch06: build-06_nn_architectures
ch07: build-07_frameworks
ch08: build-08_training
ch09: build-09_data_selection
ch10: build-10_model_compression
ch11: build-11_hw_acceleration
ch12: build-12_benchmarking
ch13: build-13_model_serving
ch14: build-14_ml_ops
ch15: build-15_responsible_engr
ch16: build-16_conclusion
# =============================================================================
# Volume II: Per-chapter build rules
# =============================================================================
# Helper function for building any chapter from any volume source dir
# Usage: $(call build-chapter,SOURCE_DIR,OUTPUT_DIR,CHAPTER_DIR)
define build-chapter-impl
@mkdir -p $(2)
@ch_dir="$(1)/$(3)"; \
tex_file=$$(ls $$ch_dir/*.tex 2>/dev/null | head -1); \
if [ -z "$$tex_file" ]; then \
echo "No .tex file found in $$ch_dir"; exit 1; \
fi; \
tex_name=$$(basename $$tex_file .tex); \
echo "Building $$tex_name..."; \
cd $$ch_dir && \
$(LATEX) $(LATEX_FLAGS) $$tex_name.tex > /dev/null 2>&1 && \
$(LATEX) $(LATEX_FLAGS) $$tex_name.tex > /dev/null 2>&1 && \
echo "$$tex_name.pdf (pass 2)" || \
{ echo " ✗ Build failed. Check $$ch_dir/$$tex_name.log"; exit 1; }; \
cd - > /dev/null; \
cp $$ch_dir/$$tex_name.pdf $(2)/$$tex_name.pdf; \
echo "$(2)/$$tex_name.pdf"; \
echo ""; \
overfull=$$(grep -c "Overfull" $$ch_dir/$$tex_name.log 2>/dev/null || echo 0); \
underfull=$$(grep -c "Underfull" $$ch_dir/$$tex_name.log 2>/dev/null || echo 0); \
if [ "$$overfull" -gt 0 ]; then \
echo "$$overfull overfull boxes:"; \
grep "Overfull" $$ch_dir/$$tex_name.log | sed 's/^/ /' | head -10; \
echo ""; \
fi; \
if [ "$$overfull" -eq 0 ] && [ "$$underfull" -eq 0 ]; then \
echo " ✓ No overflow warnings"; \
fi; \
cd $$ch_dir && rm -f *.aux *.nav *.out *.snm *.toc *.vrb *.fls *.fdb_latexmk *.synctex.gz $$tex_name.pdf && cd - > /dev/null; \
if [ "$$overfull" -gt 5 ]; then \
echo " ⛔ Too many overflows ($$overfull) — review slide content"; \
fi
endef
# Convenience aliases: v2ch01, v2ch02, ..., v2ch17
# Each target explicitly calls the build function with vol2 paths
v2ch01: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),01_introduction)
v2ch02: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),02_compute_infrastructure)
v2ch03: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),03_network_fabrics)
v2ch04: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),04_data_storage)
v2ch05: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),05_distributed_training)
v2ch06: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),06_collective_communication)
v2ch07: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),07_fault_tolerance)
v2ch08: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),08_fleet_orchestration)
v2ch09: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),09_inference)
v2ch10: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),10_performance_engineering)
v2ch11: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),11_edge_intelligence)
v2ch12: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),12_ops_scale)
v2ch13: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),13_security_privacy)
v2ch14: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),14_robust_ai)
v2ch15: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),15_sustainable_ai)
v2ch16: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),16_responsible_ai)
v2ch17: svgs ; $(call build-chapter-impl,$(VOL2_SRC),$(VOL2_OUT),17_conclusion)
# =============================================================================
# PPTX conversion (PDF → PowerPoint, image-based)
# =============================================================================
pptx: pptx-vol1 pptx-vol2
pptx-vol1: vol1
@echo "Converting Vol1 PDFs to PPTX..."
@$(PDF2PPTX) $(VOL1_OUT)/*.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-vol2: vol2
@echo "Converting Vol2 PDFs to PPTX..."
@$(PDF2PPTX) $(VOL2_OUT)/*.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
# Per-chapter PPTX: pptx-ch01, pptx-ch02, ..., pptx-v2ch01, ...
pptx-ch01: ch01 ; @$(PDF2PPTX) $(VOL1_OUT)/01_introduction.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch02: ch02 ; @$(PDF2PPTX) $(VOL1_OUT)/02_ml_systems.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch03: ch03 ; @$(PDF2PPTX) $(VOL1_OUT)/03_ml_workflow.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch04: ch04 ; @$(PDF2PPTX) $(VOL1_OUT)/04_data_engineering.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch05: ch05 ; @$(PDF2PPTX) $(VOL1_OUT)/05_nn_computation.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch06: ch06 ; @$(PDF2PPTX) $(VOL1_OUT)/06_nn_architectures.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch07: ch07 ; @$(PDF2PPTX) $(VOL1_OUT)/07_frameworks.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch08: ch08 ; @$(PDF2PPTX) $(VOL1_OUT)/08_training.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch09: ch09 ; @$(PDF2PPTX) $(VOL1_OUT)/09_data_selection.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch10: ch10 ; @$(PDF2PPTX) $(VOL1_OUT)/10_model_compression.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch11: ch11 ; @$(PDF2PPTX) $(VOL1_OUT)/11_hw_acceleration.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch12: ch12 ; @$(PDF2PPTX) $(VOL1_OUT)/12_benchmarking.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch13: ch13 ; @$(PDF2PPTX) $(VOL1_OUT)/13_model_serving.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch14: ch14 ; @$(PDF2PPTX) $(VOL1_OUT)/14_ml_ops.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch15: ch15 ; @$(PDF2PPTX) $(VOL1_OUT)/15_responsible_engr.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-ch16: ch16 ; @$(PDF2PPTX) $(VOL1_OUT)/16_conclusion.pdf --output-dir $(VOL1_OUT) --dpi $(PPTX_DPI)
pptx-v2ch01: v2ch01 ; @$(PDF2PPTX) $(VOL2_OUT)/01_introduction.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch02: v2ch02 ; @$(PDF2PPTX) $(VOL2_OUT)/02_compute_infrastructure.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch03: v2ch03 ; @$(PDF2PPTX) $(VOL2_OUT)/03_network_fabrics.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch04: v2ch04 ; @$(PDF2PPTX) $(VOL2_OUT)/04_data_storage.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch05: v2ch05 ; @$(PDF2PPTX) $(VOL2_OUT)/05_distributed_training.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch06: v2ch06 ; @$(PDF2PPTX) $(VOL2_OUT)/06_collective_communication.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch07: v2ch07 ; @$(PDF2PPTX) $(VOL2_OUT)/07_fault_tolerance.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch08: v2ch08 ; @$(PDF2PPTX) $(VOL2_OUT)/08_fleet_orchestration.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch09: v2ch09 ; @$(PDF2PPTX) $(VOL2_OUT)/09_inference.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch10: v2ch10 ; @$(PDF2PPTX) $(VOL2_OUT)/10_performance_engineering.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch11: v2ch11 ; @$(PDF2PPTX) $(VOL2_OUT)/11_edge_intelligence.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch12: v2ch12 ; @$(PDF2PPTX) $(VOL2_OUT)/12_ops_scale.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch13: v2ch13 ; @$(PDF2PPTX) $(VOL2_OUT)/13_security_privacy.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch14: v2ch14 ; @$(PDF2PPTX) $(VOL2_OUT)/14_robust_ai.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch15: v2ch15 ; @$(PDF2PPTX) $(VOL2_OUT)/15_sustainable_ai.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch16: v2ch16 ; @$(PDF2PPTX) $(VOL2_OUT)/16_responsible_ai.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
pptx-v2ch17: v2ch17 ; @$(PDF2PPTX) $(VOL2_OUT)/17_conclusion.pdf --output-dir $(VOL2_OUT) --dpi $(PPTX_DPI)
# =============================================================================
# Clean build artifacts from source directories (keep them pristine)
# =============================================================================
clean:
@echo "Cleaning build artifacts from source directories..."
@find $(VOL1_SRC) $(VOL2_SRC) -type f \( \
-name "*.aux" -o -name "*.log" -o -name "*.nav" -o \
-name "*.out" -o -name "*.snm" -o -name "*.toc" -o \
-name "*.vrb" -o -name "*.fls" -o -name "*.fdb_latexmk" -o \
-name "*.synctex.gz" -o -name "*.bbl" -o -name "*.blg" \
\) -delete 2>/dev/null
@find $(VOL1_SRC) $(VOL2_SRC) -name "*.pdf" ! -path "*/images/*" -delete 2>/dev/null
@rm -rf $(BUILD_DIR)
@echo "Done. Source directories and build output are clean."
# =============================================================================
# Quality check: build + fail on significant overflows (> 10pt)
# =============================================================================
MAX_OVERFLOW := 10
check: svgs
@echo "Building with overflow check (max $(MAX_OVERFLOW)pt)..."
@fail=0; \
for ch_dir in $(VOL1_SRC)/*_*/ $(VOL2_SRC)/*_*/; do \
[ -d "$$ch_dir" ] || continue; \
tex_file=$$(ls $$ch_dir/*.tex 2>/dev/null | head -1); \
[ -z "$$tex_file" ] && continue; \
tex_name=$$(basename $$tex_file .tex); \
cd $$ch_dir && \
$(LATEX) $(LATEX_FLAGS) $$tex_name.tex > /dev/null 2>&1 && \
$(LATEX) $(LATEX_FLAGS) $$tex_name.tex > /dev/null 2>&1; \
bad=$$(grep "Overfull" $$tex_name.log 2>/dev/null | \
sed 's/.*(\([0-9]*\)\..*/\1/' | \
awk '{ if ($$1 > $(MAX_OVERFLOW)) print }' | wc -l | tr -d ' '); \
if [ "$$bad" -gt 0 ]; then \
echo "$$tex_name: $$bad overflows > $(MAX_OVERFLOW)pt"; \
grep "Overfull" $$tex_name.log | sed 's/^/ /'; \
fail=1; \
else \
echo "$$tex_name"; \
fi; \
rm -f *.aux *.log *.nav *.out *.snm *.toc *.vrb *.fls *.fdb_latexmk *.synctex.gz $$tex_name.pdf; \
cd - > /dev/null; \
done; \
if [ "$$fail" -eq 1 ]; then \
echo ""; echo "⛔ FAILED: Some slides have overflows > $(MAX_OVERFLOW)pt"; exit 1; \
else \
echo ""; echo "✓ All slides pass overflow check"; \
fi