示例#1
0
 /** Destructor. */
 ~Worker() {
    if ( handle ) {
       handle.kill();
       handle.join();
    }
    if ( cplex.getImpl() ) {
       cplex.userfunction(USERACTION_REMOVECALLBACK, 0, NULL, 0, 0, NULL);
       cplex.end();
    }
    rng.end();
    x.end();
    obj.end();
    model.end();
 }
示例#2
0
   /** Create a new worker.
    * The constructor mainly does the following:
    * - create an IloCplex instance that refers to a remote worker,
    * - load the model in <code>modelfile</code>,
    * - setup parameters depending on this worker's index,
    * - start an asynchronous solve.
    * If anything fails then an exception will be thrown.
    * @param env The environment used for instantiating Ilo* objects.
    * @param i The index of the worker to be created. This also
    *          determines the parameter settings to use in this worker.
    * @param s  A pointer to the global solve state.
    * @param transport  The transport name for the IloCplex constructor.
    * @param argc       The argument count for the IloCplex constructor.
    * @param argv       The array of transport arguments for the IloCplex
    *                   constructor.
    * @param modelfile  Name of the model to be loaded into the worker.
    * @param output     The output mode.
    * @param objdiff    The minimal difference between so that two
    *                   consecutive objective function values are considered
    *                   different.
    */
   Worker(IloEnv env, int i, SolveState *s, char const *transport,
          int argc, char const **argv, char const *modelfile,
          OUTPUT output, double objdiff)
      : idx(i), state(s), model(env), cplex(0), handle(0),
        primal(IloInfinity), dual(-IloInfinity),
        obj(env), x(env), rng(env), infoHandler(this), outb(idx), outs(&outb)
   {
      try {
         // Create remote object, setup output and load the model.
         cplex = IloCplex(model, transport, argc, argv);
         switch (output) {
         case OUTPUT_SILENT:
            // Disable output on the output and warning stream.
            cplex.setOut(env.getNullStream());
            cplex.setWarning(env.getNullStream());
            break;
         case OUTPUT_PREFIXED:
            // Redirect output to our custom stream.
            cplex.setOut(outs);
            cplex.setWarning(outs);
            break;
         case OUTPUT_LOG:
            // Nothing to do here. By default output is enabled.
            break;
         }
         cplex.importModel(model, modelfile, obj, x, rng);
         if ( obj.getSense() == IloObjective::Minimize ) {
            primal = -IloInfinity;
            dual = IloInfinity;
         }

         // We set the thread count for each solver to 1 so that we do not
         // run into problems if multiple solves are performed on the same
         // machine.
         cplex.setParam(IloCplex::Param::Threads, 1);
         // Each worker runs with a different random seed. This way we
         // get different paths through the tree even if the other
         // parameter settings are the same.
         cplex.setParam(IloCplex::Param::RandomSeed, idx);
         // Apply parameter settings.
         for (class ParamValue const *vals = settings[idx % NUMSETTINGS].values;
              vals->isValid(); ++vals)
            vals->apply(cplex);

         // Install callback and set objective change.
         int status = cplex.userfunction (USERACTION_ADDCALLBACK,
                                          0, NULL, 0, 0, NULL);
         if ( status )
            throw status;
         IloCplex::Serializer s;
         s.add(objdiff);
         status = cplex.userfunction (USERACTION_CHANGEOBJDIFF,
                                      s.getRawLength(), s.getRawData(),
                                      0, 0, NULL);
         if ( status )
            throw status;

         // Register the handler that will process info messages sent
         // from the worker.
         cplex.setRemoteInfoHandler(&infoHandler);

         // Everything is setup. Launch the asynchronous solve.
         handle = cplex.solve(true);
      } catch (...) {
         // In case of an exception we need to take some special
         // cleanup actions. Note that if we get here then the
         // solve cannot have been started and we don't need to
         // kill or join the asynchronous solve.
         if ( cplex.getImpl() )
            cplex.end();
         rng.end();
         x.end();
         obj.end();
         model.end();
         throw;
      }
   }