diff --git a/src/main/java/syscamstranslator/SysCAMSSpecification.java b/src/main/java/syscamstranslator/SysCAMSSpecification.java index 7349f34aea5ade84becaed193536851659fd2fea..4c4f1e747106a16238d99000aee158677b99ce9b 100644 --- a/src/main/java/syscamstranslator/SysCAMSSpecification.java +++ b/src/main/java/syscamstranslator/SysCAMSSpecification.java @@ -170,6 +170,18 @@ public class SysCAMSSpecification{ } return cons; } + + public LinkedList<SysCAMSTConnector> getAllConnectorsCluster4Matrix(){ + LinkedList<SysCAMSTConnector> cons = new LinkedList<SysCAMSTConnector>(); + for (SysCAMSTConnector con : connectors) { + if (con instanceof SysCAMSTConnector) { + if (con.get_p1().getComponent() instanceof SysCAMSTPortTDF && con.get_p2().getComponent() instanceof SysCAMSTPortTDF) { + cons.add(con); + } + } + } + return cons; + } public int getNbBlockTDF(){ return (getAllBlockTDF()).size(); @@ -198,4 +210,4 @@ public class SysCAMSSpecification{ public int getNbConnectorCluster(){ return (getAllConnectorCluster()).size(); } -} \ No newline at end of file +} diff --git a/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java b/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java index 65cff7cbf0d9557cedd4c65fb1e722a97f346d4e..f773138e5eaf9bc7623c5087103e099c91f64abd 100644 --- a/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java +++ b/src/main/java/syscamstranslator/SysCAMSTBlockTDF.java @@ -64,6 +64,8 @@ public class SysCAMSTBlockTDF extends SysCAMSTComponent { private LinkedList<SysCAMSTPortTDF> portTDF; private LinkedList<SysCAMSTPortConverter> portConverter; + private SysCAMSTPortConverter localPortConverter; + private int n; public SysCAMSTBlockTDF(String _name, int _period, String _time, String _processCode, DefaultListModel<String> _listStruct, String _nameTemplate, String _typeTemplate, DefaultListModel<String> _listTypedef, SysCAMSTCluster _cluster) { name = _name; @@ -77,6 +79,7 @@ public class SysCAMSTBlockTDF extends SysCAMSTComponent { cluster = _cluster; portTDF = new LinkedList<SysCAMSTPortTDF>(); portConverter = new LinkedList<SysCAMSTPortConverter>(); + n = 0; } public String getName() { @@ -130,4 +133,116 @@ public class SysCAMSTBlockTDF extends SysCAMSTComponent { public void addPortConverter(SysCAMSTPortConverter converter){ portConverter.add(converter); } -} \ No newline at end of file + + public void syncTDFBlockDEBlock(double[] time_prev) throws SysCAMSValidateException { + double tp; + try{ + for(int i = 0; i < portConverter.size(); i++) { + localPortConverter = portConverter.get(i); + if(localPortConverter.getOrigin() == 0) { //Input + check_causality_in(time_prev); + } else if (localPortConverter.getOrigin() == 1) { //Output + check_causality_out(time_prev); + } + } + } catch (SysCAMSValidateException se){ + throw new SysCAMSValidateException(se.getMessage()); + } + } + + private void check_causality_in(double[] time_prev_max) throws SysCAMSValidateException { + double time_now_min_tdf, time_now_max_tdf, time_tmp_tdf, time_tmp_de, + time_now_min_de, time_now_max_de; + double tm = 0.0; + double tp = 0.0; + int r = 0; + int d = 0; + int k = 1; + if(period > 0) + tm = period; + if(localPortConverter.getPeriod() > 0) + tp = localPortConverter.getPeriod(); + if(localPortConverter.getRate() > 0) + r = localPortConverter.getRate(); + if(localPortConverter.getDelay() > 0) + d = localPortConverter.getDelay(); + + time_now_min_tdf = (n*tm)+((k-1)*tp); + time_now_max_tdf = (n*tm)+((k-1)*tp); + time_now_min_de = (n*tm)+((k-1)*tp)-(d*tp); + time_now_max_de = (n*tm)+((k-1)*tp)-(d*tp); + + for (k = 1; k <= r; k++) { + time_tmp_tdf = (n*tm)+((k-1)*tp); + time_tmp_de = (n*tm)+((k-1)*tp)-(d*tp); + System.out.println("tmstmp_in_tdf: " + time_tmp_tdf); + System.out.println("tmstmp_in_de: " + time_tmp_de); + time_now_min_tdf = Math.min(time_tmp_tdf, time_now_min_tdf); + time_now_max_tdf = Math.max(time_tmp_tdf, time_now_max_tdf); + time_now_min_de = Math.min(time_tmp_de, time_now_min_de); + time_now_max_de = Math.max(time_tmp_de, time_now_max_de); + System.out.println("time_now_min_de: " + time_now_min_de); + System.out.println("time_now_max_de: " + time_now_max_de); + System.out.println("time_now_min_tdf: " + time_now_min_tdf); + System.out.println("time_now_max_tdf: " + time_now_max_tdf); + } + //Increase number of times block has been executed + n++; + + System.out.println("time_prev_max_out: " + time_prev_max[1]); + if(time_now_min_de < time_prev_max[1]) { + throw new SysCAMSValidateException("Timestamp of previous write port executed module is: " + time_prev_max[1] + + " and current timestamp is: " + time_now_min_de); + } + time_prev_max[0] = Double.valueOf(Math.max(time_prev_max[0],time_now_max_de)); + System.out.println("New time_prev_max_in: " + time_prev_max[0]); + } + + private void check_causality_out(double[] time_prev_max) throws SysCAMSValidateException { + double time_now_min_tdf, time_now_max_tdf, time_tmp_tdf, time_tmp_de, + time_now_min_de, time_now_max_de; + double tm = 0.0; + double tp = 0.0; + int r = 0; + int d = 0; + int k = 1; + if(period > 0) + tm = period; + if(localPortConverter.getPeriod() > 0) + tp = localPortConverter.getPeriod(); + if(localPortConverter.getRate() > 0) + r = localPortConverter.getRate(); + if(localPortConverter.getDelay() > 0) + d = localPortConverter.getDelay(); + + time_now_min_tdf = (n*tm)+((k-1)*tp); + time_now_max_tdf = (n*tm)+((k-1)*tp); + time_now_min_de = (n*tm)+((k-1)*tp)+(d*tp); + time_now_max_de = (n*tm)+((k-1)*tp)+(d*tp); + + for (k = 1; k <= r; k++) { + time_tmp_tdf = (n*tm)+((k-1)*tp); + time_tmp_de = (n*tm)+((k-1)*tp)+(d*tp);; + System.out.println("tmstmp_in_tdf: " + time_tmp_tdf); + System.out.println("tmstmp_in_de: " + time_tmp_de); + time_now_min_tdf = Math.min(time_tmp_tdf, time_now_min_tdf); + time_now_max_tdf = Math.max(time_tmp_tdf, time_now_max_tdf); + time_now_min_de = Math.min(time_tmp_de, time_now_min_de); + time_now_max_de = Math.max(time_tmp_de, time_now_max_de); + System.out.println("time_now_min_de: " + time_now_min_de); + System.out.println("time_now_max_de: " + time_now_max_de); + System.out.println("time_now_min_tdf: " + time_now_min_tdf); + System.out.println("time_now_max_tdf: " + time_now_max_tdf); + } + //Increase number of times block has been executed + n++; + + System.out.println("time_prev_max_in: " + time_prev_max[0]); + if(time_now_min_de < time_prev_max[0]) { + throw new SysCAMSValidateException("Timestamp of previous read port executed module is: " + time_prev_max[0] + + " and current timestamp is: " + time_now_min_de); + } + time_prev_max[1] = Double.valueOf(Math.max(time_prev_max[1],time_now_max_tdf)); + System.out.println("New time_prev_max_out: " + time_prev_max[1]); + } +} diff --git a/src/main/java/syscamstranslator/SysCAMSValidateException.java b/src/main/java/syscamstranslator/SysCAMSValidateException.java new file mode 100644 index 0000000000000000000000000000000000000000..5784ed79562a6e522aa07af615c6660f16fd2bf5 --- /dev/null +++ b/src/main/java/syscamstranslator/SysCAMSValidateException.java @@ -0,0 +1,61 @@ +/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille + * + * ludovic.apvrille AT enst.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + */ + + + + +package syscamstranslator; + + +/** + * Class SysCAMSValidateException + * Creation: 14/08/2018 + * version 1.0 14/08/2018 + * @author Rodrigo CORTES PORTO + */ +public class SysCAMSValidateException extends Exception { + + public SysCAMSValidateException() { + super("SysC-AMS diagram validation exception"); + } + + public SysCAMSValidateException(String msg) { + super(msg); + } + +} // Class diff --git a/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java b/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java index fecbe00e61221b3531c882dac320f11bff83148c..d76cc5ddced8e6a5e6c42ab8811f6c334c9c1717 100644 --- a/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java +++ b/src/main/java/syscamstranslator/toSysCAMSCluster/ClusterCode.java @@ -38,11 +38,6 @@ * knowledge of the CeCILL license and that you accept its terms. */ -/* this class produces the lines containing essentially the initial #includes; we include all potential components event if they are not used in the deployment diagram*/ - -/* authors: v1.0 Raja GATGOUT 2014 - v2.0 Daniela GENIUS, Julien HENON 2015 */ - package syscamstranslator.toSysCAMSCluster; import java.util.LinkedList; @@ -51,10 +46,10 @@ import syscamstranslator.*; /** * Class ClusterCode - * Principal code of a cluster component - * Creation: 14/05/2018 - * @version 1.0 14/05/2018 - * @author Irina Kit Yan LEE + * Principal code of a cluster component that wraps all AMS components. + * Creation: 30/07/2018 + * @version 1.0 30/07/2018 + * @author Rodrigo CORTES PORTO */ public class ClusterCode { diff --git a/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java b/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java index e20067c572810432d38976ffbbc4937bb58b0fac..ba78e5bef3624f1f90758ac40c9980548a811366 100644 --- a/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java +++ b/src/main/java/syscamstranslator/toSysCAMSCluster/Header.java @@ -38,11 +38,6 @@ * knowledge of the CeCILL license and that you accept its terms. */ -/* this class produces the lines containing essentially the initial #includes; we include all potential components event if they are not used in the deployment diagram*/ - -/* authors: v1.0 Raja GATGOUT 2014 - v2.0 Daniela GENIUS, Julien HENON 2015 */ - package syscamstranslator.toSysCAMSCluster; import java.util.LinkedList; @@ -55,6 +50,8 @@ import syscamstranslator.*; * Creation: 14/05/2018 * @version 1.0 14/05/2018 * @author Irina Kit Yan LEE + * @version 1.1 30/07/2018 + * @author Rodrigo CORTES PORTO */ public class Header { diff --git a/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java b/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java index fb6dfac0f64f7c2dd58ddca199583db859cc9088..7d469baeba8320cd6b0cbf31a5880cba1a678e48 100644 --- a/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java +++ b/src/main/java/syscamstranslator/toSysCAMSCluster/TopCellGeneratorCluster.java @@ -56,6 +56,8 @@ import java.util.LinkedList; * Creation: 14/05/2018 * @version 1.0 14/05/2018 * @author Irina Kit Yan LEE + * @version 1.1 30/07/2018 + * @author Rodrigo CORTES PORTO */ public class TopCellGeneratorCluster { diff --git a/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java b/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java index f207d6f395a9c05fb21eff76568ba63c633e127a..2782a23bfbc734222be2ccf1393e095ea88586c8 100644 --- a/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java +++ b/src/main/java/ui/window/JDialogSysCAMSExecutableCodeGeneration.java @@ -44,12 +44,14 @@ import syscamstranslator.toSysCAMSCluster.TopCellGeneratorCluster; import launcher.LauncherException; import launcher.RshClient; import myutil.*; -import syscamstranslator.SysCAMSSpecification; -import syscamstranslator.SysCAMSTCluster; +import syscamstranslator.*; import ui.util.IconManager; import ui.MainGUI; import ui.SysCAMSPanelTranslator; import ui.syscams.SysCAMSComponentTaskDiagramPanel; +import org.apache.commons.math3.linear.*; +import org.apache.commons.math3.util.*; +import org.apache.commons.math3.fraction.*; import javax.swing.*; import java.awt.*; @@ -60,6 +62,7 @@ import java.io.StringWriter; import java.io.Writer; import java.util.LinkedList; import java.util.Vector; +import java.util.Arrays; /** * Class JDialogSysCAMSExecutableCodeGeneration @@ -130,7 +133,7 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i private Thread t; private boolean go = false; -// private boolean hasError = false; + private boolean hasError = false; protected boolean startProcess = false; // private String hostExecute; @@ -178,31 +181,33 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i // Issue #41 Ordering of tabbed panes jp1 = GraphicLib.createTabbedPane();//new JTabbedPane(); - + + JPanel jp00 = new JPanel(); + GridBagLayout gridbag00 = new GridBagLayout(); + GridBagConstraints c00 = new GridBagConstraints(); + jp00.setLayout(gridbag00); + jp00.setBorder(new javax.swing.border.TitledBorder("Validation")); + JPanel jp01 = new JPanel(); GridBagLayout gridbag01 = new GridBagLayout(); GridBagConstraints c01 = new GridBagConstraints(); jp01.setLayout(gridbag01); jp01.setBorder(new javax.swing.border.TitledBorder("Code generation")); + + // Panel 00 -> Validation + c00.gridheight = 1; + c00.weighty = 1.0; + c00.weightx = 1.0; + c00.gridwidth = GridBagConstraints.REMAINDER; //end row + c00.fill = GridBagConstraints.BOTH; + c00.gridheight = 1; -// JPanel jp02 = new JPanel(); -// GridBagLayout gridbag02 = new GridBagLayout(); -// GridBagConstraints c02 = new GridBagConstraints(); -// jp02.setLayout(gridbag02); -// jp02.setBorder(new javax.swing.border.TitledBorder("Compilation")); -// -// JPanel jp03 = new JPanel(); -// GridBagLayout gridbag03 = new GridBagLayout(); -// GridBagConstraints c03 = new GridBagConstraints(); -// jp03.setLayout(gridbag03); -// jp03.setBorder(new javax.swing.border.TitledBorder("Execution")); -// -// JPanel jp04 = new JPanel(); -// GridBagLayout gridbag04 = new GridBagLayout(); -// GridBagConstraints c04 = new GridBagConstraints(); -// jp04.setLayout(gridbag04); -// jp04.setBorder(new javax.swing.border.TitledBorder("Simulation trace")); + jp00.add(new JLabel(" "), c00); + c00.gridwidth = GridBagConstraints.REMAINDER; //end row + jp1.add("Validation", jp00); + + // Panel 01 -> Code Generation c01.gridheight = 1; c01.weighty = 1.0; c01.weightx = 1.0; @@ -229,7 +234,7 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i jp01.add(code3, c01); jp01.add(new JLabel(" "), c01); - c01.gridwidth = GridBagConstraints.REMAINDER; //end row + //c01.gridwidth = GridBagConstraints.REMAINDER; //end row // removeCFiles = new JCheckBox("Remove .c / .h files"); // removeCFiles.setSelected(removeCFilesValue); @@ -371,7 +376,7 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i jta.setEditable(false); jta.setMargin(new Insets(10, 10, 10, 10)); jta.setTabSize(3); - jta.append("Select options and then, click on 'start' to launch code generation\n"); // / compilation / execution + jta.append("Select options and then, click on 'start' to launch validation / code generation\n"); // / compilation / execution Font f = new Font("Courrier", Font.BOLD, 12); jta.setFont(f); jsp = new JScrollPane(jta, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); @@ -500,10 +505,55 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i public void run() { // String cmd; // String list;//, data; -// hasError = false; + hasError = false; try { if (jp1.getSelectedIndex() == 0) { + Vector<SysCAMSComponentTaskDiagramPanel> syscamsDiagramPanels = mgui.getListSysCAMSPanel(); + for (SysCAMSComponentTaskDiagramPanel syscamsDiagramPanel : syscamsDiagramPanels) { + SysCAMSPanelTranslator syscamspaneltranslator = new SysCAMSPanelTranslator(syscamsDiagramPanel); + SysCAMSSpecification syscalsspec = syscamspaneltranslator.getSysCAMSSpecification(); + if (syscalsspec == null) { + jta.append("Error: No SYSCAMS specification\n"); + } else { + jta.append("Performing Validation for \""+(syscalsspec.getCluster()).getClusterName()+"\".\n"); + LinkedList<SysCAMSTConnector> connectors = syscalsspec.getAllConnectorsCluster4Matrix(); + System.out.printf("Connectors for 1 cluster = %d.\n", connectors.size()); + LinkedList<SysCAMSTBlockTDF> tdfBlocks = syscalsspec.getAllBlockTDF(); + System.out.printf("Blocks for 1 cluster = %d.\n", tdfBlocks.size()); + //TODO: verify trivial case when only 1 block and no connectors. + if(connectors.size() > 0) { + RealVector buffer = new ArrayRealVector(connectors.size()); + RealVectorFormat printFormat = new RealVectorFormat(); + RealMatrix topologyMatrix = buildTopologyMatrix(connectors, tdfBlocks, buffer); + System.out.println("Buffer after topMatrix is: " + printFormat.format(buffer) ); + try { + RealVector execRate = solveTopologyMatrix(topologyMatrix, tdfBlocks); + //TODO: to recompute, put a while loop here with a flag. Check after compute if no error. If error, modify buffer with the suggested delay, and loop. + computeSchedule(execRate, topologyMatrix, buffer, tdfBlocks, connectors); + jta.append("Validation for \""+(syscalsspec.getCluster()).getClusterName()+"\" completed.\n"); + } catch (InterruptedException ie) { + System.err.println("Interrupted"); + jta.append("Interrupted\n"); + mode = STOPPED; + setButtons(); + hasError = true; + //return; + } catch (Exception e) { + e.printStackTrace(); + mode = STOPPED; + setButtons(); + hasError = true; + return; + } + } + } + } + } + + testGo(); + + if (jp1.getSelectedIndex() == 1) { jta.append("Generating executable code (SystemC-AMS version)\n"); Vector<SysCAMSComponentTaskDiagramPanel> syscamsDiagramPanels = mgui.getListSysCAMSPanel(); @@ -675,17 +725,18 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i // return; // } // } -// if ((hasError == false) && (jp1.getSelectedIndex() < 2)) { -// jp1.setSelectedIndex(jp1.getSelectedIndex() + 1); -// } + if ((hasError == false) && (jp1.getSelectedIndex() < 2)) { + jp1.setSelectedIndex(jp1.getSelectedIndex() + 1); + } } catch (InterruptedException ie) { jta.append("Interrupted\n"); } + if (!hasError) { + jta.append("\n\nReady to process next command\n"); - jta.append("\n\nReady to process next command\n"); - - checkMode(); - setButtons(); + checkMode(); + setButtons(); + } } protected void processCmd(String cmd, JTextArea _jta) throws LauncherException { @@ -739,6 +790,135 @@ public class JDialogSysCAMSExecutableCodeGeneration extends javax.swing.JFrame i // hasError = true; } + public RealMatrix buildTopologyMatrix(LinkedList<SysCAMSTConnector> connectors, LinkedList<SysCAMSTBlockTDF> blocks, RealVector buffer) { + double [][] tArray = new double[connectors.size()][blocks.size()]; + for(int i = 0; i < connectors.size(); i++) { + for(int j = 0; j < blocks.size(); j++) { + if( ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getBlockTDF().getName().equals(blocks.get(j).getName()) ) { + System.out.println("Inserting in : "+ i + " " + j + " From port: "+ ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getName() +" Rate: " + ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getRate() ); + tArray[i][j] = ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getRate(); + if(((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getDelay() > 0) { + buffer.addToEntry(i, ((SysCAMSTPortTDF) connectors.get(i).get_p1().getComponent()).getDelay() ); + } + } else if( ((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getBlockTDF().getName().equals(blocks.get(j).getName()) ) { + System.out.println("Inserting in : "+ i + " " + j + " From port: "+ ((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getName() +" Rate: " + -((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getRate() ); + tArray[i][j] = -((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getRate(); + if(((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getDelay() > 0) { + buffer.addToEntry(i, ((SysCAMSTPortTDF) connectors.get(i).get_p2().getComponent()).getDelay() ); + } + } + } + } + + //double[][] tArray = { { 2, -1, 0 }, { 0, 2, -4 }, { -1, 0, 1 } }; + //double[][] tArray = { { 2, 3, 5 }, { -4, 2, 3} }; + //double[][] tArray = { { 3, -2, 0, 0 }, { 0, 4, 0, -3 }, { 0, 1, -3, 0 }, { -1, 0, 2, 0 }, { -2, 0, 0, 1 } }; + //double[][] tArray = { { 3, -2 } }; + RealMatrix tMatrix = new Array2DRowRealMatrix(tArray); + return tMatrix; + } + + public RealVector solveTopologyMatrix(RealMatrix matrixA, LinkedList<SysCAMSTBlockTDF> blocks) throws InterruptedException { + double dropThreshold = 1e-7; + //Using QR decomposition, A^TP=QR. Since rank MUST be rank = s-1 + //(where s is number of blocks), then the last column of Q provides a basis for the kernel of A. + RRQRDecomposition qr = new RRQRDecomposition(matrixA.transpose()); + RealMatrix qMatrix = qr.getQ(); + int rank = qr.getRank(dropThreshold); + if(rank != blocks.size()-1){ + jta.append("Error: Port sample rates are inconsistent. Topology matrix can not be solved.\n"); + System.err.println("Port sample rates are inconsistent. Topology matrix can not be solved. Rank: " +rank+" != #blocks-1"); + throw new InterruptedException(); + } + System.out.println("Checking kernel columns ..."); + RealMatrix zMatrix = matrixA.multiply(qMatrix); + for (int c = rank; c < matrixA.getColumnDimension(); c++) { + System.out.printf("The product of A with column %d of Q has sup " + + "norm %f.\n", + c, zMatrix.getColumnMatrix(c).getNorm()); + //TODO: verify if norm is not zero, throw error that kernel could not be found. + } + + RealMatrix kernelMatrix = qMatrix.getSubMatrix( 0, qMatrix.getRowDimension()-1, rank, qMatrix.getColumnDimension()-1 ); + double[] resultArray = new double[kernelMatrix.getRowDimension()]; + double result_tmp = 0.0; + int v_lcm = 1; + Fraction[] resultFractionArray = new Fraction[kernelMatrix.getRowDimension()]; + for (int i = 0; i < kernelMatrix.getRowDimension(); i++) { + System.out.printf("The kernelMatrix is %f .\n", kernelMatrix.getEntry(i, 0) ); + resultArray[i] = kernelMatrix.getEntry(i, 0) / kernelMatrix.getEntry(kernelMatrix.getRowDimension()-1, 0); + result_tmp = kernelMatrix.getEntry(i, 0) / kernelMatrix.getEntry(kernelMatrix.getRowDimension()-1, 0); + resultFractionArray[i] = new Fraction(result_tmp); + System.out.println("The resultArray is: "+ resultArray[i] ); + System.out.println("The resultFractionArray is: "+ resultFractionArray[i].toString() ); + v_lcm = ArithmeticUtils.lcm(resultFractionArray[i].getDenominator() , v_lcm); + System.out.println("The lcm is: "+ v_lcm ); + } + int[] tmpResult = new int[kernelMatrix.getRowDimension()]; + double[] finalResult = new double[kernelMatrix.getRowDimension()]; + for (int i = 0; i < kernelMatrix.getRowDimension(); i++) { + tmpResult[i] = (resultFractionArray[i].multiply(v_lcm)).intValue(); + finalResult[i] = (double)tmpResult[i]; + System.out.println("The finalResult is: "+ finalResult[i] + " - " + blocks.get(i).getName() ); + } + RealVector xVector = new ArrayRealVector(finalResult); + return xVector; + } + + public void computeSchedule(RealVector q, RealMatrix gamma, RealVector buffer, LinkedList<SysCAMSTBlockTDF> tdfBlocks, LinkedList<SysCAMSTConnector> connectors) throws InterruptedException { + RealVector q1 = new ArrayRealVector(q.getDimension()); + RealVector nu = new ArrayRealVector(q.getDimension()); + RealVector tmpBuffer = new ArrayRealVector(gamma.getRowDimension());; + RealVectorFormat printFormat = new RealVectorFormat(); + boolean deadlock = false; + SysCAMSTBlockTDF tdfBlock; + double[] time_prev = {0.0, 0.0}; //array to store in[0] and out[1] previous times + try { + while (!(q1.equals(q)) && !deadlock){ + deadlock = true; + for(int i = 0; i < tdfBlocks.size(); i++) { + tdfBlock = tdfBlocks.get(i); + //check if block is runnable: If it has not run q times + //and it won't cause a buffer size to go negative. + System.out.println("q1 is: " + printFormat.format(q1) ); + System.out.println("q is: " + printFormat.format(q) ); + if(q1.getEntry(i) != q.getEntry(i)) { + nu.setEntry(i, 1); + tmpBuffer = buffer.add(gamma.operate(nu)); + System.out.println("tmpBuffer is: " + printFormat.format(tmpBuffer) ); + if(tmpBuffer.getMinValue() >= 0) { + deadlock = false; + q1 = q1.add(nu); + buffer = tmpBuffer.copy(); + System.out.println("Schedule " + tdfBlock.getName() ); + System.out.println("Buffer is: " + printFormat.format(buffer) ); + //Validate sync bewtween TDF/DE + tdfBlock.syncTDFBlockDEBlock(time_prev); + } + nu.setEntry(i, 0); + } + } + } + } catch (SysCAMSValidateException se) { + System.out.println("Causality exception: " + se.getMessage()); + } + if (deadlock){ + System.out.println("Static schedule can not be computed due to missing delays in loops" ); + jta.append("Error: Static schedule can not be computed due to missing delays in loops\n" ); + int minIndex = tmpBuffer.getMinIndex(); + //TODO: for the suggested delay, I need to first detect loops within the graph(DFS?), then recompute recursively with the suggested delay until it can be solved. + /*jta.append("Following delay is suggested:\n" ); + int currentDelay = ((SysCAMSTPortTDF) connectors.get(minIndex).get_p2().getComponent()).getDelay(); + jta.append(currentDelay-(int)tmpBuffer.getMinValue() +" in port \"" + +((SysCAMSTPortTDF) connectors.get(minIndex).get_p2().getComponent()).getName() + +"\" from block \""+ ((SysCAMSTPortTDF) connectors.get(minIndex).get_p2().getComponent()).getBlockTDF().getName()+"\"\n"); + */ + throw new InterruptedException(); + } else { + System.out.println("Schedule complete-STOP" ); + } + } + // public void showSimulationTrace() { // JFrameSimulationSDPanel jfssdp = new JFrameSimulationSDPanel(f, mgui, "Simulation trace of " + simulationTraceFile.getText()); // jfssdp.setIconImage(IconManager.img8);