/home/coin/SVN-release/OS-1.1.1/OS/applications/amplClient/OSAmplClient.cpp

Go to the documentation of this file.
00001 
00040 #include "OSCoinSolver.h"
00041 #include "OSConfig.h"
00042 #include "OSnl2osil.h"
00043 #include "OSiLReader.h"
00044 #include "OSrLReader.h"
00045 #include "OSiLWriter.h"
00046 #include "OSrLWriter.h"
00047 #include "OSInstance.h"
00048 #include "OSResult.h"
00049 #ifdef COIN_HAS_LINDO    
00050 #include "OSLindoSolver.h"
00051 #endif 
00052 #ifdef COIN_HAS_IPOPT    
00053 #include "OSIpoptSolver.h"
00054 #endif  
00055 #ifdef COIN_HAS_BONMIN    
00056 #include "OSBonminSolver.h"
00057 #endif 
00058 #include "OSFileUtil.h"
00059 #include "OSDefaultSolver.h"
00060 #include "OSSolverAgent.h"
00061 #include "OShL.h"
00062 #include "OSErrorClass.h"
00063 #include <sstream>
00064 
00065 #ifdef HAVE_CSTRING
00066 # include <cstring>
00067 #else
00068 # ifdef HAVE_STRING_H
00069 #  include <string.h>
00070 # else
00071 #  error "don't have header file for string"
00072 # endif
00073 #endif
00074 
00075 
00076 //AMPL includes must be last.
00077 #include <asl.h>
00078 using std::cerr;
00079 using std::cout;
00080 using std::endl;
00081 
00082 
00083 int main(int argc, char **argv)
00084 {
00085         WindowsErrorPopupBlocker();
00086         char *stub;
00087         // set AMPL structures
00088         ASL *asl;
00089         asl = ASL_alloc(ASL_read_fg);
00090     stub = argv[1];
00091         jac0dim((char*)stub, (fint)strlen(stub));
00092         OSnl2osil *nl2osil = NULL;
00093         //initialize object with stub -- the nl file
00094         nl2osil = new OSnl2osil( stub);
00095         // create an osinstance object
00096         OSInstance *osinstance;
00097         std::cout << " call nl2osil" << std::endl;
00098         try{
00099                 nl2osil->createOSInstance() ;
00100         }
00101         catch(const ErrorClass& eclass){
00102                 std::cout << eclass.errormsg << std::endl;
00103                 return 0;
00104         }
00105         std::cout << " return from  nl2osil" << std::endl;
00106         osinstance = nl2osil->osinstance;
00107         std::cout << " osinstance created" << std::endl;
00108         // turn the osinstance into osil 
00109         // not needed for a local solve
00110         // send an osinstance object in memory
00118         char *amplclient_options = NULL;
00119         char *agent_address = NULL;
00120         char *solver_option = NULL;
00121         // set solver type default to clp
00122         DefaultSolver *solverType  = NULL;      
00123         OSrLReader *osrlreader = NULL;
00124         OSrLWriter *osrlwriter;
00125         osrlwriter = new OSrLWriter();
00126         OSResult *osresult = NULL;
00127         std::string osrl = "";
00128         std::string sSolverName = "";
00129         // note that default solver is coin and default subSolver is Cbc
00130         std::string osol = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <osol xmlns=\"os.optimizationservices.org\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"os.optimizationservices.org http://www.optimizationservices.org/schemas/OSoL.xsd\"></osol>";
00131         
00132         char *num_procOption = NULL;
00133         char *num_processors = NULL;
00134         char *URL = NULL;
00135         char delims[] = " ";
00136         
00137         // get the solver set by AMPL
00138         amplclient_options = getenv("OSAmplClient_options");
00139         if( amplclient_options != NULL) cout << "HERE ARE THE AMPLCLIENT OPTIONS " <<   amplclient_options << endl;
00140         try{
00141                 if(amplclient_options == NULL ) throw ErrorClass( "a local solver was not specified in AMPL option");
00142                 else{
00143                         if( strstr(amplclient_options, "lindo") != NULL) {
00144                                 // we are requesting the Lindo solver
00145                                 bool bLindoIsPresent = false;
00146                                 #ifdef COIN_HAS_LINDO
00147                                 sSolverName = "lindo";
00148                                 bLindoIsPresent = true;
00149                                 solver_option = getenv("lindo_options");
00150                                 if(( solver_option == NULL) ||  strstr(solver_option, "service") == NULL)  solverType = new LindoSolver();
00151                                 #endif
00152                                 if(bLindoIsPresent == false) throw ErrorClass( "the Lindo solver requested is not present");
00153                         }
00154                         else{ 
00155                                 if( strstr(amplclient_options, "clp") != NULL){
00156                                         if( solver_option != NULL) cout << "HERE ARE THE Clp SOLVER OPTIONS " <<   solver_option << endl;
00157                                         sSolverName = "clp";
00158                                         solver_option = getenv("clp_options");
00159                                         if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00160                                                 solverType = new CoinSolver();
00161                                                 solverType->sSolverName = "clp";
00162                                         }
00163                                 }
00164                                 else{
00165                                         if( strstr(amplclient_options, "cbc") != NULL){
00166                                                 sSolverName = "cbc";
00167                                                 solver_option = getenv("cbc_options");
00168                                                 if( solver_option != NULL) cout << "HERE ARE THE Cbc SOLVER OPTIONS " <<   solver_option << endl;
00169                                                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL)){
00170                                                         solverType = new CoinSolver();
00171                                                         solverType->sSolverName = "cbc";
00172                                                 }
00173                                         }
00174                                         else{
00175                                                 if( strstr(amplclient_options, "cplex") != NULL){
00176                                                         bool bCplexIsPresent = false;
00177                                                         #ifdef COIN_HAS_CPX
00178                                                                 bCplexIsPresent = true;
00179                                                                 sSolverName = "cplex";
00180                                                                 solver_option = getenv("cplex_options");
00181                                                                 if( solver_option != NULL) cout << "HERE ARE THE Cplex SOLVER OPTIONS " <<   solver_option << endl;
00182                                                                 if(  ( solver_option == NULL) ||  (strstr(solver_option, "service") == NULL)){
00183                                                                         solverType = new CoinSolver();
00184                                                                         solverType->sSolverName = "cplex";
00185                                                                 }
00186                                                         #endif
00187                                                                 if(bCplexIsPresent == false) throw ErrorClass( "the Cplex solver requested is not present");
00188                                                 }
00189                                                 else{
00190                                                         if( strstr(amplclient_options, "glpk") != NULL){
00191                                                                 bool bGlpkIsPresent = false;
00192                                                                 #ifdef COIN_HAS_GLPK
00193                                                                         bGlpkIsPresent = true;
00194                                                                         solverType = new CoinSolver();
00195                                                                         sSolverName = "glpk";
00196                                                                         solver_option = getenv("glpk_options");
00197                                                                         if( solver_option != NULL) cout << "HERE ARE THE Glpk SOLVER OPTIONS " <<   solver_option << endl;
00198                                                                         if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL)){
00199                                                                                 solverType = new CoinSolver();
00200                                                                                 solverType->sSolverName = "glpk";
00201                                                                         }
00202                                                                 #endif
00203                                                                 if(bGlpkIsPresent == false) throw ErrorClass( "the Glpk solver requested is not present");
00204                                                         }
00205                                                         else{
00206                                                                 if( strstr(amplclient_options, "ipopt") != NULL){
00207                                                                         bool bIpoptIsPresent = false;
00208                                                                         #ifdef COIN_HAS_IPOPT
00209                                                                                 bIpoptIsPresent = true;
00210                                                                                 sSolverName = "ipopt";
00211                                                                                 solver_option = getenv("ipopt_options");
00212                                                                                 if( solver_option != NULL) cout << "HERE ARE THE Ipopt SOLVER OPTIONS " <<   solver_option << endl;
00213                                                                                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00214                                                                                         solverType = new IpoptSolver();
00215                                                                                         solverType->sSolverName = "ipopt";
00216                                                                                 }
00217                                                                         #endif
00218                                                                         if(bIpoptIsPresent == false) throw ErrorClass( "the Ipopt solver requested is not present");
00219                                                                 }
00220                                                                 else{
00221                                                                         if( strstr(amplclient_options, "symphony") != NULL){
00222                                                                                 bool bSymIsPresent = false;
00223                                                                                 #ifdef COIN_HAS_SYMPHONY
00224                                                                                         bSymIsPresent = true; 
00225                                                                                         sSolverName = "symphony";
00226                                                                                         solver_option = getenv("symphony_options");
00227                                                                                         if( solver_option != NULL) cout << "HERE ARE THE SYMPHONY SOLVER OPTIONS " <<   solver_option << endl;
00228                                                                                         // get the number of parallel parallel processors and insert into the osol
00229                                                                                         // tokenize the symphony_options string
00230                                                                                         // just test for now, make a subroutine later
00231 
00232                                                                                         //
00233                                                                                         if(solver_option != NULL){
00234                                                                                                 num_procOption = strstr(solver_option, "num_proc");
00235                                                                                                 if (num_procOption != NULL){
00236                                                                                                         // kipp -- probably should make this a subroutine in
00237                                                                                                         // case other solvers have options???
00238                                                                                                         // get the number of processors
00239                                                                                                         //move past the num_proc option name token
00240                                                                                                         num_procOption += 8;
00241                                                                                                         num_processors = strtok( num_procOption, delims );
00242                                                                                                         //
00243                                                                                                         string::size_type iStringpos;
00244                                                                                                         iStringpos = osol.find("</osol");
00245                                                                                                         std::string insertText = "<other name=\"num_proc\">";
00246                                                                                                         insertText +=  num_processors;
00247                                                                                                         insertText += "</other>";
00248                                                                                                         osol.insert(iStringpos, insertText);
00249 
00250                                                                                                 }
00251                                                                                         }
00252                                                                                         if(  ( solver_option == NULL) ||  (strstr(solver_option, "service") == NULL)){
00253                                                                                                 solverType = new CoinSolver();
00254                                                                                                 solverType->sSolverName = "symphony";
00255                                                                                         }
00256                                                                                 #endif
00257                                                                                 if(bSymIsPresent == false) throw ErrorClass( "the SYMPHONY solver requested is not present");
00258                                                                         }
00259                                                                         else{
00260                                                                                 if( strstr(amplclient_options, "dylp") != NULL){
00261                                                                                         bool bDyLPIsPresent = false;
00262                                                                                         #ifdef COIN_HAS_DYLP
00263                                                                                                 bDyLPIsPresent = true;
00264                                                                                                 sSolverName = "dylp";
00265                                                                                                 solver_option = getenv("dylp_options");
00266                                                                                                 if( solver_option != NULL) cout << "HERE ARE THE DyLP SOLVER OPTIONS " <<   solver_option << endl;
00267                                                                                                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00268                                                                                                         solverType = new CoinSolver();
00269                                                                                                         solverType->sSolverName = "dylp";
00270                                                                                                 }
00271                                                                                         #endif
00272                                                                                         if(bDyLPIsPresent == false) throw ErrorClass( "the DyLP solver requested is not present");
00273                                                                                 }                                               
00274                                                                                 else{
00275                                                                                         if( strstr(amplclient_options, "bonmin") != NULL ){
00276                                                                                                 bool bBonminIsPresent = false;
00277                                                                                                 #ifdef COIN_HAS_BONMIN
00278                                                                                                         bBonminIsPresent = true;
00279                                                                                                         sSolverName = "bonmin";
00280                                                                                                         solver_option = getenv("bonmin_options");
00281                                                                                                         if( solver_option != NULL) cout << "HERE ARE THE Bonmin SOLVER OPTIONS " <<   solver_option << endl;
00282                                                                                                         if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00283                                                                                                                 solverType = new BonminSolver();
00284                                                                                                                 solverType->sSolverName = "bonmin";
00285                                                                                                         }
00286                                                                                                 #endif
00287                                                                                                 if(bBonminIsPresent == false) throw ErrorClass( "the Bonmin solver requested is not present");                                                                                          
00288                                                                                         }
00289                                                                                         else{
00290                                                                                                 throw ErrorClass( "a supported solver has not been selected");
00291                                                                                         }
00292                                                                                 }
00293                                                                         }       
00294                                                                 } 
00295                                                         }
00296                                                 }
00297                                         }
00298                                 }
00299                         }
00300                 }
00301                 // do a local solve
00302                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL)  ){
00303                         solverType->osol = osol;
00304                         //std::cout << osol << std::endl;
00305                         solverType->osinstance = osinstance;
00306                         solverType->buildSolverInstance();
00307                         solverType->solve();
00308                         osrl = solverType->osrl ;
00309                         //std::cout << osrl << std::endl;
00310                 }
00311         }
00312         catch(const ErrorClass& eclass){
00313                 osresult = new OSResult();      
00314                 osresult->setGeneralMessage( eclass.errormsg);
00315                 osresult->setGeneralStatusType( "error");
00316                 osrl = osrlwriter->writeOSrL( osresult);
00317                 std::cout  << osrl << std::endl;
00318                 osrl = " ";
00319                 write_sol(const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00320                 delete osresult;
00321                 return 0;
00322         }
00323         try{
00324                 // do the following for a remote solve
00325                 if( (solver_option != NULL) && (strstr(solver_option, "service") != NULL)){
00326                         OSSolverAgent* osagent = NULL;
00327                         OSiLWriter *osilwriter = NULL;
00328                         osilwriter = new OSiLWriter();
00329                         std::string  osil = osilwriter->writeOSiL( osinstance);
00331                         agent_address = strstr(solver_option, "service");
00332                         agent_address += 7;
00333                         URL = strtok( agent_address, delims );
00334                         std::string sURL = URL;
00336                         // we should be pointing to the start of the address
00337                         osagent = new OSSolverAgent( URL);
00338                         // if a solver option was specified put that in
00339                         string::size_type iStringpos;
00340                         iStringpos = osol.find("</osol");
00341                         //std::cout <<  solverType->sSolverName << std::endl;
00342                         std::string solverInput = "<other name=\"os_solver\">"
00343                                 + sSolverName  + "</other>";
00344                         osol.insert(iStringpos, solverInput);
00345                         cout << "Place remote synchronous call: " + sURL << endl << endl << endl;
00346                         cout << osol << endl;
00347                         osrl = osagent->solve(osil, osol);
00348                         if (osrl.size() == 0) throw ErrorClass("Nothing was returned from the server, please check service address");
00349                         delete osilwriter;
00350                         delete osagent; 
00351                 } 
00352         }
00353         catch(const ErrorClass& eclass){
00354                 osresult = new OSResult();
00355                 osresult->setGeneralMessage( eclass.errormsg);
00356                 osresult->setGeneralStatusType( "error");
00357                 osrl = osrlwriter->writeOSrL( osresult);        
00358                 write_sol(const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00359                 delete osresult;
00360                 return 0;
00361         }
00362         try{ 
00363                 //need_nl = 0;
00364                 std::string sResultFileName = "solutionResult.osrl";
00365                 FileUtil *fileUtil;
00366                 fileUtil = new FileUtil();
00367                 fileUtil->writeFileFromString(sResultFileName, osrl);
00368                 delete fileUtil;
00369                 //cout << "WRITE THE SOLUTION BACK INTO AMPL" <<endl;
00370                 string::size_type pos1 = osrl.find( "error");
00371                 if(pos1 == std::string::npos){
00372                         std::string sReport = "model was solved";
00373                         std::cout << sReport << std::endl;
00374                         osrlreader = new OSrLReader();
00375                         osresult = osrlreader->readOSrL( osrl);
00376                         // do the following so output is not written twice
00377                         // see page 23 of hooking solver to AMPL
00378                         //need_nl = printf( sReport.c_str());
00379 
00380                         //
00381                         sReport = " ";
00382                         write_sol(  const_cast<char*>(sReport.c_str()), 
00383                                         osresult->getOptimalPrimalVariableValues( -1), 
00384                                         osresult->getOptimalDualVariableValues( -1) , NULL);
00385                         
00386                         delete osrlreader;
00387                         osrlreader = NULL;
00388                 }else{
00389                         // do the following so output is not written twice
00390                         // see page 23 of hooking solver to AMPL
00391                         std::cout  << osrl << std::endl;
00392                         osrl = " ";
00393                         //
00394                         write_sol(  const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00395                         need_nl = 0;
00396                 }
00397                 //cout << "DONE WRITING THE SOLUTION BACK INTO AMPL" <<endl;
00398         }
00399         catch(const ErrorClass& eclass){
00400                 cout << "There was an error parsing the OSrL" << endl << eclass.errormsg << endl << endl;
00401         }
00402         if(  solverType != NULL ){
00403                 //cout << "TRY TO DELETE solverType" <<endl;
00404                 delete solverType;
00405                 //cout << "solverType JUST DELETED" <<endl;
00406                 solverType = NULL;
00407         }
00408         delete osrlwriter;
00409         //cout << "osrlwriter JUST DELETED" <<endl;
00410         osrlwriter = NULL;
00411         delete nl2osil;
00412         //cout << "nl2osil JUST DELETED" <<endl;
00413         nl2osil = NULL;
00414         ASL_free(&asl);
00415         return 0; 
00416 } // end main

Generated on Tue Sep 30 03:01:24 2008 by  doxygen 1.4.7