Giter Site home page Giter Site logo

cp-profiler-deprecated-'s Introduction

CP-Profiler

CP-Profiler provides search tree visualisations for executions of constraint programming solvers.

Table of Contents

Building

Dependencies:

  • Qt5.x
    git submodule update --init
    mkdir build && cd build
    qmake .. && make

Usage

  1. Starting CP-Profiler

    cp-profiler.app/Contents/MacOS/cp-profiler (Mac)

This starts a local TCP server listening on one of the available ports (6565 by default).

  1. Executing a supported solver

The solver must implement the profiling protocol (TODO). Integration libraries are available if you wish to extend your solver to work with CP-Profiler.

The Protocol (high level)

The following describes the protocol that a solver must implement to communicate with the profiler.

The protocol distinguishes between the following types of messages: Start, Restart, Done, and Node.

The Start message is sent at the beginning of the execution (TODO: multithreaded search). The message has two optional (?) parameters:

  • Name: execution's descriptor to be presented to the user (e.g. the model's name)
  • Execution ID: globally unique identifier used to distinguish between different executions.

TODO: any other parameters?

The Restart message is sent whenever a solver performs a restart in case of a restart-based search.

The Done message is sent to the profiler at the end of the execution to indicate that no further nodes should be expected.

The Node message is sent whenever a new node is explored by the solver and contains information necessary for reconstructing the search tree. The required parameters are:

  • Node ID: unique node identifier in the execution.
  • Parent ID: the identifier (Node ID) of the parent node. A root node can have an identifier of -1. (TODO: needs checking)
  • Alternative: the node's position relative to its siblings; for the left-most child it is 0, for the second left-most it is 1 etc.
  • Number of Children: the number of children nodes. If not known, can be set to 0 and the node will be extended with extra children later on if necessary. It is, however, advisable to specify the number of children the profiler should expect (for example, the yet to arrive nodes can be visualised to give a better idea about the search).
  • Status: allows to distinguish between different types of nodes. Supported values are:
    • BRANCH: internal node in the tree;
    • SOLUTION: leaf node representing a solution;
    • FAILURE: leaf node representing a failure;
    • SKIPPED: leaf node representing unexplored search space due to backjumping.

Example. The following sequence of nodes (excluding the Start and Done messages) produces the simple tree below:

Label Node ID Parent ID Alternative Number of Children Status
Root 0 -1 -1 2 BRANCH
Failure 1 0 0 0 FAILED
Solution 2 0 1 0 SOLVED

A simple search tree

The Protocol (low level)

Each message starts with a four-byte integer encoding the size of the remainder of the message in bytes. This is followed by a single byte encoding the type of the message. The corresponding values are: Node: 0, Done: 1, Start: 2, Restart: 3.

Node message

In case the message is of the type Node, the following fields are added in order: id, pid, alt, children and status.

Node identifiers id and pid are represented using three four-byte integers: first identifies the identifier of the node within a thread, the second — the identifier of the restart (in a restart-based search), and the third — the identifier of the thread. The alt and children fields are represented by a single four byte integer each. The status field is represented by a single byte; its possible values are: SOLVED: 0, FAILED: 1, BRANCH: 2, SKIPPED: 3. All multi-byte integer values are encoded using the two's compliment notation in the big-endian order.

Additionally, each node message can contain the following optional fields:

  • label: branching decision (or any arbitrary string to be drawn together with the node);
  • nogood: string representation of a newly generated nogood in a learning solver;
  • info: arbitrary information about the node (TODO).

Field identifiers and their sizes in bytes:

field name field id size (bytes)
id n/a 12
pid n/a 12
alt n/a 4
children n/a 4
status n/a 1
label 0 any
nogood 1 any
info 2 any

Example. The following is a possible correspondence between a solver and the profiler that generates the simple tree above.The order in which different fields arrive is shown from top to bottom (rows are numbered for convenience).

Message 1:

Row Bytes Interpretation
1 00 00 00 21 message size (33)
2 02 message type (START)
3 02 field (info)
4 00 00 00 1B string size (27)
5 7b 22 6e 61 6d 65 22 3a 20 22 6d 69 6e 69 6d 61 6c 20 65 78 61 6d 70 6c 65 22 7d '{"name": "minimal example"}'

Message 2:

Row Bytes Interpretation
6 00 00 00 2B message size (43)
7 00 message type (NODE)
8 00 00 00 00 node id (0)
9 FF FF FF FF node restart id (-1)
10 FF FF FF FF node thread id (-1)
11 FF FF FF FF parent id (-1)
12 FF FF FF FF parent restart id (-1)
13 FF FF FF FF parent thread id (-1)
14 FF FF FF FF alternative (-1)
15 00 00 00 02 children (2)
16 02 status (BRANCH)
17 00 field (label)
18 00 00 00 04 string size (4)
19 52 6f 6f 74 'Root'

Message 3:

Row Bytes Interpretation
20 00 00 00 01 message size (1)
21 01 message type (DONE)

Tree Visualisations

Traditional Tree Visualisation

When a new execution is connected to the profiler it will be added to the list of executions displayed at the top of the main window. For example, in the image below execution golomb6a.fzn is shown to be added to the profiler. To display the execution, select its name from the list and click the Show Tree button. Note that the solver can still be running the execution, in which case the profiler will draw the search tree in real time.

Profiler Conductor

The image below shows an example of a traditional (node-link) visualisation of the search tree. Different types of nodes are shown differently: branch (internal) nodes are shown as blue circles; nodes representing failures are shown as red squares; solution nodes are shown as green diamonds.

Note that the root of the tree is shown in gold colour indicating the currently selected node. Arrow keys on the keyboard allow the user to navigate the tree by changing which node is selected. Down navigates to the first child of the current node, Shift+Down — to its last child, Up — to its the parent, Left — to its next sibling on the left, Right — to its next sibling on the right. Additionally, pressing R will navigate to the root of the tree. The same actions are available under the Navigation menu.

Traditional Visualisation Interface

If a subtree contains no solutions, it can be collapsed into a special single node displayed as a large red triangle. By default, the tree will be collapse failed subtrees automatically during its construction as a way to deal with large trees. The image below shows the same search tree as above, but with all failed subtrees collapsed.

Collapsed Failed Subtrees

This view of the tree allows the user to show additional information for every node — its label, which usually represents the branching decision made by the solver to move from the parent node to its child. Pressing L on the keyboard will display labels for all descendants of the current node. Shift+L will display labels on the path to the current node. For example, the visualisation above shows branching decisions on the path from the first solution (shown as the new current node) to the root of the tree.

Status bar at the bottom of the window displays node statistics: the depth of the tree and the counts of different types of nodes. The scroll bar on the right lets the user to zoom in/out on the visualisation;

Similar Subtree Analysis

This analysis allows users to find similarities within a single search tree.

It can be initiated by selecting Similar Subtrees from the menu Analyses (shortcut: Shift+S). The image below shows the result of running the analysis on the search tree above. Horizontal bars on the left lists all similarities (patterns) found in the tree. Here, the lengths of the bars indicate are configured to indicate how many subtrees belong to a particular pattern (count). Additionally the bars are sorted so that the patterns with subtrees of larger size appear at the top. Another property of a pattern is its height, which indicates the height/depth of subtrees that the pattern represent.

Note that the second from the top pattern is currently selected (shown with orange outline). The view on the right shows a "preview" (traditional visualisation) of one of the subtrees representing the selected pattern. The two rows below the show the result of computing the difference in labels on the path from the root to two of the subtrees representing the pattern (in this case it is the first two subtrees encountered when the tree is traversed in the depth-first-search order).

Similar Subtrees Summary

Changing the configuration menu at the bottom of the window, the user can filter the list of patterns based on their count and height values. They way the length of horizontal bars is determined and the sorting criteria can also be specified there.

Whenever a pattern on the left hand side is selected, the corresponding subtrees will be highlighted on the traditional visualisation by drawing their . Additionally, if the option Hide not selected is selected (top of the window), the subtrees of t

Similar Subtrees Highlighted

Elimination of subsumed patterns

A pattern P is said to be subsumed by one or more patterns if subtrees of those patterns contain all of the subtrees of P as descendants.

Applying filters.

Should filtered out patterns be allowed to subsume?

cp-profiler-deprecated-'s People

Contributors

cmears avatar eggeek avatar guidotack avatar lokdlok avatar msgmaxim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cp-profiler-deprecated-'s Issues

Native support in Choco3

Hi,

Considering the limited number of files modified in the fork of Choco3 (see cp-profiler/choco3@5002fd1), I was wondering if, instead of a fork, we (Choco3 dev team) could maintain the binding natively within Choco3.
It is only a matter of search monitor (indeed, the SearchLoop doest not need to be modified directly since Choco3 supports search monitors) and a light dedicated project (made of Connector.java and Message.java) seen as a light dependency for us.

I believe you're already thinking about that, since you created java-integration.

Charles

additional data on nodes

That would be great if, when showing info of a node, the depth and it id (global ranking) is also indicated.
For example, when two trees are compared, having such additional info would save me time.

Not able to send correct restart instructions

What should be the instructions sent by a solver to indicate a restart?
I tried the followings (with java-integration):

connector.restart(nbrestarts);

I expected the new branch to be plugged to the ROOT node, but it is collapse to the last created node.

connector.restart(nbrestarts);
pid_stack.clear();
alt_stack.clear();
alt_stack.push(-1); // -1 is alt for the root node
pid_stack.push(-1); // -1 is pid for the root node

It fails. I supposed it comes from the fact that I declared the ROOT node to be made of only one child?
If so, do I have to consider a ROOT node as unbounded-ary decision?

Thanks for your help.

Watching LDS and DDS

Hi,

I want to visualize three resolutions on binary constraints 8-queens problem solved with Choco3, one with a DFS, another with LDS(1) and the last one DDS(2).
DFS is ok; LDS crashes, and I can't figure out why; DDS outputs wrong labels, but I can live with that, since I believe cp-profiler is made for DFS.

I'm pretty sure Choco3 sent wrong information to cp-profiler, but since there is no log file (or I can't find it), so I can't make it works by myself.
Do I have to send some specific node when the discrepancy increases?

Thank you for your help.
FYI, here are the three set of instructions I sent to cp-profiler:

LDS(1) which crashes:

connector.sendNode(0, -1, -1, 2, Connector.NodeStatus.BRANCH, "ROOT", "");
connector.sendNode(1, 0, 0, 2, Connector.NodeStatus.BRANCH, "Q_0 = {1}", "");
connector.sendNode(2, 1, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {3}", "");
connector.sendNode(3, 2, 0, 0, Connector.NodeStatus.FAILED, "Q_2 = {5}", "");
connector.sendNode(4, 0, 1, 2, Connector.NodeStatus.BRANCH, "Q_0 = {1}", "");
connector.sendNode(5, 4, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {3}", "");
connector.sendNode(6, 5, 0, 0, Connector.NodeStatus.FAILED, "Q_2 = {5}", "");
connector.sendNode(7, 5, 1, 2, Connector.NodeStatus.BRANCH, "Q_2 \ {5}", "");
connector.sendNode(8, 7, 0, 2, Connector.NodeStatus.BRANCH, "Q_2 = {6}", "");
connector.sendNode(9, 8, 0, 0, Connector.NodeStatus.FAILED, "Q_3 = {2}", "");
connector.sendNode(10, 5, 1, 2, Connector.NodeStatus.BRANCH, "Q_1 \ {3}", "");
connector.sendNode(11, 10, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {4}", "");
connector.sendNode(12, 11, 0, 2, Connector.NodeStatus.BRANCH, "Q_2 = {2}", "");
connector.sendNode(13, 12, 0, 0, Connector.NodeStatus.FAILED, "Q_3 = {5}", "");
connector.sendNode(14, 10, 1, 2, Connector.NodeStatus.BRANCH, "Q_0 \ {1}", "");
connector.sendNode(15, 14, 0, 2, Connector.NodeStatus.BRANCH, "Q_0 = {2}", "");
connector.sendNode(16, 15, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {4}", "");
connector.sendNode(17, 16, 0, 2, Connector.NodeStatus.BRANCH, "Q_2 = {1}", "");
connector.sendNode(18, 17, 0, 0, Connector.NodeStatus.FAILED, "Q_3 = {3}", "");

DDS(2) which outputs wrong labels:

connector.sendNode(0, -1, -1, 2, Connector.NodeStatus.BRANCH, "ROOT", "");
connector.sendNode(1, 0, 0, 2, Connector.NodeStatus.BRANCH, "Q_0 = {1}", "");
connector.sendNode(2, 1, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {3}", "");
connector.sendNode(3, 2, 0, 0, Connector.NodeStatus.FAILED, "Q_2 = {5}", "");
connector.sendNode(4, 0, 1, 2, Connector.NodeStatus.BRANCH, "Q_0 \ {1}", "");
connector.sendNode(5, 4, 0, 2, Connector.NodeStatus.BRANCH, "Q_0 = {2}", "");
connector.sendNode(6, 5, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {4}", "");
connector.sendNode(7, 6, 0, 2, Connector.NodeStatus.BRANCH, "Q_2 = {1}", "");
connector.sendNode(8, 7, 0, 0, Connector.NodeStatus.FAILED, "Q_3 = {3}", "");
connector.sendNode(9, 4, 1, 2, Connector.NodeStatus.BRANCH, "Q_0 = {1}", "");
connector.sendNode(10, 9, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 \ {3}", "");
connector.sendNode(11, 10, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {4}", "");
connector.sendNode(12, 11, 0, 2, Connector.NodeStatus.BRANCH, "Q_2 = {2}", "");
connector.sendNode(13, 12, 0, 0, Connector.NodeStatus.FAILED, "Q_3 = {5}", "");
connector.sendNode(14, 10, 1, 2, Connector.NodeStatus.BRANCH, "Q_0 \ {1}", "");
connector.sendNode(15, 14, 0, 2, Connector.NodeStatus.BRANCH, "Q_0 \ {2}", "");
connector.sendNode(16, 15, 0, 2, Connector.NodeStatus.BRANCH, "Q_0 = {3}", "");
connector.sendNode(17, 16, 0, 2, Connector.NodeStatus.BRANCH, "Q_1 = {1}", "");
connector.sendNode(18, 17, 0, 2, Connector.NodeStatus.BRANCH, "Q_2 = {4}", "");
connector.sendNode(19, 18, 0, 0, Connector.NodeStatus.FAILED, "Q_3 = {2}", "");

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.