7.7 MOSEK OptServer

MOSEK provides an easy way to offload optimization problem to a remote server in both synchronous or asynchronous mode. This section describes related functionalities from the client side, i.e. sending optimization tasks to the remote server and retrieving solutions.

Setting up and configuring the remote server is described in a separate manual for the OptServer.

7.7.1 Synchronous Remote Optimization

In synchronous mode the client sends an optimization problem to the server and blocks, waiting for the optimization to end. Once the result has been received, the program can continue. This is the simplest mode and requires very few modifications to existing code: instead of MSK_optimize the user must invoke MSK_optimizermt with the host and port where the server is running and listening as additional arguments. The rest of the code remains untouched.

Note that it is impossible to recover the job in case of a broken connection.

Source code example

Listing 7.6 Using the OptServer in synchronous mode. Click here to download.
#include "mosek.h"

static void MSKAPI printstr(void *handle, const char str[])
{
  printf("%s", str);
}

int main (int argc, const char * argv[])
{
  MSKenv_t    env  = NULL;
  MSKtask_t   task = NULL;
  MSKrescodee res  = MSK_RES_OK;
  MSKrescodee trm  = MSK_RES_OK;

  if (argc <= 3)
  {
    printf ("Missing argument, syntax is:\n");
    printf ("  opt_server_sync inputfile host port\n");
  }
  else
  {
    // Create the mosek environment.
    // The `NULL' arguments here, are used to specify customized
    // memory allocators and a memory debug file. These can
    // safely be ignored for now.
    res = MSK_makeenv (&env, NULL);

    // Create a task object linked with the environment env.
    // We create it with 0 variables and 0 constraints initially,
    // since we do not know the size of the problem.
    if ( res == MSK_RES_OK )
      res = MSK_maketask (env, 0, 0, &task);

    // Direct the task log stream to a user specified function
    if ( res == MSK_RES_OK )
      res = MSK_linkfunctotaskstream (task, MSK_STREAM_LOG, NULL, printstr);

    // We assume that a problem file was given as the first command
    // line argument (received in `argv')
    if ( res == MSK_RES_OK )
      res = MSK_readdata (task, argv[1]);

    // Solve the problem remotely
    if ( res == MSK_RES_OK )
      res = MSK_optimizermt (task, argv[2], argv[3], &trm);

    // Print a summary of the solution.
    if ( res == MSK_RES_OK )
      res = MSK_solutionsummary (task, MSK_STREAM_LOG);

    // If an output file was specified, write a solution
    if ( res == MSK_RES_OK && argc >= 3 )
    {
      // We define the output format to be OPF, and tell MOSEK to
      // leave out parameters and problem data from the output file.
      MSK_putintparam (task, MSK_IPAR_WRITE_DATA_FORMAT,    MSK_DATA_FORMAT_OP);
      MSK_putintparam (task, MSK_IPAR_OPF_WRITE_SOLUTIONS,  MSK_ON);
      MSK_putintparam (task, MSK_IPAR_OPF_WRITE_HINTS,      MSK_OFF);
      MSK_putintparam (task, MSK_IPAR_OPF_WRITE_PARAMETERS, MSK_OFF);
      MSK_putintparam (task, MSK_IPAR_OPF_WRITE_PROBLEM,    MSK_OFF);

      res = MSK_writedata (task, argv[2]);
    }

    // Delete task and environment
    MSK_deletetask (&task);
    MSK_deleteenv (&env);
  }
  return res;
}

7.7.2 Asynchronous Remote Optimization

In asynchronous mode the client sends a job to the remote server and the execution of the client code continues. In particular, it is the client’s responsibility to periodically check the optimization status and, when ready, fetch the results. The client can also interrupt optimization. The most relevant methods are:

Source code example

In the example below the program enters in a polling loop that regularly checks whether the result of the optimization is available.

Listing 7.7 Using the OptServer in asynchronous mode. Click here to download.
#include "mosek.h"
#ifdef _WIN32
#include "windows.h"
#else
#include "unistd.h"
#endif

static void MSKAPI printstr(void *handle, const char str[])
{
  printf("%s", str);
}

int main (int argc, char * argv[])
{

  char token[33];

  int         numpolls = 10;
  int         i = 0;

  MSKbooleant respavailable;

  MSKenv_t    env   = NULL;
  MSKtask_t   task  = NULL;

  MSKrescodee res   = MSK_RES_OK;
  MSKrescodee trm;
  MSKrescodee resp;

  const char * filename = "../data/25fv47.mps";
  const char * host     = "karise";
  const char * port     = "30080";

  if (argc < 5)
  {
    fprintf(stderr, "Syntax: opt_server_async filename host port numpolls\n");
    return 0;
  }

  if (argc > 1) filename = argv[1];
  if (argc > 2) host     = argv[2];
  if (argc > 2) port     = argv[3];
  if (argc > 4) numpolls = atoi(argv[4]);

  res = MSK_makeenv (&env, NULL);

  if ( res == MSK_RES_OK )
    res = MSK_maketask (env, 0, 0, &task);
  if ( res == MSK_RES_OK )
    res = MSK_linkfunctotaskstream (task, MSK_STREAM_LOG, NULL, printstr);

  if ( res == MSK_RES_OK )
    res = MSK_readdata (task, filename);

  res = MSK_asyncoptimize(task,
                          host,
                          port,
                          token);
  MSK_deletetask (&task);
  printf("token = %s\n", token);

  if ( res == MSK_RES_OK )
    res = MSK_maketask (env, 0, 0, &task);

  if ( res == MSK_RES_OK )
    res = MSK_readdata (task, filename);

  if ( res == MSK_RES_OK )
    res = MSK_linkfunctotaskstream (task, MSK_STREAM_LOG, NULL, printstr);

  for ( i = 0; i < numpolls &&  res == MSK_RES_OK ; i++)
  {
#if __linux__
    sleep(1);
#elif defined(_WIN32)
    Sleep(1000);
#endif

    printf("poll %d\n ", i);


    res = MSK_asyncpoll( task,
                         host,
                         port,
                         token,
                         &respavailable,
                         &resp,
                         &trm);

    puts("polling done");

    if (respavailable)
    {
      puts("solution available!");
      res = MSK_asyncgetresult(task,
                               host,
                               port,
                               token,
                               &respavailable,
                               &resp,
                               &trm);

      MSK_solutionsummary (task, MSK_STREAM_LOG);
      break;
    }

  }


  if (i == numpolls)
  {
    printf("max num polls reached, stopping %s", host);
    MSK_asyncstop (task, host, port, token);
  }

  MSK_deletetask (&task);
  MSK_deleteenv (&env);

  printf("%s:%d: Result = %d\n", __FILE__, __LINE__, res); fflush(stdout);

  return res;
}