crown  1.0.0
src/crown-modular.cpp
Go to the documentation of this file.
00001 /*
00002  Copyright 2015 Nicolas Melot
00003 
00004  This file is part of Crown.
00005 
00006  Crown 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  Crown 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 Crown. If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 
00021 #include <pelib/Scalar.hpp>
00022 #include <pelib/argument_parsing.hpp>
00023 #include <pelib/scheduler.h>
00024 #include <pelib/dl.h>
00025 
00026 #include <crown/crown-scheduler.hpp>
00027 #include <crown/CrownAllocation.hpp>
00028 #include <crown/CrownMapping.hpp>
00029 #include <crown/CrownScaling.hpp>
00030 #include <crown/CrownModular.hpp>
00031 
00032 #ifdef debug
00033 #undef debug
00034 #endif
00035 
00036 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << endl;
00037 
00038 using namespace std;
00039 using namespace pelib;
00040 using namespace crown;
00041 
00042 #ifdef __cplusplus
00043 extern "C" {
00044 #endif
00045 
00046 struct args
00047 {
00048         double alpha, eta, zeta, kappa;
00049         pelib_argument_stream alloc, mapping, scaling, config;
00050         bool showError, showOutput;
00051         
00052 };
00053 typedef struct args args_t;
00054 
00055 static args_t
00056 parse(char **args)
00057 {
00058         args_t out;
00059         out.showError = false;
00060         out.showOutput = false;
00061         out.alpha = 3;
00062         out.zeta = 0.649;
00063         out.eta = 0.018611;
00064         out.kappa = 52.639161335;
00065         pelib_argument_stream_init(&out.alloc);
00066         pelib_argument_stream_init(&out.mapping);
00067         pelib_argument_stream_init(&out.scaling);
00068         pelib_argument_stream_init(&out.config);
00069 
00070         for(; args[0] != NULL; args++)
00071         {
00072                 if(strcmp(args[0], "--show-stdout") == 0)
00073                 {
00074                         out.showOutput = true;
00075                         continue;
00076                 }
00077                 if(strcmp(args[0], "--show-stderr") == 0)
00078                 {
00079                         out.showError = true;
00080                         continue;
00081                 }
00082                 if(strcmp(args[0], "--alpha") == 0)
00083                 {
00084                         args++;
00085                         stringstream str(args[0]);
00086                         str >> out.alpha;
00087                         continue;
00088                 }
00089                 if(strcmp(args[0], "--eta") == 0)
00090                 {
00091                         args++;
00092                         stringstream str(args[0]);
00093                         str >> out.eta;
00094                         continue;
00095                 }
00096                 if(strcmp(args[0], "--zeta") == 0)
00097                 {
00098                         args++;
00099                         stringstream str(args[0]);
00100                         str >> out.zeta;
00101                         continue;
00102                 }
00103                 if(strcmp(args[0], "--kappa") == 0)
00104                 {
00105                         args++;
00106                         stringstream str(args[0]);
00107                         str >> out.kappa;
00108                         continue;
00109                 }
00110                 if(strcmp(args[0], "--config") == 0)
00111                 {
00112                         args++;
00113                         args += pelib_argument_stream_parse(args, &out.config) - 1;
00114                         continue;
00115                 }
00116                 if(strcmp(args[0], "--allocation") == 0)
00117                 {
00118                         args++;
00119                         args += pelib_argument_stream_parse(args, &out.alloc) - 1;
00120                         continue;
00121                 }
00122                 if(strcmp(args[0], "--mapping") == 0)
00123                 {
00124                         args++;
00125                         args += pelib_argument_stream_parse(args, &out.mapping) - 1;
00126                         continue;
00127                 }
00128                 if(strcmp(args[0], "--scaling") == 0)
00129                 {
00130                         args++;
00131                         args += pelib_argument_stream_parse(args, &out.scaling) - 1;
00132                         continue;
00133                 }
00134         }
00135 
00136         return out;
00137 }
00138 
00139 const CrownScheduler*
00140 crown_scheduler(size_t argc, char **argv, const CrownScheduler *composite)
00141 {
00142         args_t args = parse(argv);
00143 
00144         void *libAlloc = load_lib(args.alloc.library);
00145         void *libMapping = load_lib(args.mapping.library);
00146         void *libScaling = load_lib(args.scaling.library);
00147         void *libConfig = load_lib(args.config.library);
00148 
00149         CrownAllocation* (*allocate)(size_t argc, char **argv);
00150         CrownMapping* (*map)(size_t argc, char **argv);
00151         CrownScaling* (*scal)(size_t argc, char **argv);
00152         CrownConfig* (*conf)(size_t argc, char **argv);
00153 
00154         Algebra param;
00155         param.insert(new Scalar<float>("alpha", args.alpha));
00156         param.insert(new Scalar<float>("eta", args.eta));
00157         param.insert(new Scalar<float>("zeta", args.zeta));
00158         param.insert(new Scalar<float>("kappa", args.kappa));
00159 
00160         CrownAllocation* alloc = NULL;
00161         CrownMapping* mapping = NULL;
00162         CrownScaling* scaling = NULL;
00163         CrownConfig *config = NULL;
00164 
00165         // Load crown allocation
00166         if(args.alloc.library != NULL)
00167         {
00168                 void *libConfig = load_lib(args.alloc.library);
00169                 allocate = (CrownAllocation* (*)(size_t argc, char **argv))load_function(libConfig, "crown_allocation");
00170                 alloc = allocate(args.alloc.argc, args.alloc.argv);
00171         }
00172 
00173         // Load crown mapping
00174         if(args.mapping.library != NULL)
00175         {
00176                 void *libConfig = load_lib(args.mapping.library);
00177                 map = (CrownMapping* (*)(size_t argc, char **argv))load_function(libConfig, "crown_mapping");
00178                 mapping = map(args.mapping.argc, args.mapping.argv);
00179         }
00180 
00181         // Load crown scaling
00182         if(args.scaling.library != NULL)
00183         {
00184                 void *libConfig = load_lib(args.scaling.library);
00185                 scal = (CrownScaling* (*)(size_t argc, char **argv))load_function(libConfig, "crown_scaling");
00186                 scaling = scal(args.scaling.argc, args.scaling.argv);
00187         }
00188 
00189         // Load crown config
00190         if(args.config.library != NULL)
00191         {
00192                 void *libConfig = load_lib(args.config.library);
00193                 conf = (CrownConfig* (*)(size_t argc, char **argv))load_function(libConfig, "crown_config");
00194                 config = conf(args.config.argc, args.config.argv);
00195         }
00196 
00197         CrownScheduler *scheduler;
00198         // Compute a schedule
00199         scheduler = new CrownModular(param, config, alloc, mapping, scaling, args.showOutput, args.showError);
00200 
00201         // Destroy object instances by libraries
00202         if(args.alloc.library != NULL)
00203         {
00204                 void (*del)(CrownAllocation *) = (void (*)(CrownAllocation*))load_function(libAlloc, "crown_delete_algebra");
00205                 del(alloc);
00206                 destroy_lib(libAlloc);
00207         }
00208 
00209         // Destroy object instances by libraries
00210         if(args.mapping.library != NULL)
00211         {
00212                 void (*del)(CrownMapping *) = (void (*)(CrownMapping*))load_function(libMapping, "crown_delete_algebra");
00213                 del(mapping);
00214                 destroy_lib(libMapping);
00215         }
00216 
00217         // Destroy object instances by libraries
00218         if(args.scaling.library != NULL)
00219         {
00220                 void (*del)(CrownScaling *) = (void (*)(CrownScaling*))load_function(libScaling, "crown_delete_algebra");
00221                 del(scaling);
00222                 destroy_lib(libScaling);
00223         }
00224 
00225         // Destroy object instances by libraries
00226         if(args.config.library != NULL)
00227         {
00228                 void (*del)(CrownConfig *) = (void (*)(CrownConfig*))load_function(libConfig, "crown_delete_config");
00229                 del(config);
00230                 destroy_lib(libConfig);
00231         }
00232 
00233         return scheduler;
00234 }
00235 
00236 #ifdef __cplusplus
00237 }
00238 #endif