<commit_before>// Copyright 2016 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <MD.hpp>
#include <utils.hpp>

namespace TuneBench {

std::string * getMDOpenCL(const isa::OpenCL::KernelConf & conf, const std::string & dataName, const unsigned int nrAtoms, const float LJ1, const float LJ2) {
  std::string * code = new std::string();
  std::string LJ1_s = isa::utils::toString(LJ1);
  std::string LJ2_s = isa::utils::toString(LJ2);

  if ( LJ1_s.find(".") == std::string::npos ) {
    LJ1_s += ".0f";
  } else {
    LJ1_s += "f";
  }
  if ( LJ2_s.find(".") == std::string::npos ) {
    LJ2_s += ".0f";
  } else {
    LJ2_s += "f";
  }
  // Begin kernel's code
  *code = "__kernel void MD(__global const " + dataName + "4 * const restrict input, __global " + dataName + "4 * const restrict output) {\n"
    "<%DEFPOSITION%>"
    "<%DEFNEIGHBOR%>"
    "<%DEF%>"
    "\n"
    "<%LOAD_POSITION%>"
    "for ( unsigned int neighbor = 0; neighbor < " + isa::utils::toString(nrAtoms) + "; neighbor += " + isa::utils::toString(conf.getNrItemsD1()) + " ) {\n"
    "<%LOADNEIGHBOR%>"
    "<%COMPUTE%>"
    "}\n"
    "// Optional in-thread reduction\n"
    "<%REDUCE%>"
    "// Store\n"
    "<%STORE%>"
    "}\n";
  std::string defPosition_sTemplate = dataName + "4 position<%NUMD0%> = {0.0f, 0.0f, 0.0f, 0.0f};\n";
  std::string defNeighbor_sTemplate = dataName + "4 neighbor<%NUMD1%> = {0.0f, 0.0f, 0.0f, 0.0f};\n";
  std::string def_sTemplate = dataName + "4 accumulator<%NUMD0%>x<%NUMD1%> = {0.0f, 0.0f, 0.0f, 0.0f};\n"
    + dataName + " inverseDistance<%NUMD0%>x<%NUMD1%> = 0.0;\n"
    + dataName + " force<%NUMD0%>x<%NUMD1%> = 0.0;\n";
  std::string loadPosition_sTemplate = "position<%NUMD0%> = input[(get_group_id(0) * " + std::to_string(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0) + <%OFFSETD0%>];\n";
  std::string loadNeighbor_sTemplate = "neighbor<%NUMD1%> = input[neighbor + <%OFFSETD1%>];\n";
  std::vector< std::string > compute_sTemplate(5);
  compute_sTemplate[0] = "inverseDistance<%NUMD0%>x<%NUMD1%> = 1.0f / (((position<%NUMD0%>.x - neighbor<%NUMD1%>.x) * (position<%NUMD0%>.x - neighbor<%NUMD1%>.x)) + ((position<%NUMD0%>.y - neighbor<%NUMD1%>.y) * (position<%NUMD0%>.y - neighbor<%NUMD1%>.y)) + ((position<%NUMD0%>.z - neighbor<%NUMD1%>.z) * (position<%NUMD0%>.z - neighbor<%NUMD1%>.z)));\n";
  compute_sTemplate[1] =  "force<%NUMD0%>x<%NUMD1%> = (inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%>) * ((" + LJ1_s + " * (inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%>)) - " + LJ2_s + ");\n";
  compute_sTemplate[2] = "accumulator<%NUMD0%>x<%NUMD1%>.x += (position<%NUMD0%>.x - neighbor<%NUMD1%>.x) * force<%NUMD0%>x<%NUMD1%>;\n";
  compute_sTemplate[3] = "accumulator<%NUMD0%>x<%NUMD1%>.y += (position<%NUMD0%>.y - neighbor<%NUMD1%>.y) * force<%NUMD0%>x<%NUMD1%>;\n";
  compute_sTemplate[4] = "accumulator<%NUMD0%>x<%NUMD1%>.z += (position<%NUMD0%>.z - neighbor<%NUMD1%>.z) * force<%NUMD0%>x<%NUMD1%>;\n";
  std::string reduce_sTemplate = "accumulator<%NUMD0%>x0 += accumulator<%NUMD0%>x<%NUMD1%>;\n";
  std::string store_sTemplate = "output[(get_group_id(0) * " + std::to_string(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0) + <%OFFSETD0%>] = accumulator<%NUMD0%>x0;\n";
  // End kernel's code

  std::string * defPosition_s = new std::string();
  std::string * defNeighbor_s = new std::string();
  std::string * def_s = new std::string();
  std::string * loadPosition_s = new std::string();
  std::string * loadNeighbor_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * reduce_s = new std::string();
  std::string * store_s = new std::string();
  std::string empty_s("");

  for ( unsigned int d0 = 0; d0 < conf.getNrItemsD0(); d0++ ) {
    std::string d0_s = isa::utils::toString(d0);
    std::string offsetD0_s = isa::utils::toString(d0 * conf.getNrThreadsD0());
    std::string * temp = 0;

    temp = isa::utils::replace(&defPosition_sTemplate, "<%NUMD0%>", d0_s);
    defPosition_s->append(*temp);
    delete temp;
    for ( unsigned int d1 = 0; d1 < conf.getNrItemsD1(); d1++ ) {
      std::string d1_s = isa::utils::toString(d1);
      std::string offsetD1_s = isa::utils::toString(d1);

      temp = isa::utils::replace(&def_sTemplate, "<%NUMD1%>", d1_s);
      def_s->append(*temp);
      delete temp;
      for ( unsigned int computeStatement = 0; computeStatement < 5; computeStatement++ ) {
        temp = isa::utils::replace(&compute_sTemplate[computeStatement], "<%NUMD1%>", d1_s);
        if ( d1 == 0 ) {
          temp = isa::utils::replace(temp, " + <%OFFSETD1%>", empty_s, true);
        } else {
          temp = isa::utils::replace(temp, "<%OFFSETD1%>", offsetD1_s, true);
        }
        compute_s->append(*temp);
        delete temp;
      }
      if ( d1 > 0 ) {
        temp = isa::utils::replace(&reduce_sTemplate, "<%NUMD1%>", d1_s);
        reduce_s->append(*temp);
        delete temp;
      }
    }
    def_s = isa::utils::replace(def_s, "<%NUMD0%>", d0_s, true);
    compute_s = isa::utils::replace(compute_s, "<%NUMD0%>", d0_s, true);
    if ( d0 == 0 ) {
      compute_s = isa::utils::replace(compute_s, " + <%OFFSETD0%>", empty_s, true);
    } else {
      compute_s = isa::utils::replace(compute_s, "<%OFFSETD0%>", offsetD0_s, true);
    }
    temp = isa::utils::replace(&loadPosition_sTemplate, "<%NUMD0%>", d0_s);
    if ( d0 == 0 ) {
      temp = isa::utils::replace(temp, " + <%OFFSETD0%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSETD0%>", offsetD0_s, true);
    }
    loadPosition_s->append(*temp);
    delete temp;
    if ( conf.getNrItemsD1() > 1 ) {
      reduce_s = isa::utils::replace(reduce_s, "<%NUMD0%>", d0_s, true);
    }
    temp = isa::utils::replace(&store_sTemplate, "<%NUMD0%>", d0_s);
    if ( d0 == 0 ) {
      temp = isa::utils::replace(temp, " + <%OFFSETD0%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSETD0%>", offsetD0_s, true);
    }
    store_s->append(*temp);
    delete temp;
  }
  for ( unsigned int d1 = 0; d1 < conf.getNrItemsD1(); d1++ ) {
    std::string d1_s = isa::utils::toString(d1);
    std::string offsetD1_s = isa::utils::toString(d1);
    std::string * temp = 0;

    temp = isa::utils::replace(&defNeighbor_sTemplate, "<%NUMD1%>", d1_s);
    defNeighbor_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&loadNeighbor_sTemplate, "<%NUMD1%>", d1_s);
    if ( d1 == 0 ) {
      temp = isa::utils::replace(temp, " + <%OFFSETD1%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSETD1%>", offsetD1_s, true);
    }
    loadNeighbor_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEFPOSITION%>", *defPosition_s, true);
  code = isa::utils::replace(code, "<%DEFNEIGHBOR%>", *defNeighbor_s, true);
  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%LOAD_POSITION%>", *loadPosition_s, true);
  code = isa::utils::replace(code, "<%LOADNEIGHBOR%>", *loadNeighbor_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%REDUCE%>", *reduce_s, true);
  code = isa::utils::replace(code, "<%STORE%>", *store_s, true);
  delete defPosition_s;
  delete defNeighbor_s;
  delete def_s;
  delete loadPosition_s;
  delete loadNeighbor_s;
  delete compute_s;
  delete reduce_s;
  delete store_s;

  return code;
}

} // TuneBench

<commit_msg>Finalizing the new code organization.<commit_after>// Copyright 2016 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <MD.hpp>
#include <utils.hpp>

namespace TuneBench {

std::string * getMDOpenCL(const isa::OpenCL::KernelConf & conf, const std::string & dataName, const unsigned int nrAtoms, const float LJ1, const float LJ2) {
  std::string * code = new std::string();
  std::string LJ1_s = isa::utils::toString(LJ1);
  std::string LJ2_s = isa::utils::toString(LJ2);

  if ( LJ1_s.find(".") == std::string::npos ) {
    LJ1_s += ".0f";
  } else {
    LJ1_s += "f";
  }
  if ( LJ2_s.find(".") == std::string::npos ) {
    LJ2_s += ".0f";
  } else {
    LJ2_s += "f";
  }
  // Begin kernel's code
  *code = "__kernel void MD(__global const " + dataName + "4 * const restrict input, __global " + dataName + "4 * const restrict output) {\n"
    "<%DEFPOSITION%>"
    "<%DEFNEIGHBOR%>"
    "<%DEF%>"
    "\n"
    "<%LOAD_POSITION%>"
    "for ( unsigned int neighbor = 0; neighbor < " + isa::utils::toString(nrAtoms) + "; neighbor += " + isa::utils::toString(conf.getNrItemsD1()) + " ) {\n"
    "<%LOADNEIGHBOR%>"
    "<%COMPUTE%>"
    "}\n"
    "// Optional in-thread reduction\n"
    "<%REDUCE%>"
    "// Store\n"
    "<%STORE%>"
    "}\n";
  std::string defPosition_sTemplate = dataName + "4 position<%NUMD0%> = {0.0f, 0.0f, 0.0f, 0.0f};\n";
  std::string defNeighbor_sTemplate = dataName + "4 neighbor<%NUMD1%> = {0.0f, 0.0f, 0.0f, 0.0f};\n";
  std::string def_sTemplate = dataName + "4 accumulator<%NUMD0%>x<%NUMD1%> = {0.0f, 0.0f, 0.0f, 0.0f};\n"
    + dataName + " inverseDistance<%NUMD0%>x<%NUMD1%> = 0.0;\n"
    + dataName + " force<%NUMD0%>x<%NUMD1%> = 0.0;\n";
  std::string loadPosition_sTemplate = "position<%NUMD0%> = input[(get_group_id(0) * " + std::to_string(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0) + <%OFFSETD0%>];\n";
  std::string loadNeighbor_sTemplate = "neighbor<%NUMD1%> = input[neighbor + <%OFFSETD1%>];\n";
  std::vector< std::string > compute_sTemplate(5);
  compute_sTemplate[0] = "inverseDistance<%NUMD0%>x<%NUMD1%> = 1.0f / (((position<%NUMD0%>.x - neighbor<%NUMD1%>.x) * (position<%NUMD0%>.x - neighbor<%NUMD1%>.x)) + ((position<%NUMD0%>.y - neighbor<%NUMD1%>.y) * (position<%NUMD0%>.y - neighbor<%NUMD1%>.y)) + ((position<%NUMD0%>.z - neighbor<%NUMD1%>.z) * (position<%NUMD0%>.z - neighbor<%NUMD1%>.z)));\n";
  compute_sTemplate[1] =  "force<%NUMD0%>x<%NUMD1%> = (inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%>) * ((" + LJ1_s + " * (inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%> * inverseDistance<%NUMD0%>x<%NUMD1%>)) - " + LJ2_s + ");\n";
  compute_sTemplate[2] = "accumulator<%NUMD0%>x<%NUMD1%>.x += (position<%NUMD0%>.x - neighbor<%NUMD1%>.x) * force<%NUMD0%>x<%NUMD1%>;\n";
  compute_sTemplate[3] = "accumulator<%NUMD0%>x<%NUMD1%>.y += (position<%NUMD0%>.y - neighbor<%NUMD1%>.y) * force<%NUMD0%>x<%NUMD1%>;\n";
  compute_sTemplate[4] = "accumulator<%NUMD0%>x<%NUMD1%>.z += (position<%NUMD0%>.z - neighbor<%NUMD1%>.z) * force<%NUMD0%>x<%NUMD1%>;\n";
  std::string reduce_sTemplate = "accumulator<%NUMD0%>x0 += accumulator<%NUMD0%>x<%NUMD1%>;\n";
  std::string store_sTemplate = "output[(get_group_id(0) * " + std::to_string(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0) + <%OFFSETD0%>] = accumulator<%NUMD0%>x0;\n";
  // End kernel's code

  std::string * defPosition_s = new std::string();
  std::string * defNeighbor_s = new std::string();
  std::string * def_s = new std::string();
  std::string * loadPosition_s = new std::string();
  std::string * loadNeighbor_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * reduce_s = new std::string();
  std::string * store_s = new std::string();
  std::string empty_s("");

  for ( unsigned int d0 = 0; d0 < conf.getNrItemsD0(); d0++ ) {
    std::string d0_s = isa::utils::toString(d0);
    std::string offsetD0_s = isa::utils::toString(d0 * conf.getNrThreadsD0());
    std::string * temp = 0;

    temp = isa::utils::replace(&defPosition_sTemplate, "<%NUMD0%>", d0_s);
    defPosition_s->append(*temp);
    delete temp;
    for ( unsigned int d1 = 0; d1 < conf.getNrItemsD1(); d1++ ) {
      std::string d1_s = isa::utils::toString(d1);

      temp = isa::utils::replace(&def_sTemplate, "<%NUMD1%>", d1_s);
      def_s->append(*temp);
      delete temp;
      if ( d1 > 0 ) {
        temp = isa::utils::replace(&reduce_sTemplate, "<%NUMD1%>", d1_s);
        reduce_s->append(*temp);
        delete temp;
      }
    }
    def_s = isa::utils::replace(def_s, "<%NUMD0%>", d0_s, true);
    temp = isa::utils::replace(&loadPosition_sTemplate, "<%NUMD0%>", d0_s);
    if ( d0 == 0 ) {
      temp = isa::utils::replace(temp, " + <%OFFSETD0%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSETD0%>", offsetD0_s, true);
    }
    loadPosition_s->append(*temp);
    delete temp;
    if ( conf.getNrItemsD1() > 1 ) {
      reduce_s = isa::utils::replace(reduce_s, "<%NUMD0%>", d0_s, true);
    }
    temp = isa::utils::replace(&store_sTemplate, "<%NUMD0%>", d0_s);
    if ( d0 == 0 ) {
      temp = isa::utils::replace(temp, " + <%OFFSETD0%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSETD0%>", offsetD0_s, true);
    }
    store_s->append(*temp);
    delete temp;
  }
  for ( unsigned int computeStatement = 0; computeStatement < 5; computeStatement++ ) {
    std::string * temp = 0;

    for ( unsigned int d0 = 0; d0 < conf.getNrItemsD0(); d0++ ) {
      std::string d0_s = isa::utils::toString(d0);
      std::string offsetD0_s = isa::utils::toString(d0 * conf.getNrThreadsD0());

      for ( unsigned int d1 = 0; d1 < conf.getNrItemsD1(); d1++ ) {
        std::string d1_s = isa::utils::toString(d1);
        std::string offsetD1_s = isa::utils::toString(d1);

        temp = isa::utils::replace(&compute_sTemplate[computeStatement], "<%NUMD1%>", d1_s);
        if ( d1 == 0 ) {
          temp = isa::utils::replace(temp, " + <%OFFSETD1%>", empty_s, true);
        } else {
          temp = isa::utils::replace(temp, "<%OFFSETD1%>", offsetD1_s, true);
        }
        compute_s->append(*temp);
        delete temp;
      }
      compute_s = isa::utils::replace(compute_s, "<%NUMD0%>", d0_s, true);
      if ( d0 == 0 ) {
        compute_s = isa::utils::replace(compute_s, " + <%OFFSETD0%>", empty_s, true);
      } else {
        compute_s = isa::utils::replace(compute_s, "<%OFFSETD0%>", offsetD0_s, true);
      }
    }
  }
  for ( unsigned int d1 = 0; d1 < conf.getNrItemsD1(); d1++ ) {
    std::string d1_s = isa::utils::toString(d1);
    std::string offsetD1_s = isa::utils::toString(d1);
    std::string * temp = 0;

    temp = isa::utils::replace(&defNeighbor_sTemplate, "<%NUMD1%>", d1_s);
    defNeighbor_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&loadNeighbor_sTemplate, "<%NUMD1%>", d1_s);
    if ( d1 == 0 ) {
      temp = isa::utils::replace(temp, " + <%OFFSETD1%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSETD1%>", offsetD1_s, true);
    }
    loadNeighbor_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEFPOSITION%>", *defPosition_s, true);
  code = isa::utils::replace(code, "<%DEFNEIGHBOR%>", *defNeighbor_s, true);
  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%LOAD_POSITION%>", *loadPosition_s, true);
  code = isa::utils::replace(code, "<%LOADNEIGHBOR%>", *loadNeighbor_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%REDUCE%>", *reduce_s, true);
  code = isa::utils::replace(code, "<%STORE%>", *store_s, true);
  delete defPosition_s;
  delete defNeighbor_s;
  delete def_s;
  delete loadPosition_s;
  delete loadNeighbor_s;
  delete compute_s;
  delete reduce_s;
  delete store_s;

  return code;
}

} // TuneBench

<|endoftext|>


<commit_before>/*
** Copyright (c) 2015 Boise Center Aerospace Laboratory
**
** Author: Kyle Shannon <kyle at pobox dot com>
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pulsereader.hpp"

#define MAX(a, b) (a)>(b)?(a):(b)

/*
** This program opens and reads a pulse waves file, and outputs pertinent
** information for each in/out waveform.  The output should be consumable by
** matlab.
*/

void Usage() {
    printf("pw input.pls output_prefix\n");
    exit(1);
}

int main(int argc, char *argv[]) {
    PULSEreadOpener pOpener;
    PULSEreader *pReader;
    WAVESsampling *sampling;
    int i, j, k;
    char *szPulseOut, *szWaveOut, *szWaveIn, *szBase, *szScanOut;
    FILE *pout;
    FILE *wout;
    FILE **wins;
    int nwins = 1;
    FILE *scanout;

    /* start with one incoming file */
    wins = (FILE**)malloc(sizeof(FILE*) * nwins);

    if(argc < 3) {
        Usage();
    }
    pOpener.set_file_name(argv[1]);
    pReader = pOpener.open();
    if(pReader == 0)
    {
        printf("Could not open file\n");
        return 1;
    }

    /* Open n files for output */
    szPulseOut = (char*)calloc(8192, 1);
    szWaveIn = (char*)calloc(8192, 1);
    szWaveOut = (char*)calloc(8192, 1);
    szScanOut = (char*)calloc(8192, 1);
    szBase = argv[2];
    sprintf(szPulseOut, "%s_PULSE.csv", szBase);
    sprintf(szWaveIn, "%s_WAVE_IN.txt", szBase);
    sprintf(szWaveOut, "%s_WAVE_OUT.txt", szBase);

    /* Scanner metadata */
    PULSEscanner scanner;
    sprintf(szScanOut, "%s_SCANNER.csv", szBase);
    scanout = fopen(szScanOut, "w");
    fprintf(scanout,
            "scanner_id,wave_length,outgoing_pulse_width,scan_pattern,"
            "number_of_mirror_facets,scan_frequency,scan_angle_min,"
            "scan_angle_max,pulse_frequency,beam_diameter_at_exit_aperture,"
            "beam_divergence,minimal_range,maximal_range\n");

    i = 1;
    while(pReader->header.get_scanner(&scanner, i)) {
        fprintf(scanout, "%d,%lf,%lf,%d,%d,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%s\n",
                i, scanner.wave_length, scanner.outgoing_pulse_width,
                scanner.scan_pattern, scanner.number_of_mirror_facets,
                scanner.scan_frequency, scanner.scan_angle_min,
                scanner.scan_angle_max, scanner.pulse_frequency,
                scanner.beam_diameter_at_exit_aperture, scanner.beam_divergence,
                scanner.minimal_range, scanner.maximal_range,
                scanner.description);
        i++;
    }
    fclose(scanout);

    pout = fopen(szPulseOut, "w");
    fprintf(pout, "id,");
    fprintf(pout, "gps,");
    fprintf(pout, "anchor_x,anchor_y,anchor_z,");
    fprintf(pout, "target_x,target_y,target_z,");
    fprintf(pout, "first_return_x,first_return_y,first_return_z,");
    fprintf(pout, "last_return_x,last_return_y,last_return_z,");
    fprintf(pout, "raw_first_return,raw_last_return,");
    fprintf(pout, "edge,scan_dir,"); /* bit, written as uint8 */
    fprintf(pout, "facet,"); /* 2 bit, written as uint8 */
    fprintf(pout, "intensity\n"); /* uint8 */

    const char szPulseFormat[] = "%lld," \
                                 "%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%d,%d," \
                                 "%d," \
                                 "%d\n";

    for(i = 0; i < nwins; i++) {
        sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, i);
        wins[i] = fopen(szWaveIn, "w");
    }
    wout = fopen(szWaveOut, "w");

    double gpsTime;
    double xa, ya, za;
    double xt, yt, zt;
    double dx, dy, dz;
    double xf, yf, zf;
    double xl, yl, zl;
    double toff, xoff, yoff, zoff;
    double tscale, xscale, yscale, zscale;
    double rf, rl;
    unsigned char edge;
    unsigned char scan_dir;
    unsigned char intensity;
    long long p = 0;
    int rc = 0;
    int fi = 0;
    int maxCount = 0;
    int totalPoints = 0;
    int returnCount = 0;
    double progress = 0.;
    /*
    ** Scan the files for the longest pulse, we may need to pad some records
    ** with zeroes.
    */
    printf("Scanning pulses to attain max pulse length\n");
    while(pReader->read_pulse())
    {
        totalPoints++;
        if(pReader->read_waves()) {
            for(i = 0; i < pReader->waves->get_number_of_samplings(); i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    continue;
                }
                for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                    if(maxCount < sampling->get_number_of_samples()) {
                        maxCount = sampling->get_number_of_samples();
                    }
                }
            }
        }
    }
    printf("Using max count of %d for sample length\n", maxCount);
    printf("Total Points: %d\n", totalPoints);
    printf("Reported pulse count: %lld\n", pReader->p_count);

    /* Scale and Offsets */
    toff = pReader->header.t_offset;
    xoff = pReader->header.x_offset;
    yoff = pReader->header.y_offset;
    zoff = pReader->header.z_offset;

    tscale = pReader->header.t_scale_factor;
    xscale = pReader->header.x_scale_factor;
    yscale = pReader->header.y_scale_factor;
    zscale = pReader->header.z_scale_factor;

    pReader->seek(0);
    while(pReader->read_pulse()) {
        /* Write line to pulse file */
        gpsTime = (pReader->pulse.T * tscale) + toff;
        xa = (pReader->pulse.anchor_X * xscale) + xoff;
        ya = (pReader->pulse.anchor_Y * yscale) + yoff;
        za = (pReader->pulse.anchor_Z * zscale) + zoff;
        xt = (pReader->pulse.target_X * xscale) + xoff;
        yt = (pReader->pulse.target_Y * yscale) + yoff;
        zt = (pReader->pulse.target_Z * zscale) + zoff;
        dx = (xt - xa) / 1000.0;
        dy = (yt - ya) / 1000.0;
        dz = (zt - za) / 1000.0;
        xf = xa + pReader->pulse.first_returning_sample * dx;
        yf = ya + pReader->pulse.first_returning_sample * dy;
        zf = za + pReader->pulse.first_returning_sample * dz;
        xl = xa + pReader->pulse.last_returning_sample * dx;
        yl = ya + pReader->pulse.last_returning_sample * dy;
        zl = za + pReader->pulse.last_returning_sample * dz;
        rf = pReader->pulse.first_returning_sample;
        rl = pReader->pulse.last_returning_sample;

        edge = pReader->pulse.edge_of_scan_line;
        scan_dir = pReader->pulse.scan_direction;
        intensity = pReader->pulse.intensity;
        rc = fprintf(pout, szPulseFormat, p,
                                          gpsTime,
                                          xa, ya, za,
                                          xt, yt, zt,
                                          xf, yf, zf,
                                          xl, yl, zl,
                                          rf, rl,
                                          edge, scan_dir,
                                          pReader->pulse.mirror_facet,
                                          intensity);

        if(pReader->read_waves()) {
            returnCount = 0;
            for(i = 0; i < pReader->waves->get_number_of_samplings() && returnCount < 1; i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    fprintf(wout, "%lld ", p);
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        fi = 0;
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wout, "%u ", 0);
                            } else {
                                fprintf(wout, "%u ", sampling->get_sample(k));
                            }
                        }
                    }
                    fprintf(wout, "\n");
                } else if(sampling->get_type() == PULSEWAVES_RETURNING) {
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        /* Need new file? */
                        if(j >= nwins) {
                            wins = (FILE**)realloc(wins, sizeof(FILE*) * ++nwins);
                            sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, nwins-1);
                            wins[j] = fopen(szWaveIn, "w");
                        }
                        fprintf(wins[j], "%lld ", p);
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wins[j], "%u ", 0);
                            } else {
                                fprintf(wins[j], "%u ", sampling->get_sample(k));
                            }
                        }
                        fprintf(wins[j], "\n");
                        returnCount++;
                    }
                } else {
                    printf("Unknown type: %d\n", sampling->get_type());
                }
            }
        } else {
            /* No data??? */
            printf("NO DATA!\n");
        }
        p++;
        if(p % 1000 == 0) {
            progress = ((double)p / (double)totalPoints) * 100.;
            printf("\r%d%% done...", (int)progress);
        }
    }
    printf("\r100%% done.\n");

    free(szPulseOut);
    free(szWaveIn);
    free(szWaveOut);
    free(szScanOut);
    pReader->close();
    delete pReader;

    fclose(pout);
    fclose(wout);
    for(i = 0; i < nwins; i++) {
        fclose(wins[i]);
    }
    free(wins);
    printf("Created %d incoming wave files\n", nwins);
    printf("Total points processed: %lld\n", p);

    return 0;
}

<commit_msg>use compute() interface<commit_after>/*
** Copyright (c) 2015 Boise Center Aerospace Laboratory
**
** Author: Kyle Shannon <kyle at pobox dot com>
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pulsereader.hpp"

#define MAX(a, b) (a)>(b)?(a):(b)

/*
** This program opens and reads a pulse waves file, and outputs pertinent
** information for each in/out waveform.  The output should be consumable by
** matlab.
*/

void Usage() {
    printf("pw input.pls output_prefix\n");
    exit(1);
}

int main(int argc, char *argv[]) {
    PULSEreadOpener pOpener;
    PULSEreader *pReader;
    WAVESsampling *sampling;
    int i, j, k;
    char *szPulseOut, *szWaveOut, *szWaveIn, *szBase, *szScanOut;
    FILE *pout;
    FILE *wout;
    FILE **wins;
    int nwins = 1;
    FILE *scanout;

    /* start with one incoming file */
    wins = (FILE**)malloc(sizeof(FILE*) * nwins);

    if(argc < 3) {
        Usage();
    }
    pOpener.set_file_name(argv[1]);
    pReader = pOpener.open();
    if(pReader == 0)
    {
        printf("Could not open file\n");
        return 1;
    }

    /* Open n files for output */
    szPulseOut = (char*)calloc(8192, 1);
    szWaveIn = (char*)calloc(8192, 1);
    szWaveOut = (char*)calloc(8192, 1);
    szScanOut = (char*)calloc(8192, 1);
    szBase = argv[2];
    sprintf(szPulseOut, "%s_PULSE.csv", szBase);
    sprintf(szWaveIn, "%s_WAVE_IN.txt", szBase);
    sprintf(szWaveOut, "%s_WAVE_OUT.txt", szBase);

    /* Scanner metadata */
    PULSEscanner scanner;
    sprintf(szScanOut, "%s_SCANNER.csv", szBase);
    scanout = fopen(szScanOut, "w");
    fprintf(scanout,
            "scanner_id,wave_length,outgoing_pulse_width,scan_pattern,"
            "number_of_mirror_facets,scan_frequency,scan_angle_min,"
            "scan_angle_max,pulse_frequency,beam_diameter_at_exit_aperture,"
            "beam_divergence,minimal_range,maximal_range\n");

    i = 1;
    while(pReader->header.get_scanner(&scanner, i)) {
        fprintf(scanout, "%d,%lf,%lf,%d,%d,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%s\n",
                i, scanner.wave_length, scanner.outgoing_pulse_width,
                scanner.scan_pattern, scanner.number_of_mirror_facets,
                scanner.scan_frequency, scanner.scan_angle_min,
                scanner.scan_angle_max, scanner.pulse_frequency,
                scanner.beam_diameter_at_exit_aperture, scanner.beam_divergence,
                scanner.minimal_range, scanner.maximal_range,
                scanner.description);
        i++;
    }
    fclose(scanout);

    pout = fopen(szPulseOut, "w");
    fprintf(pout, "id,");
    fprintf(pout, "gps,");
    fprintf(pout, "anchor_x,anchor_y,anchor_z,");
    fprintf(pout, "target_x,target_y,target_z,");
    fprintf(pout, "first_return_x,first_return_y,first_return_z,");
    fprintf(pout, "last_return_x,last_return_y,last_return_z,");
    fprintf(pout, "edge,scan_dir,"); /* bit, written as uint8 */
    fprintf(pout, "facet,"); /* 2 bit, written as uint8 */
    fprintf(pout, "intensity\n"); /* uint8 */

    const char szPulseFormat[] = "%lld," \
                                 "%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%lf,%lf,%lf," \
                                 "%d,%d," \
                                 "%d," \
                                 "%d\n";

    for(i = 0; i < nwins; i++) {
        sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, i);
        wins[i] = fopen(szWaveIn, "w");
    }
    wout = fopen(szWaveOut, "w");

    double gpsTime;
    double xa, ya, za;
    double xt, yt, zt;
    double dx, dy, dz;
    double xf, yf, zf;
    double xl, yl, zl;
    unsigned char edge;
    unsigned char scan_dir;
    unsigned char intensity;
    long long p = 0;
    int rc = 0;
    int fi = 0;
    int maxCount = 0;
    int totalPoints = 0;
    int returnCount = 0;
    double progress = 0.;
    /*
    ** Scan the files for the longest pulse, we may need to pad some records
    ** with zeroes.
    */
    printf("Scanning pulses to attain max pulse length\n");
    while(pReader->read_pulse())
    {
        totalPoints++;
        if(pReader->read_waves()) {
            for(i = 0; i < pReader->waves->get_number_of_samplings(); i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    continue;
                }
                for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                    if(maxCount < sampling->get_number_of_samples()) {
                        maxCount = sampling->get_number_of_samples();
                    }
                }
            }
        }
    }
    printf("Using max count of %d for sample length\n", maxCount);
    printf("Total Points: %d\n", totalPoints);
    printf("Reported pulse count: %lld\n", pReader->p_count);

    pReader->seek(0);
    while(pReader->read_pulse()) {
        /* Write line to pulse file */
        gpsTime = pReader->pulse.get_T();
        xa = pReader->pulse.compute_and_get_anchor_x();
        ya = pReader->pulse.compute_and_get_anchor_y();
        za = pReader->pulse.compute_and_get_anchor_z();
        xt = pReader->pulse.compute_and_get_target_x();
        yt = pReader->pulse.compute_and_get_target_y();
        zt = pReader->pulse.compute_and_get_target_z();
        xf = pReader->pulse.compute_and_get_first_x();
        yf = pReader->pulse.compute_and_get_first_y();
        zf = pReader->pulse.compute_and_get_first_z();
        xl = pReader->pulse.compute_and_get_last_x();
        yl = pReader->pulse.compute_and_get_last_y();
        zl = pReader->pulse.compute_and_get_last_z();

        edge = pReader->pulse.edge_of_scan_line;
        scan_dir = pReader->pulse.scan_direction;
        intensity = pReader->pulse.intensity;
        rc = fprintf(pout, szPulseFormat, p,
                                          gpsTime,
                                          xa, ya, za,
                                          xt, yt, zt,
                                          xf, yf, zf,
                                          xl, yl, zl,
                                          edge, scan_dir,
                                          pReader->pulse.mirror_facet,
                                          intensity);

        if(pReader->read_waves()) {
            returnCount = 0;
            for(i = 0; i < pReader->waves->get_number_of_samplings() && returnCount < 1; i++) {
                sampling = pReader->waves->get_sampling(i);
                if(sampling->get_type() == PULSEWAVES_OUTGOING) {
                    fprintf(wout, "%lld ", p);
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        fi = 0;
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wout, "%u ", 0);
                            } else {
                                fprintf(wout, "%u ", sampling->get_sample(k));
                            }
                        }
                    }
                    fprintf(wout, "\n");
                } else if(sampling->get_type() == PULSEWAVES_RETURNING) {
                    for(j = 0; j < sampling->get_number_of_segments(); j++ ) {
                        /* Need new file? */
                        if(j >= nwins) {
                            wins = (FILE**)realloc(wins, sizeof(FILE*) * ++nwins);
                            sprintf(szWaveIn, "%s_WAVE_IN_%d.txt", szBase, nwins-1);
                            wins[j] = fopen(szWaveIn, "w");
                        }
                        fprintf(wins[j], "%lld ", p);
                        for(k = 0; k < maxCount; k++) {
                            if(k >= sampling->get_number_of_samples()) {
                                fprintf(wins[j], "%u ", 0);
                            } else {
                                fprintf(wins[j], "%u ", sampling->get_sample(k));
                            }
                        }
                        fprintf(wins[j], "\n");
                        returnCount++;
                    }
                } else {
                    printf("Unknown type: %d\n", sampling->get_type());
                }
            }
        } else {
            /* No data??? */
            printf("NO DATA!\n");
        }
        p++;
        if(p % 1000 == 0) {
            progress = ((double)p / (double)totalPoints) * 100.;
            printf("\r%d%% done...", (int)progress);
        }
    }
    printf("\r100%% done.\n");

    free(szPulseOut);
    free(szWaveIn);
    free(szWaveOut);
    free(szScanOut);
    pReader->close();
    delete pReader;

    fclose(pout);
    fclose(wout);
    for(i = 0; i < nwins; i++) {
        fclose(wins[i]);
    }
    free(wins);
    printf("Created %d incoming wave files\n", nwins);
    printf("Total points processed: %lld\n", p);

    return 0;
}

<|endoftext|>


<commit_before>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2003 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <GL/gl.h>
#include <GL/glext.h>
#include <PerfProbe.h>
#include <gmtl/Output.h>
#include <Text.h>
#include <string>

#include <vpr/Perf/ProfileManager.h>
#include <vpr/Perf/ProfileIterator.h>

#include <vrj/Kernel/Kernel.h>

//#include <boost/format.hpp>

namespace
{
   template<class OutIt>
   void splitStr(
      const std::string& s,
      const std::string& sep,
      OutIt dest)
   {
      std::string::size_type left = s.find_first_not_of( sep );
      std::string::size_type right = s.find_first_of( sep, left );
      while( left < right )
      {
         *dest = s.substr( left, right-left );
         ++dest;
         left = s.find_first_not_of( sep, right );
         right = s.find_first_of( sep, left );
      }
   }

   //std::string s = "apple, orange, cherry, peach, grapefruit, cantalope,watermelon";

   //std::vector<std::string> v;
   //split( s, " ,", std::back_inserter(v) );

}

PerfProbe::PerfProbe()
   : mLastUpdateTime(0, vpr::Interval::Base),
     mFrameRate(0), mNumTrackedFrames(500), mMaxFrameRate(200.0f)
{
}

void PerfProbe::update()
{
   // Reset stream for output
   mOverlayTextStream.str(std::string(""));     // Clear it

   // Update frame rate info.
   if(mLastUpdateTime.getBaseVal() != 0)
   {
      vpr::Interval frame_time = vpr::Interval::now() - mLastUpdateTime;
      mFrameTimes.push_front(frame_time.secf());
      mFrameTimes.resize(100);
      mFrameRate = 0.0f;
      for(std::deque<float>::iterator i=mFrameTimes.begin(); i!=mFrameTimes.end(); ++i)
      { mFrameRate += *i; }
      mFrameRate /= float(mFrameTimes.size());
      mFrameRate = 1/mFrameRate;

      // Track frame rates
      mFrameRateHistory.push_front(1.0f/frame_time.secf());    // Add more data about frame rates
      mFrameRateHistory.resize(mNumTrackedFrames,0.0f);        // Resize and fill if needed.
   }
   mLastUpdateTime.setNow();

   mOverlayTextStream << "fps: " << mFrameRate << std::endl;

   mOverlayTextStream << "\nKernel loop profile:\n";

   vpr::ProfileIterator prof_node(vpr::ProfileManager::getRootNode(const_cast<vpr::Thread*>(vrj::Kernel::instance()->getThread())) );
   vpr::ProfileIterator end_node(NULL);
   for(; prof_node != end_node; ++prof_node)
   {
      for(unsigned d=0;d<prof_node.depth();d++)
      { mOverlayTextStream << "   "; }
      mOverlayTextStream << (*prof_node).getName() << "  " << (*prof_node).getSTA().msecf() << std::endl;
   }

}

void PerfProbe::draw()
{
   glPushAttrib(GL_ALL_ATTRIB_BITS);

   glDisable(GL_LIGHTING);
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);

   drawOverlayText();
   drawFrameRateGraph();

   glPopAttrib();
}

void PerfProbe::drawOverlayText()
{
   const float font_height(10.0f);
   const float font_h_spacing(font_height*1.3f);
   float win_height(1000);
   float win_width(win_height * 1.4f);

   std::string overlay_text = mOverlayTextStream.str();
   std::vector<std::string> overlay_lines;
   splitStr(overlay_text,"\n",std::back_inserter(overlay_lines));

   float needed_h = font_h_spacing*float(overlay_lines.size());
   if(needed_h > win_height)
   {
      win_height = needed_h * 1.1f;
      win_width = win_height * 1.4f;
   }

   glMatrixMode( GL_PROJECTION );
   glPushMatrix();
   glLoadIdentity();
   glOrtho( 0.0, win_width, 0.0, win_height, -1.0, 1.0);     // Setup virtual space 1000, 1000

   glMatrixMode( GL_MODELVIEW );
   glPushMatrix();
   glLoadIdentity();

   glDisable(GL_DEPTH_TEST);

   /*
   glBegin(GL_TRIANGLES);
      glColor3f(1.0, 0.0, 0);
      glVertex3f(100,100,-0.5);
      glColor3f(0,1,0);
      glVertex3f(900,100,-0.5);
      glColor3f(0,0,1);
      glVertex3f(450,800,-0.5);
   glEnd();
   */
   //Text::getSingleton()->drawString(Text::StrokeFont, std::string("No Translation"));

   glColor3f(1.0,1.0,0.0);
   glTranslatef(10, win_height-30, 0);
   //float num_lines(overlay_lines.size());

   for (unsigned l=0;l<overlay_lines.size();++l)
   {
      glPushMatrix();
      glTranslatef(0,-font_h_spacing*float(l), 0);
      Text::getSingleton()->drawString(Text::StrokeFont, overlay_lines[l]);
      glPopMatrix();
   }

   glEnable(GL_DEPTH_TEST);

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode( GL_MODELVIEW);
   glPopMatrix();
}

void PerfProbe::drawFrameRateGraph()
{
   float win_height(1000);
   float win_width(1000);
   float pos_x(200),pos_y(875);
   float graph_width(750), graph_height(100);

   glMatrixMode( GL_PROJECTION );
   glPushMatrix();
   glLoadIdentity();
   glOrtho( 0.0, win_width, 0.0, win_height, -1.0, 1.0);     // Setup virtual space 1000, 1000

   glMatrixMode( GL_MODELVIEW );
   glPushMatrix();
   glLoadIdentity();

   glDisable(GL_DEPTH_TEST);

   unsigned num_samples(mFrameRateHistory.size());

   glColor3f(1.0f, 0.0f, 0.0f);
   glBegin(GL_LINE_STRIP);
      for(unsigned i=0;i<num_samples;++i)
      {
         float x_offset(graph_width*(float(i)/float(num_samples)));
         float y_offset(graph_height*(mFrameRateHistory[i]/mMaxFrameRate));
         glVertex3f(pos_x+x_offset, pos_y+y_offset, 0.0f);
      }
   glEnd();

   // Draw border
   glColor3f(0,0,1);
   glBegin(GL_LINE_STRIP);
      glVertex3f(pos_x,pos_y,0);
      glVertex3f(pos_x+graph_width,pos_y,0);
      glVertex3f(pos_x+graph_width,pos_y+graph_height,0);
      glVertex3f(pos_x,pos_y+graph_height,0);
      glVertex3f(pos_x,pos_y,0);
   glEnd();

   glEnable(GL_DEPTH_TEST);

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode( GL_MODELVIEW);
   glPopMatrix();
}
<commit_msg>Get this to compile on Windows.<commit_after>/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2003 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vrj/vrjConfig.h>

#include <GL/gl.h>
#ifndef WIN32
#include <GL/glext.h>
#endif
#include <PerfProbe.h>
#include <gmtl/Output.h>
#include <Text.h>
#include <string>

#include <vpr/Perf/ProfileManager.h>
#include <vpr/Perf/ProfileIterator.h>

#include <vrj/Kernel/Kernel.h>

//#include <boost/format.hpp>

namespace
{
   template<class OutIt>
   void splitStr(
      const std::string& s,
      const std::string& sep,
      OutIt dest)
   {
      std::string::size_type left = s.find_first_not_of( sep );
      std::string::size_type right = s.find_first_of( sep, left );
      while( left < right )
      {
         *dest = s.substr( left, right-left );
         ++dest;
         left = s.find_first_not_of( sep, right );
         right = s.find_first_of( sep, left );
      }
   }

   //std::string s = "apple, orange, cherry, peach, grapefruit, cantalope,watermelon";

   //std::vector<std::string> v;
   //split( s, " ,", std::back_inserter(v) );

}

PerfProbe::PerfProbe()
   : mLastUpdateTime(0, vpr::Interval::Base),
     mFrameRate(0), mNumTrackedFrames(500), mMaxFrameRate(200.0f)
{
}

void PerfProbe::update()
{
   // Reset stream for output
   mOverlayTextStream.str(std::string(""));     // Clear it

   // Update frame rate info.
   if(mLastUpdateTime.getBaseVal() != 0)
   {
      vpr::Interval frame_time = vpr::Interval::now() - mLastUpdateTime;
      mFrameTimes.push_front(frame_time.secf());
      mFrameTimes.resize(100);
      mFrameRate = 0.0f;
      for(std::deque<float>::iterator i=mFrameTimes.begin(); i!=mFrameTimes.end(); ++i)
      { mFrameRate += *i; }
      mFrameRate /= float(mFrameTimes.size());
      mFrameRate = 1/mFrameRate;

      // Track frame rates
      mFrameRateHistory.push_front(1.0f/frame_time.secf());    // Add more data about frame rates
      mFrameRateHistory.resize(mNumTrackedFrames,0.0f);        // Resize and fill if needed.
   }
   mLastUpdateTime.setNow();

   mOverlayTextStream << "fps: " << mFrameRate << std::endl;

   mOverlayTextStream << "\nKernel loop profile:\n";

   vpr::ProfileIterator prof_node(vpr::ProfileManager::getRootNode(const_cast<vpr::Thread*>(vrj::Kernel::instance()->getThread())) );
   vpr::ProfileIterator end_node(NULL);
   for(; prof_node != end_node; ++prof_node)
   {
      for(unsigned d=0;d<prof_node.depth();d++)
      { mOverlayTextStream << "   "; }
      mOverlayTextStream << (*prof_node).getName() << "  " << (*prof_node).getSTA().msecf() << std::endl;
   }

}

void PerfProbe::draw()
{
   glPushAttrib(GL_ALL_ATTRIB_BITS);

   glDisable(GL_LIGHTING);
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);

   drawOverlayText();
   drawFrameRateGraph();

   glPopAttrib();
}

void PerfProbe::drawOverlayText()
{
   const float font_height(10.0f);
   const float font_h_spacing(font_height*1.3f);
   float win_height(1000);
   float win_width(win_height * 1.4f);

   std::string overlay_text = mOverlayTextStream.str();
   std::vector<std::string> overlay_lines;
   splitStr(overlay_text,"\n",std::back_inserter(overlay_lines));

   float needed_h = font_h_spacing*float(overlay_lines.size());
   if(needed_h > win_height)
   {
      win_height = needed_h * 1.1f;
      win_width = win_height * 1.4f;
   }

   glMatrixMode( GL_PROJECTION );
   glPushMatrix();
   glLoadIdentity();
   glOrtho( 0.0, win_width, 0.0, win_height, -1.0, 1.0);     // Setup virtual space 1000, 1000

   glMatrixMode( GL_MODELVIEW );
   glPushMatrix();
   glLoadIdentity();

   glDisable(GL_DEPTH_TEST);

   /*
   glBegin(GL_TRIANGLES);
      glColor3f(1.0, 0.0, 0);
      glVertex3f(100,100,-0.5);
      glColor3f(0,1,0);
      glVertex3f(900,100,-0.5);
      glColor3f(0,0,1);
      glVertex3f(450,800,-0.5);
   glEnd();
   */
   //Text::getSingleton()->drawString(Text::StrokeFont, std::string("No Translation"));

   glColor3f(1.0,1.0,0.0);
   glTranslatef(10, win_height-30, 0);
   //float num_lines(overlay_lines.size());

   for (unsigned l=0;l<overlay_lines.size();++l)
   {
      glPushMatrix();
      glTranslatef(0,-font_h_spacing*float(l), 0);
      Text::getSingleton()->drawString(Text::StrokeFont, overlay_lines[l]);
      glPopMatrix();
   }

   glEnable(GL_DEPTH_TEST);

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode( GL_MODELVIEW);
   glPopMatrix();
}

void PerfProbe::drawFrameRateGraph()
{
   float win_height(1000);
   float win_width(1000);
   float pos_x(200),pos_y(875);
   float graph_width(750), graph_height(100);

   glMatrixMode( GL_PROJECTION );
   glPushMatrix();
   glLoadIdentity();
   glOrtho( 0.0, win_width, 0.0, win_height, -1.0, 1.0);     // Setup virtual space 1000, 1000

   glMatrixMode( GL_MODELVIEW );
   glPushMatrix();
   glLoadIdentity();

   glDisable(GL_DEPTH_TEST);

   unsigned num_samples(mFrameRateHistory.size());

   glColor3f(1.0f, 0.0f, 0.0f);
   glBegin(GL_LINE_STRIP);
      for(unsigned i=0;i<num_samples;++i)
      {
         float x_offset(graph_width*(float(i)/float(num_samples)));
         float y_offset(graph_height*(mFrameRateHistory[i]/mMaxFrameRate));
         glVertex3f(pos_x+x_offset, pos_y+y_offset, 0.0f);
      }
   glEnd();

   // Draw border
   glColor3f(0,0,1);
   glBegin(GL_LINE_STRIP);
      glVertex3f(pos_x,pos_y,0);
      glVertex3f(pos_x+graph_width,pos_y,0);
      glVertex3f(pos_x+graph_width,pos_y+graph_height,0);
      glVertex3f(pos_x,pos_y+graph_height,0);
      glVertex3f(pos_x,pos_y,0);
   glEnd();

   glEnable(GL_DEPTH_TEST);

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode( GL_MODELVIEW);
   glPopMatrix();
}
<|endoftext|>


<commit_before>#include "memory.h"
#include "../phasor-lua.hpp"
#include <cstdint>
#include <array>
#include <Windows.h>

#undef min
#undef max

void readData(lua_State* L, void* dest, void* src, size_t nbytes) {
    DWORD oldProtect = 0;
    if (VirtualProtect(src, nbytes, PAGE_EXECUTE_READ, &oldProtect)) {
        memcpy(dest, src, nbytes);
        VirtualProtect(src, nbytes, oldProtect, &oldProtect);
    } else {
        auto f = boost::format("invalid read: %u bytes from 0x%08X") % nbytes % src;
        luaL_error(L, "%s", f.str().c_str());
    }
}

void writeData(lua_State* L, void* dest, const void* src, size_t nbytes) {
    DWORD oldProtect = 0;
    if (VirtualProtect(dest, nbytes, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        memcpy(dest, src, nbytes);
        VirtualProtect(dest, nbytes, oldProtect, &oldProtect);
    } else {
        auto f = boost::format("invalid write: %u bytes from 0x%08X") % nbytes % src;
        luaL_error(L, "%s", f.str().c_str());
    }
}

template <typename T>
bool checkLimits(double value, T& out) {
    static const T max_value = std::numeric_limits<T>::max();
    static const T min_value = std::numeric_limits<T>::lowest();
    if (value <= max_value && value >= min_value) {
        out = static_cast<T>(value);
        return true;
    } else {
        return false;
    }
}

size_t addBitOffset(size_t x, int& offset) {
    x += offset / 8;
    offset %= 8;
    return x;
}

// --------------------------------------------------------

int l_readbit(lua_State* L) {
    size_t address;
    int bitOffset;

    if (lua_gettop(L) == 3) {
        // legacy: three args mean address, address_offset, bit_offset
        int addrOffset;
        std::tie(address, addrOffset, bitOffset) = phlua::callback::getArguments<size_t, int, int>(L, __FUNCTION__);
        address += addrOffset;
    } else {
        std::tie(address, bitOffset) = phlua::callback::getArguments<size_t, int>(L, __FUNCTION__);
    }

    address = addBitOffset(address, bitOffset);

    std::uint8_t b;
    readData(L, &b, (void*)address, sizeof(b));
    bool bit = (b & (1 << bitOffset)) != 0;

    return phlua::callback::pushReturns(L, std::make_tuple(bit));
}

int l_writebit(lua_State* L) {
    size_t address;
    int bitOffset;
    bool value;

    if (lua_gettop(L) == 4) {
        int addrOffset;
        // legacy: four args mean address, address_offset, bit_offset, value
        std::tie(address, addrOffset, bitOffset, value) = phlua::callback::getArguments<size_t, int, int, bool>(L, __FUNCTION__);
        address += addrOffset;
    } else {
        std::tie(address, bitOffset, value) = phlua::callback::getArguments<size_t, int, bool>(L, __FUNCTION__);
    }

    address = addBitOffset(address, bitOffset);

    std::uint8_t b;
    readData(L, &b, (void*)address, sizeof(b));
    if (value) b |= 1 << bitOffset;
    else b &= ~(1 << bitOffset);
    writeData(L, (void*)address, &b, sizeof(b));

    return 0;
}

// --------------------------------------------------------

template <typename T>
int readNumber(lua_State* L, const char* f) {
    size_t address;
    boost::optional<size_t> offset; // backwards compatibility

    std::tie(address, offset) = phlua::callback::getArguments<size_t, decltype(offset)>(L, f);

    if (offset) address += *offset;

    T x;
    readData(L, &x, (void*)address, sizeof(T));

    return phlua::callback::pushReturns(L, std::make_tuple(x));
}

int l_readbyte(lua_State* L) {
    return readNumber<std::uint8_t>(L, __FUNCTION__);
}

int l_readchar(lua_State* L) {
    return readNumber<std::int8_t>(L, __FUNCTION__);
}

int l_readword(lua_State* L) {
    return readNumber<std::uint16_t>(L, __FUNCTION__);
}

int l_readshort(lua_State* L) {
    return readNumber<std::int16_t>(L, __FUNCTION__);
}

int l_readdword(lua_State* L) {
    return readNumber<std::uint32_t>(L, __FUNCTION__);
}

int l_readint(lua_State* L) {
    return readNumber<std::int32_t>(L, __FUNCTION__);
}

int l_readfloat(lua_State* L) {
    return readNumber<float>(L, __FUNCTION__);
}

int l_readdouble(lua_State* L) {
    return readNumber<double>(L, __FUNCTION__);
}

// --------------------------------------------------------

template <typename T>
int writeNumber(lua_State* L, const char* f) {
    size_t address;
    lua_Number value;

    if (lua_gettop(L) == 3) { // backwards compatibility
        // address, offset, value
        int offset;
        std::tie(address, offset, value) = phlua::callback::getArguments<size_t, int, lua_Number>(L, f);
        address += offset;
    } else {
        std::tie(address, value) = phlua::callback::getArguments<size_t, lua_Number>(L, f);
    }

    T x;
    if (!checkLimits<T>(value, x)) {
        auto f = boost::format("invalid write: value (%.0f) outside of type's range") % value;
        luaL_error(L, "%s", f.str().c_str());
    }

    writeData(L, (void*)address, &x, sizeof(T));
    return 0;
}

int l_writebyte(lua_State* L) {
    return writeNumber<std::uint8_t>(L, __FUNCTION__);
}

int l_writechar(lua_State* L) {
    return writeNumber<std::int8_t>(L, __FUNCTION__);
}

int l_writeword(lua_State* L) {
    return writeNumber<std::uint16_t>(L, __FUNCTION__);
}

int l_writeshort(lua_State* L) {
    return writeNumber<std::int16_t>(L, __FUNCTION__);
}

int l_writedword(lua_State* L) {
    return writeNumber<std::uint32_t>(L, __FUNCTION__);
}

int l_writeint(lua_State* L) {
    return writeNumber<std::int32_t>(L, __FUNCTION__);
}

int l_writefloat(lua_State* L) {
    return writeNumber<float>(L, __FUNCTION__);
}

int l_writedouble(lua_State* L) {
    return writeNumber<double>(L, __FUNCTION__);
}

// --------------------------------------------------------

static const size_t kMaxStringElements = 160;

template <typename T>
int readstring(lua_State* L, const char* f) {
    size_t address;
    boost::optional<unsigned int> length;
    std::array<T, kMaxStringElements+1> dest;

    std::tie(address, length) = phlua::callback::getArguments<size_t, decltype(length)>(L, f);

    size_t readLength = kMaxStringElements;
    if (length) {
        if (length > kMaxStringElements) {
            auto f = boost::format("can only read strings to a maximum size of %u characters") % kMaxStringElements;
            luaL_argerror(L, 2, f.str().c_str());
        }
        readLength *= *length;
    }

    readData(L, dest.data(), (void*)address, readLength*sizeof(T));
    dest[readLength] = 0; // ensure it's null terminated

    return phlua::callback::pushReturns(L, std::make_tuple(dest.data()));
}

int l_readstring(lua_State* L) {
    return readstring<char>(L, __FUNCTION__);
}

int l_readwidestring(lua_State* L) {
    return readstring<wchar_t>(L, __FUNCTION__);
}

// --------------------------------------------------------

template <typename StrType>
int writestring(lua_State* L, const char* f) {
    typedef typename StrType::value_type char_type;
    size_t address;
    boost::optional<size_t> offset;
    StrType s;

    if (lua_gettop(L) == 3) { // backwards compatibility
        std::tie(address, offset, s) = phlua::callback::getArguments<size_t, decltype(offset), StrType>(L, f);
    } else {
        std::tie(address, s) = phlua::callback::getArguments<size_t, StrType>(L, f);
    }

    if (offset) address += *offset;

    size_t byteLength = s.size() * sizeof(char_type);
    writeData(L, (void*)address, s.c_str(), byteLength);
    char_type nullChar = 0;
    writeData(L, (void*)(address + byteLength), &nullChar, sizeof(nullChar));
    return 0;
}

int l_writestring(lua_State* L) {
    return writestring<std::string>(L, __FUNCTION__);
}

int l_writewidestring(lua_State* L) {
    return writestring<std::wstring>(L, __FUNCTION__);
}<commit_msg>Fix readstring<commit_after>#include "memory.h"
#include "../phasor-lua.hpp"
#include <cstdint>
#include <array>
#include <Windows.h>

#undef min
#undef max

void readData(lua_State* L, void* dest, void* src, size_t nbytes) {
    DWORD oldProtect = 0;
    if (VirtualProtect(src, nbytes, PAGE_EXECUTE_READ, &oldProtect)) {
        memcpy(dest, src, nbytes);
        VirtualProtect(src, nbytes, oldProtect, &oldProtect);
    } else {
        auto f = boost::format("invalid read: %u bytes from 0x%08X") % nbytes % src;
        luaL_error(L, "%s", f.str().c_str());
    }
}

void writeData(lua_State* L, void* dest, const void* src, size_t nbytes) {
    DWORD oldProtect = 0;
    if (VirtualProtect(dest, nbytes, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        memcpy(dest, src, nbytes);
        VirtualProtect(dest, nbytes, oldProtect, &oldProtect);
    } else {
        auto f = boost::format("invalid write: %u bytes from 0x%08X") % nbytes % src;
        luaL_error(L, "%s", f.str().c_str());
    }
}

template <typename T>
bool checkLimits(double value, T& out) {
    static const T max_value = std::numeric_limits<T>::max();
    static const T min_value = std::numeric_limits<T>::lowest();
    if (value <= max_value && value >= min_value) {
        out = static_cast<T>(value);
        return true;
    } else {
        return false;
    }
}

size_t addBitOffset(size_t x, int& offset) {
    x += offset / 8;
    offset %= 8;
    return x;
}

// --------------------------------------------------------

int l_readbit(lua_State* L) {
    size_t address;
    int bitOffset;

    if (lua_gettop(L) == 3) {
        // legacy: three args mean address, address_offset, bit_offset
        int addrOffset;
        std::tie(address, addrOffset, bitOffset) = phlua::callback::getArguments<size_t, int, int>(L, __FUNCTION__);
        address += addrOffset;
    } else {
        std::tie(address, bitOffset) = phlua::callback::getArguments<size_t, int>(L, __FUNCTION__);
    }

    address = addBitOffset(address, bitOffset);

    std::uint8_t b;
    readData(L, &b, (void*)address, sizeof(b));
    bool bit = (b & (1 << bitOffset)) != 0;

    return phlua::callback::pushReturns(L, std::make_tuple(bit));
}

int l_writebit(lua_State* L) {
    size_t address;
    int bitOffset;
    bool value;

    if (lua_gettop(L) == 4) {
        int addrOffset;
        // legacy: four args mean address, address_offset, bit_offset, value
        std::tie(address, addrOffset, bitOffset, value) = phlua::callback::getArguments<size_t, int, int, bool>(L, __FUNCTION__);
        address += addrOffset;
    } else {
        std::tie(address, bitOffset, value) = phlua::callback::getArguments<size_t, int, bool>(L, __FUNCTION__);
    }

    address = addBitOffset(address, bitOffset);

    std::uint8_t b;
    readData(L, &b, (void*)address, sizeof(b));
    if (value) b |= 1 << bitOffset;
    else b &= ~(1 << bitOffset);
    writeData(L, (void*)address, &b, sizeof(b));

    return 0;
}

// --------------------------------------------------------

template <typename T>
int readNumber(lua_State* L, const char* f) {
    size_t address;
    boost::optional<size_t> offset; // backwards compatibility

    std::tie(address, offset) = phlua::callback::getArguments<size_t, decltype(offset)>(L, f);

    if (offset) address += *offset;

    T x;
    readData(L, &x, (void*)address, sizeof(T));

    return phlua::callback::pushReturns(L, std::make_tuple(x));
}

int l_readbyte(lua_State* L) {
    return readNumber<std::uint8_t>(L, __FUNCTION__);
}

int l_readchar(lua_State* L) {
    return readNumber<std::int8_t>(L, __FUNCTION__);
}

int l_readword(lua_State* L) {
    return readNumber<std::uint16_t>(L, __FUNCTION__);
}

int l_readshort(lua_State* L) {
    return readNumber<std::int16_t>(L, __FUNCTION__);
}

int l_readdword(lua_State* L) {
    return readNumber<std::uint32_t>(L, __FUNCTION__);
}

int l_readint(lua_State* L) {
    return readNumber<std::int32_t>(L, __FUNCTION__);
}

int l_readfloat(lua_State* L) {
    return readNumber<float>(L, __FUNCTION__);
}

int l_readdouble(lua_State* L) {
    return readNumber<double>(L, __FUNCTION__);
}

// --------------------------------------------------------

template <typename T>
int writeNumber(lua_State* L, const char* f) {
    size_t address;
    lua_Number value;

    if (lua_gettop(L) == 3) { // backwards compatibility
        // address, offset, value
        int offset;
        std::tie(address, offset, value) = phlua::callback::getArguments<size_t, int, lua_Number>(L, f);
        address += offset;
    } else {
        std::tie(address, value) = phlua::callback::getArguments<size_t, lua_Number>(L, f);
    }

    T x;
    if (!checkLimits<T>(value, x)) {
        auto f = boost::format("invalid write: value (%.0f) outside of type's range") % value;
        luaL_error(L, "%s", f.str().c_str());
    }

    writeData(L, (void*)address, &x, sizeof(T));
    return 0;
}

int l_writebyte(lua_State* L) {
    return writeNumber<std::uint8_t>(L, __FUNCTION__);
}

int l_writechar(lua_State* L) {
    return writeNumber<std::int8_t>(L, __FUNCTION__);
}

int l_writeword(lua_State* L) {
    return writeNumber<std::uint16_t>(L, __FUNCTION__);
}

int l_writeshort(lua_State* L) {
    return writeNumber<std::int16_t>(L, __FUNCTION__);
}

int l_writedword(lua_State* L) {
    return writeNumber<std::uint32_t>(L, __FUNCTION__);
}

int l_writeint(lua_State* L) {
    return writeNumber<std::int32_t>(L, __FUNCTION__);
}

int l_writefloat(lua_State* L) {
    return writeNumber<float>(L, __FUNCTION__);
}

int l_writedouble(lua_State* L) {
    return writeNumber<double>(L, __FUNCTION__);
}

// --------------------------------------------------------

static const size_t kMaxStringElements = 160;

template <typename T>
int readstring(lua_State* L, const char* f) {
    size_t address;
    boost::optional<unsigned int> length;
    std::array<T, kMaxStringElements+1> dest;

    std::tie(address, length) = phlua::callback::getArguments<size_t, decltype(length)>(L, f);

    size_t readLength = kMaxStringElements;
    if (length) {
        if (length > kMaxStringElements) {
            auto f = boost::format("can only read strings to a maximum size of %u characters") % kMaxStringElements;
            luaL_argerror(L, 2, f.str().c_str());
        }
        readLength = *length;
    }

    readData(L, dest.data(), (void*)address, readLength*sizeof(T));
    dest[readLength] = 0; // ensure it's null terminated

    return phlua::callback::pushReturns(L, std::make_tuple(dest.data()));
}

int l_readstring(lua_State* L) {
    return readstring<char>(L, __FUNCTION__);
}

int l_readwidestring(lua_State* L) {
    return readstring<wchar_t>(L, __FUNCTION__);
}

// --------------------------------------------------------

template <typename StrType>
int writestring(lua_State* L, const char* f) {
    typedef typename StrType::value_type char_type;
    size_t address;
    boost::optional<size_t> offset;
    StrType s;

    if (lua_gettop(L) == 3) { // backwards compatibility
        std::tie(address, offset, s) = phlua::callback::getArguments<size_t, decltype(offset), StrType>(L, f);
    } else {
        std::tie(address, s) = phlua::callback::getArguments<size_t, StrType>(L, f);
    }

    if (offset) address += *offset;

    size_t byteLength = s.size() * sizeof(char_type);
    writeData(L, (void*)address, s.c_str(), byteLength);
    char_type nullChar = 0;
    writeData(L, (void*)(address + byteLength), &nullChar, sizeof(nullChar));
    return 0;
}

int l_writestring(lua_State* L) {
    return writestring<std::string>(L, __FUNCTION__);
}

int l_writewidestring(lua_State* L) {
    return writestring<std::wstring>(L, __FUNCTION__);
}<|endoftext|>


<commit_before>#include <signal.h>				// for signal, SIGINT
#include <thread>
#include <armadillo>
#include <zmq.hpp>
#include "util.h"
#include "artifact_filter.h"

bool s_interrupted = false;

static void s_signal_handler(int)
{
	s_interrupted = true;
}

static void s_catch_signals(void)
{
	struct sigaction action;
	action.sa_handler = s_signal_handler;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaction(SIGINT, &action, NULL);
	sigaction(SIGQUIT, &action, NULL);
	sigaction(SIGTERM, &action, NULL);
}

void trainer(zmq::context_t &ctx, ArtifactNLMS3 &af)
{

	// for data
	zmq::socket_t socket(ctx, ZMQ_SUB);
	socket.connect("inproc://data");
	socket.setsockopt(ZMQ_SUBSCRIBE, "", 0);	// subscribe to everything

	// for control input
	zmq::socket_t controller(ctx, ZMQ_SUB);
	controller.connect("inproc://controller");
	controller.setsockopt(ZMQ_SUBSCRIBE, "", 0);

	// init poll set
	zmq::pollitem_t items [] = {
		{ socket, 		0, ZMQ_POLLIN, 0 },
		{ controller, 	0, ZMQ_POLLIN, 0}
	};

	while (true) {

		zmq::message_t buf;

		zmq::poll(&items[0], 2, -1); //  -1 means block

		if (items[0].revents & ZMQ_POLLIN) {
			socket.recv(&buf);

			char *ptr = (char *)buf.data();

			u64 nc, ns;

			// parse message
			memcpy(&nc, ptr+0, sizeof(u64));
			memcpy(&ns, ptr+8, sizeof(u64));

			auto f = new float[nc*ns];
			memcpy(f, ptr+24, nc*ns*sizeof(float));

			mat X(nc, ns);
			for (size_t i=0; i<nc; i++) {
				for (size_t k=0; k<ns; k++) {
					X(i, k) = f[i*ns+k];
				}
			}

			af.train(X);

			delete[] f;
		}

		if (items[1].revents & ZMQ_POLLIN) {
			//controller.recv(&buf);
			break;
		}
	}
}

void filter(zmq::context_t &ctx, std::string zin, std::string zout,
            ArtifactNLMS3 &af)
{

	zmq::socket_t socket_in(ctx, ZMQ_SUB);
	socket_in.connect("inproc://data");
	socket_in.setsockopt(ZMQ_SUBSCRIBE, "", 0);	// subscribe to everything

	zmq::socket_t socket_out(ctx, ZMQ_PUB);
	socket_out.bind(zout.c_str());

	// for control input
	zmq::socket_t controller(ctx, ZMQ_SUB);
	controller.connect("inproc://controller");
	controller.setsockopt(ZMQ_SUBSCRIBE, "", 0);

	// init poll set
	zmq::pollitem_t items [] = {
		{ socket_in, 	0, ZMQ_POLLIN, 0 },
		{ controller, 	0, ZMQ_POLLIN, 0 }
	};

	int waiter = 0;
	int counter = 0;
	std::vector<const char *> spinner;
	spinner.emplace_back(">>>    >>>");
	spinner.emplace_back(" >>>    >>");
	spinner.emplace_back("  >>>    >");
	spinner.emplace_back("   >>>    ");
	spinner.emplace_back("    >>>   ");
	spinner.emplace_back(">    >>>  ");
	spinner.emplace_back(">>    >>> ");

	size_t zin_n = zin.find_last_of("/");
	size_t zout_n = zout.find_last_of("/");

	while (true) {

		zmq::message_t msg;

		zmq::poll(&items[0], 2, -1); //  -1 means block

		if (items[0].revents & ZMQ_POLLIN) {
			socket_in.recv(&msg);

			// copy message to buffer
			auto buf = new char[msg.size()];
			memcpy(buf, msg.data(), msg.size());

			u64 nc, ns;

			// parse message
			memcpy(&nc, buf+0, sizeof(u64));
			memcpy(&ns, buf+8, sizeof(u64));

			auto f = new float[nc*ns];
			memcpy(f, buf+24, nc*ns*sizeof(float));

			mat X(nc, ns);
			for (size_t i=0; i<nc; i++) {
				for (size_t j=0; j<ns; j++) {
					X(i, j) = f[i*ns+j];
				}
			}

			mat Y = af.filter(X);

			for (size_t i=0; i<nc; i++) {
				for (size_t j=0; j<ns; j++) {
					f[i*ns+j] -= Y(i, j);
				}
			}

			memcpy(buf+24, f, nc*ns*sizeof(float));

			delete[] f;

			msg.rebuild(24+nc*ns*sizeof(float));
			memcpy(msg.data(), buf, msg.size());
			socket_out.send(msg);

			delete[] buf;
		}

		if (items[1].revents & ZMQ_POLLIN) {
			//controller.recv(&buf);
			break;
		}

		if (waiter % 200 == 0) {
			printf(" [%s]%s[%s]\r",
			       zin.substr(zin_n+1).c_str(),
			       spinner[counter % spinner.size()],
			       zout.substr(zout_n+1).c_str());
			fflush(stdout);
			counter++;
		}
		waiter++;

	}
}

int main(int argc, char *argv[])
{
	// af [zmq_sub] [zmq_pub]

	std::string zin  = argc > 1 ? argv[1] : "ipc:///tmp/broadband.zmq";
	std::string zout = argc > 2 ? argv[2] : "ipc:///tmp/af.zmq";

	printf("artifact filter\n");
	printf("usage: af [zmq_sub] [zmq_pub]\n\n");

	printf("ZMQ SUB: %s\n", zin.c_str());
	printf("ZMQ PUB: %s\n", zout.c_str());
	printf("\n");

	s_catch_signals();

	zmq::context_t zcontext(1);	// single zmq thread

	if (check_running("af")) {
		error("executable already running");
		return 1;
	}

	zmq::socket_t po8e_query_sock(zcontext, ZMQ_REQ);
	po8e_query_sock.connect("ipc:///tmp/po8e-query.zmq");

	u64 nnc; // num neural channels
	zmq::message_t msg(3);
	memcpy(msg.data(), "NNC", 3);
	po8e_query_sock.send(msg);
	msg.rebuild();
	po8e_query_sock.recv(&msg);
	memcpy(&nnc, (u64 *)msg.data(), sizeof(u64));

	ArtifactNLMS3 af(nnc);

	std::thread t1(trainer, std::ref(zcontext), std::ref(af));
	std::thread t2(filter, std::ref(zcontext), zin, zout, std::ref(af));

	// here is what will do:
	// subscribe to messages from po8e (tcp)
	// publish them to the training thread (inproc)
	// publish them to the filter thread (also inproc)
	// the filter thread then publishes the result (tcp)

	// this socket subscribes to messages sent from the po8e
	zmq::socket_t subscriber(zcontext, ZMQ_XSUB);
	subscriber.connect(zin.c_str());

	// this socket publishes received message to local threads
	zmq::socket_t publisher(zcontext, ZMQ_XPUB);
	publisher.bind("inproc://data");

	zmq::socket_t controller(zcontext, ZMQ_PUB);
	controller.bind("inproc://controller");

	// this hooks up the subscriber to the publisher
	try {
		zmq::proxy(subscriber, publisher, nullptr);
	} catch (zmq::error_t &e) {}

	std::string s("KILL");
	msg.rebuild(s.size());
	memcpy(msg.data(), s.c_str(), s.size());
	controller.send(msg);

	t1.join();
	t2.join();
	af.saveWeights("af.h5");
	printf("\nsaving weights\n");
}<commit_msg>af should load weights from file, if the file exists; also should use a larger learning rate<commit_after>#include <signal.h>				// for signal, SIGINT
#include <thread>
#include <sys/stat.h>
#include <armadillo>
#include <zmq.hpp>
#include "util.h"
#include "artifact_filter.h"

bool s_interrupted = false;

static void s_signal_handler(int)
{
	s_interrupted = true;
}

static void s_catch_signals(void)
{
	struct sigaction action;
	action.sa_handler = s_signal_handler;
	action.sa_flags = 0;
	sigemptyset(&action.sa_mask);
	sigaction(SIGINT, &action, NULL);
	sigaction(SIGQUIT, &action, NULL);
	sigaction(SIGTERM, &action, NULL);
}

void trainer(zmq::context_t &ctx, ArtifactNLMS3 &af)
{

	// for data
	zmq::socket_t socket(ctx, ZMQ_SUB);
	socket.connect("inproc://data");
	socket.setsockopt(ZMQ_SUBSCRIBE, "", 0);	// subscribe to everything

	// for control input
	zmq::socket_t controller(ctx, ZMQ_SUB);
	controller.connect("inproc://controller");
	controller.setsockopt(ZMQ_SUBSCRIBE, "", 0);

	// init poll set
	zmq::pollitem_t items [] = {
		{ socket, 		0, ZMQ_POLLIN, 0 },
		{ controller, 	0, ZMQ_POLLIN, 0}
	};

	while (true) {

		zmq::message_t buf;

		zmq::poll(&items[0], 2, -1); //  -1 means block

		if (items[0].revents & ZMQ_POLLIN) {
			socket.recv(&buf);

			char *ptr = (char *)buf.data();

			u64 nc, ns;

			// parse message
			memcpy(&nc, ptr+0, sizeof(u64));
			memcpy(&ns, ptr+8, sizeof(u64));

			auto f = new float[nc*ns];
			memcpy(f, ptr+24, nc*ns*sizeof(float));

			mat X(nc, ns);
			for (size_t i=0; i<nc; i++) {
				for (size_t k=0; k<ns; k++) {
					X(i, k) = f[i*ns+k];
				}
			}

			af.train(X);

			delete[] f;
		}

		if (items[1].revents & ZMQ_POLLIN) {
			//controller.recv(&buf);
			break;
		}
	}
}

void filter(zmq::context_t &ctx, std::string zin, std::string zout,
            ArtifactNLMS3 &af)
{

	zmq::socket_t socket_in(ctx, ZMQ_SUB);
	socket_in.connect("inproc://data");
	socket_in.setsockopt(ZMQ_SUBSCRIBE, "", 0);	// subscribe to everything

	zmq::socket_t socket_out(ctx, ZMQ_PUB);
	socket_out.bind(zout.c_str());

	// for control input
	zmq::socket_t controller(ctx, ZMQ_SUB);
	controller.connect("inproc://controller");
	controller.setsockopt(ZMQ_SUBSCRIBE, "", 0);

	// init poll set
	zmq::pollitem_t items [] = {
		{ socket_in, 	0, ZMQ_POLLIN, 0 },
		{ controller, 	0, ZMQ_POLLIN, 0 }
	};

	int waiter = 0;
	int counter = 0;
	std::vector<const char *> spinner;
	spinner.emplace_back(">>>    >>>");
	spinner.emplace_back(" >>>    >>");
	spinner.emplace_back("  >>>    >");
	spinner.emplace_back("   >>>    ");
	spinner.emplace_back("    >>>   ");
	spinner.emplace_back(">    >>>  ");
	spinner.emplace_back(">>    >>> ");

	size_t zin_n = zin.find_last_of("/");
	size_t zout_n = zout.find_last_of("/");

	while (true) {

		zmq::message_t msg;

		zmq::poll(&items[0], 2, -1); //  -1 means block

		if (items[0].revents & ZMQ_POLLIN) {
			socket_in.recv(&msg);

			// copy message to buffer
			auto buf = new char[msg.size()];
			memcpy(buf, msg.data(), msg.size());

			u64 nc, ns;

			// parse message
			memcpy(&nc, buf+0, sizeof(u64));
			memcpy(&ns, buf+8, sizeof(u64));

			auto f = new float[nc*ns];
			memcpy(f, buf+24, nc*ns*sizeof(float));

			mat X(nc, ns);
			for (size_t i=0; i<nc; i++) {
				for (size_t j=0; j<ns; j++) {
					X(i, j) = f[i*ns+j];
				}
			}

			mat Y = af.filter(X);

			for (size_t i=0; i<nc; i++) {
				for (size_t j=0; j<ns; j++) {
					f[i*ns+j] -= Y(i, j);
				}
			}

			memcpy(buf+24, f, nc*ns*sizeof(float));

			delete[] f;

			msg.rebuild(24+nc*ns*sizeof(float));
			memcpy(msg.data(), buf, msg.size());
			socket_out.send(msg);

			delete[] buf;
		}

		if (items[1].revents & ZMQ_POLLIN) {
			//controller.recv(&buf);
			break;
		}

		if (waiter % 200 == 0) {
			printf(" [%s]%s[%s]\r",
			       zin.substr(zin_n+1).c_str(),
			       spinner[counter % spinner.size()],
			       zout.substr(zout_n+1).c_str());
			fflush(stdout);
			counter++;
		}
		waiter++;

	}
}

int main(int argc, char *argv[])
{
	// af [zmq_sub] [zmq_pub]

	std::string zin  = argc > 1 ? argv[1] : "ipc:///tmp/broadband.zmq";
	std::string zout = argc > 2 ? argv[2] : "ipc:///tmp/af.zmq";

	printf("artifact filter\n");
	printf("usage: af [zmq_sub] [zmq_pub]\n\n");

	printf("ZMQ SUB: %s\n", zin.c_str());
	printf("ZMQ PUB: %s\n", zout.c_str());
	printf("\n");

	s_catch_signals();

	zmq::context_t zcontext(1);	// single zmq thread

	if (check_running("af")) {
		error("executable already running");
		return 1;
	}

	zmq::socket_t po8e_query_sock(zcontext, ZMQ_REQ);
	po8e_query_sock.connect("ipc:///tmp/po8e-query.zmq");

	u64 nnc; // num neural channels
	zmq::message_t msg(3);
	memcpy(msg.data(), "NNC", 3);
	po8e_query_sock.send(msg);
	msg.rebuild();
	po8e_query_sock.recv(&msg);
	memcpy(&nnc, (u64 *)msg.data(), sizeof(u64));

	ArtifactNLMS3 af(nnc);

	struct stat buf;
	if (stat("af.h5", &buf) == 0) { // ie file exists
		printf("loading af weights\n");
		af.loadWeights("af.h5");
	}

	af.setMu(1e-5);

	std::thread t1(trainer, std::ref(zcontext), std::ref(af));
	std::thread t2(filter, std::ref(zcontext), zin, zout, std::ref(af));

	// here is what will do:
	// subscribe to messages from po8e (tcp)
	// publish them to the training thread (inproc)
	// publish them to the filter thread (also inproc)
	// the filter thread then publishes the result (tcp)

	// this socket subscribes to messages sent from the po8e
	zmq::socket_t subscriber(zcontext, ZMQ_XSUB);
	subscriber.connect(zin.c_str());

	// this socket publishes received message to local threads
	zmq::socket_t publisher(zcontext, ZMQ_XPUB);
	publisher.bind("inproc://data");

	zmq::socket_t controller(zcontext, ZMQ_PUB);
	controller.bind("inproc://controller");

	// this hooks up the subscriber to the publisher
	try {
		zmq::proxy(subscriber, publisher, nullptr);
	} catch (zmq::error_t &e) {}

	std::string s("KILL");
	msg.rebuild(s.size());
	memcpy(msg.data(), s.c_str(), s.size());
	controller.send(msg);

	t1.join();
	t2.join();
	af.saveWeights("af.h5");
	printf("\nsaving weights\n");
}<|endoftext|>


<commit_before>// XYlib library test program
// Import x-y data from the sample files in "test" dir
// Licence: GNU General Public License version 2
// $Id: testmain.cpp $

#include "testmain.h"
#include "common.h"
#include <string.h>

using namespace std;
using namespace xylib;

int main(int argc, char* argv[])
{
    string in_file, out_file, ft;

    if (1 == argc)
    {
        usage(argv[0]);
        return -1;
    }

    for (int i=1; i<argc; ++i)
    {
        // auto test mode
        if (0 == strncmp("-a", argv[i], 2))
        {
            /*
            test_xy_file();
            test_uxd_file();
            test_diffracat_v2_raw_file();
            */
            test_diffracat_v1_raw_file();
            return 0;
        }
        // user specifying mode
        else
        {
            if (0 == strncmp("-i", argv[i], 2))
            {
                in_file = argv[++i];
            }
            else if (0 == strncmp("-o", argv[i], 2))
            {
                out_file = argv[++i];
            }
            else if (0 == strncmp("-t", argv[i], 2))
            {
                ft = argv[++i];
            }
            else
            {
                usage(argv[0]);
                return -1;
            }
        }
    }

    XY_Data data;
    try
    {
        XYlib::load_file(in_file, data, ft);
        data.export_xy_file(out_file);
    }
    catch (const runtime_error e)
    {
        cerr << e.what() << endl;
    }
	return 0;
}

// test files at: test/text
void test_xy_file()
{
    vector<string> fnames;
    fnames.push_back("xy_text.TXt");
    fnames.push_back("with_sigma.txt"); // sigma has not been read, modify later

    load_export(fnames, "text");
}

// test files at: test/uxd
void test_uxd_file()
{
    vector<string> fnames;
    for (int i=1; i<7; ++i)
        fnames.push_back(string("sample") + S(i) + ".uxd");

    fnames.push_back("synchro.uxd");

    load_export(fnames, "uxd");
}

// test files at: test/diffracat_v1_raw
void test_diffracat_v1_raw_file()
{
    vector<string> fnames;

    for (int i=2; i<7; ++i)
        fnames.push_back(string("sample") + S(i) + ".raw");

    load_export(fnames, "diffracat_v1_raw");
}

// test files at: test/diffracat_v2_raw
void test_diffracat_v2_raw_file()
{
    vector<string> fnames;
    fnames.push_back("QTZQUIN.RAW");
    fnames.push_back("CORKLZ20.RAW");

    load_export(fnames, "diffracat_v2_raw");
}

// helper functions
//////////////////////////////////////////////////////////////////////////

// load and export
void load_export(const std::vector<std::string>& fnames,
                 const std::string& ftype
                 )
{
    XY_Data data;

    vector<string>::const_iterator it;
    string src_base = TEST_DIR + ftype + PATH_SEP;
    string out_base = OUT_DIR + ftype + PATH_SEP;
    string src, out;

    for (it = fnames.begin(); it != fnames.end(); ++it)
    {
        src = src_base + *it;
        out = out_base + *it + "_tr.txt";
        try
        {
            XYlib::load_file(src, data, ftype);
            data.export_xy_file(out);
        }
        catch (const runtime_error e)
        {
            cerr << e.what() << endl;
            continue;
        }

        cout << src << " has been exported to " << out << endl;
    }
}

void usage(char* prog_name)
{
    cout << "usage:" << endl;
    //cout << "\t" << prog_name << "[-a] [-i in_file -o out_file -t file_type]" << endl;
    cout << "\t" << "testmain " << "[-a] [-i in_file -o out_file -t file_type]" << endl;
    cout << "\t\t-a: auto test using the existing test files." << endl;
    cout << "\t\t-i: input file path." << endl;
    cout << "\t\t-o: output file path." << endl;
    cout << "\t\t-t: format type of the input file." << endl;
}<commit_msg>added cmd line argument to let user specify in_file and out_file<commit_after>// XYlib library test program
// Import x-y data from the sample files in "test" dir
// Licence: GNU General Public License version 2
// $Id: testmain.cpp $

#include "testmain.h"
#include "common.h"
#include <string.h>

using namespace std;
using namespace xylib;

int main(int argc, char* argv[])
{
    string in_file, out_file, ft;

    if (1 == argc)
    {
        usage(argv[0]);
        return -1;
    }

    for (int i=1; i<argc; ++i)
    {
        // auto test mode
        if (0 == strncmp("-a", argv[i], 2))
        {
            /*
            test_xy_file();
            test_uxd_file();
            test_diffracat_v2_raw_file();
            */
            test_diffracat_v1_raw_file();
            return 0;
        }
        // user specifying mode
        else
        {
            if (0 == strncmp("-i", argv[i], 2))
            {
                in_file = argv[++i];
            }
            else if (0 == strncmp("-o", argv[i], 2))
            {
                out_file = argv[++i];
            }
            else if (0 == strncmp("-t", argv[i], 2))
            {
                ft = argv[++i];
            }
            else
            {
                usage(argv[0]);
                return -1;
            }
        }
    }

    if (in_file.empty() || out_file.empty() || ft.empty())
    {
        usage(argv[0]);
        return -1;
    }

    XY_Data data;
    try
    {
        XYlib::load_file(in_file, data, ft);
        data.export_xy_file(out_file);
        const << in_file << "has been exported to " << out_file << endl;
    }
    catch (const runtime_error e)
    {
        cerr << e.what() << endl;
    }
	return 0;
}

// test files at: test/text
void test_xy_file()
{
    vector<string> fnames;
    fnames.push_back("xy_text.TXt");
    fnames.push_back("with_sigma.txt"); // sigma has not been read, modify later

    load_export(fnames, "text");
}

// test files at: test/uxd
void test_uxd_file()
{
    vector<string> fnames;
    for (int i=1; i<7; ++i)
        fnames.push_back(string("sample") + S(i) + ".uxd");

    fnames.push_back("synchro.uxd");

    load_export(fnames, "uxd");
}

// test files at: test/diffracat_v1_raw
void test_diffracat_v1_raw_file()
{
    vector<string> fnames;

    for (int i=2; i<7; ++i)
        fnames.push_back(string("sample") + S(i) + ".raw");

    load_export(fnames, "diffracat_v1_raw");
}

// test files at: test/diffracat_v2_raw
void test_diffracat_v2_raw_file()
{
    vector<string> fnames;
    fnames.push_back("QTZQUIN.RAW");
    fnames.push_back("CORKLZ20.RAW");

    load_export(fnames, "diffracat_v2_raw");
}

// helper functions
//////////////////////////////////////////////////////////////////////////

// load and export
void load_export(const std::vector<std::string>& fnames,
                 const std::string& ftype
                 )
{
    XY_Data data;

    vector<string>::const_iterator it;
    string src_base = TEST_DIR + ftype + PATH_SEP;
    string out_base = OUT_DIR + ftype + PATH_SEP;
    string src, out;

    for (it = fnames.begin(); it != fnames.end(); ++it)
    {
        src = src_base + *it;
        out = out_base + *it + "_tr.txt";
        try
        {
            XYlib::load_file(src, data, ftype);
            data.export_xy_file(out);
        }
        catch (const runtime_error e)
        {
            cerr << e.what() << endl;
            continue;
        }

        cout << src << " has been exported to " << out << endl;
    }
}

void usage(char* prog_name)
{
    cout << "usage:" << endl;
    //cout << "\t" << prog_name << "[-a] [-i in_file -o out_file -t file_type]" << endl;
    cout << "\t" << "testmain " << "[-a] [-i in_file -o out_file -t file_type]" << endl;
    cout << "\t\t-a: auto test using the existing test files." << endl;
    cout << "\t\t-i: input file path." << endl;
    cout << "\t\t-o: output file path." << endl;
    cout << "\t\t-t: format type of the input file." << endl;
}<|endoftext|>