pelib  2.0.0
src/solve.cpp
Go to the documentation of this file.
00001 /*
00002  Copyright 2015 Nicolas Melot
00003 
00004  This file is part of Pelib.
00005 
00006  Pelib 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  Pelib 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 Pelib. If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 #include <iostream>
00022 #include <cstdlib>
00023 #include <vector>
00024 #include <map>
00025 
00026 #include <pelib/Algebra.hpp>
00027 #include <pelib/PelibException.hpp>
00028 
00029 #include <pelib/process.h>
00030 #include <pelib/argument_parsing.hpp>
00031 #include <pelib/dl.h>
00032 
00033 #ifdef debug
00034 #undef debug
00035 #endif
00036 
00037 #define debug(expr) cerr << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #expr << " = \"" << expr << "\"." << endl;
00038 
00039 using namespace std;
00040 using namespace pelib;
00041 
00042 #ifdef __cplusplus
00043 extern "C" {
00044 #endif
00045 
00046 // TODO: find a way to use libdl to invoke the library that created the object
00047 char *library;
00048 
00049 std::map<const char*, pelib::Record*>
00050 pelib_process(std::map<const char*, pelib::Record*> records, size_t argc, char** argv)
00051 {
00052         pelib_argument_stream_t conversion;
00053         pelib_argument_stream_init(&conversion);
00054         pelib_argument_stream_parse(argv, &conversion);
00055 
00056         if(conversion.library == NULL)
00057         {
00058                 cerr << "[ERROR] No scheduler specified. Aborting" << endl;
00059                 return map<const char*, Record*>();
00060         }
00061 
00062         // Load library
00063         library = conversion.library;
00064         void *libSolver = load_lib(library);
00065         Algebra* (*solve)(const map<string, const Algebra> &data, size_t argc, char **argv) = (Algebra* (*)(const map<string, const Algebra> &data, size_t argc, char **argv))load_function(libSolver, "pelib_calculus");
00066 
00067         // Read input data
00068         map<string, const Algebra> input;
00069         for(map<const char*, Record*>::iterator i = records.begin(); i != records.end(); i++)
00070         {
00071                 Record *data = i->second;
00072 
00073                 // Add only Algebra records
00074                 if(string(typeid(*data).name()).compare(string(typeid(Algebra).name())) == 0)
00075                 {
00076                         input.insert(pair<string, Algebra>(string(i->first), Algebra(*(Algebra*)i->second)));
00077                 }
00078         }
00079 
00080         // Prepare output collection and fill it with schedule generated by library
00081         map<const char*, Record*> output;
00082         Algebra *solution = solve(input, conversion.argc, conversion.argv);
00083         if(solution != NULL)
00084         {
00085                 output.insert(pair<const char*, pelib::Record*>(typeid(Algebra).name(), solution));
00086         }
00087         else
00088         {
00089                 throw PelibException("Solver couldn't find a correct solution");
00090         }
00091 
00092         destroy_lib(libSolver);
00093 
00094         return output;
00095 }
00096 
00097 void
00098 pelib_delete(pelib::Record* obj)
00099 {
00100         void *libSolver = load_lib(library);
00101         void (*del)(const Algebra*) = (void (*)(const Algebra*))load_function(libSolver, "pelib_delete");
00102 
00103         if(string(typeid(Algebra).name()).compare(typeid(*obj).name()) == 0)
00104         {
00105                 del((Algebra*)obj);
00106         }
00107         else
00108         {
00109                 delete obj;
00110         }
00111 }
00112 
00113 #ifdef __cplusplus
00114 }
00115 #endif
00116