<commit_before>// -*- C++ -*-
// Implementation of: ????
//
// Copyright (C) 2010 by John Weiss
// This program is free software; you can redistribute it and/or modify
// it under the terms of the Artistic License, included as the file
// "LICENSE" in the source code archive.
//
// This program 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.
//
// You should have received a copy of the file "LICENSE", containing
// the License John Weiss originally placed this program under.
//
static const char* const
xFOOx_cc__="RCS $Id$";

// Includes
//
#include <iostream>
#include <string>
#include <vector>
#include <exception>

//#include <boost/something.hpp>

//TODO// Note:  The guts of the ProgramOptions helper code now resides in its
//TODO//        own class.  You will need to do one of the following:
//TODO//        1. Use -ljpwTools and -I$JPWLIB_BASE/include
//TODO//        2. Symlink to the following files in $JPWLIB_BASE/src:
//TODO//           - tracing/Trace.{h,cc}
//TODO//           - tracing/LibTrace.h
//TODO//           - boost_helpers/ProgramOptions_Base.{h,cc}
//TODO//           You'll need to add the two *.cc files to your Makefile.
//TODO//        3. Like #2, but copy the files instead of symlinking to them.
#include "ProgramOptions_Base.h"
#include "xFOOx.h"

//
// Using Decls.
//
using std::string;
using std::vector;
using std::exception;
using std::cerr;
using std::cout;
using std::endl;
using std::flush;

//
// Static variables
//

//
// Typedefs
//

/////////////////////////

//
// Class:  ProgramOptions
//

// NOTE:
//
// When using boost::program_options, you need to compile or link using:
//   '-lboost_program_options-mt'
// (Check your Boost build to see if you have to remove the '-mt' suffix.)
class ProgramOptions : public jpwTools::boost_helpers::ProgramOptions_Base
{
    typedef jpwTools::boost_helpers::ProgramOptions_Base Base_t;
public:
    // Member variables for individually storing program options.
    //   ADD HERE:
    /*
    example_type myExample;
     */

    // C'tor
    //
    // There are a few different ways you can use the base-class.
    //
    explicit ProgramOptions(const string& programName)
        : Base_t(programName)
    {
        m__docDetails_FakeOption[2] = 0;
    }

    // Implement this function (see below).
    void defineOptionsAndVariables();

    // Implement this function (below), or remove this fn.
    bool validateParsedOptions();
};

/////////////////////////

//
// ProgramOptions Member Functions
//

// Define your commandline options in this function.
//
// The options "--help", "--verbose", "--config", and "--help-config" will
// be defined for you.  No need to put them in here.
void ProgramOptions::defineOptionsAndVariables()
{
    using namespace boost::program_options;

    //
    // Commandline-only Options
    //

    //-----
    // About the Documentation String:
    //
    // - Long lines are automatically wrapped.
    // - It can contain '\n' chars.
    // - Any space following a '\n' indents the first line accordingly, but
    //   not any wrapped lines.
    // - The '\t' character is always removed.
    // - A '\t' character in the first "line" adds extra indentation to all
    //   subsequently-wrapped lines.  Its position marks the position of the
    //   left margin for the wrapped lines.
    //-----

    addOpts()
        ("exampleOpt,e", "Documentation of the --exampleOpt.")
        //("ex2", value<example_type>(&myExample)
        // "Example with a specific storage variable.")
        ("ex3", value<int>()->default_value(42),
         "Example with a default value and fixed data type.")
        //("xil", value< <std::vector<int> >()->compositing(),
        // "Example of a \"list option\".  Specifying \"--xil\" multiple "
        // "times just adds another element to the list.")
        ;

    // Define the "Hidden" Commandline Parameters
    //
    // These options will not appear in the "usage" message.

    /*
    addOpts(Base_t::HIDDEN)
        ("secretExampleOpt,s", bool_switch(&secretExampleSwitch),
         "Documentation of the --secretExampleOpt.\t"
         "This example shows how to define a \"boolean switch\" option."
         )
        ("ex2",
         value<int>(&m_ex2)->default_value(-1)
         ->implicit_value(42)->zero_tokens(),
         "Example of how to have an option that takes a value, but doesn't "
         "_require_ it.\n"
         "In this example, the variable \"m_ex2\" has the value '-1' if the "
         "option isn't specified on the cmdline.  Specifying \"--ex2\" "
         "sets \"m_ex2\" to '42'.  Specifying \"--ex2=12345\" sets "
         "\"m_ex2\" to '12345', the value used.")
        ("ex3", value<int>(&m_ztEx)->zero_tokens(),
         "Like \"--ex2\", but without a default value or an implicit "
         "value.  If you pass \"--ex3\" on the commandline, \"m_ztEx\" "
         "isn't set.  Instead, you'll have to use "
         "'progOptInst[\"ex3\"].empty()' to determine if it's set (where "
         "'progOptInst' is a ProgramOptions object).")
        ;
    */

    //
    // The Positional Parameters:
    //

    /*
    addPosnParam("pp1",
                 "The description of the first positional parameter.");
    addPosnParam("pp2",
                 "The description of the second positional parameter.");
    addPosnParam("pp_list::all_remaining",
                 //value< std::vector<std::string> >,
                 "The description of the remaining positional parameters.",
                 -1);
    */

    //
    // The Configuration File Variables:
    //

    /*
    addCfgVars()
        ("example", "An example")
        ("group1.example",
         "An example of a configfile variable in a group.  You can specify "
         "the group using ini-file syntax, or you can use Java-style "
         "synax for the group+variable name.")
        ("oddname.group.foo",
         "Here, if you used ini-file style groups, you'd have to specify "
         "[oddname.group] as the group heading.  Cfgfile vars never have "
         "a '.' in their names, unless you're using Java-style syntax.")
        ;
    */

    //
    // Configuration File Variables that can also be passed as Commandline
    // Options:
    //

    /*
    addCfgVars(Base_t::SHARED)
        ("sharedEx", "A common opt.")
        ;

    // Can also do this:
    //addOpts(Base_t::SHARED)
    //    ("sharedEx", "A common opt.")
    //    ;
    */

    //
    // Define the additional/verbose/enhanced configuration file
    // documentation:
    //

    addConfigHelpDetails("\n"
                         "* \tHeading\n"
                         "\n  \t" // Line end/begin boilerplate
                         "Some stuff about one or more of the config "
                         "file variables."
                         "\n");
}

// Performs more complex program option validation.
//
// Remove this override if you don't need it.
bool ProgramOptions::validateParsedOptions()
{
    // Example:  Handle a missing configuration file.
    // Delete or modify as needed.
    if(m__cfgfile.empty()) {
        throw boost::program_options::invalid_option_value(
            "No configuration file specified!  \"--config\" is "
            "a required option.");
    }
}

/////////////////////////

//
// General Function Definitions
//

/////////////////////////

//
// Functions "main()" and "cxx_main()"
//

// This is where all of your main handling should go.
int cxx_main(const string& myName,
             const string& myPath,
             const ProgramOptions& opts)
{
    // How to retrieve entries from 'opts':
    //     opts["option"].as<type>()
    //
    // To check if the option is unset or wasn't passed:
    //     opts["option"].empty()
    //
    // To check if an option with a default value wasn't passed:
    //     opts["option"].defaulted()
}

int main(int argc, char* argv[])
{
    // Split off the name of the executable from its path.
    string myName(argv[0]);
    string::size_type last_pathsep = myName.find_last_of('/');
    string myPath;
    if(last_pathsep != string::npos) {
        myPath = myName.substr(0, last_pathsep+1);
        myName.erase(0, last_pathsep+1);
    }

    // Call cxx_main(), which is where almost all of your code should go.
    try {
        ProgramOptions myOpts(myName);
        myOpts.parse(argc, argv);

        return cxx_main(myName, myPath, myOpts);
    } catch(FooException& ex) {
        cerr << "Caught Foo: " << ex.what() << endl;
        return 3;
    } catch(boost::program_options::duplicate_option_error& ex) {
        cerr << "Fatal Internal Programming Error:  "
             << endl
             << ex.what()
             << endl << endl;
        return 9;
    } catch(boost::program_options::error& ex) {
        cerr << "Error while parsing program options: " << ex.what()
             << endl << endl
             << "Rerun as \"" << myName << " --help\" for usage."
             << endl;
        return 1;
    } catch(exception& ex) {
         cerr << endl << "(Std) Exception caught: \""
              << ex.what() << "\"" << endl;
    } catch(...) {
        cerr << "Unknown exception caught." << endl;
    }
    return -1;
}

/////////////////////////
//
// End
<commit_msg>- Renaming variable that hides a member.<commit_after>// -*- C++ -*-
// Implementation of: ????
//
// Copyright (C) 2010 by John Weiss
// This program is free software; you can redistribute it and/or modify
// it under the terms of the Artistic License, included as the file
// "LICENSE" in the source code archive.
//
// This program 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.
//
// You should have received a copy of the file "LICENSE", containing
// the License John Weiss originally placed this program under.
//
static const char* const
xFOOx_cc__="RCS $Id$";

// Includes
//
#include <iostream>
#include <string>
#include <vector>
#include <exception>

//#include <boost/something.hpp>

//TODO// Note:  The guts of the ProgramOptions helper code now resides in its
//TODO//        own class.  You will need to do one of the following:
//TODO//        1. Use -ljpwTools and -I$JPWLIB_BASE/include
//TODO//        2. Symlink to the following files in $JPWLIB_BASE/src:
//TODO//           - tracing/Trace.{h,cc}
//TODO//           - tracing/LibTrace.h
//TODO//           - boost_helpers/ProgramOptions_Base.{h,cc}
//TODO//           You'll need to add the two *.cc files to your Makefile.
//TODO//        3. Like #2, but copy the files instead of symlinking to them.
#include "ProgramOptions_Base.h"
#include "xFOOx.h"

//
// Using Decls.
//
using std::string;
using std::vector;
using std::exception;
using std::cerr;
using std::cout;
using std::endl;
using std::flush;

//
// Static variables
//

//
// Typedefs
//

/////////////////////////

//
// Class:  ProgramOptions
//

// NOTE:
//
// When using boost::program_options, you need to compile or link using:
//   '-lboost_program_options-mt'
// (Check your Boost build to see if you have to remove the '-mt' suffix.)
class ProgramOptions : public jpwTools::boost_helpers::ProgramOptions_Base
{
    typedef jpwTools::boost_helpers::ProgramOptions_Base Base_t;
public:
    // Member variables for individually storing program options.
    //   ADD HERE:
    /*
    example_type myExample;
     */

    // C'tor
    //
    // There are a few different ways you can use the base-class.
    //
    explicit ProgramOptions(const string& theProgramName)
        : Base_t(theProgramName)
    {
        m__docDetails_FakeOption[2] = 0;
    }

    // Implement this function (see below).
    void defineOptionsAndVariables();

    // Implement this function (below), or remove this fn.
    bool validateParsedOptions();
};

/////////////////////////

//
// ProgramOptions Member Functions
//

// Define your commandline options in this function.
//
// The options "--help", "--verbose", "--config", and "--help-config" will
// be defined for you.  No need to put them in here.
void ProgramOptions::defineOptionsAndVariables()
{
    using namespace boost::program_options;

    //
    // Commandline-only Options
    //

    //-----
    // About the Documentation String:
    //
    // - Long lines are automatically wrapped.
    // - It can contain '\n' chars.
    // - Any space following a '\n' indents the first line accordingly, but
    //   not any wrapped lines.
    // - The '\t' character is always removed.
    // - A '\t' character in the first "line" adds extra indentation to all
    //   subsequently-wrapped lines.  Its position marks the position of the
    //   left margin for the wrapped lines.
    //-----

    addOpts()
        ("exampleOpt,e", "Documentation of the --exampleOpt.")
        //("ex2", value<example_type>(&myExample)
        // "Example with a specific storage variable.")
        ("ex3", value<int>()->default_value(42),
         "Example with a default value and fixed data type.")
        //("xil", value< <std::vector<int> >()->compositing(),
        // "Example of a \"list option\".  Specifying \"--xil\" multiple "
        // "times just adds another element to the list.")
        ;

    // Define the "Hidden" Commandline Parameters
    //
    // These options will not appear in the "usage" message.

    /*
    addOpts(Base_t::HIDDEN)
        ("secretExampleOpt,s", bool_switch(&secretExampleSwitch),
         "Documentation of the --secretExampleOpt.\t"
         "This example shows how to define a \"boolean switch\" option."
         )
        ("ex2",
         value<int>(&m_ex2)->default_value(-1)
         ->implicit_value(42)->zero_tokens(),
         "Example of how to have an option that takes a value, but doesn't "
         "_require_ it.\n"
         "In this example, the variable \"m_ex2\" has the value '-1' if the "
         "option isn't specified on the cmdline.  Specifying \"--ex2\" "
         "sets \"m_ex2\" to '42'.  Specifying \"--ex2=12345\" sets "
         "\"m_ex2\" to '12345', the value used.")
        ("ex3", value<int>(&m_ztEx)->zero_tokens(),
         "Like \"--ex2\", but without a default value or an implicit "
         "value.  If you pass \"--ex3\" on the commandline, \"m_ztEx\" "
         "isn't set.  Instead, you'll have to use "
         "'progOptInst[\"ex3\"].empty()' to determine if it's set (where "
         "'progOptInst' is a ProgramOptions object).")
        ;
    */

    //
    // The Positional Parameters:
    //

    /*
    addPosnParam("pp1",
                 "The description of the first positional parameter.");
    addPosnParam("pp2",
                 "The description of the second positional parameter.");
    addPosnParam("pp_list::all_remaining",
                 //value< std::vector<std::string> >,
                 "The description of the remaining positional parameters.",
                 -1);
    */

    //
    // The Configuration File Variables:
    //

    /*
    addCfgVars()
        ("example", "An example")
        ("group1.example",
         "An example of a configfile variable in a group.  You can specify "
         "the group using ini-file syntax, or you can use Java-style "
         "synax for the group+variable name.")
        ("oddname.group.foo",
         "Here, if you used ini-file style groups, you'd have to specify "
         "[oddname.group] as the group heading.  Cfgfile vars never have "
         "a '.' in their names, unless you're using Java-style syntax.")
        ;
    */

    //
    // Configuration File Variables that can also be passed as Commandline
    // Options:
    //

    /*
    addCfgVars(Base_t::SHARED)
        ("sharedEx", "A common opt.")
        ;

    // Can also do this:
    //addOpts(Base_t::SHARED)
    //    ("sharedEx", "A common opt.")
    //    ;
    */

    //
    // Define the additional/verbose/enhanced configuration file
    // documentation:
    //

    addConfigHelpDetails("\n"
                         "* \tHeading\n"
                         "\n  \t" // Line end/begin boilerplate
                         "Some stuff about one or more of the config "
                         "file variables."
                         "\n");
}

// Performs more complex program option validation.
//
// Remove this override if you don't need it.
bool ProgramOptions::validateParsedOptions()
{
    // Example:  Handle a missing configuration file.
    // Delete or modify as needed.
    if(m__cfgfile.empty()) {
        throw boost::program_options::invalid_option_value(
            "No configuration file specified!  \"--config\" is "
            "a required option.");
    }
}

/////////////////////////

//
// General Function Definitions
//

/////////////////////////

//
// Functions "main()" and "cxx_main()"
//

// This is where all of your main handling should go.
int cxx_main(const string& myName,
             const string& myPath,
             const ProgramOptions& opts)
{
    // How to retrieve entries from 'opts':
    //     opts["option"].as<type>()
    //
    // To check if the option is unset or wasn't passed:
    //     opts["option"].empty()
    //
    // To check if an option with a default value wasn't passed:
    //     opts["option"].defaulted()
}

int main(int argc, char* argv[])
{
    // Split off the name of the executable from its path.
    string myName(argv[0]);
    string::size_type last_pathsep = myName.find_last_of('/');
    string myPath;
    if(last_pathsep != string::npos) {
        myPath = myName.substr(0, last_pathsep+1);
        myName.erase(0, last_pathsep+1);
    }

    // Call cxx_main(), which is where almost all of your code should go.
    try {
        ProgramOptions myOpts(myName);
        myOpts.parse(argc, argv);

        return cxx_main(myName, myPath, myOpts);
    } catch(FooException& ex) {
        cerr << "Caught Foo: " << ex.what() << endl;
        return 3;
    } catch(boost::program_options::duplicate_option_error& ex) {
        cerr << "Fatal Internal Programming Error:  "
             << endl
             << ex.what()
             << endl << endl;
        return 9;
    } catch(boost::program_options::error& ex) {
        cerr << "Error while parsing program options: " << ex.what()
             << endl << endl
             << "Rerun as \"" << myName << " --help\" for usage."
             << endl;
        return 1;
    } catch(exception& ex) {
         cerr << endl << "(Std) Exception caught: \""
              << ex.what() << "\"" << endl;
    } catch(...) {
        cerr << "Unknown exception caught." << endl;
    }
    return -1;
}

/////////////////////////
//
// End
<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/core/tpu/tpu_api_dlsym_initializer.h"

#include <dlfcn.h>

#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/platform/status.h"
#if !defined(PLATFORM_GOOGLE)
#include "tensorflow/core/tpu/tpu_api.h"
#include "tensorflow/core/tpu/tpu_system_device.h"
#include "tensorflow/stream_executor/tpu/tpu_platform.h"
#endif

#define TFTPU_SET_FN(Struct, FnName)                                         \
  Struct->FnName##Fn =                                                       \
      reinterpret_cast<decltype(FnName)*>(dlsym(library_handle, #FnName));   \
  if (!(Struct->FnName##Fn)) {                                               \
    LOG(ERROR) << #FnName " not available in this library.";                 \
    return errors::Unimplemented(#FnName " not available in this library."); \
  }

// Reminder: Update tpu_library_loader_windows.cc if you are adding new publicly
// visible methods.

namespace tensorflow {
namespace tpu {

#if defined(PLATFORM_GOOGLE)
Status InitializeTpuLibrary(void* library_handle) {
  return errors::Unimplemented("You must statically link in a TPU library.");
}
#else  // PLATFORM_GOOGLE
#include "tensorflow/core/tpu/tpu_library_init_fns.inc"

Status InitializeTpuLibrary(void* library_handle) {
  Status s = InitializeTpuStructFns(library_handle);

  // TPU platform registration must only be performed after the library is
  // loaded. We do not want to register a TPU platform in XLA without the
  // supporting library providing the necessary APIs.
  if (s.ok()) {
    // TODO(frankchn): Make initialization actually work
    // Initialize TPU platform when the platform code is loaded from a library.
    // InitializeApiFn()->TfTpu_InitializeFn();

    RegisterTpuPlatform();
    RegisterTpuSystemDevice();
  }

  return s;
}

bool FindAndLoadTpuLibrary() {
  void* library = dlopen("libtftpu.so", RTLD_NOW);
  if (library) {
    InitializeTpuLibrary(library);
  }
  return true;
}

static bool tpu_library_finder = FindAndLoadTpuLibrary();
#endif  // PLATFORM_GOOGLE

}  // namespace tpu
}  // namespace tensorflow
<commit_msg>Call TfTpu_Initialize() to initialize relevant bits of the TPU framework when loading the TPU library<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

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 "tensorflow/core/tpu/tpu_api_dlsym_initializer.h"

#include <dlfcn.h>

#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/platform/status.h"
#if !defined(PLATFORM_GOOGLE)
#include "tensorflow/core/tpu/tpu_api.h"
#include "tensorflow/core/tpu/tpu_system_device.h"
#include "tensorflow/stream_executor/tpu/tpu_platform.h"
#endif

#define TFTPU_SET_FN(Struct, FnName)                                         \
  Struct->FnName##Fn =                                                       \
      reinterpret_cast<decltype(FnName)*>(dlsym(library_handle, #FnName));   \
  if (!(Struct->FnName##Fn)) {                                               \
    LOG(ERROR) << #FnName " not available in this library.";                 \
    return errors::Unimplemented(#FnName " not available in this library."); \
  }

// Reminder: Update tpu_library_loader_windows.cc if you are adding new publicly
// visible methods.

namespace tensorflow {
namespace tpu {

#if defined(PLATFORM_GOOGLE)
Status InitializeTpuLibrary(void* library_handle) {
  return errors::Unimplemented("You must statically link in a TPU library.");
}
#else  // PLATFORM_GOOGLE
#include "tensorflow/core/tpu/tpu_library_init_fns.inc"

Status InitializeTpuLibrary(void* library_handle) {
  Status s = InitializeTpuStructFns(library_handle);

  // TPU platform registration must only be performed after the library is
  // loaded. We do not want to register a TPU platform in XLA without the
  // supporting library providing the necessary APIs.
  if (s.ok()) {
    void (*initialize_fn)();
    initialize_fn = reinterpret_cast<decltype(initialize_fn)>(
        dlsym(library_handle, "TfTpu_Initialize"));
    (*initialize_fn)();

    RegisterTpuPlatform();
    RegisterTpuSystemDevice();
  }

  return s;
}

bool FindAndLoadTpuLibrary() {
  void* library = dlopen("libtftpu.so", RTLD_NOW);
  if (library) {
    InitializeTpuLibrary(library);
  }
  return true;
}

static bool tpu_library_finder = FindAndLoadTpuLibrary();
#endif  // PLATFORM_GOOGLE

}  // namespace tpu
}  // namespace tensorflow
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <ctime>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include "gaussian.h"

#define BLUR_RADIUS 3
#define PATH_COUNT 16
#define MAX_SHORT 65535
#define SMALL_PENALTY 3
#define LARGE_PENALTY 20
#define DEBUG false

struct path {
    short rowDiff;
    short colDiff;
    short index;
};

void printArray(unsigned short ***array, int rows, int cols, int depth) {
    for (int d = 0; d < depth; ++d) {
        std::cout << "disparity: " << d << std::endl;
        for (int row = 0; row < rows; ++row) {
            for (int col = 0; col < cols; ++col) {
                std::cout << "\t" << array[row][col][d];
            }
            std::cout << std::endl;
        }
    }
}

unsigned short calculatePixelCostOneWayBT(int row, int leftCol, int rightCol, const cv::Mat &leftImage, const cv::Mat &rightImage) {

    char leftValue, rightValue, beforeRightValue, afterRightValue, rightValueMinus, rightValuePlus, rightValueMin, rightValueMax;

    leftValue = leftImage.at<uchar>(row, leftCol);
    rightValue = rightImage.at<uchar>(row, rightCol);

    if (rightCol > 0) {
        beforeRightValue = rightImage.at<uchar>(row, rightCol - 1);
    } else {
        beforeRightValue = rightValue;
    }

    if (rightCol + 1 < rightImage.cols) {
        afterRightValue = rightImage.at<uchar>(row, rightCol + 1);
    } else {
        afterRightValue = rightValue;
    }

    rightValueMinus = round((rightValue + beforeRightValue) / 2.f);
    rightValuePlus = round((rightValue + afterRightValue) / 2.f);

    rightValueMin = std::min(rightValue, std::min(rightValueMinus, rightValuePlus));
    rightValueMax = std::max(rightValue, std::max(rightValueMinus, rightValuePlus));

    return std::max(0, std::max((leftValue - rightValueMax), (rightValueMin - leftValue)));
}

inline unsigned short calculatePixelCostBT(int row, int leftCol, int rightCol, const cv::Mat &leftImage, const cv::Mat &rightImage) {
    return std::min(calculatePixelCostOneWayBT(row, leftCol, rightCol, leftImage, rightImage),
        calculatePixelCostOneWayBT(row, rightCol, leftCol, rightImage, leftImage));
}

void calculatePixelCost(cv::Mat &firstImage, cv::Mat &secondImage, int disparityRange, unsigned short ***C) {
    for (int row = 0; row < firstImage.rows; ++row) {
        for (int col = 0; col < firstImage.cols; ++col) {
            for (int d = 0; d < disparityRange; ++d) {
                C[row][col][d] = calculatePixelCostBT(row, col, col - d, firstImage, secondImage);
            }
        }
    }
}

void initializePaths(std::vector<path> &paths, unsigned short pathCount) {
    for (unsigned short i = 0; i < pathCount; ++i) {
        paths.push_back(path());
    }

    if(paths.size() >= 2) {
        paths[0].rowDiff = 0;
        paths[0].colDiff = 1;
        paths[0].index = 0;

        paths[1].rowDiff = 0;
        paths[1].colDiff = -1;
        paths[1].index = 1;
    }

    if(paths.size() >= 4) {
        paths[2].rowDiff = -1;
        paths[2].colDiff = 0;
        paths[2].index = 2;

        paths[3].rowDiff = 1;
        paths[3].colDiff = 0;
        paths[3].index = 3;
    }

    if(paths.size() >= 8) {
        paths[4].rowDiff = -1;
        paths[4].colDiff = 1;
        paths[4].index = 4;

        paths[5].rowDiff = 1;
        paths[5].colDiff = 1;
        paths[5].index = 5;

        paths[6].rowDiff = 1;
        paths[6].colDiff = -1;
        paths[6].index = 6;

        paths[7].rowDiff = -1;
        paths[7].colDiff = -1;
        paths[7].index = 7;
    }

    if(paths.size() >= 16) {
        paths[8].rowDiff = -2;
        paths[8].colDiff = 1;
        paths[8].index = 8;

        paths[9].rowDiff = -2;
        paths[9].colDiff = -1;
        paths[9].index = 9;

        paths[10].rowDiff = 2;
        paths[10].colDiff = 1;
        paths[10].index = 10;

        paths[11].rowDiff = 2;
        paths[11].colDiff = -1;
        paths[11].index = 11;

        paths[12].rowDiff = 1;
        paths[12].colDiff = -2;
        paths[12].index = 12;

        paths[13].rowDiff = -1;
        paths[13].colDiff = -2;
        paths[13].index = 13;

        paths[14].rowDiff = 1;
        paths[14].colDiff = 2;
        paths[14].index = 14;

        paths[15].rowDiff = -1;
        paths[15].colDiff = 2;
        paths[15].index = 15;
    }
}

unsigned short aggregateCost(int row, int col, int d, path &p, int rows, int cols, int disparityRange, unsigned short ***C, unsigned short ****A, unsigned short ***S, unsigned int iter) {
    unsigned short aggregatedCost = 0;
    aggregatedCost += C[row][col][d];

    if(DEBUG) {
        for (unsigned int i = 0; i < iter; ++i) {
            printf(" ");
        }
        printf("{P%d}[%d][%d](d%d)\n", p.index, row, col, d);
    }

    if (A[p.index][row][col][d] != MAX_SHORT) {
        if(DEBUG) {
            for (unsigned int i = 0; i < iter; ++i) {
                printf(" ");
            }
            printf("{P%d}[%d][%d](d%d)-> %d<CACHED>\n", p.index, row, col, d, A[p.index][row][col][d]);
        }
        return A[p.index][row][col][d];
    }

    if (row + p.rowDiff < 0 || row + p.rowDiff >= rows || col + p.colDiff < 0 || col + p.colDiff >= cols) {
        // border
        A[p.index][row][col][d] = aggregatedCost;
        if(DEBUG) {
            for (unsigned int i = 0; i < iter; ++i) {
                printf(" ");
            }
            printf("{P%d}[%d][%d](d%d)-> %d <BORDER>\n", p.index, row, col, d, A[p.index][row][col][d]);
        }
        return A[p.index][row][col][d];

        return aggregatedCost;
    }

    unsigned short minPrev, minPrevOther, prev, prevPlus, prevMinus;
    prev = minPrev = minPrevOther = prevPlus = prevMinus = MAX_SHORT;

    for (int disp = 0; disp < disparityRange; ++disp) {
        unsigned short tmp = aggregateCost(row + p.rowDiff, col + p.colDiff, disp, p, rows, cols, disparityRange, C, A, S, ++iter);
        if(minPrev > tmp) {
            minPrev = tmp;
        }

        if(disp == d) {
            prev = tmp;
        } else if(disp == d + 1) {
            prevPlus = tmp;
        } else if (disp == d - 1) {
            prevMinus = tmp;
        } else {
            if(minPrevOther > tmp + LARGE_PENALTY) {
                minPrevOther = tmp + LARGE_PENALTY;
            }
        }
    }

    aggregatedCost += std::min(std::min((int)prevPlus + SMALL_PENALTY, (int)prevMinus + SMALL_PENALTY), std::min((int)prev, (int)minPrevOther + LARGE_PENALTY));
    aggregatedCost -= minPrev;

    A[p.index][row][col][d] = aggregatedCost;

    if(DEBUG) {
        for (unsigned int i = 0; i < iter; ++i) {
            printf(" ");
        }
        printf("{P%d}[%d][%d](d%d)-> %d<CALCULATED>\n", p.index, row, col, d, A[p.index][row][col][d]);
    }

    return aggregatedCost;
}

void aggregateCosts(int rows, int cols, int disparityRange, std::vector<path> &paths, unsigned short ***C, unsigned short ****A, unsigned short ***S) {
    for (unsigned long p = 0; p < paths.size(); ++p) {
        for (int row = 0; row < rows; ++row) {
            for (int col = 0; col < cols; ++col) {
                for (int d = 0; d < disparityRange; ++d) {
                    S[row][col][d] += aggregateCost(row, col, d, paths[p], rows, cols, disparityRange, C, A, S, 0);
                }
            }
        }
    }
}

void computeDisparity(unsigned short ***S, int rows, int cols, int disparityRange, cv::Mat &disparityMap) {
    unsigned int disparity = 0, minCost;
    for (int row = 0; row < rows; ++row) {
        for (int col = 0; col < cols; ++col) {
            minCost = 65535;
            for (int d = disparityRange - 1; d >= 0; --d) {
                if(minCost > S[row][col][d]) {
                    minCost = S[row][col][d];
                    disparity = d;
                }
            }
            disparityMap.at<uchar>(row, col) = disparity;
        }
    }
}

void saveDisparityMap(cv::Mat &disparityMap, int disparityRange, char* outputFile) {
    double factor = 256.0 / disparityRange;
    for (int row = 0; row < disparityMap.rows; ++row) {
        for (int col = 0; col < disparityMap.cols; ++col) {
            disparityMap.at<uchar>(row, col) *= factor;
        }
    }
    cv::imwrite(outputFile, disparityMap);
}

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

    if (argc != 5) {
        std::cerr << "Usage: " << argv[0] << " <left image> <right image> <output image file> <disparity range>" << std::endl;
        return -1;
    }

    char *firstFileName = argv[1];
    char *secondFileName = argv[2];
    char *outFileName = argv[3];

    cv::Mat firstImage;
    cv::Mat secondImage;
    firstImage = cv::imread(firstFileName, CV_LOAD_IMAGE_GRAYSCALE);
    secondImage = cv::imread(secondFileName, CV_LOAD_IMAGE_GRAYSCALE);

    if(!firstImage.data || !secondImage.data) {
        std::cerr <<  "Could not open or find one of the images!" << std::endl;
        return -1;
    }

    unsigned int disparityRange = atoi(argv[4]);
    unsigned short ***C; // pixel cost array W x H x D
    unsigned short ***S; // aggregated cost array W x H x D
    unsigned short ****A; // path cost array P x W x H x D
    std::vector<path> paths;

    initializePaths(paths, PATH_COUNT);

    /*
    * TODO
    * variable LARGE_PENALTY
    */

    clock_t begin = clock();

    std::cout << "Allocating space..." << std::endl;

    // allocate cost arrays
    C = new unsigned short**[firstImage.rows];
    S = new unsigned short**[firstImage.rows];
    for (int row = 0; row < firstImage.rows; ++row) {
        C[row] = new unsigned short*[firstImage.cols];
        S[row] = new unsigned short*[firstImage.cols]();
        for (int col = 0; col < firstImage.cols; ++col) {
            C[row][col] = new unsigned short[disparityRange];
            S[row][col] = new unsigned short[disparityRange](); // initialize to 0
        }
    }

    A = new unsigned short ***[paths.size()];
    for (unsigned long p = 0; p < paths.size(); ++p) {
        A[p] = new unsigned short **[firstImage.rows];
        for (int row = 0; row < firstImage.rows; ++row) {
            A[p][row] = new unsigned short*[firstImage.cols];
            for (int col = 0; col < firstImage.cols; ++col) {
                A[p][row][col] = new unsigned short[disparityRange];
                for (unsigned int d = 0; d < disparityRange; ++d) {
                    A[p][row][col][d] = MAX_SHORT;
                }
            }
        }
    }

    std::cout << "Smoothing images..." << std::endl;
    grayscaleGaussianBlur(firstImage, firstImage, BLUR_RADIUS);
    grayscaleGaussianBlur(secondImage, secondImage, BLUR_RADIUS);

    std::cout << "Calculating pixel cost for the image..." << std::endl;
    calculatePixelCost(firstImage, secondImage, disparityRange, C);
    if(DEBUG) {
        printArray(C, firstImage.rows, firstImage.cols, disparityRange);
    }
    std::cout << "Aggregating costs..." << std::endl;
    aggregateCosts(firstImage.rows, firstImage.cols, disparityRange, paths, C, A, S);

    cv::Mat disparityMap = cv::Mat(cv::Size(firstImage.cols, firstImage.rows), CV_8UC1, cv::Scalar::all(0));

    std::cout << "Computing disparity..." << std::endl;
    computeDisparity(S, firstImage.rows, firstImage.cols, disparityRange, disparityMap);

    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    printf("Done in %.2lf seconds.\n", elapsed_secs);

    saveDisparityMap(disparityMap, disparityRange, outFileName);

    return 0;
}<commit_msg>Significantly decreased memory usage by reusing path cost cache<commit_after>#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <ctime>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include "gaussian.h"

#define BLUR_RADIUS 3
#define PATH_COUNT 16
#define MAX_SHORT std::numeric_limits<unsigned short>::max()
#define SMALL_PENALTY 3
#define LARGE_PENALTY 20
#define DEBUG false

struct path {
    short rowDiff;
    short colDiff;
    short index;
};

void printArray(unsigned short ***array, int rows, int cols, int depth) {
    for (int d = 0; d < depth; ++d) {
        std::cout << "disparity: " << d << std::endl;
        for (int row = 0; row < rows; ++row) {
            for (int col = 0; col < cols; ++col) {
                std::cout << "\t" << array[row][col][d];
            }
            std::cout << std::endl;
        }
    }
}

unsigned short calculatePixelCostOneWayBT(int row, int leftCol, int rightCol, const cv::Mat &leftImage, const cv::Mat &rightImage) {

    char leftValue, rightValue, beforeRightValue, afterRightValue, rightValueMinus, rightValuePlus, rightValueMin, rightValueMax;

    leftValue = leftImage.at<uchar>(row, leftCol);
    rightValue = rightImage.at<uchar>(row, rightCol);

    if (rightCol > 0) {
        beforeRightValue = rightImage.at<uchar>(row, rightCol - 1);
    } else {
        beforeRightValue = rightValue;
    }

    if (rightCol + 1 < rightImage.cols) {
        afterRightValue = rightImage.at<uchar>(row, rightCol + 1);
    } else {
        afterRightValue = rightValue;
    }

    rightValueMinus = round((rightValue + beforeRightValue) / 2.f);
    rightValuePlus = round((rightValue + afterRightValue) / 2.f);

    rightValueMin = std::min(rightValue, std::min(rightValueMinus, rightValuePlus));
    rightValueMax = std::max(rightValue, std::max(rightValueMinus, rightValuePlus));

    return std::max(0, std::max((leftValue - rightValueMax), (rightValueMin - leftValue)));
}

inline unsigned short calculatePixelCostBT(int row, int leftCol, int rightCol, const cv::Mat &leftImage, const cv::Mat &rightImage) {
    return std::min(calculatePixelCostOneWayBT(row, leftCol, rightCol, leftImage, rightImage),
        calculatePixelCostOneWayBT(row, rightCol, leftCol, rightImage, leftImage));
}

void calculatePixelCost(cv::Mat &firstImage, cv::Mat &secondImage, int disparityRange, unsigned short ***C) {
    for (int row = 0; row < firstImage.rows; ++row) {
        for (int col = 0; col < firstImage.cols; ++col) {
            for (int d = 0; d < disparityRange; ++d) {
                C[row][col][d] = calculatePixelCostBT(row, col, col - d, firstImage, secondImage);
            }
        }
    }
}

void initializePaths(std::vector<path> &paths, unsigned short pathCount) {
    for (unsigned short i = 0; i < pathCount; ++i) {
        paths.push_back(path());
    }

    if(paths.size() >= 2) {
        paths[0].rowDiff = 0;
        paths[0].colDiff = 1;
        paths[0].index = 0;

        paths[1].rowDiff = 0;
        paths[1].colDiff = -1;
        paths[1].index = 1;
    }

    if(paths.size() >= 4) {
        paths[2].rowDiff = -1;
        paths[2].colDiff = 0;
        paths[2].index = 2;

        paths[3].rowDiff = 1;
        paths[3].colDiff = 0;
        paths[3].index = 3;
    }

    if(paths.size() >= 8) {
        paths[4].rowDiff = -1;
        paths[4].colDiff = 1;
        paths[4].index = 4;

        paths[5].rowDiff = 1;
        paths[5].colDiff = 1;
        paths[5].index = 5;

        paths[6].rowDiff = 1;
        paths[6].colDiff = -1;
        paths[6].index = 6;

        paths[7].rowDiff = -1;
        paths[7].colDiff = -1;
        paths[7].index = 7;
    }

    if(paths.size() >= 16) {
        paths[8].rowDiff = -2;
        paths[8].colDiff = 1;
        paths[8].index = 8;

        paths[9].rowDiff = -2;
        paths[9].colDiff = -1;
        paths[9].index = 9;

        paths[10].rowDiff = 2;
        paths[10].colDiff = 1;
        paths[10].index = 10;

        paths[11].rowDiff = 2;
        paths[11].colDiff = -1;
        paths[11].index = 11;

        paths[12].rowDiff = 1;
        paths[12].colDiff = -2;
        paths[12].index = 12;

        paths[13].rowDiff = -1;
        paths[13].colDiff = -2;
        paths[13].index = 13;

        paths[14].rowDiff = 1;
        paths[14].colDiff = 2;
        paths[14].index = 14;

        paths[15].rowDiff = -1;
        paths[15].colDiff = 2;
        paths[15].index = 15;
    }
}

unsigned short aggregateCost(int row, int col, int d, path &p, int rows, int cols, int disparityRange, unsigned short ***C, unsigned short ***A, unsigned short ***S, unsigned int iter) {
    unsigned short aggregatedCost = 0;
    aggregatedCost += C[row][col][d];

    if(DEBUG) {
        for (unsigned int i = 0; i < iter; ++i) {
            printf(" ");
        }
        printf("{P%d}[%d][%d](d%d)\n", p.index, row, col, d);
    }

    if (A[row][col][d] != MAX_SHORT) {
        if(DEBUG) {
            for (unsigned int i = 0; i < iter; ++i) {
                printf(" ");
            }
            printf("{P%d}[%d][%d](d%d)-> %d<CACHED>\n", p.index, row, col, d, A[row][col][d]);
        }
        return A[row][col][d];
    }

    if (row + p.rowDiff < 0 || row + p.rowDiff >= rows || col + p.colDiff < 0 || col + p.colDiff >= cols) {
        // border
        A[row][col][d] = aggregatedCost;
        if(DEBUG) {
            for (unsigned int i = 0; i < iter; ++i) {
                printf(" ");
            }
            printf("{P%d}[%d][%d](d%d)-> %d <BORDER>\n", p.index, row, col, d, A[row][col][d]);
        }
        return A[row][col][d];

        return aggregatedCost;
    }

    unsigned short minPrev, minPrevOther, prev, prevPlus, prevMinus;
    prev = minPrev = minPrevOther = prevPlus = prevMinus = MAX_SHORT;

    for (int disp = 0; disp < disparityRange; ++disp) {
        unsigned short tmp = aggregateCost(row + p.rowDiff, col + p.colDiff, disp, p, rows, cols, disparityRange, C, A, S, ++iter);
        if(minPrev > tmp) {
            minPrev = tmp;
        }

        if(disp == d) {
            prev = tmp;
        } else if(disp == d + 1) {
            prevPlus = tmp;
        } else if (disp == d - 1) {
            prevMinus = tmp;
        } else {
            if(minPrevOther > tmp + LARGE_PENALTY) {
                minPrevOther = tmp + LARGE_PENALTY;
            }
        }
    }

    aggregatedCost += std::min(std::min((int)prevPlus + SMALL_PENALTY, (int)prevMinus + SMALL_PENALTY), std::min((int)prev, (int)minPrevOther + LARGE_PENALTY));
    aggregatedCost -= minPrev;

    A[row][col][d] = aggregatedCost;

    if(DEBUG) {
        for (unsigned int i = 0; i < iter; ++i) {
            printf(" ");
        }
        printf("{P%d}[%d][%d](d%d)-> %d<CALCULATED>\n", p.index, row, col, d, A[row][col][d]);
    }

    return aggregatedCost;
}

void aggregateCosts(int rows, int cols, int disparityRange, std::vector<path> &paths, unsigned short ***C, unsigned short ***A, unsigned short ***S) {
    for (unsigned long p = 0; p < paths.size(); ++p) {
        // TODO clear path array
        unsigned int size = rows * cols * disparityRange;
        for (int row = 0; row < rows; ++row) {
            for (int col = 0; col < cols; ++col) {
                for (int d = 0; d < disparityRange; ++d) {
                    A[row][col][d] = MAX_SHORT;
                }
            }
        }

        for (int row = 0; row < rows; ++row) {
            for (int col = 0; col < cols; ++col) {
                for (int d = 0; d < disparityRange; ++d) {
                    S[row][col][d] += aggregateCost(row, col, d, paths[p], rows, cols, disparityRange, C, A, S, 0);
                }
            }
        }
    }
}

void computeDisparity(unsigned short ***S, int rows, int cols, int disparityRange, cv::Mat &disparityMap) {
    unsigned int disparity = 0, minCost;
    for (int row = 0; row < rows; ++row) {
        for (int col = 0; col < cols; ++col) {
            minCost = MAX_SHORT;
            for (int d = disparityRange - 1; d >= 0; --d) {
                if(minCost > S[row][col][d]) {
                    minCost = S[row][col][d];
                    disparity = d;
                }
            }
            disparityMap.at<uchar>(row, col) = disparity;
        }
    }
}

void saveDisparityMap(cv::Mat &disparityMap, int disparityRange, char* outputFile) {
    double factor = 256.0 / disparityRange;
    for (int row = 0; row < disparityMap.rows; ++row) {
        for (int col = 0; col < disparityMap.cols; ++col) {
            disparityMap.at<uchar>(row, col) *= factor;
        }
    }
    cv::imwrite(outputFile, disparityMap);
}

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

    if (argc != 5) {
        std::cerr << "Usage: " << argv[0] << " <left image> <right image> <output image file> <disparity range>" << std::endl;
        return -1;
    }

    char *firstFileName = argv[1];
    char *secondFileName = argv[2];
    char *outFileName = argv[3];

    cv::Mat firstImage;
    cv::Mat secondImage;
    firstImage = cv::imread(firstFileName, CV_LOAD_IMAGE_GRAYSCALE);
    secondImage = cv::imread(secondFileName, CV_LOAD_IMAGE_GRAYSCALE);

    if(!firstImage.data || !secondImage.data) {
        std::cerr <<  "Could not open or find one of the images!" << std::endl;
        return -1;
    }

    unsigned int disparityRange = atoi(argv[4]);
    unsigned short ***C; // pixel cost array W x H x D
    unsigned short ***S; // aggregated cost array W x H x D
    unsigned short ***A; // single path cost array W x H x D
    std::vector<path> paths;

    initializePaths(paths, PATH_COUNT);

    /*
    * TODO
    * variable LARGE_PENALTY
    */

    clock_t begin = clock();

    std::cout << "Allocating space..." << std::endl;

    // allocate cost arrays
    C = new unsigned short**[firstImage.rows];
    S = new unsigned short**[firstImage.rows];
    for (int row = 0; row < firstImage.rows; ++row) {
        C[row] = new unsigned short*[firstImage.cols];
        S[row] = new unsigned short*[firstImage.cols]();
        for (int col = 0; col < firstImage.cols; ++col) {
            C[row][col] = new unsigned short[disparityRange];
            S[row][col] = new unsigned short[disparityRange](); // initialize to 0
        }
    }

    A = new unsigned short **[firstImage.rows];
    for (int row = 0; row < firstImage.rows; ++row) {
        A[row] = new unsigned short*[firstImage.cols];
        for (int col = 0; col < firstImage.cols; ++col) {
            A[row][col] = new unsigned short[disparityRange];
            for (unsigned int d = 0; d < disparityRange; ++d) {
                A[row][col][d] = MAX_SHORT; // TODO set before each path calculation
            }
        }
    }

    std::cout << "Smoothing images..." << std::endl;
    grayscaleGaussianBlur(firstImage, firstImage, BLUR_RADIUS);
    grayscaleGaussianBlur(secondImage, secondImage, BLUR_RADIUS);

    std::cout << "Calculating pixel cost for the image..." << std::endl;
    calculatePixelCost(firstImage, secondImage, disparityRange, C);
    if(DEBUG) {
        printArray(C, firstImage.rows, firstImage.cols, disparityRange);
    }
    std::cout << "Aggregating costs..." << std::endl;
    aggregateCosts(firstImage.rows, firstImage.cols, disparityRange, paths, C, A, S);

    cv::Mat disparityMap = cv::Mat(cv::Size(firstImage.cols, firstImage.rows), CV_8UC1, cv::Scalar::all(0));

    std::cout << "Computing disparity..." << std::endl;
    computeDisparity(S, firstImage.rows, firstImage.cols, disparityRange, disparityMap);

    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    printf("Done in %.2lf seconds.\n", elapsed_secs);

    saveDisparityMap(disparityMap, disparityRange, outFileName);

    return 0;
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 David Chisnall
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <iostream>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#include "parser.hh"
#include "ast.hh"

static int enableTiming = 0;

static void logTimeSince(clock_t c1, const char *msg)
{
	if (!enableTiming) { return; }
	clock_t c2 = clock();
	struct rusage r;
	getrusage(RUSAGE_SELF, &r);
	fprintf(stderr, "%s took %f seconds.	Peak used %ldKB.\n", msg,
		(static_cast<double>(c2) - static_cast<double>(c1)) / static_cast<double>(CLOCKS_PER_SEC), r.ru_maxrss);
}

int main(int argc, char **argv)
{
	int iterations = 1;
	int useJIT = 0;
	int optimiseLevel = 0;
	int gridSize = 5;
	int maxValue = 1;
	clock_t c1;
	int c;
	while ((c = getopt(argc, argv, "ji:tO:x:m:")) != -1)
	{
		switch (c)
		{
			default:
				break;
			case 'j':
				useJIT = 1;
				break;
			case 'x':
				gridSize = strtol(optarg, 0, 10);
				break;
			case 'm':
				maxValue = strtol(optarg, 0, 10);
				break;
			case 'i':
				iterations = strtol(optarg, 0, 10);
				break;
			case 't':
				enableTiming = 1;
				break;
			case 'O':
				optimiseLevel = strtol(optarg, 0, 10);
		}
	}
	argc -= optind;
	if (argc < 1)
	{
		fprintf(stderr, "usage: %s -jt -i {iterations} -o {optimisation level} -x {grid size} -m {max initial value} {file name}\n", argv[0]);
		return EXIT_FAILURE;
	}
	argv += optind;

	// Do the parsing
	Parser::CellAtomParser p;
	pegmatite::AsciiFileInput input(open(argv[0], O_RDONLY));
	std::unique_ptr<AST::StatementList> ast = 0;
	c1 = clock();
	pegmatite::ErrorReporter err =
		[](const pegmatite::InputRange& r, const std::string& msg) {
		std::cout << "error: " << msg << std::endl;
		std::cout << "line " << r.start.line
		          << ", col " << r.start.col << std::endl;
	};
	if (!p.parse(input, p.g.statements, p.g.ignored, err, ast))
	{
		return EXIT_FAILURE;
	}
	logTimeSince(c1, "Parsing program");
	assert(ast);

#ifdef DUMP_AST
	for (uintptr_t i=0 ; i<result->count ; i++)
	{
		printAST(result->list[i]);
		putchar('\n');
	}
#endif
#ifdef STATIC_TESTING_GRID
	int16_t oldgrid[] = {
		 0,0,0,0,0,
		 0,0,0,0,0,
		 0,1,1,1,0,
		 0,0,0,0,0,
		 0,0,0,0,0
	};
	int16_t newgrid[25];
	gridSize = 5;
	int16_t *g1 = oldgrid;
	int16_t *g2 = newgrid;
#else
	int16_t *g1 = reinterpret_cast<int16_t*>(malloc(sizeof(int16_t) * gridSize * gridSize));
	int16_t *g2 = reinterpret_cast<int16_t*>(malloc(sizeof(int16_t) * gridSize * gridSize));
	//int16_t *g2 = new int16_t[gridSize * gridSize];
	c1 = clock();
	for (int i=0 ; i<(gridSize*gridSize) ; i++)
	{
		g1[i] = random() % (maxValue + 1);
	}
	logTimeSince(c1, "Generating random grid");
#endif
	int i=0;
	if (useJIT)
	{
		c1 = clock();
		Compiler::automaton ca = Compiler::compile(ast.get(), optimiseLevel);
		logTimeSince(c1, "Compiling");
		c1 = clock();
		for (int i=0 ; i<iterations ; i++)
		{
			ca(g1, g2, gridSize, gridSize);
			std::swap(g1, g2);
		}
		logTimeSince(c1, "Running compiled version");
	}
	else
	{
		c1 = clock();
		for (int i=0 ; i<iterations ; i++)
		{
			Interpreter::runOneStep(g1, g2, gridSize, gridSize, ast.get());
			std::swap(g1, g2);
		}
		logTimeSince(c1, "Interpreting");
	}
	for (int x=0 ; x<gridSize ; x++)
	{
		for (int y=0 ; y<gridSize ; y++)
		{
			printf("%d ", g1[i++]);
		}
		putchar('\n');
	}
	return 0;
}
<commit_msg>Fix typo in help text.<commit_after>/*
 * Copyright (c) 2014 David Chisnall
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <iostream>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <time.h>
#include <unistd.h>
#include "parser.hh"
#include "ast.hh"

static int enableTiming = 0;

static void logTimeSince(clock_t c1, const char *msg)
{
	if (!enableTiming) { return; }
	clock_t c2 = clock();
	struct rusage r;
	getrusage(RUSAGE_SELF, &r);
	fprintf(stderr, "%s took %f seconds.	Peak used %ldKB.\n", msg,
		(static_cast<double>(c2) - static_cast<double>(c1)) / static_cast<double>(CLOCKS_PER_SEC), r.ru_maxrss);
}

int main(int argc, char **argv)
{
	int iterations = 1;
	int useJIT = 0;
	int optimiseLevel = 0;
	int gridSize = 5;
	int maxValue = 1;
	clock_t c1;
	int c;
	while ((c = getopt(argc, argv, "ji:tO:x:m:")) != -1)
	{
		switch (c)
		{
			default:
				break;
			case 'j':
				useJIT = 1;
				break;
			case 'x':
				gridSize = strtol(optarg, 0, 10);
				break;
			case 'm':
				maxValue = strtol(optarg, 0, 10);
				break;
			case 'i':
				iterations = strtol(optarg, 0, 10);
				break;
			case 't':
				enableTiming = 1;
				break;
			case 'O':
				optimiseLevel = strtol(optarg, 0, 10);
		}
	}
	argc -= optind;
	if (argc < 1)
	{
		fprintf(stderr, "usage: %s -jt -i {iterations} -O {optimisation level} -x {grid size} -m {max initial value} {file name}\n", argv[0]);
		return EXIT_FAILURE;
	}
	argv += optind;

	// Do the parsing
	Parser::CellAtomParser p;
	pegmatite::AsciiFileInput input(open(argv[0], O_RDONLY));
	std::unique_ptr<AST::StatementList> ast = 0;
	c1 = clock();
	pegmatite::ErrorReporter err =
		[](const pegmatite::InputRange& r, const std::string& msg) {
		std::cout << "error: " << msg << std::endl;
		std::cout << "line " << r.start.line
		          << ", col " << r.start.col << std::endl;
	};
	if (!p.parse(input, p.g.statements, p.g.ignored, err, ast))
	{
		return EXIT_FAILURE;
	}
	logTimeSince(c1, "Parsing program");
	assert(ast);

#ifdef DUMP_AST
	for (uintptr_t i=0 ; i<result->count ; i++)
	{
		printAST(result->list[i]);
		putchar('\n');
	}
#endif
#ifdef STATIC_TESTING_GRID
	int16_t oldgrid[] = {
		 0,0,0,0,0,
		 0,0,0,0,0,
		 0,1,1,1,0,
		 0,0,0,0,0,
		 0,0,0,0,0
	};
	int16_t newgrid[25];
	gridSize = 5;
	int16_t *g1 = oldgrid;
	int16_t *g2 = newgrid;
#else
	int16_t *g1 = reinterpret_cast<int16_t*>(malloc(sizeof(int16_t) * gridSize * gridSize));
	int16_t *g2 = reinterpret_cast<int16_t*>(malloc(sizeof(int16_t) * gridSize * gridSize));
	//int16_t *g2 = new int16_t[gridSize * gridSize];
	c1 = clock();
	for (int i=0 ; i<(gridSize*gridSize) ; i++)
	{
		g1[i] = random() % (maxValue + 1);
	}
	logTimeSince(c1, "Generating random grid");
#endif
	int i=0;
	if (useJIT)
	{
		c1 = clock();
		Compiler::automaton ca = Compiler::compile(ast.get(), optimiseLevel);
		logTimeSince(c1, "Compiling");
		c1 = clock();
		for (int i=0 ; i<iterations ; i++)
		{
			ca(g1, g2, gridSize, gridSize);
			std::swap(g1, g2);
		}
		logTimeSince(c1, "Running compiled version");
	}
	else
	{
		c1 = clock();
		for (int i=0 ; i<iterations ; i++)
		{
			Interpreter::runOneStep(g1, g2, gridSize, gridSize, ast.get());
			std::swap(g1, g2);
		}
		logTimeSince(c1, "Interpreting");
	}
	for (int x=0 ; x<gridSize ; x++)
	{
		for (int y=0 ; y<gridSize ; y++)
		{
			printf("%d ", g1[i++]);
		}
		putchar('\n');
	}
	return 0;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.10  2001/11/21 14:30:13  knoaman
 * Fix for UPA checking.
 *
 * Revision 1.9  2001/11/07 21:50:28  tng
 * Fix comment log that lead to error.
 *
 * Revision 1.8  2001/11/07 21:12:15  tng
 * Performance: Create QName in ContentSpecNode only if it is a leaf/Any/PCDataNode.
 *
 * Revision 1.7  2001/10/04 15:08:56  knoaman
 * Add support for circular import.
 *
 * Revision 1.6  2001/08/21 15:57:51  tng
 * Schema: Add isAllowedByWildcard.  Help from James Murphy.
 *
 * Revision 1.5  2001/05/29 19:47:22  knoaman
 * Fix bug -  memory was not allocated before call to XMLString::subString
 *
 * Revision 1.4  2001/05/28 20:55:42  tng
 * Schema: Null pointer checking in SubsitutionGropuComparator
 *
 * Revision 1.3  2001/05/11 13:27:37  tng
 * Copyright update.
 *
 * Revision 1.2  2001/05/04 14:50:28  tng
 * Fixed the cvs symbols.
 *
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <validators/schema/SubstitutionGroupComparator.hpp>
#include <validators/common/Grammar.hpp>
#include <validators/schema/SchemaGrammar.hpp>
#include <validators/schema/ComplexTypeInfo.hpp>
#include <validators/schema/SchemaSymbols.hpp>

bool SubstitutionGroupComparator::isEquivalentTo(QName* const anElement
                                               , QName* const exemplar)
{
    if (!anElement && !exemplar)
        return true;

    if ((!anElement && exemplar) || (anElement && !exemplar))
        return false;

    if ((XMLString::compareString(anElement->getLocalPart(), exemplar->getLocalPart()) == 0) &&
        (anElement->getURI() == exemplar->getURI()))
        return true; // they're the same!

    if (!fGrammarResolver || !fStringPool )
    {
        ThrowXML(RuntimeException, XMLExcepts::SubGrpComparator_NGR);
    }

    unsigned int uriId = anElement->getURI();
    if (uriId == XMLContentModel::gEOCFakeId ||
        uriId == XMLContentModel::gEpsilonFakeId ||
        uriId == XMLElementDecl::fgPCDataElemId)
        return false;

    const XMLCh* uri = fStringPool->getValueForId(uriId);
    const XMLCh* localpart = anElement->getLocalPart();

    // In addition to simply trying to find a chain between anElement and exemplar,
    // we need to make sure that no steps in the chain are blocked.
    // That is, at every step, we need to make sure that the element
    // being substituted for will permit being substituted
    // for, and whether the type of the element will permit derivations in
    // instance documents of this sort.

    if (!uri)
        return false;

    SchemaGrammar *sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uri);
    if (!sGrammar || sGrammar->getGrammarType() == Grammar::DTDGrammarType)
        return false;

    SchemaElementDecl* pElemDecl = (SchemaElementDecl*) sGrammar->getElemDecl(uriId, localpart, 0, Grammar::TOP_LEVEL_SCOPE);
    if (!pElemDecl)
        return false;

    SchemaElementDecl* anElementDecl = pElemDecl;     // to preserve the ElementDecl for anElement
    XMLCh* substitutionGroupFullName = pElemDecl->getSubstitutionGroupName();
    bool foundIt = false;

    while (substitutionGroupFullName)
    {
        int commaAt = XMLString::indexOf(substitutionGroupFullName, chComma);
        XMLCh tmpURI[256];
        XMLCh tmpLocalpart[256];

        if (commaAt >= 0)
        {
            if (commaAt > 0)
                 XMLString::subString(tmpURI, substitutionGroupFullName, 0, commaAt);

            XMLString::subString(tmpLocalpart, substitutionGroupFullName, commaAt+1, XMLString::stringLen(substitutionGroupFullName));
        }
        else {
            XMLString::subString(tmpLocalpart, substitutionGroupFullName, 0, XMLString::stringLen(substitutionGroupFullName));
        }

        if (!tmpURI)
            return false;

        sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(tmpURI);
        if (!sGrammar || sGrammar->getGrammarType() == Grammar::DTDGrammarType)
            return false;

        uriId = fStringPool->addOrFind(tmpURI);
        pElemDecl = (SchemaElementDecl*) sGrammar->getElemDecl(uriId, tmpLocalpart, 0, Grammar::TOP_LEVEL_SCOPE);

        if (!pElemDecl)
            return false;

        if ((XMLString::compareString(tmpLocalpart, exemplar->getLocalPart()) == 0) &&
            (uriId == exemplar->getURI()))
        {
            // time to check for block value on element
            if((pElemDecl->getBlockSet() & SchemaSymbols::SUBSTITUTION) != 0)
                return false;

            foundIt = true;
            break;
        }

        substitutionGroupFullName = pElemDecl->getSubstitutionGroupName();
    }//while

    if (!foundIt)
        return false;

    // this will contain anElement's complexType information.
    ComplexTypeInfo *aComplexType = anElementDecl->getComplexTypeInfo();
    int exemplarBlockSet = pElemDecl->getBlockSet();

    if(!aComplexType)
    {
        // check on simpleType case
        DatatypeValidator *anElementDV = anElementDecl->getDatatypeValidator();
        DatatypeValidator *exemplarDV = pElemDecl->getDatatypeValidator();

        return((anElementDV == 0) ||
            ((anElementDV == exemplarDV) ||
            ((exemplarBlockSet & SchemaSymbols::RESTRICTION) == 0)));
    }

    // now we have to make sure there are no blocks on the complexTypes that this is based upon
    int anElementDerivationMethod = aComplexType->getDerivedBy();
    if((anElementDerivationMethod & exemplarBlockSet) != 0)
        return false;

    // this will contain exemplar's complexType information.
    ComplexTypeInfo *exemplarComplexType = pElemDecl->getComplexTypeInfo();

    for(ComplexTypeInfo *tempType = aComplexType;
        tempType != 0 && tempType != exemplarComplexType;
        tempType = tempType->getBaseComplexTypeInfo())
    {
        if((tempType->getBlockSet() & anElementDerivationMethod) != 0)
            return false;
    }//for

    return true;
}

bool SubstitutionGroupComparator::isAllowedByWildcard(SchemaGrammar* const pGrammar,
                                                      QName* const element,
                                                      unsigned int wuri, bool wother)
{
    // whether the uri is allowed directly by the wildcard
    unsigned int uriId = element->getURI();

    if ((!wother && uriId == wuri) ||
        (wother && uriId != wuri && uriId != XMLContentModel::gEOCFakeId && uriId != XMLContentModel::gEpsilonFakeId))
    {
        return true;
    }

    // get all elements that can substitute the current element
    RefHash2KeysTableOf<ElemVector>* theValidSubstitutionGroups = pGrammar->getValidSubstitutionGroups();

    if (!theValidSubstitutionGroups)
        return false;

    ValueVectorOf<SchemaElementDecl*>* subsElements = theValidSubstitutionGroups->get(element->getLocalPart(), uriId);

    if (!subsElements)
        return false;

    // then check whether there exists one element that is allowed by the wildcard
    int size = subsElements->size();

    for (int i = 0; i < size; i++)
    {
        unsigned int subUriId = subsElements->elementAt(i)->getElementName()->getURI();

        if ((!wother && subUriId == wuri) ||
            (wother && subUriId != wuri && subUriId != XMLContentModel::gEOCFakeId && subUriId != XMLContentModel::gEpsilonFakeId))
        {
            return true;
        }
    }
    return false;
}

/**
  * End of file SubstitutionGroupComparator.cpp
  */

<commit_msg>Schema fix: Initialize the temporary string as null terminated.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.11  2001/11/28 16:46:03  tng
 * Schema fix: Initialize the temporary string as null terminated.
 *
 * Revision 1.10  2001/11/21 14:30:13  knoaman
 * Fix for UPA checking.
 *
 * Revision 1.9  2001/11/07 21:50:28  tng
 * Fix comment log that lead to error.
 *
 * Revision 1.8  2001/11/07 21:12:15  tng
 * Performance: Create QName in ContentSpecNode only if it is a leaf/Any/PCDataNode.
 *
 * Revision 1.7  2001/10/04 15:08:56  knoaman
 * Add support for circular import.
 *
 * Revision 1.6  2001/08/21 15:57:51  tng
 * Schema: Add isAllowedByWildcard.  Help from James Murphy.
 *
 * Revision 1.5  2001/05/29 19:47:22  knoaman
 * Fix bug -  memory was not allocated before call to XMLString::subString
 *
 * Revision 1.4  2001/05/28 20:55:42  tng
 * Schema: Null pointer checking in SubsitutionGropuComparator
 *
 * Revision 1.3  2001/05/11 13:27:37  tng
 * Copyright update.
 *
 * Revision 1.2  2001/05/04 14:50:28  tng
 * Fixed the cvs symbols.
 *
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <validators/schema/SubstitutionGroupComparator.hpp>
#include <validators/common/Grammar.hpp>
#include <validators/schema/SchemaGrammar.hpp>
#include <validators/schema/ComplexTypeInfo.hpp>
#include <validators/schema/SchemaSymbols.hpp>

bool SubstitutionGroupComparator::isEquivalentTo(QName* const anElement
                                               , QName* const exemplar)
{
    if (!anElement && !exemplar)
        return true;

    if ((!anElement && exemplar) || (anElement && !exemplar))
        return false;

    if ((XMLString::compareString(anElement->getLocalPart(), exemplar->getLocalPart()) == 0) &&
        (anElement->getURI() == exemplar->getURI()))
        return true; // they're the same!

    if (!fGrammarResolver || !fStringPool )
    {
        ThrowXML(RuntimeException, XMLExcepts::SubGrpComparator_NGR);
    }

    unsigned int uriId = anElement->getURI();
    if (uriId == XMLContentModel::gEOCFakeId ||
        uriId == XMLContentModel::gEpsilonFakeId ||
        uriId == XMLElementDecl::fgPCDataElemId)
        return false;

    const XMLCh* uri = fStringPool->getValueForId(uriId);
    const XMLCh* localpart = anElement->getLocalPart();

    // In addition to simply trying to find a chain between anElement and exemplar,
    // we need to make sure that no steps in the chain are blocked.
    // That is, at every step, we need to make sure that the element
    // being substituted for will permit being substituted
    // for, and whether the type of the element will permit derivations in
    // instance documents of this sort.

    if (!uri)
        return false;

    SchemaGrammar *sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uri);
    if (!sGrammar || sGrammar->getGrammarType() == Grammar::DTDGrammarType)
        return false;

    SchemaElementDecl* pElemDecl = (SchemaElementDecl*) sGrammar->getElemDecl(uriId, localpart, 0, Grammar::TOP_LEVEL_SCOPE);
    if (!pElemDecl)
        return false;

    SchemaElementDecl* anElementDecl = pElemDecl;     // to preserve the ElementDecl for anElement
    XMLCh* substitutionGroupFullName = pElemDecl->getSubstitutionGroupName();
    bool foundIt = false;

    while (substitutionGroupFullName)
    {
        int commaAt = XMLString::indexOf(substitutionGroupFullName, chComma);
        XMLCh tmpURI[256];
        tmpURI[0] = chNull;
        XMLCh tmpLocalpart[256];
        tmpLocalpart[0] = chNull;

        if (commaAt >= 0)
        {
            if (commaAt > 0)
                 XMLString::subString(tmpURI, substitutionGroupFullName, 0, commaAt);

            XMLString::subString(tmpLocalpart, substitutionGroupFullName, commaAt+1, XMLString::stringLen(substitutionGroupFullName));
        }
        else {
            XMLString::subString(tmpLocalpart, substitutionGroupFullName, 0, XMLString::stringLen(substitutionGroupFullName));
        }

        sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(tmpURI);
        if (!sGrammar || sGrammar->getGrammarType() == Grammar::DTDGrammarType)
            return false;

        uriId = fStringPool->addOrFind(tmpURI);
        pElemDecl = (SchemaElementDecl*) sGrammar->getElemDecl(uriId, tmpLocalpart, 0, Grammar::TOP_LEVEL_SCOPE);

        if (!pElemDecl)
            return false;

        if ((XMLString::compareString(tmpLocalpart, exemplar->getLocalPart()) == 0) &&
            (uriId == exemplar->getURI()))
        {
            // time to check for block value on element
            if((pElemDecl->getBlockSet() & SchemaSymbols::SUBSTITUTION) != 0)
                return false;

            foundIt = true;
            break;
        }

        substitutionGroupFullName = pElemDecl->getSubstitutionGroupName();
    }//while

    if (!foundIt)
        return false;

    // this will contain anElement's complexType information.
    ComplexTypeInfo *aComplexType = anElementDecl->getComplexTypeInfo();
    int exemplarBlockSet = pElemDecl->getBlockSet();

    if(!aComplexType)
    {
        // check on simpleType case
        DatatypeValidator *anElementDV = anElementDecl->getDatatypeValidator();
        DatatypeValidator *exemplarDV = pElemDecl->getDatatypeValidator();

        return((anElementDV == 0) ||
            ((anElementDV == exemplarDV) ||
            ((exemplarBlockSet & SchemaSymbols::RESTRICTION) == 0)));
    }

    // now we have to make sure there are no blocks on the complexTypes that this is based upon
    int anElementDerivationMethod = aComplexType->getDerivedBy();
    if((anElementDerivationMethod & exemplarBlockSet) != 0)
        return false;

    // this will contain exemplar's complexType information.
    ComplexTypeInfo *exemplarComplexType = pElemDecl->getComplexTypeInfo();

    for(ComplexTypeInfo *tempType = aComplexType;
        tempType != 0 && tempType != exemplarComplexType;
        tempType = tempType->getBaseComplexTypeInfo())
    {
        if((tempType->getBlockSet() & anElementDerivationMethod) != 0)
            return false;
    }//for

    return true;
}

bool SubstitutionGroupComparator::isAllowedByWildcard(SchemaGrammar* const pGrammar,
                                                      QName* const element,
                                                      unsigned int wuri, bool wother)
{
    // whether the uri is allowed directly by the wildcard
    unsigned int uriId = element->getURI();

    if ((!wother && uriId == wuri) ||
        (wother && uriId != wuri && uriId != XMLContentModel::gEOCFakeId && uriId != XMLContentModel::gEpsilonFakeId))
    {
        return true;
    }

    // get all elements that can substitute the current element
    RefHash2KeysTableOf<ElemVector>* theValidSubstitutionGroups = pGrammar->getValidSubstitutionGroups();

    if (!theValidSubstitutionGroups)
        return false;

    ValueVectorOf<SchemaElementDecl*>* subsElements = theValidSubstitutionGroups->get(element->getLocalPart(), uriId);

    if (!subsElements)
        return false;

    // then check whether there exists one element that is allowed by the wildcard
    int size = subsElements->size();

    for (int i = 0; i < size; i++)
    {
        unsigned int subUriId = subsElements->elementAt(i)->getElementName()->getURI();

        if ((!wother && subUriId == wuri) ||
            (wother && subUriId != wuri && subUriId != XMLContentModel::gEOCFakeId && subUriId != XMLContentModel::gEpsilonFakeId))
        {
            return true;
        }
    }
    return false;
}

/**
  * End of file SubstitutionGroupComparator.cpp
  */

<|endoftext|>


<commit_before>// Copyright 2019 TF.Text Authors.
//
// 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 <limits>
#include <memory>
#include <string>
#include <vector>

#include "third_party/absl/base/integral_types.h"
#include "third_party/tensorflow/core/framework/lookup_interface.h"
#include "third_party/tensorflow/core/framework/op_kernel.h"
#include "third_party/tensorflow/core/framework/resource_mgr.h"
#include "third_party/tensorflow/core/framework/tensor.h"
#include "third_party/tensorflow/core/framework/tensor_shape.h"
#include "third_party/tensorflow/core/kernels/lookup_util.h"
#include "third_party/tensorflow/core/lib/core/status.h"
#include "third_party/tensorflow/core/lib/core/threadpool.h"
#include "third_party/tensorflow/core/lib/io/path.h"
#include "third_party/tensorflow/core/platform/logging.h"
#include "third_party/tensorflow_text/core/kernels/wordpiece_tokenizer.h"

namespace tensorflow {
namespace text {

namespace {
string GetWordSplitChar(OpKernelConstruction* ctx) {
  string suffix_indicator;
  ([=](string* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("suffix_indicator", c));
  })(&suffix_indicator);
  return suffix_indicator;
}

int32 GetMaxCharsPerWord(OpKernelConstruction* ctx) {
  int32 max_chars_per_word;
  ([=](int32* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("max_bytes_per_word", c));
  })(&max_chars_per_word);
  return max_chars_per_word;
}

bool GetShouldUseUnknownToken(OpKernelConstruction* ctx) {
  bool use_unknown_token;
  ([=](bool* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("use_unknown_token", c));
  })(&use_unknown_token);
  return use_unknown_token;
}

string GetUnknownToken(OpKernelConstruction* ctx) {
  string unknown_token;
  ([=](string* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("unknown_token", c));
  })(&unknown_token);
  return unknown_token;
}

}  // namespace

class WordpieceTokenizeWithOffsetsOp : public OpKernel {
 public:
  explicit WordpieceTokenizeWithOffsetsOp(OpKernelConstruction* ctx)
      : OpKernel(ctx),
        suffix_indicator_(GetWordSplitChar(ctx)),
        max_bytes_per_word_(GetMaxCharsPerWord(ctx)),
        use_unknown_token_(GetShouldUseUnknownToken(ctx)),
        unknown_token_(GetUnknownToken(ctx)) {}

  void Compute(OpKernelContext* ctx) override {
    const Tensor* input_values;
    OP_REQUIRES_OK(ctx, ctx->input("input_values", &input_values));
    const auto& values_vec = input_values->flat<string>();

    lookup::LookupInterface* lookup_table;
    OP_REQUIRES_OK(
        ctx, lookup::GetLookupTable("vocab_lookup_table", ctx, &lookup_table));
    LookupTableVocab vocab_map(lookup_table, ctx);

    std::vector<string> subwords;
    std::vector<int> begin_offset;
    std::vector<int> end_offset;
    std::vector<int> row_lengths;

    // Iterate through all the values and wordpiece tokenize them.
    for (int i = 0; i < values_vec.size(); ++i) {
      // Tokenize into subwords and record the offset locations.
      int num_wordpieces = 0;
      OP_REQUIRES_OK(
          ctx, WordpieceTokenize(values_vec(i), max_bytes_per_word_,
                                 suffix_indicator_, use_unknown_token_,
                                 unknown_token_, &vocab_map, &subwords,
                                 &begin_offset, &end_offset, &num_wordpieces));

      // Record the row splits.
      row_lengths.push_back(num_wordpieces);
    }

    std::vector<int64> output_subwords_shape;
    output_subwords_shape.push_back(subwords.size());

    std::vector<int64> output_row_lengths_shape;
    output_row_lengths_shape.push_back(row_lengths.size());

    Tensor* output_values;
    OP_REQUIRES_OK(ctx, ctx->allocate_output("output_values",
                                             TensorShape(output_subwords_shape),
                                             &output_values));
    auto output_values_vec = output_values->vec<string>();

    Tensor* output_row_lengths;
    OP_REQUIRES_OK(ctx,
                   ctx->allocate_output("output_row_lengths",
                                        TensorShape(output_row_lengths_shape),
                                        &output_row_lengths));
    auto output_row_lengths_vec = output_row_lengths->vec<int64>();

    Tensor* start_values;
    OP_REQUIRES_OK(ctx, ctx->allocate_output("start_values",
                                             TensorShape(output_subwords_shape),
                                             &start_values));
    auto start_values_vec = start_values->vec<int64>();

    Tensor* limit_values;
    OP_REQUIRES_OK(ctx, ctx->allocate_output("limit_values",
                                             TensorShape(output_subwords_shape),
                                             &limit_values));
    auto limit_values_vec = limit_values->vec<int64>();

    for (int i = 0; i < subwords.size(); ++i) {
      output_values_vec(i) = subwords[i];
    }

    for (int i = 0; i < row_lengths.size(); ++i) {
      output_row_lengths_vec(i) = row_lengths[i];
    }

    for (int i = 0; i < begin_offset.size(); ++i) {
      start_values_vec(i) = begin_offset[i];
    }

    for (int i = 0; i < end_offset.size(); ++i) {
      limit_values_vec(i) = end_offset[i];
    }
  }

 private:
  const string suffix_indicator_;
  const int max_bytes_per_word_;
  const bool use_unknown_token_;
  const string unknown_token_;

  TF_DISALLOW_COPY_AND_ASSIGN(WordpieceTokenizeWithOffsetsOp);
};

REGISTER_KERNEL_BUILDER(Name("WordpieceTokenizeWithOffsets").Device(DEVICE_CPU),
                        WordpieceTokenizeWithOffsetsOp);

}  // namespace text
}  // namespace tensorflow
<commit_msg>Internal change<commit_after>// Copyright 2019 TF.Text Authors.
//
// 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 <limits>
#include <memory>
#include <string>
#include <vector>

#include "third_party/absl/base/integral_types.h"
#include "third_party/tensorflow/core/framework/lookup_interface.h"
#include "third_party/tensorflow/core/framework/op_kernel.h"
#include "third_party/tensorflow/core/framework/resource_mgr.h"
#include "third_party/tensorflow/core/framework/tensor.h"
#include "third_party/tensorflow/core/framework/tensor_shape.h"
#include "third_party/tensorflow/core/lib/core/status.h"
#include "third_party/tensorflow/core/lib/core/threadpool.h"
#include "third_party/tensorflow/core/lib/io/path.h"
#include "third_party/tensorflow/core/platform/logging.h"
#include "third_party/tensorflow_text/core/kernels/wordpiece_tokenizer.h"

namespace tensorflow {
namespace text {

namespace {
string GetWordSplitChar(OpKernelConstruction* ctx) {
  string suffix_indicator;
  ([=](string* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("suffix_indicator", c));
  })(&suffix_indicator);
  return suffix_indicator;
}

int32 GetMaxCharsPerWord(OpKernelConstruction* ctx) {
  int32 max_chars_per_word;
  ([=](int32* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("max_bytes_per_word", c));
  })(&max_chars_per_word);
  return max_chars_per_word;
}

bool GetShouldUseUnknownToken(OpKernelConstruction* ctx) {
  bool use_unknown_token;
  ([=](bool* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("use_unknown_token", c));
  })(&use_unknown_token);
  return use_unknown_token;
}

string GetUnknownToken(OpKernelConstruction* ctx) {
  string unknown_token;
  ([=](string* c) -> void {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("unknown_token", c));
  })(&unknown_token);
  return unknown_token;
}

Status GetTableHandle(const string& input_name, OpKernelContext* ctx,
                      string* container, string* table_handle) {
  {
    mutex* mu;
    TF_RETURN_IF_ERROR(ctx->input_ref_mutex(input_name, &mu));
    mutex_lock l(*mu);
    Tensor tensor;
    TF_RETURN_IF_ERROR(ctx->mutable_input(input_name, &tensor, true));
    if (tensor.NumElements() != 2) {
      return errors::InvalidArgument(
          "Lookup table handle must be scalar, but had shape: ",
          tensor.shape().DebugString());
    }
    auto h = tensor.flat<string>();
    *container = h(0);
    *table_handle = h(1);
  }
  return Status::OK();
}

// Gets the LookupTable stored in the ctx->resource_manager() with key
// passed by attribute with name input_name, returns null if the table
// doesn't exist.
Status GetLookupTable(const string& input_name, OpKernelContext* ctx,
                      lookup::LookupInterface** table) {
  string container;
  string table_handle;
  DataType handle_dtype;
  TF_RETURN_IF_ERROR(ctx->input_dtype(input_name, &handle_dtype));
  if (handle_dtype == DT_RESOURCE) {
    ResourceHandle handle;
    TF_RETURN_IF_ERROR(HandleFromInput(ctx, input_name, &handle));
    return LookupResource(ctx, handle, table);
  } else {
    TF_RETURN_IF_ERROR(
        GetTableHandle(input_name, ctx, &container, &table_handle));
    return ctx->resource_manager()->Lookup(container, table_handle, table);
  }
}

}  // namespace

class WordpieceTokenizeWithOffsetsOp : public OpKernel {
 public:
  explicit WordpieceTokenizeWithOffsetsOp(OpKernelConstruction* ctx)
      : OpKernel(ctx),
        suffix_indicator_(GetWordSplitChar(ctx)),
        max_bytes_per_word_(GetMaxCharsPerWord(ctx)),
        use_unknown_token_(GetShouldUseUnknownToken(ctx)),
        unknown_token_(GetUnknownToken(ctx)) {}

  void Compute(OpKernelContext* ctx) override {
    const Tensor* input_values;
    OP_REQUIRES_OK(ctx, ctx->input("input_values", &input_values));
    const auto& values_vec = input_values->flat<string>();

    lookup::LookupInterface* lookup_table;
    // MKH: subject to change....
    OP_REQUIRES_OK(ctx,
                   GetLookupTable("vocab_lookup_table", ctx, &lookup_table));
    LookupTableVocab vocab_map(lookup_table, ctx);

    std::vector<string> subwords;
    std::vector<int> begin_offset;
    std::vector<int> end_offset;
    std::vector<int> row_lengths;

    // Iterate through all the values and wordpiece tokenize them.
    for (int i = 0; i < values_vec.size(); ++i) {
      // Tokenize into subwords and record the offset locations.
      int num_wordpieces = 0;
      OP_REQUIRES_OK(
          ctx, WordpieceTokenize(values_vec(i), max_bytes_per_word_,
                                 suffix_indicator_, use_unknown_token_,
                                 unknown_token_, &vocab_map, &subwords,
                                 &begin_offset, &end_offset, &num_wordpieces));

      // Record the row splits.
      row_lengths.push_back(num_wordpieces);
    }

    std::vector<int64> output_subwords_shape;
    output_subwords_shape.push_back(subwords.size());

    std::vector<int64> output_row_lengths_shape;
    output_row_lengths_shape.push_back(row_lengths.size());

    Tensor* output_values;
    OP_REQUIRES_OK(ctx, ctx->allocate_output("output_values",
                                             TensorShape(output_subwords_shape),
                                             &output_values));
    auto output_values_vec = output_values->vec<string>();

    Tensor* output_row_lengths;
    OP_REQUIRES_OK(ctx,
                   ctx->allocate_output("output_row_lengths",
                                        TensorShape(output_row_lengths_shape),
                                        &output_row_lengths));
    auto output_row_lengths_vec = output_row_lengths->vec<int64>();

    Tensor* start_values;
    OP_REQUIRES_OK(ctx, ctx->allocate_output("start_values",
                                             TensorShape(output_subwords_shape),
                                             &start_values));
    auto start_values_vec = start_values->vec<int64>();

    Tensor* limit_values;
    OP_REQUIRES_OK(ctx, ctx->allocate_output("limit_values",
                                             TensorShape(output_subwords_shape),
                                             &limit_values));
    auto limit_values_vec = limit_values->vec<int64>();

    for (int i = 0; i < subwords.size(); ++i) {
      output_values_vec(i) = subwords[i];
    }

    for (int i = 0; i < row_lengths.size(); ++i) {
      output_row_lengths_vec(i) = row_lengths[i];
    }

    for (int i = 0; i < begin_offset.size(); ++i) {
      start_values_vec(i) = begin_offset[i];
    }

    for (int i = 0; i < end_offset.size(); ++i) {
      limit_values_vec(i) = end_offset[i];
    }
  }

 private:
  const string suffix_indicator_;
  const int max_bytes_per_word_;
  const bool use_unknown_token_;
  const string unknown_token_;

  TF_DISALLOW_COPY_AND_ASSIGN(WordpieceTokenizeWithOffsetsOp);
};

REGISTER_KERNEL_BUILDER(Name("WordpieceTokenizeWithOffsets").Device(DEVICE_CPU),
                        WordpieceTokenizeWithOffsetsOp);

}  // namespace text
}  // namespace tensorflow
<|endoftext|>