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
Binary file removed 3rd-party/sbg/sb-graph-1.0.0.tar.gz
Binary file not shown.
45 changes: 6 additions & 39 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,21 @@ AST_DIR := ast
PARSER_DIR := parser
SBG_LIB := sbg
SBG_DEV := sb-graph-dev
SBG_1_0_0 := sb-graph-1.0.0
BOOST_LIB_PATH := $(3RD_PARTY_DIR)/boost
BOOST_1_81 := boost-1.81.0
BOOST_1_81_LIB := $(BOOST_1_81).tar.xz
BOOST_1_81_INC := -I$(BOOST_LIB_PATH)/$(BOOST_1_81)/include
SBG_1_0_0 := sb-graph-dev


# Flags, Libraries and Includes
SBG_LIB_DEV_INCLUDE := -I$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV)/usr/include
SBG_LIB_1_0_0_INCLUDE := -I$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0)/usr/include
SBG_LIB_DEV_INCLUDE := -I$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV)/install/include
SBG_LIB_1_0_0_INCLUDE := -I$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0)/install/include
INCLUDES := -I.
CXXFLAGS := -std=c++17 -Wall -Wno-reorder -O3
ifeq ($(MODE),Debug)
CXXFLAGS += -ggdb
endif
LIBMODELICA = lib/libmodelica.a
LIBS := -L./lib -lginac -lmodelica
SBG_LIB_DEV_LINK := -L$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV)/usr/lib -lsbgraph
SBG_LIB_1_0_0_LINK := -L$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0)/usr/lib -lsbgraph
SBG_LIB_DEV_LINK := -L$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV)/install/lib -lsbgraph
SBG_LIB_1_0_0_LINK := -L$(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0)/install/lib -lsbgraph

all: $(LIBMODELICA)

Expand Down Expand Up @@ -71,36 +67,7 @@ $(BUILD_DIR)/%.o : %.cpp

$(COMMON_OBJ): | create-folders

lib-boost:
ifeq ("$(wildcard $(BOOST_LIB_PATH)/$(BOOST_1_81))","")
cd $(BOOST_LIB_PATH); tar -xvf $(BOOST_1_81_LIB)
endif

update-sbg:
cd $(3RD_PARTY_DIR)/$(SBG_LIB); python3 ./update.py --branch_name $(sbg_branch) --repo_checkout $(repo_checkout)
cd $(3RD_PARTY_DIR)/$(SBG_LIB); tar -zxvf $(SBG_DEV).tar.gz

lib-sbg: lib-boost
ifeq ("$(wildcard $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0))","")
cd $(3RD_PARTY_DIR)/$(SBG_LIB); tar -zxvf $(SBG_1_0_0).tar.gz
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0); autoconf
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0); ./configure
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0); make
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0); mkdir -p usr
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_1_0_0); make install prefix=./usr
endif
ifeq ("$(wildcard $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV))","")
make update-sbg
endif
ifeq ($(build_sbg), True)
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV); autoconf
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV); ./configure
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV); make boost_libdir=../../boost/$(BOOST_1_81)
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV); mkdir -p usr
cd $(3RD_PARTY_DIR)/$(SBG_LIB)/$(SBG_DEV); make install prefix=./usr
endif

$(LIBMODELICA): $(COMMON_OBJ) lib-sbg | create-folders
$(LIBMODELICA): $(COMMON_OBJ) | create-folders
$(AR) rcs $(LIBMODELICA) $(COMMON_OBJ)

doc: Doxyfile
Expand Down
3 changes: 2 additions & 1 deletion ast/modification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ std::ostream& operator<<(std::ostream& out, const ShortClass& c) // output
out << c.name() << " = ";
if (c.derived()) {
if (c.type_prefixes()) {
foreach_(Option<TypePrefix> tp, c.type_prefixes().get()) out << typePrefix(tp);
auto type_prefixes = c.type_prefixes().get();
foreach_(Option<TypePrefix> tp, type_prefixes) out << typePrefix(tp);
}

out << c.derived().get();
Expand Down
30 changes: 30 additions & 0 deletions causalize/graph_implementation/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# The Directories, Source, Includes, Objects, Binary
CAUSALIZE_GRP_DIR := $(CAUSALIZE_DIR)/graph_implementation
CAUSALIZE_GRP := bin/grp_causalize

all: $(CAUSALIZE_GRP)

# Sources
CAUSALIZE_GRP_SRC := \
$(CAUSALIZE_GRP_DIR)/main.cpp \
$(CAUSALIZE_GRP_DIR)/apply_tarjan.cpp \
$(CAUSALIZE_GRP_DIR)/unknowns_collector.cpp \
$(CAUSALIZE_GRP_DIR)/causalization_strategy.cpp \
$(CAUSALIZE_GRP_DIR)/vector/contains_vector.cpp \
$(CAUSALIZE_GRP_DIR)/vector/graph_builder.cpp \
$(CAUSALIZE_GRP_DIR)/vector/causalization_algorithm.cpp \
$(CAUSALIZE_GRP_DIR)/vector/splitfor.cpp \
$(CAUSALIZE_GRP_DIR)/graph/graph_definition.cpp \
$(CAUSALIZE_DIR)/common/for_unrolling/process_for_equations.cpp

# Objects
CAUSALIZE_GRP_OBJ=$(addprefix $(BUILD_DIR)/, $(CAUSALIZE_GRP_SRC:.cpp=.o))

create-folders::
@mkdir -p $(BUILD_DIR)/$(CAUSALIZE_DIR)/graph_implementation
@mkdir -p $(BUILD_DIR)/$(CAUSALIZE_DIR)/graph_implementation/vector
@mkdir -p $(BUILD_DIR)/$(CAUSALIZE_DIR)/graph_implementation/graph

$(CAUSALIZE_GRP): $(CAUSALIZE_GRP_OBJ) $(CAUSALIZE_COMMON_OBJ) $(LIBMODELICA)
$(CXX) $(CXXFLAGS) $(INCLUDES) -o $(CAUSALIZE_GRP) $(CAUSALIZE_COMMON_OBJ) $(CAUSALIZE_GRP_OBJ) $(LIBS)

180 changes: 180 additions & 0 deletions causalize/graph_implementation/apply_tarjan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*****************************************************************************

This file is part of Modelica C Compiler.

Modelica C Compiler is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Modelica C Compiler is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Modelica C Compiler. If not, see <http://www.gnu.org/licenses/>.

******************************************************************************/

#include <causalize/graph_implementation/apply_tarjan.h>
#include <util/debug.h>

#include <boost/property_map/property_map.hpp>
#include <boost/graph/max_cardinality_matching.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/adjacency_list.hpp>

#include <map>
#include <stdio.h>

namespace Causalize {
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> DirectedGraph;
typedef boost::graph_traits<DirectedGraph>::vertex_descriptor DGVertex;
typedef boost::graph_traits<DirectedGraph>::edge_descriptor DGEdge;

std::map<Vertex, Vertex> _matching;
std::map<DGVertex, Vertex> _collapsed2original;
using namespace Causalize;

DGVertex original2collapsed(Vertex value)
{
std::map<DGVertex, Vertex>::iterator it;
for (it = _collapsed2original.begin(); it != _collapsed2original.end(); it++) {
if ((*it).second == value) {
return (*it).first;
}
}
ERROR("Can't find collapsed vertex from original.");
return (*it).first;
}

void buildCollapsedGraph(Causalize::CausalizationGraph &graph, DirectedGraph &digraph)
{
// Create the vertices on the directed graph
Causalize::CausalizationGraph::vertex_iterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(graph); vi != vi_end; ++vi) {
if (graph[*vi].type == E) {
DGVertex v = add_vertex(digraph);
_collapsed2original[v] = *vi;
}
}
// Create the edges on the directed graph
DirectedGraph::vertex_iterator vj, vj_end;
for (boost::tie(vj, vj_end) = vertices(digraph); vj != vj_end; ++vj) {
CausalizationGraph::out_edge_iterator ek, ek_end;
Vertex originalEqVertex = _collapsed2original[*vj];
Vertex uMatchingVertex = _matching[originalEqVertex];
for (boost::tie(ek, ek_end) = out_edges(uMatchingVertex, graph); ek != ek_end; ++ek) {
Vertex eqAdjacentVertex = target(*ek, graph);
if (eqAdjacentVertex != originalEqVertex) {
boost::add_edge(original2collapsed(eqAdjacentVertex), *vj, digraph);
}
}
}
}

// void replaceMMOClassEquations(MMO_Class mmoClass, MMO_EquationList causalEqs) {
// MMO_EquationList oldEquations = mmoClass->getEquations();
// MMO_EquationListIterator iter, auxiliaryIter;
// auxiliaryIter = oldEquations->begin();
// for(iter = auxiliaryIter; iter != oldEquations->end(); iter = auxiliaryIter) {
// ++auxiliaryIter;
// mmoClass->removeEquation(current_element(iter));
// }
// foreach(iter, causalEqs) {
// mmoClass->addEquation(current_element(iter));
// }
//}

int apply_tarjan(CausalizationGraph &graph, std::map<int, Causalize::ComponentPtr> &components)
{
boost::associative_property_map<std::map<Vertex, Vertex>> matching_map(_matching);

// Vertex Index Map required for checked_edmonds_maximum_cardinality_matching.
// This is to allow the causalization graph, which is an adjacency list, to
// use as VertexList either vecS or listS.
std::map<Vertex, int> vertex2index;
CausalizationGraph::vertex_iterator i, iend;
int ic = 0;
for (boost::tie(i, iend) = vertices(graph); i != iend; ++i, ++ic) {
vertex2index[*i] = ic;
}
boost::associative_property_map<std::map<Vertex, int>> index_map(vertex2index);

DEBUG('c', "Calculating maximum cardinality matching over causalization graph...\n");

bool success = checked_edmonds_maximum_cardinality_matching(graph, matching_map, index_map);
if (!success) {
ERROR("Can't find a maximum cardinality matching.\n");
}

for (std::map<Vertex, Vertex>::iterator it = _matching.begin(); it != _matching.end(); ++it) {
char se[10];
Vertex v1 = it->first;
if (graph[v1].type == E) {
sprintf(se, "E%d", vertex2index[v1]);
} else {
sprintf(se, "U%d", vertex2index[v1]);
}
char su[10];
Vertex v2 = it->second;
if (graph[v2].type == E) {
sprintf(su, "E%d", vertex2index[v2]);
} else {
sprintf(su, "U%d", vertex2index[v2]);
}
DEBUG('c', "%s matches %s\n", se, su);
}

DirectedGraph collapsedGraph;

DEBUG('c', "Collapsing matching vertices...\n");

buildCollapsedGraph(graph, collapsedGraph);

std::map<DGVertex, int> vertex2component;
boost::associative_property_map<std::map<DGVertex, int>> component_map(vertex2component);
std::map<DGVertex, int> dg_vertex2index;
DirectedGraph::vertex_iterator j, jend;
int jc = 0;
for (boost::tie(j, jend) = vertices(collapsedGraph); j != jend; ++j, ++jc) {
dg_vertex2index[*j] = jc;
}
boost::associative_property_map<std::map<DGVertex, int>> dg_index_map(dg_vertex2index);

DEBUG('c', "Running tarjan algorithm over collapsed graph...\n");

int numComponents = strong_components(collapsedGraph, component_map, boost::vertex_index_map(dg_index_map));

DEBUG('c', "%d strong components identifed.\n", numComponents);

for (std::map<DGVertex, int>::iterator it = vertex2component.begin(); it != vertex2component.end(); ++it) {
DGVertex dgVertex = it->first;
int componentIndex = it->second;
DEBUG('c', "Vertex: %d -- Component: %d\n", dg_vertex2index[dgVertex], componentIndex);
Vertex eqVertex = _collapsed2original[dgVertex];
Vertex uVertex = _matching[eqVertex];
std::map<int, Causalize::ComponentPtr>::iterator componentsIt = components.find(componentIndex);
if (componentsIt == components.end()) {
Causalize::ComponentPtr component = new Causalize::Component;
std::list<Vertex> *uVertices = new std::list<Vertex>;
uVertices->push_back(uVertex);
component->uVertices = uVertices;
std::list<Vertex> *eqVertices = new std::list<Vertex>;
eqVertices->push_back(eqVertex);
component->eqVertices = eqVertices;
components[componentIndex] = component;
} else {
Causalize::ComponentPtr component = componentsIt->second;
std::list<Vertex> *uVertices = component->uVertices;
uVertices->push_back(uVertex);
std::list<Vertex> *eqVertices = component->eqVertices;
eqVertices->push_back(eqVertex);
}
}

return components.size();
}

} // namespace Causalize
37 changes: 37 additions & 0 deletions causalize/graph_implementation/apply_tarjan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*****************************************************************************

This file is part of Modelica C Compiler.

Modelica C Compiler is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Modelica C Compiler is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Modelica C Compiler. If not, see <http://www.gnu.org/licenses/>.

******************************************************************************/

#ifndef APPLY_TARJAN_H_
#define APPLY_TARJAN_H_

#include <causalize/graph_implementation/graph/graph_definition.h>
#include <utility>
#include <list>
#include <map>

namespace Causalize {
struct Component {
std::list<Vertex> *uVertices;
std::list<Vertex> *eqVertices;
};
typedef Component *ComponentPtr;
int apply_tarjan(CausalizationGraph &graph, std::map<int, ComponentPtr> &components);
} // namespace Causalize

#endif /* APPLY_TARJAN_H_ */
Loading