Commit bff1daca authored by Matthias Braun's avatar Matthias Braun
Browse files

lpp: Remove support for using remote solvers.

This has not been used for years and the code is often causing compile
problems on systems with bad posix implementations like windows.
parent 86ac6281
......@@ -42,7 +42,6 @@ struct be_options_t {
bool omit_fp; /**< try to omit the frame pointer */
bool pic; /**< create position independent code */
bool do_verify; /**< backend verify option */
char ilp_server[128]; /**< the ilp server name */
char ilp_solver[128]; /**< the ilp solver name */
bool verbose_asm; /**< dump verbose assembler */
};
......
......@@ -234,7 +234,7 @@ lpp_sol_state_t ilp_go(ilp_env_t *ienv)
if (solve_log)
lpp_set_log(ienv->lp, stdout);
lpp_solve(ienv->lp, be_options.ilp_server, be_options.ilp_solver);
lpp_solve(ienv->lp, be_options.ilp_solver);
//stat_ev_dbl("co_ilp_objval", ienv->lp->objval);
//stat_ev_dbl("co_ilp_best_bound", ienv->lp->best_bound);
......
......@@ -26,7 +26,6 @@
*****************************************************************************/
#include "lpp.h"
#include "lpp_net.h"
#define EPSILON 0.00001
......
......@@ -68,7 +68,6 @@ be_options_t be_options = {
.omit_fp = false,
.pic = false,
.do_verify = true,
.ilp_server = "",
.ilp_solver = "",
.verbose_asm = true,
};
......@@ -103,7 +102,6 @@ static const lc_opt_table_entry_t be_main_options[] = {
LC_OPT_ENT_BOOL ("profileuse", "use existing profile data", &be_options.opt_profile_use),
LC_OPT_ENT_BOOL ("verboseasm", "enable verbose assembler output", &be_options.verbose_asm),
LC_OPT_ENT_STR("ilp.server", "the ilp server name", &be_options.ilp_server),
LC_OPT_ENT_STR("ilp.solver", "the ilp solver name", &be_options.ilp_solver),
LC_OPT_LAST
};
......
......@@ -1063,7 +1063,7 @@ static void solve_lpp(ir_nodeset_t *live_nodes, ir_node *node,
fclose(out);
/* solve lpp */
lpp_solve(lpp, be_options.ilp_server, be_options.ilp_solver);
lpp_solve(lpp, be_options.ilp_solver);
if (!lpp_is_sol_valid(lpp))
panic("ilp solution not valid");
......
......@@ -21,10 +21,7 @@
#include "sp_matrix.h"
#include "mps.h"
#include "lpp_t.h"
#include "lpp_comm.h"
#include "lpp_solvers.h"
#include "lpp_net.h"
#define HASH_NAME_T(n) hash_str((n)->name)
......@@ -433,207 +430,10 @@ void lpp_dump_plain(lpp_t *lpp, FILE *f)
fprintf(f, "End\n");
}
/**
* Serialize a lpp to a file descriptor.
* @param comm The file descriptor.
* @param lpp The lpp.
*/
void lpp_serialize(lpp_comm_t *comm, const lpp_t *lpp, int with_names)
void lpp_solve(lpp_t *lpp, const char* solver)
{
int n, i;
lpp_writel(comm, with_names);
lpp_writel(comm, lpp->cst_next);
lpp_writel(comm, lpp->var_next);
lpp_writel(comm, lpp->opt_type);
lpp_writes(comm, lpp->name);
/* write options */
lpp_writel(comm, lpp->set_bound);
lpp_writed(comm, lpp->bound);
lpp_writed(comm, lpp->time_limit_secs);
lpp_writel(comm, lpp->emphasis);
for(i = 0; i < lpp->cst_next; ++i) {
lpp_name_t *name = lpp->csts[i];
lpp_writel(comm, name->nr);
lpp_writel(comm, name->value_kind);
lpp_writel(comm, name->type.cst_type);
if(with_names)
lpp_writes(comm, name->name);
}
for(i = 0; i < lpp->var_next; ++i) {
lpp_name_t *name = lpp->vars[i];
lpp_writel(comm, name->nr);
lpp_writel(comm, name->value_kind);
lpp_writel(comm, name->type.var_type);
if(with_names)
lpp_writes(comm, name->name);
}
n = 0;
matrix_foreach(lpp->m, elm)
n++;
assert(n == matrix_get_entries(lpp->m));
lpp_writel(comm, n);
matrix_foreach(lpp->m, elm) {
lpp_writel(comm, elm->row);
lpp_writel(comm, elm->col);
lpp_writed(comm, elm->val);
}
}
/**
* Deserialize an lpp from a file descriptor.
* @param comm The file descriptor.
* @return The Problem.
*/
lpp_t *lpp_deserialize(lpp_comm_t *comm)
{
int i, n;
int with_names;
lpp_t *lpp = XMALLOCZ(lpp_t);
/* read general settings */
with_names = lpp_readl(comm);
lpp->cst_next = lpp_readl(comm);
lpp->var_next = lpp_readl(comm);
lpp->opt_type = (lpp_opt_t)lpp_readl(comm);
lpp->name = lpp_reads(comm);
/* read options */
lpp->set_bound = lpp_readl(comm);
lpp->bound = lpp_readd(comm);
lpp->time_limit_secs = lpp_readd(comm);
lpp->emphasis = (lpp_emphasis_t)lpp_readl(comm);
lpp->cst_size = lpp->cst_next;
lpp->var_size = lpp->var_next;
lpp->cst2nr = new_set(cmp_name_t, lpp->cst_next);
lpp->var2nr = new_set(cmp_name_t, lpp->var_next);
lpp->csts = XMALLOCNZ(lpp_name_t*, lpp->cst_next);
lpp->vars = XMALLOCNZ(lpp_name_t*, lpp->var_next);
lpp->m = new_matrix(lpp->cst_next, lpp->var_next);
for(i = 0; i < lpp->cst_next; ++i) {
lpp_name_t name, *res;
name.nr = lpp_readl(comm);
name.value_kind = (lpp_value_kind_t)lpp_readl(comm);
name.type.cst_type = (lpp_cst_t)lpp_readl(comm);
if(with_names) {
name.name = lpp_reads(comm);
} else {
char* buf = XMALLOCN(char, 32);
snprintf(buf, 32, "c%d\n", name.nr);
name.name = buf;
}
res = set_insert(lpp_name_t, lpp->cst2nr, &name, sizeof(name), HASH_NAME_T(&name));
lpp->csts[name.nr] = res;
}
for(i = 0; i < lpp->var_next; ++i) {
lpp_name_t name, *res;
name.nr = lpp_readl(comm);
name.value_kind = (lpp_value_kind_t)lpp_readl(comm);
name.type.var_type = (lpp_var_t)lpp_readl(comm);
if(with_names) {
name.name = lpp_reads(comm);
} else {
char* buf = XMALLOCN(char, 32);
snprintf(buf, 32, "v%d\n", name.nr);
name.name = buf;
}
res = set_insert(lpp_name_t, lpp->var2nr, &name, sizeof(name), HASH_NAME_T(&name));
lpp->vars[name.nr] = res;
}
n = lpp_readl(comm);
for(i = 0; i < n; ++i) {
matrix_elem_t elm;
elm.row = lpp_readl(comm);
elm.col = lpp_readl(comm);
elm.val = lpp_readd(comm);
matrix_set(lpp->m, elm.row, elm.col, elm.val);
}
return lpp;
}
void lpp_serialize_values(lpp_comm_t *comm, const lpp_t *lpp, lpp_value_kind_t value_kind)
{
int i, n;
for(i = 0, n = 0; i < lpp->var_next; ++i)
n += lpp->vars[i]->value_kind == value_kind;
/* Write the number of values to expect */
lpp_writel(comm, n);
/* send the values */
for(i = 0, n = lpp->var_next; i < n; ++i) {
const lpp_name_t *name = lpp->vars[i];
if(name->value_kind == value_kind) {
lpp_writel(comm, name->nr);
lpp_writed(comm, name->value);
}
}
}
void lpp_deserialize_values(lpp_comm_t *comm, lpp_t *lpp, lpp_value_kind_t value_kind)
{
int i, n;
/* Get the number of values to read */
n = lpp_readl(comm);
for(i = 0; i < n; ++i) {
int nr = lpp_readl(comm);
lpp_name_t *name = lpp->vars[nr];
name->value_kind = value_kind;
name->value = lpp_readd(comm);
}
}
void lpp_serialize_stats(lpp_comm_t *comm, const lpp_t *lpp)
{
lpp_writel(comm, lpp->sol_state);
lpp_writel(comm, lpp->iterations);
lpp_writed(comm, lpp->sol_time);
lpp_writed(comm, lpp->objval);
lpp_writed(comm, lpp->best_bound);
}
void lpp_deserialize_stats(lpp_comm_t *comm, lpp_t *lpp)
{
lpp->sol_state = (lpp_sol_state_t)lpp_readl(comm);
lpp->iterations = lpp_readl(comm);
lpp->sol_time = lpp_readd(comm);
lpp->objval = lpp_readd(comm);
lpp->best_bound = lpp_readd(comm);
}
void lpp_solve(lpp_t *lpp, const char* host, const char* solver)
{
if (host == NULL || strlen(host) == 0) {
lpp_solver_func_t* f = lpp_find_solver(solver);
if (f != NULL)
f(lpp);
} else {
lpp_solve_net(lpp, host, solver);
}
lpp_solver_func_t* f = lpp_find_solver(solver);
if (f != NULL)
f(lpp);
}
......@@ -342,9 +342,8 @@ static inline void lpp_unset_bound(lpp_t *lpp)
/**
* Solve an ILP.
* @param lpp The problem.
* @param host The host to solve on.
* @param solver The solver to use.
*/
void lpp_solve(lpp_t *lpp, const char* host, const char* solver);
void lpp_solve(lpp_t *lpp, const char* solver);
#endif
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Protocol stuff for lpp server
* @author Sebastian Hack
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <BaseTsd.h>
#ifdef _MSC_VER
typedef SSIZE_T ssize_t;
#endif
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#endif
#include "xmalloc.h"
#include "util.h"
#include "debug.h"
#include "lpp_comm.h"
struct _lpp_comm_t {
int fd;
size_t buf_size;
char *w_pos;
char *r_pos;
char *r_max;
char *w_buf;
char *r_buf;
};
#ifdef DEBUG_libfirm
static inline firm_dbg_module_t *get_dbg_module(void)
{
static firm_dbg_module_t *dbg = NULL;
if(!dbg) {
dbg = firm_dbg_register("lpp.comm");
}
return dbg;
}
#define dbg get_dbg_module()
#endif
/**
* Try to read some bytes but block until a certain amount is read.
* @param fd The file descriptor.
* @param buf The buffer to read into.
* @param try_amount The amount of bytes to try to read.
* @param at_least block until this many bytes are read.
* @return The number of bytes read or -1 on error.
*/
static ssize_t secure_recv(int fd, void *buf, size_t try_amount, size_t at_least)
{
ssize_t res;
size_t bytes_read = 0;
char *data = (char*)buf;
do {
res = recv(fd, &data[bytes_read], try_amount - bytes_read, 0);
if(res <= 0) {
if(res == 0 || errno != EAGAIN)
return -1;
continue;
}
bytes_read += res;
} while(bytes_read < at_least);
return bytes_read;
}
static ssize_t secure_send(int fd, const void *buf, size_t n)
{
ssize_t res;
size_t bytes_written = 0;
const char *data = (const char*)buf;
do {
res = send(fd, &data[bytes_written], n - bytes_written, 0);
if(res < 0) {
if(errno != EAGAIN)
return -1;
continue;
}
bytes_written += res;
} while(bytes_written < n);
return n;
}
static ssize_t lpp_flush_(lpp_comm_t *comm)
{
ssize_t res = 0;
if(comm->w_pos - comm->w_buf > 0) {
DBG((dbg, LEVEL_1, "flushing %d bytes\n", comm->w_pos - comm->w_buf));
res = secure_send(comm->fd, comm->w_buf, comm->w_pos - comm->w_buf);
if(res < 0)
return res;
comm->w_pos = comm->w_buf;
}
return res;
}
void lpp_flush(lpp_comm_t *comm)
{
lpp_flush_(comm);
}
static ssize_t lpp_write(lpp_comm_t *comm, const void *buf, size_t len)
{
assert(comm->w_pos - comm->w_buf >= 0);
DBG((dbg, LEVEL_1, "write of length %d\n", len));
if(len > 0) {
size_t free = (comm->w_buf + comm->buf_size) - comm->w_pos;
size_t copy = MIN(free, len);
size_t rest = len - copy;
const char *pos = (const char*)buf;
DBG((dbg, LEVEL_1, "\tfree = %d, copy = %d, rest = %d\n", free, copy, rest));
if(copy > 0) {
memcpy(comm->w_pos, pos, copy);
comm->w_pos += copy;
pos += copy;
}
/*
* Not everything in buf fits into the buffer,
* so flush the buffer and write the rest.
*/
if(rest > 0) {
size_t i;
size_t n_direct = rest / comm->buf_size;
size_t last_rest;
if(lpp_flush_(comm) < 0)
return -1;
for(i = 0; i < n_direct; ++i) {
if(secure_send(comm->fd, pos, comm->buf_size) < 0)
return -1;
pos += comm->buf_size;
}
last_rest = ((const char *) buf + len) - pos;
if(last_rest > 0) {
assert(last_rest < comm->buf_size);
assert(comm->w_pos == comm->w_buf);
memcpy(comm->w_pos, pos, last_rest);
comm->w_pos += last_rest;
}
}
}
return len;
}
static ssize_t lpp_read(lpp_comm_t *comm, void *buf, size_t len)
{
DBG((dbg, LEVEL_1, "read of length %d\n", len));
if(len > 0) {
size_t left = comm->r_max - comm->r_pos;
size_t copy = MIN(left, len);
size_t rest = len - copy;
char *pos = (char*)buf;
DBG((dbg, LEVEL_1, "\tleft = %d, copy = %d, rest = %d\n", left, copy, rest));
if(copy > 0) {
memcpy(pos, comm->r_pos, copy);
pos += copy;
comm->r_pos += copy;
}
/* We want to read more than the buffer can provide. */
if(rest > 0) {
size_t bs = comm->buf_size;
size_t n_direct = rest / comm->buf_size;
size_t i;
size_t last_rest;
/*
* The buffer is now completely read, so
* reset the pointers.
*/
comm->r_pos = comm->r_buf;
comm->r_max = comm->r_buf;
for(i = 0; i < n_direct; ++i) {
if(secure_recv(comm->fd, pos, bs, bs) < 0)
return -1;
pos += comm->buf_size;
}
last_rest = ((const char *) buf + len) - pos;
if(last_rest > 0) {
ssize_t bytes_read = 0;
assert(last_rest < comm->buf_size);
assert(comm->r_pos == comm->r_buf);
bytes_read = secure_recv(comm->fd, comm->r_buf, bs, last_rest);
if(bytes_read < 0)
return -1;
memcpy(pos, comm->r_buf, last_rest);
comm->r_pos = comm->r_buf + last_rest;
comm->r_max = comm->r_buf + bytes_read;
}
}
}
return len;
}
lpp_comm_t *lpp_comm_new(int fd, size_t buf_size)
{
lpp_comm_t *res = XMALLOCZ(lpp_comm_t);
res->fd = fd;
res->w_buf = XMALLOCN(char, buf_size);
res->w_pos = res->w_buf;
res->r_buf = XMALLOCN(char, buf_size);
res->r_pos = res->r_buf;
res->r_max = res->r_buf;
res->buf_size = buf_size;
return res;
}
int lpp_comm_fileno(const lpp_comm_t *comm)
{
return comm->fd;
}
void lpp_comm_free(lpp_comm_t *comm)
{
free(comm->w_buf);
free(comm->r_buf);
free(comm);
}
void lpp_print_err(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
void lpp_writel(lpp_comm_t *comm, uint32_t x)
{
x = htonl(x);
ERRNO_CHECK(lpp_write(comm, &x, sizeof(x)), !=, (ssize_t)sizeof(x));
}
void lpp_writed(lpp_comm_t *comm, double dbl)
{
ERRNO_CHECK(lpp_write(comm, &dbl, sizeof(dbl)), !=, (ssize_t)sizeof(dbl));
}
void lpp_writes(lpp_comm_t *comm, const char *str)
{
size_t n = strlen(str);
lpp_writel(comm, n);
ERRNO_CHECK(lpp_write(comm, str, n), !=, (ssize_t) n);
}
uint32_t lpp_readl(lpp_comm_t *comm)
{
uint32_t res;
ERRNO_CHECK(lpp_read(comm, &res, sizeof(res)), !=, (ssize_t)sizeof(res));
return ntohl(res);
}
int lpp_read_cmd(lpp_comm_t *comm)
{
uint32_t res = 0;
int retval;
for(;;) {
retval = recv(comm->fd, (char *)&res, sizeof(res), 0);
if(retval < 0) {
if(errno != EAGAIN)
return -1;
}
else
break;
}
return (int) ntohl(res);
}
double lpp_readd(lpp_comm_t *comm)
{
double res;
ERRNO_CHECK(lpp_read(comm, &res, sizeof(res)), !=, (ssize_t)sizeof(res));
return res;
}
char *lpp_reads(lpp_comm_t *comm)
{
size_t len = lpp_readl(comm);