Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Core: Lazy MIFs #129

Merged
merged 28 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
58d283c
Remove backends/ folder
iopapamanoglou Nov 8, 2024
2bed4d6
Add pathfinder
iopapamanoglou Nov 8, 2024
420856e
fix compile errors
iopapamanoglou Nov 8, 2024
7b6c1d9
expose pathfinder
iopapamanoglou Nov 8, 2024
2e80456
Merge rest of lazy mifs
iopapamanoglou Nov 8, 2024
695c218
missing include
iopapamanoglou Nov 8, 2024
d5ff64b
Remove _on_connect
iopapamanoglou Nov 8, 2024
45f04c5
Fix mif:is_connected_to
iopapamanoglou Nov 8, 2024
9dc0974
Add counters to py
iopapamanoglou Nov 8, 2024
782c780
Fix path filtering & LinkConditionals
iopapamanoglou Nov 8, 2024
31e5f25
remove unnecessary move(copy())
iopapamanoglou Nov 8, 2024
384bbfa
mini optimization
iopapamanoglou Nov 8, 2024
50ccb0d
Tests: Unique filenames
iopapamanoglou Nov 11, 2024
62ee143
Basic implied paths
iopapamanoglou Nov 11, 2024
85ffadf
Make connect test cases pass
iopapamanoglou Nov 11, 2024
aea1084
faster node mif check
iopapamanoglou Nov 11, 2024
3295c0e
pomise->split; run all condtionals
iopapamanoglou Nov 12, 2024
4d3055d
Max paths heuristic
iopapamanoglou Nov 12, 2024
a281ca5
clonable links
iopapamanoglou Nov 12, 2024
0226f77
link eq & simple link resolution
iopapamanoglou Nov 12, 2024
3ad4f8f
make all tests pass
iopapamanoglou Nov 12, 2024
07096ba
uncloneable link workaround
iopapamanoglou Nov 12, 2024
bae262e
multiple path limits; fix rp2040; fix minimal_led_order
iopapamanoglou Nov 12, 2024
c7608e8
higher heuristic tuning
iopapamanoglou Nov 12, 2024
994ef01
Disable debug
iopapamanoglou Nov 12, 2024
8b5e439
Remove deprecated `unique` method for `use_count` instead.
mawildoer Nov 12, 2024
35b2308
Use run_live instead of subprocess.check_output for ruff checking on …
mawildoer Nov 12, 2024
a645802
Fix logical falicy in use_count refactor and add comments on it being…
mawildoer Nov 12, 2024
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
3 changes: 2 additions & 1 deletion examples/minimal_led_orderable.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy
from faebryk.libs.app.checks import run_checks
from faebryk.libs.app.manufacturing import export_pcba_artifacts
from faebryk.libs.app.parameters import replace_tbd_with_any
from faebryk.libs.app.parameters import replace_tbd_with_any, resolve_dynamic_parameters
from faebryk.libs.brightness import TypicalLuminousIntensity
from faebryk.libs.examples.buildutil import BUILD_DIR, PCB_FILE, apply_design_to_pcb
from faebryk.libs.examples.pickers import add_example_pickers
Expand Down Expand Up @@ -130,6 +130,7 @@ def main():
logger.info("Building app")
app = App()
G = app.get_graph()
resolve_dynamic_parameters(G)

# picking ----------------------------------------------------------------
replace_tbd_with_any(app, recursive=True)
Expand Down
8 changes: 8 additions & 0 deletions scripts/find_duplicate_test_files.sh
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an odd thing to enforce, but we can discuss it another time

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

parent_dir=$(dirname "$0")/..
test_dir="$parent_dir/test"

# find all files in test_dir ending in .py
# make sure the filenames are unique
find "$test_dir" -type f -name "*.py" -exec basename {} \; | sort | uniq -d
5 changes: 5 additions & 0 deletions src/faebryk/core/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
if(${EDITABLE} AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
endif()

if(GLOBAL_PRINTF_DEBUG)
add_definitions(-DGLOBAL_PRINTF_DEBUG=1)
endif()

# source files ---------------------------------------------------------
include_directories(${CMAKE_SOURCE_DIR}/include)
file(GLOB_RECURSE SOURCE_FILES
Expand Down
3 changes: 3 additions & 0 deletions src/faebryk/core/cpp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

LEAK_WARNINGS = ConfigFlag("CPP_LEAK_WARNINGS", default=False)
DEBUG_BUILD = ConfigFlag("CPP_DEBUG_BUILD", default=False)
PRINTF_DEBUG = ConfigFlag("CPP_PRINTF_DEBUG", default=False)


# Check if installed as editable
Expand Down Expand Up @@ -66,6 +67,7 @@ def compile_and_load():

if DEBUG_BUILD:
other_flags += ["-DCMAKE_BUILD_TYPE=Debug"]
other_flags += [f"-DGLOBAL_PRINTF_DEBUG={int(bool(PRINTF_DEBUG))}"]

with global_lock(_build_dir / "lock", timeout_s=60):
run_live(
Expand Down Expand Up @@ -115,6 +117,7 @@ def compile_and_load():
is_pyi=True,
)
)
run_live(["ruff", "check", "--fix", pyi_out], logger=logger)


# Re-export c++ with type hints provided by __init__.pyi
Expand Down
60 changes: 55 additions & 5 deletions src/faebryk/core/cpp/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,39 @@ import enum
from collections.abc import Callable, Sequence, Set
from typing import overload

class Counter:
@property
def in_cnt(self) -> int: ...
@property
def weak_in_cnt(self) -> int: ...
@property
def out_weaker(self) -> int: ...
@property
def out_stronger(self) -> int: ...
@property
def out_cnt(self) -> int: ...
@property
def time_spent_s(self) -> float: ...
@property
def hide(self) -> bool: ...
@property
def name(self) -> str: ...
@property
def multi(self) -> bool: ...
@property
def total_counter(self) -> bool: ...

class Edge:
def __repr__(self) -> str: ...
@property
def to(self) -> GraphInterface: ...

class Graph:
def __init__(self) -> None: ...
def get_edges(self, arg: GraphInterface, /) -> dict[GraphInterface, Link]: ...
@property
def edges(self) -> list[tuple[GraphInterface, GraphInterface, Link]]: ...
def get_gifs(self) -> set[GraphInterface]: ...
def invalidate(self) -> None: ...
@property
def node_count(self) -> int: ...
Expand Down Expand Up @@ -50,6 +80,8 @@ class GraphInterface:
def connect(self, others: Sequence[GraphInterface]) -> None: ...
@overload
def connect(self, other: GraphInterface, link: Link) -> None: ...
@overload
def connect(self, others: Sequence[GraphInterface], link: Link) -> None: ...

class GraphInterfaceHierarchical(GraphInterface):
def __init__(self, is_parent: bool) -> None: ...
Expand Down Expand Up @@ -77,18 +109,17 @@ class GraphInterfaceSelf(GraphInterface):
def __init__(self) -> None: ...

class Link:
pass
def __eq__(self, arg: Link, /) -> bool: ...
def is_cloneable(self) -> bool: ...

class LinkDirect(Link):
def __init__(self) -> None: ...

class LinkDirectConditional(LinkDirect):
def __init__(
self,
arg: Callable[
[GraphInterface, GraphInterface], LinkDirectConditionalFilterResult
],
/,
filter: Callable[[Path], LinkDirectConditionalFilterResult],
needs_only_first_in_path: bool = False,
) -> None: ...

class LinkDirectConditionalFilterResult(enum.Enum):
Expand All @@ -98,6 +129,12 @@ class LinkDirectConditionalFilterResult(enum.Enum):

FILTER_FAIL_UNRECOVERABLE = 2

class LinkDirectDerived(LinkDirectConditional):
def __init__(self, arg: Path, /) -> None: ...

class LinkExists(Exception):
pass

class LinkFilteredException(Exception):
pass

Expand Down Expand Up @@ -145,9 +182,22 @@ class NodeException(Exception):
class NodeNoParent(Exception):
pass

class Path:
def __repr__(self) -> str: ...
def __len__(self) -> int: ...
def contains(self, arg: GraphInterface, /) -> bool: ...
def last(self) -> GraphInterface: ...
def first(self) -> GraphInterface: ...
def get_link(self, arg: Edge, /) -> Link: ...
def iterate_edges(self, arg: Callable[[Edge], bool], /) -> None: ...
def __getitem__(self, arg: int, /) -> GraphInterface: ...

def add(i: int, j: int = 1) -> int:
"""A function that adds two numbers"""

def call_python_function(func: Callable[[], int]) -> int: ...
def find_paths(src: Node, dst: Sequence[Node]) -> tuple[list[Path], list[Counter]]: ...
def print_obj(obj: object) -> None: ...
def set_indiv_measure(value: bool) -> None: ...
def set_leak_warnings(value: bool) -> None: ...
def set_max_paths(arg0: int, arg1: int, arg2: int, /) -> None: ...
83 changes: 80 additions & 3 deletions src/faebryk/core/cpp/include/graph/graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <nanobind/stl/pair.h>
#include <nanobind/stl/shared_ptr.h>
#include <nanobind/stl/string.h>
#include <nanobind/stl/tuple.h>
#include <nanobind/stl/unordered_map.h>
#include <nanobind/stl/unordered_set.h>
#include <nanobind/stl/vector.h>
Expand All @@ -35,11 +36,22 @@ using Node_ref = std::shared_ptr<Node>;
using Graph_ref = std::shared_ptr<Graph>;
using GI_refs_weak = std::vector<GI_ref_weak>;
using HierarchicalNodeRef = std::pair<Node_ref, std::string>;
using Link_weak_ref = Link *;

class Node {
class LinkExists : public std::runtime_error {
private:
std::optional<nb::object> py_handle{};
Link_ref existing_link;
Link_ref new_link;
std::string make_msg(Link_ref existing_link, Link_ref new_link,
const std::string &msg);

public:
LinkExists(Link_ref existing_link, Link_ref new_link, const std::string &msg);
Link_ref get_existing_link();
Link_ref get_new_link();
};

class Node {
public:
struct NodeException : public std::runtime_error {
NodeException(Node &node, const std::string &msg)
Expand All @@ -53,8 +65,27 @@ class Node {
}
};

class Type {
private:
nb::handle type;
bool hack_cache_is_moduleinterface;

public:
Type(nb::handle type);
bool operator==(const Type &other) const;
std::string get_name();
// TODO these are weird
bool is_moduleinterface();
static nb::type_object get_moduleinterface_type();
};

private:
std::optional<nb::object> py_handle{};
std::optional<Type> type{};

private:
std::shared_ptr<GraphInterfaceSelf> self;

std::shared_ptr<GraphInterfaceHierarchical> children;
std::shared_ptr<GraphInterfaceHierarchical> parent;

Expand All @@ -80,6 +111,7 @@ class Node {
std::string get_full_name(bool types = false);
std::string repr();

Type get_type();
std::string get_type_name();
// TODO replace with constructor
void set_py_handle(nb::object handle);
Expand Down Expand Up @@ -119,6 +151,7 @@ class GraphInterface {
void connect(GI_ref_weak other);
void connect(GI_refs_weak others);
void connect(GI_ref_weak other, Link_ref link);
void connect(GI_refs_weak others, Link_ref link);
// TODO replace with set_node(Node_ref node, std::string name)
void set_node(Node_ref node);
Node_ref get_node();
Expand All @@ -128,6 +161,9 @@ class GraphInterface {
std::string repr();
// force vtable, for typename
virtual void do_stuff() {};

/** Index in Graph::v */
size_t v_i = 0;
};

class Link {
Expand All @@ -138,14 +174,52 @@ class Link {
protected:
Link();
Link(GI_ref_weak from, GI_ref_weak to);
Link(const Link &other);

public:
std::pair<GI_ref_weak, GI_ref_weak> get_connections();
virtual void set_connections(GI_ref_weak from, GI_ref_weak to);
bool is_setup();
virtual Link_ref clone() const = 0;
virtual bool is_cloneable() const = 0;
virtual bool operator==(const Link &other) const;
virtual std::string str() const;
};

struct Edge {
/*const*/ GI_ref_weak from;
/*const*/ GI_ref_weak to;

std::string str() const;
};

using Path = std::vector<GI_ref_weak>;
using TriEdge = std::tuple</*const*/ GI_ref_weak, /*const*/ GI_ref_weak,
/*const*/ GI_ref_weak>;

class Path {
public:
Path(/*const*/ GI_ref_weak path_head);
Path(std::vector<GI_ref_weak> path);
Path(const Path &other);
Path(Path &&other);
~Path();

std::vector</*const*/ GI_ref_weak> path;

/*const*/ Link_weak_ref get_link(Edge edge) /*const*/;
std::optional<Edge> last_edge() /*const*/;
std::optional<TriEdge> last_tri_edge() /*const*/;
/*const*/ GI_ref_weak last() /*const*/;
/*const*/ GI_ref_weak first() /*const*/;
/*const*/ GI_ref_weak operator[](int idx) /*const*/;
size_t size() /*const*/;
bool contains(/*const*/ GI_ref_weak gif) /*const*/;
void iterate_edges(std::function<bool(Edge &)> visitor) /*const*/;
/*const*/ std::vector</*const*/ GI_ref_weak> &get_path() /*const*/;
size_t index(/*const*/ GI_ref_weak gif) /*const*/;

std::string str() const;
};

class Graph {
Set<GI_ref> v;
Expand Down Expand Up @@ -176,6 +250,9 @@ class Graph {

std::string repr();

Set<GI_ref> get_gifs();
std::vector<std::tuple<GI_ref_weak, GI_ref_weak, Link_ref>> all_edges();

// Algorithms
std::unordered_set<Node_ref> node_projection();
std::vector<std::pair<Node_ref, std::string>>
Expand Down
Loading
Loading