Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-koch committed Oct 18, 2024
2 parents 3dc8b87 + 83b9f31 commit 8134a85
Show file tree
Hide file tree
Showing 35 changed files with 1,191 additions and 938 deletions.
297 changes: 194 additions & 103 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,16 @@ debug_assert_with_mut_call = "warn"

[workspace.dependencies]
pyo3 = "0.19.0"
hugr = "0.12.1"
hugr-cli = "0.6.0"
hugr-llvm = "0.5.0"
serde_json = "1.0.111"
inkwell = "0.4.0"
cargo_toml = "0.20.4"
thiserror = "1.0.37"
hugr-llvm = "0.5.1"

[patch.crates-io]

# Uncomment these to test the latest dependency version during development
#hugr = { git = "https://github.com/CQCL/hugr", rev = "6bf6c82c9ec9d801ab43e311e5f815a3eea7d9c1" }
#hugr-cli = { git = "https://github.com/CQCL/hugr", rev = "6bf6c82c9ec9d801ab43e311e5f815a3eea7d9c1" }
#hugr-llvm = { git = "https://github.com/CQCL/hugr-llvm", commit = "7245ca91b45b828ddb49456e9e0a895d79f1d739" }

# TODO update to 0.6 when released https://github.com/CQCL/guppylang/issues/564
hugr-llvm = { git = "https://github.com/CQCL/hugr-llvm", rev = "c1e6407" }
32 changes: 12 additions & 20 deletions devenv.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1724504184,
"lastModified": 1729009702,
"owner": "cachix",
"repo": "devenv",
"rev": "51338b58fd666f448db7486ec145dbe52db9b829",
"treeHash": "cedf6d41b00189dfd5132772cb5f35fcb10a7f7b",
"rev": "67004f395b11fc32a9805d5e7da0012306323859",
"type": "github"
},
"original": {
Expand All @@ -25,11 +24,10 @@
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1724740262,
"lastModified": 1728973961,
"owner": "nix-community",
"repo": "fenix",
"rev": "703efdd9b5c6a7d5824afa348a24fbbf8ff226be",
"treeHash": "813b64ec284029d7f1cf5349a17c2a19a203a8da",
"rev": "d6a9ff4d1e60c347a23bc96ccdb058d37a810541",
"type": "github"
},
"original": {
Expand All @@ -45,7 +43,6 @@
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"treeHash": "2addb7b71a20a25ea74feeaf5c2f6a6b30898ecb",
"type": "github"
},
"original": {
Expand All @@ -66,7 +63,6 @@
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"treeHash": "ca14199cabdfe1a06a7b1654c76ed49100a689f9",
"type": "github"
},
"original": {
Expand All @@ -77,11 +73,10 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1724395761,
"lastModified": 1728538411,
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ae815cee91b417be55d43781eb4b73ae1ecc396c",
"treeHash": "849822d55d3862e40c77934bd38c466cb06ec0bb",
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221",
"type": "github"
},
"original": {
Expand All @@ -93,11 +88,10 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1724316499,
"lastModified": 1728909085,
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "797f7dc49e0bc7fab4b57c021cdf68f595e47841",
"treeHash": "fe60fe6585f3b84f2ee7fcbf10f02f02fc5c54ca",
"rev": "c0b1da36f7c34a7146501f684e9ebdf15d2bebf8",
"type": "github"
},
"original": {
Expand All @@ -117,11 +111,10 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1724440431,
"lastModified": 1728778939,
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "c8a54057aae480c56e28ef3e14e4960628ac495b",
"treeHash": "40ee1da550348c789ed9503eea365533a618506c",
"rev": "ff68f91754be6f3427e4986d7949e6273659be1d",
"type": "github"
},
"original": {
Expand All @@ -141,11 +134,10 @@
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1724739663,
"lastModified": 1728977395,
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "0f7f68dad2e0e545150e6088f0e1964f7455e9e1",
"treeHash": "c23c2b1e46737d09685cb1848adb6d6a245e2287",
"rev": "418c1365eccf20c9261b6948a6e637f789224af9",
"type": "github"
},
"original": {
Expand Down
2 changes: 1 addition & 1 deletion devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

enterShell = ''
just setup-extras
source .venv/bin/activate
source .devenv/state/venv/activate
'';

languages.python = {
Expand Down
4 changes: 1 addition & 3 deletions execute_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ name = "execute_llvm"
crate-type = ["cdylib"]

[dependencies]
pyo3.workspace = true
hugr.workspace = true
hugr-llvm.workspace = true
pyo3.workspace = true
serde_json.workspace = true
inkwell.workspace = true
18 changes: 8 additions & 10 deletions execute_llvm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use hugr::{self, ops::custom::resolve_extension_ops, std_extensions};
//! This module provides a Python interface to compile and execute a Hugr program to LLVM IR.
use hugr::{extension::ExtensionRegistry, ops, HugrView};
use hugr_llvm;
use hugr_llvm::fat::FatExt;
use inkwell::{context::Context, module::Module, values::GenericValue};
use hugr_llvm::hugr::{self, ops::custom::resolve_extension_ops, std_extensions};
use hugr_llvm::inkwell::{context::Context, module::Module, values::GenericValue};
use hugr_llvm::utils::fat::FatExt;
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;

Expand Down Expand Up @@ -59,15 +59,15 @@ fn compile_module<'a>(
) -> PyResult<Module<'a>> {
let llvm_module = ctx.create_module("guppy_llvm");
// TODO: Handle tket2 codegen extension
let extensions = hugr_llvm::custom::CodegenExtsMap::default()
let extensions = hugr_llvm::custom::CodegenExtsBuilder::default()
.add_int_extensions()
.add_default_prelude_extensions()
.add_float_extensions()
.add_conversion_extensions()
.add_rotation_extensions();
let extensions = hugr_llvm::custom::conversions::add_conversions_extension(extensions);

let emitter =
hugr_llvm::emit::EmitHugr::new(&ctx, llvm_module, namer.into(), extensions.into());
hugr_llvm::emit::EmitHugr::new(ctx, llvm_module, namer.into(), extensions.finish().into());
let hugr_module = hugr.fat_root().unwrap();
let emitter = emitter
.emit_module(hugr_module)
Expand Down Expand Up @@ -116,9 +116,7 @@ fn run_int_function(hugr_json: &str, fn_name: &str) -> PyResult<i64> {
run_function::<i64>(hugr_json, fn_name, |_, llvm_val| {
// GenericVal is 64 bits wide
let int_with_sign = llvm_val.as_int(true);
let unsigned_int =
u64::try_from(int_with_sign).map_err(|e| pyerr!("Reading back llvm value: {}", e))?;
let signed_int = unsigned_int as i64;
let signed_int = int_with_sign as i64;
Ok(signed_int)
})
}
Expand Down
7 changes: 4 additions & 3 deletions guppylang/checker/expr_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1118,7 +1118,8 @@ def python_value_to_guppy_type(v: Any, node: ast.expr, globals: Globals) -> Type
case list():
return _python_list_to_guppy_type(v, node, globals)
case _:
# Pytket conversion is an optional feature
# Pytket conversion is an experimental feature
# if pytket and tket2 are installed
try:
import pytket

Expand All @@ -1136,8 +1137,8 @@ def python_value_to_guppy_type(v: Any, node: ast.expr, globals: Globals) -> Type
)
except ImportError:
raise GuppyError(
"Pytket compatibility requires `tket2` to be installed. "
"See https://github.com/CQCL/tket2/tree/main/tket2-py",
"Experimental pytket compatibility requires `tket2` to be"
" installed. See https://github.com/CQCL/tket2/tree/main/tket2-py",
node,
) from None
except ImportError:
Expand Down
1 change: 1 addition & 0 deletions guppylang/checker/linearity_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def visit_PlaceNode(self, node: PlaceNode, /, is_inout_arg: bool = False) -> Non
f"`{subscript.parent.ty}` is not allowed in `@owned` position",
node,
)
self.visit(subscript.item_expr)
self.scope.assign(subscript.item)
# Visiting the `__getitem__(place.parent, place.item)` call ensures that we
# linearity-check the parent and element.
Expand Down
4 changes: 3 additions & 1 deletion guppylang/compiler/expr_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,9 @@ def python_value_to_hugr(v: Any, exp_ty: Type) -> hv.Value | None:
if doesnt_contain_none(vs):
return ListVal(vs, get_element_type(exp_ty).to_hugr())
case _:
# Pytket conversion is an optional feature
# TODO replace with hugr protocol handling: https://github.com/CQCL/guppylang/issues/563
# Pytket conversion is an experimental feature
# if pytket and tket2 are installed
try:
import pytket

Expand Down
26 changes: 23 additions & 3 deletions guppylang/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from types import ModuleType
from typing import Any, TypeVar, overload

import hugr.ext
from hugr import ops
from hugr import tys as ht
from hugr import val as hv
from hugr.package import FuncDefnPointer, ModulePointer

import guppylang
from guppylang.ast_util import annotate_location, has_empty_body
Expand All @@ -25,7 +25,11 @@
)
from guppylang.definition.declaration import RawFunctionDecl
from guppylang.definition.extern import RawExternDef
from guppylang.definition.function import RawFunctionDef, parse_py_func
from guppylang.definition.function import (
CompiledFunctionDef,
RawFunctionDef,
parse_py_func,
)
from guppylang.definition.parameter import ConstVarDef, TypeVarDef
from guppylang.definition.struct import RawStructDef
from guppylang.definition.ty import OpaqueTypeDef, TypeDef
Expand Down Expand Up @@ -433,7 +437,7 @@ def get_module(
module.load(**defs)
return module

def compile_module(self, id: ModuleIdentifier | None = None) -> hugr.ext.Package:
def compile_module(self, id: ModuleIdentifier | None = None) -> ModulePointer:
"""Compiles the local module into a Hugr."""
module = self.get_module(id)
if not module:
Expand All @@ -445,6 +449,22 @@ def compile_module(self, id: ModuleIdentifier | None = None) -> hugr.ext.Package
raise MissingModuleError(err)
return module.compile()

def compile_function(self, f_def: RawFunctionDef) -> FuncDefnPointer:
"""Compiles a single function definition."""
module = f_def.id.module
if not module:
raise GuppyError("Function definition must belong to a module")
compiled_module = module.compile()
assert module._compiled is not None, "Module should be compiled"
globs = module._compiled.globs
assert globs is not None
compiled_def = globs[f_def.id]
assert isinstance(compiled_def, CompiledFunctionDef)
node = compiled_def.func_def.parent_node
return FuncDefnPointer(
compiled_module.package, compiled_module.module_index, node
)

def registered_modules(self) -> KeysView[ModuleIdentifier]:
"""Returns a list of all currently registered modules for local contexts."""
return self._modules.keys()
Expand Down
5 changes: 0 additions & 5 deletions guppylang/definition/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from typing import TYPE_CHECKING, ClassVar, TypeAlias

from hugr.build.dfg import DefinitionBuilder, OpVar
from hugr.ext import Package

from guppylang.span import SourceMap

Expand Down Expand Up @@ -75,10 +74,6 @@ def description(self) -> str:
a function, but got {description of this definition} instead".
"""

def compile(self) -> Package:
assert self.id.module is not None
return self.id.module.compile()


class ParsableDef(Definition):
"""Abstract base class for raw definitions that still require parsing.
Expand Down
6 changes: 6 additions & 0 deletions guppylang/definition/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import hugr.tys as ht
from hugr import Wire
from hugr.build.dfg import DefinitionBuilder, OpVar
from hugr.package import FuncDefnPointer

from guppylang.ast_util import AstNode, annotate_location, with_loc
from guppylang.checker.cfg_checker import CheckedCFG
Expand Down Expand Up @@ -66,6 +67,11 @@ def parse(self, globals: Globals, sources: SourceMap) -> "ParsedFunctionDef":
self.id, self.name, func_ast, ty, self.python_scope, docstring
)

def compile(self) -> FuncDefnPointer:
from guppylang.decorator import guppy

return guppy.compile_function(self)


@dataclass(frozen=True)
class ParsedFunctionDef(CheckableDef, CallableDef):
Expand Down
Loading

0 comments on commit 8134a85

Please sign in to comment.