yosys/libs/subcircuit/subcircuit.h

156 lines
5.5 KiB
C++

/*
* SubCircuit -- An implementation of the Ullmann Subgraph Isomorphism
* algorithm for coarse grain logic networks
*
* Copyright (C) 2013 Claire Xenia Wolf <claire@yosyshq.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#ifndef SUBCIRCUIT_H
#define SUBCIRCUIT_H
#include <string>
#include <vector>
#include <set>
#include <map>
namespace SubCircuit
{
class SolverWorker;
class Graph
{
protected:
struct BitRef {
int nodeIdx, portIdx, bitIdx;
BitRef(int nodeIdx = -1, int portIdx = -1, int bitIdx = -1) : nodeIdx(nodeIdx), portIdx(portIdx), bitIdx(bitIdx) { };
bool operator < (const BitRef &other) const;
};
struct Edge {
std::set<BitRef> portBits;
int constValue;
bool isExtern;
Edge() : constValue(0), isExtern(false) { };
};
struct PortBit {
int edgeIdx;
PortBit() : edgeIdx(-1) { };
};
struct Port {
std::string portId;
int minWidth;
std::vector<PortBit> bits;
Port() : minWidth(-1) { };
};
struct Node {
std::string nodeId, typeId;
std::map<std::string, int> portMap;
std::vector<Port> ports;
void *userData;
bool shared;
Node() : userData(NULL), shared(false) { };
};
bool allExtern;
std::map<std::string, int> nodeMap;
std::vector<Node> nodes;
std::vector<Edge> edges;
public:
Graph() : allExtern(false) { };
Graph(const Graph &other, const std::vector<std::string> &otherNodes);
void createNode(std::string nodeId, std::string typeId, void *userData = NULL, bool shared = false);
void createPort(std::string nodeId, std::string portId, int width = 1, int minWidth = -1);
void createConnection(std::string fromNodeId, std::string fromPortId, int fromBit, std::string toNodeId, std::string toPortId, int toBit, int width = 1);
void createConnection(std::string fromNodeId, std::string fromPortId, std::string toNodeId, std::string toPortId);
void createConstant(std::string toNodeId, std::string toPortId, int toBit, int constValue);
void createConstant(std::string toNodeId, std::string toPortId, int constValue);
void markExtern(std::string nodeId, std::string portId, int bit = -1);
void markAllExtern();
void print();
friend class SolverWorker;
};
class Solver
{
public:
struct ResultNodeMapping {
std::string needleNodeId, haystackNodeId;
void *needleUserData, *haystackUserData;
std::map<std::string, std::string> portMapping;
};
struct Result {
std::string needleGraphId, haystackGraphId;
std::map<std::string, ResultNodeMapping> mappings;
};
struct MineResultNode {
std::string nodeId;
void *userData;
};
struct MineResult {
std::string graphId;
int totalMatchesAfterLimits;
std::map<std::string, int> matchesPerGraph;
std::vector<MineResultNode> nodes;
};
private:
SolverWorker *worker;
protected:
virtual bool userCompareNodes(const std::string &needleGraphId, const std::string &needleNodeId, void *needleUserData,
const std::string &haystackGraphId, const std::string &haystackNodeId, void *haystackUserData, const std::map<std::string, std::string> &portMapping);
virtual std::string userAnnotateEdge(const std::string &graphId, const std::string &fromNodeId, void *fromUserData, const std::string &toNodeId, void *toUserData);
virtual bool userCompareEdge(const std::string &needleGraphId, const std::string &needleFromNodeId, void *needleFromUserData, const std::string &needleToNodeId, void *needleToUserData,
const std::string &haystackGraphId, const std::string &haystackFromNodeId, void *haystackFromUserData, const std::string &haystackToNodeId, void *haystackToUserData);
virtual bool userCheckSolution(const Result &result);
friend class SolverWorker;
public:
Solver();
virtual ~Solver();
void setVerbose();
void addGraph(std::string graphId, const Graph &graph);
void addCompatibleTypes(std::string needleTypeId, std::string haystackTypeId);
void addCompatibleConstants(int needleConstant, int haystackConstant);
void addSwappablePorts(std::string needleTypeId, std::string portId1, std::string portId2, std::string portId3 = std::string(), std::string portId4 = std::string());
void addSwappablePorts(std::string needleTypeId, std::set<std::string> ports);
void addSwappablePortsPermutation(std::string needleTypeId, std::map<std::string, std::string> portMapping);
void solve(std::vector<Result> &results, std::string needleGraphId, std::string haystackGraphId, bool allowOverlap = true, int maxSolutions = -1);
void solve(std::vector<Result> &results, std::string needleGraphId, std::string haystackGraphId,
const std::map<std::string, std::set<std::string>> &initialMapping, bool allowOverlap = true, int maxSolutions = -1);
void mine(std::vector<MineResult> &results, int minNodes, int maxNodes, int minMatches, int limitMatchesPerGraph = -1);
void clearOverlapHistory();
void clearConfig();
};
}
#endif /* SUBCIRCUIT_H */