drake  1.0.0
src/drake.cpp
Go to the documentation of this file.
00001 /*
00002  Copyright 2015 Nicolas Melot
00003 
00004  This file is part of Drake.
00005 
00006  Drake is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  Drake is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with Drake. If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 
00021 
00022 #include <iostream>
00023 #include <cstdlib>
00024 #include <fstream>
00025 #include <string>
00026 #include <iomanip>
00027 
00028 #include <pelib/AmplInput.hpp>
00029 #include <pelib/AmplOutput.hpp>
00030 #include <pelib/Platform.hpp>
00031 #include <pelib/GraphML.hpp>
00032 
00033 #include <crown/allocation.h>
00034 #include <crown/mapping.h>
00035 #include <crown/scaling.h>
00036 #include <crown/annealing.h>
00037 #include <crown/crown.h>
00038 
00039 #include <pelib/DrakeCSchedule.hpp>
00040 #include <pelib/AmplInput.hpp>
00041 #include <pelib/AmplOutput.hpp>
00042 #include <pelib/Vector.hpp>
00043 #include <pelib/Matrix.hpp>
00044 #include <pelib/Set.hpp>
00045 #include <pelib/GraphML.hpp>
00046 #include <pelib/Schedule.hpp>
00047 
00048 using namespace std;
00049 using namespace pelib;
00050 using namespace pelib::crown;
00051 
00052 enum action {NONE, NAME, TASKS, TASK, SCHEDULE};
00053 
00054 enum action request = NONE;
00055 int input_stdin = 0;
00056 char* input_file = NULL;
00057 char* task_name = NULL;
00058 char *output_schedule = NULL;
00059 char *output_taskgraph = NULL;
00060 
00061 char *platform_filename = NULL, *parameters_filename = NULL;
00062 char *scheduler;
00063 
00064 #if DEBUG
00065 #define trace(var) cerr << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << var << "\"." << endl
00066 #else
00067 #define trace(var)
00068 #endif
00069 
00070 static void
00071 set_action(enum action req)
00072 {
00073         if(request != NONE)
00074         {
00075                 cerr << "[WARN ] Action already set, replacing." << endl;
00076         }
00077         request = req;
00078 }
00079 
00080 static void
00081 read_args(char **argv)
00082 {
00083         while(*argv != NULL)
00084         {
00085 //              cerr << "[DEBUG] argv = \"" << *argv << "\"." << endl;
00086 //              cerr << "[DEBUG] strcmp(*argv, \"--tasks\") == \"" << strcmp(*argv, "--tasks") << "\"." << endl;
00087                 if(!strcmp(*argv, "--schedule") || !strcmp(*argv, "-g"))
00088                 {
00089                                 set_action(SCHEDULE);
00090                 }
00091                 if(!strcmp(*argv, "--name") || !strcmp(*argv, "-g"))
00092                 {
00093                                 set_action(NAME);
00094                 }
00095                 if(!strcmp(*argv, "--tasks") || !strcmp(*argv, "-g"))
00096                 {
00097                                 set_action(TASKS);
00098                 }
00099                 if(!strcmp(*argv, "--module") || !strcmp(*argv, "-g"))
00100                 {
00101                         set_action(TASK);
00102                         argv++;
00103                         if(**argv != '-')
00104                         {
00105                                 task_name = *argv;
00106                         }
00107                         else
00108                         {
00109                                 cerr << "[WARN ] Missing task name to read information from. Ignoring." << endl;
00110                                 argv--;
00111                         }
00112                 }
00113                 else if(!strcmp(*argv, "--platform") || !strcmp(*argv, "-t"))
00114                 {
00115                         // Read next argument
00116                         argv++;
00117                         if(*argv[0] == '-')
00118                         {       
00119                                 cerr << "[WARN ] Cannot read platform from standard input or invalid option for platform (\"" << argv << "\" starts with '-'). Ignoring." << endl;
00120                                 argv--;
00121                         }
00122                         else
00123                         {
00124                                 platform_filename = *argv;
00125                         }
00126                 }
00127                 else if(!strcmp(*argv, "--taskgraph") || !strcmp(*argv, "-t"))
00128                 {
00129                         // Get to next parameter
00130                         argv++;
00131 
00132                         if(*argv[0] == '-')
00133                         {
00134                                 cerr << "[WARN ] Cannot read taskgraph from standard input or invalid option for taskgraph (\"" << argv << "\" starts with '-'). Ignoring." << endl;
00135                         } else
00136                         {
00137                                 input_file = *argv;
00138                         }
00139                 }
00140                 else if(!strcmp(*argv, "--scheduler") || !strcmp(*argv, "-s"))
00141                 {
00142                         argv++;
00143                         scheduler = *argv;
00144                 }
00145                 else if(!strcmp(*argv, "--output") || !strcmp(*argv, "-s"))
00146                 {
00147                         argv++;
00148                         while(*argv != '\0')
00149                         {
00150                                 if(!strcmp(*argv, "--schedule") || !strcmp(*argv, "-s"))
00151                                 {
00152                                         argv++;
00153                                         if(*argv[0] == '-')
00154                                         {
00155                                                 cerr << "[WARN ] Invalid filename for output schedule (\"" << argv << "\" starts with '-'). Ignoring." << endl;
00156                                         }
00157                                         else
00158                                         {
00159                                                 output_schedule = *argv;
00160                                         }
00161                                         argv++;
00162                                 }
00163                                 else if(!strcmp(*argv, "--taskgraph") || !strcmp(*argv, "-s"))
00164                                 {
00165                                         argv++;
00166                                         if(*argv[0] == '-')
00167                                         {
00168                                                 cerr << "[WARN ] Invalid filename for output taskgraph (\"" << argv << "\" starts with '-'). Ignoring." << endl;
00169                                         }
00170                                         else
00171                                         {
00172                                                 output_taskgraph = *argv;
00173                                         }
00174                                         argv++;
00175                                 }
00176                                 else
00177                                 {
00178                                         break;
00179                                 }
00180                         }
00181                 }
00182 
00183                 // Read next argument
00184                 argv++;
00185         }
00186 }
00187 
00188 int main(int argc, char **argv)
00189 {
00190         read_args(argv);
00191         
00192         switch(request)
00193         {
00194                 case NAME:
00195                 {
00196                         GraphML input;
00197                         std::ifstream myfile;
00198                         myfile.open (input_file, std::ios::in);
00199                         Taskgraph tg = input.parse(myfile);
00200                         myfile.close();
00201 
00202                         cout << tg.getName() << endl;   
00203                         break;
00204                 }
00205                 case TASKS:
00206                 {
00207                         GraphML input;
00208                         std::ifstream myfile;
00209                         myfile.open (input_file, std::ios::in);
00210                         Taskgraph tg = input.parse(myfile);
00211                         myfile.close();
00212 
00213                         for(set<Task>::const_iterator i = tg.getTasks().begin(); i != tg.getTasks().end(); i++)
00214                         {
00215                                 cout << i->getName() << " ";
00216                         }
00217                         cout << endl;
00218 
00219                         break;
00220                 }
00221                 case TASK:
00222                 {
00223                         GraphML input;
00224                         std::ifstream myfile;
00225                         myfile.open (input_file, std::ios::in);
00226                         Taskgraph tg = input.parse(myfile);
00227                         myfile.close();
00228 
00229                         cout << tg.findTask(task_name).getModule() << endl;
00230                         break;
00231                 }
00232                 case SCHEDULE:
00233                 {       
00234                         stringstream ss;
00235                         // Run a mimer scheduler, discard the output taskgraph and statistics and redirect taskgraph and schedule outputs to respective output files (default: /dev/null for taskgraph and /dev/stdout for schedule)
00236                         ss << "bash -c '" << scheduler << " --taskgraph " << input_file << " --platform " << platform_filename << " --taskgraph-output >(cat >" << (output_taskgraph == NULL ? "/dev/null" : output_taskgraph) << ") --schedule-output >(cat >" << (output_schedule == NULL ? "/dev/stdout" : output_schedule) << ") >/dev/null'";
00237                         cerr << "Running \"" << ss.str() << "\"" << endl;
00238                         int res = system(ss.str().c_str());
00239 
00240                         if(res != 0)
00241                         {
00242                                 cerr << "[ERROR] Error while running scheduler \"" << scheduler << "\". Aborting." << endl;
00243                                 exit(res);
00244                         }
00245 
00246                         break;
00247                 }
00248                 case NONE:
00249                         cerr << "[ERROR] No valid action requested. Aborting." << endl;
00250                         exit(1);
00251                 break;
00252                 default:
00253                         cerr << "[ERROR] Unknown action requested. Aborting." << endl;
00254                         exit(1);
00255                 break;
00256         }
00257                 
00258         // Set floating point var output format to fixed at 7 digits
00259         std::cout << std::setprecision(6)                                                                                                        
00260                 << std::setiosflags(std::ios::fixed)                                                                                                     
00261                 << std::setiosflags(std::ios::showpoint);  
00262 
00263         return 0;
00264 }