source: sources/src/schedulers.cc @ 61

Last change on this file since 61 was 61, checked in by meunier, 7 years ago
  • Fixing include of openmp (still not functional as regarding of the compilation)
File size: 10.9 KB
Line 
1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                 schedulers.cc                     |
6|                                                             |
7| Author  :                 Buchmann Richard                  |
8|                           Nicolas Pouillon                  |
9|                                                             |
10| Date    :                   23_03_2007                      |
11|                                                             |
12\------------------------------------------------------------*/
13
14/*
15 * This file is part of the Disydent Project
16 * Copyright (C) Laboratoire LIP6 - Département ASIM
17 * Universite Pierre et Marie Curie
18 *
19 * Home page          : http://www-asim.lip6.fr/disydent
20 * E-mail             : mailto:richard.buchmann@lip6.fr
21 *
22 * This library is free software; you  can redistribute it and/or modify it
23 * under the terms  of the GNU Library General Public  License as published
24 * by the Free Software Foundation; either version 2 of the License, or (at
25 * your option) any later version.
26 *
27 * Disydent is distributed  in the hope  that it  will be
28 * useful, but WITHOUT  ANY WARRANTY; without even the  implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
30 * Public License for more details.
31 *
32 * You should have received a copy  of the GNU General Public License along
33 * with the GNU C Library; see the  file COPYING. If not, write to the Free
34 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36
37#include <cstdio>
38#include <cassert>
39#include <iostream>
40#include <algorithm> //std::sort
41
42#include "sc_module.h" // method_process_t
43#include "gen_code.h"  // gen_scheduling_code_for_dynamic_link & gen_scheduling_code_for_static_func
44#include "internal.h"  // dump_all_graph
45#include "graph_cass.h" // makegraph
46#include "process_dependency.h" // MakeProcessDependencyList
47#include "signal_dependency.h" // MakeSignalDependencyGraph
48#include "mouchard_scheduling.h" // MakeMouchardScheduling
49#include "graph_signals.h" // makegraph
50
51#ifdef USE_OPENMP
52    #include <omp.h>
53#endif
54
55#ifdef HAVE_CONFIG_H
56#include "config.h"
57#endif
58
59using namespace std;
60
61namespace sc_core {
62
63// sort_functions splits and sorts instances_list into three functions lists :
64method_process_list_t * transition_func_list;
65method_process_list_t * moore_func_list;
66#pragma omp threadprivate(transition_func_list, moore_func_list)
67method_process_list_t combinational_func_list;
68/* ***************************** */
69/* Dumping functions (for debug) */
70/* ***************************** */
71
72template <typename T>
73ostream & operator << (ostream & o, const vector<T*> & v) {
74    typename vector<T *>::const_iterator i;
75    for (i = v.begin(); i != v.end(); ++i) {
76        o << **i << " ";
77    }
78    return o;
79}
80
81/* ************ */
82/*  functions   */
83/****************/
84
85
86
87static bool sort_by_module_ptr (const method_process_t * a1, const method_process_t * a2) {
88    assert(a1 != NULL);
89    assert(a2 != NULL);
90    return (a1->module < a2->module);
91}
92
93
94static bool sort_by_fct_ptr (const method_process_t * a1, const method_process_t * a2) {
95    assert(a1 != NULL);
96    assert(a2 != NULL);
97    union {
98        SC_ENTRY_FUNC func;
99        unsigned long addr_l;
100        unsigned long long addr_ll;
101    } addr1, addr2;
102
103    addr1.func = a1->func;
104    addr2.func = a2->func;
105   
106    if (a1->func == a2->func) {
107        return sort_by_module_ptr(a1,a2);
108    }
109
110    if (sizeof(SC_ENTRY_FUNC) == 4 ) {
111        return (addr1.addr_l < addr2.addr_l);
112    }
113    else {
114        return (addr1.addr_ll < addr2.addr_ll);
115    }
116}
117
118
119
120void sort_functions() {
121    method_process_list_t::const_iterator m;
122#pragma omp parallel
123#pragma omp critical
124    {
125        transition_func_list = new method_process_list_t;
126        moore_func_list = new method_process_list_t;
127        for (m = method_process_list.begin(); m != method_process_list.end(); ++m) {
128#ifdef _OPENMP
129            if ((*m)->omp_threadnum == omp_get_thread_num())
130#endif
131            {
132                if ((*m)->is_transition()) {
133                    transition_func_list->push_back(*m);
134                }
135                else if ((*m)->is_genmoore()) {
136                    moore_func_list->push_back(*m);
137                }
138            }
139        }
140        // Sort transition functions by method pointer (1) and by module pointer (2)
141        std::sort(transition_func_list->begin(), transition_func_list->end(), sort_by_fct_ptr);
142        // Sort generation functions by method pointer (1) and by module pointer (2)
143        std::sort(moore_func_list->begin(), moore_func_list->end(), sort_by_fct_ptr);
144    }
145
146    for (m = method_process_list.begin(); m != method_process_list.end(); ++m) {
147        if ((*m)->is_combinational()) {
148            combinational_func_list.push_back(*m);
149        }
150    }
151}
152
153/* ****************** */
154/* process dependency */
155/* ****************** */
156
157static SignalDependencyGraph * MakeAcyclicSignalDependencyGraph() {
158    if (dump_all_graph) {
159        const PortDependencyGraph & port_graph = get_port_dependency_graph ();
160        PortDependencyGraph2dot ("port_graph", port_graph);
161    }
162
163    SignalDependencyGraph * sig_graph = MakeSignalDependencyGraph();
164
165    if (dump_all_graph) {
166        SignalDependencyGraph2dot ("signal_graph",*sig_graph);
167    }
168
169    if (!Check(*sig_graph)) {
170        cerr << "The signal dependency graph is not valid.\n";
171        exit (29092004);
172    }
173
174    if (!Check(method_process_list, *sig_graph)) {
175        cerr << "Sensitivity list is not valid.\n";
176        exit (30092004);
177    }
178
179    // There is a cycle in the signal dependency graph ?
180    Graph * sig_knuth = makegraph(*sig_graph);
181    strong_component_list_t * s = strong_component(sig_knuth);
182
183    if (dump_all_graph) {
184        SignalDependencyOrder2txt("signal_order",*s);
185    }
186
187    if (has_cycle(*s)) {
188        cerr << "Error : There is a cycle in the signal dependency graph.\n";
189        exit (24092004);
190    }
191    return sig_graph;
192}
193
194
195static ProcessDependencyList * MouchardScheduling() {
196    SignalDependencyGraph * sig_graph = MakeAcyclicSignalDependencyGraph();
197    assert(sig_graph != NULL);
198    // Create the process evaluation list
199    ProcessDependencyList * process_list = MakeMouchardScheduling(*sig_graph);
200    assert(process_list != NULL);
201
202    if (dump_all_graph) {
203        ProcessDependencyList2dot  ("process_order", *process_list);
204    }
205
206    return process_list;
207}
208
209
210static ProcessDependencyList * BuchmannScheduling() {
211    SignalDependencyGraph * sig_graph = MakeAcyclicSignalDependencyGraph();
212    // Create the process evaluation list
213    ProcessDependencyList * process_list = MakeProcessDependencyList(*sig_graph);
214
215    if (dump_all_graph) {
216        ProcessDependencyList2dot("process_order", *process_list);
217    }
218
219    return process_list;
220}
221
222
223string get_scheduling(int scheduling_method) {
224    string base_name;
225    /* marque les fonctions comme fonction de mealy ou non */
226    if (dump_funclist_info) {
227        cerr << "method process list : " << method_process_list << "\n";
228    }
229
230    sort_functions();
231#pragma omp parallel
232#pragma omp critical
233    {
234        if (dump_funclist_info) {
235#ifdef _OPENMP
236            cerr << "Thread " << omp_get_thread_num() << "\n";
237#endif
238            cerr << "  Transition functions : " << *transition_func_list << "\n";
239            cerr << "  Moore generation functions : " << *moore_func_list << "\n";
240#pragma omp master
241            {
242                if (!combinational_func_list.empty()) {
243                    cerr << "Mealy generation functions : " << combinational_func_list << "\n";
244                }
245            }
246        }
247
248    /* Schedule */
249    switch (scheduling_method) {
250        case BUCHMANN_SCHEDULING :
251        {
252            // Generate the scheduled code, compile and link.
253            // Buchmann's thesis explains this scheduling method.
254            // Uses port dependancies like Dr. Mouchard.
255            ProcessDependencyList * process_list = BuchmannScheduling();
256            if (dynamic_link_of_scheduling_code) {
257                base_name = gen_scheduling_code_for_dynamic_link(*transition_func_list, *moore_func_list, *process_list);
258            }
259            else {
260                gen_scheduling_code_for_static_func(*transition_func_list, *moore_func_list, *process_list);
261            }
262            break;
263        }
264
265        case MOUCHARD_SCHEDULING :
266        {
267            // Generate the scheduled code, compile and link.
268            // Mouchard's thesis explains this scheduling method.
269            // Uses port dependancies like Dr. Mouchard.
270            // CAUTION : unlike FastSysC, this scheduling is totally static
271            // and does not use an event-driven scheduler.
272            ProcessDependencyList * process_list = MouchardScheduling();
273            if (dynamic_link_of_scheduling_code) {
274                base_name = gen_scheduling_code_for_dynamic_link(*transition_func_list, *moore_func_list, *process_list);
275            }
276            else {
277                gen_scheduling_code_for_static_func (*transition_func_list, *moore_func_list, *process_list);
278            }
279            break;
280        }
281
282        case CASS_SCHEDULING :
283        {
284            // Generate the scheduled code, compile and link
285            // Hommais's thesis explains this scheduling method (like CASS strategy)
286            // Doesn't use port dependancies
287            strong_component_list_t * strong_list = NULL;
288#pragma omp master
289            {
290                Graph * g = makegraph (&combinational_func_list);
291                if (dump_all_graph && g) {
292                    graph2dot("module_graph", *g);
293                }
294                strong_list = strong_component(g);
295            }
296            if (dynamic_link_of_scheduling_code) {
297                base_name = gen_scheduling_code_for_dynamic_link(*transition_func_list, *moore_func_list, strong_list);
298            }
299            else {
300                gen_scheduling_code_for_quasistatic_func (*transition_func_list, *moore_func_list, strong_list);
301            }
302            break;
303        }
304        default :
305            cerr << "Error : Unable to schedule SystemC process."
306                    "Please select a scheduling method.\n";
307            exit (35);
308    }
309    }
310    return base_name;
311}
312
313
314bool run_schedule_editor (const char * schedule) {
315    char buf[128];
316    const char * editor = getenv("EDITOR");
317    if (editor == NULL) {
318        editor = "vim";
319    }
320    sprintf (buf, "(cd '%s' ; %s '%s')", temporary_dir, editor, schedule);
321    if (dump_stage) {
322        cerr << "Executing : " << buf << endl;
323    }
324    return (system(buf) == 0);
325}
326
327
328} // end of sc_core namespace
329
330/*
331# Local Variables:
332# tab-width: 4;
333# c-basic-offset: 4;
334# c-file-offsets:((innamespace . 0)(inline-open . 0));
335# indent-tabs-mode: nil;
336# End:
337#
338# vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
339*/
340
Note: See TracBrowser for help on using the repository browser.