Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library/chemistry/src/Tests.qs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ operation JordanWignerUCCDTermPQRSTest() : Unit {
}

@Config(Unrestricted)
// @Test()
@Test()
operation JordanWignerUCCDTermPRQSTest() : Unit {
let term0 = [NewJordanWignerInputState(2.0, 0.0, [2, 0, 4, 1])];
let state0 = [0., 0., 0., 0., 0.,-0.416147, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.909297, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.];
Expand Down
1 change: 0 additions & 1 deletion library/fixed_point/src/Operations.qs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import Types.FixedPoint;
import Init.PrepareFxP;
import Operations.AddFxP;
import Signed.Operations.Invert2sSI, Signed.Operations.MultiplySI, Signed.Operations.SquareSI;
import Facts.AssertPointPositionsIdenticalFxP;
import Std.Arrays.Zipped;
Expand Down
25 changes: 17 additions & 8 deletions source/compiler/qsc/src/interpret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ impl Interpreter {

/// Given a package ID, returns all the global items in the package.
/// Note this does not currently include re-exports.
fn package_globals(&self, package_id: PackageId) -> Vec<(Vec<Rc<str>>, Rc<str>, Value)> {
fn package_globals(&self, package_id: PackageId) -> Vec<PackageGlobal> {
let mut exported_items = Vec::new();
let package = &self
.compiler
Expand All @@ -454,24 +454,25 @@ impl Interpreter {
package: package_id,
item: fir::LocalItemId::from(usize::from(term.id.item)),
};
exported_items.push((
global.namespace,
global.name,
Value::Global(store_item_id, FunctorApp::default()),
));
exported_items.push(PackageGlobal {
namespace: global.namespace,
name: global.name,
value: Value::Global(store_item_id, FunctorApp::default()),
is_test: term.is_test,
});
}
}
exported_items
}

/// Get the global callables defined in the user source passed into initialization of the interpreter as `Value` instances.
pub fn source_globals(&self) -> Vec<(Vec<Rc<str>>, Rc<str>, Value)> {
pub fn source_globals(&self) -> Vec<PackageGlobal> {
self.package_globals(self.source_package)
}

/// Get the global callables defined in the open package being interpreted as `Value` instances, which will include any items
/// defined by calls to `eval_fragments` and the like.
pub fn user_globals(&self) -> Vec<(Vec<Rc<str>>, Rc<str>, Value)> {
pub fn user_globals(&self) -> Vec<PackageGlobal> {
self.package_globals(self.package)
}

Expand Down Expand Up @@ -1811,6 +1812,14 @@ pub enum CircuitGenerationMethod {
Static,
}

/// A global item as enumerated from a package.
pub struct PackageGlobal {
pub namespace: Vec<Rc<str>>,
pub name: Rc<str>,
pub value: Value,
pub is_test: bool,
}

/// A debugger that enables step-by-step evaluation of code
/// and inspecting state in the interpreter.
pub struct Debugger {
Expand Down
10 changes: 5 additions & 5 deletions source/compiler/qsc/src/interpret/circuit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use super::{CircuitEntryPoint, Debugger, Interpreter};
use crate::{
interpret::{CircuitGenerationMethod, Error},
interpret::{CircuitGenerationMethod, Error, PackageGlobal},
target::Profile,
};
use expect_test::expect;
Expand Down Expand Up @@ -280,15 +280,15 @@ fn static_circuit_from_callable_with_callable_arg_matches_classical_eval() {
let globals = interp.source_globals();
let invoke = globals
.iter()
.find(|(_, n, _)| &**n == "InvokeWithQubits")
.find(|PackageGlobal { name, .. }| &**name == "InvokeWithQubits")
.expect("InvokeWithQubits should be a source global")
.2
.value
.clone();
let all_h = globals
.iter()
.find(|(_, n, _)| &**n == "AllH")
.find(|PackageGlobal { name, .. }| &**name == "AllH")
.expect("AllH should be a source global")
.2
.value
.clone();
let args = Value::Tuple(vec![Value::Int(3), all_h].into(), None);

Expand Down
42 changes: 25 additions & 17 deletions source/compiler/qsc/src/interpret/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ mod given_interpreter {
use expect_test::expect;
use indoc::indoc;

use crate::interpret::PackageGlobal;

use super::*;

mod without_stdlib {
Expand Down Expand Up @@ -674,17 +676,17 @@ mod given_interpreter {
let items = interpreter.user_globals();
assert_eq!(items.len(), 2);
// No namespace for top-level items
assert!(items[0].0.is_empty());
assert!(items[0].namespace.is_empty());
expect![[r#"
"Foo"
"#]]
.assert_debug_eq(&items[0].1);
.assert_debug_eq(&items[0].name);
// No namespace for top-level items
assert!(items[1].0.is_empty());
assert!(items[1].namespace.is_empty());
expect![[r#"
"Bar"
"#]]
.assert_debug_eq(&items[1].1);
.assert_debug_eq(&items[1].name);
}

#[test]
Expand All @@ -706,11 +708,11 @@ mod given_interpreter {
"Foo",
]
"#]]
.assert_debug_eq(&items[0].0);
.assert_debug_eq(&items[0].namespace);
expect![[r#"
"Bar"
"#]]
.assert_debug_eq(&items[0].1);
.assert_debug_eq(&items[0].name);
}

#[test]
Expand All @@ -737,29 +739,29 @@ mod given_interpreter {
let items = interpreter.user_globals();
assert_eq!(items.len(), 4);
// No namespace for top-level items
assert!(items[0].0.is_empty());
assert!(items[0].namespace.is_empty());
expect![[r#"
"Foo"
"#]]
.assert_debug_eq(&items[0].1);
.assert_debug_eq(&items[0].name);
// No namespace for top-level items
assert!(items[1].0.is_empty());
assert!(items[1].namespace.is_empty());
expect![[r#"
"Bar"
"#]]
.assert_debug_eq(&items[1].1);
.assert_debug_eq(&items[1].name);
// No namespace for top-level items
assert!(items[2].0.is_empty());
assert!(items[2].namespace.is_empty());
expect![[r#"
"Baz"
"#]]
.assert_debug_eq(&items[2].1);
.assert_debug_eq(&items[2].name);
// No namespace for top-level items
assert!(items[3].0.is_empty());
assert!(items[3].namespace.is_empty());
expect![[r#"
"Qux"
"#]]
.assert_debug_eq(&items[3].1);
.assert_debug_eq(&items[3].name);
}

#[test]
Expand Down Expand Up @@ -1105,7 +1107,13 @@ mod given_interpreter {
interpreter
.user_globals()
.into_iter()
.find_map(|(_, global_name, value)| (global_name.as_ref() == name).then_some(value))
.find_map(
|PackageGlobal {
name: global_name,
value,
..
}| { (global_name.as_ref() == name).then_some(value) },
)
.unwrap_or_else(|| panic!("{name} should be present in user globals"))
}

Expand Down Expand Up @@ -2952,11 +2960,11 @@ mod given_interpreter {
"A",
]
"#]]
.assert_debug_eq(&items[0].0);
.assert_debug_eq(&items[0].namespace);
expect![[r#"
"B"
"#]]
.assert_debug_eq(&items[0].1);
.assert_debug_eq(&items[0].name);
}

#[test]
Expand Down
4 changes: 2 additions & 2 deletions source/compiler/qsc_frontend/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ impl GlobalTable {

for global in global::iter_package(id, package).filter(|global| {
global.visibility == hir::Visibility::Public
|| matches!(&global.kind, global::Kind::Callable(t) if t.intrinsic)
|| matches!(&global.kind, global::Kind::Callable(t) if t.is_intrinsic)
}) {
// If the namespace is `Main` and we have an alias, we treat it as the root of the package, so there's no
// namespace prefix between the dependency alias and the defined items.
Expand Down Expand Up @@ -1322,7 +1322,7 @@ impl GlobalTable {
Res::Importable(Importable::Callable(term.id, global.status)),
);
}
if term.intrinsic {
if term.is_intrinsic {
self.scope.intrinsics.insert(global.name);
}
}
Expand Down
12 changes: 8 additions & 4 deletions source/compiler/qsc_hir/src/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

use crate::{
hir::{
Item, ItemId, ItemKind, ItemStatus, Package, PackageId, Res, SpecBody, SpecGen, Visibility,
Attr, Item, ItemId, ItemKind, ItemStatus, Package, PackageId, Res, SpecBody, SpecGen,
Visibility,
},
ty::Scheme,
};
Expand Down Expand Up @@ -48,7 +49,8 @@ pub struct Ty {
pub struct Callable {
pub id: ItemId,
pub scheme: Scheme,
pub intrinsic: bool,
pub is_intrinsic: bool,
pub is_test: bool,
}

/// A lookup table used for looking up global core items for insertion in `qsc_passes`.
Expand Down Expand Up @@ -144,7 +146,8 @@ impl PackageIter<'_> {
kind: Kind::Callable(Callable {
id: item_id,
scheme: decl.scheme(),
intrinsic: decl.body.body == SpecBody::Gen(SpecGen::Intrinsic),
is_intrinsic: decl.body.body == SpecBody::Gen(SpecGen::Intrinsic),
is_test: decl.attrs.contains(&Attr::Test),
}),
}),
(ItemKind::Callable(decl), None) => Some(Global {
Expand All @@ -155,7 +158,8 @@ impl PackageIter<'_> {
kind: Kind::Callable(Callable {
id: item_id,
scheme: decl.scheme(),
intrinsic: decl.body.body == SpecBody::Gen(SpecGen::Intrinsic),
is_intrinsic: decl.body.body == SpecBody::Gen(SpecGen::Intrinsic),
is_test: decl.attrs.contains(&Attr::Test),
}),
}),
(ItemKind::Ty(name, _def), Some(ItemKind::Namespace(namespace, _))) => Some(Global {
Expand Down
17 changes: 13 additions & 4 deletions source/qdk_package/qdk/_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,15 @@ def __init__(
self_ref = weakref.ref(self)

def make_callable_weak(
callable: GlobalCallable, namespace: List[str], callable_name: str
callable: GlobalCallable,
namespace: List[str],
callable_name: str,
is_test: bool,
) -> None:
ctx = self_ref()
if ctx is None or ctx._disposed:
return
ctx._make_callable(callable, namespace, callable_name)
ctx._make_callable(callable, namespace, callable_name, is_test)

def make_class_weak(
qsharp_type: TypeIR, namespace: List[str], class_name: str
Expand Down Expand Up @@ -433,7 +436,11 @@ def _get_code_module(
return module

def _make_callable(
self, callable: GlobalCallable, namespace: List[str], callable_name: str
self,
callable: GlobalCallable,
namespace: List[str],
callable_name: str,
is_test: bool,
):
"""Registers a Q# callable in this context's code module."""
module = self._get_code_module(namespace)
Expand All @@ -452,12 +459,14 @@ def _callable_fn(*args):

setattr(_callable_fn, "_qdk_context", self)
setattr(_callable_fn, "__global_callable", callable)
setattr(_callable_fn, "__is_test__", is_test)
setattr(_callable_fn, "__name__", ".".join(namespace + [callable_name]))

if module.__dict__.get(callable_name) is None:
module.__setattr__(callable_name, _callable_fn)
else:
for key, val in module.__dict__.get(callable_name).__dict__.items():
if key != "__global_callable":
if key != "__global_callable" and key != "__is_test__":
_callable_fn.__dict__[key] = val
module.__setattr__(callable_name, _callable_fn)

Expand Down
2 changes: 1 addition & 1 deletion source/qdk_package/qdk/_native.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class Interpreter:
list_directory: Callable[[str], List[Dict[str, str]]],
resolve_path: Callable[[str, str], str],
fetch_github: Callable[[str, str, str, str], str],
make_callable: Optional[Callable[[GlobalCallable, List[str], str], None]],
make_callable: Optional[Callable[[GlobalCallable, List[str], str, bool], None]],
make_class: Optional[Callable[[TypeIR, List[str], str], None]],
trace_circuit: Optional[bool],
) -> None:
Expand Down
Loading
Loading