we always have liblpp now, remove WITH_ILP flag
[libfirm] / ir / lpp / lpp_remote.c
1 /**
2  * Author:      Daniel Grund
3  * Date:        02.06.2005
4  * Copyright:   (c) Universitaet Karlsruhe
5  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
6  */
7 #include "config.h"
8
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14
15 #include "lpp_remote.h"
16 #include "assert.h"
17 #include "mps.h"
18
19 #ifdef _WIN32
20 #define WIN32_LEAN_AND_MEAN
21 #include <io.h>
22
23 #define snprintf      _snprintf
24 #define chmod(a, b)   _chmod(a, b)
25
26 /* disable warning: 'foo' was declared deprecated, use 'bla' instead */
27 /* of course MS had to make 'bla' incompatible to 'foo', so a simple */
28 /* define will not work :-((( */
29 #pragma warning( disable : 4996 )
30
31 #endif
32
33 /* CPLEX-account related stuff */
34 #define DELETE_FILES    /**< deletes all dumped files after use. Files on server are always deleted. */
35 #define SSH_USER_HOST   "kb61@sp-smp.rz.uni-karlsruhe.de"
36 #define SSH_PASSWD_FILE "/ben/daniel/.smppw"
37 #define EXPECT_FILENAME "runme" /* name of the expect-script */
38
39 static FILE *ffopen(const char *base, const char *ext, const char *mode) {
40         FILE *out;
41         char buf[1024];
42
43         snprintf(buf, sizeof(buf), "%s.%s", base, ext);
44         if (! (out = fopen(buf, mode))) {
45                 fprintf(stderr, "Cannot open file %s in mode %s\n", buf, mode);
46                 return NULL;
47         }
48         return out;
49 }
50
51 static void lpp_write_cmd(lpp_t *lpp) {
52         FILE *out = ffopen(lpp->name, "cmd", "wt");
53         fprintf(out, "set logfile %s.sol\n", lpp->name);
54         fprintf(out, "set mip strategy mipstart 1\n");
55         // fprintf(out, "set mip emphasis 3\n"); /* moving best bound */
56         fprintf(out, "set mip emphasis 0\n"); /* balance optimality and feasability */
57         fprintf(out, "set mip strategy variableselect 3\n"); /* strong branching */
58         fprintf(out, "read %s.mps\n", lpp->name);
59         fprintf(out, "read %s.mst\n", lpp->name);
60         fprintf(out, "optimize\n");
61         fprintf(out, "display solution variables -\n");
62         fprintf(out, "quit\n");
63         fclose(out);
64 }
65
66 static void lpp_write_exp(lpp_t *lpp) {
67         FILE *pwfile, *out;
68         char passwd[128];
69
70         pwfile = fopen(SSH_PASSWD_FILE, "rt");
71         fgets(passwd, sizeof(passwd), pwfile);
72         fclose(pwfile);
73
74         out = ffopen(EXPECT_FILENAME, "exp", "wt");
75         fprintf(out, "#! /usr/bin/expect\n");
76         fprintf(out, "spawn scp %s.mps %s.mst %s.cmd %s:\n", lpp->name, lpp->name, lpp->name, SSH_USER_HOST); /* copy problem files */
77         fprintf(out, "expect \"word:\"\nsend \"%s\\n\"\ninteract\n", passwd);
78
79         fprintf(out, "spawn ssh %s \"./cplex90 < %s.cmd\"\n", SSH_USER_HOST, lpp->name); /* solve */
80         fprintf(out, "expect \"word:\"\nsend \"%s\\n\"\ninteract\n", passwd);
81
82         fprintf(out, "spawn scp %s:%s.sol .\n", SSH_USER_HOST, lpp->name); /*copy back solution */
83         fprintf(out, "expect \"word:\"\nsend \"%s\\n\"\ninteract\n", passwd);
84
85         fprintf(out, "spawn ssh %s ./dell\n", SSH_USER_HOST); /* clean files on server */
86         fprintf(out, "expect \"word:\"\nsend \"%s\\n\"\ninteract\n", passwd);
87         fclose(out);
88 }
89
90 static void lpp_read_solution(lpp_t *lpp) {
91         FILE *in;
92         double sol_time;
93         unsigned iter;
94         int vars_section = 0;
95         char var_name[128];
96         double var_value;
97
98         if (!(in = ffopen(lpp->name, "sol", "rt"))) {
99                 lpp->sol_state = lpp_unknown;
100                 return;
101         }
102         while (!feof(in)) {
103                 char buf[1024];
104                 fgets(buf, sizeof(buf), in);
105
106                 /* error and solution state */
107                 if (!strncmp(buf, "CPLEX Error", 11))
108                         lpp->error = strdup(buf);
109                 else if (!strncmp(buf, "Warning:", 8))
110                         lpp->error = strdup(buf);
111                 else if (!strncmp(buf, "Integer optimal solution:", 25))
112                         lpp->sol_state = lpp_optimal;
113                 else if (!strcmp(buf, "No integer feasible solution exists."))
114                         lpp->sol_state = lpp_infeasible;
115                 else if (!strcmp(buf, "Error termination, integer feasible:"))
116                         lpp->sol_state = lpp_feasible;
117                 /* stats */
118                 else if (sscanf(buf, "Solution time = %lg sec. Iterations = %u", &sol_time, &iter) == 2) {
119                         lpp->sol_time = sol_time;
120                         lpp->iterations = iter;
121                 }
122                 /* variable values */
123                 else if(!strcmp(buf, "Variable Name           Solution Value")) {
124                         int i;
125                         vars_section = 1;
126                         for(i=0; i<lpp->var_next; ++i) {
127                                 lpp_name_t *var = lpp->vars[i];
128                                 var->value = 0;
129                                 var->value_kind = lpp_value_solution;
130                         }
131                 }
132                 else if(!strncmp(buf, "All other var", 13))
133                         vars_section = 0;
134                 else if (vars_section) {
135                         if (sscanf(buf, "%s %lg", var_name, &var_value) == 2)
136                                 lpp->vars[lpp_get_var_idx(lpp, var_name)]->value = var_value;
137                         else
138                                 assert(0 && "There should be variables to read in!");
139                 }
140         }
141         fclose(in);
142         if (lpp->error) {
143                 printf("\n%s\n", lpp->error);
144                 assert(0);
145         }
146 }
147
148 #ifdef DELETE_FILES
149 static void lpp_delete_files(lpp_t *lpp) {
150         char buf[1024];
151         int end = snprintf(buf, sizeof(buf), "%s", lpp->name);
152
153         snprintf(buf+end, sizeof(buf)-end, ".mps");
154         remove(buf);
155         snprintf(buf+end, sizeof(buf)-end, ".mst");
156         remove(buf);
157         snprintf(buf+end, sizeof(buf)-end, ".cmd");
158         remove(buf);
159         snprintf(buf+end, sizeof(buf)-end, ".sol");
160         remove(buf);
161         remove(EXPECT_FILENAME ".exp");
162 }
163 #endif
164
165 void lpp_solve_remote(lpp_t *lpp) {
166         FILE *out;
167         out = ffopen(lpp->name, "mps", "wt");
168         mps_write_mps(lpp, s_mps_free, out);
169         fclose(out);
170
171         out = ffopen(lpp->name, "mst", "wt");
172         mps_write_mst(lpp, s_mps_free, out);
173         fclose(out);
174
175         lpp_write_cmd(lpp);
176         lpp_write_exp(lpp);
177
178         /* call the expect script */
179         chmod(EXPECT_FILENAME ".exp", 0700);
180         system(EXPECT_FILENAME ".exp");
181
182         lpp_read_solution(lpp);
183 #ifdef DELETE_FILES
184         lpp_delete_files(lpp);
185 #endif
186 }