Skip to content

Commit f59b283

Browse files
committed
julia, agents and claude files
1 parent b89be94 commit f59b283

3 files changed

Lines changed: 103 additions & 176 deletions

File tree

AGENTS.md

Lines changed: 51 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# AGENTS.md
22

3-
Guidance for Claude Code when working in this repository.
4-
5-
See also: @JULIA.md for general Julia engineering and review guidance.
3+
Guidance for Claude Code in this repository. See @JULIA.md for general Julia practices.
64

75
## Project Overview
86

@@ -12,64 +10,59 @@ DynamicPPL builds on AbstractPPL.jl for shared PPL interfaces such as `VarName`,
1210

1311
## Tests And Formatting
1412

15-
- Tests are split into Group1 and Group2 for CI parallelism, controlled by `GROUP` in `test/runtests.jl`.
16-
- CI also runs Aqua.jl quality checks, doctests, formatting, and multi-platform tests across selected Julia versions and thread counts.
17-
- Each test file should be self-contained. Use package imports, not relative imports or `include()` statements, so files can run individually with tools such as TestPicker.jl.
18-
- Formatting uses JuliaFormatter.jl v1, not v2, with Blue style from `.JuliaFormatter.toml`.
13+
- Tests are split into Group1/Group2 via `GROUP` in `test/runtests.jl`.
1914

20-
```bash
21-
julia --project -e 'using JuliaFormatter; format(".")'
22-
```
15+
- Test files are self-contained — use package imports, not relative imports or `include()`, so they run individually with TestPicker.jl.
16+
- Formatting is JuliaFormatter v1 (Blue style):
17+
18+
```bash
19+
julia --project -e 'using JuliaFormatter; format(".")'
20+
```
2321

2422
## Architecture Pointers
2523

26-
Use the docs for model evaluation, the tilde pipeline, init strategies, transform strategies, accumulators, conditioning/fixing, threading, `VarNamedTuple`, and `LogDensityFunction`.
24+
- `Model` (`src/model.jl`): wraps model function, args, context; created by `@model` in `src/compiler.jl`.
25+
- `AbstractVarInfo` (`src/abstract_varinfo.jl`): tracks random variables and accumulated quantities during evaluation.
26+
- `VarName` (AbstractPPL): address for model variables, including nested fields/indices.
27+
- `VarNamedTuple` (`src/varnamedtuple.jl`): named-tuple-like parameter storage keyed by `VarName`.
28+
- `LogDensityFunction` (`src/logdensityfunction.jl`): bridge from named parameters to flat `AbstractVector` for samplers/AD.
29+
- `ext/`: ForwardDiff, Mooncake, ReverseDiff, EnzymeCore, MCMCChains, MarginalLogDensities integrations.
30+
- `DynamicPPL.TestUtils`: analytical test models, `run_ad`, `ADResult`.
2731

28-
- `Model` (`src/model.jl`): wraps a model function, arguments, and context; created by `@model` in `src/compiler.jl`.
29-
- `AbstractVarInfo` (`src/abstract_varinfo.jl`): interface for tracking random variables and accumulated quantities during model execution.
30-
- `VarName` (AbstractPPL): address for model variables, including nested fields and indices.
31-
- `VarNamedTuple` (`src/varnamedtuple.jl`): named-tuple-like parameter storage keyed by `VarName`.
32-
- `LogDensityFunction` (`src/logdensityfunction.jl`): bridge between named model parameters and flat `AbstractVector{<:Real}` inputs for samplers, optimizers, and AD.
33-
- Optional integrations live in `ext/`: ForwardDiff, Mooncake, ReverseDiff, EnzymeCore, MCMCChains, and MarginalLogDensities.
34-
- `DynamicPPL.TestUtils` provides analytical test models and AD helpers (`run_ad`, `ADResult`) used across the Turing ecosystem.
32+
## Key Invariants
3533

36-
## DynamicPPL Review Notes
34+
Evaluator methods follow BangBang `!!` semantics (see JULIA.md).
3735

38-
- Prefer `OnlyAccsVarInfo` plus `init!!` for new evaluation code when fast paths only need accumulators or a subset of VarInfo state.
39-
- `VarInfo` remains important, but it combines vector values, transform state, metadata, and accumulators. Many fast paths need only part of that state, so avoid adding behavior to `VarInfo` by default.
40-
- Functions ending in `!!` follow BangBang.jl semantics: they may mutate or return a replacement object. Always use the return value, and return updated state from callers that invoke `!!`.
36+
**`accumulate_assume!!`**`val` is model-space (passed to `logpdf`); `tval` is transformed; `logjac` is the log-Jacobian of the forward link transform (zero if unlinked):
4137

4238
```julia
43-
# Wrong: updates may be lost.
44-
accumulate_assume!!(vi, x, tval, logjac, vn, dist, template)
45-
46-
# Right.
4739
vi = accumulate_assume!!(vi, x, tval, logjac, vn, dist, template)
4840
```
4941

50-
- In `accumulate_assume!!`, `val` is the model-space value and should be passed to `logpdf`; `tval` is the transformed value.
51-
- `logjac` is the log-Jacobian of the forward link transform, or zero if unlinked.
52-
- `LogLikelihoodAccumulator` uses `Distributions.loglikelihood`, not `logpdf`; array-valued or product-like observations can differ in shape or aggregation.
53-
- `copy(acc)` must not share mutable internal state unless that sharing is intentional and documented.
54-
- `get_raw_value(tv, dist)` is required for dynamic transforms because `DynamicLink` and `Unlink` derive their transform from the distribution; the raw value cannot be recovered correctly from `tv` alone when support is distribution-dependent.
55-
- The one-argument `get_raw_value(tv)` is only for cases where the transform is already fully known.
56-
- `DynamicLink` re-derives the bijection from `dist` during evaluation because support can depend on earlier random variables, such as `y ~ truncated(Normal(); lower=x)`. Do not cache or reuse a fixed bijection unless support is known to be constant.
57-
- If support is known to be constant, consider `FixedTransform` via `WithTransforms`; fixed transforms must match the target transform.
58-
- Samplers operating in unconstrained space usually need `getlogjoint_internal`; `getlogjoint` is the constrained-space log joint.
59-
- Compiled ReverseDiff tapes are input-dependent; do not use `AutoReverseDiff(; compile=true)` when model control flow depends on parameter values.
60-
- Keep evaluator APIs split into structural preparation and AD-specific preparation. Put backend-specific gradient code in extensions when possible.
61-
- Check aliasing in evaluator and AD APIs. `!!` methods may return buffers that alias internal caches; copy before exposing results to callers, storing them long term, or reusing them after another model evaluation.
42+
**`LogLikelihoodAccumulator`** uses `Distributions.loglikelihood`, not `logpdf` — array/product observations differ in shape and aggregation.
43+
44+
**Dynamic transforms**`DynamicLink`/`Unlink` re-derive bijections from `dist` because support can depend on earlier RVs (e.g. `y ~ truncated(Normal(); lower=x)`). Use `get_raw_value(tv, dist)`; never cache a fixed bijection. Use `FixedTransform`/`WithTransforms` only when support is constant.
45+
46+
**Log joint** — samplers in unconstrained space want `getlogjoint_internal`; constrained-space is `getlogjoint`.
47+
48+
**ReverseDiff** — don't use `AutoReverseDiff(; compile=true)` when model control flow depends on parameter values (compiled tapes are input-dependent).
49+
50+
## DynamicPPL Review Notes
51+
52+
- Prefer `OnlyAccsVarInfo` + `init!!` for new evaluation code that needs only accumulators or a subset of `VarInfo` state.
53+
- Avoid adding behaviour to `VarInfo` by default — it bundles values, transform state, metadata, and accumulators, but most fast paths need only part.
54+
- Keep evaluator APIs split: structural prep vs AD-specific prep. Backend gradient code goes in extensions.
6255
6356
## Names And Parameter Storage
6457
65-
- Use `VarNamedTuple` as the canonical internal representation for named parameter collections in new code.
66-
- Accept `NamedTuple` and `Dict{VarName}` at user-facing boundaries, but convert to `VarNamedTuple` rather than propagating them internally.
67-
- Preserve templates, shapes, and index structure when round-tripping between named values and flat vectors.
68-
- Avoid large mostly-empty shadow arrays for sparse indexed variables.
69-
- Use `@varname(x)`, not `:x` or `VarName(:x)`.
70-
- Use subsumption for containment checks: `subsumes(@varname(x), @varname(x[1]))` is true, but the names are not equal.
71-
- Treat VarName display, sorting, prefixing, unprefixing, and serialization as downstream-facing interface behavior.
72-
- Test nested fields, indices, ranges, `Colon`, and non-standard indices when changing VarName optics.
58+
- Use `VarNamedTuple` as the canonical internal representation for named parameter collections in new code.
59+
- Accept `NamedTuple` and `Dict{VarName}` at user-facing boundaries, but convert to `VarNamedTuple` rather than propagating them internally.
60+
- Preserve templates, shapes, and index structure when round-tripping between named values and flat vectors.
61+
- Avoid large mostly-empty shadow arrays for sparse indexed variables.
62+
- Use `@varname(x)`, not `:x` or `VarName(:x)`.
63+
- Use subsumption for containment checks: `subsumes(@varname(x), @varname(x[1]))` is true, but the names are not equal.
64+
- Treat VarName display, sorting, prefixing, unprefixing, and serialization as downstream-facing interface behavior.
65+
- Test nested fields, indices, ranges, `Colon`, and non-standard indices when changing VarName optics.
7366
7467
## `@model` Compiler
7568
@@ -81,18 +74,18 @@ Keep macro hygiene explicit. User variables, generated temporaries, and globals
8174
8275
## Threading
8376
84-
- Implement `promote_for_threadsafe_eval(acc, T)` if an accumulator stores typed containers that need to hold AD tracer types such as ForwardDiff `Dual`s. The default no-op is wrong for accumulators with concrete float fields.
85-
- Avoid designs that index storage by `Threads.threadid()`. Julia scheduling and thread IDs are not a stable ownership model.
77+
- Implement `promote_for_threadsafe_eval(acc, T)` for accumulators with concrete float fields — the default no-op leaves them unable to hold AD tracers like ForwardDiff `Dual`s.
78+
- Avoid designs that index storage by `Threads.threadid()`. Julia scheduling and thread IDs are not a stable ownership model.
8679
8780
## Contributing Checklist
8881
89-
- Non-breaking changes target `main`; breaking changes target `breaking`.
90-
- Identify whether the change is user-facing, internal, or downstream-facing through Turing.jl.
91-
- Add the smallest tests that exercise the behavior.
92-
- Add nested-submodel tests for context, prefix, conditioning, or fixing changes.
93-
- Add AD backend tests for log-density, transform, vector-parameter, or `run_ad` changes.
94-
- Add round-trip tests for flattening and unflattening changes, including scalars, arrays, tuples, `NamedTuple`s, nested values, and mixed element types.
95-
- Check type stability and allocations for hot paths.
96-
- Check dependency placement and compat bounds when touching Project files, extensions, docs, or tests.
97-
- Include benchmark numbers for performance-sensitive changes.
98-
- Document and test new user-facing API.
82+
- Non-breaking changes target `main`; breaking changes target `breaking`.
83+
- Identify whether the change is user-facing, internal, or downstream-facing through Turing.jl.
84+
- Add the smallest tests that exercise the behavior.
85+
- Add nested-submodel tests for context, prefix, conditioning, or fixing changes.
86+
- Add AD backend tests for log-density, transform, vector-parameter, or `run_ad` changes.
87+
- Add round-trip tests for flattening and unflattening changes, including scalars, arrays, tuples, `NamedTuple`s, nested values, and mixed element types.
88+
- Check type stability and allocations for hot paths.
89+
- Check dependency placement and compat bounds when touching Project files, extensions, docs, or tests.
90+
- Include benchmark numbers for performance-sensitive changes.
91+
- Document and test new user-facing API.

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
@AGENTS.md
2-
@JULIA.md
2+
@JULIA.md

0 commit comments

Comments
 (0)