next up previous contents
Next: References Up: No Title Previous: Example Implementation for ptrace

 

Example Implementation for Visual Quantify

The most common and simple way to use Visual Quantify is by using its Graphical User Interface (GUI). However, a more powerful and more complex way to use the package is provided by its built-in APIgif library functions which may be inserted into the test programs source code. In this case, the access to the program is more complex but it offers the interesting flexibility which is required for the use as accurate fitness function in GA programming.

In order to to install the API functions properly, the header file pure.hgif must be included into the test program's source code. The test program must be recompiled and rebuilt. Finally, quantify may be called from a command shell without the display of any windows on the screen.

The QuantifyClearData() function removes any data collected so far from the system and resets all counters. This function must be called before any recording is started. The function also indicates the begin of a ``snapshot'', which may be stored separately into a file. The functions QuantifyStartRecordingData() and QuantifyStopRecordingData() are used in order to restrict the gathering of timing data to the section of the program which is enclosed by the two commands. This is usually the actual test procedure. It avoids any computational overhead as only statements within the two function calls are timed. QuantifySaveData() writes a previously taken ``snapshot'' into a binary or a text file, depending on a command-line option.

The following source code examples show the usage of visual quantify for repeated program timing:

// fitness function in the GA program
double fitness (int size,
                unsigned char* parameter_string,
                char* exe_name) {
  ofstream out;

  out.open("qfyifce.dat",ios::binary); // write parameter 
  out.write(parameter_string,size);    // to binary file
  out.close();
  if (call_qfy(exe_name,size) != 0)    // call qantify and wait
    return (-1.0);
  // read the quantify result from file
  // and return the fitness
  return ((double)qfy_txt_scan(exe_name));
}

// create a new quantify process
int call_qfy (char* exe_name, int size) {
  char str_size[8];
  switch (fork()) {
  case -1: perror("fork");
           return(-1);
           break;
  case 0:  {
           ostrstream oss (str_size,8);
           oss << size;
           // call qantify with option /SaveTextData and
           // Test Program <exe_name> which takes the
           // parameter <str_size>
           execlp("quantify", "quantify", "/save-text-data",
                  exe_name, str_size, NULL);
           perror("execlp");
           break;
           }
  default:
           wait(); // for for quantify to return
  }
  return (0);
}

// scan quantify's result file for the fitness
int qfy_txt_scan (char* exe_name) {

  const int LSZ = 256;           // max size of input
  const char* KEY = "function";  // keyword to search for
  char line [LSZ];               // input read buffer
  char name [LSZ];               // filename
  ifstream in;                   // input file
  char tok1[LSZ], tok2[LSZ];     // input line tokens
  int tok3, tok4, tok5;
  ostrstream oss (name,LSZ);
  oss << exename << ".txt";      // strcat <exename>.txt

  // read input file line by line until eof or key found
  while (in.getline(line,LSZ,'\n')) {
    istrstream ins (line, LSZ);  // split line into tokens
    ins >> tok1 >> tok2 >> tok3 >> tok4 >> tok5;
    if (strcmp(tok1,KEY) == 0) { // keyword found
      in.close();
      return(tok5);              // return F+D time (=fitness)
    }
  }
  in.close();
  return (-1);
}

// main program which is "instrumentalized" by quantify
int main (int argc, char* argv[]) {
  int size;
  unsigned char* buffer;
  ifstream in;
  istrstream iss (argv[1],8);
  iss >> size;

  buffer = new unsigned char[size];
  in.open("qfyifce.dat", ios::in|ios::binary);
  in.read(buffer,size);
  in.close();
  QuantifyClearData();
  QuantifyStartRecordingData();
  TestProgram (*(Test_Type*)&buffer); // call the test procedure
  QuantifyStopRecordingData();
  QuantifySaveData();
  delete [] buffer;
}

As Quantify cannot be executed directly as daemon running in the background and waiting for a client's request, a network interface is obviously an appropriate solution. Basically, every type of IPCgif could be used, but the usage of network sockets provides easy implementation, hardware independence and distribution. In this case, Visual Quantify is started in order to perform timing on a network server which executes the test program. The network server is executed on a remote host waiting for a GA process - the client - to send its produced input parameters. Although, a socket implementation is already in use and has proved valuable, a detailed description including code examples is beyond the scope of this report.


next up previous contents
Next: References Up: No Title Previous: Example Implementation for ptrace

Commander
Thu Oct 22 15:09:09 GMT 1998