Training and inference frameworks, tensor and kernel code, ML platforms and pipelines.
343 instructions from 14 repositories. Last updated 2026-04-28.
Avoid “config monsters” by limiting new runtime knobs and centralizing stable defaults. Only add CLI/config parameters when they materially change behavior across experiments; otherwise, bake them into the existing config (or the run script) and reuse current config locations rather than introducing new config modules for a few constants. For evaluation-critical settings, explicitly pin values and avoid hidden coupling between constants.
Apply:
VAL_SHARD_INDEX = 1822) rather than tying them indirectly to other values that might change.choices) so invalid settings fail fast.Example (CLI boundary + baked/stable defaults):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--device', type=str, default='cuda', choices=['mps','cuda'])
# Keep eval config explicit and stable
VAL_SHARD_INDEX = 1822
Adopt explicit compatibility guards in PyTorch code to prevent silent numeric issues and runtime failures across devices, PyTorch versions, and compilation modes.
Apply these rules:
torch.compile tracing.Example pattern (combine the above):
import torch
import torch.nn.functional as F
# 1) Explicit init
# self.smear_lambda is a Parameter or buffer newly added
# Always initialize deterministically.
torch.nn.init.zeros_(self.smear_lambda)
# 2) Version/API fallback
def norm(x):
if hasattr(F, "rms_norm"):
return F.rms_norm(x, (x.size(-1),))
# fallback implementation (placeholder)
return x * 1.0
# 3) Safe dynamic cache update with compile guard
def ensure_rope_cache(model, needed_seq_len: int, device: torch.device):
cur_len = model.cos.size(1)
if needed_seq_len <= cur_len:
return
try:
import torch._dynamo
if torch._dynamo.is_compiling():
raise RuntimeError("RoPE cache growth during torch.compile is unsafe; pre-size or disable compile.")
except Exception:
pass
new_len = 1 << (needed_seq_len - 1).bit_length()
head_dim = model.config.n_embd // model.config.n_head
cos, sin = model._precompute_rotary_embeddings(seq_len=new_len, head_dim=head_dim, device=device)
# preserve invariants and overwrite existing registered tensors
cos = cos.to(dtype=model.cos.dtype, device=device)
sin = sin.to(dtype=model.sin.dtype, device=device)
model.cos = cos
model.sin = sin
This standard reduces runtime surprises (especially on MPS), keeps numerics stable when adding parameters, and prevents compilation/tracing issues when using dynamic tensor caches.
When implementing performance-critical algorithms (e.g., pooling, math kernels, SIMD/ISA code), preserve the algorithm’s true numeric semantics and parameterization:
1) Match rounding/truncation semantics with the ISA’s exact instruction
static inline float32x4_t trunc_ps(const float32x4_t& x)
{
#if __aarch64__
return vrndq_f32(x); // trunc toward zero
#else
// fallback, but verify it matches trunc-toward-zero semantics
int32x4_t xi = vcvtq_s32_f32(x);
return vcvtq_f32_s32(xi);
#endif
}
2) Don’t “constant-fold” parameters that are mathematically location-dependent
3) Add a quick correctness checklist during review
Applying this standard prevents cross-architecture drift (wrong rounding) and algorithm drift (wrong kernel sizes), which are frequent root causes of subtle accuracy regressions in algorithmic code paths.
When implementing algorithmic “pick/keep/max” logic, make the selected set deterministic and the ordering explicit—then compute sort/max keys using robust parsing.
Apply:
range(n)) is already unique and ordered, don’t add set() or extra sorted() just to satisfy uniqueness.Path/stem/name and direct stat().st_mtime for sort keys; keep parsing aligned with how files are named/saved.Example (ids construction and checkpoint step selection):
# Deterministic, minimal ordering
ids_to_download = list(range(num))
if VAL_SHARD_INDEX not in ids_to_download:
ids_to_download.append(VAL_SHARD_INDEX)
ids_to_download.sort() # only if you must re-establish order
# Robust parsing + max selection
checkpoint_files = list(checkpoint_dir.glob('model_*.pt'))
last_step = int(max(f.stem.split('_')[-1] for f in checkpoint_files))
When an operation can fail in a known way (edge-case inputs, risky math, I/O/parsing, optional capabilities), handle it explicitly:
except Exception that unintentionally swallows the error you meant to surface).Example (defensive guard + clean recovery):
num_tokens = torch.tensor(0, device=device)
steps = [next(train_loader) for _ in range(grad_accum_steps)]
num_tokens += sum((targets >= 0).sum() for _, targets in steps)
# (optional) sync across ranks
if ddp:
dist.all_reduce(num_tokens, op=dist.ReduceOp.SUM)
# prevent NaN loss
if num_tokens.item() == 0:
model.zero_grad(set_to_none=True)
# skip this accumulation window
return
for train_inputs, train_targets in steps:
loss = model(train_inputs, train_targets, loss_reduction='sum')
loss = loss / num_tokens
loss.backward()
Example (don’t swallow intended errors):
# WRONG: throws, then immediately swallows everything
try:
raise RuntimeError("something important")
except Exception:
pass
# RIGHT: either remove the throw/silencing, or narrow the exception
try:
import torch._dynamo
if torch._dynamo.is_compiling():
raise RuntimeError("RoPE cache too small during torch.compile")
except ImportError:
# only ignore the missing module case
pass
Example (cleanup on integrity failure):
Apply this consistently across training loops, dataset download/verification, and state load paths.
When touching code that formats output or builds paths, keep it idiomatic and repo-consistent:
Path, build derived paths with Path operators (base / name, with_name) instead of os.path.join.int(round(x)) when round(x) already returns an int).Example (readable conditional print):
print_grad_norm = ""
if grad_clip > 0.0:
print_grad_norm = f"grad_norm: {grad_norm.item():.5f} | "
print0(
f"step {step:05d}/{num_iterations:05d} ({pct_done:.2f}%) | "
f"loss: {debiased_smooth_loss:.6f} | "
f"{print_grad_norm}"
f"lrm: {lrm:.2f} | dt: {dt * 1000:.2f}ms | tok/sec: {tok_per_sec:,} | "
f"mfu: {mfu:.2f} | total time: {total_training_time/60:.2f}m"
)
Example (Path composition):
checkpoints_dir = base_dir / model_dir # when base_dir is a Path
lock_path = file_path.with_name(f"{file_path.name}.lock")
When optimizing for speed, make the fast path both correct for the actual hardware and lightweight in implementation.
1) Keep kernel support documentation accurate and capability-aware
Example (pattern):
# Supported FA3 archs reflect what kernels are compiled for
# sm90 (Hopper), sm89 (Ada), sm80/sm86 (Ampere)
# sm100 (Blackwell): fallback to SDPA until FA3 is recompiled
def _load_flash_attention_3():
if not torch.cuda.is_available():
return None
# ... select FA3 vs fallback based on device capability ...
2) Avoid unnecessary overhead in parsing/utility code
model_<step>.pt, prefer simple split/string ops over regex.basename) when you already operate on plain filenames.Example (pattern):
# checkpoint_files contains only filenames like model_123456.pt
last_step = int(max(f.split("_")[-1].split(".")[0] for f in checkpoint_files))
Result: faster execution with fewer CPU-side bottlenecks, and fewer correctness surprises caused by stale/incorrect hardware assumptions.
Ensure GitHub Actions CI runs are repeatable, targeted, and don’t rely on brittle hacks.
1) Run tests using the environment you just prepared
uv sync, run pytest using the created venv/python (or otherwise guarantee uv run uses the synced environment without re-installing).2) Install the project instead of mutating PYTHONPATH
name: Set up uv uses: astral-sh/setup-uv@v7
name: Install dependencies run: | uv sync –extra cpu uv pip install -e . # CPU-only torch for Linux runners without CUDA uv pip install torch torchvision –index-url https://download.pytorch.org/whl/cpu
3) Keep workflows minimal and aligned with support
on.push to master/main (and use pull_request for PR validation) rather than running on every branch push.if: conditions for OSes not in the matrix.Applying this prevents CI flakiness from environment mismatches, reduces “works on my machine” import issues, and cuts unnecessary CI load.
Apply a single, repeatable style checklist across all new/modified code:
1) Remove unused/redundant code
#includes and unused variables.2) Keep compiler/standard compatibility
{...} initializer lists).for if the codebase/toolchain constraints require explicit indexing.const T t = {}; over uninitialized default construction).3) Factor preprocessor/SIMD-heavy logic for readability
#if/#ifdef blocks for SSE/AVX/AVX512, move the implementation into small helper functions (e.g., packA_*, packB_*, subkernel_*) so the main algorithm focuses on tiling/control flow.4) Enforce formatting conventions
// comment with a space; keep meaningful text aligned with code).#if vs #ifdef) and consistent patterns.(void)opt;).Example (SIMD factoring)
static void packA_sse(const float* src, float* dst, int k, const Option& opt);
static void packA_avx(const float* src, float* dst, int k, const Option& opt);
for (int i = 0; i < M; i += TILE_M)
{
// keep tiling/control logic here
if (j == 0)
{
#if __SSE2__
#if __AVX__
packA_avx(A_ptr, AT_ptr, k, opt);
#else
packA_sse(A_ptr, AT_ptr, k, opt);
#endif
#endif
}
}
Rule: choose concise, semantically accurate, and responsibility-respecting names for identifiers (variables, functions, classes, modules). Motivation: clear names reduce cognitive load, avoid ambiguity, and prevent leaking responsibilities across layers.
Guidelines:
Code examples:
Application checklist for reviewers:
References: discussion indices [0,1,3,4,6,7,8,10,11,12,13].
Summary
Why this matters
How to apply (concrete rules) 1) Ownership — plugin-provided defaults and metadata
Example pattern (plugin exposes defaults): class MyPluginSettings(BaseModel): markers: list[str]
class MyPlugin: @classmethod def default_settings(cls) -> MyPluginSettings: return MyPluginSettings(markers=[“I refuse”, “sorry”])
2) Deterministic checkpointing and resume
3) Explicit, scoped configuration for non-obvious choices
4) Avoid silent platform/environment heuristics
5) Structured config types and robust parsing
6) Precedence and sources
7) Prefer maintained utilities over ad-hoc checks
Checklist for code reviewers
Applying these rules will reduce configuration drift, improve reproducibility (especially for resumable experiments), and make the system easier to understand and extend by ensuring clear ownership and deterministic behavior.
When adding or changing model loading, quantization, LoRA/abliteration logic, or merging behavior, follow these explicit rules to ensure correctness, compatibility and reproducibility.
1) Explicit quantization and dtype handling
Example: quant_cfg = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16, …)
2) LoRA adapter configuration and scaling
3) Row normalization / magnitude preservation modes
Snippet (FULL flow outline): W = W_org.view(W.shape[0], -1) W = W + lora_B @ lora_A W = F.normalize(W, p=2, dim=1) W = W * W_row_norms W = W - W_org U, S, Vh = torch.svd_lowrank(W, q=2*r+4)
lora_B = U[:, :r] @ diag(sqrt_S) lora_A = diag(sqrt_S) @ Vh[:r, :]
4) Compatibility & hybrid fallback
5) Safe merging for quantized models
6) Data processing and diagnostics
7) UX, tests, and diagnostics
Why this matters (motivation)
References: discussions about LoRA scaling, normalization and merging, quantization config and compute dtype, hybrid compatibility and PEFT unwrapping, winsorization axis and testing guidance (see source discussions).
When writing run/config scripts, prefer local, opt-in environment changes and guarded defaults.
Rules
~/.bashrc/~/.profile). If you need PATH changes, set them for the current process only (e.g., export PATH=... inside the script).Example pattern
#!/usr/bin/env bash
set -euo pipefail
# Local PATH change (no ~/.bashrc mutation)
if command -v uv &>/dev/null; then :; else
curl -LsSf https://astral.sh/uv/install.sh | sh
fi
export PATH="$HOME/.local/bin:$PATH"
# Conditional system dependency (only if missing)
if ! dpkg -s python3-dev &>/dev/null; then
echo "Installing python3-dev (needed for Python.h during compilation)"
sudo apt-get update && sudo apt-get install -y python3-dev
fi
# Hardware override: opt-in via env var
# e.g. export HSA_OVERRIDE_GFX_VERSION=11.0.0 before running if needed
: "${HSA_OVERRIDE_GFX_VERSION:=}"
if [ -n "${HSA_OVERRIDE_GFX_VERSION}" ]; then
export HSA_OVERRIDE_GFX_VERSION
fi
exec python3 -m your_program "$@"
Applying this standard reduces cross-environment breakage (VM/container/bare metal), prevents unintended side effects on developers’ shells, and avoids configuration values that can harm unsupported hardware.
Motivation: Large models and matrix ops can produce big ephemeral tensors, cross-device copies, and temporary allocations that lead to excessive memory use or OOMs. Adopt consistent, device-aware tensor handling, prefer built-in ops, and free large temporaries at clear boundaries.
Guidelines:
Avoid unnecessary copies: use Tensor.to(dtype, copy=True) when you need a guaranteed new tensor; skip copying if you don’t perform in-place mutation. Example: W = base_weight.to(torch.float32, copy=True) # only if you will modify W in-place
Use built-in numeric primitives where possible (F.normalize, torch.linalg.vector_norm, etc.) instead of brittle manual clamps. Prefer out= variants if you truly need to avoid temporaries. Example: F.normalize(W, p=2, dim=1, out=W) # in-place normalization to save allocs when safe
Be device-aware: move small helpers to the target tensor’s device before heavy ops to avoid implicit cross-device copies. Example: device_projector = projector.to(matrix.device) matrix.sub_(weight * (device_projector @ matrix))
Free large temporaries at well-defined lifecycle boundaries (model reload, merge/save, end of trial). If you observe OOMs or large resident memory, explicitly delete big objects and force collection: Example: del merged_model import gc, torch gc.collect() torch.cuda.empty_cache() Use these only at boundaries where large tensors are no longer needed; don’t sprinkle gc.collect() indiscriminately.
Profile expensive steps (e.g., low-rank SVD) before tuning: measure runtime and only reduce accuracy parameters (q, niter, rank) if they meaningfully affect end-to-end time/quality.
When to use which pattern:
Result: following these practices reduces peak/resident memory, avoids hidden cross-device allocations, and keeps heavy numeric code both readable and efficient.
Define a clear, minimal plugin contract and loader API for all external/ built-in plugins. Motivation: plugins (taggers/scorers) are the public extension points of the system and must declare what data they need, how they initialize, and be loadable from arbitrary modules so users can provide custom implementations without modifying the project.
Rules and how to apply them:
Declarative requirements: each plugin class must provide classmethods that declare required fields. Example methods: required_response_metadata_fields() -> list[str], required_context_metadata_fields() -> list[str]. The core app will call these before invoking the plugin and instruct the Model to only return requested fields.
Optional heavy fields: plugins must indicate whether they need the full response text or only a prefix/n tokens. Make this configurable so the model can avoid returning expensive data when unnecessary (e.g., include_text() -> bool or text_token_limit() -> int).
Settings schema: plugins may declare a pydantic BaseModel subclass as settings to validate plugin-specific configuration. The loader should instantiate plugin settings from the global config.
Lifecycle hooks and validation: enforce a small lifecycle surface. Plugins must not define init(); instead provide an init(ctx) -> None hook for initialization and an optional start(ctx) for runtime setup. Provide a validate_contract() classmethod that the loader calls to enforce these rules and raise clear errors.
| Keep APIs minimal and consistent: plugin methods should accept explicit typed objects, not ad-hoc arg lists. Use small domain objects like Response and Context rather than multiple parallel arguments. Example Response: Response(text: str | None, metadata: dict[str, Any], tokens: Optional[list[int]]). Make fields optional and typed so callers know what’s available. |
Example usage (illustrative):
class MyTagger(TaggerBase): @classmethod def required_response_metadata_fields(cls) -> list[str]: return [“logprobs”, “finish_reason”]
@classmethod
def include_text(cls) -> bool:
return False # avoids returning full text when not needed
@classmethod
def validate_contract(cls) -> None:
# ensure no __init__ and required methods exist
...
def init(self, ctx: Context) -> None:
# optional initialization using provided Context
...
def tag_batch(self, responses: list[Response]) -> list[dict[str, float]]:
...
plugin_cls = load_plugin(name=settings.tagger) # accepts package name or module:path plugin_cls.validate_contract() model.set_requested_response_fields(plugin_cls.required_response_metadata_fields()) model.set_requested_context_fields(plugin_cls.required_context_metadata_fields()) plugin = plugin_cls(settings=settings, model=model, context_metadata=model.get_context_metadata()) plugin.init(Context(settings=settings, model=model))
Rationale: This rule prevents fragile implicit contracts, avoids unnecessary data transfers (performance), enables third-party plugin distribution without altering core code, and makes plugin initialization predictable and testable. Following it reduces bugs from mismatched expectations (missing fields, incorrect init semantics, hardcoded package names) and simplifies upgrading third-party libraries by keeping argument names and responsibilities explicit.
Keep code organized by responsibility and centralize reusable logic. Concretely:
Centralize helpers: move shared implementations (plugin loading, dataset parsing, prompt helpers, is_notebook, prompt wrappers, etc.) into a single utils or plugin package and import them from one place. Avoid copy-pasting variations of the same logic across files — this prevents drift, duplicate bugs, and inconsistent behavior (see plugin loaders and load_prompts). Example consolidation: replace duplicated _load_tagger_plugin/_load_scorer_plugin logic with a single load_plugin utility used by Evaluator.
Example pattern:
| utils.load_plugin(name: str, base_cls: type) -> type | instance |
Enforce separation of concerns: keep UI and interaction code in the CLI layer (main.py); core classes (Model, Evaluator, Scorer) should expose well-typed methods and not prompt the user or perform I/O. If an operation needs user input, prompt in main then call a Model/Evaluator method with the chosen parameters (e.g., prompt in main, then call model.get_merged_model(strategy)).
Preserve strong typing and clear APIs when refactoring: keep explicit attributes and return types on public classes (avoid silently removing typed fields or returning ambiguous types). Use pydantic/BaseModel types for plugin settings and declare function return types so static checkers catch regressions.
Reduce duplication and improve resource handling: reuse existing computations (e.g., max_memory), consolidate is_notebook implementations, and avoid relying on del for cleanup — use context managers or explicit close/unlink behavior.
Small style rules that follow from organization: place imports at the top of modules, prefer named arguments (e.g., dim=…), remove unused imports, and use single authoritative helper functions rather than many inline special cases.
How to apply:
Benefits: improved readability, fewer subtle behavioral regressions, simpler testing, and stronger static typing — all aligning with code style and maintainability goals.
Provide a clear, stable, and discoverable configuration schema. Apply the following rules to all TOML/environment configs:
1) Use self-documenting values
scorers = [ { plugin = “heretic.scorers.refusal_rate.RefusalRate”, direction = “MINIMIZE”, scale = 1.0 } ]
quantization_method = “bnb_4bit” # instead of load_in_4bit = true
2) Encode mutually exclusive or dependent options as a single enum
| row_normalization = “none” | “row_normalize” | “row_normalize_and_restore_magnitudes” |
3) Standardize plugin-scoped tables and plugin import paths
[scorer.RefusalRate]
[scorer.RefusalRate_instanceA]
tagger = “heretic.taggers.keyword.KeywordRefusalDetector”
4) Validate and warn on conflicts or removed/renamed keys
5) Maintain backward-compatibility with deprecation policy
How to apply in practice
Example (combined TOML):
scorers = [ { plugin = “heretic.scorers.refusal_rate.RefusalRate”, direction = “MINIMIZE”, scale = 1.0 } ]
tagger = “heretic.taggers.keyword.KeywordRefusalDetector”
[scorer.RefusalRate] good_evaluation_prompts = { dataset = “mlabonne/harmless_alpaca”, split = “test[:100]”, column = “text” }
quantization_method = “bnb_4bit” row_normalization = “row_normalize_and_restore_magnitudes”
References: discussions 0–7.
Rule: Fail fast, validate assumptions, and distinguish user cancellation.
Motivation
How to apply
Don’t swallow exceptions silently. If a library call or validation can fail, either let the exception propagate or catch it and re-raise with additional context. Only catch exceptions when you can meaningfully handle or recover; otherwise surface them to the caller/user. Example: remove broad try/except that hides JSON validation errors and instead let it fail with context. Bad: try: old_settings = Settings.model_validate_json(previous_settings) can_resume = True except ValidationError: can_resume = False
Good: old_settings = Settings.model_validate_json(previous_settings) # raises on error — user sees the problem
Treat user cancellation distinctly. Do not conflate None/empty input with a legitimate selection. If a prompt returns None (e.g., Ctrl+C), cancel the current operation or surface that the user aborted instead of picking a default value or exiting the program unexpectedly. Example: merge_choice = prompt_select(…) if merge_choice is None: # user cancelled — abort or ask again, do not treat as “adapter” raise UserCancelledError(“merge aborted by user”)
Why this matters
Follow-up checklist for code reviewers
References: 1,2,3,4,5,6,7,8,9,10,11
Treat None/absent values explicitly and guard attribute access.
Motivation: user input, storage APIs, optional configuration, and runtime objects can all produce None or lack expected attributes. Implicitly assuming presence leads to data loss (e.g., deleting checkpoints on a cancelled prompt), brittle logic, and runtime errors.
Rules and how to apply them:
Use Optional typing to model nullable semantics and document what None means. Prefer existing option types over ad-hoc enums/sentinels. Example: ObjectiveDirection: use optuna.StudyDirection | None where None = “do not optimize”.
Always check return values that can be None before acting. For interactive prompts or library calls that may return None (e.g., user cancels), handle the None case explicitly instead of treating it as a valid choice. Example: choice = prompt_select(“What do you want to do?”, choices) if choice is None: print(“Operation cancelled”) return if choice == “continue”: …
When reading from storage/APIs, distinguish between None and empty collections and fail fast if invariants are violated. Prefer explicit checks over assumptions like “there is always one study”. Example: try: study_id = storage.get_study_id_from_name(“heretic”) except KeyError: study_id = None if study_id is None: # no study — handle cleanly
Guard attribute access on heterogeneous runtime objects. Use hasattr/isinstance checks or explicit casting/typing before accessing .weight, .device, or plugin class attributes. Example: if hasattr(module, “weight”): v = layer_refusal_direction.to(module.weight.device) else: # handle tensor or non-weight module path
Rely on framework validation (e.g., pydantic.model_validate) for defaults, but still verify the validated object is present and of the expected type before use. Example: settings_obj = Settings.model_validate_json(maybe_previous_settings) if settings_obj is None: # handle missing or invalid settings
Fail fast and be explicit: if an assumption about presence/shape/type is critical and violated, raise a clear error instead of proceeding silently.
Benefits: reduces accidental data loss, prevents unexpected None-driven behavior, makes control flow explicit, and improves safety when interacting with external APIs and heterogeneous objects.
When implementing or changing optimization code (samplers, objectives, and result selection), ensure algorithmic correctness, preserve sampler assumptions, and prefer explicit post-processing over ad‑hoc objective hacks.
Why: Incorrect assumptions about samplers, unclear trial counting, off-by-one indexing, or hidden objective tweaks can silently break search quality or produce confusing results. The rule reduces bugs and makes behavior auditable.
Checklist (practical actions):
When to apply: any change touching sampling logic, objective computation, trial bookkeeping, or final selection of best trials. Following this guidance improves correctness, reproducibility, and debuggability of optimization code.
When constructing filesystem paths or filenames from external input (model names, user-provided identifiers, etc.), treat those strings as untrusted. Whitelist allowed characters, disallow dots and path separators, and verify the final path stays inside the intended directory to prevent path traversal or accidental file access/deletion.
Why: Allowing ‘.’ or path separators can enable path traversal (e.g., “model/../../path”) or surprising behavior later if code changes. This is a security vulnerability and should be mitigated by input validation and path containment checks.
How to apply:
Example (based on the discussion):
import os import re
ALLOWED = re.compile(r”^[A-Za-z0-9_-]+$”) # note: no dot
def safe_name(name): if not ALLOWED.match(name): raise ValueError(“invalid name”) return name
base_dir = settings.study_checkpoint_dir user_name = safe_name(model_name) filename = os.path.join(base_dir, user_name + “.json”)
norm_base = os.path.normpath(base_dir) norm_path = os.path.normpath(filename) if not norm_path.startswith(norm_base + os.path.sep) and norm_path != norm_base: raise ValueError(“resulting path escapes base directory”)
References: discussion indices [0].
When working on LLM inference/engines, ensure (1) determinism tests actually test the intended invariants, (2) optional GPU-accelerated kernels are only loaded when the hardware supports them (with a safe fallback), and (3) KV-cache shape assumptions are documented accurately.
prompt = [261, 72, 101, 108, 108, 111]
engine = Engine(MockModel(), ByteTokenizer())
r1, _ = engine.generate_batch(prompt, temperature=0.0, max_tokens=5, seed=1)
r2, _ = engine.generate_batch(prompt, temperature=0.0, max_tokens=5, seed=42)
r3, _ = engine.generate_batch(prompt, temperature=0.0, max_tokens=5, seed=123)
assert r1 == r2 == r3
flash_attn = None
if torch.cuda.is_available():
if torch.cuda.get_device_capability()[0] >= 9:
flash_attn = get_kernel('varunneal/flash-attention-3').flash_attn_interface
else:
import flash_attn_interface as flash_attn # fallback
Prefer clear, consistent, and semantic names for variables, classes, config keys, and section labels. Use these concrete rules when naming:
scorers = [ [“heretic.scorers.count_refusals.CountRefusals”, “minimize”, 1.0] ]
scorers = [ [“heretic.scorers.refusal_rate.RefusalRate”, “minimize”, 1.0] ]
Make units explicit in the name when scale matters (Rate, Count, Score, Probability). If a value depends on dataset size, prefer a rate or normalized form.
[scorer.RefusalRate] threshold = 0.05
abliteration_orthogonal_project = false abliteration_preserve_magnitude = false
orthogonalize_direction = false preserve_magnitudes = false
Checklist to apply during review:
Following these rules reduces ambiguity, makes configuration values interpretable (especially scales), and keeps naming consistent across code and config.
When code depends on environment/build features (SIMD/FP16 availability, OpenCV versioned APIs, packing layout support, OS/ABI-specific macros), you must (1) gate the code at compile time with the correct macros and (2) reflect the real capability in the backend’s support_* flags so the framework won’t select an unsupported execution path.
Apply this as a standard checklist:
CV_MAJOR_VERSION/CV_MINOR_VERSION).__ARM_NEON.create_pipeline() (e.g., set support_packing = false or the equivalent packing flags), and then you can remove/avoid unused unpacking glue._WIN32 when detecting x64).Example patterns:
// 1) Version-gated optional headers
#if (CV_MAJOR_VERSION >= 3)
#include <opencv2/videoio/videoio.hpp>
#endif
// 2) SIMD/FP16 gated implementation
#if defined(__ARM_NEON) && (__ARM_FP & 2)
static int lstm_fp16(...){ /* fp16 NEON path */ }
#endif
// 3) Capability flags match implementation
int InnerProduct_arm::create_pipeline(const Option& opt)
{
if (axis == 1)
support_packing = false; // packing/layout not implemented for this axis
return 0;
}
// 4) If you disable packing support, don’t keep unpacking logic around
if (!support_vulkan_packing && !support_vulkan_any_packing)
{
// avoid selecting unpack/convert glue; only accept supported layouts
}
This prevents build-breaks on unsupported platforms, avoids dead/incorrect code paths, and ensures runtime execution matches what the backend actually supports.
Any config change that affects build/runtime behavior (dependency version pins, feature flags, build backend settings, tool/target sources like GPU wheels) must include a concrete compatibility rationale and align with the build tooling or runtime environment.
How to apply:
libpython).Example (pyproject.toml):
[build-system]
requires = ["maturin>=1.9.6,<2.0"]
build-backend = "maturin"
[tool.maturin]
features = ["pyo3/extension-module"]
# Needed so editable installs and Docker multi-stage builds don't depend on build-stage libpython.
[project]
dependencies = [
# datasets' hf:// downloader requires pyarrow >= 21.0.0
"pyarrow>=21.0.0",
]
Acceptance check:
When writing PyTorch code, preserve tensor dtypes and devices and be explicit about vector/matrix shapes to avoid precision loss, incorrect broadcasting, and unnecessary CPU allocations.
Why: mixed-precision and quantized weights are common in model deployment. Unnecessary up/downcasts, implicit device transfers, and incorrect assumptions about 1D tensor shapes (torch treats a 1D tensor as shape (d,) and matmul/outer have specific shape requirements) lead to subtle correctness and performance bugs.
Rules (actionable):
When projecting against possibly low-precision weights, do projection math in a safe compute dtype, but avoid redundant round-trips (downcast then upcast). Example: if refusal_directions is float32 and W is bfloat16/4-bit, move the vector to W’s device but keep its dtype:
v = layer_refusal_direction.to(matrix.device) r_transpose_W = torch.matmul(v, matrix) matrix.sub_(weight * torch.outer(v, r_transpose_W))
Avoid creating tensors on CPU unless necessary. Most torch operations preserve the source device; respect the device of source tensors to prevent implicit transfers and extra memory usage.
Example (combined pattern):
# r is (d,) float32 already r_device = r.to(matrix.device) # r_device: (d,), matrix: (d, k) -> torch.matmul yields (k,) r_transpose_W = torch.matmul(r_device, matrix) # outer(r, r_transpose_W) -> (d, k) matrix.sub_(weight * torch.outer(r_device, r_transpose_W))
Apply these guidelines consistently to avoid unnecessary precision loss, incorrect broadcasting, and extraneous device transfers when working with models, LoRA adapters, and quantized weights.
Always prefer the built-in GITHUB_TOKEN, explicitly document why it’s needed, and grant it only the minimum permissions required. For third‑party actions that call the GitHub API, pin them and justify token usage in the workflow so reviewers can verify scope and intent.
Why: automatic tokens are safer than adding shared secrets; minimizing permissions reduces blast radius if an action is compromised; pinning and documenting lets reviewers assess supply‑chain risk.
How to apply:
Example (from discussion): name: Lint PR
on: pull_request_target: types: [opened, reopened, edited]
jobs: main: name: Validate PR title runs-on: ubuntu-latest permissions: pull-requests: read # minimal permission needed to read PR metadata steps: - uses: amannn/action-semantic-pull-request@v6 # pin action env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # builtin token; documented above
Checklist for reviewers:
References: [0]
When using uv to build Python extensions via PEP 517 (e.g., maturin), ensure cache invalidation is keyed to the actual build inputs. Configure tool.uv.cache-keys so builds rerun only when the underlying sources for the compiled artifact change—especially Rust sources and Cargo manifests—rather than rebuilding whatever project owns the root pyproject.toml.
Apply this by:
tool.uv.cache-keys (e.g., src/**/*.rs, Cargo.toml, Cargo.lock, or the whole crate dir like rustbpe/**).rustbpe = { workspace = true }).uv sync / uv run actually rebuilds the intended artifact when Rust code changes.Example:
[tool.uv]
# Invalidate build cache when Rust crate inputs change
cache-keys = [
{ file = "pyproject.toml" },
{ file = "rustbpe/**" },
# alternatively, more targeted keys like:
# { file = "src/**/*.rs" },
# { file = "Cargo.toml" },
# { file = "Cargo.lock" }
]
# Ensure the crate is part of the workspace so the right package rebuilds
[rustbpe]
# (or in the relevant uv sources section)
# rustbpe = { workspace = true }
All algorithm implementations must be spec-aligned for the exact operator variant, tensor shapes/axes, and boundary conditions. Before merging, developers should explicitly verify that special cases and out-of-bound behavior follow the framework/ONNX semantics; avoid “one-size-fits-all” code paths that silently produce wrong results.
Apply these checks: 1) Operator variant semantics must match the spec
2) Boundary/padding modes must apply to every sampled neighbor
3) Use integer-safe floor/ceil for index mapping
// floor div: ih0 = floor(h*i/out_h)
int ih0 = (h * i) / out_h;
// ceil div: ih1 = ceil(h*(i+1)/out_h)
int ih1 = (h * (i + 1) + out_h - 1) / out_h;
4) Shape/axis/loop structure must match the actual Mat layout
5) Special cases must not be routed through general logic
6) Output type must match the source spec
7) Add minimal correctness tests
When writing library code, never hard-terminate or silently ignore failures. Always (1) validate inputs/shape compatibility correctly (including pack/elempack and dynamic dims), (2) signal errors with consistent return codes, and (3) propagate error statuses from lower-level operations to the caller.
Apply these rules:
assert(0)/process termination with a returned error code so the caller can decide how to recover.-1 for invalid parameter, existing -100 for allocation failure, etc.).Example: propagate and handle submit errors
// Bad: ignoring status
cmd.submit_and_wait();
return 0;
// Good: propagate to caller
return cmd.submit_and_wait();
Example: avoid assert(0) in library code
switch (impl_type) {
case 1: /* ... */ break;
case 2: /* ... */ break;
// ...
default:
return -1; // invalid impl_type
}
When adding/changing code, use names that (1) match existing project conventions, (2) clearly express intent, and (3) avoid reserved/problematic identifier patterns.
Rules:
_ (e.g., prefer top, front, behind over _top, _front).size_threshold; prefer names that encode behavior/meaning (e.g., budget_count_threshold / budget_drop_threshold).kernel_w, stride_w, and similarly out_w, out_h).z y x meaning dep/row/col), and ensure axis transforms follow ncnn conventions.Example (naming fixes):
// Bad: reserved leading underscore + vague intent
int _top;
size_t size_threshold = 10;
// Good: non-reserved + semantic intent
int top;
size_t budget_drop_threshold = 10;
// Good: follow *_w / *_h conventions
int out_w = pd.get(18, out_h);
When evolving or integrating client-facing interfaces (CLI/API) and platform-dependent APIs, preserve compatibility across existing clients and across SDK/platform versions.
Apply these rules: 1) Backward-compatible interface changes
Example (CLI):
// Old: prog caffeproto caffemodel ncnnproto ncnnbin quantizelevel int8scaletable
// New: prog ocr|noocr caffeproto caffemodel ncnnproto ncnnbin quantizelevel int8scaletable
// Implementation rule: keep the new optional argument(s) after existing ones, and
// only extend argv parsing in a way that preserves old argc patterns.
2) Guard optional platform/API features
Example (Vulkan-like pattern):
VkInstanceCreateInfo instanceCreateInfo{};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
// Prefer feature/support-based gating over hard-coding.
if (support_portability_enumeration) {
instanceCreateInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
3) Use compatibility shims for missing SDK symbols
vulkan_header_fix.h) rather than sprinkling ad-hoc defines throughout code.4) Don’t leak platform/ISA-specific details into stable interfaces
Together, these practices keep client interfaces stable for existing users while still allowing safe use of newer platform capabilities.
Tests should be designed to be independent and avoid coupling to implementation details. Use public interfaces rather than accessing internal state, prefer mocked or fake data over external dependencies, and keep tests general rather than tightly coupled to specific implementations.
Key principles:
raw_points in test cases - use proper public interfaces like handle_log insteadExample of good practice:
# Instead of accessing internal state:
est.raw_points["lat_active"].append(True)
# Use the public interface:
est.handle_log(log_message)
This approach makes tests more maintainable, less brittle to refactoring, and easier to understand by focusing on the component’s public contract rather than its internal implementation.
When optimizing hot kernels (SIMD/vectorized paths), remove avoidable overhead and improve locality:
1) Unroll small fixed-size tails (e.g., remainder=4)
// Instead of: for (int i=0;i<4;i++){ if(i%2)... }
// Do a straight-line unroll:
{
outptr[0] = ptr0[0];
outptr[1] = ptr1[0];
outptr[2] = ptr0[1];
outptr[3] = ptr1[1];
ptr0 += 2;
ptr1 += 2;
outptr += 4;
}
2) Use packed/contiguous intermediate buffers in vector code
// Instead of separate small-dim Mats that increase pointer indirections,
// create a single contiguous layout:
offset_blob.create(outw, outh, elemsize * 4, 4, opt.workspace_allocator);
value_blob.create(outw, outh, elemsize * 2, 2, opt.workspace_allocator);
// (Or merge offset+value into one buffer when feasible.)
3) Keep ISA guards and branching structure “compiler-friendly”
__AVX2__ implies __AVX__):
#if defined(__AVX__) && defined(__AVX2__).elempack==1 scalar handling inside SIMD-only macros in a way that blocks optimization; keep elempack branching clear at the appropriate scope.4) For reductions, avoid inefficient reduction patterns
These rules target the same bottlenecks discussed: loop/branch overhead on tiny remainders, poor memory locality for intermediates, and avoidable SIMD/ISA/reduction inefficiencies.
When working with concurrent operations involving shared resources or processes, use context managers and explicit synchronization to ensure proper cleanup and thread safety. This prevents resource leaks, race conditions, and ensures graceful shutdown even when operations are interrupted.
For process management, wrap subprocess operations in context managers instead of relying on atexit handlers:
# Instead of atexit.register()
with ProcessManager() as pm:
xvfb_proc = pm.start_process(xvfb_cmd, env)
ui_proc = pm.start_process(ui_cmd, env)
# processes automatically cleaned up on exit
For shared resources accessed by multiple threads, use explicit locking:
class AudioProcessor:
def __init__(self):
self.lock = threading.Lock() # Add a lock for thread safety
self.sound_data = []
def process_audio(self, data):
with self.lock:
self.sound_data.append(data)
When adding concurrency to existing APIs, maintain backward compatibility by encapsulating threading details within the implementation rather than exposing them to consumers. This allows you to improve responsiveness (like preventing UI freezing) without breaking existing code that depends on the original synchronous interface.
Ensure configuration parameters have appropriate default values, consistent naming conventions, and centralized default management. When adding new configuration keys, consider security implications for defaults (e.g., audio recording should default to off), maintain consistent naming patterns with existing keys, and centralize default values in the configuration structure rather than scattered throughout the codebase.
Example of good practice:
inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"AdbEnabled", {PERSISTENT}}, // Consistent with SshEnabled naming
{"RecordAudioFeedback", {PERSISTENT, BOOL, "0"}}, // Default off for privacy
// Centralized defaults as third parameter
};
This approach improves maintainability, reduces configuration errors, and ensures security-conscious defaults for sensitive features.
Create reusable error handling functions that accept custom error callbacks instead of duplicating error handling logic across multiple files. This approach provides flexibility in error response while maintaining consistent error handling patterns throughout the codebase.
When implementing system calls or operations that can fail, use a centralized utility function that accepts an error message and a callback for custom error handling. This eliminates code duplication and allows each call site to define appropriate failure responses.
Example implementation:
template<typename ErrorCallback>
int safe_ioctl(int fd, unsigned long request, void *argp, const char* error_msg, ErrorCallback error_callback) {
int ret;
do {
ret = ioctl(fd, request, argp);
} while ((ret == -1) && (errno == EINTR));
if (ret == -1 && error_msg) {
LOGE("ioctl failed: %s", error_msg);
error_callback();
}
return ret;
}
// Usage with custom error handling
auto fail = [this, serial] {
cleanup();
throw std::runtime_error("Error connecting to panda " + serial);
};
safe_ioctl(spi_fd, SPI_IOC_WR_MODE, &spi_mode, "failed setting SPI mode", fail);
This pattern allows for consistent error logging while enabling call sites to implement appropriate cleanup, exception throwing, or recovery strategies based on their specific context.
Use consistent units and data representations throughout mathematical calculations to avoid unnecessary computational overhead. When working with value ranges, prefer direct mathematical mappings over multiple conversions, and leverage utility functions for range transformations.
For example, instead of converting between different units multiple times:
// Avoid multiple conversions
int ir_percent = util::map_val(static_cast<int>(ir_pwr), 0, static_cast<int>(100*MAX_IR_POWER), 0, 100);
// Better: work in consistent units, then map once
int value = util::map_val(std::clamp(percent, 0, 100), 0, 100, 0, 255);
This approach reduces computational complexity, minimizes floating-point precision errors, and makes the code more maintainable by establishing clear data flow patterns. Choose the most natural unit for your domain and stick with it throughout the calculation pipeline.
Ensure API changes maintain backward compatibility to avoid breaking existing clients and workflows. When adding new functionality, use optional parameters with sensible defaults rather than required parameters. When versioning APIs, follow the /api/v2/resource pattern and maintain deprecated endpoints during transition periods to allow clients time to migrate.
Key practices:
/api/v2/userdata rather than /userdata-v2Example of backward-compatible parameter addition:
def INPUT_TYPES(s):
return {
"required": {
"images": ("IMAGE", ),
"filename_prefix": ("STRING", {"default": "ComfyUI"})
},
"optional": {
"disable_metadata": ("BOOLEAN", {"default": False}) # New parameter as optional
}
}
This approach prevents breaking existing API workflows while enabling new functionality for clients that choose to adopt it.
Always use explicit value specifications and type-safe handling to prevent undefined behavior and ensure predictable code execution. This includes specifying appropriate default values for configuration parameters and using platform-independent format specifiers for data types.
For configuration defaults, be explicit about expected values even when they seem obvious:
// Good: Explicit defaults prevent undefined states
{"UptimeOffroad", {PERSISTENT, FLOAT, "0.0"}},
{"UptimeOnroad", {PERSISTENT, FLOAT, "0.0"}},
For type formatting, use portable macros to ensure correct behavior across platforms:
// Good: Type-safe formatting prevents undefined behavior
LOGE("SV_ID != SLOT_NUMBER: %d %" PRIu64, msg->sv_id(), data->n());
// Alternative: Explicit casting for clarity
LOGE("SV_ID != SLOT_NUMBER: %d %llu", msg->sv_id(), (unsigned long long)data->n());
This approach prevents subtle bugs from implicit assumptions about default values or platform-specific type representations, ensuring consistent behavior across different environments and reducing the risk of undefined states.
APIs should provide convenient methods that handle common operations directly, rather than requiring users to write helper functions or use verbose patterns. This improves developer experience and reduces boilerplate code.
Key principles:
Example of good API design:
# Good: Simple constructor with direct parameter passing
CC = car.CarControl(cruiseControl={'cancel': True})
# Avoid: Verbose chaining that could be simplified
CC = car.CarControl.new_message(cruiseControl={'cancel': True})
test_car_controller(CC.as_reader())
When designing APIs, consider what the most common use cases will be and optimize the interface for those scenarios. If you find yourself writing helper functions or seeing users write repetitive boilerplate, that’s a signal the API could be more convenient.
Identify and eliminate unnecessary expensive operations that can significantly impact performance. Common patterns to watch for include:
Unnecessary deep copying: Instead of using deepcopy() on large objects, build new dictionaries with only the required values. For example, rather than copy.deepcopy(self.history[key]) and then removing unwanted fields, construct a new dictionary with only the needed data.
Loop-invariant computations: Move calculations that don’t change between iterations outside of loops. For instance, if interpolator(x) produces the same result in every loop iteration, compute it once before the loop and store in a variable like computed_spacing.
Missing caching for expensive operations: Implement caching for frequently accessed heavy resources like models, file system operations, or computed values. Use model caches to “directly copy from cpu memory” rather than reloading from disk repeatedly.
Redundant processing: Avoid performing expensive operations on every function call when they could be done once or only when necessary. Check if computations can be moved to initialization or triggered only when input conditions change.
Before implementing expensive operations, consider: Is this computation necessary every time? Can the result be cached? Can the operation be moved outside a loop or conditional block? These optimizations often provide significant performance improvements with minimal code changes.
Use runtime-determined configuration sources instead of hardcoded values or static file parsing when more reliable alternatives are available. This improves robustness, cross-platform compatibility, and deployment flexibility.
Examples of preferred approaches:
importlib.metadata.version("package-name") instead of parsing requirements.txt files for version informationwin32api.GetSystemDirectory() instead of hardcoded paths like "C:\Windows\System32"os.path.join() instead of hardcoded absolute pathsWhy this matters:
Implementation:
# Instead of hardcoded paths:
ICACLS_PATH = r"C:\Windows\System32\icacls.exe"
# Use dynamic system paths:
ICACLS_PATH = os.path.join(win32api.GetSystemDirectory(), "icacls.exe")
# Instead of parsing static files:
with open("requirements.txt", "r") as f:
version = f.readline().split("=")[-1].strip()
# Use runtime package information:
from importlib.metadata import version
frontend_version = version("comfyui-frontend-package")
When you notice code patterns being repeated across functions or methods, extract the common logic into separate, reusable functions. This improves maintainability, reduces bugs, and follows the DRY (Don’t Repeat Yourself) principle.
Look for opportunities to:
Example of refactoring repeated logic:
# Before: Repeated logic in multiple places
def get_free_memory(dev=None, torch_free_too=False):
if os.path.isfile('/sys/fs/cgroup/memory/memory.limit_in_bytes'):
with open('/sys/fs/cgroup/memory/memory.limit_in_bytes', 'r') as f:
mem_used_total = psutil.virtual_memory().used
mem_total = int(f.read())
# ... more logic
def get_total_memory(dev=None):
if os.path.isfile('/sys/fs/cgroup/memory/memory.limit_in_bytes'):
with open('/sys/fs/cgroup/memory/memory.limit_in_bytes', 'r') as f:
mem_used_total = psutil.virtual_memory().used
mem_total = int(f.read())
# ... more logic
# After: Extracted common logic
def get_containerd_memory_limit():
if os.path.isfile('/sys/fs/cgroup/memory/memory.limit_in_bytes'):
with open('/sys/fs/cgroup/memory/memory.limit_in_bytes', 'r') as f:
mem_used_total = psutil.virtual_memory().used
mem_total = int(f.read())
return mem_used_total, mem_total
return None, None
def get_free_memory(dev=None, torch_free_too=False):
mem_used, mem_total = get_containerd_memory_limit()
if mem_used is not None:
# ... use extracted values
This approach makes code more maintainable, testable, and reduces the likelihood of introducing bugs when making changes.
When enabling/disabling CPU features or platform-specific APIs, derive decisions from the configured target/platform (toolchain/CMake target selection) and apply consistent compile-time guards across code and tests. Do not rely on compiler-defined feature macros that may differ between build/test environments.
Apply it like this:
# Toolchain for an older/limited target
set(NCNN_AVX OFF CACHE BOOL "Disable AVX" FORCE)
set(NCNN_AVX2 OFF CACHE BOOL "Disable AVX2" FORCE)
set(NCNN_SSE2 ON CACHE BOOL "Enable SSE2" FORCE)
set(CMAKE_SYSTEM_VERSION 5.1)
set(CMAKE_GENERATOR_PLATFORM "Win32")
_WIN32 && !(__MINGW32__) over ad-hoc flags; keep intrinsics loads inside the matching arch block).
#if (defined _WIN32 && !(defined __MINGW32__))
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#endif
#if __ARM_NEON
float32x4_t _k0123 = vld1q_f32(kernel0);
#else
const float* k0 = kernel0;
#endif
__AVX__.This prevents “works in net.cpp, fails in ctest” and “breaks armv7 without NEON” class regressions, and keeps feature gating consistent across the build and runtime/test environments.
When changing build configuration (compiler definitions, link libraries, compile/link flags), ensure it is applied only when the correct feature option is enabled and the selected target/toolchain actually requires it. Avoid unconditional/global flags that can break other platforms or remove the ability to disable features.
Practical rules:
Example pattern (OpenMP):
option(NCNN_OPENMP "build with OpenMP" ON)
if(NCNN_OPENMP)
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
# Apply to the actual consuming target(s)
target_link_libraries(my_executable PRIVATE OpenMP::OpenMP_CXX)
endif()
endif()
Example pattern (target/toolchain gating):
# Don’t treat any ANDROID-defined toolchain as an Android NDK build.
if(ANDROID AND ANDROID_NDK)
# android-specific flags/libs
endif()
# Don’t force XP-only definitions for every WIN32 build.
if(WIN32 AND NCNN_TARGET_XP)
target_compile_definitions(ncnn PUBLIC _WIN32_WINNT=0x0501 WINVER=0x0501)
endif()
When optimizing for CPU/GPU speed, don’t accidentally remove fast paths via build/toolchain settings, and don’t add expensive memory-access patterns in the hottest kernels.
Apply this standard: 1) Don’t globally disable ISA features or runtime CPU dispatch from generic toolchain files
2) In SIMD kernels, avoid unnecessary gather/indirection for contiguous data
3) Keep SIMD tail handling simple and width-driven
nn/offset-tail bookkeeping.4) Don’t assume #pragma omp simd will outperform hand-written intrinsics in hot paths
Example (contiguous access vs gather):
// Bad: gather when srcptr is contiguous and offsets are sequential
// __m256 v00_val = mask_gather_ps256(srcptr, v00_offset, mask);
// Good: use vector load directly when indices are contiguous
// (illustrative; exact mask logic depends on bounds)
__m256 v00_val = _mm256_loadu_ps(srcptr + base_index);
// apply mask/lerp/fma as needed
Example (width-driven tail loop instead of nn bookkeeping):
int x = 0;
#if __SSE2__
#if __AVX__
for (; x + 7 < grid_size; x += 8) {
// AVX body
}
#endif
for (; x + 3 < grid_size; x += 4) {
// SSE body
}
#endif
for (; x < grid_size; x++) {
// scalar remainder
}
Net effect: you preserve the compiler/runtime ability to select the fastest supported implementation, and you prevent common “hidden” slowdowns from gather/indirection and overly complex SIMD tails.
Ensure CI/CD workflows build, test, and package artifacts in a way that is correct for each target platform/architecture—without running irrelevant jobs.
Apply these rules: 1) Prefer dedicated toolchains; avoid hardcoded compiler/arch knobs unless the workflow explicitly documents and matches the toolchain. 2) Scope CI triggers and steps by actual feature/platform support.
Concrete example (macOS per-arch Vulkan wiring):
# x86_64
CIBW_ENVIRONMENT: |
NCNN_VULKAN=ON
Vulkan_INCLUDE_DIR=$GITHUB_WORKSPACE/vulkansdk-macos-1.3.236.0/MoltenVK/include
Vulkan_LIBRARY=$GITHUB_WORKSPACE/vulkansdk-macos-1.3.236.0/MoltenVK/dylib/macOS/libMoltenVK.dylib
Concrete example (path-scoped CI triggering):
# Only run when relevant; don’t trigger for Vulkan-only subtree changes if Vulkan is off
on:
pull_request:
paths:
- '.github/workflows/windows-xp-clang.yml'
- 'CMakeLists.txt'
- 'src/*'
# Omit 'src/layer/vulkan/**' if Vulkan support is disabled
Quick validation checklist for each platform/arch:
Ensure concurrent execution is race-free by (a) not storing per-inference mutable state in shared layer objects, (b) keeping OpenMP loop temporaries thread-local, and (c) using the correct synchronization primitive for the target platform.
Apply these rules: 1) State must be owned by the running instance, not by the shared model/layer.
mutable members updated in forward().Example pattern:
// Instead of: mutable Mat hidden, cell; hidden=...; cell=...; in forward()
// Do:
int forward(const std::vector<Blob*>& bottom_blobs,
std::vector<Blob*>& top_blobs) {
const Mat& hidden_in = bottom_blobs[HIDDEN_BLOB_INDEX]->data;
const Mat& cell_in = bottom_blobs[CELL_BLOB_INDEX]->data;
Mat hidden_out, cell_out;
// compute hidden_out/cell_out...
top_blobs[HIDDEN_OUT]->data = hidden_out;
top_blobs[CELL_OUT]->data = cell_out;
return 0;
}
2) In parallel loops, never let per-iteration data become shared state.
#pragma omp parallel for, any pointer/variable that changes per iteration (e.g., pc, pa, scales, bias) must be thread-local or loop-local (declared inside the loop or as private variables), not shared across iterations.3) Locking primitives must match platform semantics.
CRITICAL_SECTION vs newer primitives).When code depends on possibly-missing inputs/outputs or optional attributes, do not index or read them unconditionally. Add explicit guards for presence and fall back to a safe default/overload.
Apply this pattern:
bottom_blobs.size() / top_blobs.size() before using fixed indices (e.g., hidden/cell), and if hidden/cell aren’t provided, delegate to the simpler overload.n.has_attr("eps")); only then use the value, otherwise use the intended default.Example (vector forward fallback):
int forward(const std::vector<Mat>& bottom_blobs,
std::vector<Mat>& top_blobs,
const Option& opt) const {
if (bottom_blobs.size() < 1 || top_blobs.size() < 1)
return -100;
// hidden/cell optional: only use them when present
if (top_blobs.size() >= 3) {
// access indices safely
Mat& hidden_state = top_blobs[1];
Mat& cell_state = top_blobs[2];
return forward(bottom_blobs[0], top_blobs[0], hidden_state, cell_state, opt);
}
// safe fallback
Mat& top_blob = top_blobs[0];
return forward(bottom_blobs[0], top_blob, opt);
}
Example (attribute existence guard):
float eps = 1e-3f; // intended default
if (n.has_attr("eps"))
eps = n.attr("eps");
Rule of thumb: if the code would otherwise dereference an index or consume an attribute that may not be present, you must add a guard and a fallback path before the dereference.
When introducing new terminology or naming conventions, ensure consistency with existing patterns in the codebase while prioritizing clarity and universal understanding. Before adding new names, identifiers, or terminology, review existing usage patterns and adopt the established conventions. When multiple options exist, choose the most widely understood and universally applicable terms.
For example, when adding translations or interface text, check existing instances: “I saw that ‘Associer’ is the verb used in all other instances” and maintain that consistency. Similarly, when choosing between terminology options, select the “most universal way” that will be clear to the broadest audience.
This applies to variable names, method names, UI text, comments, and any other identifiers where consistency and clarity are important for maintainability and user understanding.
Functions and APIs should employ explicit strategies for handling null/None values rather than leaving null handling ambiguous. Choose one of two approaches:
Avoid: Returning None from functions without clear handling expectations, or requiring frequent isinstance/null checks due to inconsistent data formats.
Example of good null handling:
# Option 1: Design out nulls with defaults
def get_config(key: str) -> Config:
return config_dict.get(key, DEFAULT_CONFIG) # Never returns None
# Option 2: Explicit null contract
def get_node(node_id: str) -> Node:
node = self._find_node(node_id)
if node is None:
raise NodeNotFoundError(f"Node {node_id} not found")
return node
Example of problematic null handling:
# Ambiguous - callers don't know if they need to handle None
def get_node(node_id: str) -> Node | None:
# Returns None sometimes, unclear when
return self.nodes.get(node_id)
This approach prevents attribute errors, reduces defensive programming overhead, and makes null-handling expectations explicit in the codebase.
Implement memoization and guard clauses to eliminate redundant computations and improve algorithmic performance. Many algorithms can be significantly optimized by caching intermediate results and avoiding unnecessary work.
Key optimization strategies:
islice instead of creating full intermediate collectionsExample of proper memoization implementation:
# Before: Redundant recursive calculations
def recursive_will_execute(prompt, outputs, node_id):
# Expensive recursive computation repeated many times
return calculate_dependencies(prompt, outputs, node_id)
# After: Memoized version with proper scope
memo = {} # Create memo outside the sorting algorithm
output_node_id = min(to_execute, key=lambda a: len(recursive_will_execute(prompt, outputs, a, memo)))
Example of guard clause optimization:
# Before: Always processes string replacements
def compute_vars(input, image_width, image_height):
input = input.replace("%width%", str(image_width))
input = input.replace("%height%", str(image_height))
return input
# After: Skip processing if no variables present
def compute_vars(input, image_width, image_height):
if '%' not in input:
return input # Guard clause avoids unnecessary work
input = input.replace("%width%", str(image_width))
input = input.replace("%height%", str(image_height))
return input
These optimizations can dramatically improve performance, especially in algorithms that process large datasets or perform repeated calculations.
When implementing AI operations that involve matrix multiplication or neural network components, explicitly support modern numerical precision formats (TF32, BFloat16, Float8) across different hardware backends. These precision formats significantly accelerate AI training and inference while maintaining acceptable numerical accuracy.
For maximum performance:
if ((input_.is_cuda() || input_.is_xpu()) && input_.scalar_type() == ScalarType::Half) {
// Use accelerator-specific optimizations
}
These optimizations can lead to significant speedups in large model training and inference without requiring algorithm changes.
Always be explicit and specific when handling errors rather than using catch-all approaches or implicit conventions. This improves code robustness, debuggability, and maintainability.
When catching exceptions:
# Don't do this - catching all exceptions masks problems
try:
result = complex_operation()
except Exception as exc:
result = default_value # Which errors should actually be handled this way?
# Do this - be specific about what you're catching
try:
result = complex_operation()
except MemoryError:
# Handle specific memory issues
raise RuntimeError("Insufficient memory for operation") from exc
except KeyError as e:
# Handle missing keys appropriately
return None # Indicate failure with explicit return
When raising or signaling errors:
# Don't do this - using special return values is error-prone
def check_if_supported():
if not meets_requirements():
return False # Caller might miss this!
# ...
# Do this - be explicit about errors
def check_if_supported():
if not meets_requirements():
raise RuntimeError("Requirements not met: missing XYZ")
# ...
# Order operations to maintain system integrity
def perform_mutation(self, key):
# First validate - may raise exceptions
if key not in self.valid_keys:
raise_args_mismatch()
# Only mutate state after validation passes
self.should_reconstruct = True
self.output.side_effects.mutation(self)
By being specific about errors, you make code easier to debug and maintain while preventing your system from entering invalid states.
Design your code to minimize the unexpected introduction of None values into data structures and APIs. Use immutable parameter types when you don’t need to modify the input, and be explicit about nullable types to establish clear contracts.
# Bad: Unexpectedly modifies input with None values
def process_data(progression_futures: list):
progression_futures.append(None) # Caller now has List[Optional[...]]
# Good: Communicates intent with immutable parameter type
def process_data(progression_futures: Sequence):
# Create a new collection instead of modifying input
result = list(progression_futures) + [None]
return result
# Good: Be explicit about nullable return values
def get_first(items: list[Optional[str]]) -> Optional[str]:
return items[0] if items else None
When handling potentially null attributes or dictionary keys, use concise safe access patterns:
# Verbose and error-prone
if "max_version" in kwargs:
kwargs.pop("max_version")
# Better: Use safe dictionary operations
kwargs.pop("max_version", None) # No KeyError if missing
# Verbose attribute access
name = str(e.name) if hasattr(e, 'name') else str(e)
# Better: Use getattr with default
name = str(getattr(e, "name", e))
When working with multiple sequences that need to be combined, prefer higher-level iteration abstractions over nested loops. This improves code readability, reduces nesting depth, and helps prevent logical errors when managing multiple iterative dimensions.
For example, instead of writing nested loops:
dtypes = [torch.int, torch.long, torch.short]
for count_dtype in dtypes:
for prob_dtype in dtypes:
# process with count_dtype and prob_dtype
Use itertools.product for a cleaner approach:
dtypes = [torch.int, torch.long, torch.short]
for count_dtype, prob_dtype in itertools.product(dtypes, repeat=2):
# process with count_dtype and prob_dtype
Similarly, other Python constructs can simplify iteration patterns:
enumerate when you need both index and valuezip to iterate through multiple sequences in parallelreversed, sorted, or other builtin functions when applicableThese higher-level abstractions make algorithmic intent more evident and reduce opportunities for off-by-one errors or incorrect nested logic.
Select the proper exception type based on the error scenario to provide clearer error handling and better debugging experience:
Example:
// For invalid parameter values
TORCH_CHECK_VALUE(
at::isFloatingType(count.scalar_type()),
"binomial only supports floating-point dtypes for count, got: ",
count.scalar_type());
// For other input validation
TORCH_CHECK(
indices.is_pinned() == values.is_pinned(),
"memory pinning of indices must match memory pinning of values");
// For internal invariants
TORCH_INTERNAL_ASSERT(r.idx == 0, "Unexpected parser result");
// For C API null checks
PyObject* tuple = PyTuple_New(2);
if (!tuple) {
throw python_error();
}
Using appropriate exception types helps users better understand and handle errors, improves API clarity, and facilitates more effective debugging. Proper error messages that describe the problem and expected behavior enable users to quickly identify and fix issues.
Always normalize configuration inputs (especially environment variables) by removing whitespace and applying consistent case transformation before processing them. This prevents unexpected behaviors caused by insignificant variations in input format.
For environment variables:
# Good practice
env_value = os.environ.get('TORCH_CONFIG_VAR', None)
if env_value:
env_value = env_value.strip().lower()
# Now process with normalized value
For configuration dictionaries, make sure keys are properly normalized if case-insensitive matching is required.
Additionally:
PYTORCH_TUNABLEOP_ENABLED=1 without spaces).Always verify CUDA availability before performing CUDA-specific operations to prevent runtime errors when code runs on systems without CUDA support. When working with device-specific code:
torch.cuda.is_available() before any CUDA-specific operationsExample:
# Bad - may fail on CPU-only systems
if torch.cuda.is_current_stream_capturing():
# CUDA-specific code
# Good - safely checks CUDA availability first
if torch.cuda.is_available() and torch.cuda.is_current_stream_capturing():
# CUDA-specific code
# Better device property handling - use specific properties instead of just names
device = input_nodes[0].get_device()
if device.type == "cuda":
# Use specific device properties for hardware identification
device_properties = torch.cuda.get_device_properties(device.index)
# Use properties like device_properties.major, device_properties.minor, etc.
This approach ensures code works reliably across different hardware configurations and gracefully handles CPU-only environments.
Instead of duplicating test code or using nested loops, use test parameterization to handle multiple test cases efficiently. This improves maintainability, ensures complete coverage, and makes test failures more traceable.
Key benefits:
Example:
# Instead of:
def test_binomial_dtype_error(self):
for count_dtype in dtypes:
for prob_dtype in dtypes:
# test logic...
# Use:
@parametrize("count_dtype", [torch.int, torch.long, torch.short])
@parametrize("prob_dtype", [torch.int, torch.long, torch.short])
def test_binomial_dtype_error(self, count_dtype, prob_dtype):
# test logic...
# For multiple configuration parameters:
@parametrize("device", (GPU_TYPE, "cpu"))
@parametrize("format", ("binary", "unpacked"))
@parametrize("dynamic", (False, True))
def test_basic(self, device: str, format: str, dynamic: bool):
# test logic...
When modifying existing APIs, always prioritize backward compatibility to avoid breaking client code. Before changing API signatures, function names, or return types, first consider the impact on existing consumers.
If an API needs new functionality:
For new APIs, consider future compatibility:
C10_API)Example from the discussions:
// Instead of changing an existing function signature:
// TORCH_API DLManagedTensor* toDLPack(const Tensor& src);
// -> TORCH_API DLManagedTensorVersioned* toDLPack(const Tensor& src);
// Prefer adding a new function while preserving the original:
TORCH_API DLManagedTensor* toDLPack(const Tensor& src); // Maintain original
TORCH_API DLManagedTensorVersioned* toDLPackV2(const Tensor& src); // Add new version
This approach ensures libraries using your API can upgrade on their own timeline and prevents unexpected runtime failures.
Avoid hardcoding specific device types like ‘cuda’ in AI code. Instead, use device-agnostic approaches such as device type variables or accelerator detection functions. This ensures code runs efficiently across different hardware accelerators (CUDA, ROCm, XPU, etc.) without modification.
Examples:
# Instead of this:
x = torch.randn(100, 100, device='cuda')
# Do this:
x = torch.randn(100, 100, device=GPU_TYPE)
# Or for more dynamic detection:
device = torch.accelerator.current_accelerator().type if torch.accelerator.current_accelerator() else "cpu"
x = torch.randn(100, 100, device=device)
This approach helps maintain compatibility with various AI hardware acceleration platforms and simplifies testing across multiple device types. For common test cases, prefer using constants like GPU_TYPE defined in testing utilities, and for production code, use the accelerator API to detect available devices at runtime.
When evolving APIs, prioritize backward compatibility to minimize disruption for existing users. Add new functionality using default arguments rather than creating overloaded methods that could cause ABI compatibility issues. For example:
// Prefer this:
void set_device(DeviceIndex device, bool force = false);
// Over this:
void set_device(DeviceIndex device);
void set_device(DeviceIndex device, bool force);
When introducing version-dependent features, implement appropriate version checks and fallbacks:
#if defined(CUDA_VERSION) && (CUDA_VERSION >= 12050)
// Use newer API version
#else
// Fallback implementation for older versions
#endif
Keep internal implementation details hidden from public-facing interfaces by clearly distinguishing between public APIs and internal functionality. For evolving ABIs, provide transition mechanisms that support both old and new versions simultaneously, allowing consumers to opt into newer versions explicitly while maintaining backward compatibility.
When configuring library searches in CMake, use HINTS instead of PATHS when you want to prioritize specific locations before falling back to system defaults. HINTS are searched before default paths, while PATHS are searched after default paths. This ensures that user-specified or environment-provided paths are checked first, making dependency resolution more predictable.
Include common path suffixes to improve the robustness of library discovery:
find_library(NVSHMEM_HOST_LIB
# In pip install case, the lib suffix is `.so.3` instead of `.so`
NAMES nvshmem_host nvshmem_host.so.3
HINTS $ENV{NVSHMEM_HOME} ${NVSHMEM_PY_DIR}
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64
DOC "The location of NVSHMEM host library.")
This approach creates a more reliable search order:
Using this pattern helps avoid unexpected library resolution and ensures dependencies are found in the correct locations, especially in complex build environments with multiple library versions.
Choose identifier names that clearly reveal their purpose and behavior. Names should be specific, descriptive, and self-explanatory:
is_consistent() rather than consistency())VersionString is better than generic VersionParser)Avoid vague or overly generic names that don’t communicate their specific role. When reviewing code, ask “Does this name clearly explain what it does or represents?”
Example:
# Less clear:
def contains_ungroupable(node):
# Implementation...
# More clear:
def contains_gemm_like(node):
# Implementation...
This naming approach reduces cognitive load for readers and makes code more maintainable over time by making its purpose immediately evident.
Eliminate repeated code patterns by using appropriate abstraction techniques. This improves readability, reduces maintenance burden, and minimizes the risk of inconsistencies when changes are needed.
Consider these approaches:
// Use a template:
template
2. **Extract repeated logic into helper functions**:
```cpp
// Instead of duplicating checking logic:
if (condition_for_iv) {
// many lines of validation logic for iv
}
if (condition_for_src_iv) {
// same validation logic repeated for src_iv
}
// Create a helper function:
void validateIValue(const IValue& iv) {
// validation logic in one place
}
// Use enumerate for cleaner code: for (const auto&& [i, node] : c10::enumerate(graph_->nodes())) { LOG(INFO) « “Node #” « i « ”: “ « node.toString(); }
By consistently applying these patterns, you'll create more maintainable code that's easier to understand and modify.
---
## Thread context management
<!-- source: pytorch/pytorch | topic: Concurrency | language: Python | updated: 2025-07-05 -->
Always explicitly set required thread context and state rather than assuming inheritance from parent threads or other concurrent processes. In multithreaded and distributed environments, assumptions about shared state can lead to subtle bugs, race conditions, and incorrect behavior.
For example, when setting device context in a multithreaded environment:
```python
# Incorrect: Assuming device context is inherited
def _pin_memory_loop(in_queue, out_queue, done_event, device):
# This might not work as expected in a different thread
process_data(in_queue)
# Correct: Explicitly set device context in each thread
def _pin_memory_loop(in_queue, out_queue, done_event, device):
# Set device context explicitly in this thread
torch.accelerator.set_device_index(torch.accelerator.current_device_index())
process_data(in_queue)
Similarly, be careful about assumptions regarding process groups in distributed computing. Each component should clearly document and validate its threading model and required context. Use proper synchronization mechanisms like barriers when operations across threads depend on each other’s completion.
Structure code to maximize readability by reducing unnecessary complexity. Use early returns to minimize nesting levels, move invariant conditions outside of loops, and replace magic numbers with named constants.
Example - Replace deeply nested conditions:
# Instead of this:
def estimate_flops(self) -> int | None:
if isinstance(self, ExternKernel):
if op is not None:
# Deep logic here
pass
return None
# Prefer this:
def estimate_flops(self) -> int | None:
if not isinstance(self, ExternKernel) or op is None:
return None
# Logic continues at a single nesting level
Similarly, when a condition inside a loop doesn’t change between iterations, move it outside:
# Instead of checking the same condition in each iteration
for i, future in enumerate(self._progression_futures):
if self._post_compile_data and future.done():
# Logic here
# Check invariant conditions before the loop
if self._post_compile_data:
for i, future in enumerate(self._progression_futures):
if future.done():
# Logic here
And always use named constants instead of unexplained numbers:
# Instead of:
for i, (gb_type, info) in enumerate(sorted(gb_types.items()), 1001):
# Logic using magic number 1001
# Use:
START_ID = 1001 # Base ID for graph break types
for i, (gb_type, info) in enumerate(sorted(gb_types.items()), START_ID):
# Logic using named constant
When implementing hardware-accelerated operations for AI models, ensure support for the latest architectures while considering determinism requirements.
// Example: Ensure architecture lists include the latest generations
// Don't forget to add new architectures like Blackwell
elseif(${arch_name} STREQUAL "Ampere")
set(arch_bin 8.0)
set(arch_ptx 8.0)
elseif(${arch_name} STREQUAL "Hopper")
set(arch_bin 9.0)
set(arch_ptx 9.0)
elseif(${arch_name} STREQUAL "Blackwell")
set(arch_bin 10.0)
set(arch_ptx 10.0)
// When implementing operations with potential non-determinism:
// 1. Document the non-deterministic behavior
// 2. Consider providing a deterministic alternative implementation
// 3. Add appropriate flags for torch.use_deterministic_algorithms()
// Example for pooling operations:
if (at::globalContext().deterministicAlgorithms() &&
requires_deterministic_implementation) {
// Use deterministic implementation (might be slower)
} else {
// Use potentially faster non-deterministic implementation with atomics
AtomicType<T>::atomic_add(...);
}
Hardware-optimized implementations significantly impact AI model performance, but must be balanced with requirements for reproducibility in research and production deployments.
When writing error messages in PyTorch code, include not only what went wrong but also clear guidance on how to fix the issue. This helps users quickly understand and resolve problems without digging through documentation.
Example from tensor device operations:
// Poor error message:
TORCH_CHECK(false, "Cannot move tensor between devices");
// Better error message with remediation:
TORCH_CHECK(
!force_move,
"cannot move tensor from ",
data.device(),
" to ",
device,
" without copying. Set copy=True is needed.");
This practice is especially important for operations that have non-obvious requirements or constraints, such as tensor movement between devices, shape transformations, or operations with specific dtype requirements. By providing actionable guidance directly in error messages, you improve the developer experience and reduce support burden.
Always use descriptive variable names that clearly indicate their purpose without requiring readers to check call sites or implementation details. Avoid single-letter variables like t or vague abbreviations, especially in public interfaces and open-source code. Additionally, ensure clear distinction between similarly named variables, particularly when distinguishing between member variables and local variables with related purposes.
Bad example:
void LayoutManager::assert_no_overlapping_storages(const Node& node, size_t t) {
// t is unclear - does it mean time, temporary, or something else?
}
class AliasAnalyzer {
private:
std::set<Value*> aliases_;
void someMethod() {
std::set<Value*> aliases; // Confusing similarity to member variable
// Code using both aliases_ and aliases
}
};
Good example:
void LayoutManager::assert_no_overlapping_storages(const Node& node, size_t nodeIdx) {
// Clear that this refers to a node index
}
class AliasAnalyzer {
private:
std::set<Value*> finalized_aliases_; // More descriptive name
void someMethod() {
std::set<Value*> current_aliases; // Clearly distinct from member variable
// Code using both finalized_aliases_ and current_aliases
}
};
Design public APIs to work seamlessly across different programming languages and platforms. Follow these key principles:
int over size_t for array sizes and indicesclass CV_EXPORTS_W MyClass {
public:
CV_WRAP void process(int size); // Not size_t
CV_WRAP_AS(processBytes) Mat process(InputArray data); // Alias for clarity
};
Following these guidelines ensures your API works reliably across Python, Java, and C++ while maintaining long-term stability.
Limit memory consumption in performance-critical paths by conditionally creating large data structures or deferring allocation until needed. Large tracking structures, debug information, and memory-intensive operations should be guarded by configuration flags to prevent them from impacting performance in production environments.
For example, when implementing debug features, wrap memory-intensive operations in conditional blocks:
// Before: Always creates large data structure
for (const auto& [v, lifetime] : lifetimes_) {
for (const auto t : c10::irange(lifetime.start, lifetime.end + 1)) {
alive_values_at_time_[t].emplace_back(v);
}
}
// After: Only create when debug mode is enabled
#ifdef DEBUG_MODE
for (const auto& [v, lifetime] : lifetimes_) {
for (const auto t : c10::irange(lifetime.start, lifetime.end + 1)) {
alive_values_at_time_[t].emplace_back(v);
}
}
#endif
Additionally, use appropriate resource management patterns (RAII, smart pointers) to ensure efficient memory utilization and prevent leaks in performance-sensitive code. When working with external APIs like the Python C API, maintain correct reference counting to avoid memory leaks that can gradually degrade performance over time.
In memory-constrained environments like GPU computing, these optimizations can prevent out-of-memory errors and significantly improve overall system performance.
Follow consistent code organization patterns:
// Prefer in implementation (.cpp): HeartbeatMonitor* HeartbeatMonitor::get() { static HeartbeatMonitor instance; return &instance; }
2. Explicitly define class semantics using appropriate macros and default specifications:
```cpp
class BiasHandler {
C10_DISABLE_COPY_AND_ASSIGN(BiasHandler);
BiasHandler(BiasHandler&&) = default;
BiasHandler& operator=(BiasHandler&&) = default;
// Class implementation...
};
Always use centralized configuration detection mechanisms (like CMake finder modules) instead of hardcoding paths or environment variables. This approach ensures compatibility across different installation methods and environments.
When integrating with external libraries or tools:
findXXX.cmake) that can detect installations in multiple locationsFor example, instead of hardcoding:
export NVSHMEM_HOME=/usr/local
Create a CMake finder module that can handle multiple installation scenarios:
# findNVSHMEM.cmake example
find_path(NVSHMEM_INCLUDE_DIR nvshmem.h
PATHS
${NVSHMEM_HOME}/include
/usr/local/include
$ENV{CONDA_PREFIX}/include
)
if(NVSHMEM_INCLUDE_DIR)
get_filename_component(NVSHMEM_HOME ${NVSHMEM_INCLUDE_DIR} DIRECTORY)
endif()
This approach ensures your build system can adapt to different installation methods (pip, system packages, custom paths) without requiring manual configuration changes.
When designing algorithms, select data structures that accommodate all possible scenarios, not just the common case. For static analysis algorithms where certainty isn’t guaranteed, prefer collections that can represent one-to-many relationships even when most instances will contain only one element. This prevents having to redesign your algorithm later when edge cases are discovered.
For example, instead of using:
c10::FastMap<const Value*, const Value*> aliases_; // One-to-one mapping
Use a structure that supports potential multiple relationships:
c10::FastMap<const Value*, c10::FastSet<const Value*>> aliases_; // One-to-many mapping
This approach is particularly important in static analysis, compiler optimizations, and other scenarios where the algorithm must account for all possible execution paths, even if most runtime instances follow a simpler pattern.
Design APIs with clear contracts that behave exactly as their names and signatures suggest. Functions should do precisely what they claim to do without surprising side effects or hidden behaviors.
Key principles:
Example of poor design:
// Confusing API with unclear behavior
bool initializeContextFromVA(VADisplay display, bool tryInterop) {
// Uses a different display if provided one doesn't work
// Silently falls back to non-interop mode if tryInterop fails
// Returns success even when not using the requested display
}
Improved design:
// Clear contract, predictable behavior
bool initializeContextFromVA(VADisplay display) {
// Only initializes with the exact display provided
// Throws exception with clear message if initialization fails
// Returns true only when successfully initialized with given display
}
Remember to document any special parameter handling. If your function treats certain values (like Point(0,0)) specially, make this explicit in both the function signature (with default parameters) and documentation. When extending existing APIs, maintain consistency with established patterns in the codebase.
Avoid unnecessary operations that can impact performance. This includes:
Example of improvements:
# Bad - Unnecessary string conversion and temporary storage
content = path.read_text(encoding="utf-8")
pyproject = tomllib.loads(content)
# Good - Direct loading
pyproject = tomllib.loads(path.read_text(encoding="utf-8"))
# Bad - Redundant str conversion in logging
log.debug("Selected choice: %s", str(node))
# Good - Let logging handle the conversion
log.debug("Selected choice: %s", node)
These optimizations are particularly important in performance-critical paths and frequently executed code sections.
Configuration systems should be designed with modularity and clarity in mind. When creating configuration classes or mechanisms:
// Good practice - clear separation of concerns
class AcceleratorAllocatorConfig {
// Common settings applicable to all accelerators
};
class CUDAAllocatorConfig : public AcceleratorAllocatorConfig {
// CUDA-specific settings
};
device_malloc not cudamalloc)pinned_ for pinned memory settings)Document all configuration options: Each option should have clear documentation explaining its purpose, valid values, and implications.
Design for extensibility: Implement hook mechanisms that allow domain-specific configurations to be integrated with generic ones.
These practices improve maintainability by making configuration systems more intuitive, better documented, and easier to extend for new devices or backends.
Prioritize human readability when writing code. Split complex expressions into steps with meaningful variable names. Extract repeated logic into well-named functions. Avoid magic numbers - derive values from existing structures or use named constants. Simplify control flow by reducing nesting levels and using early returns.
// Instead of:
if (VP8_STATUS_OK == WebPGetFeatures(header, sizeof(header), &features)) {
// Many lines of nested code
}
// Prefer:
if (VP8_STATUS_OK < WebPGetFeatures(header, sizeof(header), &features))
return false;
// For complex conditions, split into steps:
// Instead of:
if(cv::gapi::getCompileArg<std::reference_wrapper<cv::gapi::wip::ov::workload_type>>(compileArgs).has_value()) {
// ...
// Prefer:
auto workload = cv::gapi::getCompileArg<std::reference_wrapper<cv::gapi::wip::ov::workload_type>>(compileArgs);
if(workload.has_value()) {
// ...
// Instead of magic numbers:
const Mat points_mat = Mat(Size(6, 24), CV_32F, &points_data);
// Prefer:
const size_t channels = 6; // 3 coordinates + 3 color values
const size_t pointCount = sizeof(points_data)/(channels*sizeof(float));
const Mat points_mat = Mat(Size(channels, pointCount), CV_32F, &points_data);
Choose names that clearly communicate purpose and meaning rather than using abbreviations or unclear terms. Names should be self-documenting and make the code’s intent obvious without requiring additional context.
Avoid abbreviations that obscure meaning. Instead of ds use downscale, instead of audioData and microphone use rawAudio and audioMetadata to clarify their distinct purposes.
Replace computed expressions with semantic variable names. Instead of repeatedly using width / scale, define clear variables like inputSize and outputSize.
Make struct and class names descriptive of their actual purpose. Instead of generic names like SmolModelDataV2, use specific names like DrivingModelData that indicate what the data represents.
Example:
// Poor naming - unclear purpose
void OS04C10::OS04C10_IFE_ds_override() { ... }
struct SmolModelDataV2 { ... }
// Better naming - clear and descriptive
void OS04C10::ife_downscale_configure() { ... }
struct DrivingModelData { ... }
This approach makes code more maintainable and reduces the need for developers to reference other files or documentation to understand what identifiers represent.
Always document configuration decisions in package metadata files like pyproject.toml with clear comments, especially when:
When configuration decisions deviate from best practices, include the reasoning and any relevant links or references. Additionally, implement linters to ensure consistency between related configuration sections (e.g., Python version constraints and classifiers).
Example:
[project]
# TODO: change to `license = "BSD-3-Clause"` and enable PEP 639 after pinning setuptools>=77
# FIXME: As of 2025.06.20, it is hard to ensure the minimum version of setuptools in our CI environment.
# TOML-table-based license deprecated in setuptools>=77, and the deprecation warning will be changed
# to an error on 2026.02.18. See also: https://github.com/pypa/setuptools/issues/4903
license = { text = "BSD-3-Clause" }
requires-python = ">=3.9" # also update classifiers when changing this
This approach ensures that future developers understand the context behind configuration choices and helps maintain consistency across the codebase. It also creates clear reminders for revisiting temporary workarounds as technical constraints evolve.
Always initialize variables with sensible default values and validate inputs to prevent null reference errors and undefined behavior. This includes three key practices:
Initialize with defaults: Set initial values in constructors to avoid uninitialized state issues, especially when methods may be called before updates occur.
Validate inputs: Check that input parameters meet expected formats and constraints before processing, even if you don’t validate the full domain.
Handle missing values: Provide explicit fallback behavior when parameters or configuration values might be missing or deleted.
Example from the codebase:
# Good: Initialize with default value
def __init__(self):
self.avg_dt = MovingAverage(100)
self.avg_dt.add_value(self._interval) # Prevents uninitialized state
# Good: Validate input format
def setEsimProfile(iccid: str):
# Validate input is valid ICCID format
if not is_valid_iccid(iccid):
raise ValueError("Invalid ICCID format")
HARDWARE.get_sim_lpa().switch_profile(iccid)
# Good: Handle missing parameters with fallback
def read_param(self):
param_value = self.params.get('LongitudinalPersonality')
if param_value is not None:
self.personality = param_value
else:
self.personality = log.LongitudinalPersonality.standard # Fallback
This prevents runtime errors from null references, uninitialized variables, and invalid inputs while ensuring predictable behavior.
Implement proper hardware compatibility patterns when working with different GPU backends and AI frameworks. Many AI applications need to support multiple hardware platforms (NVIDIA CUDA, AMD ROCm, Intel XPU, Moore Threads, DirectML, ZLUDA) which have different capabilities and limitations.
Key practices:
Example implementation:
# Device-specific handling with fallbacks
if image.device.type == 'musa':
# Moore Threads GPU doesn't support bicubic with antialias
image = image.cpu()
image = torch.nn.functional.interpolate(image, size=scale_size, mode="bicubic", antialias=True)
image = image.to('musa')
else:
image = torch.nn.functional.interpolate(image, size=scale_size, mode="bicubic", antialias=True)
# Hardware detection with specific optimizations
if "[ZLUDA]" in torch_device_name:
torch.backends.cudnn.enabled = False
torch.backends.cuda.enable_flash_sdp(False)
torch.backends.cuda.enable_math_sdp(True)
torch.backends.cuda.enable_mem_efficient_sdp(False)
# DirectML-specific tensor operations
if comfy.model_management.is_directml_enabled():
latents_ubyte = latents_ubyte.to(dtype=torch.uint8)
latents_ubyte = latents_ubyte.to(device="cpu", dtype=torch.uint8, non_blocking=...)
This approach ensures AI applications work reliably across different hardware while taking advantage of platform-specific optimizations where available.
Before implementing common algorithms or utilities, check if the codebase already contains an appropriate implementation. Reusing existing, tested code reduces bugs, improves maintainability, and often provides better performance characteristics.
For example, instead of reimplementing a counting function:
// Don't reimplement existing functionality
template <typename T>
size_t count_leading_zeros(T val) {
// Custom implementation...
}
Use the existing implementation:
// Do use existing implementations
#include <c10/util/llvmMathExtras.h>
// Then use LeadingZerosCounter directly
Similarly, when selecting algorithms (like random number generators), evaluate existing options based on required properties such as period length or performance characteristics. For instance, prefer VSL_BRNG_PHILOX4X32X10 or VSL_BRNG_MT19937 over simpler generators if statistical quality is important, rather than implementing custom variants.
This principle helps maintain code consistency, avoids duplication of effort, and leverages optimizations already present in established implementations.
Always pin specific versions of dependencies, tools, and commits in configuration files to ensure consistent behavior across environments and deployments. When pinning versions, include comments explaining the reasoning behind the specific version choice.
This practice prevents unexpected breakages from automatic updates and ensures all team members and deployment environments use identical dependency versions. When allowing version overrides through parameters, maintain the pinned version as the default fallback.
Example:
# Pin specific versions with explanatory comments
brew "llvm@19" # pinned for tinygrad compatibility
# In build scripts, allow override but keep pinned default
COMMIT="${1:-66030a7de62c9e1ee8ab30a1d657a740333bb4f2}" # default pinned commit
# Version numbers should be incremented properly
export AGNOS_VERSION="12" # increment ensures all devices run same version
This approach maintains stability while allowing flexibility when needed, and the comments help future maintainers understand the rationale behind version choices.
AI applications must properly handle different GPU platforms (NVIDIA CUDA, AMD ROCm, Iluvatar Corex, etc.) through both build-time configuration and runtime capability detection. This ensures models can run efficiently across diverse hardware environments.
Build-time considerations:
Runtime considerations:
Example implementation:
# Runtime capability check
def cuda_malloc_supported():
# Check if platform supports cudaMallocAsync
if platform_is_iluvatar():
return False
return True
# Build-time configuration
# docker build --build-arg VARIANT=cu126 . # NVIDIA
# docker build --build-arg VARIANT=rocm6.2 . # AMD
# python main.py --disable-cuda-malloc # Iluvatar fallback
This approach ensures AI applications remain portable and performant across different hardware platforms while leveraging platform-specific optimizations when available.
Always use OpenCV’s built-in error handling mechanisms instead of C++ exceptions or custom error handling. This ensures consistent error handling across the codebase and proper integration with OpenCV’s error handling infrastructure.
Key guidelines:
Example:
void processImage(InputArray src, OutputArray dst, int param) {
// Input validation
CV_Assert(src.dims() <= 2 && src.channels() <= 4);
CV_Assert(param > 0 && param < 100);
// Runtime error handling
if (!src.isContinuous())
CV_Error(Error::StsBadArg, "Input array must be continuous");
// Warning for non-fatal issues
if (param < 10)
CV_LOG_WARNING(NULL, "Parameter value < 10 may reduce accuracy");
// Return false instead of throwing
if (!processData())
return false;
}
Prefer efficient memory allocation patterns to improve performance. Key practices:
Example - Before:
// Inefficient allocation patterns
char* get_raw_data() {
return new char[size]; // Raw pointer, potential memory leak
}
std::vector<Mat> img_vec;
img_vec.push_back(img); // Potential reallocation
fcvPyramidLevel_v2 *framePyr = new fcvPyramidLevel_v2[2]; // Unnecessary heap allocation
Example - After:
// Efficient allocation patterns
Mat get_data() {
return Mat(size); // RAII handles cleanup
}
std::vector<Mat> img_vec(1, img); // Pre-allocated size
fcvPyramidLevel_v2 framePyr[2]; // Stack allocation for small arrays
Benefits:
Write code that prioritizes readability and explicitness over cleverness or brevity. This includes several key practices:
Import Organization: Follow standard import ordering - stdlib and third-party imports first, then openpilot imports after a blank line:
import os
import threading
import numpy as np
from openpilot.common.params import Params
from openpilot.selfdrive.ui.ui_state import ui_state
Explicit Conditionals: Use clear if-elif chains instead of complex conditional expressions:
# Prefer this:
if self.CP.carFingerprint in FCEV_CAR:
ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 254.
elif self.CP.carFingerprint in HYBRID_CAR:
ret.gas = cp.vl["E_EMS11"]["CR_Vcu_AccPedDep_Pos"] / 254.
else:
ret.gas = cp.vl["E_EMS11"]["Accel_Pedal_Pos"] / 254.
# Over this:
gas_sig = "Accel_Pedal_Pos" if self.CP.carFingerprint in EV_CAR else \
"ACCELERATOR_PEDAL" if self.CP.carFingerprint in FCEV_CAR else \
"CR_Vcu_AccPedDep_Pos"
Simple Variable Assignment: Avoid walrus operators and complex expressions when simple two-line assignments are clearer:
# Prefer this:
events_changed = self.events.names != self.events_prev
if events_changed:
# Over this:
if events_changed := (self.events.names != self.events_prev):
Meaningful Variable Names: Use descriptive variables instead of magic numbers or complex expressions:
# Prefer this:
counter = int(CS.sccm_right_stalk["SCCM_rightStalkCounter"])
can_sends.append(self.tesla_can.right_stalk_press(counter + 1, 1))
can_sends.append(self.tesla_can.right_stalk_press(counter + 2, 0))
# Over this:
counter = int(CS.sccm_right_stalk["SCCM_rightStalkCounter"] + 1) % 16
can_sends.append(self.tesla_can.right_stalk_press(counter, 1))
can_sends.append(self.tesla_can.right_stalk_press((counter + 1) % 16, 0))
The goal is to write code that other developers can quickly understand without having to decode complex expressions or trace through clever logic.
Always validate and sanitize file paths from user input to prevent directory traversal attacks. Malicious actors can use path manipulation techniques like ../../../ sequences or absolute paths to access files outside intended directories, potentially overwriting critical system files or accessing sensitive data.
Key validation steps:
Example of vulnerable code:
# BAD: No validation allows path traversal
model_name = user_input # Could be "../../../../passwd"
file_path = os.path.join(models_dir, model_sub_directory, model_name)
Example of secure implementation:
# GOOD: Validate filename and check final path
def validate_filename(filename):
# Reject dangerous characters and sequences
if '..' in filename or '/' in filename or '\\' in filename:
return False
return True
if not validate_filename(model_name):
raise ValueError("Invalid filename")
file_path = os.path.join(models_dir, model_sub_directory, model_name)
resolved_path = os.path.abspath(file_path)
# Ensure final path is within allowed directory
if not resolved_path.startswith(os.path.abspath(models_dir)):
raise ValueError("Path outside allowed directory")
This prevents attackers from writing malicious code to locations like custom_nodes/*/.__init__.py or accessing sensitive system directories.
Choose descriptive, self-documenting names for constants, functions, parameters, and types that clearly communicate their purpose and meaning. Avoid magic numbers, generic strings, and ambiguous identifiers that require additional context to understand.
Replace magic values with named constants:
# Instead of:
win32event.WaitForSingleObject(hProcess, 10 * 1000)
# Use:
TEN_SECONDS_MS = 10 * 1000
win32event.WaitForSingleObject(hProcess, TEN_SECONDS_MS)
Use semantic constants instead of magic strings:
# Instead of:
{"source": ("*", {})}
# Use:
{"source": (node_typing.IO.ANY, {})}
Choose accurate function names that reflect their actual behavior:
# Instead of:
def init_builtin_custom_nodes():
# Use:
def init_builtin_extra_nodes():
Use specific type annotations that communicate intent:
# Instead of:
def filter_files_content_types(files: List[str], content_types: List[str]) -> List[str]:
# Use:
def filter_files_content_types(files: List[str], content_types: Literal["image", "video", "audio"]) -> List[str]:
This practice makes code self-documenting, reduces the need for comments, and helps prevent misunderstandings about the code’s purpose and behavior.
Functions should raise exceptions with meaningful messages instead of returning False, None, or silently catching all exceptions. This allows calling code to properly understand what went wrong and take appropriate action.
Key principles:
Example of problematic pattern:
def path_is_low_integrity_writable(path):
result = subprocess.run([ICACLS_PATH, path], capture_output=True, text=True)
if result.returncode != 0:
# Silent failure - calling code doesn't know what went wrong
return False
return does_permit_low_integrity_write(result.stdout)
Improved approach:
def path_is_low_integrity_writable(path):
result = subprocess.run([ICACLS_PATH, path], capture_output=True, text=True)
if result.returncode != 0:
raise PermissionError(f"Failed to check ACL for path {path}: {result.stderr}")
return does_permit_low_integrity_write(result.stdout)
Additional considerations:
Add explanatory comments or docstrings for complex, specialized, or non-obvious code that may not be immediately clear to other developers. This includes magic constants, platform-specific operations, advanced APIs, and implementation decisions with specific reasoning.
Key areas requiring documentation:
Example for magic constants:
# Windows Low Integrity Level SID - restricts process permissions for sandboxing
LOW_INTEGRITY_SID_STRING = "S-1-16-4096"
Example for specialized functions:
def set_process_integrity_level_to_low():
"""
Set the current process to run at a low integrity level.
This restricts the process's permissions, creating a sandboxed environment
to limit potential damage if compromised.
"""
Example for implementation decisions:
# Use .tmp suffix during download to prevent incomplete state if interrupted
# Otherwise CTRL+C during download leaves ComfyUI thinking frontend is installed
tmp_path = web_root + ".tmp"
This ensures code maintainability and helps other developers understand the reasoning behind complex or specialized implementations.
When implementing AI model inference code, always validate tensor dimensions and shapes before manipulating them. Neural network outputs often have complex multi-dimensional structures that require careful handling. Adding explicit dimension checks prevents subtle runtime errors, improves code robustness, and makes debugging easier.
Before reshaping tensors or extracting specific values:
Example:
// Before tensor manipulation, add validation
CV_CheckEQ(outs[0].dims, 3, "Expected 3D tensor output");
CV_CheckEQ((outs[0].size[2] == nc + 5 || outs[0].size[2] == nc + 4), true, "Invalid output shape");
// Then proceed with manipulation
vector<Mat> channels;
for (int i = 0; i < 3; ++i) {
channels.push_back(Mat(output_transposed.size[1], output_transposed.size[2], CV_32F,
output_transposed.ptr<float>(i)));
}
For parameters derived from tensor shapes, consider whether they should be computed or passed as parameters based on the model’s architecture. Always document your assumptions about tensor shapes, especially when working with different AI model formats or versions.
When modifying build scripts or configurations, ensure compatibility across all supported environments and properly test changes through CI pipelines. For tools with version-dependent features, add version checks and provide alternative implementations for older versions.
Example for CMake version-specific features:
if(CMAKE_VERSION VERSION_LESS "3.13")
# Use older approach for CMake < 3.13
set(PROTOBUF_GENERATE_CPP_APPEND_PATH ON)
protobuf_generate_cpp(fw_srcs fw_hdrs ${proto_files})
else()
# Use newer approach available in CMake 3.13+
protobuf_generate(
APPEND_PATH
LANGUAGE cpp
IMPORT_DIRS ${Protobuf_IMPORT_DIRS}
OUT_VAR fw_srcs
PROTOC_EXE ${Protobuf_PROTOC_EXECUTABLE}
PROTOS ${proto_files})
# Process the output variables as needed
set(fw_hdrs "${fw_srcs}")
list(FILTER fw_srcs EXCLUDE REGEX ".+\.h$")
list(FILTER fw_hdrs INCLUDE REGEX ".+\.h$")
endif()
Always reference the specific CI workflow that validates your build changes (e.g., “This change is tested by the workflow at .github/workflows/OCV-PR-4.x-Android-Test.yaml”) to demonstrate the build continues to work across all supported platforms and configurations.
Replace all print() statements with appropriate logging calls using Python’s built-in logging module. This applies to debug output, informational messages, and error reporting. Print statements should be reserved only for direct user interaction or when logging infrastructure is not available.
Use appropriate logging levels:
logging.debug() for debug informationlogging.info() for general informational messageslogging.warning() for warningslogging.error() for error conditionsExample transformation:
# Instead of:
print(f"Error reading version in get_workflow_templates_version: {e}")
print("Single LLAMA3_8 for HiDreams")
print(mask.shape)
# Use:
logging.error(f"Error reading version in get_workflow_templates_version: {e}")
logging.info("Single LLAMA3_8 for HiDreams")
logging.debug(f"Mask shape: {mask.shape}")
This ensures consistent log formatting, proper log levels, and enables centralized log management and filtering. Remove debug print statements entirely when they’re no longer needed, and ensure you’re using Python’s standard logging module rather than custom logging libraries.
Design CI/CD workflows with reusability and clear naming conventions from the start. Use meaningful prefixes that reflect the conceptual purpose (like “trunk” for trunk-based development), and consider future extraction into standalone, parameterized actions when similar functionality might be needed across repositories.
For workflow implementation:
Example:
name: reusable-build-workflow
on:
workflow_call:
inputs:
commit_sha:
description: 'Commit SHA to build (leave empty for current HEAD)'
required: false
type: string
prefix:
description: 'Tag prefix to use (e.g. trunk)'
required: true
type: string
jobs:
build:
steps:
- name: Set variables
id: vars
run: |
COMMIT_SHA="${{ inputs.commit_sha || github.sha }}"
echo "tag_name=${{ inputs.prefix }}/${COMMIT_SHA}" >> $GITHUB_OUTPUT
# For package installation, use consistent approach with explicit flags
- name: Install dependencies
run: pip install cmake --force-reinstall
This approach makes workflows more maintainable and enables cross-repository sharing of common CI/CD patterns.
Minimize CPU overhead in container operations by using efficient data structure patterns:
// Efficient: Creates map once for all calls void handle() { static std::unordered_map<int, HandlerFn> handler_map = { /* entries */ }; // … }
2. **Prefer emplace over insert** for maps and other containers to avoid unnecessary temporary object construction:
```cpp
// Less efficient: Creates a temporary pair object
args.insert({DNNL_ARG_SRC, dnnl::memory(m1_md, eng, m1.data_ptr())});
// More efficient: Constructs the object in-place
args.emplace(DNNL_ARG_SRC, dnnl::memory(m1_md, eng, m1.data_ptr()));
These optimizations reduce memory allocations, minimize CPU cycles, and can significantly improve performance in hot code paths or when working with large containers.
Always use type-appropriate mechanisms to represent the absence of a value. For objects, use default constructors rather than nullptr. For potentially absent values, consider using optional types. For pointers, use null checks before performing operations on them.
Examples:
bias_md = nullptr; when bias_md is an object type (dnnl::memory::desc)CORRECT: bias_md = dnnl::memory::desc(); to represent an “empty” descriptor
ncclHeartbeatMonitorThread_ = std::thread(...); without checking current state// Check nullness before assignment to prevent issues on second call
if (!ncclHeartbeatMonitorThread_.joinable()) {
ncclHeartbeatMonitorThread_ = std::thread(...);
}
This practice improves type safety, prevents null pointer dereferences, and creates more maintainable code by using language features designed for representing absence of values.
Write tests with proper assertions to ensure reliability and maintainability. Follow these guidelines:
string path = cvtest::findDataFile("test_image.png");
Mat img = imread(path);
ASSERT_FALSE(img.empty()) << "Cannot open test image: " << path;
// Use EXPECT_* for test validations that shouldn’t interrupt the test EXPECT_EQ(dst.cols, 270);
3. **Maintain correct parameter order** in equality assertions with (expected, actual) to generate meaningful error messages:
```cpp
// Correct: ASSERT_EQ(expected_reference, actual_result)
ASSERT_EQ(4, img.channels());
EXPECT_EQ(6, lines[0][0]);
// Use instead of manual matrix comparison loops
EXPECT_MAT_NEAR(src_mat, dst_mat, 0);
// or
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), src_mat, dst_mat);
Well-written assertions make tests more reliable, easier to debug, and help identify the exact cause of failures.
Variable, method, and class names should accurately reflect their actual behavior and purpose. Misleading or vague names create confusion and make code harder to understand and maintain.
Key principles:
Examples of improvements:
# Bad: misleading name
params_reader.put_nonblocking("LiveParameters", msg_dat) # writes but called "reader"
# Good: accurate name
params_writer.put_nonblocking("LiveParameters", msg_dat)
# Bad: vague name
def switchEsimProfile(iccid: str):
# Good: clear action
def setEsimProfile(iccid: str):
# Bad: ambiguous state
"ENABLED": 1 # could mean active or just available
# Good: specific meaning
"LKAS_AVAILABLE": 1
# Bad: generic name
def daemon_alive(cam):
# Good: descriptive purpose
def camera_thread(cam):
When reviewing names, ask: “Does this name accurately describe what this code element actually does or represents?” If there’s any ambiguity or mismatch between the name and behavior, suggest a more precise alternative.
When implementing algorithms, prioritize both correctness and performance by selecting appropriate data structures, optimizing memory usage, and leveraging language features.
Implement proper three-way comparisons that handle equality cases correctly:
// INCORRECT: Returns only -1 or 1, missing 0 for equality
inline int WeightedDeltaCompare(const void* const a, const void* const b) {
return (reinterpret_cast<const WeightedDelta*>(a)->delta -
reinterpret_cast<const WeightedDelta*>(b)->delta) <= 0 ? 1 : -1;
}
// CORRECT: Returns -1, 0, or 1 for proper ordering
inline int WeightedDeltaCompare(const void* const a, const void* const b) {
float delta_a = reinterpret_cast<const WeightedDelta*>(a)->delta;
float delta_b = reinterpret_cast<const WeightedDelta*>(b)->delta;
if (delta_a < delta_b) return -1;
if (delta_a > delta_b) return 1;
return 0;
}
Defer memory allocation until needed to avoid unnecessary resource consumption:
// INEFFICIENT: Creates vector regardless of whether it will be used
std::vector<std::uint16_t> uint16_data;
if (GetDataType() != QNN_DATATYPE_SFIXED_POINT_16) {
return;
}
// EFFICIENT: Only creates vector when it will be used
if (GetDataType() != QNN_DATATYPE_SFIXED_POINT_16) {
return;
}
std::vector<std::uint16_t> uint16_data;
Use std::iota for sequential initialization instead of manual loops:
// INEFFICIENT: Manual population of sequential values
std::vector<TypeParam> values;
for (int i = 0; i < 32768; i++) {
values.push_back(i);
}
// EFFICIENT: Use std::iota for sequential initialization
std::vector<TypeParam> values(32768);
std::iota(values.begin(), values.end(), TypeParam(0));
Use std::move when transferring collections to optimize performance:
// INEFFICIENT: Copying elements one by one
for (const auto& op_wrapper : op_wrappers) {
graph_op_wrappers.emplace_back(op_wrapper);
}
// EFFICIENT: Moving entire collection at once
std::move(op_wrappers.begin(), op_wrappers.end(),
std::back_inserter(graph_op_wrappers));
Ensure mathematical algorithms handle edge cases and are implemented according to their proper definitions:
// INCORRECT: Wrong implementation of floormod
// floormod(x,y) = (x/y) - floor(x/y)
// CORRECT: Proper implementation with additional multiplication
// floormod(x,y) = ((x/y) - floor(x/y))*y
Be vigilant about integer overflow, especially in calculations involving ranges or large numbers:
// VULNERABLE to overflow when limit-start is large
auto size_auto = Eigen::numext::ceil(Eigen::numext::abs((limit - start) / delta));
// SAFER approach to avoid overflow
auto size_auto = Eigen::numext::ceil(
Eigen::numext::abs((limit / delta) - (start / delta)));
Select the right pointer type based on ownership semantics to prevent null reference issues and memory leaks. Follow these guidelines:
shared_ptr, unique_ptr) when ownership transfer is neededweak_ptr for non-owning references to shared objects to avoid cyclic dependenciesBe explicit about object lifecycle by properly defining or deleting special member functions in classes that manage resources.
// GOOD: Clear ownership with smart pointer
std::unique_ptr<HeartbeatMonitor> monitor_ = std::make_unique<HeartbeatMonitor>();
// GOOD: Non-owning reference to shared object, avoids cyclic dependency
std::weak_ptr<ProcessGroupNCCL> processGroup_;
// ACCEPTABLE: Raw pointer when lifecycle is contained within parent
// HeartbeatMonitor(ProcessGroupNCCL* pg); // Only if pg's lifetime > HeartbeatMonitor
// GOOD: Explicitly handle or delete copy semantics to prevent null reference issues
struct MPSCachedKernel {
MPSCachedKernel(NSObject* object) : _object([object retain]) {}
MPSCachedKernel(const MPSCachedKernel&) = delete; // Prevent accidental copies
// ...
};
Establish a consistent pattern for feature flags and dependency management in configuration files:
WITH_* or OPENCV_ENABLE_* variables to represent user intentions (features to enable if available)find_package() and preferably try_compile() to validate dependenciesHAVE_* variables based on actual availability check resultsHAVE_* checksExample:
# User intention
ocv_option(OPENCV_ENABLE_EGL_INTEROP "Build with EGL interoperability support" ON)
# Actual detection (in main CMakeLists.txt)
if(OPENCV_ENABLE_EGL_INTEROP)
find_package(EGL)
if(EGL_FOUND)
set(HAVE_EGL_INTEROP ON)
endif()
endif()
# Usage in module CMakeLists.txt
if(HAVE_EGL_INTEROP)
# Prefer target-based dependencies
target_link_libraries(${the_module} PUBLIC ocv.3rdparty.egl)
# Make definitions PUBLIC if used in headers
target_compile_definitions(${the_module} PUBLIC HAVE_EGL_INTEROP)
endif()
This convention ensures all dependencies are properly detected during configuration stage, not build stage, preventing build failures due to missing dependencies. It clearly separates user intent from actual availability and promotes modern CMake practices.
When working with PyTorch tensors, look for opportunities to optimize operation chains for better performance and memory efficiency. This involves two key strategies:
def optimized_add(x: torch.Tensor, value: float) -> torch.Tensor:
if x.is_leaf:
x = x + value # Create new tensor for leaf nodes
else:
x += value # Inplace operation for non-leaf nodes
return x
# Instead of: x.add(1.0).div(2.0).clamp(0,1).mul(255.).round()
# Use: x.add(1.0).clamp(0,2).mul(127.5).round()
# This eliminates one operation while maintaining mathematical correctness
These optimizations are particularly important in neural network forward/backward passes where tensor operations are performed repeatedly on large data. Always verify mathematical equivalence when simplifying operation chains, and profile performance gains in your specific use case.
Make configuration values configurable through environment variables with sensible defaults instead of hard-coding them. This improves flexibility and testability while maintaining backward compatibility.
Use os.getenv() with appropriate type conversion and default values:
# Good: Configurable with defaults
YUV_BUFFER_COUNT = int(os.getenv("YUV_BUFFER_COUNT", "20"))
DUAL_CAMERA = bool(int(os.getenv("DUAL", "0")))
CAMERA_ROAD_ID = int(os.getenv("CAMERA_ROAD_ID", "0"))
# Bad: Hard-coded values
YUV_BUFFER_COUNT = 20
DUAL_CAMERA = False
CAMERA_ROAD_ID = 0
For platform-specific behavior, prefer hardware abstraction over hard-coded paths:
# Good: Use hardware abstraction
USER_AGENT = f"AGNOSSetup-{HARDWARE.get_os_version()}"
# Bad: Hard-coded file reading
USER_AGENT = f"AGNOSSetup-{open('/VERSION').read().strip()}"
This approach allows runtime configuration changes, easier testing with different values, and better separation of configuration from code logic.
When working with network-related data, always read from the most direct and authoritative source available rather than making assumptions or relying on indirect indicators. This ensures accuracy and robustness in network operations.
For network connections, query the active connection state directly instead of inferring properties from adapter information. For data format detection, examine file headers or content signatures rather than relying solely on file extensions that may be absent or misleading.
Example of preferred approach:
// Instead of guessing from adapter
bool WifiManager::currentNetworkMetered() {
// Read from active connection directly
return getActiveConnectionMeteredStatus();
}
// Instead of relying only on file extensions
if (url.find(".bz2") != std::string::npos) {
data = decompressBZ2(data, abort);
} else {
// Also detect from file header like python LogReader
if (detectBZ2Header(data)) {
data = decompressBZ2(data, abort);
}
}
This approach prevents issues when indirect indicators (like file extensions) are removed or when adapter properties don’t accurately reflect the actual network state.
Configuration management requires careful handling of optional dependencies in both build scripts and source code. Always guard code that depends on optional modules or libraries with appropriate feature guards, and check for component existence before using them.
In build scripts:
# Check for optional components before using them
FIND_LIBRARY(WEBP_MUX_LIBRARY NAMES webpmux)
if(WEBP_MUX_LIBRARY)
SET(WEBP_LIBRARIES ${WEBP_LIBRARIES} ${WEBP_MUX_LIBRARY})
endif()
In header files:
// Guard features that depend on optional modules
#ifdef HAVE_OPENCV_DNN
// DNN-dependent code here
#endif
For configuration variables, use standardized naming conventions:
HAVE_ prefix for feature availability (e.g., HAVE_ZLIB instead of ZLIB_FOUND)OPENCV_ prefix for OpenCV-specific settings to avoid conflicts (e.g., OPENCV_ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES)When detecting incompatible dependencies, provide clear messages and fallback options:
if(HAVE_CXX17 AND OPENEXR_VERSION VERSION_LESS "2.3.0")
message(STATUS "OpenEXR(ver ${OPENEXR_VERSION}) doesn't support C++17. Updating OpenEXR 2.3.0+ is required.")
# Provide fallback or clear error
endif()
Use clear, descriptive names that follow consistent patterns established in the codebase and broader programming standards. This includes:
// Better: Clearer indication of behavior void writeTo(OutputArray m) const;
2. Avoid unnecessary abbreviations when clarity would be improved:
```cpp
// Poor: Ambiguous abbreviation
CV_WRAP void computeCCM();
// Better: Clear meaning
CV_WRAP Mat computeColorCorrectionMatrix();
// Better: Consistent all-caps for constants enum ColorCheckerType { COLORCHECKER_MACBETH, COLORCHECKER_VINYL };
4. Follow established naming patterns for related classes or components:
```cpp
// Poor: Inconsistent with existing naming patterns
enum DisposalMethod {
GRFMT_GIF_Nothing = 0,
GRFMT_GIF_PreviousImage = 1
};
// Better: Consistent naming pattern
enum GifDisposeMethod {
GIF_DISPOSE_NONE = 1,
GIF_DISPOSE_RESTORE_PREVIOUS = 3
};
// Better: Clear indication this is a setter int setPaletteSize(int size);
This approach leads to more maintainable, readable, and self-documenting code while preserving consistency across the codebase.
---
## Optimize container access
<!-- source: opencv/opencv | topic: Performance Optimization | language: Other | updated: 2025-05-17 -->
Choose efficient container types and optimize access patterns in performance-critical code. Avoid operations that cause hidden allocations and minimize overhead when accessing container elements.
**Key practices:**
1. **Avoid in-place operations** that cause hidden copies:
```cpp
// Bad: causes hidden .clone() call
inputMat.convertTo(inputMat, CV_8UC1, 1.0 / 256);
// Good: use a separate destination
inputMat.convertTo(convertedMat, CV_8UC1, 1.0 / 256);
// Bad: vector of vectors has high overhead
std::vector<std::vector<uint16_t>> hist256(channels, std::vector<uint16_t>(256, 0));
// Good: single flat vector
std::vector<uint16_t> hist256(channels * 256, 0);
// Bad: repeatedly accessing vector methods in tight loops
for (int i = 0; i < size; i++) {
result += hist256[c][i];
}
// Good: extract pointer once before loop
std::vector<uint16_t> hist256vec(256, 0);
uint16_t* hist256 = hist256vec.data();
for (int i = 0; i < size; i++) {
result += hist256[i];
}
// Bad: unnecessary heap allocation
if (condition) {
std::vector<uchar> *dst = new std::vector<uchar>(size);
// use dst
delete dst;
}
// Good: stack allocation with proper scope
std::vector<uchar> dst;
if (condition) {
dst.resize(size);
// use dst
}
Choose container types based on actual performance measurements rather than assumptions, as the best data structure can vary by platform and usage pattern.
When modifying, deprecating, or replacing APIs, ensure a smooth transition experience for developers by following these practices:
@deprecated(
"`isinstance(treespec, LeafSpec)` is deprecated, "
"use `isinstance(treespec, TreeSpec)` and `treespec.is_leaf()` instead.",
category=FutureWarning,
)
class LeafSpec(TreeSpec):
# ...
Provide clear migration paths in deprecation messages and documentation that show exactly how to transition from old APIs to new ones.
Manage public exports by updating __all__ lists to remove deprecated items, preventing new code from adopting soon-to-be-removed APIs.
Ensure interoperability between old and new implementations during transition periods, allowing gradual migration without breaking existing code.
Following these practices helps maintain trust with developers using your libraries and reduces friction during necessary API evolution.
When implementing algorithms, create specialized versions for common cases to improve performance, while maintaining a generic version for completeness. For functions that process data with different channel counts, implement separate optimized code paths for 1-channel and 3-channel data, which represent the majority of image processing workloads.
For example, in histogram-based median filtering:
// Specialized version for 1-channel images
if (channels == 1) {
uint16_t* hist0 = hist256[0].data();
for (int x = x_start; x != x_end; x += x_step) {
// Optimized single-channel histogram update
}
}
// Specialized version for 3-channel images
else if (channels == 3) {
uint16_t* hist0 = hist256[0].data();
uint16_t* hist1 = hist256[1].data();
uint16_t* hist2 = hist256[2].data();
for (int x = x_start; x != x_end; x += x_step) {
// RGB-specific histogram update
}
}
// Generic version for other channel counts
else {
for (int x = x_start; x != x_end; x += x_step) {
// Generic multi-channel implementation
}
}
Structure loops efficiently to avoid redundant calculations. When processing arrays, consider vectorization boundaries and ensure proper handling of edge cases with minimum conditional branches. For iterative algorithms with fixed-size vectors, implement a tail-handling pattern:
size_t i = 0;
for (; i <= len - vl; i += vl) {
// Process full vector width
}
if (i < len) {
size_t tail_len = remaining_elements(len - i);
// Process remaining elements
}
This pattern avoids unnecessary modulo operations and extra variables for tracking remainders. When implementing algorithms with specialized branches, ensure that all cases are handled correctly, including those that don’t meet optimization criteria.
Always separate code from documentation and use proper referencing techniques. Documentation should be in markdown files when extensive, while code should be in files that are regularly checked for compilation.
When documenting APIs:
CV_EXPORTS_W for functions that should be included in Java and Python bindings@snippet and @include directives to embed code examples in documentationExample - Avoid:
/** @brief Enum of the possible types of ccm.
*/
enum CCM_TYPE
{
CCM_3x3, ///< The CCM with the shape \f$3\times3\f$ performs linear transformation on color values.
CCM_4x3, ///< The CCM with the shape \f$4\times3\f$ performs affine transformation.
};
// [followed by 200+ lines of in-header documentation]
Example - Prefer:
/** @brief Enum of the possible types of ccm.
* @see @ref ccm_documentation for detailed explanations
*/
enum CCM_TYPE
{
CCM_3x3, ///< The CCM with the shape \f$3\times3\f$ performs linear transformation
CCM_4x3, ///< The CCM with the shape \f$4\times3\f$ performs affine transformation
};
With detailed documentation in a markdown file referenced by @ref ccm_documentation and any code examples included via @snippet or @include directives.
When implementing algorithms, prefer using OpenCV’s built-in optimized functions over writing custom implementations. OpenCV’s library functions are typically vectorized, extensively tested, and optimized for performance across different platforms and hardware architectures.
Key examples:
inRange() instead of custom saturation checks (Discussion 7)cv::sum() for channel operations instead of manually splitting and summing (Discussion 9)divide(src, 2, dst) instead of creating intermediate matrices (Discussion 20)cv::PSNR() instead of custom implementations (Discussion 42)cv::RNG over standard library random generators for deterministic behavior and testability (Discussion 47)Example - Instead of this:
Mat saturate(Mat& src, const double& low, const double& up)
{
Mat dst = Mat::ones(src.size(), CV_8UC1);
MatIterator_<Vec3d> it_src = src.begin<Vec3d>(), end_src = src.end<Vec3d>();
MatIterator_<uchar> it_dst = dst.begin<uchar>();
for (; it_src != end_src; ++it_src, ++it_dst)
{
for (int i = 0; i < 3; ++i)
{
if ((*it_src)[i] > up || (*it_src)[i] < low)
{
*it_dst = 0;
break;
}
}
}
return dst;
}
Use this:
Mat saturate(Mat& src, const double& low, const double& up)
{
Mat dst;
inRange(src, Scalar(low, low, low), Scalar(up, up, up), dst);
return dst;
}
Documentation should provide complete, practical information while maintaining logical organization and information hierarchy. Ensure sections include all necessary details for users to successfully implement or understand the feature, and organize content to flow logically from basic to advanced concepts.
When adding new documentation sections:
For example, when documenting Docker usage:
# Complete example with practical details
docker run -it --rm \
-v /path/to/models:/app/models \
-v /path/to/output:/app/output \
-p 8188:8188 \
-e COMFYUI_PORT=8188 \
ghcr.io/comfyanonymous/comfyui:latest-cu124
Rather than just:
# Incomplete - only shows how to pull
docker pull ghcr.io/comfyanonymous/comfyui:latest-cu124
Organize sections to follow user progression: Introduction → Getting Started → Features → Advanced Topics → Development/Release Information.
Choose names that clearly communicate purpose and follow consistent patterns across the codebase:
# Instead of:
def check_have_ipp_flag(cmake_file):
# Check specifically for HAVE_IPP flag
# Prefer:
def check_cmake_flag_enabled(cmake_file, flag_name):
# Check for any flag
# Instead of changing:
corners, ids, rejected = aruco_detector.detectMarkers(img)
# To:
corners, ids, rejected, extra = aruco_detector.detectMarkers(img)
# Create a new method:
corners, ids, rejected, extra = aruco_detector.detectMarkersMultiDict(img)
Make build configuration options explicit and document their version dependencies. When introducing configuration parameters that are version-specific, clearly indicate compatibility requirements and provide command-line options to make constraints optional when appropriate.
For example, instead of hardcoding checks or settings:
# Not recommended: Hardcoded check with no option to disable
check_have_ipp_flag(os.path.join(builder.libdest, "CMakeVars.txt"))
# Better approach: Make the check configurable
if args.strict_dependencies:
check_have_ipp_flag(os.path.join(builder.libdest, "CMakeVars.txt"))
# When defining version-specific configurations, document requirements
# and use proper syntax
ABI("3", "arm64-v8a", None, 21, cmake_vars=dict(
# Supported in Android NDK r27 and higher, ignored in earlier versions
ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES='ON'
))
This approach ensures that configuration options remain flexible while clearly communicating version requirements to developers, preventing unexpected behavior across different environments.
Always ensure proper memory management when using dynamic allocation. Memory leaks are a critical performance issue that can degrade application performance over time and eventually lead to resource exhaustion.
Instead of using raw pointers with new without corresponding delete operations:
Poor example (potential memory leak):
ShapeDescriptor *descriptor = new ShapeDescriptor(dtype, order, shape);
// Missing corresponding delete
Better example:
// Using smart pointer
std::unique_ptr<ShapeDescriptor> descriptor =
std::make_unique<ShapeDescriptor>(dtype, order, shape);
// No explicit delete needed, memory will be freed automatically
// Or if raw pointer is necessary
ShapeDescriptor *descriptor = new ShapeDescriptor(dtype, order, shape);
try {
// use descriptor
// ...
delete descriptor; // Clean up when done
} catch (...) {
delete descriptor; // Clean up on exceptions too
throw;
}
Configure all systems with the minimum permissions required to function. For Kubernetes deployments, use security contexts that prevent privilege escalation and running as root:
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
runAsUser: 65532 # Use specific non-root UID matching Dockerfile
For RBAC permissions, regularly audit and remove unnecessary permissions. Test thoroughly after removing permissions to ensure the application still functions correctly. When introducing new permissions, document their purpose and limit their scope as much as possible. Following this principle reduces attack surface and minimizes potential damage from compromised components.
Keep code clean and consistent with established project conventions. This includes:
// Follow Allman style if file uses it
void function()
{
if (condition)
{
statement;
}
}
Avoid using namespace declarations as they pollute the namespace, even if the header is not included directly.
// Use feature macros if code might be needed later #ifdef EXPERIMENTAL_FEATURE for (int i1 = 0; i1 < STEP_SIZE; ++i1) { if (ptr + i1 < n1) { matOut[ptr + i1] = matA[ptr1 + i1] + matB[ptr2 + i1]; } } #endif
4. Prefer C++ templates over complex multi-line macros for better debugging and type safety.
5. Use standard type names rather than shortcuts (e.g., `unsigned char` instead of `uchar`).
Consistency in code style significantly improves readability and maintainability while reducing review friction.
---
## Framework synchronization practices
<!-- source: opencv/opencv | topic: Concurrency | language: C++ | updated: 2025-04-02 -->
When implementing concurrent code, always use the framework's provided synchronization primitives rather than direct language features. This ensures compatibility across all build configurations and platforms:
1. Use OpenCV synchronization mechanisms like `cv::getInitializationMutex()` and `cv::AutoLock` instead of standard C++ constructs like `std::mutex` and `std::lock_guard`:
```cpp
// Instead of this:
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
// Use this:
cv::AutoLock lock(cv::getInitializationMutex());
cv::getNumThreads() rather than hardcoding thread counts:// Instead of this:
m_parallel_runner = JxlThreadParallelRunnerMake(nullptr, 8); // Hardcoded value
// Use this:
m_parallel_runner = JxlThreadParallelRunnerMake(nullptr, cv::getNumThreads());
Be aware that thread counts vary by platform (e.g., Android defaults to 2, Linux uses all cores) and that nested parallel operations may be serialized.
When using static resources in multithreaded contexts, ensure proper synchronization or consider alternatives like on-demand initialization that avoid static state altogether.
These practices ensure your code remains compatible with special configurations like OPENCV_DISABLE_THREAD_SUPPORT while maintaining optimal performance across various platforms.
Avoid catching broad exception types like Exception and instead catch specific exceptions that you expect and can handle appropriately. When errors occur, they should be explicit rather than failing silently, and should include proper logging or re-raising when necessary.
Key principles:
except Exception: clausesExample of what to avoid:
try:
last_parameters_msg.liveParameters.stiffnessFactor = last_parameters_dict['stiffnessFactor']
params_reader.put("LiveParameters", last_parameters_msg.to_bytes())
except Exception: # Too broad, fails silently
pass
Better approach:
try:
last_parameters_msg.liveParameters.stiffnessFactor = last_parameters_dict['stiffnessFactor']
params_reader.put("LiveParameters", last_parameters_msg.to_bytes())
except (json.JSONDecodeError, KeyError) as e: # Specific exceptions
cloudlog.warn(f"Failed to migrate cached params: {e}")
This approach makes code more maintainable by clearly documenting what can go wrong and ensuring failures are visible rather than hidden.
When designing APIs, favor simple and explicit interfaces over flexible but complex ones. This reduces cognitive load, improves compile-time checking, and makes the code more maintainable.
Key principles:
Example - Instead of flexible but costly:
pub fn vocab<S: BuildHasher>(mut self, vocab: HashMap<String, u32, S>) -> Self {
// Implementation
}
Prefer explicit:
pub fn vocab(mut self, vocab: HashMap<String, u32>) -> Self {
// Implementation
}
Or when dealing with multiple return types, instead of:
fn token_to_word(token: usize) -> Option<(usize, usize)> | Option<usize> {
// Implementation varies based on sequence count
}
Prefer separate methods:
fn token_to_word(token: usize) -> Option<usize> {
// Single sequence implementation
}
fn token_to_word_with_sequence(token: usize) -> Option<(usize, usize)> {
// Multi-sequence implementation
}
This approach makes APIs more predictable, easier to maintain, and reduces potential runtime errors by catching issues at compile-time.
Always ensure all resources are properly released before raising errors to prevent resource leaks. This practice is essential for maintaining system stability and avoiding memory leaks in both normal and error conditions.
When handling errors, follow this pattern:
This approach is particularly important when working with external resources like Python references, locks, file handles, and memory allocations.
For example, instead of immediately raising an error:
// BAD: Error raised before cleanup is performed
if (!PyObject_IsInstance(obj, type))
CV_Error(cv::Error::StsBadArg, "Input stream should be derived from io.BufferedIOBase");
// The GIL is never released and 'type' reference is leaked
Set a flag, perform cleanup, then raise the error:
// GOOD: Cleanup performed before raising error
bool has_error = false;
if (!PyObject_IsInstance(obj, type))
has_error = true;
// Cleanup resources regardless of error
Py_DECREF(type);
PyGILState_Release(gstate);
// Raise error after cleanup
if (has_error)
CV_Error(cv::Error::StsBadArg, "Input stream should be derived from io.BufferedIOBase");
This pattern applies to all error scenarios, whether using exceptions (like CV_Error), assertions (CV_Assert), or returning error codes. By ensuring resources are released before propagating errors, you create more robust code that can handle failure scenarios gracefully.
When adding new imports to code files, always synchronize by updating the corresponding dependencies in BUILD files. Different build environments enforce dependency rules with varying strictness, so proper configuration is essential even if local builds succeed. This helps prevent errors like:
ERROR: Strict deps violations: //tensorflow/python/client:device_lib
In tensorflow/python/client/device_lib.py, no direct deps found for imports:
line 21: from tensorflow.python.platform import tf_logging as logging: Module "tensorflow.python.platform" not provided by a direct dep
When adding a new import like from tensorflow.python.platform import tf_logging as logging, ensure you also update the appropriate BUILD file to include this dependency, even if your local environment doesn’t immediately flag the missing dependency.
Maintain code clarity by using appropriate type declarations and parameter passing conventions:
auto when the type is known and simple:
```cpp
// Instead of:
auto device_ordinal = 0;// Prefer: int device_ordinal = 0;
2. **Use prefix form (`++i`) instead of postfix (`i++`) in loops** for better performance with non-primitive types:
```cpp
// Instead of:
for (int i = 0; i < perm.NumElements(); i++)
// Prefer:
for (int i = 0; i < perm.NumElements(); ++i)
const when they’re not modified:
```cpp
// Instead of:
std::vector// Prefer:
const std::vector
4. **Pass parameters appropriately**:
- Pass lightweight objects like span by value: `void foo(absl::Span<int64_t> dims)`
- Pass `const&` for larger objects: `void foo(const std::vector<int>& vec)`
- Mark function parameters as `const` when they're not modified
5. **Use C++-style casts instead of C-style casts**:
```cpp
// Instead of:
*itr = bfloat16(data[i]);
rescaled_6 = (int64_t)std::round(6.0f / input_qtype.getScale()) + input_qtype.getZeroPoint();
// Prefer:
*itr = static_cast<bfloat16>(data[i]);
rescaled_6 = static_cast<int64_t>(std::round(6.0f / input_qtype.getScale())) + input_qtype.getZeroPoint();
// Prefer: if (crop_window_vec(2) < 0 || crop_window_vec(3) < 0)
---
## optimize data structure selection
<!-- source: commaai/openpilot | topic: Algorithms | language: Python | updated: 2025-03-19 -->
Choose data structures and algorithms based on their computational complexity and access patterns rather than convenience. Consider performance implications when selecting between alternatives.
Key principles:
1. **Match data structure to access patterns**: Use `np.array` instead of Python lists when performing mathematical operations, as numpy can optimize operations internally without type conversion overhead.
2. **Choose algorithms based on constraints**: Select streaming algorithms when memory usage matters more than speed, and batch algorithms when speed is critical and memory is available.
3. **Avoid expensive operations in hot paths**: Replace costly operations like `inspect.getmodule()` with simpler alternatives such as direct I/O operations or cached lookups.
4. **Make implementations algorithm-agnostic**: Design interfaces that work with different underlying implementations (e.g., `queue.clear()` vs creating new queue instances).
Example from the codebase:
```python
# Before: Python list requiring conversion
self.posenet_stds = [POSENET_STD_INITIAL_VALUE] * (POSENET_STD_HIST_HALF * 2)
old_mean = np.mean(self.posenet_stds[:POSENET_STD_HIST_HALF]) # Converts list to array internally
# After: Direct numpy array for better performance
self.posenet_stds = np.array([POSENET_STD_INITIAL_VALUE] * (POSENET_STD_HIST_HALF * 2))
old_mean = np.mean(self.posenet_stds[:POSENET_STD_HIST_HALF]) # No conversion needed
When choosing between algorithmic approaches, document the trade-offs. For instance, zstd.decompress() is faster for files with size headers, while streaming decompression handles variable-size data but with slight performance cost. Choose based on your data characteristics and constraints.
When implementing resource cleanup in concurrent applications, avoid using deprecated finalizers and instead use PhantomReference-based cleanup mechanisms that ensure thread safety.
Key considerations:
Example implementation:
public final class SafeResourceCleaner {
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private final PhantomCleanable phantomCleanableList = new PhantomCleanable();
// Create a single cleaner per application/library component
public static SafeResourceCleaner create() {
SafeResourceCleaner cleaner = new SafeResourceCleaner();
cleaner.startCleanerThread();
return cleaner;
}
public Cleanable register(Object resource, Runnable cleanupAction) {
return new PhantomCleanable(
Objects.requireNonNull(resource),
Objects.requireNonNull(cleanupAction)
);
}
private void startCleanerThread() {
Thread thread = new Thread(() -> {
while (!isShutdown()) {
try {
// Use reasonable timeout to allow thread termination if needed
Cleanable ref = (Cleanable) queue.remove(60 * 1000L);
if (ref != null) {
ref.clean();
}
} catch (Throwable e) {
// Handle exceptions gracefully, never let them terminate the cleaner thread
}
}
}, "ResourceCleaner-Thread");
thread.setDaemon(true); // Don't prevent JVM shutdown
thread.start();
}
}
This approach is particularly important for concurrent applications where thread safety must be maintained during resource cleanup, and it provides a more reliable alternative to the deprecated finalize() method.
Use ALL_CAPS for constants and environment variables in shell scripts, and reference these variables consistently throughout the script with proper quoting. This improves code readability and prevents errors when handling paths with spaces.
Example:
# Correct
OUTPUT_FILE=tf_env.txt
PYTHON_BIN_PATH="$(which python || which python3 || die "Cannot find Python binary")"
# Then reference consistently
"${PYTHON_BIN_PATH}" -c 'import sys; print(sys.version_info[:])'
# Incorrect
python_bin_path=$(which python || which python3 || die "Cannot find Python binary")
python -c 'import sys; print(sys.version_info[:])' # Inconsistent reference
Using a consistent naming convention makes scripts more maintainable and helps other developers understand which values are constants. Double-quoting variables (like "${PYTHON_BIN_PATH}") ensures that paths with spaces are handled correctly.
When writing networking code that interacts with platform-specific features, always check for the existence of platform-specific functions or resources before attempting to use them. This prevents runtime errors when your code runs in different environments (Windows, Linux, macOS, containers) that might have different capabilities or implementations.
For example, when detecting network environment properties:
import platform
# Good practice - check if function exists before using
def get_network_platform_info():
info = {}
# Define platform functions that might provide network-related information
platform_checks = [
("network_os", "system"),
("container_environment", "freedesktop_os_release"),
("virtual_machine", "mac_ver")
]
# Only use functions that exist on the current platform
for label, function_name in platform_checks:
if hasattr(platform, function_name):
function = getattr(platform, function_name)
info[label] = function()
else:
info[label] = "N/A"
return info
This approach ensures your networking code gracefully handles different platforms rather than failing with attribute errors when a particular function isn’t available.
All unit tests should be (1) intentionally designed for coverage, (2) non-redundant, and (3) maintainable.
Apply these rules:
1) Enforce correctness with invariants
int cpucount = ncnn::get_cpu_count();
int bigcpucount = ncnn::get_big_cpu_count();
int littlecpucount = ncnn::get_little_cpu_count();
if (bigcpucount + littlecpucount != cpucount || bigcpucount > cpucount || !(littlecpucount < cpucount))
return -1;
2) Cover critical tensor ranks/shapes, not just “typical” ones
3) Reuse shared test helpers for layer/model execution
test_layer<>-style utility) instead of duplicating manual layer creation, parameter loading, pipeline creation, and forward logic.4) Remove duplicated or near-identical test cases
Result: tests become smaller, faster to review, easier to maintain, and less likely to miss regressions due to missing shape variants or redundant cases.
Design CI/CD workflows to minimize unnecessary resource consumption and provide faster feedback. Avoid triggering builds when changes don’t impact the build output, use appropriate event triggers, and implement clean artifact management strategies.
Key practices:
release: types: [published] for production deployments rather than building on every branch pushtype=edge,branch=master instead of type=ref,event=branch and avoid unnecessary tags like type=sha or type=ref,event=prExample of efficient workflow triggers:
on:
release:
types: [published] # Only build on actual releases
push:
branches: [master]
paths-ignore: ['docs/**', '*.md'] # Skip builds for doc changes
This approach reduces CI costs, speeds up feedback loops, and prevents resource waste while maintaining necessary build coverage.
Choose names that are both semantically precise and follow consistent conventions. Names should accurately reflect behavior and purpose while adhering to established patterns in the codebase.
Function naming:
// Poor: Function returns true for zero values too
bool IsPositive(const HloInstruction* hlo)
// Better: Name accurately describes behavior
bool IsNonNegative(const HloInstruction* hlo)
// Poor: Name suggests it only returns true/false
bool IsShapedUint8Type(OpBuilder& builder, const Type type, Type& rescaled_type)
// Better: Name indicates it extracts information
bool ExtractUint8TypeInfo(OpBuilder& builder, const ShapedType type, Type& rescaled_type)
Variable naming:
// Poor: Technical implementation detail
auto a0_pad_const_op = rewriter.create<tosa::ConstOp>();
// Better: Role-based description
auto padding_const_op = rewriter.create<tosa::ConstOp>();
// Poor: Abbreviated form
bool merge_h_to_d_stream = true;
// Better: Fully descriptive
bool merge_host_to_device_stream = true;
Consistency:
thisIsTheFunctionName()empty_lines not emptyLinesThese naming practices improve readability, maintainability, and reduce bugs caused by misunderstandings about code behavior.
Always check that pointers, optional values, and results of type casts are valid before dereferencing or using them. This prevents null pointer exceptions, undefined behavior, and potential crashes in production.
For pointers obtained from operations or external sources:
// Before accessing a pointer's members
if (value.getDefiningOp() != nullptr) {
// Now safe to use value.getDefiningOp()->getResult(0)
}
For optional values, verify presence before access:
auto shared_library_dir = FindDispatchOption(options, num_options, kDispatchOptionSharedLibraryDir);
if (shared_library_dir.HasValue()) {
shared_library_dir_opt.emplace(std::any_cast<const char*>(shared_library_dir.Value()));
}
For dynamic casts, check success before using the result:
auto input_type = input_value.getType().dyn_cast<RankedTensorType>();
if (!input_type) {
op->emitOpError("Input type not ranked tensor");
return nullptr;
}
When designing APIs, preserve nullability expectations to maintain compatibility:
// Check parameters that might be null rather than requiring non-null
if (run_metadata != nullptr) {
// Only use run_metadata when it's provided
}
When configuring applications in containerized environments, prefer using the application’s built-in configuration mechanisms over extensive external configuration like multiple volume mounts or environment variable overrides. This approach reduces complexity, improves maintainability, and leverages the application’s intended configuration patterns.
For example, instead of mounting multiple individual directories:
volumes:
- "./models:/app/models"
- "./input:/app/input"
- "./temp:/app/output/temp"
- "./output:/app/output"
- "./user:/app/user"
- "./custom_venv:/app/custom_venv"
- "./custom_nodes:/app/custom_nodes"
Use the application’s native configuration support with a single base directory and let the application manage its internal structure:
volumes:
- "./data:/home/comfyui/data"
command: ["--base-directory", "/home/comfyui/data"]
This pattern applies broadly - look for CLI arguments, configuration files, or environment variables that allow applications to self-organize their directory structure and file locations rather than imposing external mounting schemes. Additionally, avoid mixing conflicting configuration options (like image + build in Docker Compose) that can lead to unexpected behavior.
Implement comprehensive security measures in containerized applications to prevent privilege escalation, injection attacks, and unauthorized access. This includes proper user configuration, variable quoting, and secure process handling.
Key security practices:
setpriv for secure user switching and exec for proper signal handlingExample of secure variable quoting:
# Vulnerable - unquoted variables
CMD python -u main.py --listen ${COMFYUI_ADDRESS} --port ${COMFYUI_PORT}
# Secure - quoted variables
CMD python -u main.py --listen "${COMFYUI_ADDRESS}" --port "${COMFYUI_PORT}"
Example of secure user configuration:
# Use standard secure UID/GID
ARG USER_UID=999
ARG USER_GID=999
# Create system user with restricted permissions
RUN adduser --system --home /home/user --uid ${USER_UID} --group user
These practices significantly reduce attack surface and prevent common container security vulnerabilities.
When configuring TCP socket options, always check the platform and apply appropriate settings for each operating system. Different platforms support different socket options and may require different approaches for connection management.
Use proper platform detection with sys.platform to conditionally apply socket options. For example, TCP_USER_TIMEOUT is Linux-specific, while TCP_KEEPALIVE is used on Darwin (macOS). Always provide fallbacks or alternative approaches for unsupported platforms.
Example implementation:
if sys.platform == 'linux':
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_USER_TIMEOUT, 16000 if onroad else 0)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 7 if onroad else 30)
elif sys.platform == 'darwin':
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPALIVE, 7 if onroad else 30)
This approach ensures reliable network connections across different deployment environments and prevents runtime errors from unsupported socket operations. Consider the specific networking requirements of your application (timeouts, keepalive intervals) and how they should vary by platform and operational state.
Always pin external GitHub Actions to specific commit hashes rather than using tags or branch names, and prefer built-in runner capabilities when available. This improves security by preventing supply chain attacks and ensures reproducible builds.
Unpinned actions create security vulnerabilities and can break workflows when external maintainers update their actions. Additionally, using built-in runner features reduces external dependencies and improves performance.
Example of proper pinning:
# Bad - using tag
- uses: stefanzweifel/git-auto-commit-action@v5
# Good - pinned to commit hash
- uses: stefanzweifel/git-auto-commit-action@8621497c8c39c72f3e2a999a13b1c01d91af5b75
# Even better - use built-in capabilities when possible
# Instead of actions/setup-python@v5.3.0, use:
runs-on: ubuntu-24.04 # comes with python 3.12 pre-installed
Always research if the runner already provides the needed functionality before adding external dependencies.
Always include performance benchmarks when making changes that could impact execution speed, CPU usage, or resource consumption. This prevents performance regressions and validates optimization claims.
For any performance-related pull request, provide before/after measurements using appropriate benchmarking tools. Include specific metrics like execution time, CPU usage, or throughput improvements.
Example benchmark format:
# Before optimization
old_parse_structs(): 7.900648624985479 seconds
# After optimization
new_parse_structs(): 5.590290749911219 seconds
This practice is essential because performance regressions can be subtle but significant - like the locationd process that “uses 2-3x more CPU than the previous” version, or CAN parsing changes that initially appeared “twice as slow.” Without benchmarks, these issues may go unnoticed until they impact system performance in production.
Benchmarks should be run on representative hardware and workloads, and results should demonstrate meaningful improvements or at minimum show no regression in critical performance metrics.
When designing APIs or interfaces, avoid hardcoding string literals, configuration values, or identifiers that could be made configurable through parameters. This makes the API more flexible, reusable, and maintainable by allowing callers to specify their own values rather than being locked into fixed behavior.
Hardcoded values in APIs create tight coupling and reduce reusability. Instead, expose these values as parameters in your interface design, allowing different use cases to be supported without code changes.
Example of the problem:
// Bad: hardcoded "thumbnail" string
pm.reset(new PubMaster({encoder_info.publish_name, "thumbnail"}));
Better approach:
// Good: parameterize the thumbnail name through EncoderInfo
pm.reset(new PubMaster({encoder_info.publish_name, encoder_info.thumbnail_name}));
This principle applies to API endpoints, configuration keys, default values, and any identifier that might need to vary across different contexts or use cases. By parameterizing these values, you create more flexible interfaces that can adapt to different requirements without requiring code modifications.
Place configuration settings in centralized, appropriate locations rather than duplicating them across multiple files. This improves maintainability by ensuring changes only need to be made in one place.
For build configurations:
.bazelrc file for settings that apply across multiple configurationstools/toolchains)release_base or release_cpu_linux for settings that apply to groups of configurationsFor code configurations:
Example:
# Bad: Duplicating settings in multiple environment-specific files
# ci/official/envs/continuous_linux_x86_cpu_py310
# ci/official/envs/continuous_linux_arm64_cpu_py310
# ...
# Good: Single definition in .bazelrc
# .bazelrc
build:release_base --define=some_feature=enabled
build:release_cpu_linux --config=release_base --some_other_setting=value
Similarly, for code:
# Bad: Duplicating settings across multiple configuration sets
_DNNL_RUNTIME_THREADPOOL = {
"#cmakedefine01 DNNL_WITH_SYCL": "#define DNNL_WITH_SYCL 0",
"#cmakedefine01 DNNL_WITH_LEVEL_ZERO": "#define DNNL_WITH_LEVEL_ZERO 0",
}
_DNNL_RUNTIME_OMP = {
"#cmakedefine01 DNNL_WITH_SYCL": "#define DNNL_WITH_SYCL 0",
"#cmakedefine01 DNNL_WITH_LEVEL_ZERO": "#define DNNL_WITH_LEVEL_ZERO 0",
}
# Good: Define common settings once
_CMAKE_COMMON_LIST = {
"#cmakedefine01 DNNL_WITH_SYCL": "#define DNNL_WITH_SYCL 0",
"#cmakedefine01 DNNL_WITH_LEVEL_ZERO": "#define DNNL_WITH_LEVEL_ZERO 0",
}
_DNNL_RUNTIME_THREADPOOL = dict(_CMAKE_COMMON_LIST)
_DNNL_RUNTIME_OMP = dict(_CMAKE_COMMON_LIST)
This approach reduces maintenance burden and helps prevent inconsistencies that arise when settings are updated in some places but not others.
When testing algorithms, verify their actual functionality rather than just checking for proper instantiation or property modification. Ensure your tests capture the core behaviors of the algorithm under various parameters.
For deterministic algorithms:
For non-deterministic algorithms:
Example:
# Insufficient test - only checks properties
def test_fixed_length_weak():
pretok = FixedLength(length=5)
assert pretok.length == 5
pretok.length = 10
assert pretok.length == 10
# Better test - verifies actual algorithm behavior
def test_fixed_length_complete():
test_string = "This is a test string for tokenization"
# Test with length=5
pretok = FixedLength(length=5)
output_5 = pretok.pre_tokenize(test_string)
assert len(output_5[0]) == 5 # First chunk should be 5 chars
assert "".join([t for t, _ in output_5]) == test_string # Original text preserved
# Test with length=10
pretok.length = 10
output_10 = pretok.pre_tokenize(test_string)
assert len(output_10[0]) == 10 # First chunk should be 10 chars
assert len(output_10) < len(output_5) # Fewer chunks with larger length
For algorithms with inherent variability (like probabilistic models), focus on testing stable properties rather than specific outputs that might change between runs.
Use asynchronous patterns to prevent blocking operations from degrading system performance, especially in UI contexts and real-time systems. Prefer higher-level async abstractions like std::future over manual thread management when possible, as they provide automatic thread management, better exception handling, and simpler code maintenance.
For UI operations, ensure any potentially blocking calls (even those taking 0.1s) are made asynchronous to maintain smooth frame rates. For system operations that may block due to external factors (like network timeouts or hardware buffer states), isolate them in separate threads to prevent cascading delays.
Example from brightness control:
// Preferred: Using std::future for automatic thread management
if (!brightness_future.valid() ||
brightness_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
brightness_future = std::async(std::launch::async, Hardware::set_brightness, brightness);
}
// Avoid: Manual thread management requiring explicit cleanup and exception handling
if (!brightness_thread || !brightness_thread->joinable()) {
brightness_thread = std::make_unique<std::thread>(wrapper_function, brightness);
}
When operations must remain in separate threads due to blocking behavior (such as hardware buffer management), document the reasoning clearly and implement appropriate error handling for synchronization failures.
Ensure consistent formatting and proper usage of environment variables in Dockerfiles. Remove unnecessary quotes from ENV declarations and choose between ARG and ENV based on their intended scope - use ARG for build-time configuration that may change between builds, and ENV for runtime configuration that containers need during execution.
Key guidelines:
Example:
# Good - consistent formatting, appropriate usage
ARG PYTHON_VERSION=3.11
ENV PIP_CACHE_DIR=/cache/pip
ENV VIRTUAL_ENV=/app/venv
ENV TRANSFORMERS_CACHE=/app/.cache/transformers
# Avoid - unnecessary quotes and inconsistent formatting
ENV PIP_CACHE_DIR="/cache/pip"
ENV VIRTUAL_ENV=/app/venv
ENV TRANSFORMERS_CACHE="/app/.cache/transformers"
This approach improves readability, reduces confusion about when quotes are necessary, and ensures proper separation between build-time and runtime configuration.
Check objects directly for null/empty state instead of using separate tracking variables. Always perform null checks early in your functions, before entering resource-intensive blocks or operations that assume non-null values.
Don’t do this:
// Using a separate boolean flag to track object state
std::shared_ptr<dnn::Net> qbar_sr;
bool net_loaded_ = false; // Redundant tracking variable
void someFunction() {
if (net_loaded_) { // Indirect check through tracking variable
qbar_sr->performOperation();
}
}
Do this instead:
// Check the object directly
std::shared_ptr<dnn::Net> qbar_sr;
void someFunction() {
if (qbar_sr) { // Direct check of the object itself
qbar_sr->performOperation();
}
}
And always check for null parameters at the beginning of functions:
void processData(const char* name) {
// Check nulls early, before any processing or resource allocation
if (name == NULL) {
handleError("NULL name parameter");
return;
}
// Now it's safe to use the parameter
processName(name);
}
This approach improves code readability, reduces state tracking errors, and prevents null dereference bugs by ensuring validation happens before any operations that assume non-null values.
Keep headers “composition-safe” and minimal. Apply these rules:
.cpp file to avoid multiple-definition/linker problems.constexpr, enum, or an internal-scoped construct rather than a global #define.Example (bad → good):
// bad: in header
// foo.h
int gettimeofday_impl(); // ...
int gettimeofday_impl() { return 0; } // implementation in header
// good: in header
// foo.h
int gettimeofday_impl();
// foo.cpp
int gettimeofday_impl() { return 0; }
Checklist for changes to .h files:
inline) in the header?#define entries?When documenting or implementing configuration procedures, prioritize standard, unified approaches over custom or platform-specific solutions. This applies to setup scripts, environment activation, and configuration management.
For setup procedures, favor consolidated scripts that work across platforms:
# Preferred: unified approach
tools/op.sh setup
# Avoid: platform-specific manual steps
# Ubuntu 24.04:
# tools/ubuntu_setup.sh
# macOS:
# tools/mac_setup.sh
For environment management, stick to familiar standard practices rather than introducing custom commands:
# Preferred: standard Python environment activation
source .env/bin/activate
# Avoid: custom commands that require special knowledge
openpilot_shell
This approach reduces cognitive load for developers, leverages existing knowledge, and maintains consistency across different environments. Only introduce custom configuration methods when standard approaches are insufficient for the specific use case.
Use container classes and smart pointers instead of manual memory allocation to prevent null pointer dereferences and memory leaks.
Instead of raw memory allocation:
// Problematic: Potential memory leak if exceptions occur
uint32_t* buffer = new uint32_t[size];
// ... operations that might throw
delete[] buffer; // May never be reached
Prefer container classes:
// Better: Automatic cleanup even with exceptions
std::vector<uint32_t> buffer(size);
// or
cv::AutoBuffer<uint32_t> buffer(size); // May use stack space for small allocations
For custom resource types, use smart pointers with appropriate deleters:
// Problematic: Manual resource management
WebPAnimDecoder* decoder = WebPAnimDecoderNew(&webp_data, &dec_options);
// ... operations
WebPAnimDecoderDelete(decoder); // May be forgotten or skipped due to early returns
// Better: Automatic cleanup with custom deleter
struct UniquePtrDeleter {
void operator()(WebPAnimDecoder* decoder) const { WebPAnimDecoderDelete(decoder); }
};
std::unique_ptr<WebPAnimDecoder, UniquePtrDeleter> decoder(WebPAnimDecoderNew(&webp_data, &dec_options));
When null is invalid, use references instead of pointers:
// Problematic: Needs null check
uint32_t read_chunk(CHUNK* pChunk);
// Better: NULL is not possible
uint32_t read_chunk(CHUNK& pChunk);
Proper memory management not only prevents memory leaks but also eliminates many null pointer scenarios, making your code more robust and easier to maintain.
Remove redundant code constructs and prefer concise, direct patterns that improve readability and maintainability. This includes eliminating unnecessary widget/layout creation, using ternary operators for simple conditionals, direct initialization patterns, and simplifying complex calculations with named constants.
Examples of improvements:
routes_type_selector_->addTab(preserved_route_list_ = new RouteListWidget, tr("&Preserved"));return routes_type_selector_->currentIndex() == 0 ? route_list_ : preserved_route_list_;auto layout = new QVBoxLayout(widget) instead of separate setLayout() callsconst QColor ENGAGED_COLOR = QColor::fromRgbF(0.1, 0.945, 0.26); instead of inline mathThis approach reduces code bloat, makes intent clearer, and improves maintainability by removing opportunities for errors in redundant code paths.
When performing git operations that involve network communication, use proper syntax and efficient strategies to minimize data transfer and ensure correct remote branch handling.
For remote branch fetching, always specify both remote and local branch names to avoid ambiguity and ensure the branch is properly tracked locally:
# Preferred: explicit remote:local syntax
git fetch origin $1:$1
# Avoid: ambiguous fetch that may not create local branch
git fetch origin $1
For repository cloning, consider using shallow clones with --depth=1 to reduce initial network transfer, especially for testing or CI environments where full history isn’t needed:
# Efficient for testing/CI
git clone --depth=1 https://github.com/user/repo.git
# Note: shallow clones can be unshallowed later if needed
git fetch --unshallow
This approach reduces network bandwidth usage while maintaining the ability to expand the repository scope when necessary. Always consider the trade-offs between initial clone speed and future git operation capabilities when choosing clone strategies.
Ensure all configuration parameters have explicit default values and are thoroughly documented. When using argparse with action='store_true', always pair it with default=False. Document parameter purposes, valid values, and default behaviors in README files. For dependency management, separate conflicting requirements into different files to avoid version incompatibilities.
Example:
# Good: Explicit default value
parser.add_argument('--use_modelscope', action='store_true', default=False,
help='Whether to use ModelScope; if False, HuggingFace is used')
parser.add_argument('--generate_length', type=int, default=2048,
help='Number of tokens to generate (default: 2048)')
In README documentation:
Parameters:
- `--use_modelscope`: Whether to use ModelScope; if False, HuggingFace is used; default is False
- `--generate_length`: Number of tokens to generate; default is 2048
For dependencies, use separate requirement files:
requirements/perf_transformer.txt # For transformer-specific dependencies
requirements/perf_vllm.txt # For vLLM-specific dependencies
When specifying AI/ML library dependencies, ensure version compatibility between related packages and verify that prebuilt binaries are available for the target environment. Many AI libraries like auto_gptq, autoawq, and flash_attn are compiled against specific versions of PyTorch and CUDA, and version mismatches can force compilation from source or cause runtime failures.
Before finalizing requirements, check:
Consider separating incompatible libraries into different requirements files when necessary.
Example of problematic dependencies:
torch==2.3.1
auto_gptq==0.7.1 # Compiled against torch 2.2.1, will cause issues
Better approach:
# requirements-gptq.txt
torch==2.2.1
auto_gptq==0.7.1
# requirements-awq.txt
torch==2.4.1
autoawq==0.2.6
When documenting AI/ML model deployment and inference procedures, always test and specify compatible library versions to prevent runtime failures. Version incompatibilities in AI libraries can cause critical errors like inference failures, probability tensor issues, or model output corruption.
Key practices:
Example from model deployment documentation:
# Working configuration
auto_gptq==0.6.0+cu1210 # Note: >=0.7.0 causes RuntimeError with probability tensors
# vLLM version notes
vLLM==0.6.2 # Recommended for Qwen2.5 7B/14B/32B with 128k context
vLLM==0.6.3 # May cause output issues: !!!!!!!!!!!!!!!!!!!!!!!
This prevents users from encountering runtime errors like “probability tensor contains either inf, nan or element < 0” or model output corruption, ensuring reliable AI model deployment and inference.
Keep code clean by removing all forms of redundancy that affect readability and maintainability. This includes:
// BAD - duplicated macro definition
#define ARRAY_IS_VIEW 33554432
#define ARRAY_IS_VIEW 33554432 // Duplicate!
// GOOD - defined once
#define ARRAY_IS_VIEW 33554432
// BAD - debug statement in production code
registerUse({&res}, {this});
sd_printf("After before exec\n",0); // Debug print in production code
// GOOD - only in error paths or removed entirely
registerUse({&res}, {this});
// No unnecessary print statements
Each form of redundancy impacts code readability and increases maintenance burden. When reviewing code, make sure information is stated once and only once where appropriate.
Configure CI workflows with targeted triggers and path filters to balance thoroughness with efficiency. Run critical build jobs on every commit for affected components, while avoiding unnecessary builds when changes don’t impact certain components.
For example, use path filters to only run specific workflows when relevant files change:
name: Node Build
on:
push:
paths:
- 'bindings/node/**'
- 'src/**'
paths-ignore:
- '*.md'
- 'docs/**'
pull_request:
paths:
- 'bindings/node/**'
- 'src/**'
jobs:
build:
# Build configuration here
Keep your CI components updated to their latest stable versions:
- name: Install Python
uses: actions/setup-python@v5 # Use latest stable version
Consider workflow organization - separate workflows by component or purpose, but look for opportunities to consolidate setup steps and reuse configuration across similar jobs.
Design cache keys to avoid performance pitfalls and ensure reliable cache behavior. Cache keys should be lightweight, hashable, and deterministic to prevent unnecessary cache misses and memory bloat.
Key principles:
Example of problematic cache key design:
# BAD: Large image data becomes part of cache key
cache_key = (node_id, large_image_tensor, other_inputs)
# BAD: Unhashable model object causes cache misses
cache_key = (node_id, model_instance, inputs)
Example of optimized cache key design:
# GOOD: Use link references instead of actual values
if is_link(input_data):
cache_key = (node_id, ("ANCESTOR", ancestor_index, socket))
else:
cache_key = (node_id, input_data) # Only for small, hashable data
# GOOD: Cache expensive signature computations
if node_id not in self.immediate_node_signature:
self.immediate_node_signature[node_id] = self.compute_signature(node_id)
This approach ensures cache keys remain efficient while maintaining cache correctness, preventing both performance degradation and incorrect cache behavior.
Documentation should be structured to optimize user navigation and information discovery. When organizing documentation elements:
For example, when creating documentation indexes or navigation elements:
# Good organization example
documentation_links:
# Community resources (general info)
- name: Documentation
url: https://docs.example.org/
about: Official Documentation
- name: Community Support
url: https://community.example.org/
about: Get help from the community
# Component-specific resources (alphabetically sorted)
- name: API Reference
url: https://api.example.org/
about: Please refer to the API documentation
- name: Installation Guide
url: https://install.example.org/
about: Follow the installation steps
This organization style makes navigation intuitive and ensures users can quickly find the information they need, rather than getting lost in poorly structured documentation.
Store all configuration values in dedicated configuration files rather than hardcoding them throughout the application. This makes the codebase more maintainable and reduces the need for code changes when configurations change.
Key practices:
Example - Before:
constructor(private translate: TranslateService) {
const currentLanguage = this.translate.getBrowserLang();
const lang = currentLanguage.match(/en|fr/) ? currentLanguage : 'en';
}
constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
iconRegistry.addSvgIcon('jupyterlab', sanitizer.bypassSecurityTrustResourceUrl('static/assets/jupyterlab-wordmark.svg'));
}
Example - After:
// In environment.ts
export const environment = {
supportedLanguages: ['en', 'fr'],
defaultLanguage: 'en',
assetPaths: {
jupyterlab: 'static/assets/jupyterlab-wordmark.svg',
}
};
// In component
constructor(private translate: TranslateService) {
const currentLanguage = this.translate.getBrowserLang();
const lang = environment.supportedLanguages.includes(currentLanguage) ?
currentLanguage : environment.defaultLanguage;
}
constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
iconRegistry.addSvgIcon(
'jupyterlab',
sanitizer.bypassSecurityTrustResourceUrl(environment.assetPaths.jupyterlab)
);
}
This approach makes it easier to add new languages or assets without modifying component code, and keeps configuration organized in central locations.
Create comprehensive documentation with clear structure and practical examples. Documentation should include:
Standard documentation files like README.md, CHANGELOG.md, and CONTRIBUTING.md, even if they primarily link to external resources. Search engines index these standard files, improving project discoverability.
Well-organized content with clear headings, tables for related information, and consistent formatting. For complex projects, organize information hierarchically:
# Component Name
## About
Brief description of the component's purpose.
## Table of Components
| Component | Source Repository |
|-----------|-------------------|
| Component A | [`org/repo-a`](https://github.com/org/repo-a) |
| Component B | [`org/repo-b`](https://github.com/org/repo-b) |
## Usage Examples
**Run all tests**
`make run`
**Run component-specific tests**
`make run-kfp` # Run Kubeflow Pipelines tests
`make run-katib` # Run Katib tests
Active voice rather than passive voice to improve clarity and directness.
Links to stable versions rather than development branches to prevent users from accidentally using unstable code.
Following these practices makes documentation more useful, accessible, and maintainable while improving the overall user experience.
Ensure CI/CD pipeline tools run with the same configuration, flags, and behavior as developers use locally. This prevents masking errors in CI/CD that developers would encounter in their local environment and maintains consistency in the development workflow.
When configuring linting, testing, or other quality tools in CI/CD scripts, avoid adding flags or modifications that change the tool’s behavior compared to local usage. For example, avoid adding --quiet flags or different file selection criteria that could hide issues developers need to see.
Example of what to avoid:
# This masks errors that developers see locally
run "ruff" ruff check $PYTHON_FILES --quiet
Instead, ensure CI/CD runs the same commands developers would run:
# This matches what developers run locally: "ruff check ."
run "ruff" ruff check $PYTHON_FILES
This principle applies to all CI/CD tools including linters, formatters, test runners, and build tools. The goal is to eliminate surprises where something passes in CI/CD but fails locally, or vice versa.
Store configuration constants, defaults, and environment variable mappings in dedicated configuration files rather than duplicating them across the codebase. This provides a single source of truth, improves maintainability, and reduces errors from inconsistent values.
For environment variables with defaults:
# In a central config.py file:
METRICS = bool(os.environ.get("METRICS", False))
BACKEND_MODE = os.environ.get("BACKEND_MODE", BackendMode.PRODUCTION.value)
# In application code:
from config import METRICS, BACKEND_MODE
For registry references, version constants, and other configuration mappings:
# In config.py
AWS_REGISTRIES = {
"jupyter": "public.ecr.aws/j1r0q0g6/jupyter-web-app",
"volumes": "public.ecr.aws/j1r0q0g6/volumes-web-app",
# Add more as needed
}
# In application code:
from config import AWS_REGISTRIES
registry = AWS_REGISTRIES["jupyter"]
When system-wide defaults are available (like in configmaps), prefer those over hardcoded values to ensure consistency across components.
Manage environment variables in Docker configurations with appropriate scope, placement, and documentation:
DEBIAN_FRONTEND only within the commands that need them:
```dockerfile
RUN apt-get update
&& DEBIAN_FRONTEND=noninteractive apt-get install -y –no-install-recommends
package1 package2
ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y package1 package2 ```
# version details
ARG LIBFABRIC_VERSION="1.20.0"
ARG PYTORCH_VERSION="2.2.2"
# Gaudi does not currently support Python 3.11, so we downgrade to 3.10
# https://docs.habana.ai/en/latest/Support_Matrix/Support_Matrix.html
When performing network operations in build scripts or containers, prefer curl over wget for HTTP requests to standardize dependencies and improve portability. Use the specific flags -fsSL for silent operation with proper error handling, and explicitly specify output destinations.
Additionally, ensure network services support both IPv4 and IPv6 addressing by using dual-stack binding configurations rather than binding only to 0.0.0.0 (IPv4).
Example replacing wget with curl:
# Instead of:
wget -q -O- https://example.com/file.tar.gz | tar xz
# Use:
curl -fsSL https://example.com/file.tar.gz | tar xz
Example of dual-stack binding in gunicorn:
# Instead of:
gunicorn -w 3 --bind 0.0.0.0:5000 app:app
# Use:
gunicorn -w 3 --bind 0.0.0.0:5000 --bind [::]:5000 app:app
Write informative, consistent, and precise code comments throughout your codebase. When documenting code:
# AVOID:
# Content below is extracted from scripts/Dockerfiles here:
# https://github.com/HabanaAI/Setup_and_Install/tree/main/dockerfiles/base
# BETTER:
# Content below is based on:
# https://github.com/HabanaAI/Setup_and_Install/blob/1.17.0/dockerfiles/base/Dockerfile.ubuntu22.04
# AVOID:
RUN python3 -m pip install habana_media_loader=="${VERSION}"."${REVISION}"
# BETTER:
# Install Habana media loader library for PyTorch integration
RUN python3 -m pip install habana_media_loader=="${VERSION}"."${REVISION}"
# AVOID mixing styles:
# version details
# and elsewhere:
# args - software versions
# BETTER: Use consistent headers:
# args - software versions
Well-documented code improves comprehension, facilitates maintenance, and enhances collaboration among team members.
Maintain clean, professional code by removing development artifacts and improving readability:
// Bad:
System.out.println("Functrace on: " + funcTrace);
// Bad:
// ptrDataBuffer.closeBuffer();
// if(pointer != null && !pointer.isNull())
// pointer.close();
// If really necessary:
// TODO: Re-enable this after fixing JIRA-1234
// ptrDataBuffer.closeBuffer();
// Bad:
if (edgeCount - lastEdgeCount > 10000) {
// ...
}
// Good:
private static final int EDGE_COUNT_REPORT_THRESHOLD = 10000;
if (edgeCount - lastEdgeCount > EDGE_COUNT_REPORT_THRESHOLD) {
// ...
}
// Bad:
Preconditions.checkArgument(data >= 0,
"Values for " + paramName + " must be >= 0, got: " + data);
// Good:
Preconditions.checkArgument(data >= 0, "Values for %s must be >= 0, got %s", paramName, data);
// Good:
public class ValidationUtils {
private ValidationUtils() {
// Private constructor to prevent instantiation
}
// Static utility methods...
}
Identify operations that are expensive and called frequently, then optimize them by caching results, moving to appropriate lifecycle events, or replacing with faster alternatives. Expensive operations like parameter reads, system calls, or complex computations should not be repeated unnecessarily in hot code paths.
For example, instead of calling expensive parameter reads on every update:
// Avoid: Called on every update (expensive)
bool AnnotatedCameraWidget::isDMAlwaysOn() const {
Params params;
return params.getBool("AlwaysOnDM"); // params.get() is expensive
}
Move the expensive operation to initialization or appropriate lifecycle events:
// Better: Update once when widget becomes visible
void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
Params params;
dm_always_on = params.getBool("AlwaysOnDM"); // Cache the result
}
Similarly, replace slow system operations with faster alternatives when available. A 16ms operation replaced with a 0.5ms equivalent can significantly improve responsiveness in frequently called code paths.
Function documentation should follow a consistent structure that includes all necessary components to be complete and usable. Each docstring should:
Example of proper docstring structure:
def is_platform_supported(precision, gpu_id=0):
"""Determines if the current NVIDIA GPU platform supports the requested precision.
Required Compute Capabilities:
- FP16 = 5.3 || 6.0 || 6.2 || 7.0+
- INT8 = 6.1 || 7.0 || 7.2+
Args:
precision: String indicating the desired compute precision.
gpu_id: Integer ID of the GPU to check. Defaults to 0.
Returns:
Boolean indicating whether the platform supports the requested precision.
Raises:
ValueError: If precision is not a supported value.
"""
Following this structure ensures documentation is consistent, complete, and meets style guidelines. It helps other developers understand your code more quickly and makes automated documentation generation more effective.
Apply standardized error handling patterns across your codebase for improved reliability and debugging. For new code, use the absl error types instead of tsl::errors and include descriptive error messages with context.
Key practices:
absl error types with absl::StrCat for error messagesStatusOr<T> for operations that can fail instead of raw values// Instead of:
return errors::InvalidArgument("Invalid shape: ", shape.DebugString());
// Use:
return absl::InvalidArgumentError(
absl::StrCat("Invalid shape: ", shape.DebugString()));
// For void functions, use the proper macro:
OP_REQUIRES(ctx, input.shape().dim_size(i) != 0,
absl::InvalidArgumentError("Invalid input: Dimension cannot be 0."));
// For functions that can fail, return StatusOr:
StatusOr<string> GetDeviceNameFromStreamDeviceName(const string& stream_name) {
if (!IsValidStreamName(stream_name)) {
return absl::InvalidArgumentError("Invalid stream device name");
}
return ParsedName;
}
Design machine learning model code with clear component boundaries and proper separation of concerns. Each component (tokenizer, normalizer, model, etc.) should have a single responsibility with appropriate visibility modifiers.
Benefits:
For example, instead of embedding tokenization logic directly in the model:
// Not recommended: Tokenization functionality embedded in model
impl ModelClass {
pub fn tokenize_and_process(&self, text: &str) -> Result<Vec<Token>> {
// Logic mixing tokenization and model-specific processing
}
}
// Recommended: Separate components with clear responsibilities
pub mod tokenizers {
pub(crate) fn bytes_char() -> HashMap<u8, char> {
// Tokenization logic isolated
}
}
impl ModelClass {
// Higher-level API using the tokenizer component
pub fn process(&self, tokens: Vec<Token>) -> Result<Output> {
// Model-specific processing only
}
}
When designing ML libraries, consider which functionality belongs in the core model versus specialized components like normalizers, tokenizers, or trainers. This modularity is especially important for generative AI and NLP systems where preprocessing pipelines can vary significantly between model architectures.
Use optional chaining (?.) and nullish coalescing (??) operators instead of manual null checks to safely access nested properties and provide fallback values. These operators prevent runtime errors when dealing with potentially null or undefined values and result in cleaner, more readable code.
Instead of verbose manual checks:
if (item.meta && item.meta[key] && item.meta[key].display_node) {
app.nodeOutputs[item.meta[key].display_node] = value;
} else {
app.nodeOutputs[key] = value;
}
Use optional chaining with nullish coalescing:
const realKey = item?.meta?.[key]?.display_node ?? key;
app.nodeOutputs[realKey] = value;
For simple property access, replace potentially unsafe access like input.widget.name with input.widget?.name to handle cases where the parent object might be null or undefined. This approach reduces boilerplate code while providing robust null safety.
When building container images, ensure they’re compatible with restricted Kubernetes security contexts. Use numeric UIDs instead of symbolic usernames, and test compatibility with the following security constraints:
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
This approach prevents privilege escalation attacks and follows the principle of least privilege. For example, in a Dockerfile, prefer USER 1000 over USER jovyan to ensure compatibility with security contexts that enforce non-root execution. This practice enhances security in various Kubernetes environments, including those that don’t automatically apply these restrictions.
When working with configuration files that support multiple tools or package managers, ensure that configuration syntax and constraints accommodate all supported tools while maintaining functionality across the ecosystem.
Different tools have specific requirements and limitations that must be understood and accommodated. For example, uv requires lower bounds for dependencies in preview mode (“sounddevice >= 0” instead of “sounddevice”), cannot combine github sources with platform markers in the same declaration, and poetry has limitations on non-existent version specifications.
Always verify that configuration changes work across all intended tools and document tool-specific constraints when they influence configuration decisions. For static analysis tools like mypy, align version settings with the project’s minimum supported version rather than the latest available version to prevent use of unsupported language features.
Example from pyproject.toml:
# uv requires lower bounds in preview mode
"sounddevice >= 0", # micd + soundd
# uv limitation: github source + markers must be split
dependencies = [
"metadrive-simulator; platform_machine != 'aarch64'"
]
[tool.uv.sources]
metadrive-simulator = { git = "https://github.com/commaai/metadrive.git", branch = "python3.12" }
# mypy should target minimum supported Python version
[tool.mypy]
python_version = "3.11" # keep to minimum supported, not latest
Use Rust’s idiomatic patterns when working with Option and Result types to prevent panics and improve code clarity.
Avoid unwrapping
Prefer pattern matching or propagating errors instead of using .unwrap() which can cause runtime panics:
// Instead of this:
fn __str__(&self) -> PyResult<String> {
Ok(format!("{}", self.model.read().unwrap()))
}
// Prefer this:
fn __str__(&self) -> PyResult<String> {
self.model.read()
.map(|model| format!("{}", model))
.map_err(|e| e.into()) // Convert to PyResult
}
Use Option types appropriately
Only use Option
// Instead of:
pub fn from(
vocab: Vec<(String, f64)>,
unk_id: Option<usize>,
byte_fallback: Option<bool>, // Unnecessarily complex
) -> Result<Self>
// Prefer:
pub fn from(
vocab: Vec<(String, f64)>,
unk_id: Option<usize>, // Truly optional
byte_fallback: bool, // Just a flag
) -> Result<Self>
Handle Option values clearly Use clear patterns for handling optional values, remembering that None means absence, not zero:
// Instead of:
match max_merge_length {
None | Some(0) => { /* in case 0 was manually entered, treat as None */ }
Some(length) => { /* handle length */ }
}
// Prefer:
if let Some(max_token_length) = max_token_length {
if new_token.chars().count() > max_token_length {
continue;
}
}
Design for nullable parameters When creating APIs with optional parameters, consider how values can be both set and unset:
// Option in builder pattern
fn with_dropout(mut self, dropout: Option<f32>) -> Self {
self.dropout = dropout;
self
}
// Or provide explicit methods
fn with_dropout(mut self, dropout: f32) -> Self {
self.dropout = Some(dropout);
self
}
fn without_dropout(mut self) -> Self {
self.dropout = None;
self
}
When adding or updating dependencies for AI/ML libraries in your project, follow these two key practices:
# Too restrictive
dependencies = ["huggingface_hub>=0.16.4,<0.17"]
# Better approach - allows minor version updates
dependencies = ["huggingface_hub>=0.16.4,<0.18"]
# Potentially too permissive for rapidly evolving AI libraries
dependencies = ["huggingface_hub>=0.16.4,<1.0"]
# Better approach with optional flag
arrow = { git = "https://github.com/apache/arrow-rs", branch = "master", features = [
"pyarrow",
], optional=True }
This approach reduces unnecessary dependencies for users who don’t need all ML features and provides flexibility in environments with compatibility constraints.
When implementing quantized operations in ML models, thoroughly validate quantization parameters to ensure correctness and prevent subtle numerical errors. Key validation points:
Example:
// Good: Proper quantization parameter validation
if (input->type == kTfLiteInt16) {
TF_LITE_ENSURE_EQ(context, input->params.zero_point, 0);
TF_LITE_ENSURE_EQ(context, output->params.zero_point, 0);
}
// For quantized operations, validate scale consistency
if (input->type == kTfLiteInt8 || input->type == kTfLiteInt16) {
TF_LITE_ENSURE_EQ(context, input->params.scale, output->params.scale);
}
// Ensure quantization scheme compatibility
if (lhs.IsQuantized()) {
if (!rhs.IsQuantized() || !output.IsQuantized()) {
return absl::FailedPreconditionError(
"If one tensor is quantized, all must be quantized");
}
}
Minimize expensive operations within inner loops to improve performance. Key practices include:
// Good: Calculate once before the loop const size_t loop_limit = output.shape().Dim(dimension) * inner_dimensions_size; for (size_t j = 0; j < loop_limit; j++) { // Loop body }
2. Avoid expensive function calls like `Offset()` in inner loops
```cpp
// Bad: Using Offset() in inner loop
for (int filter_d1 = filter_d1_start; filter_d1 < filter_d1_end; ++filter_d1) {
for (int filter_d2 = filter_d2_start; filter_d2 < filter_d2_end; ++filter_d2) {
for (int filter_d3 = filter_d3_start; filter_d3 < filter_d3_end; ++filter_d3) {
total += input_data[Offset(input_shape, batch, in_d1, in_d2, in_d3, channel)];
}
}
}
// Good: Calculate indices incrementally
// Initialize base_offset before the loops
for (int filter_d1 = filter_d1_start; filter_d1 < filter_d1_end; ++filter_d1) {
int d1_offset = base_offset + stride_d1 * filter_d1;
for (int filter_d2 = filter_d2_start; filter_d2 < filter_d2_end; ++filter_d2) {
int d2_offset = d1_offset + stride_d2 * filter_d2;
for (int filter_d3 = filter_d3_start; filter_d3 < filter_d3_end; ++filter_d3) {
int index = d2_offset + stride_d3 * filter_d3;
total += input_data[index];
}
}
}
// Good: Using small vector optimization llvm::SmallVector<int64_t, 4> a1_transpose_dims; // Or absl::InlinedVector<size_t, 6> lhs_index;
These optimizations can significantly improve performance in computation-intensive applications by reducing memory allocation overhead and unnecessary calculations.
---
## Separate test data
<!-- source: tensorflow/tensorflow | topic: Testing | language: Other | updated: 2024-05-10 -->
Large test data should be separated from test logic to improve readability and maintainability. Move test data into separate files or define as constants at the top of test files. This makes the test bodies clearer and easier to understand.
For example, instead of:
```cpp
TYPED_TEST(NonQuantizedIntDotGeneralTest, IntTestTypesTensorsWork2) {
using StorageT = typename TypeParam::StorageT;
const Shape shape_lhs({7, 3, 4});
const Shape shape_rhs({7, 4});
// ...
Vector<int64_t> lhs_data_int{
0, 1, 4, 1, -2, -3, 0, 0, 6, -1, 0, 0, 1, 0, -2, 0, 1,
3, 4, -6, 2, 4, 4, 0, 0, -2, -1, 1, -2, -3, 0, 2, -3, 0,
0, -2, 4, -7, 2, 2, 0, 4, 2, 0, -6, 1, 1, 2, -2, -2, 0,
-1, -4, -1, 0, -1, 1, 3, 1, 1, -4, 0, 0, 1, -1, 0, 4, -2,
0, 5, 0, -1, 0, 2, 1, 2, -1, 1, -3, -2, -6, -3, -1, -3};
// ... test logic
}
Use:
// At file scope or in a separate header
constexpr int64_t kLhsDataInt[] = {
0, 1, 4, 1, -2, -3, 0, 0, 6, -1, 0, 0, 1, 0, -2, 0, 1,
3, 4, -6, 2, 4, 4, 0, 0, -2, -1, 1, -2, -3, 0, 2, -3, 0,
0, -2, 4, -7, 2, 2, 0, 4, 2, 0, -6, 1, 1, 2, -2, -2, 0,
-1, -4, -1, 0, -1, 1, 3, 1, 1, -4, 0, 0, 1, -1, 0, 4, -2,
0, 5, 0, -1, 0, 2, 1, 2, -1, 1, -3, -2, -6, -3, -1, -3
};
TYPED_TEST(NonQuantizedIntDotGeneralTest, IntTestTypesTensorsWork2) {
using StorageT = typename TypeParam::StorageT;
const Shape shape_lhs({7, 3, 4});
const Shape shape_rhs({7, 4});
// ...
Vector<int64_t> lhs_data_int(std::begin(kLhsDataInt), std::end(kLhsDataInt));
// ... test logic
}
Additionally, create separate, focused test cases for different data types or edge cases rather than handling them all in one test with conditional logic. This makes tests easier to maintain and provides clearer failure diagnostics.
Prefer smart configuration defaults that auto-detect the environment instead of requiring explicit configuration flags. When possible, implement automatic detection of the runtime context and provide sensible defaults while still allowing explicit overrides.
For example, instead of requiring a boolean flag to control behavior:
def __init__(
self,
tokenizer: Tokenizer,
default_to_notebook: bool = False,
# ...
)
Consider auto-detecting the environment:
def __init__(
self,
tokenizer: Tokenizer,
# No default_to_notebook parameter needed
# ...
):
# Auto-detect if running in a notebook environment
use_notebook = _is_in_notebook_environment()
# ...
Similarly, when changing configuration parameters for backward compatibility, translate legacy boolean parameters to more descriptive string options:
# Instead of directly using boolean parameter
prepend_scheme = "always" if add_prefix_space else "never"
This approach reduces configuration burden on users, provides more intuitive defaults, and makes the API more user-friendly while maintaining compatibility with existing code.
When working with TensorFlow tensors, avoid using Python comparison operators (<, >=, ==) or conditional checks that expect Boolean scalars. Python operators evaluate eagerly and won’t work correctly with tensors that represent deferred computations.
Instead:
tf.condcheck_ops module such as assert_lessIncorrect:
def random_uniform(shape, minval=0, maxval=None, dtype=dtypes.float32):
if minval >= maxval: # Will fail if these are tensors
raise ValueError("minval must be less than maxval")
Correct:
def random_uniform(shape, minval=0, maxval=None, dtype=dtypes.float32):
# Use check_ops for tensor-compatible validation
minval = ops.convert_to_tensor(minval, dtype=dtype)
maxval = ops.convert_to_tensor(maxval, dtype=dtype)
check_ops.assert_less(minval, maxval,
message="minval must be less than maxval")
This pattern is essential for building TensorFlow graphs that will execute correctly in both eager and graph execution modes, ensuring your AI models behave as expected regardless of execution environment.
Avoid duplicating CI/CD scripts by leveraging configuration files and parameterization instead of creating multiple similar scripts for different platforms or build scenarios. Use platform-specific configuration options in shared config files (like .bazelrc) or make scripts accept parameters for variant behaviors.
For example, instead of having separate build scripts for different compilers:
# Bad: Multiple nearly-identical scripts
build_tf_windows.sh # For MSVC
build_tf_windows_clang.sh # For Clang
# Good: Single script with parameters
build_tf_windows.sh --compiler=clang
# Or use configuration files
bazel build --config=win_clang
Similarly, for build parameters like job counts, prefer configurable variables with defaults instead of hard-coding:
# Bad: Hard-coded value
cmake --build . --verbose -j $(nproc)
# Good: Configurable with default
: ${BUILD_NUM_JOBS:=$(nproc)} # Default to nproc if not set
cmake --build . --verbose -j ${BUILD_NUM_JOBS}
This approach improves maintainability, reduces errors from out-of-sync scripts, and provides flexibility for different build environments and debugging scenarios.
Ensure all code follows formatting guidelines for readability and consistency. Keep lines under 80 characters, splitting longer lines appropriately across multiple lines when needed. All comments should be written as complete sentences with proper capitalization and ending punctuation.
For example, instead of:
# autoparallel optimizer - automatically parallelizes graphs by splitting along the batch dimension
Write it as:
# Autoparallel optimizer - Automatically parallelizes graphs by splitting along
# the batch dimension.
For longer parameter descriptions in documentation, follow established patterns:
- min_graph_nodes: The minimum number of nodes in a graph to optimizer.
For smaller graphs, optimization is skipped.
- auto_parallel: Automatically parallelizes graphs by splitting along the batch
dimension.
This improves readability and helps maintain a professional and consistent codebase.
When documenting AI framework migrations (like TensorFlow/Keras version changes), provide complete instructions covering both installation and code modifications. Include:
Example for Keras 2 to 3 migration:
# Installation
# pip install tf-keras~=2.16
# Import changes - Before:
import tensorflow.keras as keras
# or
import keras
# Import changes - After:
import tf_keras as keras
# OR to continue using Keras 2
import os
os.environ["TF_USE_LEGACY_KERAS"] = "1"
# then use original imports
This practice ensures AI developers can smoothly transition between framework versions without disrupting their workflows or introducing subtle bugs.
When implementing tensor-based algorithms, avoid assumptions about fixed tensor shapes by not relying on direct shape attributes (.shape, .ndim), which may return None in graph mode. Instead, use TensorFlow operations like tf.shape() and tf.rank() which work in both eager and graph execution modes. For validation, use TensorFlow’s conditional operations rather than Python conditionals.
For example, replace:
# Problematic code - may fail in graph mode
mat1_shape = mat1.shape
dense_rows = mat1_shape[-2] # This might fail if shape is not known
if dense_shape[-2] != dense_rows: # Python conditional won't work with tensors
raise ValueError("Shapes don't match")
With:
# Robust code that works in both eager and graph modes
mat1_shape = array_ops.shape(mat1)
dense_rows = mat1_shape[-2]
condition = math_ops.equal(dense_shape[-2], dense_rows)
gen_logging_ops._assert(condition, ["Shapes don't match"], name="Assert")
This approach ensures algorithms work reliably regardless of whether shapes are statically known at graph construction time or only determined during execution.
When writing documentation, always be specific and explicit when referring to files, tools, configurations, or other elements. Vague references create confusion and require readers to make assumptions or search for additional context.
Provide complete information by:
Specifying exact versions and names of tools mentioned Example: Use “Bazel 0.4.5” instead of just “0.4.5” in a table cell
Clearly stating file locations when referencing them Example: Write “env files in the envs/ folder” instead of just “env files”
Using descriptive headers that accurately reflect content Example: Use “Build tools” instead of “Bazel/Cmake” when the table shows various build tools
This practice ensures documentation is immediately clear to all readers, regardless of their familiarity with the codebase, and reduces the need for clarifying questions.
Error messages should be informative, actionable, and concise to help users quickly understand and fix issues. Follow these guidelines:
# Avoid
raise ValueError('Invalid axis: {} not in range {}-{}'.format(axis, min_val, max_val))
# Prefer
raise ValueError(f"Argument `axis` = {axis} not in range [{min_val}, {max_val})")
# Too verbose
raise ValueError(f'Python found at {python_bin_path} is not version 3. Please update to the latest version to continue with installation.')
# Better
raise ValueError(f'Python from {python_bin_path} is not version 3.')
# Vague
raise ValueError("Type annotation does not match input_signature")
# Better
raise ValueError(f"Type annotation for argument '{arg}' expected {annotation_dtype} but input_signature specified {input_signature_dtype}")
Well-crafted error messages reduce debugging time and improve the overall developer experience when using your code.
Libraries should never panic as this can crash applications using the library. Always return a Result type rather than using functions or methods that can panic (panic!(), unwrap(), expect(), assert!()) in public APIs and internal logic. This allows consumers of your library to properly handle error conditions.
For example, instead of:
// BAD: This will panic if the string doesn't match any scheme
impl From<&str> for PrependScheme {
fn from(s: &str) -> Self {
match s.to_lowercase().as_str() {
"first" => PrependScheme::First,
"never" => PrependScheme::Never,
"always" => PrependScheme::Always,
_ => panic!("Invalid value for PrependScheme: {}", s),
}
}
}
Prefer:
// GOOD: Returns Result so the caller can handle the error
impl TryFrom<&str> for PrependScheme {
type Error = String;
fn try_from(s: &str) -> Result<Self, Self::Error> {
match s.to_lowercase().as_str() {
"first" => Ok(PrependScheme::First),
"never" => Ok(PrependScheme::Never),
"always" => Ok(PrependScheme::Always),
_ => Err(format!("Invalid value for PrependScheme: {}", s)),
}
}
}
Similarly, instead of using .unwrap() or .expect() on Options or Results, propagate errors up the call stack. For public APIs that are expected to succeed under normal circumstances, validate inputs and return informative errors rather than using assertions.
When handling regex matches or other operations that theoretically shouldn’t fail but might in practice, return appropriate error types rather than assuming success with .expect(). This approach makes your library more robust and provides a better experience for users.
Avoid unnecessary memory allocations to improve performance. Each allocation has both CPU and memory overhead that can accumulate significantly, especially in hot code paths.
Follow these practices:
// Better: Process directly without temporary collection let result = items.map(process).reduce(|a, b| a + b).unwrap_or_default();
2. Don't allocate in getter methods - return references or copy small values instead:
```rust
// Avoid: Returning newly allocated vectors
pub fn get_added_tokens(&self) -> Vec<String> {
self.added_vocabulary.get_added_tokens()
}
// Better: Return a reference to existing data
pub fn get_added_tokens(&self) -> &[String] {
self.added_vocabulary.tokens()
}
// Better: Accept a slice reference fn process(data: &[u8]) { /* … */ }
4. Consider extending existing structures rather than creating and combining new ones:
```rust
// Instead of creating multiple encodings and merging them later,
// extend a single encoding incrementally
let mut encoding = Encoding::default();
for item in items {
let tokens = tokenize(item);
encoding.extend(tokens);
}
Performance optimizations often involve trading readability for speed - make these tradeoffs intentionally and document when necessary.
Select parameter and method names that accurately describe their purpose and behavior, avoiding ambiguous terms that can lead to confusion. Consider these guidelines:
// AVOID: Parameter name doesn't clearly indicate truncation behavior
pub fn truncate(&mut self, max_len: usize, stride: usize, left: bool) {
// ...
}
// BETTER: Use an enum with meaningful names
pub fn truncate(&mut self, max_len: usize, stride: usize, direction: TruncationDirection) {
// ...
}
"first" instead of "First")from_string not _from_string)// AVOID: Similar method names with different behaviors
fn add_tokens(&mut self) { /* ... */ }
fn num_added_tokens(&self) { /* ... */ }
// BETTER: Clear distinction in naming
fn add_tokens(&mut self) { /* ... */ }
fn num_special_tokens_to_add(&self) { /* ... */ }
When choosing identifiers, always ask: “Would another developer immediately understand what this name represents without looking at its implementation?”
In Go, the first letter of an identifier (function, variable, struct field, etc.) determines its visibility outside the package:
Always follow these rules:
// Exported - can be called from other packages
func DisableCullingAnnotationIsSet(meta metav1.ObjectMeta) bool {
// implementation
}
// Non-exported - only callable within the same package
func exists(slice []string, val string) bool {
for _, item := range slice {
if item == val {
return true
}
}
return false
}
Name functions to accurately reflect their purpose and return type. Boolean functions should use predicate naming (is, has, can*).
type MetricsExporter struct {
Component string // Exported - accessible
metricsPort int // Non-exported - internal only
}
err rather than custom names like kfErr, generateErr, etc.This convention is a critical part of Go’s visibility system and module design - it’s not just a style preference but affects how your code can be used by others.
Create configurations that can be easily managed outside your application code. Design configuration parameters to be externalized through appropriate mechanisms like environment variables, config files, or Kubernetes custom resources (CRs). This improves manageability, enables GitOps workflows, and supports different deployment environments.
For Kubernetes-based applications, consider using Custom Resources to abstract complex configurations:
# Example: Using a custom resource for simplified configuration
apiVersion: kubeflow.org/v2
kind: Profile
metadata:
name: ml
spec:
resourceQuotaSpec:
hard:
cpu: "2"
memory: 2Gi
requests.nvidia.com/gpu: "1"
persistentvolumeclaims: "1"
requests.storage: "5Gi"
# Optional: Add LimitRange configurations here
Key practices:
When handling package installation in environments like notebooks, be aware of how configuration choices affect persistence across restarts and different environments.
When adding or updating package dependencies, place them in centralized configuration files rather than duplicating them across multiple services. Keep dependencies up-to-date with the latest stable versions and replace deprecated packages with their recommended successors. Always verify backward compatibility when upgrading dependency versions.
Example for centralization:
# Instead of:
# Adding to components/crud-web-apps/jupyter/backend/requirements.txt
# kubernetes==v22.6.0
# Do this:
# Update in components/crud-web-apps/common/backend/setup.py
install_requires=[
"kubernetes>=22.6.0",
# other dependencies
]
Example for replacing deprecated packages:
# Don't:
kfserving==0.5.1 # deprecated package
# Do:
kserve==0.11.1 # recommended successor
When configuring dependency version constraints in project files, follow these principles:
dependencies = ["huggingface_hub>=0.16.4,<1.0"] instead of <0.17pyo3 = "0.16.2"
numpy = "0.16.2"
When modifying or adding exported interfaces in public headers, ensure the external API surface is stable, easy to use across platforms/languages, and does not leak internal implementation details.
Apply these rules: 1) Platform-agnostic signatures: wrap OS/platform-specific details inside internal types/modules; the public API should not force callers to use different types/macros per platform.
// public header
class CpuSet;
CpuSet get_cpu_thread_affinity_mask(int powersave);
2) Consistent return types and lifetimes: prefer references to global/static data when the lifetime is guaranteed.
// if the underlying object is always alive
const CpuSet& get_cpu_thread_affinity_mask(int powersave);
3) Integration-friendly API design: when there is an established de-facto API (e.g., OpenCV), prefer compatibility in names/semantics so drop-in usage is possible.
4) Public header encapsulation: do not expose internal helper/holder classes or implementation-only types in public headers—move them to source files or internal headers.
5) Cross-language linkage: for functions meant to be called from C/other languages, guard declarations and definitions with extern "C" under __cplusplus.
#ifdef __cplusplus
extern "C" {
#endif
void some_exported_c_function(void);
#ifdef __cplusplus
}
#endif
Outcome: callers get one predictable API surface regardless of platform, language, or internal refactors—reducing integration breakage and preventing accidental exposure of internal implementation details.
Ensure layer math, parameter semantics, and model conversion/backends remain consistent so inference results don’t silently change.
Apply these rules:
Example pattern for fast-path gating:
int create_pipeline(const Option& opt) {
if (opt.fast_gelu == 0) {
support_packing = false; // disable incomplete fast/packing
}
return 0;
}
int forward_inplace(Mat& x, const Option& opt) const {
if (opt.fast_gelu == 0) {
// correct baseline implementation
return GELU::forward(x, opt);
}
// otherwise run optimized path
// ...
return 0;
}
These rules prevent silent output drift across AI inference workloads and keep model conversion reliable.
Design configurations that work consistently across different environments without requiring environment-specific modifications. Configurations should be parameterized and adaptable to various deployment contexts (development, production, air-gapped environments).
Key practices:
For example, instead of:
# Only works in master branch with "latest" tag
export CURRENT_CENTRALDB_IMG=docker.io/kubeflownotebookswg/centraldashboard:latest
kustomize build overlays/kserve | kubectl apply -f -
Use a more flexible approach:
# Works across different branches and environments
IMG=${{env.IMG}}:${{env.TAG}}
kustomize build overlays/kserve | kubectl apply -f -
kubectl patch deployment $DEPLOYMENT -n kubeflow --patch \
'{"spec": {"template": {"spec": {"containers": [{"name": "'"$CONTAINER"'","image": "'"$IMG"'"}]}}}}'
Additionally, for UI resources, consider providing configuration options that work in restricted network environments:
# Configurable options for different environments
imageOptions:
- source: internal # For air-gapped environments
- source: external # For internet-connected environments
Configuration values, constants, and default settings should be defined in a single location and referenced from there, rather than duplicated across multiple files or functions. This prevents inconsistencies, reduces maintenance burden, and ensures that changes to configuration values only need to be made in one place.
When you find the same configuration value appearing in multiple locations, extract it to a shared constant or configuration object. For example:
// Bad - duplicated constant
const workflow_count = 10; // in app.js
// ...and the same value hardcoded elsewhere in ui.js
// Bad - duplicated default value
const delta = 0.025; // in one function
let delta = localStorage.getItem("...") || "0.1" // different default elsewhere
// Good - centralized configuration
const CONFIG = {
WORKFLOW_COUNT: 10,
EDIT_ATTENTION_DELTA: 0.1
};
// Reference the centralized value
const workflow_count = CONFIG.WORKFLOW_COUNT;
let delta = localStorage.getItem("...") || CONFIG.EDIT_ATTENTION_DELTA;
This approach ensures that configuration changes are atomic and reduces the risk of inconsistent behavior across your application.
Always use current assertion methods in test code to ensure clarity and future compatibility. Specifically, replace deprecated methods with their modern equivalents, such as using assertRaisesRegex instead of assertRaisesRegexp when validating exceptions. This approach allows you to verify both the exception type and the specific error message content in a single assertion.
# Bad
with self.assertRaisesRegexp(ValueError, "expected message"):
function_that_raises()
# Good
with self.assertRaisesRegex(ValueError, "expected message"):
function_that_raises()
By using modern assertion methods, you improve test readability and maintainability while ensuring your tests will continue to work with future framework updates.
All identifiers should be (1) semantically clear, (2) consistent with project naming patterns, and (3) collision-safe.
Apply this checklist:
resize_type when the concept is “mode/sample_type”).
mode / sample_type and keep comments consistent with the chosen name.enum InterpolationMode {
Interpolation_BILINEAR = 1,
Interpolation_Nearest = 2,
Interpolation_BICUBIC = 3
};
int _axis; use int axis).forceinline with NCNN_FORCE_INLINE).Result: names communicate intent, remain consistent across the codebase, and won’t conflict with external code or platform headers.
Production code should be free from debugging artifacts that reduce readability and maintainability. Remove all debugging print statements, commented-out code blocks, and other temporary debugging elements before merging code.
Specifically:
Remove all debugging print statements: Debug prints should only appear in development branches or be wrapped in appropriate debug-only conditions.
// BAD: Unconditional debug printing
sd_printf("Before op execution \n", 0);
// GOOD: Conditional printing only when needed
if (LOG_LEVEL >= DEBUG) {
sd_printf("Before op execution \n", 0);
}
Delete commented-out code: Commented-out code creates confusion about which implementation is correct and clutters the codebase.
// BAD: Leaving commented-out code without explanation
//REQUIRE_TRUE(expectedUpdShape == updShape, 0, "SCATTER_ADD OP: wrong shape of updates array...");
// GOOD: Either remove it entirely or provide a clear justification comment
// REQUIRE statement intentionally disabled during beta testing until shape validation is fixed in issue #1234
//REQUIRE_TRUE(expectedUpdShape == updShape, 0, "SCATTER_ADD OP: wrong shape of updates array...");
Clean up unused variables and redundant operations: Remove variables that are declared but never used.
If debugging functionality needs to be preserved for future troubleshooting, consider implementing proper logging with configurable levels rather than leaving print statements scattered throughout the code.
Add clarifying comments to improve code readability and maintainability when code behavior isn’t immediately obvious. Two key practices to follow:
/*arg=*/ prefix to clarify their purpose. This is especially important for boolean flags, magic numbers, or default values where the meaning isn’t self-evident.Example:
// Poor: Parameters without context
rescaled_type = uint8_type.clone(buildQTypeFromMinMax(
builder, uint8_element_quant_type.getExpressedType(),
builder.getF64FloatAttr(type_range_min),
builder.getF64FloatAttr(type_range_max),
builder.getI32IntegerAttr(
uint8_element_quant_type.getStorageTypeIntegralWidth()),
0, true, builder.getBoolAttr(narrow_range)));
// Better: Non-obvious arguments labeled
rescaled_type = uint8_type.clone(buildQTypeFromMinMax(
builder, uint8_element_quant_type.getExpressedType(),
builder.getF64FloatAttr(type_range_min),
builder.getF64FloatAttr(type_range_max),
builder.getI32IntegerAttr(
uint8_element_quant_type.getStorageTypeIntegralWidth()),
/*bias=*/0, /*signed=*/true, builder.getBoolAttr(narrow_range)));
For instance, when writing code that manipulates compiler include paths:
// This fixes include paths by also including paths where resolved symlinks are replaced
// by the original paths. Example:
// If cc returns "/usr/bin/gcc/lib/include" but the actual path is a symlink from
// "/usr/lib/include", both paths will be included to ensure proper header resolution.
These documentation practices help other developers understand code intent without having to reverse-engineer the logic, reducing maintenance burden and preventing bugs during future modifications.
When handling tensor inputs that may contain invalid values, use transformational approaches rather than conditional checks. Conditional checks like if value < 0: may work with scalar values but fail with tensor objects during graph execution.
Instead of raising exceptions based on conditions:
# Not tensor-friendly - may fail during graph execution
if clip_norm < 0:
raise ValueError('clip_norm should be positive')
Use transformations to handle invalid values:
# Tensor-friendly approach
clip_norm = math_ops.maximum(clip_norm, 0) # Convert negative values to zero
For type validations, ensure you check all inputs comprehensively:
# Complete validation for both input and output types
if (not dtype.is_floating and not dtype.is_integer) or (not image.dtype.is_floating and not image.dtype.is_integer):
raise AttributeError('data type must be either floating point or integer')
When implementing such transformations, document the behavior clearly to inform users how edge cases are handled.
Use canonical, consistently formatted identifiers across code and build files, and verify every variable/option name is spelled exactly as the build system expects.
Apply this checklist:
1) Canonical token per platform/arch: follow the established external style the project aligns with (e.g., for Loongarch, prefer loongarch consistently rather than loongarch64 for directory/file/class naming).
2) Consistent formatting for feature/option names: follow existing project patterns for suffixes (e.g., prefer NCNN_SSE41 over NCNN_SSE4_1 to match conventions like NCNN_ARM82, NCNN_ARM86XXX).
3) Typo-proof build identifiers: for CMake, use the exact variable names (typos silently break behavior).
Example (CMake):
# Bad (typo)
set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} ...")
# Good
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s FORCE_FILESYSTEM=1")
# Good option naming
option(NCNN_SSE41 "optimize ... with sse4.1 extension" ON)
Maintain consistency in naming patterns across related resources while ensuring names accurately reflect their purpose. When naming components, files, or configurations:
Example:
# Good
namespace: kubeflow
namePrefix: pvcviewer- # Consistent with label "pvcviewers" used elsewhere
# Avoid
namespace: kubeflow
namePrefix: pvc-viewer- # Inconsistent with "pvcviewers" label
For workflow files, use names that accurately describe their function:
# Good
name: CentralDashboard-angular Frontend Tests
# filename: centraldb_angular_frontend_test.yaml
# Avoid
name: CentralDashboard-angular Frontend check
# filename: centraldb_angular_frontend_check.yaml
OWNERS files must follow project documentation standards to properly reflect component ownership and maintainership. When creating or updating these files:
Example of a properly structured OWNERS file:
approvers:
- developer1
- developer2
- developer3
reviewers:
- reviewer1
- reviewer2
If someone should be both an approver and a reviewer, only list them as an approver. This ensures clear documentation of component ownership and streamlines the review process.
Maintain CI/CD infrastructure with security and currency as top priorities. This includes:
Keep build tools updated: Always use the latest stable versions of build tools and dependencies in CI/CD environments to benefit from bug fixes, security updates, and improved features.
Never bypass security measures: Security controls like package signature verification are essential and should never be disabled for convenience.
Example from Discussion 1:
# GOOD: Keep signature verification enabled
# Install packages securely
RUN C:\tools\msys64\usr\bin\bash.exe -lc 'pacman --noconfirm -Syy git curl zip unzip patch'
# BAD: Don't disable signature verification
# RUN Add-Content -Path C:\tools\msys64\etc\pacman.d\mirrorlist.mingw32 -Value 'SigLevel = Never'
# RUN Add-Content -Path C:\tools\msys64\etc\pacman.d\mirrorlist.mingw64 -Value 'SigLevel = Never'
# RUN Add-Content -Path C:\tools\msys64\etc\pacman.d\mirrorlist.msys -Value 'SigLevel = Never'
Example from Discussion 0:
# GOOD: Use recent versions of build tools
RUN (New-Object Net.WebClient).DownloadFile(
'https://github.com/bazelbuild/bazelisk/releases/download/v1.16.0/bazelisk-windows-amd64.exe',
'C:\tools\bazel\bazel.exe')
# BAD: Don't use outdated versions
# RUN (New-Object Net.WebClient).DownloadFile(
# 'https://github.com/bazelbuild/bazelisk/releases/download/v1.11.0/bazelisk-windows-amd64.exe',
# 'C:\tools\bazel\bazel.exe')
Regularly audit build environments to ensure they remain secure and up-to-date. Document version update procedures to make maintenance easier for the team.
Always keep signature verification enabled in package managers, even in development environments, Docker containers, or when facing initialization challenges. Disabling signature verification creates a significant security vulnerability by allowing potentially compromised or malicious packages to be installed.
Why this matters: Package signature verification is a critical defense against supply chain attacks. Even temporary disabling for convenience can expose systems to compromise.
Example - Do not do this:
# Disable signature checking on pacman because we cannot initialize the keyring
RUN pacman-key --init && pacman -Sy --noconfirm --disable-download-timeout
Instead do this:
# Initialize keyring properly to maintain signature checking
RUN pacman-key --init && pacman-key --populate && pacman -Sy --noconfirm --disable-download-timeout
When facing difficulties with package signature verification, research the proper initialization method rather than disabling the security feature.
When implementing version changes or migrations, provide comprehensive documentation and tools to support users through the transition process. This includes:
For example, when creating a version converter tool:
# KfDef version converter
## Overview
This is a simple helper CLI that converts KfDef between versions.
## Usage
A simple CLI to convert KfDef from v1alpha1 to v1beta1
Usage:
kfdef-converter [command]
Available Commands:
help Help about any command
tov1beta1 Convert a KfDef config in v1alpha1 into v1beta1 format.
## Example
# Convert a config file from v1alpha1 to v1beta1
kfdef-converter tov1beta1 --input=/path/to/old-config.yaml --output=/path/to/new-config.yaml
When planning roadmaps that include migrations, be specific about upgrade capabilities rather than making general promises. If complete migration support isn’t feasible, consider defining limited scope migrations or marking them as stretch goals.
When implementing AI model components like tokenizers, favor simplicity over rarely-used features that significantly increase code complexity. This is especially important for performance-critical paths in machine learning pipelines. Consider removing or deferring implementation of features that:
Example:
// AVOID: Complex implementation with rarely-used features
let encodeBatch = promisify(tokenizer.encodeBatch.bind(tokenizer));
var output = await encodeBatch(
[["Hello, y'all!", "How are you 😁 ?"], ["Hello to you too!", "I'm fine, thank you!"]]
);
// BETTER: Simplified implementation focusing on core functionality
var output = await tokenizer.encodeBatch(["Hello, y'all!", "How are you 😁 ?"]);
This approach helps maintain performance in AI inference paths while keeping the codebase maintainable. Features can always be added later when there’s a clear need and sufficient time for proper implementation.
Never expose security vulnerabilities in public issue trackers. Security issues require confidential handling to prevent exploitation before fixes are available. Use private reporting channels such as:
When implementing security reporting processes:
Example security.md section:
## Reporting a Vulnerability
Please DO NOT report security vulnerabilities through public GitHub issues.
Instead, please report them via:
- Our dedicated security email: security@project.org
- GitHub's private vulnerability reporting feature: [Project Security](https://github.com/organization/project/security/advisories/new)
Include as much information as possible about the vulnerability. The security team will respond acknowledging receipt of the report and outline the next steps in handling your submission.
This practice helps protect users while vulnerabilities are being addressed and follows security industry best practices.
Ensure all configuration elements (dependencies, build settings, preprocessor flags) are up-to-date, documented, and consistent with project standards. This practice prevents issues arising from outdated references and improves maintainability for team members.
Key practices include:
// In NecAurora.md:
// .vc/.vcpp file extensions are used to differentiate VE device files
// from c/cpp in cmake. Cmake will compile them using nec.
-#ifdef HAVE_MKLDNN
+#ifdef HAVE_ONEDNN
// Updated to reflect new dependency name
Maintain consistent tool versions across related projects (e.g., same Maven version for all modules)
Regularly audit configuration files to ensure they remain aligned with current technologies, dependency versions, and organizational standards.
Tests should assert specific expected values rather than just verifying general functionality. This practice makes tests more robust against subtle regressions and helps catch “under the radar” bugs where behavior is modified unintentionally.
Instead of print statements or simply checking that code runs without errors, include explicit assertions that verify exact expected outputs:
// LESS ROBUST: Only verifies the code runs without errors
#[test]
fn test_tokenizer() {
let output = tokenizer.encode("Hello", true).unwrap();
println!("{:?}", output.get_tokens()); // Just prints, doesn't verify
}
// MORE ROBUST: Explicitly checks expected values
#[test]
fn test_tokenizer() {
let output = tokenizer.encode("Hello", true).unwrap();
assert_eq!(
output.get_tokens(),
["[CLS]", "Hello", "[SEP]"]
);
assert_eq!(
output.get_ids(),
[1, 27253, 2]
);
}
This approach creates tests that serve as both verification and documentation of expected behavior. While it may require more maintenance when intentionally changing behavior, it significantly improves the ability to catch unintended changes and regressions.
Maintain consistent Makefile patterns across all components to improve build reliability and developer experience in CI/CD pipelines.
Key practices to follow:
.PHONY targets for all rules to prevent conflicts with actual files:
.PHONY: build docker-build docker-push image
TAG ?= $(shell git describe --tags --always)
docker-build:
docker build -t ${IMG}:${TAG} -f Dockerfile .
docker-push:
docker push ${IMG}:${TAG}
image: docker-build docker-push
# Instead of:
# cd .. && docker build -t ${IMG}:${TAG} -f Dockerfile .
# Prefer:
docker build -t ${IMG}:${TAG} -f Dockerfile ..
These standardized patterns make it easier for developers to work across different components, improve CI/CD pipeline reliability, and reduce confusion when building and deploying components.
Replace hardcoded styling values and configuration constants with flexible alternatives to improve maintainability and consistency. Use CSS variables for colors and theming, backend-provided values for limits and ranges, and semantic CSS properties instead of absolute positioning.
Instead of hardcoding values:
// Avoid this
divElement.style.backgroundColor = 'Black';
divElement.style.left = "20px";
divElement.style.position = "absolute";
max = 1920; // hardcoded limit
Use flexible alternatives:
// Prefer this
divElement.style.backgroundColor = "var(--comfy-input-bg)";
divElement.style.cssFloat = "left";
divElement.style.marginRight = "4px";
max = targetWidget.options?.max; // use backend value
This approach makes code more maintainable by centralizing styling decisions, enables consistent theming across the application, and reduces the need to update multiple locations when requirements change. It also ensures that UI components adapt properly to different contexts and user preferences.
Manage dependencies at the top level using <dependencyManagement> to ensure version consistency across modules and prevent conflicts. Define version properties in one place and reference them throughout the project:
<!-- In parent pom.xml -->
<properties>
<jackson.version>2.15.0</jackson.version>
<jmh.version>1.33</jmh.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
In module pom files, reference dependencies without version numbers:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
Avoid:
${project.version} or ${project.parent.version}For related but distinct libraries (like Netty 3.x vs 4.x), create separate version properties (e.g., netty3.version and netty.version) to clearly distinguish them.
Always match logging levels to the message’s purpose and severity. Use log.Info for general information, log.Warn for warnings, and log.Error for error conditions. Avoid using fmt.Println for logging as it bypasses the logging framework’s level-based filtering capabilities.
Keep these guidelines in mind:
Example of incorrect logging:
// Incorrect usage
fmt.Println("Present working directory is: %v", cwd)
log.Info("WARNING: Notebook container is not found, so could not update State of Notebook CR")
Example of correct logging:
// Correct usage
log.Info("setting up workload identity", "ClientId", azure.AzureIdentityClientId)
log.Error("could not find the notebook container", "notebook-name", instance.Name)
Following these practices helps with log filtering, improves troubleshooting, and creates a consistent logging experience throughout the codebase.
Create reusable components with styles that don’t make assumptions about parent contexts or affect their positioning in different applications. Keep positioning styles (like margins) in the parent components that use them rather than in the reusable component itself. Prefer properties that don’t assume parent styling context.
Instead of this:
// In a reusable component
.panel-body {
margin-top: 5px; // Affects positioning
flex: 1; // Assumes parent has display: flex
}
Do this:
// In a reusable component
.panel-body {
padding: 1px; // Internal spacing only
height: 100%; // Fills available space without assumptions
}
// In the parent component that uses it
.parent-container .panel-body {
margin-top: 5px; // Position-affecting styles belong here
}
This approach ensures components remain flexible and can be reused in different contexts without layout issues.
Use the ‘prv’ prefix for private class members and ensure they’re explicitly declared with the ‘private’ access modifier. This maintains consistency with established team conventions and improves code readability by clearly indicating variable scope.
export class MyComponent {
// Correct: prefix matches access modifier
private prvUserData: UserData;
// Incorrect: prefix doesn't match access modifier
public prvConfig: Config;
// Incorrect: no prefix but is private
private userData: UserData;
}
When refactoring existing code, update variable declarations to follow this pattern consistently. For observable patterns, public-facing properties should have clean names without implementation details while their corresponding subjects should use the ‘prv’ prefix:
export class MyService {
// Private subjects
private prvDataSubject = new ReplaySubject<Data>(1);
// Public observable (clean naming)
data = this.prvDataSubject.asObservable();
}
Select algorithmic constructs and control structures that are appropriate for the specific task. Common issues include:
For example, replace this inefficient nested loop approach:
# Unnecessarily complex traversal
for condition in conditions:
for item in condition:
if "reason" in item:
# process item
With a direct, more efficient approach:
# Simple, appropriate traversal
for condition in conditions:
if "reason" in condition:
# process condition directly
Similarly, use if statements rather than while loops when you’re only checking a condition once without repeated execution. This improves readability, prevents potential infinite loops, and better expresses the logical intent of your code.
Initialize variables with type-appropriate default values to prevent type errors and null reference exceptions during operations. When a variable is expected to hold a collection type (list, dictionary, set), use the corresponding empty collection ([], {}, set()) rather than other falsy values like None or empty strings.
For example, instead of:
conditions = notebook.get("status", {}).get("conditions", "")
# Using "" as default for a variable that should be a list is problematic
if some_condition:
conditions.append(new_item) # This will fail if conditions is ""
Use type-appropriate defaults:
conditions = notebook.get("status", {}).get("conditions", [])
# Using [] as default ensures the variable is always a list
if some_condition:
conditions.append(new_item) # This will work regardless
For complex data structures like dictionaries passed as parameters, consider adding type hints or documentation that clearly defines the expected structure, including which fields are optional vs. required. This helps prevent null reference errors when accessing dictionary keys.
Follow Python’s PEP 8 naming convention by using snake_case for variables, functions, and methods rather than camelCase or other styles. This enhances readability and maintains consistency across the codebase.
According to PEP 8, variable and function names in Python should use lowercase with words separated by underscores (snake_case).
Instead of writing:
def set_notebook_memory(notebook, body, defaults):
container = notebook["spec"]["template"]["spec"]["containers"][0]
memory = get_form_value(body, defaults, "memory")
memoryLimit = get_form_value(body, defaults, "memoryLimit")
Write:
def set_notebook_memory(notebook, body, defaults):
container = notebook["spec"]["template"]["spec"]["containers"][0]
memory = get_form_value(body, defaults, "memory")
memory_limit = get_form_value(body, defaults, "memoryLimit")
This applies to all variable names, function names, method names, and module names in Python code. Class names should use CapWords (PascalCase) convention.
Create reliable and reproducible tests by explicitly controlling test inputs and verifying function behavior doesn’t have unintended side effects. Two key practices to follow:
// Call function under test PCA.pca_factor(inputMatrix, …);
// Verify input wasn’t modified assertEquals(duplicateInput, inputMatrix);
2. Make tests deterministic by setting explicit seeds for any operations involving randomness:
```java
// Use a specific seed to ensure deterministic behavior
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.seed(2021) // Important: ensures consistent initialization for tests
.dataType(DataType.DOUBLE)
// other configuration
.build();
Including these practices in your tests will help prevent flaky tests, make debugging easier, and ensure that test failures represent actual issues rather than side effects or randomness.
Maintain a clear separation between resource-specific API handlers and common utilities. Resource-specific handlers should remain in their dedicated modules to reduce dependencies, while common functionality should be extracted into shared helpers for consistency.
Example:
# GOOD: Common helper function in a shared utility file
# components/crud-web-apps/common/backend/kubeflow/kubeflow/crud_backend/helpers.py
def get_age(k8s_object):
"""Return age information in a standardized format for any k8s object."""
creation_time = dt.datetime.strptime(
k8s_object["metadata"]["creationTimestamp"], "%Y-%m-%dT%H:%M:%SZ")
uptime = dt.datetime.now() - creation_time
return {
"uptime": str(uptime).split('.')[0], # Remove microseconds
"timestamp": creation_time.strftime("%Y-%m-%dT%H:%M:%SZ")
}
# GOOD: Resource-specific handlers in dedicated modules
# components/model-web-app/backend/app/routes/inference_service.py
def list_inference_services(namespace):
"""Handler specific to InferenceService resources."""
# Implementation specific to this resource type
This approach prevents common code from accumulating resource-specific dependencies while still promoting reuse of utility functions that apply across multiple API endpoints. When designing APIs, always evaluate whether functionality belongs in shared utilities or should remain in resource-specific implementations.
Improve code readability by reducing nesting depth with early returns and functional approaches. Use early returns to handle edge cases first, and prefer functional operators over nested conditionals when working with streams or collections.
Example for early return:
// Instead of this
selectType(event): void {
this.typeSelected = event.value;
if (this.typeSelected === 'New') {
this.volume.controls.name.setValue(this.currentVolName);
}
}
// Prefer this
selectType(event): void {
this.typeSelected = event.value;
if (this.typeSelected !== 'New') return;
this.volume.controls.name.setValue(this.currentVolName);
}
Example for functional approach:
// Instead of this
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
// Do something
}
});
// Prefer this
this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe(event => {
// Do something
});
When handling URLs for API interactions and navigation, use precise methods for both comparison and construction to avoid subtle bugs:
startsWith() instead of includes() to prevent false positives from substring matches:// AVOID: May lead to incorrect matches
return browserUrl.includes(url);
// BETTER: More precise path matching
return browserUrl.startsWith(url);
// AVOID: Potential issues with relative paths
const href = window.location.origin + url;
const urlObject = new URL(href);
// BETTER: Robust URL construction
const urlObject = new URL(url, window.location.origin);
These practices ensure reliable API interactions and prevent navigation edge cases when handling routes and endpoints.
Reserve logging statements for their appropriate purposes and levels. Use debugging-level logs (sd_debug) for development-time diagnostic information, and only use standard printing functions (sd_printf) for critical user-facing messages or error conditions. Excessive or incorrectly leveled logging creates noise in production systems and can impact performance.
Bad example:
// Inappropriate for normal operation flow
sd_printf("Setting input buffer %d\n", index);
sd_printf("Pushing variable\n", 0);
sd_printf("realdiv: Pre variables\n", 0);
Good example:
// For diagnostic information during development
sd_debug("Setting input buffer %d\n", index);
sd_debug("Pushing variable\n");
// For error conditions that users need to see
if(ptr == nullptr)
sd_printf("ERROR: Context pointer is null!\n");
Consistent logging practices improve code readability, aid in debugging, and prevent log pollution in production environments.
When handling nullable or undefined states, use enumerations instead of primitive types like boolean or null/undefined. Enums provide more descriptive and type-safe representations of different states, including the absence of a value or an unknown state.
Instead of:
private dashboardConnectedSource = new BehaviorSubject<boolean>(true);
Use an enum to explicitly represent all possible states:
enum DashboardState {
Unknown = 0, // Initial state before connection status is determined
Connected,
Disconnected,
}
private dashboardStateSource = new BehaviorSubject<DashboardState>(DashboardState.Unknown);
This approach prevents misleading default values, improves code readability, and provides better type safety. When making decisions based on state, the enum forces you to handle all possibilities, reducing the likelihood of bugs related to unexpected null or undefined values.
When handling URLs in web applications, consistently normalize path formats to prevent routing and service communication issues. This is especially important when working with services like Istio that expect specific URL formats (e.g., trailing slashes).
Key implementation practices:
Example:
// Ensure trailing slash for service URLs that require it (e.g., Istio)
function normalizeServiceUrl(url: string): string {
return url?.endsWith('/') ? url : url + '/';
}
// When comparing URLs, normalize paths first
function equalUrlPaths(firstUrl: string, secondUrl: string): boolean {
// Handle sometimes missing '/' from URLs for consistent comparison
const normalizedFirst = firstUrl?.endsWith('/') ? firstUrl : firstUrl + '/';
const normalizedSecond = secondUrl?.endsWith('/') ? secondUrl : secondUrl + '/';
return normalizedFirst === normalizedSecond;
}
When implementing numerical algorithms, never compare floating-point values directly for equality due to precision errors. Instead:
// Instead of this: if (backpropGradient == 0.0) { … }
// Do this: if (Math.abs(backpropGradient) < EPSILON) { … }
2. For equality comparisons in algorithms like sorting or searching, use built-in methods:
```java
// Instead of manually comparing with multiple conditions:
if (lhs.fitness < rhs.fitness)
return 1;
else if (rhs.fitness < lhs.fitness)
return -1;
return 0;
// Use the built-in compare method:
return Double.compare(rhs.getFitness(), lhs.getFitness());
Following these practices prevents subtle bugs in sorting, searching, and numerical algorithms where small differences in representation can lead to incorrect results.
When implementing tokenizers for AI models, ensure flexibility and robust behavior across different contexts:
tokenizer = Tokenizer(BPE(
unk_token=str(unk_token),
dropout=dropout,
end_of_word_suffix=suffix
))
# Instead of checking for exactly "[UNK]"
unk_token_regex = re.compile('(.{1}\b)?unk(\b.{1})?', flags=re.IGNORECASE)
This approach ensures tokenizers work consistently across different implementations and models, which is critical for reliable AI text processing pipelines and model interoperability.
Configure CI/CD workflows to trigger precisely based on relevant file path changes. This minimizes unnecessary builds and tests while ensuring all required workflows run when dependencies are modified.
For component-specific workflows:
# Example for a web application workflow
name: Build & Publish JWA Docker image
on:
push:
branches:
- master
- v*-branch
paths:
- components/crud-web-apps/jupyter/** # Component code
- components/crud-web-apps/common/** # Shared dependencies
For manifest-related workflows:
# For manifest testing, specify manifest paths only
name: Build Profile Controller manifests
on:
pull_request:
paths:
- components/profile-controller/config/** # Only manifest changes
Centralize build logic in Makefiles instead of duplicating in GitHub Actions. This allows workflows to simply call make targets, making pipelines more maintainable and consistent across environments.
Maintain consistent code style enforcement scripts across all projects by standardizing linting and formatting configurations in package.json. Use modern, supported tools instead of deprecated ones (like tslint).
Every frontend project should include these standard scripts:
{
"scripts": {
"lint-check": "ng lint",
"lint": "ng lint --fix",
"format:check": "prettier --check 'src/**/*.{js,ts,html,scss,css}' || node scripts/check-format-error.js"
}
}
This approach ensures:
lint-check, format:check) and auto-fixing options (lint)When adding these scripts, make appropriate configurations in angular.json as needed to support them.
Configure your development environment to automatically enforce code style standards rather than relying on manual checks during code review. This includes:
Example IDE configuration for VSCode (settings.json):
{
"files.insertFinalNewline": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
This approach reduces style-related comments in code reviews, ensures consistency across the codebase, and allows reviewers to focus on more substantive issues.
Use descriptive and consistent names throughout the codebase. Prefer full, meaningful names over acronyms or abbreviations to improve readability and understanding, especially for newcomers. Maintain naming consistency across different files, configurations, and references to the same entity.
Examples:
centraldashboard-angular over centraldashboard when referring to the Angular version of the central dashboardAccess Management instead of KFAM to clearly indicate the component’s purposeWhen introducing new components or refactoring existing ones, ensure the same naming pattern is followed in all references to maintain consistency and avoid confusion. This includes Makefiles, configuration files, documentation, and code comments.
When documenting network access methods or service connections, always provide specific commands with explicit ports and namespaces rather than general approaches. Include clear examples of how to connect to each required service and explain the underlying proxying mechanisms.
For example, instead of general instructions like:
To access the Kubernetes REST API, run kubectl proxy --port=8083.
Provide specific commands for each service:
To access a Kubernetes service, run `kubectl port-forward -n kubeflow svc/<service-name> <service-proxy-port>:<service-port>`
e.g. `kubectl port-forward -n kubeflow svc/jupyter-web-app-service 8085:80`.
Additionally, document how proxying works and what happens if network connections fail, including any potential cascade effects on dependent services. This specificity helps developers understand exactly what networking configurations are needed and prevents confusion when setting up local development environments or troubleshooting connection issues.
Configure containerized application builds to be efficient and flexible by avoiding hardcoded architecture decisions and using appropriate compiler flags. Let the build system determine architecture targeting instead of maintaining architecture-specific code blocks in your Dockerfiles. For Go applications, use appropriate build flags like CGO_ENABLED=0 to enable static linking and optimize container images.
Example: Instead of:
RUN if [ "$(uname -m)" = "aarch64" ]; then \
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o webhook -a . ; \
else \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o webhook -a . ; \
fi
Prefer:
RUN CGO_ENABLED=0 GOOS=linux go build -o webhook -ldflags "-w" -a .
This approach simplifies maintenance, allows multi-architecture builds through tools like Docker buildx (e.g., docker buildx build --platform linux/amd64,linux/arm64 ...), and produces more efficient container images.
When implementing AI model optimization techniques such as early stopping algorithms or hyperparameter tuning, include proper validation mechanisms to help users effectively reduce model overfitting and improve accuracy.
Validation should include:
For example, when implementing early stopping validation for Katib experiments:
# Example validation for early stopping settings
algorithm:
earlyStoppingSettings:
# Validate these values with appropriate ranges and types
evaluationInterval: 1 # Validate this is a positive integer
threshold: 0.01 # Validate this is a positive float
comparisonType: "smaller" # Validate this is one of ["smaller", "larger"]
This approach helps prevent common errors in machine learning workflows, reduces debugging time, and improves model quality by ensuring optimization techniques are correctly applied.
Design applications to use external configuration sources rather than hardcoding values directly in source code. This allows for configuration changes without requiring code modifications or redeployment.
When defining configurations that might change between environments or user preferences:
For example, instead of hardcoding allowed namespaces:
// Avoid this
export const ALL_NAMESPACES_ALLOWED_LIST = ['jupyter'];
// Prefer dynamic configuration loaded from an external source
export const ALL_NAMESPACES_ALLOWED_LIST = loadFromConfigMap('namespaces.allowed');
Similarly, when importing resources to support configurable features, consider importing complete libraries if it enables easier configuration through external sources:
// This allows for configurable icons via ConfigMap without source code changes
import '@polymer/iron-icons/communication-icons.js';
Ensure CI/CD workflow configuration files follow best practices for maintainability and correctness:
extras_require = { “dev”: [“black==22.3”, “click==8.0.4”] }
pip install package[dev]
pip install black==22.3 click==8.0.4
2. Always quote numerical values in YAML files to prevent parsing issues, especially for version numbers:
```yaml
# Correct:
python: ["3.7", "3.8", "3.9", "3.10"]
# Problematic:
python: [3.7, 3.8, 3.9, 3.10] # 3.10 will be parsed as 3.1
Use consistent string formatting in logging statements throughout the codebase. Prefer % style placeholders over f-strings or .format() in logging calls as this is more efficient when logs are filtered by level (placeholders are only evaluated if the log is actually emitted).
For good logging practices:
logging.info(‘%s benchmark running.’, operation_type)
logging.error(‘No models found in S3 bucket: {}’.format(bucket_name)) logging.warning(f’Failed to process {item_name}’) # Avoid f-strings in logging
2. Reduce duplicate logging logic:
```python
# Instead of:
if opt.train:
logging.info('%s training benchmark.', cell)
else:
logging.info('%s inference benchmark.', cell)
# Prefer:
mode = 'training' if opt.train else 'inference'
logging.info('%s %s benchmark.', cell, mode)
logging.error() for failures that prevent normal operationlogging.warning() for potential issues that don’t stop executionIn Go, prefer table-driven tests over multiple separate test functions. Table tests allow for concise testing of multiple scenarios, improve code readability, and make it easier to add new test cases.
A table-driven test consists of:
Example:
func TestSomething(t *testing.T) {
tests := []struct {
name string
input map[string]string
expected map[string]string
}{
{
name: "case1",
input: map[string]string{"key1": "value1"},
expected: map[string]string{"key1": "value1", "defaultKey": "defaultValue"},
},
{
name: "case2",
input: map[string]string{},
expected: map[string]string{"defaultKey": "defaultValue"},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := functionUnderTest(test.input)
if !reflect.DeepEqual(result, test.expected) {
t.Errorf("Expected:\n%v\nGot:\n%v", test.expected, result)
}
})
}
}
This pattern makes your test suite more maintainable and encourages thorough testing of edge cases by making it trivial to add new scenarios. When reviewing code, ensure new functionality is tested with table-driven tests rather than creating separate test functions for related scenarios.
Strive to simplify code structure by eliminating unnecessary complexity. This includes:
// Bad
if (someCondition) {
// do work
}
if err := r.Update(ctx, profileIns); err != nil {
return err
}
// Good
if (someCondition) {
// do work
if err := r.Update(ctx, profileIns); err != nil {
return err
}
}
// Bad
if !ok || existingValue != v {
ns.Labels[k] = v
}
// Good
ns.Labels[k] = v
// Bad
if pod.Status.ContainerStatuses[i].Name == instance.Name &&
pod.Status.ContainerStatuses[i].State != instance.Status.ContainerState {
// handle condition
}
// Good
if pod.Status.ContainerStatuses[i].Name != instance.Name {
continue
}
if pod.Status.ContainerStatuses[i].State == instance.Status.ContainerState {
continue
}
// handle condition
// Bad
if nodename != "" {
// lots of code here
}
// Good
if nodename == "" {
return nil
}
// lots of code here with less indentation
This makes your code more readable, maintainable, and less error-prone.
Always validate that objects, maps, and other reference types are non-nil before attempting to use them. Use early nil checks with clear returns to improve code readability and prevent null pointer exceptions.
For objects:
// Good: Early nil check with informative logging
if pod == nil {
log.Info("No pod found. Won't update notebook conditions and containerState")
return status, nil
}
// Now safely use pod...
For maps and collections:
// Good: Initialize map if nil before adding items
if currSA.Annotations == nil {
currSA.Annotations = map[string]string{}
}
currSA.Annotations[key] = value
This pattern reduces nesting levels, makes error conditions explicit, and prevents the most common source of runtime panics in Go. When functions receive objects from external sources or other functions, always check their validity before proceeding with operations on them.
When documenting AI models, frameworks, and optimization techniques, precision in language is as important as precision in your algorithms. Technical inaccuracies or unclear explanations can lead to implementation errors and confusion.
Key practices to follow:
Clear documentation directly impacts how effectively developers can implement and optimize AI models, particularly for critical operations like quantization that balance accuracy and performance.
Complex expressions, especially nested ternary operations, reduce code readability and maintainability. Prefer simpler alternatives:
// More readable: if ((common::is_int(inputs[0].type_flag_) || inputs[0].type_flag_ == kBool) && !param.exp_is_int) { temp_mid_tblob = outputs[0]; } else if (inputs[0].type_flag_ == kBool) { temp_mid_tblob = TBlob(…); } else { temp_mid_tblob = inputs[0]; }
2. Simplify boolean conditions and remove unnecessary parentheses:
```cpp
// Instead of:
const bool same_shape = (inputs[0].shape() == inputs[1].shape());
// Use:
const bool same_shape = inputs[0].shape() == inputs[1].shape();
// Extract shapes used multiple times
const auto& lhs_shape = inputs[0].shape();
const auto& rhs_shape = inputs[1].shape();
const bool same_shape = lhs_shape == rhs_shape;
// Define a constant: const float SOFTRELU_THRESHOLD = 20.0f; const auto softrelu = (val > SOFTRELU_THRESHOLD) ? val : ::log(1 + ::exp(val));
5. Use const for loop iterators and function parameters when they're not modified:
```cpp
// Prefer:
for (const auto& kv : n.outputs) {
// code
}
These practices improve code clarity, reduce cognitive load when reading the code, and make future maintenance easier.
When implementing or documenting performance optimizations, clearly explain the mechanism and expected performance benefit. For memory-bound optimizations, specify exactly how memory operations are reduced:
# Instead of:
out_mem = conv_result # Requires writing to output memory
activation_layer(out_mem) # Requires reading and writing again
# Better (fusion):
out_mem = activation_layer(conv_result) # Single memory write
# For additive operations:
# Instead of:
out_mem = conv_result # Overwrites existing data
# Better:
out_mem += conv_result # Adds to existing data without separate read
For data-intensive operations like quantization tuning, include preparation best practices: “As input data is used many times during tuning, it is better to have it prepared earlier.” This reduces redundant processing and improves overall performance.
When explaining optimization patterns, clearly describe the benefit: “chaining operations which can be performed one after another immediately, where input of every subsequent operation is the output of the previous one” provides specific insight into why the optimization helps. Precise explanations help developers implement optimizations correctly and make informed decisions about performance trade-offs.
When data will be accessed multiple times during processing, avoid redundant calculations by pre-computing values upfront rather than using lazy evaluation. This pattern significantly improves performance in iterative operations like machine learning training, inference, or repeated data transformations.
For example, in data processing pipelines:
# Performance optimization:
# Pre-compute transformations when data will be accessed repeatedly
transformer = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=rgb_mean, std=rgb_std)
])
# Use lazy=False to prepare data upfront when it will be used multiple times
data_loader = DataLoader(dataset.transform_first(transformer, lazy=False))
By preparing data once rather than on-demand, you reduce computational overhead and improve overall execution speed, especially in performance-critical sections of code.
When updating technical docs, ensure they are reliable in both what they claim and how developers can apply them:
参考:<https://zhuanlan.zhihu.com/p/128974102>
Practical checklist before merging a doc change: 1) Do section titles/subtitles match the commands and parameters in the text? 2) Are version statements accurate (use >= or range when appropriate)? 3) Can someone follow the steps from a clean environment to a working result? 4) Are there cautions for known failure modes (path conflicts, mismatched shared libraries)? 5) Do external links render consistently in Markdown?
When introducing or updating environment/configuration behavior, ensure the documented meaning, runtime inputs (CLI/feature flags), and build-time discovery (CMake/pkg paths) all point to the same intended target. Avoid “it compiles” success that doesn’t enable the feature, and avoid “it builds” that accidentally links against a mismatched dependency set.
Apply this checklist: 1) Runtime flags must match documentation semantics
gpu_device = -1), do not report results or behavior as if the feature were enabled. Ensure the corresponding benchmark/runtime command-line option actually enables it.2) Build-time dependency resolution must be anchored to an explicit prefix
--prefix.CMAKE_PREFIX_PATH to paths under that prefix (so bin/lib/include match) BEFORE find_package.Example (CMake prefix configuration):
# e.g., /path/to/protobuf/install
set(ProtobufRoot "/path/to/protobuf/install")
# Point CMake to the exact install root’s artifacts
list(APPEND CMAKE_PREFIX_PATH
"${ProtobufRoot}/bin"
"${ProtobufRoot}/lib"
"${ProtobufRoot}/include")
find_package(Protobuf REQUIRED)
If configuration involves both build and runtime, verify end-to-end: the build-time selection (what got found/linked) and the runtime enablement (what got switched on) are consistent with the docs and expected behavior.
Choose names that clearly reveal the purpose, behavior, or type of the code elements they represent. A good name should answer “what” rather than “how” and should be precise enough to avoid ambiguity.
For functions, choose names that indicate what they do or return:
// Less clear
inline bool is_float(const int dtype) {
// checks if dtype is any floating point type
}
// More clear
inline bool is_floating(const int dtype) {
// clearly indicates checking for any floating point type
}
For variables, use domain-specific terms that express their meaning:
// Less clear
const int strides_1 = floor((IH << 1) / OH) - floor(IH / OH);
const int strides_2 = floor((IW << 1) / OW) - floor(IW / OW);
// More clear
const int strides_H = floor((IH << 1) / OH) - floor(IH / OH);
const int strides_W = floor((IW << 1) / OW) - floor(IW / OW);
Use prefixes or qualifiers when name conflicts might occur:
// Potential conflict with mshadow::kInt8
enum QuantizeOutType { qAuto = 0, qInt8, qUint8 };
For configuration variables, be specific about what they control:
// Too generic
bool disable_fuse_all = dmlc::GetEnv("MXNET_DISABLE_ONEDNN_FUSE_ALL", false);
// More specific
bool disable_fuse_requantize = dmlc::GetEnv("MXNET_DISABLE_ONEDNN_FUSE_REQUANTIZE", false);
bool disable_fuse_dequantize = dmlc::GetEnv("MXNET_DISABLE_ONEDNN_FUSE_DEQUANTIZE", false);
Extract meaningful operations into well-named functions instead of using inline code blocks.
Explicitly pin version dependencies in configuration files to ensure reproducible builds and prevent breaking changes. When dealing with external tools, scripts, or APIs, always specify exact versions or commit hashes rather than using “latest” or master branches.
Examples:
# Good: Pin external scripts to specific commit hashes
test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/a9bd9117a77a2f84bbc546e28991136fe0000dc0/hack/setup-envtest.sh
# Good: Specify exact versions of tools
$(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0)
When managing cross-version compatibility, add clear documentation for when temporary compatibility configurations can be removed:
# Good: Document temporary compatibility settings
spec:
preserveUnknownFields: false # TODO: Remove in Kubeflow 1.7 release
For build configurations, explicitly define the environment to ensure consistency:
# Setting SHELL to bash allows bash commands to be executed by recipes
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec
Regularly clean up unused dependencies with tools like go mod tidy to maintain clean configuration files.
When writing documentation (README files, tutorials, API docs), ensure clarity and proper formatting:
# Arguments
- batch_size: Define batch size (default=64)
- epochs: Define total epochs (default=1000)
- mu: Define μ in μ-Law encoding for audio quantization (see https://en.wikipedia.org/wiki/μ-law_algorithm)
Understand markdown formatting rules - Be aware that formatting details like trailing spaces affect rendering. Double spaces at line ends create line breaks in markdown.
Preview rendered output - Always check how documentation will actually appear to users before committing changes.
Keep technical references current - When documenting code structures, ensure descriptions match the actual implementation. Update documentation when code interfaces change.
Following these practices ensures documentation is both technically accurate and genuinely helpful to other developers.
Error messages should be specific, descriptive, and include context to help with debugging. Avoid generic messages like “Failed execution” or numeric error codes without explanation.
Key principles:
ShapeList::push_back: ShapeList limit exceededExpected type FLOAT32, but got INT32Example with improved error messaging:
// Poor error message
if (size() <= idx || idx < 0)
throw std::runtime_error("Can't find requested variable by index");
// Better error message
if (size() <= idx || idx < 0)
throw std::runtime_error(
std::string("ShapeList::at: Index out of bounds, requested: ") +
std::to_string(idx) + " but size is: " + std::to_string(size())
);
For assertions in lower-level code that might be called from higher-level languages like Java, include descriptive messages that don’t require reading C++ code to understand the error condition.
Always use explicit null checks (value is None or value is not None) rather than implicit truthiness evaluations when testing for null/None values. Implicit boolean checks can invoke __bool__ methods leading to unexpected behavior.
Do this:
# Explicitly check if out is not None
if out is not None:
# Use out
process(out)
Not this:
# Don't rely on truthiness which may call __bool__
if out:
# May not behave as expected if __bool__ is implemented
process(out)
For complex types that can represent optional values, use proper optional type wrappers:
In C++:
// Use optional wrappers for nullable types
'float or None': 'dmlc::optional<float>' // Instead of just 'mx_float'
When handling values that might have multiple return types or be null:
# Check the specific type before processing
if isinstance(out, NDArrayBase):
return out
return list(out) # Convert if needed
Always handle null values explicitly and consistently throughout your codebase to prevent null pointer exceptions. Follow these guidelines:
// Use explicit null checks with informative messages
Preconditions.checkNotNull(input, "Input cannot be null");
Preconditions.checkArgument(shape != null && shape.length > 0, "Invalid shape: %s", shape);
/**
* Creates a buffer in the specified workspace.
* @param workspace Optional memory workspace to define the buffer in, may be null
* (buffer not created in workspace when null)
*/
public DataBuffer createBuffer(DataType dataType, long length, boolean initialize, MemoryWorkspace workspace) {
// Implementation
}
Handle nulls at the source rather than requiring downstream methods to handle them, preventing defensive null checks throughout the codebase.
// Instead of:
int numWords = (int) tokenizerConfig.get("num_words");
// Use:
Integer numWords = (Integer) tokenizerConfig.get("num_words");
@NonNull or @Nullable to clearly indicate intent and enable static analysis tools to catch potential null issues.Following these practices helps prevent null pointer exceptions and makes code more robust and maintainable.
Always provide complete and accurate documentation for all function parameters, especially when adding new ones. Each parameter should have a clear description that explains its purpose, expected values, and behavior.
When adding a new parameter to an existing function:
For example, when adding a parameter like failsafe:
/**
* \brief Allocation.
* \param handle Handle struct.
* \param failsafe Return a handle with a null dptr if out of memory, rather than exit.
*/
virtual void Alloc(Storage::Handle* handle, bool failsafe = false);
This helps other developers understand how to use the function correctly and makes the codebase more maintainable. Incomplete parameter documentation can lead to misuse of functions and introduces bugs that are difficult to diagnose.
When sharing mutable data between threads, use the Arc<RwLock<T>> pattern to ensure thread safety. Arc provides thread-safe reference counting for sharing ownership across thread boundaries, while RwLock enables controlled mutation of the shared data.
This pattern is particularly important when:
// Instead of this (not thread-safe for mutation):
let model = Arc::new(MyModel::new());
// Use this pattern for thread-safe mutation:
let model = Arc::new(RwLock::new(MyModel::new()));
// Reading from the shared resource:
let data = model.read().unwrap().get_data();
// Writing to the shared resource:
model.write().unwrap().update_data();
When working with RwLock, unwrap() is generally acceptable for lock acquisition failures as they indicate a thread panic (unrecoverable state), but consider proper error handling in production code where appropriate. Remember that RwLock allows multiple simultaneous readers but only one writer, optimizing for read-heavy workloads.
In AI model implementations, avoid using magic numbers directly in code as they reduce readability and make maintenance difficult. Always define constants with meaningful names, especially for values related to tensor dimensions, indices, and type identifiers.
For dimension limits:
// Instead of this:
if (shape.ndim() >= 1 && shape.ndim() <= 12) {
// Process shape
}
// Use this:
const int MAX_ONEDNN_DIMS = 12;
if (shape.ndim() >= 1 && shape.ndim() <= MAX_ONEDNN_DIMS) {
// Process shape
}
For array indices representing specific tensor components:
// Instead of this:
if (n->inputs[2].node->is_variable()) {
// Process bias
}
// Use this:
const int BIAS_INDEX = 2; // Or better, use enum or named constant
if (n->inputs[BIAS_INDEX].node->is_variable()) {
// Process bias
}
This practice makes code more maintainable as dimensions and tensor layouts evolve during AI model optimization efforts.
When working with graph structures, avoid performing redundant depth-first search (DFS) traversals as each traversal incurs an O(V+E) complexity cost. Instead, consider:
For example, instead of:
// Multiple independent DFS calls on the same graph structure
for (auto pattern : patterns) {
DFSVisit(sym.outputs, [&](const nnvm::ObjectPtr &node) {
if (node->is_variable()) return;
// Find nodes matching pattern
});
}
Consider:
// Single traversal with collected state
std::vector<nnvm::ObjectPtr> traversal_order;
std::unordered_map<nnvm::ObjectPtr, int> node_labels;
DFSVisit(sym.outputs, [&](const nnvm::ObjectPtr &node) {
if (node->is_variable()) return;
traversal_order.push_back(node);
// Label nodes as needed
});
// Now use cached traversal for pattern matching without repeating DFS
for (auto pattern : patterns) {
for (const auto& node : traversal_order) {
// Match against patterns
}
}
This approach significantly reduces computational complexity when multiple operations or pattern matching need to be performed on the same graph structure.
Prioritize code readability by using simpler and more direct expressions. When possible, return values directly instead of using temporary variables and explicit return statements. Break complex logic into intermediate variables with descriptive names. Structure control flow for maximum clarity, preferring Rust idioms like match expressions over nested conditionals.
Example 1 - direct returns:
// Instead of:
pub fn from_string(content: String) -> Result<Self> {
let tokenizer = serde_json::from_str(&content)?;
Ok(tokenizer)
}
// Prefer:
pub fn from_string(content: &str) -> Result<Self> {
serde_json::from_str(content)
}
Example 2 - match expressions:
// Instead of:
if direction != "right" && direction != "left" {
panic!("Invalid truncation direction value : {}", direction);
}
let tdir = if direction == "right" {
TruncateDirection::Right
} else {
TruncateDirection::Left
};
// Prefer:
let direction = match direction.as_str() {
"left" => Truncate::Left,
"right" => Truncate::Right,
other => panic!("Invalid truncation direction value : {}", other),
};
For complex code blocks, use intermediate variables with descriptive names to break down logic and make the code easier to follow. When implementing iterators or transformation functions, consider structuring them for readability even if it requires a few more lines of code.
Maintain consistent naming conventions throughout the codebase to enhance readability and reduce confusion. This applies to:
import numpy as onp # Official NumPy
from mxnet import np # MXNet NumPy
# Good
def matrix_transpose(x: ndarray, /) -> ndarray:
# implementation
# Avoid
def matrix_transpose(self: ndarray, /) -> ndarray:
# implementation
# Good
for key, value in data_shape.items():
# implementation
# Avoid
for obj in data_shape:
# implementation
Type annotations: Maintain a consistent style for type annotations throughout the codebase, with explicit type names for parameters and return values.
When dealing with values that may be absent or null, always use explicit optional type wrappers instead of implicit null checks or nullable types without clear type constraints. This makes the code’s intent clearer, prevents null reference errors, and improves type safety.
In Perl, use Maybe[Type] to clearly indicate a value could be absent:
has 'sum_metric' => (is => 'rw', isa => 'Maybe[Num|ArrayRef[Num]|PDL]');
In C++, use appropriate optional containers like dmlc::optional<T> (or std::optional<T> in C++17) when a parameter might not have a value:
dmlc::optional<bool> shifted_output; // Clearly indicates this boolean might not be set
Be explicit about which values can be null and provide appropriate methods to safely access or transform these values. When working with optional types, ensure consistent handling across the codebase rather than using ad-hoc null checks. This pattern helps catch null-related errors at compile time rather than runtime.
Carefully manage configuration file changes to ensure consistency and minimize unintended impacts across your project. When modifying configuration files:
1) Ensure compiler settings match runtime requirements - update targets to support required language features (like changing TypeScript target to “es2020” to support BigInt in Node.js 12)
2) Maintain consistent paths and settings across related configurations to prevent deployment issues
// Example: Consistent paths in build scripts
"scripts": {
"start": "ng serve --base-href /tensorboards/ --deploy-url /tensorboards/",
"build": "ng build --prod --base-href /tensorboards/ --deploy-url static/"
}
3) Isolate high-impact configuration changes (like dependency updates that affect package-lock.json) into separate PRs to maintain reviewability and minimize unintended side effects
When designing and modifying APIs, ensure consistency in parameter naming, default values, and which functionality is exposed. Each API design decision should:
For example, when adding new parameters like in the truncate method:
def truncate(self, max_length, stride=0, left=True):
"""Truncate the sequence(s) represented by this encoding
Args:
max_length: The maximum length to truncate to
stride: The length of the stride to use
left: Whether to truncate left (True) or right (False)
"""
# implementation
Ensure the parameter name (left) clearly indicates what True and False values will do, and consider whether the default value matches users’ expectations and existing behavior. Document any parameters that might have ambiguous interpretations to prevent confusion.
Make null/empty handling explicit and safe—so empty values don’t break logic or even generate invalid syntax, and raw null-pointer checks are replaced with semantic, invariant-based checks.
Guidelines: 1) Avoid “empty variable” syntax bugs (CMake): quote variables in comparisons.
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") (breaks if the variable expands to empty)elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")2) Prefer semantic checks over raw pointer null checks (C++ containers/tensors):
if (ptr != NULL) with if (!obj.empty()) or equivalent invariants when available.if (!_bias.empty()) { /* use bias */ } else { /* no bias */ }3) Don’t over-defend against null in operations that are already null-safe:
delete NULL; is safe—unnecessary if (ptr) delete ptr; can be removed for clarity.4) For null-terminated byte strings, ensure the correct terminator behavior:
len + 1 and whether you copy len+1).Applying these rules reduces crashes, undefined behavior, and correctness issues caused by missing/empty/null values.
Eliminate redundant calculations by identifying and caching frequently used values to improve performance. Consider these optimization patterns:
// After double abs_y = fabs(y); if (abs_y > 1.0) { … } // later if (abs_y < CENTRAL_RANGE) { … }
2. Move repeatedly calculated values to class attributes:
```cpp
// Before - calculating strides in multiple methods
void DNNLSplitFwd::Method1() {
std::vector<int> strides(ishape.ndim(), 1);
for (int i = ishape.ndim() - 2; i >= 0; --i) {
strides[i] = strides[i + 1] * ishape[i + 1];
}
// use strides...
}
// After - calculate once and store in class
class DNNLSplitFwd {
std::vector<int> strides; // Class member
void CalculateStrides() {
strides.resize(ishape.ndim(), 1);
for (int i = ishape.ndim() - 2; i >= 0; --i) {
strides[i] = strides[i + 1] * ishape[i + 1];
}
}
};
emplace_back over push_back to avoid creating temporary objects:
```cpp
// Before
matched_list.push_back(&n);// After matched_list.emplace_back(&n);
These optimizations can significantly improve performance in computationally intensive applications by reducing unnecessary calculations, memory operations, and object constructions.
---
## Avoid unsafe code
<!-- source: huggingface/tokenizers | topic: Security | language: Rust | updated: 2021-12-06 -->
Prioritize memory safety and security over performance optimizations by avoiding unsafe code blocks, especially in libraries. Even when bounds are checked, unsafe code can introduce subtle security vulnerabilities and maintenance challenges. Prefer using safe Rust patterns and abstractions, even if it means a slight performance overhead (like an additional clone operation).
Example:
```rust
// Avoid this approach
#[inline]
fn split_off_back<T>(vec: &mut Vec<T>, at: usize) -> Vec<T> {
assert!(vec.len() >= at);
let mut other = Vec::with_capacity(at);
let left_over_len = vec.len() - at;
let at_isize = at.try_into().unwrap();
unsafe {
// unsafe implementation
}
}
// Prefer this safer approach
#[inline]
fn split_off_back<T: Clone>(vec: &mut Vec<T>, at: usize) -> Vec<T> {
let other = vec[0..at].to_vec(); // Clone but safe
vec.rotate_left(at);
vec.truncate(vec.len() - at);
other
}
All public APIs must have comprehensive and clear documentation that helps developers understand functionality without examining implementation details. Follow these guidelines:
@Override
public void setValue(Number value) {
// No action needed - this method intentionally left empty as value is managed by parent condition
}
@Deprecated annotation@deprecated Javadoc tag explaining why and what to use instead{@link} references to replacements
```java
/**@see and {@link} references are accurate and helpful. For overloaded methods, clearly specify which signature is being referenced and explain default behavior.
```java
/**
public enum WeightsFormat {
/**
* Kernel height, kernel width, input channels, output channels [kH, kW, iC, oC]
*/
YXIO,
/**
* Output channels, input channels, kernel height, kernel width [oC, iC, kH, kW]
*/
OIYX
}
All environment variables must be documented in the central env_var.md file with clear descriptions of their purpose, acceptable values, and effects. Use consistent naming patterns that reflect the subsystem they configure (e.g., MXNET_CUDNN_, MXNET_MKLDNN_) and avoid introducing new variables when existing ones can serve the same purpose.
Example:
// Good - Uses consistent naming and is documented
// In code:
const bool brgemm_disabled = dmlc::GetEnv("MXNET_MKLDNN_DISABLE_BRGEMM_FC", true);
// In docs/static_site/src/pages/api/faq/env_var.md:
// MXNET_MKLDNN_DISABLE_BRGEMM_FC=[true|false] - Disable BRGEMM algorithm in fully connected layers when using MKLDNN backend. Default is true.
// Bad - Introduces new variable without documentation
static bool use_new_dep_engine = dmlc::GetEnv("MXNET_ASYNC_GPU_ENGINE", false);
// Instead, reuse existing variable:
// static bool use_new_dep_engine = (dmlc::GetEnv("MXNET_ENGINE_TYPE", "") == "AsyncGPU");
When adding new configuration options:
Structure unit tests using pytest’s parameterize decorator instead of manual loops or wrapper functions. This approach improves test readability, makes failure cases easier to identify, and allows individual test cases to be run separately.
When implementing tests with multiple inputs or configurations:
@pytest.mark.parametrize() decoratorsExample refactoring:
# Before - manual iteration
def test_operation():
test_cases = [
(5, 10, True),
(3, 7, False),
(0, 1, True)
]
for a, b, expected in test_cases:
result = operation(a, b)
assert result == expected
# After - pytest parameterization
@pytest.mark.parametrize('a,b,expected', [
(5, 10, True),
(3, 7, False),
(0, 1, True)
])
def test_operation(a, b, expected):
result = operation(a, b)
assert result == expected
This approach makes tests more maintainable, documents test cases more clearly, and provides better reporting when tests fail by clearly identifying which specific parameter combination caused the failure.
Avoid hardcoded paths and duplicated configuration values throughout the code. Instead:
source /opt/intel/oneapi/setvars.sh), prefer them over hardcoding pathsExample of problematic code:
# Hardcoded path that may not work across installations
export CPATH=/opt/arm/armpl_21.0_gcc-8.2/include_lp64_mp:$CPATH
# Duplicated test configuration
pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest
Better approach:
# Use environment detection or user configuration
if [[ -d "${ARM_PATH}" ]]; then
export CPATH=${ARM_PATH}/include_lp64_mp:$CPATH
fi
# Load configuration from a central file
source ./test_config.sh
pytest ${TEST_COMMON_ARGS} ${UNITTEST_ARGS} tests/python/unittest
This approach improves portability across different environments and makes maintenance easier when configurations need to change.
Ensure all API elements are thoroughly documented following a consistent format. This includes:
All function parameters must have descriptive documentation that explains their purpose, expected values, and default behaviors.
Follow established documentation formats for consistency across the codebase. Reference existing well-documented functions as templates.
Document relationships between APIs by clearly indicating when functions are aliases or standardized versions of other APIs, including appropriate references.
Include practical examples in documentation to demonstrate usage patterns.
Example of proper parameter documentation:
parser.add_argument('--batch_size', type=int, default=64,
help='Number of samples per training batch')
parser.add_argument('--learning_rate', type=float, default=0.001,
help='Initial learning rate for training')
Example of documenting API relationships:
atan = arctan
atan.__doc__ = """
Trigonometric inverse tangent, element-wise.
The inverse of tan, so that if ``y = tan(x)`` then ``x = atan(y)``.
Notes
---------
`atan` is a standard API in the Array API Standard
(https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan-x)
and is equivalent to `arctan`.
>>>np.atan is np.arctan
True
Parameters
----------
# parameter documentation follows...
"""
Always provide comprehensive API documentation that clearly specifies:
Parameter types - Document all acceptable parameter types, not just specific implementations. When a parameter accepts any object that satisfies certain behavior (like iterables), explicitly state this rather than referencing a specific class.
Function aliases - When implementing function aliases (like acos for arccos or pow for power), clearly document their relationship to the original function and explain why the alias exists.
Standards compliance - Reference any industry standards or specifications that the API follows, especially when they might differ from what users expect.
Example:
def process_data(data_source, options=None):
"""Process data from the provided source.
Parameters
----------
data_source : iterable object
Any iterable that yields data batches. This can be a DataLoader
instance, a list of arrays, or any custom iterable implementing
the required interface.
options : dict, optional
Processing options.
Notes
-----
This function follows the data processing standards specified in
https://example.org/standards/data-processing.
"""
Or when documenting aliases:
acos = arccos
acos.__doc__ = """
Trigonometric inverse cosine, element-wise.
Notes
----------
`acos` is an alias for `arccos`. It is a standard API in
https://data-apis.org/array-api/latest/ instead of an official NumPy
operator.
>>> np.acos is np.arccos
True
"""
Remove unnecessary coding patterns that add complexity without providing value. Focus on clarity and simplicity by:
for _, item in enumerate(collection): process(item)
for item in collection: process(item)
2. Using generator expressions instead of list comprehensions when creating iterables directly:
```python
# Instead of:
return tuple([x.astype(dtype) for x in args])
# Use:
return tuple(x.astype(dtype) for x in args)
if (upper == False): do_something()
if not upper: do_something()
These simplifications improve code readability and maintain a clean, Pythonic style that aligns with best practices.
---
## Optimize validation checks
<!-- source: deeplearning4j/deeplearning4j | topic: Performance Optimization | language: CUDA | updated: 2021-09-05 -->
When implementing validation and requirement checks, balance thoroughness with performance considerations. Critical validations should remain unconditional, but optimize their implementation to minimize performance impact:
1. Use short-circuit evaluation with logical operators (&&) to avoid unnecessary validations
2. Implement lazy evaluation for complex checks using lambdas
3. Consider conditionally enabling detailed error reporting in debug mode only
4. Pay special attention to validation code in performance-sensitive paths
```cpp
// Good practice - using short-circuit and lazy evaluation
Requirements req("CUDNN OPERATION");
req.expectIn(makeInfoVariable(dataType, TYPE_MSG), {ValidTypes}) &&
req.expectTrue([&]() {
// Complex validation only evaluated if previous check passes
return validateComplexCondition(input);
});
// Avoid unconditional evaluation of everything, especially in hot paths
// auto info = getDetailedInfo(input); // Always executed regardless of need
// if (!meetsRequirements(info)) return false;
This approach ensures your code remains robust with meaningful error reporting while minimizing performance overhead in production environments.
When implementing neural network models that will be hybridized for performance optimization, use operations that are compatible with symbolic execution to avoid runtime errors. Hybridization converts imperative code to symbolic for better inference performance, but requires special handling of certain operations.
Key practices:
Example of refactoring code for hybridization compatibility:
# NOT compatible with hybridization
def forward(self, x):
skip_connections = [...]
output = sum([s[:, :, -output.shape[2]:] for s in skip_connections])
return output
# Compatible with hybridization
def forward(self, x):
skip_connections = [...]
# Option 1: Use F.slice with calculated dimensions
slice_size = calculate_slice_size(...) # Calculate based on input size and model params
output = sum([F.slice(s, begin=(0, 0, -slice_size), end=(None, None, None))
for s in skip_connections])
return output
When implementing features like callbacks with hybridization, be aware of limitations with static shapes and mark experimental features appropriately in documentation.
When implementing concurrent operations, especially in heterogeneous computing environments (CPU/GPU), centralize synchronization management in dedicated components rather than using flags scattered throughout the codebase. This approach improves maintainability, reduces the potential for race conditions, and makes concurrency behavior more predictable.
For example, instead of using flags like:
struct RunContext {
// Other context data...
bool is_bulk; // Flag to indicate if synchronization is needed
};
// Usage in various places
if (!context.is_bulk) {
// Perform synchronization
}
Prefer a centralized approach where synchronization is managed by a specialized component:
struct RunContext {
// Other context data...
void *event_pool = nullptr; // Pointer to centralized event management
};
// Centralized synchronization management
void SynchronizeOperations(RunContext* ctx) {
// Handle all synchronization based on events from event_pool
}
This pattern is particularly important for CUDA operations where proper event ordering and stream synchronization are critical for correctness. Using centralized event pools and dependency tracking helps ensure operations complete in the correct order without unnecessary synchronization points.
When iterating through collections, choose the most efficient iteration pattern based on what information you actually need. If you only need the elements without using their indices, use direct iteration instead of enumerate:
# Instead of this (inefficient):
for _, item in enumerate(collection):
process(item)
# Do this (efficient and clearer):
for item in collection:
process(item)
This optimization removes unnecessary index variable allocation and makes the code more readable. The principle applies to any iterative algorithm - don’t compute values you won’t use. Similarly, when testing object capabilities (like whether an object is iterable), check for specific attributes (hasattr(obj, '__iter__')) rather than calling functions that might have side effects like prefetching data.
Maintain high-quality, consistent documentation as a critical component of API design. Documentation should feature:
Example:
# GOOD: Clear, consistent documentation with proper terminology
"""
Returns a uniform distribution array.
Parameters:
----------
low : float, optional
Lower boundary of the output interval. Default is 0.
high : float, optional
Upper boundary of the output interval. Default is 1.
size : tuple, optional
Output shape. Default is None.
"""
# BAD: Inconsistent terminology and grammatical errors
"""
Returns uniform distribution array.
Parameters:
----------
low : float, optional
lower boundary of output interval. Default is 0
high : float, optional
upper boundary of the output interval. Default is 1
shape : tuple, optional
Output size. Default is None.
"""
Consistent documentation reduces developer confusion and improves API adoption. It serves as the primary interface between your API and its users, making it as important as the implementation itself.
Always make file paths, temporary directories, and resource locations configurable with reasonable defaults instead of hard-coding them. Users may have specific environment requirements such as using SSDs instead of system drives or working with constrained environments like Spring Boot.
Implement a hierarchical approach to resource configuration:
For example, instead of:
File holder = File.createTempFile("FileChunksTracker", "Message");
Use a configurable approach:
// Define in a centralized properties class
public static final String FILE_STORAGE_DIR_PROPERTY = "org.nd4j.tempfiles.directory";
// Use in implementation
String tempDir = System.getProperty(FILE_STORAGE_DIR_PROPERTY, System.getProperty("java.io.tmpdir"));
File storageDir = new File(tempDir);
if (!storageDir.exists()) {
storageDir.mkdirs();
}
File holder = File.createTempFile("FileChunksTracker", "Message", storageDir);
This practice improves flexibility across different deployment environments and facilitates troubleshooting when resource loading issues occur.
Always validate input parameters and respond with appropriate HTTP status codes when invalid values are detected, even when inputs appear controlled by your frontend. Backend validation should explicitly check for invalid or unexpected values (like “NaN” or values outside an allowed set) and raise appropriate exceptions with clear error messages.
Example:
def set_server_type(notebook, body, defaults):
notebook_annotations = notebook["metadata"]["annotations"]
server_type = get_form_value(body, defaults, "serverType")
# Validate server type is one of the allowed values
allowed_types = ["jupyter", "rstudio", "vscode", None]
if server_type not in allowed_types:
raise werkzeug.exceptions.BadRequest(
f"Invalid server type: {server_type}. Must be one of: {allowed_types}")
notebook_annotations["notebooks.kubeflow.org/server-type"] = server_type
This practice ensures your API is robust against malformed inputs regardless of their source, provides clear error messages for debugging, and maintains a clean separation of concerns between frontend and backend validation.
All user-facing text in HTML templates should be marked for internationalization using the i18n directive. This includes labels, placeholders, error messages, and any other text displayed to users. Using the i18n directive ensures the text can be properly extracted for translation and maintains consistent internationalization throughout the application.
Example:
<!-- Incorrect -->
<mat-label>{{ 'common.name' | translate }}</mat-label>
<input matInput placeholder="{{ 'common.name' | translate }}" [formControl]="nameControl" />
<!-- Correct -->
<mat-label i18n>Name</mat-label>
<input matInput placeholder="Name" i18n-placeholder [formControl]="nameControl" />
Note that for attributes like placeholders, use the i18n-attribute syntax (e.g., i18n-placeholder) to mark them for translation.
When evolving APIs, prioritize backward compatibility to protect existing client code. Make new parameters optional whenever possible to allow existing code to continue functioning. If breaking changes are necessary, evaluate how users typically interact with your API before proceeding.
Example:
// Good: Adding a new parameter with a default value
val reduce = Mixin("reduce"){
Input(DataType.NUMERIC, "in") { description = "Input variable" }
// New parameter with default value maintains compatibility
Arg(DataType.BOOL, "keepDims", default = false) {
"Whether to keep original dimensions or produce a shrunk array"
}
Arg(DataType.INT, "dimensions") { /* ... */ }
}
// Consider impact: Breaking changes may be acceptable if most users
// are protected by higher-level abstractions (e.g., factory methods)
// rather than using these classes directly
Breaking changes may be acceptable when most users access functionality through higher-level abstractions (like factory methods) that can shield them from underlying implementation changes. Always document breaking changes clearly in release notes.
Add comprehensive documentation that helps others understand both the interface and implementation of your code. This includes:
Example of good parameter documentation:
def train(
files: List[str],
vocab_size: int = 8000,
show_progress: bool = True,
unk_token: Optional[str] = None,
):
"""
Train the model using the given files
Args:
files (:obj:`List[str]`):
A list of path to the files that we should use for training
vocab_size (:obj:`int`):
The size of the final vocabulary, including all tokens and alphabet.
show_progress (:obj:`bool`):
Whether to show progress bars while training.
unk_token (:obj:`str`, `optional`):
The unknown token to be used by the model.
"""
Example of good implementation comments:
class JiebaPreTokenizer:
def jieba_split(self, pretoken_index, pretoken):
new_tokens = []
# Convert to string to ensure compatibility with jieba tokenizer
pretoken_string = str(pretoken)
# Extract tokens using jieba's tokenize function which returns (word, start, end)
for token, start, stop in jieba.tokenize(pretoken_string):
new_tokens.append(pretoken[start:stop])
return new_tokens
def pre_tokenize(self, pretok):
# Split the PreTokenizedString using our custom jieba_split function
# which handles tokenization based on Chinese word boundaries
pretok.split(self.jieba_split)
Adopt these logging best practices to ensure consistent, efficient, and meaningful logs:
@Slf4j annotation instead of manually declaring loggers:// Avoid this:
private static final Logger log = LoggerFactory.getLogger(YourClass.class);
// Prefer this:
@Slf4j
public class YourClass {
// Logger field 'log' is automatically created
}
log.trace(): Very detailed information, typically only valuable when debugging specific issueslog.debug(): Development-time information like “Stringing exec…”, “exec done.”log.info(): Production-worthy information about application progresslog.warn(): Potential issues that don’t prevent operationlog.error(): Actual failures requiring attention// Avoid this:
try {
// code
} catch (Exception e) {
log.error("Operation failed.");
e.printStackTrace(); // Redundant and can go to a different output stream
}
// Prefer this:
try {
// code
} catch (Exception e) {
log.error("Operation failed.", e); // Includes stack trace automatically
}
Following these practices makes logs more consistent, easier to search, and more valuable for debugging.
Choose clear, self-descriptive names for all code identifiers that accurately reflect their purpose and behavior. Method names should be verbs or verb phrases that indicate their function without ambiguity. For boolean methods, use prefixes like “is”, “has”, or “should” followed by the condition they check.
When generating identifiers programmatically, use distinctive prefixes to avoid potential collisions with user-defined names. For example, prefer domain-specific prefixes like sd_var_ over generic ones like var_ to reduce collision risk.
// Avoid:
public final static boolean gilIsReleaseAutomatically() {} // awkward phrasing, hard to parse
private void parseSetupAndExecCode() {} // ambiguous, could mean "parse setup and execute code"
String varName = "var_" + _var_id.toString(); // too generic prefix
// Prefer:
public final static boolean releaseGilAutomatically() {} // direct and clear
private void parseSetupAndExecutionCode() {} // clearer alternative
// or better with JavaDoc explaining the purpose
/**
* Parses both the setup code and execution code sections from the configuration.
*/
private void parseCodeSections() {}
String varName = "sd_var_" + String.valueOf(_var_id); // domain-specific prefix
Meaningful naming reduces the need for comments, improves code readability, and makes the codebase more maintainable for all developers.
When implementing algorithms that need to execute efficiently across different platforms, consider both compile-time and runtime optimizations:
// Use CMake to generate explicit template instantiations
// in separate compilation units
#cmakedefine LIBND4J_TYPE_GEN
#include <ops/declarable/helpers/cpu/summaryReductions.hpp>
// Prefer explicit sized types rather than platform-dependent types
typedef int Nd4jInt; // For 32-bit integers
typedef long long Nd4jLong; // For 64-bit integers
// Instead of:
// if (rootSeed == 0)
// rootSeed = currentMilliseconds();
// Directly use the implementation:
if (rootSeed == 0){
auto s = std::chrono::system_clock::now().time_since_epoch();
rootSeed = std::chrono::duration_cast<std::chrono::milliseconds>(s).count();
}
template<typename Op, typename ...Args>
FORCEINLINE void callCudnnIfNoErr(cudnnStatus_t &err, Op op, Args&&... args) {
if(err==CUDNN_STATUS_SUCCESS) {
err = op(std::forward<Args>(args)...);
if(err) {
nd4j_printf("Cudnn error code %s\n", cudnnGetErrorString(err));
}
}
}
Always document platform-specific considerations directly in the code to help future developers understand your optimization decisions.
Always include explanations for implementation decisions, non-obvious constructs, and specialized functions directly within the code as comments, rather than relying on external systems like commit messages or GitHub discussions. This practice ensures that future developers can understand the code’s purpose and behavior without having to search through external documentation.
For example, when using specialized functions or constructs like in this case:
// This prepares data for GPU processing by synchronizing host memory to device memory
// and ensures proper buffer handling before computation
NDArray::prepareSpecialUse({ &output }, { &input });
// Implementation code...
// This synchronizes results back from device memory to host memory
NDArray::registerSpecialUse({ &output }, { &input });
Similarly, when implementing workarounds or choosing specific implementations:
// We default to our custom implementation here because cuDNN has precision issues
// with non-standard padding values and dilated convolutions
return goodType && (input->dataType() == gradO->dataType());
This approach makes code more maintainable and reduces onboarding time for new team members who may not have access to historical commit messages or discussions.
Favor modern JavaScript syntax and clean code practices to improve readability and maintainability. This includes:
/${namespace}/${notebook}, “_blank”);// Avoid window.open(“/” + namespace + “/” + notebook, “_blank”);
2. **Apply object destructuring** to reduce repetition and improve readability:
```javascript
// Preferred
const {contentDocument} = iframe;
contentDocument.addEventListener('click', handleEvent);
// Avoid
iframe.contentDocument.addEventListener('click', handleEvent);
// Avoid if (queryParams) { if (queryParams[“ns”]) { if (queryParams[“ns”] !== null) { // … } } }
4. **Remove unused code** including imports, commented-out code, and debug logging statements:
```javascript
// Remove before committing
console.log({own: (owned||[]).namespace, namespaces, ns: this.selected});
Maintaining these practices will lead to more consistent, readable, and maintainable code across the codebase.
Structure configuration scripts with modularity and adaptability in mind. Extract repeated parameters into variables, separate parameter construction from command execution, and use dynamic detection for environment-specific values instead of hardcoding them. This approach improves readability, maintainability, and resilience to changes in the environment.
Example:
# Instead of repeating parameters in each condition:
if [ "${HELPER}" != '' ] && [ "${EXTENSION}" != '' ]; then
command="mvn -Possrh -Djavacpp.platform.extension=-${HELPER}-${EXTENSION} ... -DskipTests"
elif [ "${HELPER}" != '' ]; then
command="mvn -Possrh -Djavacpp.platform.extension=-${HELPER} ... -DskipTests"
else
command="mvn -Possrh -Djavacpp.platform.extension=${EXTENSION} ... -DskipTests"
fi
# Prefer modular construction:
common_params="-Possrh -Dlibnd4j.buildThreads=${buildThreads} -Djavacpp.platform=linux-x86_64 -Dlibnd4j.chip=cuda --also-make -Pcuda clean --batch-mode package deploy -DskipTests"
if [ "${HELPER}" != '' ] && [ "${EXTENSION}" != '' ]; then
mvn_ext="-Djavacpp.platform.extension=-${HELPER}-${EXTENSION} -Dlibnd4j.helper=${HELPER} -Dlibnd4j.extension=${EXTENSION}"
elif [ "${HELPER}" != '' ]; then
mvn_ext="-Djavacpp.platform.extension=-${HELPER} -Dlibnd4j.helper=${HELPER}"
else
mvn_ext="-Djavacpp.platform.extension=${EXTENSION}"
fi
command="mvn ${common_params} ${mvn_ext}"
# Use dynamic version detection instead of hardcoding:
# Instead of: sudo cp /usr/lib/gcc/x86_64-linux-gnu/5.5.0/libgomp.so /usr/lib
gcc_version=$(gcc --version | head -n 1 | grep -o '[^ ]*$')
sudo cp /usr/lib/gcc/x86_64-linux-gnu/${gcc_version}/libgomp.so /usr/lib
When using Istio or other networking-related annotations in configuration files, always include detailed comments explaining their purpose, behavior, and effects. This makes networking constraints and logic transparent to developers and users who need to understand the system’s behavior.
For each networking annotation:
Example:
imageGroupOne:
# The annotation `notebooks.kubeflow.org/http-rewrite-uri: /`
# is applied to notebook in this group, configuring
# the Istio rewrite for containers that host their web UI at `/`
value: public.ecr.aws/j1r0q0g6/notebooks/notebook-servers/codeserver-python:master-1831e436
imageGroupTwo:
# The annotation `notebooks.kubeflow.org/http-rewrite-uri: /`
# is applied to notebook in this group, configuring
# the Istio rewrite for containers that host their web UI at `/`
# The annotation `notebooks.kubeflow.org/http-headers-request-set`
# is applied to notebook in this group, configuring Istio
# to add the `X-RStudio-Root-Path` header to requests
value: public.ecr.aws/j1r0q0g6/notebooks/notebook-servers/rstudio:master-1831e436
This practice ensures that network routing behaviors are explicit, making the system more maintainable and reducing confusion when debugging networking issues.
When collecting performance numbers, ensure both (1) benchmark parameters match the target hardware and (2) the execution environment is stable/isolated—otherwise results can be misleading.
Apply this:
Example (command-line style):
./benchncnn <loop> 1 ... or ./benchncnn <loop> 8 ... for an 8-core CPU, rather than a larger thread count.When designing components that require configuration, follow these practices to enhance performance, maintainability, and usability:
// Avoid: Loading in reconcile loop func (r *MyController) Reconcile() { // Don’t do this - performance issue config, _ := loadConfigFromFile(configPath) // … }
2. **Use standard formats** (YAML/JSON) with established libraries instead of creating custom parsers:
```go
// Good: Use standard libraries
import "github.com/go-yaml/yaml"
func loadConfig(file string) (Config, error) {
var config Config
data, err := os.ReadFile(file)
if err != nil {
return config, err
}
return config, yaml.Unmarshal(data, &config)
}
// Avoid: Custom parsing logic
func parseConfig(file string) {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// Custom parsing logic is harder to maintain
}
}
func main() { flag.Parse() config, err := loadConfig(*configPath) // … }
4. **Set sensible defaults** for configuration values but provide clear ways to override them through explicit configuration.
These practices help avoid reinventing parsing logic, improve performance by reducing unnecessary I/O operations, and make your components more configurable across different environments.
---
## Standardize build configurations
<!-- source: kubeflow/kubeflow | topic: CI/CD | language: Markdown | updated: 2021-03-17 -->
All components should use consistent build configurations and patterns in their CI/CD setup. This includes standardizing Makefile variables, build commands, and docker build processes across repositories. Inconsistent build configurations make CI/CD pipelines difficult to maintain and can lead to confusion during development.
For example, use consistent variable naming across Makefiles:
```bash
# Use consistent variable names like REGISTRY_PROJECT
REGISTRY_PROJECT=my-repo make docker-build
Instead of having different variable names for the same concept in different components as noted in the discussion: “Tensorboard’s makefile uses slightly different vars but we should iron them out and have the same template”
This standardization simplifies CI/CD pipeline maintenance, improves developer experience when working across components, and ensures that all artifacts follow the same build and testing patterns. It also makes it clearer which components are part of the official CI/CD pipeline and which are provided as examples only.
Avoid inline styles and !important declarations in your HTML templates. Instead, define and use CSS classes that encapsulate styling needs. This improves code maintainability, readability, and reduces CSS specificity issues.
Bad example:
<mat-icon style="height:72px !important; width:200px !important;" svgIcon="jupyterlab"></mat-icon>
Good example:
<!-- In your HTML -->
<mat-icon class="server-type" svgIcon="jupyterlab"></mat-icon>
<!-- In your CSS -->
.server-type {
height: 32px;
width: 150px;
}
.server-type-wrapper {
margin-bottom: 1rem;
}
This approach makes your styles more maintainable, easier to debug, and allows for better responsiveness. CSS classes can be reused across components and modified centrally rather than hunting through templates for inline styles.
When designing APIs, adhere to established API conventions, particularly Kubernetes API conventions when working within the Kubernetes ecosystem. This improves API clarity, maintainability, and future compatibility.
Key practices:
// Instead of custom string parsing:
requestHeaders := strings.Split(annotations["notebooks.kubeflow.org/http-headers-request-set"], "\n")
// Prefer using standard JSON:
var requestHeaders map[string]string
if err := json.Unmarshal([]byte(annotations["notebooks.kubeflow.org/http-headers-request-set"]), &requestHeaders); err != nil {
// Handle error
}
// Instead of embedding the entire ObjectMeta:
type PodDefaultSpec struct {
// ObjectMeta defines the metadata to inject into the pod
metav1.ObjectMeta `json:"metadata,omitempty"`
}
// Be specific about which fields you need:
type PodDefaultSpec struct {
// Labels to inject into pod metadata
Labels map[string]string `json:"labels,omitempty"`
// Annotations to inject into pod metadata
Annotations map[string]string `json:"annotations,omitempty"`
}
// Instead of enum-style status:
type ProfileState string
// Use standard Kubernetes condition pattern:
type ProfileCondition struct {
Type string `json:"type"`
Status v1.ConditionStatus `json:"status"`
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
Reason string `json:"reason,omitempty"`
Message string `json:"message,omitempty"`
}
Following these conventions enhances API clarity, avoids reinventing the wheel, and ensures your APIs evolve gracefully as requirements change.
When defining CI/CD workflows, always ensure task/step names are unique to prevent execution failures. Workflow engines like Argo will reject pipelines with duplicate step names, which becomes particularly important when:
To ensure uniqueness, append identifiers like random strings, build numbers, or artifact identifiers to your step names.
Example:
# Import required libraries
import random
import string
# Define character set for random string generation
alphabet = string.ascii_lowercase + string.digits
# Create unique step name by appending a random string
task["name"] = "base-task-name-" + ''.join(random.choices(alphabet, k=8))
This approach ensures each workflow step has a unique identifier while maintaining readability with a consistent prefix, allowing for reliable execution and easier debugging of CI/CD pipelines.
When allowing user-configurable HTTP headers in your application, implement strict validation to prevent security bypasses. Users should never be allowed to override security-critical headers that could compromise authentication or authorization mechanisms.
Use a whitelist approach for maximum security:
// Example: Whitelist approach for header validation
if _, ok := annotations["app.kubeflow.org/http-headers-request-set"]; ok {
requestHeaders := strings.Split(annotations["app.kubeflow.org/http-headers-request-set"], "\n")
for _, kv := range requestHeaders {
if len(strings.Split(kv, ": ")) == 2 {
k := strings.Split(kv, ": ")[0]
v := strings.Split(kv, ": ")[1]
// Only allow non-standard headers with X- prefix
if strings.HasPrefix(k, "X-") {
// Further validate against sensitive headers
if !isRestrictedHeader(k) {
headers["request"].(map[string]interface{})["set"].(map[string]interface{})[k] = v
}
}
}
}
}
This prevents attackers from overriding critical headers like authentication tokens (e.g., userid-header), protocol information (e.g., X-Forwarded-Proto), or other security mechanisms. For applications with specific header requirements, maintain a carefully curated whitelist rather than allowing arbitrary header manipulation.
When implementing machine learning algorithms, ensure numerical correctness and stability by following these practices:
// Instead of this
public static final double DEFAULT_EPSILON = 1e-8;
// Use this
public static final double DEFAULT_EPSILON = 1e-14; // Follows paper recommendation
// Add checks like this for masking probabilities
Preconditions.checkArgument(maskProb > 0 && maskProb < 1,
"Probability must be between 0 and 1, got %s", maskProb);
Preconditions.checkArgument(maskTokenProb + randomTokenProb <= 1.0,
"Sum of probabilities must be <= 1, got %s", maskTokenProb + randomTokenProb);
// When performing normalization or similar operations
SDVariable scale = SD.math.sqrt(squaredNorm.plus(1e-5)); // Prevents underflow
// Instead of this
return sd.math.abs(labels.sub(sd.getVariable("out"))).mean(1);
// Use this
return sd.math.abs(labels.sub(layerInput)).mean(1);
These practices help prevent subtle numerical bugs that can affect model convergence, training stability, and inference quality. They’re especially important in deep learning where calculations involve many operations that could compound numerical errors.
Use appropriate separators in compound identifiers to improve readability and ensure naming consistency across the codebase. Specifically:
wg-deployment, feature-namewgdeployment, featurenamev1.0, v2.30.Y, 1.0 (without v prefix)This practice makes identifiers more readable, maintains consistency with standard conventions, and helps ensure references remain valid over time as the codebase evolves. Consistent naming patterns reduce the need for future refactoring and make documentation more predictable and easier to navigate.
Make security features configurable through environment variables or configuration files, but always implement secure defaults. This allows teams to adapt security controls to their specific deployment environments while maintaining a secure baseline.
When implementing configurable security features:
Example from CSRF implementation:
# Read SameSite configuration from environment with secure default
samesite = os.environ.get("CSRF_SAMESITE", "Strict")
# Validate the input to ensure only secure options are accepted
if samesite not in ["Strict", "Lax", "None"]:
samesite = "Strict" # Fallback to secure default
# Apply the configuration to the cookie
response.set_cookie(
"CSRF_COOKIE",
csrf_token,
httponly=True,
secure=True,
samesite=samesite
)
Document this configuration in your README:
## Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| CSRF_SAMESITE | SameSite attribute for CSRF cookies (Strict, Lax, None) | Strict |
This approach balances security with flexibility, allowing secure operation in various environments while maintaining strong defaults.
When parsing untrusted files (e.g., images), do not choose decode/encode logic based on filename suffix/substring (e.g., “.pgm/.ppm/.jpg”). Instead, detect the actual format using file content (magic bytes/header) and only proceed if it matches supported signatures; otherwise fail safely.
Why: filename-based routing is trivially bypassed/ambiguous (e.g., “lena.jpg.png”); it can send data down the wrong parser path.
Apply it like this (minimal pattern):
// Read first bytes, then decide format by magic/header.
// Do not rely on path.find(...) or last-N extension checks.
enum class ImgFmt { PGM, PPM, JPG, Unknown };
ImgFmt sniff_fmt(FILE* fp) {
unsigned char b[8] = {0};
size_t n = fread(b, 1, sizeof(b), fp);
fseek(fp, 0, SEEK_SET);
// PGM/PPM: start with ASCII 'P' then '5' (binary PGM) or '6' (binary PPM)
if (n >= 2 && b[0] == 'P' && (b[1] == '5' || b[1] == '6'))
return b[1] == '5' ? ImgFmt::PGM : ImgFmt::PPM;
// Example JPG SOI
if (n >= 2 && b[0] == 0xFF && b[1] == 0xD8)
return ImgFmt::JPG;
return ImgFmt::Unknown;
}
cv::Mat imread_secure(const std::string& path) {
FILE* fp = fopen(path.c_str(), "rb");
if (!fp) return cv::Mat();
ImgFmt fmt = sniff_fmt(fp);
if (fmt == ImgFmt::Unknown) { fclose(fp); return cv::Mat(); }
// Decode based on fmt (not on filename suffix), with strict size/bounds checks.
// ...
fclose(fp);
return cv::Mat();
}
Team standard:
Design APIs that follow Python language conventions and idioms rather than blindly mirroring the underlying implementation language. Consider what would feel most natural to Python developers in terms of parameter ordering, default values, and call patterns.
Key principles:
Example:
# Instead of exposing complex implementation details:
def initialize(
vocab: Optional[Union[str, Dict[str, int]]] = None,
merges: Optional[Union[str, Dict[Tuple[int, int], Tuple[int, int]]]] = None,
)
# Provide a more Pythonic interface:
def initialize(
files,
vocab_size=30000,
min_frequency=2,
special_tokens=None
)
When adapting APIs from other languages, prioritize what makes sense for Python users rather than strictly adhering to the source language patterns. This improves usability while reducing the learning curve for your library.
When working with AI frameworks and machine learning libraries, clearly document the stability state of APIs being used. For experimental or evolving features:
For example, when documenting a feature with known limitations:
// EXPERIMENTAL: Boolean operators (&&, ||) are not differentiable in v0.11
// Use these alternative functions until the next release:
extension Bool {
public static func and(_ a: Bool, _ b: Bool) -> Bool {
if a {
if b {
return true
}
}
return false
}
// Usage: if Bool.and(condition1, condition2) instead of if condition1 && condition2
}
// TODO: Remove when upgrading to Swift release with apple/swift/pull/33511
This approach helps users understand current limitations, provides immediate solutions, and establishes clear upgrade paths when the framework evolves.
Select data structures based on their algorithmic complexity and usage patterns. Consider the tradeoffs between different structures (e.g., Vec vs HashMap) and their impact on performance. Key considerations:
Example:
// Suboptimal: Using HashMap when order matters
let mut pieces: HashMap<String, f64> = HashMap::new();
// Better: Using Vec with HashSet for uniqueness
let mut pieces: Vec<(String, f64)> = vec![];
let mut inserted: HashSet<String> = HashSet::new();
// Best: Single pass implementation for pattern matching
let mut prev = 0;
let mut splits = Vec::with_capacity(inside.len());
for m in self.find_iter(inside) {
if prev != m.start() {
splits.push(((prev, m.start()), false));
}
splits.push(((m.start(), m.end()), true));
prev = m.end();
}
Choose names for variables, methods, parameters, and fixtures that clearly communicate their purpose, content, and behavior. Names should be self-documenting and consider future code evolution.
For method names:
enable_xxx()/disable_xxx() over ambiguous patterns like with_xxx()/without_xxx()# Less clear:
def with_padding(self, direction="right", ...):
# ...
# More clear:
def enable_padding(self, direction="right", ...):
# ...
For variables and parameters:
# Less descriptive - unclear what these files contain:
@pytest.fixture(scope="session")
def precompiled_files(data_dir):
# ...
# More descriptive - clearly indicates purpose and content:
@pytest.fixture(scope="session")
def serialized_files(data_dir):
# ...
Maintain consistency in parameter naming across similar implementations to establish predictable patterns for API users.
When writing code, favor readability and maintainability over clever or compact solutions. Break down complex logic into smaller, well-named functions with clear purposes rather than embedding all logic in a single function.
Follow these specific practices:
def patch_notebook(namespace, notebook): # … some code … if STOP_ATTR in request_body: # Many lines of complex start/stop logic here # … more code …
def patch_notebook(namespace, notebook): # … some code … if STOP_ATTR in request_body: start_stop_notebook(namespace, notebook, request_body) # … more code …
def start_stop_notebook(namespace, notebook, request_body): # Start/stop logic extracted here
2. Avoid complex one-liners that span multiple lines. Instead of:
```python
resp = requests.request("GET", url, verify=False) if use_basic_auth else requests.request("GET", url, headers={"Authorization": "Bearer {}".format(token)}, verify=False)
Prefer:
if use_basic_auth:
resp = requests.request("GET", url, verify=False)
else:
resp = requests.request(
"GET",
url,
headers={"Authorization": "Bearer {}".format(token)},
verify=False
)
@bp.route(“/api/namespaces/
@bp.route(
“/api/namespaces/
This approach makes code easier to read, maintain, and debug, improving the overall quality of the codebase.
---
## Document code thoroughly
<!-- source: kubeflow/kubeflow | topic: Documentation | language: Go | updated: 2020-09-21 -->
Always include appropriate documentation in your code to improve readability, maintainability, and usability:
1. **Document all public APIs** with Go doc comments:
```go
// MetricsExporter provides functionality for exporting metrics to Prometheus
// and managing metrics collection within the application.
type MetricsExporter struct {
// fields...
}
// IncRequestCounter increments the request counter for the specified kind.
// It tracks API usage patterns for monitoring purposes.
func IncRequestCounter(kind string) {
// implementation...
}
// Update the CR status based on the ContainerState of the container
// that has the same name as the CR
if len(pod.Status.ContainerStatuses) > 0 {
// implementation...
}
// TODO(user): This endpoint is temporarily disabled until issue #123 is resolved
// which addresses the race condition in the deployment creation process.
//
//// GetLatestKfdef returns latest kfdef status.
Following these practices ensures code is understandable to new team members, facilitates easier maintenance, and helps API consumers use your code correctly. Run tools like go vet ./... regularly to catch missing documentation on public elements.
Present concepts through clear, focused examples that demonstrate features positively rather than through comparisons or criticisms of alternative approaches. Allow readers to discover benefits through well-constructed examples rather than explicit statements about superiority.
For instance, instead of:
// OOP approaches have limitations because subclassing creates rigid hierarchies
Use an illustrative example:
// Here's how protocols allow for flexible composition
protocol Drawable {
func draw()
}
struct Circle: Drawable {
func draw() { /* implementation */ }
}
struct Square: Drawable {
func draw() { /* implementation */ }
}
// Any type conforming to Drawable can be used here
func renderShapes(_ shapes: [Drawable]) {
for shape in shapes {
shape.draw()
}
}
Keep examples simple and directly tied to the concept being taught. Complex examples with multiple concepts can confuse readers and obscure the main learning objective. When possible, make examples interactive so readers can experiment with the code and reach their own conclusions about its benefits.
When a generated API surface (e.g., an enum/type-id) is derived from the order of a registration list, treat that order as part of the public/binary API. Never reorder, insert in the middle, or remove/disable entries in that list—add new items only by appending at the end.
Example (stable pattern):
# Stable ordered list; do not reorder existing entries.
ncnn_add_layer(Reshape)
ncnn_add_layer(ROIPooling)
ncnn_add_layer(Scale)
ncnn_add_layer(Sigmoid)
# New layers must be appended only:
ncnn_add_layer(HardSigmoid)
If a change must affect indices (e.g., removing an entry), require an explicit compatibility decision and versioning plan before merging, because it will break existing binaries/serialized models that depend on the numeric ids.
In build/configuration files (e.g., CMakeLists), keep statements organized so that they are (1) scoped to the conditions that actually enable the associated sources/targets, and (2) ordered deterministically (e.g., alphabetical for registration lists).
Apply scope correctly
if(WITH_...) block.Keep registrations sorted
Example (CMake)
macro(ncnn_add_layer class)
foreach(name IN LISTS ${class})
if(WITH_LAYER_${name})
if(WITH_LAYER_${name}_${arch})
# sources only for enabled arch
source_group("sources\\layers" FILES
"${CMAKE_CURRENT_SOURCE_DIR}/layer/${name}.cpp")
source_group("sources\\layers\\${arch}" FILES
"${CMAKE_CURRENT_SOURCE_DIR}/layer/${arch}/${name}_${arch}.cpp")
if(WITH_LAYER_${name}_vulkan)
# sources only for enabled Vulkan
source_group("sources\\layers\\vulkan" FILES
"${CMAKE_CURRENT_SOURCE_DIR}/layer/vulkan/${name}_vulkan.cpp")
endif()
endif()
endif()
endforeach()
endmacro()
# Tests: keep calls alphabetically
ncnn_add_layer_test(AbsVal)
ncnn_add_layer_test(ReLU)
This improves readability (future editors can see what is guarded by what) and produces cleaner, more predictable diffs.
Always validate that URLs use the HTTPS protocol in both implementation code and validation error messages. Even if your application might handle HTTP-to-HTTPS redirects, enforce HTTPS from the outset as a security best practice to prevent man-in-the-middle attacks and data exposure.
Example:
// Incorrect - allows HTTP
if (!/^https?:\/\/\S+/.test(url)) {
console.log('Invalid URL provided, must be like http*://*');
return false;
}
// Correct - enforces HTTPS only
if (!/^https:\/\/\S+/.test(url)) {
console.log('Invalid URL provided, must use HTTPS protocol');
return false;
}
This helps ensure all communications are encrypted and prevents security vulnerabilities that can arise from initial insecure connections.
Avoid creating unnecessary temporary objects or arrays which can impact performance through increased garbage collection and memory pressure. Apply these techniques to optimize memory usage:
// Inefficient: Creates a temporary array
INDArray ret = Nd4j.valueArrayOf(new long[] {1, nOut}, gainInit);
gainParamView.assign(ret);
// Efficient: Direct assignment
gainParamView.assign(gainInit);
// Inefficient: Creating larger array then extracting subset
SDVariable b = SD.zerosLike(uHat).get(SDIndex.all(), SDIndex.all(), SDIndex.all(),
SDIndex.interval(0, 1), SDIndex.interval(0, 1));
// Efficient: Create array with exact needed dimensions
SDVariable b = SD.zeros(-1, inputCapsules, capsules, 1, 1);
// Inefficient: New Pattern object per instance
private final Pattern splitPattern = Pattern.compile("...");
// Efficient: Shared across all instances
private static final Pattern SPLIT_PATTERN = Pattern.compile("...");
// Inefficient: Always creates String objects
Preconditions.checkArgument(condition, "Labels array size " + labelSize + " does not match " + outputSize);
// Efficient: Only formats if exception is thrown
Preconditions.checkArgument(condition, "Labels array size %s does not match %s", labelSize, outputSize);
Implementing these practices consistently will reduce memory churn, decrease garbage collection pauses, and improve application performance, especially in memory-intensive operations.
Always provide meaningful context when handling errors, and classify them appropriately based on their source. This improves debugging, helps users understand issues, and creates a consistent approach to error handling across the codebase.
Follow these error handling principles:
if err != nil {
// Log error and/or return response
return nil, fmt.Errorf("failed to process request: %v", err)
}
// Handle the success case
// Instead of just returning or logging the raw error
if _, err := w.Write([]byte(err.Error())); err != nil {
log.Error(err) // Poor context
// Better approach with context
log.Error(fmt.Errorf("failed to write error response: %v", err))
}
err := json.NewDecoder(r.Body).Decode(&profile)
if err != nil {
// Handle first error
if writeErr := json.NewEncoder(w).Encode(err); writeErr != nil {
log.Error(fmt.Errorf("decode failed: %v, response write failed: %v", err, writeErr))
}
return
}
// For system/internal errors return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf(“Failed to create application: %v”, err), }
5. **Use consistent error types** throughout your codebase, and consider creating helper functions to reduce boilerplate:
```go
func NewInvalidArgumentError(err error, msg string) *kfapis.KfError {
return &kfapis.KfError{
Code: int(kfapis.INVALID_ARGUMENT),
Message: fmt.Sprintf("%s: %v", msg, err),
}
}
When using locks or other synchronization mechanisms in concurrent code, always release locks in a finally block to ensure they are released even when exceptions occur. Failure to do so can lead to deadlocks if other threads need the same lock.
Additionally, choose the appropriate concurrency primitive for your specific use case. Using the wrong tool (like a Semaphore when a CountDownLatch is more appropriate) can lead to subtle bugs that are difficult to diagnose.
Bad example:
public void updateModel(@NonNull Model model) {
modelLock.writeLock().lock();
// If an exception occurs here, lock is never released!
// Do work with the model...
modelLock.writeLock().unlock();
}
Good example:
public void updateModel(@NonNull Model model) {
modelLock.writeLock().lock();
try {
// Do work with the model...
} finally {
modelLock.writeLock().unlock();
}
}
For wait/notify patterns, consider whether a CountDownLatch or other higher-level concurrency primitive would be more appropriate than using raw locks or semaphores:
// Instead of this:
private Semaphore semaphore = new Semaphore(0);
public void update(Observable o, Object arg) {
semaphore.release(Integer.MAX_VALUE); // Potential overflow!
}
// Consider this:
private CountDownLatch latch = new CountDownLatch(1);
public void update(Observable o, Object arg) {
latch.countDown(); // Safe, can only transition once
}
public void waitTillDone() throws InterruptedException {
latch.await(); // Properly propagate interruption
}
Code should be formatted to optimize readability. Apply these key practices:
// Instead of:
func getMedianExecutionTime(iterationCount: UInt = 10, _ verbose:Bool = false, _ function: () -> ()) -> Double {
// Use:
func getMedianExecutionTime(
iterationCount: UInt = 10, _ verbose:Bool = false, _ function: () -> ()
) -> Double {
// Instead of:
array.sorted(by: { s1, s2 in return s1 > s2 })
// You can write:
array.sorted { s1, s2 in return s1 > s2 }
let quotation = """
This text will have leading whitespace aligned
with the closing triple quotes.
"""
These formatting practices improve code readability, reduce cognitive load, and make the codebase more maintainable.
When implementing mathematical algorithms, ensure precise terminology and correct implementation of mathematical concepts. This is especially important for complex domains like differentiation, optimization, or numerical methods.
Three key practices to follow:
Use mathematically accurate terminology in documentation Descriptions should precisely match mathematical definitions. For example, when documenting differentiation:
// INCORRECT:
// Speaking in terms of elementary calculus, only functions that have derivatives can be differentiated.
// CORRECT:
// Speaking in terms of elementary calculus, only functions are "differentiable": only functions can *have derivatives* and can *be differentiated*.
Be explicit about algorithm limitations and edge cases Clearly state when algorithms might fail or have special requirements:
// GOOD EXPLANATION:
// Differentiation can fail for several reasons:
// * The function contains computation that cannot be differentiated
// * The function is opaque (a function parameter with a non-@differentiable type)
Ensure mathematical correctness in example code Example implementations must correctly implement the mathematical operations they demonstrate:
// INCORRECT pullback implementation (missing parameter):
@differentiating(sillyExp)
func sillyDerivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
let y = sillyExp(x)
return (value: y, pullback: { _ in y }) // Incorrect: ignores parameter
}
// CORRECT implementation:
@differentiating(sillyExp)
func sillyDerivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
let y = sillyExp(x)
return (value: y, pullback: { v in v * y }) // Correct: uses parameter
}
Following these practices ensures that algorithms are implemented correctly and are properly documented, making them more maintainable and less prone to subtle errors that can emerge when mathematical concepts are imprecisely translated to code.
Always ensure configuration values are managed consistently and sourced from stable locations.
Example:
// ❌ Poor configuration management
enum ConfigPath {
V05 = 'v0.5-branch/config/kfctl_config.yaml',
V06 = 'master/bootstrap/config/kfctl_gcp_iap.yaml' // Unstable source
}
const versionList = ['v0.7.0', 'v0.6.0']; // Hard-coded literals
// ✅ Better configuration management
enum Version {
V05 = 'v0.5.0',
V06 = 'v0.6.0',
V07 = 'v0.7.0'
}
enum ConfigPath {
V05 = 'v0.5-branch/config/kfctl_config.yaml',
V06 = 'v0.6-branch/config/kfctl_gcp_iap.0.6.yaml' // Stable source
}
// Use constants and document environment-specific values
const versionList = [
Version.V07, // For local testing, will be overwritten by env vars
Version.V06
];
When developing AI libraries and tools, provide comprehensive and accurate API documentation that helps users navigate complex functionality. Documentation should:
// BETTER documentation: // Finding outputs: Use sd.summary() to examine the graph structure // The outputs() method will be deprecated as it’s not robust enough sd.summary(); // Examine to find outputs (variables that are inputs to no ops) ```
// For multiple outputs: Map<String,INDArray> results = sd.batchOutput() .input(inputs, inputArray) .output(outputs) .exec(); ```
Structure documentation with common use cases first, followed by advanced topics, making it easy for users to find the information most relevant to their needs.
Always use correct and consistent capitalization for product names, class names, and method names throughout code and documentation. Pay special attention to:
SameDiff (not samediff or Samediff)TensorFlow (not Tensorflow)SameDiff.importFrozenTF (maintaining correct capitalization patterns)Consistent capitalization improves readability, searchability, and aligns with official naming conventions. When documenting naming behaviors, also be precise about how names are generated when not explicitly provided.
Example:
// Incorrect
SDVariable result = samediff.var("myVar", Nd4j.create(shape));
samediff.importFrozenTF(modelPath);
// Correct
SDVariable result = sameDiff.var("myVar", Nd4j.create(shape));
sameDiff.importFrozenTF(modelPath);
In documentation, maintain the same capitalization standards and be explicit about naming patterns, including when names are auto-generated based on operation names.
Create separate test functions for distinct functionality to improve test clarity and make failure points more obvious. When writing tests, avoid combining multiple scenarios into a single test function.
Instead of adding platform-specific tests to an existing function:
def test_kf_is_ready(namespace, use_basic_auth, use_istio, app_path):
# General Kubeflow tests
util.wait_for_deployment(api_client, namespace, deployment_name)
# Platform-specific tests (problematic)
if platform == "gcp":
# GCP-specific tests...
Create separate test functions:
def test_kf_is_ready(namespace, use_basic_auth, use_istio, app_path):
# General Kubeflow tests only
util.wait_for_deployment(api_client, namespace, deployment_name)
def test_workload_identity():
# Skip if not on GCP
if platform != "gcp":
pytest.skip("Workload identity test only runs on GCP")
# GCP-specific tests...
This organization makes it immediately clear which specific feature is failing when tests don’t pass, simplifies debugging, and enables more effective test filtering when running targeted test suites.
Ensure code follows established Swift naming conventions and remains consistent with domain terminology:
named: instead of called:):
```swift
// Incorrect
func expectOne// Correct
func expectOne
2. Organize functions as methods on relevant types when appropriate:
```swift
// Less idiomatic
public func operandNames(for inst: Instruction) -> [String]? { ... }
// More idiomatic
extension Instruction {
public var operandNames: [String]? { ... }
}
Use domain-specific terminology consistently (e.g., “operand names” not “registers” in SIL context)
Avoid redundancy in type names, especially in enum cases: ```swift // Redundant public indirect enum Type { case addressType(_ type: Type) }
// Concise public indirect enum Type { case address(Type) }
5. Maintain consistency with existing codebase conventions (e.g., using `inst` instead of `instr` for variables if that's the established pattern)
---
## Optimize hardware acceleration
<!-- source: deeplearning4j/deeplearning4j | topic: AI | language: Xml | updated: 2019-09-11 -->
AI systems should use the most performant hardware acceleration libraries and carefully manage hardware-specific dependencies. Prefer Intel MKL over OpenBLAS for CPU operations as it provides superior performance for matrix calculations critical to neural networks and machine learning algorithms. Keep CPU and GPU dependencies cleanly separated to support different deployment scenarios.
Example:
```xml
<!-- Preferred: Use full MKL instead of OpenBLAS or MKL-DNN -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>mkl</artifactId>
<version>${mkl.javacpp.version}</version>
<classifier>${dependency.platform}</classifier>
</dependency>
<!-- Avoid adding CPU-specific dependencies to modules that need GPU-only builds -->
<!-- Even test-scoped native dependencies can break CUDA-only CI builds -->
This approach ensures optimal performance for AI model training and inference while maintaining compatibility across different hardware configurations.
Follow Swift’s naming conventions to write more readable, maintainable code. The Swift language emphasizes clarity and expressiveness in naming:
Avoid get prefixes in function and method names. In Swift, properties and zero-argument methods serve this purpose without the prefix.
// Avoid:
func getTimeString(_ nanoseconds: Double) -> String { ... }
// Prefer:
func timeDescription(_ nanoseconds: Double) -> String { ... }
Name functions according to their purpose, not their return type. The return type is already declared in the function signature.
// Avoid:
func colorString() -> String { ... }
// Prefer:
func description() -> String { ... }
Use Swift’s shorthand type notation for collections rather than the generic form.
// Avoid:
var timings: Array<Double> = [0.0]
// Prefer:
var timings: [Double] = [0.0]
Leverage abbreviated dot syntax when the type context is already known.
var rank: Rank = .queen // Instead of Rank.queen
These conventions align with the Swift API Design Guidelines and help create a consistent codebase that other Swift developers can easily understand.
When implementing generic algorithms in Swift, follow these best practices to improve code clarity and performance:
// Not recommended
protocol SortingAlgorithm where Element: Comparable {
associatedtype Element
mutating func sort(_ array: inout [Element])
}
// Recommended
protocol SortingAlgorithm {
associatedtype Element: Comparable
mutating func sort(_ array: inout [Element])
}
// Using a protocol - more flexible but verbose
protocol FilterPredicate {
associatedtype Element
func shouldKeep(_ item: Element) -> Bool
}
// Using a function type - often simpler for basic cases
func filter<T>(_ items: [T], predicate: (T) -> Bool) -> [T] {
return items.filter(predicate)
}
Documentation should guide users toward best practices through clear examples. Begin with positive patterns before covering pitfalls, clarify all function parameters, and recommend appropriate methods for common tasks.
When writing examples:
// GOOD: Begin with positive examples, show parameter details
INDArray x = Nd4j.linspace(1, 10, 5); // start, stop, count
// [1.0000, 3.2500, 5.5000, 7.7500, 10.0000]
// GOOD: Recommend beginner-friendly methods
float[] vector = x.toFloatVector(); // Better than .data().asDouble()
// GOOD: Group related functionality with proper naming
// Reduction/accumulation operations:
x.sum(); // Sum of all elements
x.min(); // Minimum value
x.max(); // Maximum value
// BETTER: Move "don't do this" examples to the end
// Common pitfalls to avoid:
// INDArray x3 = x.add(x2); // Error if datatypes don't match
When implementing algorithms with numerical libraries like ND4J, always prefer the most direct and type-safe API methods over older patterns. This improves code clarity, prevents subtle bugs, and often leads to better performance.
Key practices:
createFromArray instead of create for array initialization, as it has clear overloads for all primitive types:
```java
// Preferred:
double arr_2d[][] = {{1.0,2.0,3.0},{4.0,5.0,6.0}};
INDArray x_2d = Nd4j.createFromArray(arr_2d);// Avoid: double[] flat = ArrayUtil.flattenDoubleArray(myDoubleArray); int[] shape = {rows, cols}; INDArray myArr = Nd4j.create(flat, shape, ‘c’);
2. Prefer direct parameter methods over shape arrays for common operations:
```java
// Preferred:
INDArray x = Nd4j.zeros(DataType.DOUBLE, 5);
// Avoid:
int[] shape = {5};
INDArray x = Nd4j.zeros(shape, DataType.DOUBLE);
castTo for proper type conversion:
```java
// When types don’t match
INDArray x = Nd4j.zeros(5, DataType.DOUBLE);
INDArray y = Nd4j.zeros(5, DataType.INT);// Preferred: INDArray result = x.add(y.castTo(DataType.DOUBLE));
// Avoid - will throw exception: INDArray result = x.add(y);
Following these practices leads to more efficient algorithm implementations with fewer errors and better maintainability.
---
## Follow Swift conventions
<!-- source: tensorflow/swift | topic: API | language: Markdown | updated: 2019-04-23 -->
When designing and documenting APIs in Swift, adhere to Swift's established naming conventions and documentation practices:
1. **Use correct initializer syntax**: Swift initializers should not form phrases with argument labels. Avoid prepositions in argument labels.
```swift
// Incorrect
let tensor = Tensor(fromNumpyArray: array)
// Correct
let tensor = Tensor(numpy: array)
Document APIs completely: When referencing APIs in documentation, include both the original framework name and the complete Swift method signature with parameter names.
// Incomplete
The saveV2 and restoreV2 ops are now supported.
// Complete
`SaveV2` (`Raw.saveV2(prefix:tensorNames:shapeAndSlices:tensors:)`), `RestoreV2` (`Raw.restoreV2(prefix:tensorNames:shapeAndSlices:dtypes:)`)
Use official terminology: Maintain consistent terminology across documentation and code (e.g., use “operator” instead of “op”).
Add API links: Where possible, include links to API documentation to enhance discoverability and understanding.
These practices ensure that your APIs are consistent with Swift ecosystem standards, making them more intuitive and discoverable for developers.
When implementing AI algorithms or neural network operations, document the sources of specific implementation choices, especially for parameters or techniques that might appear arbitrary or unusual at first glance. Include references to established AI frameworks, research papers, or model implementations that informed your approach.
This practice is particularly important for:
Example:
// Apply mask to attention weights
// Using 1e9 as a large negative value for masked positions,
// consistent with tensor2tensor implementation.
// Note: BERT uses 1e4, GPT-2 uses 1e10
*weights += (*reshapedMask - 1) * 1e9;
This documentation helps future developers understand the rationale behind implementation decisions, facilitates accurate debugging, and enables informed modifications when updating the code. It also preserves knowledge about AI model compatibility that might otherwise be lost over time.
When using configurable components, clearly document all relevant environment variables and their effects. Include examples showing how to set variables for common use cases, and specify any platform-specific differences. For environment variables that affect runtime behavior, clearly document when they need to be set and any order dependencies.
For example, when documenting Python interoperability configuration:
// Environment variables for Python configuration:
// PYTHON_LIBRARY="~/anaconda3/lib/libpython3.7m.so" - Sets specific Python library (takes precedence)
// PYTHON_VERSION="3.7" - Searches system paths for this Python version
// PYTHON_LOADER_LOGGING=1 - Enables debug output for Python library loading
// Note: Version selection must occur before any Python code is executed
import Python
// PythonLibrary.useVersion(3, 7) // Must be called immediately after import
print(Python.version) // Now safe to use Python
Note platform-specific variations when they exist, as with the Python library path example: “The exact filename will differ across Python environments and platforms.” Including such details helps users successfully configure their environment regardless of their system.
API documentation should include complete examples that demonstrate all key usage patterns. When documenting related functions (like differentiation APIs), provide examples for each variant to show their relationships and differences. Include examples that showcase both basic usage and advanced patterns.
For example, when documenting differentiation APIs:
// Basic usage example
let x: Float = 3.0
print(gradient(at: x, in: square)) // 6.0
// More comprehensive examples showing related functions
// Show value with gradient
print(valueWithGradient(at: x, in: square)) // (value: 9.0, gradient: 6.0)
// Show pullback functionality
let (result, pullback) = valueWithPullback(at: x, in: square)
print(pullback(1.0)) // 6.0
// Show higher-arity function example
let multiArgFunc: @differentiable (Float, Float) -> Float = { x, y in x * y }
print(gradient(at: 2.0, 3.0, in: multiArgFunc)) // (3.0, 2.0)
Comprehensive examples help users understand the full capabilities of your API and how different functions relate to each other, which is essential for complex systems like automatic differentiation. When documenting complex APIs or concepts, ensure your examples cover different use cases that readers might encounter in real-world scenarios.
Maintain consistent Swift style conventions throughout all code, including examples in documentation and comments. Follow these specific guidelines:
For example:
// Correct
struct Model: Differentiable {
var parameter: Float
var allDifferentiableVariables: AllDifferentiableVariables {
get { return AllDifferentiableVariables(parameter: parameter) }
set { parameter = newValue.parameter }
}
}
// Incorrect
struct Model : Differentiable { // space before colon
var parameter: Float // 2-space indentation
var allDifferentiableVariables: AllDifferentiableVariables {
get { return AllDifferentiableVariables(parameter: parameter) }
set { parameter = newValue.parameter }
}
}
When showing code patterns that may be truncated (like in documentation examples), use “…” to maintain symmetry and clarity of the pattern structure.
// Complete pattern with "..." for consistency
var allDifferentiableVariables: AllDifferentiableVariables {
get { return AllDifferentiableVariables(x: x, y: y, ...) }
set { x = newValue.x; y = newValue.y; ... }
}
Design machine learning APIs with explicit parameters for distinguishing between training and inference phases rather than relying on global state or implicit context. This pattern enables concurrent training and testing, improves model reusability, and prevents subtle bugs in distributed training scenarios.
// Instead of using global context:
protocol Layer {
func call(_ input: Input) -> Output // Implicit context is problematic
}
// Use explicit training parameters:
protocol Layer {
associatedtype Input: Differentiable
associatedtype Output: Differentiable
@differentiable(wrt: (self, input))
func call(_ input: Input, training: Bool) -> Output
}
// Implementation example:
struct BatchNorm: Layer {
var scale: Tensor<Float>
var offset: Tensor<Float>
@noDerivative var runningMean: Tensor<Float>
@noDerivative var runningVariance: Tensor<Float>
@differentiable(wrt: (self, input))
func call(_ input: Tensor<Float>, training: Bool) -> Tensor<Float> {
if training {
// Use batch statistics, update running statistics
let batchStatistics = calculateBatchStatistics(input)
updateRunningStatistics(batchStatistics)
return normalize(input, using: batchStatistics)
} else {
// Use running statistics
return normalize(input, using: (runningMean, runningVariance))
}
}
}
When making schema/proto changes, never remove (or repurpose) legacy layer parameters that existing models/configs rely on. For backward compatibility migrations, keep the old message/field definitions, mark them deprecated if appropriate, and implement translation/mapping to the new schema rather than dropping support.
Guideline (Proto example):
LayerParameter, add new optional fields with new tag numbers.Example pattern:
message LayerParameter {
// Legacy BN parameters must remain for old configs
optional BNParameter bn_param = 45; // keep, don’t remove
// New parameters added safely with new field numbers
optional AnnotatedDataParameter annotated_data_param = 200;
// If migrating semantics, keep BNParameter but implement conversion in code.
}
// Keep BNParameter definition for compatibility; optionally mark as deprecated.
message BNParameter {
optional FillerParameter filler = 3;
}
Also add a migration/compatibility test: load an older BN-containing config/model and verify it still parses and runs.
Never directly concatenate untrusted data (like user inputs or API responses) into HTML strings, as this creates cross-site scripting (XSS) vulnerabilities. Instead, create the HTML structure first, then populate content using safe DOM manipulation methods like jQuery’s .text() or native JavaScript’s .textContent that automatically escape special characters.
Example - Vulnerable code:
innerHTML = '<div class="alert alert-warning">';
innerHTML += '<strong>Warning! </strong>' + data.log + ' </div>';
Example - Secure approach:
// Create HTML structure
innerHTML = `
<div class="alert alert-warning">
<span class="close" onclick="this.parentElement.style.display='none'">×</span>
<strong>Warning!</strong><span class='warning-log'></span>
</div>`;
// Safely set the content
const $e = $("#error-msgs").html(innerHTML);
$('.warning-log', $e).text(data.log);
Never use the eval() function in Python code as it creates serious security vulnerabilities by executing arbitrary code at runtime. This can lead to code injection attacks when processing user inputs or data from untrusted sources.
Instead of using eval() to convert strings to booleans or other types, use explicit type conversion or conditional logic:
# INSECURE - vulnerable to code injection:
def setting_ctx(use_gpu):
if eval(use_gpu):
# code that uses GPU
# SECURE - using explicit boolean conversion:
def setting_ctx(use_gpu):
if isinstance(use_gpu, str):
use_gpu = use_gpu.lower() in ('true', 'yes', '1', 'y')
if use_gpu:
# code that uses GPU
For other type conversions, use appropriate functions like int(), float(), or json.loads() to safely parse data without executing code.
Configuration scripts should use variables for values that might change or are used in multiple places, such as paths, versions, and environment-specific settings. This improves maintainability, makes updates easier, and facilitates cross-platform support.
When writing configuration or installation scripts:
-y for non-interactive execution)Example:
# Bad approach - hardcoded values, separate commands
sudo wget http://example.org/dist/maven/3.6.0/apache-maven-3.6.0-bin.tar.gz
sudo tar -xf apache-maven-3.6.0-bin.tar.gz
sudo rm -f apache-maven-3.6.0-bin.tar.gz
sudo mv apache-maven-3.6.0/ apache-maven/
sudo apt-get install python-pip
sudo apt-get install python-wheel
sudo apt-get install python-dev
# Good approach - parameterized and consolidated
MAVEN_VERSION=3.6.0
cd /usr/local/src
sudo wget http://example.org/dist/maven/${MAVEN_VERSION}/apache-maven-${MAVEN_VERSION}-bin.tar.gz
sudo tar -xf apache-maven-${MAVEN_VERSION}-bin.tar.gz
sudo rm -f apache-maven-${MAVEN_VERSION}-bin.tar.gz
sudo mv apache-maven-${MAVEN_VERSION}/ apache-maven/
sudo apt-get install -y python-pip python-wheel python-dev python-setuptools
Detect and report errors as early as possible with detailed context to prevent silent failures and aid debugging. Validate inputs, states, and implementation completeness with appropriate exceptions that include relevant information.
Key practices:
// AVOID: Silently ignoring invalid parameters
if (gamma > 0)
this.gamma = gamma;
// Negative gamma silently ignored
// PREFER: Explicit validation with informative errors
Preconditions.checkArgument(gamma > 0,
"Gamma must be positive, got %s", gamma);
this.gamma = gamma;
// AVOID: Generic errors without context
if (shape[dimension] != 1) {
throw new ND4JIllegalStateException("Can squeeze only dimensions of size 1.");
}
// PREFER: Detailed exceptions with context
Preconditions.checkState(shape[dimension] == 1,
"Can squeeze only dimensions of size 1. Dimension %s has size %s. Shape: %s",
dimension, shape[dimension], Arrays.toString(shape));
// AVOID: Always constructing error messages
Preconditions.checkState(input.shape().length == 3,
"3D input expected to RNN layer expected, got " + input.shape().length);
// PREFER: Lazy message construction with format strings
Preconditions.checkState(input.rank() == 3,
"3D input expected to RNN layer, got %s", input.rank());
// AVOID: Unimplemented code with TODOs
if (modelParamsSupplier != null) {
val params = modelParamsSupplier.get();
if (params != null) {
// TODO: We should propagate params across the workers
}
}
// PREFER: Throw exception for unimplemented functionality
if (modelParamsSupplier != null) {
val params = modelParamsSupplier.get();
if (params != null) {
throw new UnsupportedOperationException(
"Parameter propagation to workers not yet implemented");
}
}
Data transfers between different compute devices (CPU/host to GPU/accelerator and back) can significantly impact performance in heterogeneous computing environments. Each transfer introduces latency and can block computation pipelines. Pay special attention to round-trip patterns where data moves from device A to B and back to A, as these create synchronization points that stall execution.
For optimal performance:
Watch for problematic patterns like this:
for step in 0...1000 {
let gradients = ... // on accelerator
weights += gradients // on accelerator
if cpuOnlyFunc(weights) == 0 { // forces data transfer to CPU and back
weights += 1 // continues on accelerator after blocking
}
}
When designing APIs that operate across device boundaries, consider providing asynchronous alternatives that allow computation to continue without blocking while transfers occur in the background.
When implementing numerical algorithms, always use appropriate data types to prevent overflow and preserve precision:
Nd4jLong or auto instead of int for array indices, dimensions, and strides, especially when working with potentially large data structures:// Poor implementation - may cause overflow
const int iStride2 = iH * iW;
const int oStride2 = oH * oW;
// Better implementation
const Nd4jLong iStride2 = iH * iW;
const Nd4jLong oStride2 = oH * oW;
// Problematic - may lose precision due to floating point limitations
z[i] = static_cast<T>(static_cast<float>(x[i]));
// Better - direct conversion preserves precision
z[i] = static_cast<T>(x[i]);
This is particularly important when converting between integer types of different sizes, as floating-point conversions can cause inaccuracies for large values. For specialized numeric types, implement proper conversion operators between them to ensure consistent and precise data handling.
Always use environment variables or configuration mechanisms instead of hardcoding paths to compilers, tools, or directories. Hardcoded paths create dependencies on specific environments and break compatibility across different platforms and CI systems.
Bad:
#!/bin/bash
CXX=/usr/bin/g++
Good:
#!/bin/bash
# Use environment variable if set, otherwise use default
CXX=${CXX:-g++}
For specialized environment paths, use specific environment variables that users can customize:
Bad:
export CMAKE_COMMAND="$CMAKE_COMMAND -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake"
Good:
# Allow users to specify RPI_HOME environment variable
export RPI_HOME=${RPI_HOME:-$HOME/raspberrypi}
export CMAKE_COMMAND="$CMAKE_COMMAND -D CMAKE_TOOLCHAIN_FILE=$RPI_HOME/pi.cmake"
This approach ensures scripts remain portable across different development environments, CI systems, and operating systems.
Use the appropriate metric types for the data being collected and consider centralizing monitoring code to ensure consistency across components.
For accumulating values like request counts, use counters rather than gauges:
// CORRECT: Request counts should use counter metrics
requestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "request_counter",
Help: "Number of request_counter",
},
[]string{COMPONENT, KIND, NAMESPACE, ACTION, SEVERITY},
)
// INCORRECT: Don't use gauges for request counts
// requestGauge = prometheus.NewGaugeVec(...)
To promote consistency, consider extracting common monitoring patterns into a shared library when multiple components need similar metrics. This ensures standardized naming conventions, label sets, and metric types across your application. Standard label keys (like component, namespace, severity) should be defined once and shared to prevent duplication and inconsistency.