Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracing for python source functions #20

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Tracing for python source functions #20

wants to merge 5 commits into from

Conversation

govereau
Copy link
Collaborator

@govereau govereau commented Jan 9, 2025

This patch adds basic tracing for user python functions. The main code
is in Python.lean, and depends on definitions in Basic.lean and
NKI.lean, which are incomplete. As more primitives are implemented,
more user kernels will be supported.

Note to reviewers: it may be helpful to check the tests in interop/tests/test_basic.py.

Default function arguments were not being handled the same way as
function arguments. It was possible that an expression that could be
passed as an argument could not have been used as a default value for
the same argument. This patch fixes this issue, and simplifies some of
the parsing code for arguments and function signatures.
Remove some unnecessary parts of KLR, and reorganize the source files.
Basic tracing of Terms in the inner TraceM monad.
@govereau govereau added the enhancement New feature or request label Jan 9, 2025
@govereau govereau requested a review from seanmcl January 9, 2025 18:13
@govereau govereau self-assigned this Jan 9, 2025
@govereau govereau requested a review from jtristan as a code owner January 9, 2025 18:13
@govereau govereau changed the base branch from main to pg-basic January 9, 2025 18:14
This patch adds basic tracing for user python functions. The main code
is in Python.lean, and depends on definitions in Basic.lean and
NKI.lean, which are incomplete. As more primitives are implemented,
more user kernels will be supported.

def runNKIKernel (k : NKL.Python.Kernel) : Except String (List NKL.KLR.Stmt) :=
tracer ⟨ .ofList nki_env, #[] ⟩ do
traceKernel k
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a kind of annoying aspect of Lean imo. Using the namespace mechanism, I now have no idea where to look for traceKernel without UI support. I wonder if we just get used to it, or have some conventions around files vs namespace organization.

let name := s.toName
(name, .term (.expr (.var s) (.any name)))

def nki_env : List (Name × Item) :=
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why snake_case here?


def indexExpr' : Expr' -> Tracer KLR.IndexExpr
| .const (.int i) => return .int i
| .const c => throw s!"invalid constant {repr c} in index expression"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't .none be np.newaxis? That's used a lot in kernels.


def list_access (l : List Term) : List KLR.Index -> TraceM Term
| [.coord (some (.int i))] =>
let n := i.toNat
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ignores Python negative integer interpretations. Does NKI not allow things like

In [146]: [1,2,3][-1]
Out[146]: 3

for (n, f) in k.funcs do
let n := n.toName
if not (s.env.contains n) then
extend_global n (.source f)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find this definition. This updates the TraceM inner monad? Maybe I'll take a break and catch up when you merge some of the earlier PRs.

let names := f.args.names
if args.length + kwargs.length > names.length then
throw "too many arguments supplied (varargs not supported)"
let argmap <- f.args.names.enum.mapM fun (i,x) => do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to know how python gets argument values now!

| .assign xs e => assign xs e
| .augAssign x op e => do
stmt' (.assign [x] (.exprPos (.binOp op x e) (<- getPos)))
| .annAssign _ _ .none => return ()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is annAssign again?

-- When we perform an assignment, we will either add to the environment
-- the term found on the RHS, or the variable itself. The latter case
-- allows us to lookup and find the variable without substituting
-- it's definition.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its

| .expr e ty => xs.forM fun x => do
extend x.toName (.expr (.var xs[0]!) ty)
add_stmt (KLR.Stmt.assign x e)
| t => xs.forM fun x => do extend x.toName t
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think you can remove the do here.

| some e => indexExpr e

def index : Expr -> Tracer KLR.Index
| .exprPos (.const .ellipsis) _ => return .ellipsis
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should make more of an effort to get rid of ... if possible.

Base automatically changed from pg-basic to main January 11, 2025 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants