Skip to content

Commit

Permalink
several bug fixes, added normilization
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonKlx committed Dec 10, 2024
1 parent f6a7ab1 commit f0e4bae
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ namespace hal
*/
igraph_t* get_graph() const;

/**
* @brief Get all the gates that are included in the netlist graph
*
* @return A vector of gates.
*/
const std::vector<Gate*> get_included_gates() const;

/**
* @brief Get the gates corresponding to the specified vertices.
*
Expand Down
7 changes: 7 additions & 0 deletions plugins/graph_algorithm/python/python_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ namespace hal
:rtype: hal_py.Netlist
)");

py_netlist_graph.def("get_included_gates", &graph_algorithm::NetlistGraph::get_included_gates, R"(
Get the gates included in the netlist graph.
:returns: The gates included in the netlsit graph.
:rtype: list[hal_py.Gate]
)");

py_netlist_graph.def(
"get_gates_from_vertices",
[](const graph_algorithm::NetlistGraph& self, const std::vector<u32>& vertices) -> std::optional<std::vector<Gate*>> {
Expand Down
8 changes: 4 additions & 4 deletions plugins/graph_algorithm/src/algorithms/centrality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace hal
return ERR(res.get_error());
}

auto res = get_harmonic_centrality(graph, &i_vertices, direction);
auto res = get_harmonic_centrality(graph, &i_vertices, direction, cutoff);

igraph_vector_int_destroy(&i_vertices);

Expand Down Expand Up @@ -61,7 +61,7 @@ namespace hal
VECTOR(i_vertices)[i] = vertices.at(i);
}

auto res = get_harmonic_centrality(graph, &i_vertices, direction);
auto res = get_harmonic_centrality(graph, &i_vertices, direction, cutoff);

igraph_vector_int_destroy(&i_vertices);

Expand Down Expand Up @@ -153,7 +153,7 @@ namespace hal
return ERR(res.get_error());
}

auto res = get_betweenness_centrality(graph, &i_vertices, directed);
auto res = get_betweenness_centrality(graph, &i_vertices, directed, cutoff);

igraph_vector_int_destroy(&i_vertices);

Expand Down Expand Up @@ -188,7 +188,7 @@ namespace hal
VECTOR(i_vertices)[i] = vertices.at(i);
}

auto res = get_betweenness_centrality(graph, &i_vertices, directed);
auto res = get_betweenness_centrality(graph, &i_vertices, directed, cutoff);

igraph_vector_int_destroy(&i_vertices);

Expand Down
19 changes: 16 additions & 3 deletions plugins/graph_algorithm/src/netlist_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,17 @@ namespace hal
std::map<Net*, u32> global_out_to_node;
for (auto* src_gate : nl_asbtr->get_target_gates())
{
for (auto* dst_gate : nl_asbtr->get_unique_successors(src_gate).get())
const auto successors = nl_asbtr->get_unique_successors(src_gate).get();
for (auto* dst_gate : successors)
{
VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(dst_gate);
}

if (create_dummy_vertices)
{
for (auto* global_in : nl_asbtr->get_global_input_predecessors(src_gate).get())
const auto global_predecessors = nl_asbtr->get_global_input_predecessors(src_gate).get();
for (auto* global_in : global_predecessors)
{
if (global_in_to_node.find(global_in) == global_in_to_node.end())
{
Expand All @@ -256,7 +258,8 @@ namespace hal
VECTOR(edges)[edge_index++] = graph->m_gates_to_nodes.at(src_gate);
}

for (auto* global_out : nl_asbtr->get_global_output_successors(src_gate).get())
const auto global_successors = nl_asbtr->get_global_output_successors(src_gate).get();
for (auto* global_out : global_successors)
{
if (global_out_to_node.find(global_out) == global_out_to_node.end())
{
Expand Down Expand Up @@ -309,6 +312,16 @@ namespace hal
return m_graph_ptr;
}

const std::vector<Gate*> NetlistGraph::get_included_gates() const
{
std::vector<Gate*> gates;
gates.reserve(m_gates_to_nodes.size());

std::transform(m_gates_to_nodes.begin(), m_gates_to_nodes.end(), std::back_inserter(gates), [](const auto& pair) { return pair.first; });

return gates;
}

Result<std::vector<Gate*>> NetlistGraph::get_gates_from_vertices(const std::vector<u32>& vertices) const
{
std::vector<Gate*> res;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,54 +11,58 @@ namespace hal
class BetweennessCentrality : public GateFeatureBulk
{
public:
BetweennessCentrality(const bool directed = true, const i32 cutoff = -1) : m_directed(directed), m_cutoff(cutoff){};
BetweennessCentrality(const bool directed = true, const i32 cutoff = -1, const bool normalize = true) : m_directed(directed), m_cutoff(cutoff), m_normalize(normalize){};

Result<std::vector<std::vector<FEATURE_TYPE>>> calculate_feature(Context& ctx, const std::vector<Gate*>& gates) const override;
std::string to_string() const override;

private:
const bool m_directed;
const i32 m_cutoff;
const bool m_normalize;
};

class HarmonicCentrality : public GateFeatureBulk
{
public:
HarmonicCentrality(const PinDirection& direction, const i32 cutoff = -1) : m_direction(direction), m_cutoff(cutoff){};
HarmonicCentrality(const PinDirection& direction, const i32 cutoff = -1, const bool normalize = true) : m_direction(direction), m_cutoff(cutoff), m_normalize(normalize){};

Result<std::vector<std::vector<FEATURE_TYPE>>> calculate_feature(Context& ctx, const std::vector<Gate*>& gates) const override;
std::string to_string() const override;

private:
const PinDirection m_direction;
const i32 m_cutoff;
const bool m_normalize;
};

class SequentialBetweennessCentrality : public GateFeatureBulk
{
public:
SequentialBetweennessCentrality(const bool directed = true, const i32 cutoff = -1) : m_directed(directed), m_cutoff(cutoff){};
SequentialBetweennessCentrality(const bool directed = true, const i32 cutoff = -1, const bool normalize = true) : m_directed(directed), m_cutoff(cutoff), m_normalize(normalize){};

Result<std::vector<std::vector<FEATURE_TYPE>>> calculate_feature(Context& ctx, const std::vector<Gate*>& gates) const override;
std::string to_string() const override;

private:
const bool m_directed;
const i32 m_cutoff;
const bool m_normalize;
};

class SequentialHarmonicCentrality : public GateFeatureBulk
{
public:
SequentialHarmonicCentrality(const PinDirection& direction, const i32 cutoff = -1) : m_direction(direction), m_cutoff(cutoff){};
SequentialHarmonicCentrality(const PinDirection& direction, const i32 cutoff = -1, const bool normalize = true) : m_direction(direction), m_cutoff(cutoff), m_normalize(normalize){};

Result<std::vector<std::vector<FEATURE_TYPE>>> calculate_feature(Context& ctx, const std::vector<Gate*>& gates) const override;
std::string to_string() const override;

private:
const PinDirection m_direction;
const i32 m_cutoff;
const bool m_normalize;
};
} // namespace gate_feature
} // namespace machine_learning
} // namespace machine_learning
} // namespace hal
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include "hal_core/utilities/result.h"

#include <vector>

namespace hal
{
namespace machine_learning
{
template<typename T>
Result<std::monostate> normalize_vector_min_max(std::vector<T>& values)
{
// Ensure T is a numeric type
static_assert(std::is_arithmetic<T>::value, "Vector elements must be numeric.");

if (!values.empty())
{
const auto min_val = *std::min_element(values.begin(), values.end());
const auto max_val = *std::max_element(values.begin(), values.end());

// Avoid division by zero if all elements are the same
if (min_val == max_val)
{
values.assign(values.size(), static_cast<T>(0.5));
return OK({});
}

// Apply min-max normalization
for (auto& value : values)
{
value = (value - min_val) / (max_val - min_val);
}
}

return OK({});
}

} // namespace machine_learning
} // namespace hal
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,57 @@
from hal_plugins import machine_learning

# Create the feature context with the netlist
fc = machine_learning.gate_feature.FeatureContext(netlist)
fc = machine_learning.Context(netlist)

# Instantiate all available gate pair features
connected_global_ios = machine_learning.gate_feature.ConnectedGlobalIOs()
distance_global_io = machine_learning.gate_feature.DistanceGlobalIO(hal_py.PinDirection.output)
sequnetial_distance_global_io = machine_learning.gate_feature.SequentialDistanceGlobalIO(hal_py.PinDirection.output)
io_degrees = machine_learning.gate_feature.IODegrees()
gate_type_one_hot = machine_learning.gate_feature.GateTypeOneHot()
neighboring_gate_types = machine_learning.gate_feature.NeighboringGateTypes(2, hal_py.PinDirection.output)

# Collect all features into a list
features = [
connected_global_ios,
distance_global_io,
#sequnetial_distance_global_io,
io_degrees,
#gate_type_one_hot,
#neighboring_gate_types,
machine_learning.GateFeature.GateFeatureSingle.ConnectedGlobalIOs(),

machine_learning.GateFeature.GateFeatureSingle.DistanceGlobalIO(hal_py.PinDirection.output, directed=True, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),
machine_learning.GateFeature.GateFeatureSingle.DistanceGlobalIO(hal_py.PinDirection.output, directed=False, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),
machine_learning.GateFeature.GateFeatureSingle.DistanceGlobalIO(hal_py.PinDirection.input, directed=True, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),
machine_learning.GateFeature.GateFeatureSingle.DistanceGlobalIO(hal_py.PinDirection.input, directed=False, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),

machine_learning.GateFeature.GateFeatureSingle.SequentialDistanceGlobalIO(hal_py.PinDirection.output, directed=True, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),
machine_learning.GateFeature.GateFeatureSingle.SequentialDistanceGlobalIO(hal_py.PinDirection.output, directed=False, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),
machine_learning.GateFeature.GateFeatureSingle.SequentialDistanceGlobalIO(hal_py.PinDirection.input, directed=True, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),
machine_learning.GateFeature.GateFeatureSingle.SequentialDistanceGlobalIO(hal_py.PinDirection.input, directed=False, forbidden_pin_types=[hal_py.PinType.clock, hal_py.PinType.reset, hal_py.PinType.enable]),

machine_learning.GateFeature.GateFeatureSingle.IODegrees(),

machine_learning.GateFeature.GateFeatureSingle.GateTypeOneHot(),

machine_learning.GateFeature.GateFeatureSingle.NeighboringGateTypes(1, hal_py.PinDirection.output, directed=True),
machine_learning.GateFeature.GateFeatureSingle.NeighboringGateTypes(2, hal_py.PinDirection.output, directed=True),
machine_learning.GateFeature.GateFeatureSingle.NeighboringGateTypes(3, hal_py.PinDirection.output, directed=True),

machine_learning.GateFeature.GateFeatureSingle.NeighboringGateTypes(1, hal_py.PinDirection.input, directed=True),
machine_learning.GateFeature.GateFeatureSingle.NeighboringGateTypes(2, hal_py.PinDirection.input, directed=True),
machine_learning.GateFeature.GateFeatureSingle.NeighboringGateTypes(3, hal_py.PinDirection.input, directed=True),

machine_learning.GateFeature.GateFeatureBulk.BetweennessCentrality(directed = True, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.BetweennessCentrality(directed = True, cutoff=16),
machine_learning.GateFeature.GateFeatureBulk.BetweennessCentrality(directed = False, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.BetweennessCentrality(directed = False, cutoff=16),
machine_learning.GateFeature.GateFeatureBulk.SequentialBetweennessCentrality(directed = True, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.SequentialBetweennessCentrality(directed = True, cutoff=16),
machine_learning.GateFeature.GateFeatureBulk.SequentialBetweennessCentrality(directed = False, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.SequentialBetweennessCentrality(directed = False, cutoff=16),

machine_learning.GateFeature.GateFeatureBulk.HarmonicCentrality(direction=hal_py.PinDirection.output, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.HarmonicCentrality(direction=hal_py.PinDirection.output, cutoff=16),
machine_learning.GateFeature.GateFeatureBulk.HarmonicCentrality(direction=hal_py.PinDirection.inout, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.HarmonicCentrality(direction=hal_py.PinDirection.inout, cutoff=16),
machine_learning.GateFeature.GateFeatureBulk.SequentialHarmonicCentrality(direction=hal_py.PinDirection.output, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.SequentialHarmonicCentrality(direction=hal_py.PinDirection.output, cutoff=16),
machine_learning.GateFeature.GateFeatureBulk.SequentialHarmonicCentrality(direction=hal_py.PinDirection.inout, cutoff=-1),
machine_learning.GateFeature.GateFeatureBulk.SequentialHarmonicCentrality(direction=hal_py.PinDirection.inout, cutoff=16),
]

gate_a = netlist.get_gate_by_id(21)
#gates = [netlist.get_gate_by_id(21)]
gates = netlist.get_gates(lambda g: g.type.has_property(hal_py.sequential))

# Build the feature vector for the pair of gates
feature_vector = machine_learning.gate_feature.build_feature_vec(fc, features, gate_a)
feature_vector = machine_learning.gate_feature.build_feature_vecs(fc, features, gates)

print("Feature vector:", feature_vector)
6 changes: 3 additions & 3 deletions plugins/machine_learning/src/features/gate_feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace hal
{
namespace gate_feature
{
Result<std::vector<std::vector<FEATURE_TYPE>>> build_feature_vecs(const std::vector<const GateFeatureBulk*>& features, const std::vector<Gate*>& gates)
Result<std::vector<std::vector<FEATURE_TYPE>>> build_feature_vecs(const std::vector<const GateFeature*>& features, const std::vector<Gate*>& gates)
{
if (gates.empty())
{
Expand All @@ -26,7 +26,7 @@ namespace hal
return build_feature_vecs(features, gates);
}

Result<std::vector<std::vector<FEATURE_TYPE>>> build_feature_vecs(Context& ctx, const std::vector<const GateFeatureBulk*>& features, const std::vector<Gate*>& gates)
Result<std::vector<std::vector<FEATURE_TYPE>>> build_feature_vecs(Context& ctx, const std::vector<const GateFeature*>& features, const std::vector<Gate*>& gates)
{
std::vector<std::vector<FEATURE_TYPE>> feature_vecs(gates.size(), std::vector<FEATURE_TYPE>());

Expand All @@ -50,5 +50,5 @@ namespace hal
return OK(feature_vecs);
}
} // namespace gate_feature
} // namespace machine_learning
} // namespace machine_learning
} // namespace hal
Loading

0 comments on commit f0e4bae

Please sign in to comment.