<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 "test.h"

#include <iostream>
#include <vector>

namespace {

bool wildcard_match(const char* p, const char* str) {
  while (*p && *str && (*p == *str || *p == '?') && *p != '*') {
    str++;
    p++;
  }

  if (!*p) {
    return *str == 0;
  } else if (*p == '*') {
    p++;
    do {
      if (wildcard_match(p, str)) {
        return true;
      }
    } while(*str++);
  }
  return !*p;
}

std::vector<std::pair<std::string, std::function<void()>>>& tests() {
  static std::vector<std::pair<std::string, std::function<void()>>> v;
  return v;
}

}  // namespace

namespace nda {

test::test(const std::string& name, std::function<void()> fn) {
  add_test(name, fn);
}

void add_test(const std::string& name, std::function<void()> fn) {
  tests().push_back(std::make_pair(name, fn));
}

}  // namespace nda

using namespace nda;

int main(int argc, const char** argv) {
  // By default, the filter matches all tests.
  const char* filter = "*";
  if (argc > 1) {
    filter = argv[1];
    std::cout << "Running tests matching '" << filter << "'..." << std::endl;
  }

  size_t passed = 0;
  size_t total = 0;
  for (auto& i : tests()) {
    if (!wildcard_match(filter, i.first.c_str())) continue;

    std::cout << i.first;
#ifndef NDARRAY_NO_EXCEPTIONS
    try {
#endif
      i.second();
      std::cout << " passed" << std::endl;
      passed++;
#ifndef NDARRAY_NO_EXCEPTIONS
    } catch(const std::exception& e) {
      std::cout << " failed: " << e.what() << std::endl;
    }
#endif
    total++;
  }
  std::cout << passed << " of " << total << " tests passed, " << tests().size() - total << " skipped" << std::endl;
  return passed < total ? -1 : 0;
}
<commit_msg>Fix formatting.<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 "test.h"

#include <iostream>
#include <vector>

namespace {

bool wildcard_match(const char* p, const char* str) {
  while (*p && *str && (*p == *str || *p == '?') && *p != '*') {
    str++;
    p++;
  }

  if (!*p) {
    return *str == 0;
  } else if (*p == '*') {
    p++;
    do {
      if (wildcard_match(p, str)) {
        return true;
      }
    } while(*str++);
  }
  return !*p;
}

std::vector<std::pair<std::string, std::function<void()>>>& tests() {
  static std::vector<std::pair<std::string, std::function<void()>>> v;
  return v;
}

}  // namespace

namespace nda {

test::test(const std::string& name, std::function<void()> fn) {
  add_test(name, fn);
}

void add_test(const std::string& name, std::function<void()> fn) {
  tests().push_back(std::make_pair(name, fn));
}

}  // namespace nda

using namespace nda;

int main(int argc, const char** argv) {
  // By default, the filter matches all tests.
  const char* filter = "*";
  if (argc > 1) {
    filter = argv[1];
    std::cout << "Running tests matching '" << filter << "'..." << std::endl;
  }

  size_t passed = 0;
  size_t total = 0;
  for (auto& i : tests()) {
    if (!wildcard_match(filter, i.first.c_str())) continue;

    std::cout << i.first << " ";
#ifndef NDARRAY_NO_EXCEPTIONS
    try {
#endif
      i.second();
      std::cout << "passed" << std::endl;
      passed++;
#ifndef NDARRAY_NO_EXCEPTIONS
    } catch(const std::exception& e) {
      std::cout << "failed: " << e.what() << std::endl;
    }
#endif
    total++;
  }
  std::cout << passed << " of " << total << " tests passed, " << tests().size() - total << " skipped" << std::endl;
  return passed < total ? -1 : 0;
}
<|endoftext|>


<commit_before>#include <cassert>
#include <chrono>
#include <cmath>
#include <iostream>

#include "dependencies/Catch/catch_with_main.hpp"

#include "../reflect.h"

struct Perfect {
   int m = 0;

   Perfect(const Perfect&) = delete;
   Perfect(Perfect&&) = delete;
};

struct NonCopyable {
   int m;

   NonCopyable(const NonCopyable&) = delete;
   NonCopyable(NonCopyable&&) = default;

   NonCopyable& operator=(NonCopyable&&) = default;
   NonCopyable& operator=(const NonCopyable&) = delete;
};

static int tally = 0;

struct Foo {
   int i = 0;
   bool b = false;
   char c = '\0';
   NonCopyable ncmem{ 0 };

   void Bar() {
      std::cout << "Bar called" << std::endl;
      b = true;
   }

   int Baz() {
      std::cout << "Baz called" << std::endl;
      return i;
   }

   int Baz2(int x) {
      std::cout << "Baz2 called" << std::endl;
      return x;
   }

   void Perf(Perfect&& n) {
      std::cout << "Perf called" << std::endl;
   }

   void NC(NonCopyable nc) {
      std::cout << "NC called" << std::endl;
   }

   void Tally(int x) {
      tally += 1 + x % static_cast<int>(std::sqrt(tally + 10));
   }
};

REFLECT_ENABLE(Foo, i, b, c, ncmem, Bar, Baz, Baz2, Perf, NC, Tally)

struct Static {
   static int abc;
};

int Static::abc = 1;

REFLECT_ENABLE(Static, abc);

struct Const {
   const static int _static = 10;
   const int _const = 12;
};

const int Const::_static;

REFLECT_ENABLE(Const, _static, _const);

struct Arrays {
   int* iptr = new int(42);
   int iarr10[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

   ~Arrays() {
      delete iptr;
   }
};

REFLECT_ENABLE(Arrays, iptr, iarr10);

SCENARIO("members can be written to", "[reflection]") {
GIVEN("a reflected object") {
   Foo f{};
   auto reflectfoo = reflect::reflect(f);

   REQUIRE(f.i == 0);
   REQUIRE(f.b == false);
   REQUIRE(f.c == 0);
   REQUIRE(f.ncmem.m == 0);

WHEN("an int is assigned to an int member") {
   constexpr int ten = 10;
   CHECK_NOTHROW(reflectfoo["i"] = ten);

THEN("the value is changed") {
   CHECK(ten == f.i);
}
}

WHEN("a char is assigned to an int member") {
   constexpr char c = 'c';
   CHECK_NOTHROW(reflectfoo["i"] = c);

THEN("the value is changed") {
   CHECK(c == f.i);
}
}

WHEN("a size_t is assigned to an int member") {
   constexpr std::size_t eleven = 11;
   CHECK_NOTHROW(reflectfoo["i"] = eleven);

THEN("the value is changed") {
   CHECK(eleven == f.i);
}
}

WHEN("a char is assigned to a char member") {
   constexpr char c = 'c';
   CHECK_NOTHROW(reflectfoo["c"] = c);

THEN("the value is changed") {
   CHECK(c == f.c);
}
}

WHEN("a string is assigned to a char member") {
THEN("an exception is thrown") {
   static const std::string s = "hello world";
   CHECK_THROWS_AS(reflectfoo["c"] = s, const reflect::invalid_assignment_type&);
}
}

WHEN("a string is assigned to a function member") {
THEN("an exception is thrown") {
   static const std::string s = "hello world";
   CHECK_THROWS_AS(reflectfoo["Bar"] = s, const reflect::invalid_assignment_type&);
}
}

}
}

/*
int main() {

   Foo f{};
   auto reflectfoo = reflect::reflect(f);
   {
      reflectfoo["i"] = 'c';

      reflectfoo["i"] = 10;
      assert(f.i == 10);
      std::cout << f.i << std::endl;

      int a = reflectfoo["i"];
      assert(a == 10);

      int& aref = reflectfoo["i"];
      assert(aref == 10);

      char c = reflectfoo["i"];

      reflectfoo["Bar"]();
      reflectfoo["Bar"].invoke<void>();
      assert(f.b);

      try {
         reflectfoo["i"]();
         assert(false);
      }
      catch (const reflect::invalid_function_call& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      reflectfoo["i"] = std::size_t{ 0 };
      assert(f.i == 0);

      try {
         reflectfoo["i"] = std::string();
         assert(false);
      }
      catch (const reflect::invalid_assignment_type& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      int i = reflectfoo["Baz"]();
      assert(i == f.i);

      reflectfoo["Baz"]();

      int x = reflectfoo["Baz2"](42);
      assert(x == 42);
      double d = reflectfoo["Baz2"](42.0);

      try {
         int x = reflectfoo["Bar"]();
         assert(false);
      }
      catch (const reflect::invalid_function_call& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      std::size_t sizei = reflectfoo["i"];
      assert(f.i == sizei);

      try {
         std::string s = reflectfoo["i"];
         assert(false);
      }
      catch (const reflect::invalid_requested_member_type& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      reflectfoo["Perf"](Perfect{ 10 });

      NonCopyable& ncref = reflectfoo["ncmem"];
      assert(ncref.m == 43);

      NonCopyable nc2{ 10 };
      reflectfoo["ncmem"] = std::move(nc2);
      assert(ncref.m == 10);

      NonCopyable nc{ 10 };
      reflectfoo["NC"](std::move(nc));
   }

   auto reflectstaticfoo = reflect::reflect<Foo>();
   {
      try {
         int  i = reflectstaticfoo["i"];
         assert(false);
      }
      catch (const reflect::member_access_error& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }
   }

   auto reflectstatic = reflect::reflect<Static>();
   {
      int abc = reflectstatic["abc"];
      assert(abc == Static::abc);

      reflectstatic["abc"] = 2;
      assert(Static::abc == 2);
   }

   Const _const;
   auto reflectconst = reflect::reflect(_const);
   {
      int c = reflectconst["_const"];
      assert(c == _const._const);

      try {
         reflectconst["_const"] = 10;
         assert(false);
      }
      catch (const reflect::invalid_assignment_to_const& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      int s = reflectconst["_static"];
      assert(s == Const::_static);

      try {
         reflectconst["_static"] = 10;
         assert(false);
      }
      catch (const reflect::invalid_assignment_to_const& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }
   }

   Arrays arrays;
   auto reflectarrays = reflect::reflect(arrays);
   {
      int* p = reflectarrays["iptr"];
      assert(p == arrays.iptr);

      int* arrptr = reflectarrays["iarr10"];
      assert(arrptr == arrays.iarr10);

      int (&arrref)[10] = reflectarrays["iarr10"];
      assert(arrref == arrays.iarr10);

      try {
         int (&badarref)[2] = reflectarrays["iarr10"];
         assert(false);
      }
      catch (const reflect::invalid_requested_member_type& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }
   }

   constexpr int iters = 100000000;
   std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
   start = std::chrono::high_resolution_clock::now();

   for (int i = 0; i < iters; ++i) {
      f.Tally(42);
   }

   end = std::chrono::high_resolution_clock::now();

   std::chrono::duration<long double, std::nano> delta = end - start;
   long double delta_per_iter = delta.count() / (long double)iters;
   std::cout.precision(15);

   std::cout << "direct: \t" << delta_per_iter << " ns/iter" << std::endl;

   start = std::chrono::high_resolution_clock::now();

   for (int i = 0; i < iters; ++i) {
      reflectfoo["Tally"](42);
   }

   end = std::chrono::high_resolution_clock::now();

   delta = end - start;
   delta_per_iter = delta.count() / (long double)iters;
   std::cout.precision(15);

   std::cout << "reflected: \t" << delta_per_iter << " ns/iter" << std::endl;

   std::cout << tally << std::endl;

   std::cin.ignore();
}
//*/
<commit_msg>some more tests<commit_after>#include <cassert>
#include <chrono>
#include <cmath>
#include <iostream>

#include "dependencies/Catch/catch_with_main.hpp"

#include "../reflect.h"

struct Perfect {
   int m = 0;

   Perfect(const Perfect&) = delete;
   Perfect(Perfect&&) = delete;
};

struct NonCopyable {
   int m;

   NonCopyable(const NonCopyable&) = delete;
   NonCopyable(NonCopyable&&) = default;

   NonCopyable& operator=(NonCopyable&&) = default;
   NonCopyable& operator=(const NonCopyable&) = delete;
};

static int tally = 0;

struct Foo {
   int i = 0;
   bool b = false;
   char c = '\0';
   NonCopyable ncmem{ 0 };

   void Bar() {
      std::cout << "Bar called" << std::endl;
      b = true;
   }

   int Baz() {
      std::cout << "Baz called" << std::endl;
      return i;
   }

   int Baz2(int x) {
      std::cout << "Baz2 called" << std::endl;
      return x;
   }

   void Perf(Perfect&& n) {
      std::cout << "Perf called" << std::endl;
   }

   void NC(NonCopyable nc) {
      std::cout << "NC called" << std::endl;
   }

   void Tally(int x) {
      tally += 1 + x % static_cast<int>(std::sqrt(tally + 10));
   }
};

REFLECT_ENABLE(Foo, i, b, c, ncmem, Bar, Baz, Baz2, Perf, NC, Tally)

struct Static {
   static int abc;
};

int Static::abc = 0;

REFLECT_ENABLE(Static, abc);

struct Const {
   const static int _static = 10;
   const int _const = 12;
};

const int Const::_static;

REFLECT_ENABLE(Const, _static, _const);

struct Arrays {
   int* iptr = new int(42);
   int iarr10[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

   ~Arrays() {
      delete iptr;
   }
};

REFLECT_ENABLE(Arrays, iptr, iarr10);

SCENARIO("members can be written to", "[reflection]") {
GIVEN("a reflected object") {
   Foo f{};
   auto reflected = reflect::reflect(f);

   REQUIRE(f.i == 0);
   REQUIRE(f.b == false);
   REQUIRE(f.c == 0);
   REQUIRE(f.ncmem.m == 0);

WHEN("an int literal is assigned to an int member") {
   CHECK_NOTHROW(reflected["i"] = 10);

THEN("the value is changed") {
   CHECK(10 == f.i);
}
}

WHEN("an int is assigned to an int member") {
   constexpr int ten = 10;
   CHECK_NOTHROW(reflected["i"] = ten);

THEN("the value is changed") {
   CHECK(ten == f.i);
}
}

WHEN("a char is assigned to an int member") {
   constexpr char c = 'c';
   CHECK_NOTHROW(reflected["i"] = c);

THEN("the value is changed") {
   CHECK(c == f.i);
}
}

WHEN("a size_t is assigned to an int member") {
   constexpr std::size_t eleven = 11;
   CHECK_NOTHROW(reflected["i"] = eleven);

THEN("the value is changed") {
   CHECK(eleven == f.i);
}
}

WHEN("a char is assigned to a char member") {
   constexpr char c = 'c';
   CHECK_NOTHROW(reflected["c"] = c);

THEN("the value is changed") {
   CHECK(c == f.c);
}
}

WHEN("a string is assigned to a char member") {
THEN("an exception is thrown") {
   static const std::string s = "hello world";
   CHECK_THROWS_AS(reflected["c"] = s, const reflect::invalid_assignment_type&);
}
}

WHEN("a string is assigned to a function member") {
THEN("an exception is thrown") {
   static const std::string s = "hello world";
   CHECK_THROWS_AS(reflected["Bar"] = s, const reflect::invalid_assignment_type&);
}
}
}

GIVEN("a reflected static instance with non-static members") {
   auto reflected = reflect::reflect<Foo>();

WHEN("a non-static member is accessed") {
THEN("an exception is thrown") {
   CHECK_THROWS_AS(reflected["i"] = 0, const reflect::member_access_error&);
}
}
}

GIVEN("a reflected static instance with static members") {
   auto reflected = reflect::reflect<Static>();
   REQUIRE(Static::abc == 0);

WHEN("a static member is accessed") {
   CHECK_NOTHROW(reflected["abc"] = 10);

THEN("the value is changed") {
   CHECK(10 == Static::abc);
}
}
}
}

/*
int main() {

   Foo f{};
   auto reflectfoo = reflect::reflect(f);
   {
      reflectfoo["i"] = 'c';

      reflectfoo["i"] = 10;
      assert(f.i == 10);
      std::cout << f.i << std::endl;

      int a = reflectfoo["i"];
      assert(a == 10);

      int& aref = reflectfoo["i"];
      assert(aref == 10);

      char c = reflectfoo["i"];

      reflectfoo["Bar"]();
      reflectfoo["Bar"].invoke<void>();
      assert(f.b);

      try {
         reflectfoo["i"]();
         assert(false);
      }
      catch (const reflect::invalid_function_call& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      reflectfoo["i"] = std::size_t{ 0 };
      assert(f.i == 0);

      try {
         reflectfoo["i"] = std::string();
         assert(false);
      }
      catch (const reflect::invalid_assignment_type& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      int i = reflectfoo["Baz"]();
      assert(i == f.i);

      reflectfoo["Baz"]();

      int x = reflectfoo["Baz2"](42);
      assert(x == 42);
      double d = reflectfoo["Baz2"](42.0);

      try {
         int x = reflectfoo["Bar"]();
         assert(false);
      }
      catch (const reflect::invalid_function_call& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      std::size_t sizei = reflectfoo["i"];
      assert(f.i == sizei);

      try {
         std::string s = reflectfoo["i"];
         assert(false);
      }
      catch (const reflect::invalid_requested_member_type& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      reflectfoo["Perf"](Perfect{ 10 });

      NonCopyable& ncref = reflectfoo["ncmem"];
      assert(ncref.m == 43);

      NonCopyable nc2{ 10 };
      reflectfoo["ncmem"] = std::move(nc2);
      assert(ncref.m == 10);

      NonCopyable nc{ 10 };
      reflectfoo["NC"](std::move(nc));
   }

   auto reflectstaticfoo = reflect::reflect<Foo>();
   {
      try {
         int  i = reflectstaticfoo["i"];
         assert(false);
      }
      catch (const reflect::member_access_error& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }
   }

   auto reflectstatic = reflect::reflect<Static>();
   {
      int abc = reflectstatic["abc"];
      assert(abc == Static::abc);

      reflectstatic["abc"] = 2;
      assert(Static::abc == 2);
   }

   Const _const;
   auto reflectconst = reflect::reflect(_const);
   {
      int c = reflectconst["_const"];
      assert(c == _const._const);

      try {
         reflectconst["_const"] = 10;
         assert(false);
      }
      catch (const reflect::invalid_assignment_to_const& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }

      int s = reflectconst["_static"];
      assert(s == Const::_static);

      try {
         reflectconst["_static"] = 10;
         assert(false);
      }
      catch (const reflect::invalid_assignment_to_const& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }
   }

   Arrays arrays;
   auto reflectarrays = reflect::reflect(arrays);
   {
      int* p = reflectarrays["iptr"];
      assert(p == arrays.iptr);

      int* arrptr = reflectarrays["iarr10"];
      assert(arrptr == arrays.iarr10);

      int (&arrref)[10] = reflectarrays["iarr10"];
      assert(arrref == arrays.iarr10);

      try {
         int (&badarref)[2] = reflectarrays["iarr10"];
         assert(false);
      }
      catch (const reflect::invalid_requested_member_type& e) {
         std::cout << "caught: " << e.what() << std::endl;
      }
   }

   constexpr int iters = 100000000;
   std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
   start = std::chrono::high_resolution_clock::now();

   for (int i = 0; i < iters; ++i) {
      f.Tally(42);
   }

   end = std::chrono::high_resolution_clock::now();

   std::chrono::duration<long double, std::nano> delta = end - start;
   long double delta_per_iter = delta.count() / (long double)iters;
   std::cout.precision(15);

   std::cout << "direct: \t" << delta_per_iter << " ns/iter" << std::endl;

   start = std::chrono::high_resolution_clock::now();

   for (int i = 0; i < iters; ++i) {
      reflectfoo["Tally"](42);
   }

   end = std::chrono::high_resolution_clock::now();

   delta = end - start;
   delta_per_iter = delta.count() / (long double)iters;
   std::cout.precision(15);

   std::cout << "reflected: \t" << delta_per_iter << " ns/iter" << std::endl;

   std::cout << tally << std::endl;

   std::cin.ignore();
}
//*/
<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011        Daniel Marth <danielmarth@gmx.at>
// Copyright 2012        Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//

#include "QtPositioningPositionProviderPlugin.h"

#include <QGeoPositionInfoSource>
#include <QGeoPositionInfo>
#include <QGeoCoordinate>

#if QT_VERSION < 0x050000

QTM_USE_NAMESPACE

#endif

namespace Marble {

class QtPositioningPositionProviderPluginPrivate
{
public:
    QtPositioningPositionProviderPluginPrivate();

    QGeoPositionInfoSource *const m_source;
    PositionProviderStatus m_status;
};

QtPositioningPositionProviderPluginPrivate::QtPositioningPositionProviderPluginPrivate() :
    m_source( QGeoPositionInfoSource::createDefaultSource( 0 ) ),
    m_status( PositionProviderStatusAcquiring )
{
}

QString QtPositioningPositionProviderPlugin::name() const
{
    return tr( "Qt Psoitioning Position Provider Plugin" );
}

QString QtPositioningPositionProviderPlugin::nameId() const
{
    return "QtPositioning";
}

QString QtPositioningPositionProviderPlugin::guiString() const
{
    return tr( "Qt Positioning Location" );
}

QString QtPositioningPositionProviderPlugin::version() const
{
    return "1.0";
}

QString QtPositioningPositionProviderPlugin::description() const
{
    return tr( "Reports the GPS position of a QtPositioning compatible device." );
}

QString QtPositioningPositionProviderPlugin::copyrightYears() const
{
    return "2011";
}

QList<PluginAuthor> QtPositioningPositionProviderPlugin::pluginAuthors() const
{
    return QList<PluginAuthor>()
            << PluginAuthor( "Daniel Marth", "danielmarth@gmx.at" );
}

QIcon QtPositioningPositionProviderPlugin::icon() const
{
    return QIcon();
}

PositionProviderPlugin* QtPositioningPositionProviderPlugin::newInstance() const
{
    return new QtPositioningPositionProviderPlugin;
}

PositionProviderStatus QtPositioningPositionProviderPlugin::status() const
{
    return d->m_status;
}

GeoDataCoordinates QtPositioningPositionProviderPlugin::position() const
{
    if ( d->m_source == 0 ) {
        return GeoDataCoordinates();
    }

    const QGeoCoordinate p = d->m_source->lastKnownPosition().coordinate();
    if( !p.isValid() ) {
        return GeoDataCoordinates();
    }

    return GeoDataCoordinates( p.longitude(), p.latitude(),
                               p.altitude(), GeoDataCoordinates::Degree );
}

GeoDataAccuracy QtPositioningPositionProviderPlugin::accuracy() const
{
    if ( d->m_source == 0 ) {
        return GeoDataAccuracy();
    }

    const QGeoPositionInfo info = d->m_source->lastKnownPosition();

    if( !info.hasAttribute( QGeoPositionInfo::HorizontalAccuracy ) ||
        !info.hasAttribute( QGeoPositionInfo::VerticalAccuracy ) ) {
        return GeoDataAccuracy();
    }

    const qreal horizontal = info.attribute( QGeoPositionInfo::HorizontalAccuracy );
    const qreal vertical = info.attribute( QGeoPositionInfo::VerticalAccuracy );

    return GeoDataAccuracy( GeoDataAccuracy::Detailed, horizontal, vertical );
}

QtPositioningPositionProviderPlugin::QtPositioningPositionProviderPlugin() :
        d( new QtPositioningPositionProviderPluginPrivate )
{
}

QtPositioningPositionProviderPlugin::~QtPositioningPositionProviderPlugin()
{
    delete d;
}

void QtPositioningPositionProviderPlugin::initialize()
{
    if( d->m_source ) {
        connect( d->m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(update()) );
        d->m_source->setUpdateInterval( 1000 );
        d->m_source->startUpdates();
    }
}

bool QtPositioningPositionProviderPlugin::isInitialized() const
{
    return d->m_source != 0;
}

qreal QtPositioningPositionProviderPlugin::speed() const
{
    if ( d->m_source == 0 ) {
        return 0.0;
    }

    if( !d->m_source->lastKnownPosition().hasAttribute( QGeoPositionInfo::GroundSpeed ) ) {
        return 0.0;
    }

    return d->m_source->lastKnownPosition().attribute( QGeoPositionInfo::GroundSpeed );
}

qreal QtPositioningPositionProviderPlugin::direction() const
{
    if ( d->m_source == 0 ) {
        return 0.0;
    }

    if( !d->m_source->lastKnownPosition().hasAttribute( QGeoPositionInfo::Direction ) ) {
        return 0.0;
    }

    return d->m_source->lastKnownPosition().attribute( QGeoPositionInfo::Direction );
}

QDateTime QtPositioningPositionProviderPlugin::timestamp() const
{
    if ( d->m_source == 0 ) {
        return QDateTime();
    }

    return d->m_source->lastKnownPosition().timestamp();
}

void QtPositioningPositionProviderPlugin::update()
{
    PositionProviderStatus newStatus = PositionProviderStatusAcquiring;
    if ( d->m_source ) {
        if ( d->m_source->lastKnownPosition().isValid() ) {
            newStatus = PositionProviderStatusAvailable;
        }
        else {
            newStatus = PositionProviderStatusError;
        }
    }

    if ( newStatus != d->m_status ) {
        d->m_status = newStatus;
        emit statusChanged( newStatus );
    }

    if ( newStatus == PositionProviderStatusAvailable ) {
        emit positionChanged( position(), accuracy() );
    }
}

} // namespace Marble

Q_EXPORT_PLUGIN2( Marble::QtMobilityPositionProviderPlugin, Marble::QtMobilityPositionProviderPlugin )

#include "moc_QtPositioningPositionProviderPlugin.cpp"
<commit_msg>Fix typo<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011        Daniel Marth <danielmarth@gmx.at>
// Copyright 2012        Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//

#include "QtPositioningPositionProviderPlugin.h"

#include <QGeoPositionInfoSource>
#include <QGeoPositionInfo>
#include <QGeoCoordinate>

#if QT_VERSION < 0x050000

QTM_USE_NAMESPACE

#endif

namespace Marble {

class QtPositioningPositionProviderPluginPrivate
{
public:
    QtPositioningPositionProviderPluginPrivate();

    QGeoPositionInfoSource *const m_source;
    PositionProviderStatus m_status;
};

QtPositioningPositionProviderPluginPrivate::QtPositioningPositionProviderPluginPrivate() :
    m_source( QGeoPositionInfoSource::createDefaultSource( 0 ) ),
    m_status( PositionProviderStatusAcquiring )
{
}

QString QtPositioningPositionProviderPlugin::name() const
{
    return tr( "Qt Positioning Position Provider Plugin" );
}

QString QtPositioningPositionProviderPlugin::nameId() const
{
    return "QtPositioning";
}

QString QtPositioningPositionProviderPlugin::guiString() const
{
    return tr( "Qt Positioning Location" );
}

QString QtPositioningPositionProviderPlugin::version() const
{
    return "1.0";
}

QString QtPositioningPositionProviderPlugin::description() const
{
    return tr( "Reports the GPS position of a QtPositioning compatible device." );
}

QString QtPositioningPositionProviderPlugin::copyrightYears() const
{
    return "2011";
}

QList<PluginAuthor> QtPositioningPositionProviderPlugin::pluginAuthors() const
{
    return QList<PluginAuthor>()
            << PluginAuthor( "Daniel Marth", "danielmarth@gmx.at" );
}

QIcon QtPositioningPositionProviderPlugin::icon() const
{
    return QIcon();
}

PositionProviderPlugin* QtPositioningPositionProviderPlugin::newInstance() const
{
    return new QtPositioningPositionProviderPlugin;
}

PositionProviderStatus QtPositioningPositionProviderPlugin::status() const
{
    return d->m_status;
}

GeoDataCoordinates QtPositioningPositionProviderPlugin::position() const
{
    if ( d->m_source == 0 ) {
        return GeoDataCoordinates();
    }

    const QGeoCoordinate p = d->m_source->lastKnownPosition().coordinate();
    if( !p.isValid() ) {
        return GeoDataCoordinates();
    }

    return GeoDataCoordinates( p.longitude(), p.latitude(),
                               p.altitude(), GeoDataCoordinates::Degree );
}

GeoDataAccuracy QtPositioningPositionProviderPlugin::accuracy() const
{
    if ( d->m_source == 0 ) {
        return GeoDataAccuracy();
    }

    const QGeoPositionInfo info = d->m_source->lastKnownPosition();

    if( !info.hasAttribute( QGeoPositionInfo::HorizontalAccuracy ) ||
        !info.hasAttribute( QGeoPositionInfo::VerticalAccuracy ) ) {
        return GeoDataAccuracy();
    }

    const qreal horizontal = info.attribute( QGeoPositionInfo::HorizontalAccuracy );
    const qreal vertical = info.attribute( QGeoPositionInfo::VerticalAccuracy );

    return GeoDataAccuracy( GeoDataAccuracy::Detailed, horizontal, vertical );
}

QtPositioningPositionProviderPlugin::QtPositioningPositionProviderPlugin() :
        d( new QtPositioningPositionProviderPluginPrivate )
{
}

QtPositioningPositionProviderPlugin::~QtPositioningPositionProviderPlugin()
{
    delete d;
}

void QtPositioningPositionProviderPlugin::initialize()
{
    if( d->m_source ) {
        connect( d->m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(update()) );
        d->m_source->setUpdateInterval( 1000 );
        d->m_source->startUpdates();
    }
}

bool QtPositioningPositionProviderPlugin::isInitialized() const
{
    return d->m_source != 0;
}

qreal QtPositioningPositionProviderPlugin::speed() const
{
    if ( d->m_source == 0 ) {
        return 0.0;
    }

    if( !d->m_source->lastKnownPosition().hasAttribute( QGeoPositionInfo::GroundSpeed ) ) {
        return 0.0;
    }

    return d->m_source->lastKnownPosition().attribute( QGeoPositionInfo::GroundSpeed );
}

qreal QtPositioningPositionProviderPlugin::direction() const
{
    if ( d->m_source == 0 ) {
        return 0.0;
    }

    if( !d->m_source->lastKnownPosition().hasAttribute( QGeoPositionInfo::Direction ) ) {
        return 0.0;
    }

    return d->m_source->lastKnownPosition().attribute( QGeoPositionInfo::Direction );
}

QDateTime QtPositioningPositionProviderPlugin::timestamp() const
{
    if ( d->m_source == 0 ) {
        return QDateTime();
    }

    return d->m_source->lastKnownPosition().timestamp();
}

void QtPositioningPositionProviderPlugin::update()
{
    PositionProviderStatus newStatus = PositionProviderStatusAcquiring;
    if ( d->m_source ) {
        if ( d->m_source->lastKnownPosition().isValid() ) {
            newStatus = PositionProviderStatusAvailable;
        }
        else {
            newStatus = PositionProviderStatusError;
        }
    }

    if ( newStatus != d->m_status ) {
        d->m_status = newStatus;
        emit statusChanged( newStatus );
    }

    if ( newStatus == PositionProviderStatusAvailable ) {
        emit positionChanged( position(), accuracy() );
    }
}

} // namespace Marble

Q_EXPORT_PLUGIN2( Marble::QtMobilityPositionProviderPlugin, Marble::QtMobilityPositionProviderPlugin )

#include "moc_QtPositioningPositionProviderPlugin.cpp"
<|endoftext|>


<commit_before>#include "board.h"
#include "renderer.h"
#include "sound.h"

#include <iostream>
#include <chrono>

#include <SFML/Window.hpp>

int main(int argc, char* argv[])
{
    //  create world
    Board board(8, 8);
    board.initBallsRandom(5);

    Renderer renderer;

    //  create window
    sf::ContextSettings contextSettings;
    contextSettings.depthBits = 32;

    sf::Window window(sf::VideoMode(800, 600), "ORDO", sf::Style::Default, contextSettings);
    window.setVerticalSyncEnabled(true);

    //  start main loop
    sf::Clock clock;

    while (window.isOpen())
    {
        //  process events
        sf::Event event;

        while (window.pollEvent(event))
        {
            //  close window -> exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }

            //  escape key -> exit
            if (event.type == sf::Event::KeyPressed)
            {
                switch (event.key.code)
                {
                    case sf::Keyboard::Escape:
                        window.close();
                        break;

                    default:
                        break;
                }
            }

            //  resize viewport
            if (event.type == sf::Event::Resized) {
                glViewport(0, 0, event.size.width, event.size.height);
            }
        }

        //  render everything
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        renderer.drawBoard(board);

        window.display();
    }

//    FMOD_RESULT result;
//
//    //  init system
//    FMOD::System* system = 0;
//    FMOD::System_Create(&system);
//
//    result = system->setOutput(FMOD_OUTPUTTYPE_COREAUDIO); FMOD::check(result);
//    result = system->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); FMOD::check(result);
//    result = system->init(64, FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED, 0); FMOD::check(result);
//
//    //  create sound
//    FMOD_CREATESOUNDEXINFO exinfo;
//    memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
//
//    exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
//    exinfo.numchannels = 2;
//    exinfo.defaultfrequency = 44100;
//    exinfo.format = FMOD_SOUND_FORMAT_PCMFLOAT;
//    exinfo.length = exinfo.defaultfrequency * sizeof(float) * exinfo.numchannels * 1.0f;
//
//    FMOD::Sound* sound = 0;
//    result = system->createSound(0, FMOD_3D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &sound); FMOD::check(result);
//
//    FMOD::DSP* dsp = 0;
//    result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp); FMOD::check(result);
//    result = dsp->setParameter(FMOD_DSP_OSCILLATOR_RATE, 440.0f); FMOD::check(result);
//    result = dsp->setParameter(FMOD_DSP_OSCILLATOR_TYPE, 2); FMOD::check(result);
//
//    FMOD::Channel* channel = 0;
//    result = system->playDSP(FMOD_CHANNEL_FREE, dsp, false, &channel); FMOD::check(result);
//
//    //  create geometry
//    FMOD::Geometry* geometry;
//    result = system->setGeometrySettings(100); FMOD::check(result);
//    result = system->createGeometry(1024, 4096, &geometry); FMOD::check(result);
//
//    int index = 0;
////    FMOD_VECTOR vertices[4] = {{-1, -1,-1}, {1, -1,-1}, {1, 1,-1}, {-1, 1,-1}};
//    FMOD_VECTOR vertices[4] = {{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}};
//    geometry->addPolygon(1.0, 1.0, true, 4, vertices, &index);
//    geometry->setPolygonAttributes(0, 0.9, 0.9, true);
//
//    //  position objects
//    FMOD_VECTOR lpos = {0, 0, 0};
//    FMOD_VECTOR lvel = {0, 0, 0};
//    FMOD_VECTOR lfwd = {0, 0, 1};
//    FMOD_VECTOR lup = {0, 1, 0};
//    result = system->set3DListenerAttributes(0, &lpos, &lvel, &lfwd, &lup);
//
//    float angle = 0.0f;
//    std::random_device rnd;
//    std::uniform_int_distribution<> uni(0, 1);
//    int dir = 2 * (uni(rnd)) - 1;
//    float v0 = dir * 2.0f;
//    float radius = 10.0f;
//
//    std::cout << dir << std::endl;
//
//    FMOD_VECTOR cpos = {0, 0, radius};
//    FMOD_VECTOR cvel = {v0, 0, 0};
//    result = channel->setMode(FMOD_3D); FMOD::check(result);
//    result = channel->set3DAttributes(&cpos, &cvel); FMOD::check(result);
//
//    //  main simulation
//    using namespace std::chrono;
//    high_resolution_clock::time_point t0 = high_resolution_clock::now();
//
//    while (true)
//    {
//        if (kbhit()) {
//            break;
//        }
//
//        //  update timer
//        high_resolution_clock::time_point t1 = high_resolution_clock::now();
//        float dt = duration_cast<milliseconds>(t1 - t0).count() / 1000.0f;
//        t0 = t1;
//
//        //  move source
//        angle = angle + dt * v0;
//        cpos.x = radius * sinf(angle);
//        cpos.z = radius * cosf(angle);
//        cvel.x = v0 * cosf(angle);
//        cvel.z = v0 * sinf(angle);
//
//        channel->set3DAttributes(&cpos, &cvel);
//
////        std::cout << cpos << std::endl;
//
//        //  update engine
//        result = system->update(); FMOD::check(result);
//        sleep(0.01f);
//    }
//
//    //  release resources
//    result = dsp->release(); FMOD::check(result);
//    result = system->release(); FMOD::check(result);

    return 0;
}<commit_msg>set up basic main loop. add movement controls<commit_after>#include "board.h"
#include "renderer.h"
#include "sound.h"

#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    //  create world
    Board board(8, 8);
    board.initBallsRandom(5);

    Renderer renderer;

    //  create window
    bool fullscreen = false;

    sf::VideoMode dmode(1440, 900);
    sf::VideoMode fmode = sf::VideoMode::getFullscreenModes()[0];
    string title = "ORDO";
    sf::ContextSettings settings(32);

    sf::Window window(dmode, title, sf::Style::Default, settings);
    window.setVerticalSyncEnabled(true);

    //  start main loop
    sf::Clock clock;

    while (window.isOpen())
    {
        //  process events
        sf::Event event;

        while (window.pollEvent(event))
        {
            //  close window -> exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }

            //  handle keys
            if (event.type == sf::Event::KeyPressed)
            {
                switch (event.key.code)
                {
                    //  close on escape
                    case sf::Keyboard::Escape:
                        window.close();
                        break;

                    //  fullscreen
                    case sf::Keyboard::F:
                    {
                        if (fullscreen) {
                            window.create(dmode, title, sf::Style::Default, settings);
                        } else {
                            window.create(fmode, title, sf::Style::Fullscreen, settings);
                        }

                        fullscreen = !fullscreen;
                        break;
                    }

                    //  move player
                    case sf::Keyboard::Right:
                        board.movePlayerRight();
                        break;

                    case sf::Keyboard::Left:
                        board.movePlayerLeft();
                        break;

                    //  shoot
                    case sf::Keyboard::Space:
                        cout << "SHOOT!" << endl;
                        break;

                    default:
                        break;
                }
            }

            //  resize viewport
            if (event.type == sf::Event::Resized) {
                glViewport(0, 0, event.size.width, event.size.height);
            }
        }

        //  render everything
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        renderer.drawBoard(board);

        window.display();
    }

//    FMOD_RESULT result;
//
//    //  init system
//    FMOD::System* system = 0;
//    FMOD::System_Create(&system);
//
//    result = system->setOutput(FMOD_OUTPUTTYPE_COREAUDIO); FMOD::check(result);
//    result = system->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); FMOD::check(result);
//    result = system->init(64, FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED, 0); FMOD::check(result);
//
//    //  create sound
//    FMOD_CREATESOUNDEXINFO exinfo;
//    memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
//
//    exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
//    exinfo.numchannels = 2;
//    exinfo.defaultfrequency = 44100;
//    exinfo.format = FMOD_SOUND_FORMAT_PCMFLOAT;
//    exinfo.length = exinfo.defaultfrequency * sizeof(float) * exinfo.numchannels * 1.0f;
//
//    FMOD::Sound* sound = 0;
//    result = system->createSound(0, FMOD_3D | FMOD_SOFTWARE | FMOD_OPENUSER, &exinfo, &sound); FMOD::check(result);
//
//    FMOD::DSP* dsp = 0;
//    result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp); FMOD::check(result);
//    result = dsp->setParameter(FMOD_DSP_OSCILLATOR_RATE, 440.0f); FMOD::check(result);
//    result = dsp->setParameter(FMOD_DSP_OSCILLATOR_TYPE, 2); FMOD::check(result);
//
//    FMOD::Channel* channel = 0;
//    result = system->playDSP(FMOD_CHANNEL_FREE, dsp, false, &channel); FMOD::check(result);
//
//    //  create geometry
//    FMOD::Geometry* geometry;
//    result = system->setGeometrySettings(100); FMOD::check(result);
//    result = system->createGeometry(1024, 4096, &geometry); FMOD::check(result);
//
//    int index = 0;
////    FMOD_VECTOR vertices[4] = {{-1, -1,-1}, {1, -1,-1}, {1, 1,-1}, {-1, 1,-1}};
//    FMOD_VECTOR vertices[4] = {{-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}};
//    geometry->addPolygon(1.0, 1.0, true, 4, vertices, &index);
//    geometry->setPolygonAttributes(0, 0.9, 0.9, true);
//
//    //  position objects
//    FMOD_VECTOR lpos = {0, 0, 0};
//    FMOD_VECTOR lvel = {0, 0, 0};
//    FMOD_VECTOR lfwd = {0, 0, 1};
//    FMOD_VECTOR lup = {0, 1, 0};
//    result = system->set3DListenerAttributes(0, &lpos, &lvel, &lfwd, &lup);
//
//    float angle = 0.0f;
//    std::random_device rnd;
//    std::uniform_int_distribution<> uni(0, 1);
//    int dir = 2 * (uni(rnd)) - 1;
//    float v0 = dir * 2.0f;
//    float radius = 10.0f;
//
//    std::cout << dir << std::endl;
//
//    FMOD_VECTOR cpos = {0, 0, radius};
//    FMOD_VECTOR cvel = {v0, 0, 0};
//    result = channel->setMode(FMOD_3D); FMOD::check(result);
//    result = channel->set3DAttributes(&cpos, &cvel); FMOD::check(result);
//
//    //  main simulation
//    using namespace std::chrono;
//    high_resolution_clock::time_point t0 = high_resolution_clock::now();
//
//    while (true)
//    {
//        if (kbhit()) {
//            break;
//        }
//
//        //  update timer
//        high_resolution_clock::time_point t1 = high_resolution_clock::now();
//        float dt = duration_cast<milliseconds>(t1 - t0).count() / 1000.0f;
//        t0 = t1;
//
//        //  move source
//        angle = angle + dt * v0;
//        cpos.x = radius * sinf(angle);
//        cpos.z = radius * cosf(angle);
//        cvel.x = v0 * cosf(angle);
//        cvel.z = v0 * sinf(angle);
//
//        channel->set3DAttributes(&cpos, &cvel);
//
////        std::cout << cpos << std::endl;
//
//        //  update engine
//        result = system->update(); FMOD::check(result);
//        sleep(0.01f);
//    }
//
//    //  release resources
//    result = dsp->release(); FMOD::check(result);
//    result = system->release(); FMOD::check(result);

    return 0;
}<|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 <memory>
#include <string>

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "mlir/IR/Attributes.h"  // from @llvm-project
#include "mlir/IR/Block.h"  // from @llvm-project
#include "mlir/IR/Builders.h"  // from @llvm-project
#include "mlir/IR/BuiltinAttributes.h"  // from @llvm-project
#include "mlir/IR/BuiltinOps.h"  // from @llvm-project
#include "mlir/IR/Operation.h"  // from @llvm-project
#include "mlir/IR/Value.h"  // from @llvm-project
#include "mlir/Interfaces/CallInterfaces.h"  // from @llvm-project
#include "mlir/Pass/Pass.h"  // from @llvm-project
#include "mlir/Pass/PassRegistry.h"  // from @llvm-project
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_device.h"
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_ops.h"
#include "tensorflow/compiler/mlir/tensorflow/utils/xla_sharding_util.h"
#include "tensorflow/compiler/xla/client/sharding_builder.h"

namespace mlir {
namespace TFTPU {
namespace {

constexpr char kShardingAttr[] = "mhlo.sharding";
constexpr char kReplicateSharding[] = "";

struct TPUShardingIdentificationPass
    : public PassWrapper<TPUShardingIdentificationPass,
                         OperationPass<ModuleOp>> {
  void runOnOperation() override;
};

// Returns XLA sharding from TPUPartitionedInput op connected to a
// `tf_device.cluster_func` operand value. If value is a resource type then
// TPUPartitionedInput op will be connected to a ReadVariable op that feeds into
// a `tf_device.cluster_func`.
llvm::Optional<llvm::StringRef> GetXlaShardingFromOperand(Value value) {
  Value value_to_visit = value;
  if (auto read_var = llvm::dyn_cast_or_null<TF::ReadVariableOp>(
          value_to_visit.getDefiningOp()))
    value_to_visit = read_var.resource();

  if (auto partitioned_input =
          llvm::dyn_cast_or_null<TF::TPUPartitionedInputOp>(
              value_to_visit.getDefiningOp()))
    return partitioned_input._XlaSharding();

  return llvm::None;
}

// Returns XLA sharding from a XlaSharding op connected to an argument value. If
// value is a resource type then XlaSharding op will be connected to a
// ReadVariable op. XlaSharding op may be direct user of inputs but it may also
// be followed by an Identity op and, in the case where bfloat16 type is used,
// Cast op may be added right after the input.
//
// TODO(hongjunchoi): Add logic to parse XlaSharding op inside control flow (If,
// Case, While) ops and Caller return values.
// TODO(hongjunchoi): Consider explicitly checking op patterns to detect sharded
// inputs.
llvm::Optional<llvm::StringRef> GetXlaShardingFromArg(Value value) {
  llvm::SmallPtrSet<Value, 4> visited_values;
  llvm::SmallVector<Value, 4> values_to_visit{value};
  while (!values_to_visit.empty()) {
    llvm::SmallVector<Value, 4> next_values_to_visit;
    for (Value value_to_visit : values_to_visit) {
      if (!visited_values.insert(value_to_visit).second) continue;

      for (auto& use : value_to_visit.getUses()) {
        Operation* owner = use.getOwner();
        if (auto sharding = llvm::dyn_cast<TF::XlaShardingOp>(owner))
          return sharding._XlaSharding();

        if (llvm::isa<TF::IdentityOp, TF::CastOp, TF::ReadVariableOp>(owner)) {
          next_values_to_visit.push_back(use.getOwner()->getResult(0));
          continue;
        }

        if (auto call_op = llvm::dyn_cast<CallOpInterface>(owner)) {
          FuncOp func = llvm::dyn_cast<FuncOp>(call_op.resolveCallable());
          if (!func) continue;
          next_values_to_visit.push_back(
              func.getArgument(use.getOperandNumber()));
        }
      }
    }

    values_to_visit.swap(next_values_to_visit);
  }

  return llvm::None;
}

// Extracts sharding configurations for all inputs by parsing XlaSharding/
// TPUPartitionedInput op connected to the operands/arguments. If argument to
// the `cluster_func` directly feeds into another function call op, then
// recursively walk the function definition to find the connected XlaSharding
// op.
void IdentifyXlaShardingForComputationInputs(
    StringRef logical_core_0_sharding, bool use_spmd,
    tf_device::ClusterFuncOp cluster_func, FuncOp func, Builder* builder) {
  // Look up function definition from module.
  Block& function_block = func.front();

  llvm::SmallVector<llvm::StringRef, 8> sharding_for_args;
  sharding_for_args.reserve(function_block.getNumArguments());

  // Iterate through operands of `cluster_func`.
  // The computation operand can either be:
  //   1) a TPUPartitionedInput Op if the input has a non-resource type;
  //   2) a ReadVariableOp else.
  //
  // Replicate sharding is used if `use_spmd` is set.
  //
  // Iterate through input arguments to the entry block of
  // tf_device.ClusterFunc. For input ops, look for XlaSharding ops.
  // XlaSharding ops can:
  //   1) Directly follow the input argument if input argument has non-resource
  //      types.
  //   2) Follow ReadVariableOp if the input type is of resource type.
  //   3) Follow IdentityOp or CastOp after above cases (1), (2).
  //
  // Sharding configurations are added to the tf_device.ClusterFunc as an
  // attribute and the function as an argument attribute.
  for (auto operand_and_arg :
       llvm::zip(cluster_func.operands(), function_block.getArguments())) {
    Value operand = std::get<0>(operand_and_arg);
    BlockArgument arg = std::get<1>(operand_and_arg);
    const int index = arg.getArgNumber();

    if (auto operand_sharding = GetXlaShardingFromOperand(operand)) {
      sharding_for_args.push_back(operand_sharding.getValue());
      func.setArgAttr(index, kShardingAttr,
                      builder->getStringAttr(operand_sharding.getValue()));
      continue;
    }

    if (use_spmd) {
      // If XLA SPMD is enabled, host variables or non-variable per-replica
      // inputs should take on replicate sharding, unless another sharding is
      // set via a TPUPartitionedInput op.
      sharding_for_args.push_back(kReplicateSharding);
      func.setArgAttr(index, kShardingAttr,
                      builder->getStringAttr(kReplicateSharding));
      continue;
    }

    auto arg_sharding = GetXlaShardingFromArg(arg);
    if (arg_sharding) {
      sharding_for_args.push_back(arg_sharding.getValue());
      func.setArgAttr(index, kShardingAttr,
                      builder->getStringAttr(arg_sharding.getValue()));
      continue;
    }

    // Default to maximal sharding core 0 if no sharding is present.
    sharding_for_args.push_back(logical_core_0_sharding);
    func.setArgAttr(index, kShardingAttr,
                    builder->getStringAttr(logical_core_0_sharding));
  }

  cluster_func->setAttr(tensorflow::kInputShardingAttr,
                        builder->getStrArrayAttr(sharding_for_args));
}

// Returns XLA sharding from TPUPartitionedOutput op connected to a
// `tf_device.cluster_func` result value.
llvm::Optional<llvm::StringRef> GetXlaShardingFromResult(Value value) {
  if (!value.hasOneUse()) return llvm::None;

  Operation* user = *value.getUsers().begin();
  if (auto partitioned_output =
          llvm::dyn_cast<TF::TPUPartitionedOutputOp>(user))
    return partitioned_output._XlaSharding();

  return llvm::None;
}

// Returns XLA sharding from XlaSharding op connected to a result value.
// XlaSharding op may be direct user of inputs but it may also be followed by an
// Identity op and, in the case where bfloat16 type is used, Cast op may be
// added right after the input.
//
// TODO(hongjunchoi): Add logic to parse XlaSharding op inside control flow (If,
// Case, While) ops and Caller argument values.
// TODO(hongjunchoi): Consider explicitly checking op patterns to detect sharded
// inputs.
llvm::Optional<StringRef> GetXlaShardingFromRetval(Value value) {
  llvm::SmallPtrSet<Value, 4> visited_values;
  Value value_to_visit = value;
  while (value_to_visit) {
    if (!visited_values.insert(value_to_visit).second) return llvm::None;

    Operation* def = value_to_visit.getDefiningOp();
    if (auto sharding = llvm::dyn_cast_or_null<TF::XlaShardingOp>(def))
      return sharding._XlaSharding();

    if (llvm::isa_and_nonnull<TF::IdentityOp, TF::CastOp>(def)) {
      value_to_visit = def->getOperand(0);
      continue;
    }

    if (auto call_op = llvm::dyn_cast_or_null<CallOpInterface>(def)) {
      FuncOp func = llvm::dyn_cast<FuncOp>(call_op.resolveCallable());
      if (!func) continue;
      value_to_visit = func.front().getTerminator()->getOperand(
          value_to_visit.cast<OpResult>().getResultNumber());
      continue;
    }

    break;
  }

  return llvm::None;
}

// Extracts sharding configurations for all outputs by parsing XlaSharding/
// TPUPartitionedOutput op connected to the retvals/results.
void IdentifyXlaShardingForComputationOutputs(
    StringRef logical_core_0_sharding, bool use_spmd,
    tf_device::ClusterFuncOp cluster_func, FuncOp func, Builder* builder) {
  Block& function_block = func.front();
  Operation* terminator = function_block.getTerminator();
  llvm::SmallVector<llvm::StringRef, 8> sharding_for_rets;
  sharding_for_rets.reserve(terminator->getNumOperands());

  // Iterate through results of `cluster_func`. For output ops, look for
  // TPUPartitionedOutput ops.
  //
  // Replicate sharding is used if `use_spmd` is set.
  //
  // Iterate through operands of the terminator. If the preceding op is
  // XlaShardingOp, then the provided sharding configuration is added to the
  // tf_device.ClusterFunc as an attribute and the function as a result
  // attribute.
  for (auto result_and_retval :
       llvm::zip(cluster_func.results(), terminator->getOpOperands())) {
    Value result = std::get<0>(result_and_retval);
    OpOperand& retval = std::get<1>(result_and_retval);
    const int index = retval.getOperandNumber();

    if (auto result_sharding = GetXlaShardingFromResult(result)) {
      sharding_for_rets.push_back(result_sharding.getValue());
      func.setResultAttr(index, kShardingAttr,
                         builder->getStringAttr(result_sharding.getValue()));
      continue;
    }

    if (use_spmd) {
      // If XLA SPMD is enabled, outputs all should have replicate sharding,
      // unless another sharding is set via a TPUPartitionedOutput op.
      sharding_for_rets.push_back(kReplicateSharding);
      func.setResultAttr(index, kShardingAttr,
                         builder->getStringAttr(kReplicateSharding));
      continue;
    }

    if (auto retval_sharding = GetXlaShardingFromRetval(retval.get())) {
      sharding_for_rets.push_back(retval_sharding.getValue());
      func.setResultAttr(index, kShardingAttr,
                         builder->getStringAttr(retval_sharding.getValue()));
      continue;
    }

    // Default to maximal sharding core 0 if no sharding is present.
    sharding_for_rets.push_back(logical_core_0_sharding);
    func.setResultAttr(index, kShardingAttr,
                       builder->getStringAttr(logical_core_0_sharding));
  }

  cluster_func->setAttr(tensorflow::kOutputShardingAttr,
                        builder->getStrArrayAttr(sharding_for_rets));
}

// Extracts input/output sharding configuration of `cluster_func` by parsing
// XlaSharding ops inside the `cluster_func`.
void IdentifyXlaShardingForTPUComputation(
    Builder* builder, tf_device::ClusterFuncOp cluster_func) {
  // Look up function definition from module.
  FuncOp func = cluster_func->getParentOfType<ModuleOp>().lookupSymbol<FuncOp>(
      cluster_func.func());

  // By default inputs/outputs have maximal sharding and are assigned to logical
  // core 0 if no sharding is defined.
  const std::string logical_core_0_sharding =
      xla::sharding_builder::AssignDevice(0).SerializeAsString();

  bool use_spmd = false;
  if (auto use_spmd_attr =
          cluster_func.getAttrOfType<BoolAttr>("use_spmd_for_xla_partitioning"))
    use_spmd = use_spmd_attr.getValue();

  IdentifyXlaShardingForComputationInputs(logical_core_0_sharding, use_spmd,
                                          cluster_func, func, builder);

  IdentifyXlaShardingForComputationOutputs(logical_core_0_sharding, use_spmd,
                                           cluster_func, func, builder);
}

void TPUShardingIdentificationPass::runOnOperation() {
  Builder builder(getOperation().getContext());

  getOperation().walk([&](tf_device::ClusterFuncOp cluster_func) {
    IdentifyXlaShardingForTPUComputation(&builder, cluster_func);
  });
}

}  // anonymous namespace

std::unique_ptr<OperationPass<ModuleOp>> CreateTPUShardingIdentificationPass() {
  return std::make_unique<TPUShardingIdentificationPass>();
}

static PassRegistration<TPUShardingIdentificationPass> pass(
    "tf-tpu-sharding-identification",
    "Identifies and handles inputs/outputs of TPU computation that is "
    "sharded across logical cores.");

}  // namespace TFTPU
}  // namespace mlir
<commit_msg>Use mlir::OpState::operator->() to get to methods of mlir::Operation.<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 <memory>
#include <string>

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "mlir/IR/Attributes.h"  // from @llvm-project
#include "mlir/IR/Block.h"  // from @llvm-project
#include "mlir/IR/Builders.h"  // from @llvm-project
#include "mlir/IR/BuiltinAttributes.h"  // from @llvm-project
#include "mlir/IR/BuiltinOps.h"  // from @llvm-project
#include "mlir/IR/Operation.h"  // from @llvm-project
#include "mlir/IR/Value.h"  // from @llvm-project
#include "mlir/Interfaces/CallInterfaces.h"  // from @llvm-project
#include "mlir/Pass/Pass.h"  // from @llvm-project
#include "mlir/Pass/PassRegistry.h"  // from @llvm-project
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_device.h"
#include "tensorflow/compiler/mlir/tensorflow/ir/tf_ops.h"
#include "tensorflow/compiler/mlir/tensorflow/utils/xla_sharding_util.h"
#include "tensorflow/compiler/xla/client/sharding_builder.h"

namespace mlir {
namespace TFTPU {
namespace {

constexpr char kShardingAttr[] = "mhlo.sharding";
constexpr char kReplicateSharding[] = "";

struct TPUShardingIdentificationPass
    : public PassWrapper<TPUShardingIdentificationPass,
                         OperationPass<ModuleOp>> {
  void runOnOperation() override;
};

// Returns XLA sharding from TPUPartitionedInput op connected to a
// `tf_device.cluster_func` operand value. If value is a resource type then
// TPUPartitionedInput op will be connected to a ReadVariable op that feeds into
// a `tf_device.cluster_func`.
llvm::Optional<llvm::StringRef> GetXlaShardingFromOperand(Value value) {
  Value value_to_visit = value;
  if (auto read_var = llvm::dyn_cast_or_null<TF::ReadVariableOp>(
          value_to_visit.getDefiningOp()))
    value_to_visit = read_var.resource();

  if (auto partitioned_input =
          llvm::dyn_cast_or_null<TF::TPUPartitionedInputOp>(
              value_to_visit.getDefiningOp()))
    return partitioned_input._XlaSharding();

  return llvm::None;
}

// Returns XLA sharding from a XlaSharding op connected to an argument value. If
// value is a resource type then XlaSharding op will be connected to a
// ReadVariable op. XlaSharding op may be direct user of inputs but it may also
// be followed by an Identity op and, in the case where bfloat16 type is used,
// Cast op may be added right after the input.
//
// TODO(hongjunchoi): Add logic to parse XlaSharding op inside control flow (If,
// Case, While) ops and Caller return values.
// TODO(hongjunchoi): Consider explicitly checking op patterns to detect sharded
// inputs.
llvm::Optional<llvm::StringRef> GetXlaShardingFromArg(Value value) {
  llvm::SmallPtrSet<Value, 4> visited_values;
  llvm::SmallVector<Value, 4> values_to_visit{value};
  while (!values_to_visit.empty()) {
    llvm::SmallVector<Value, 4> next_values_to_visit;
    for (Value value_to_visit : values_to_visit) {
      if (!visited_values.insert(value_to_visit).second) continue;

      for (auto& use : value_to_visit.getUses()) {
        Operation* owner = use.getOwner();
        if (auto sharding = llvm::dyn_cast<TF::XlaShardingOp>(owner))
          return sharding._XlaSharding();

        if (llvm::isa<TF::IdentityOp, TF::CastOp, TF::ReadVariableOp>(owner)) {
          next_values_to_visit.push_back(use.getOwner()->getResult(0));
          continue;
        }

        if (auto call_op = llvm::dyn_cast<CallOpInterface>(owner)) {
          FuncOp func = llvm::dyn_cast<FuncOp>(call_op.resolveCallable());
          if (!func) continue;
          next_values_to_visit.push_back(
              func.getArgument(use.getOperandNumber()));
        }
      }
    }

    values_to_visit.swap(next_values_to_visit);
  }

  return llvm::None;
}

// Extracts sharding configurations for all inputs by parsing XlaSharding/
// TPUPartitionedInput op connected to the operands/arguments. If argument to
// the `cluster_func` directly feeds into another function call op, then
// recursively walk the function definition to find the connected XlaSharding
// op.
void IdentifyXlaShardingForComputationInputs(
    StringRef logical_core_0_sharding, bool use_spmd,
    tf_device::ClusterFuncOp cluster_func, FuncOp func, Builder* builder) {
  // Look up function definition from module.
  Block& function_block = func.front();

  llvm::SmallVector<llvm::StringRef, 8> sharding_for_args;
  sharding_for_args.reserve(function_block.getNumArguments());

  // Iterate through operands of `cluster_func`.
  // The computation operand can either be:
  //   1) a TPUPartitionedInput Op if the input has a non-resource type;
  //   2) a ReadVariableOp else.
  //
  // Replicate sharding is used if `use_spmd` is set.
  //
  // Iterate through input arguments to the entry block of
  // tf_device.ClusterFunc. For input ops, look for XlaSharding ops.
  // XlaSharding ops can:
  //   1) Directly follow the input argument if input argument has non-resource
  //      types.
  //   2) Follow ReadVariableOp if the input type is of resource type.
  //   3) Follow IdentityOp or CastOp after above cases (1), (2).
  //
  // Sharding configurations are added to the tf_device.ClusterFunc as an
  // attribute and the function as an argument attribute.
  for (auto operand_and_arg :
       llvm::zip(cluster_func.operands(), function_block.getArguments())) {
    Value operand = std::get<0>(operand_and_arg);
    BlockArgument arg = std::get<1>(operand_and_arg);
    const int index = arg.getArgNumber();

    if (auto operand_sharding = GetXlaShardingFromOperand(operand)) {
      sharding_for_args.push_back(operand_sharding.getValue());
      func.setArgAttr(index, kShardingAttr,
                      builder->getStringAttr(operand_sharding.getValue()));
      continue;
    }

    if (use_spmd) {
      // If XLA SPMD is enabled, host variables or non-variable per-replica
      // inputs should take on replicate sharding, unless another sharding is
      // set via a TPUPartitionedInput op.
      sharding_for_args.push_back(kReplicateSharding);
      func.setArgAttr(index, kShardingAttr,
                      builder->getStringAttr(kReplicateSharding));
      continue;
    }

    auto arg_sharding = GetXlaShardingFromArg(arg);
    if (arg_sharding) {
      sharding_for_args.push_back(arg_sharding.getValue());
      func.setArgAttr(index, kShardingAttr,
                      builder->getStringAttr(arg_sharding.getValue()));
      continue;
    }

    // Default to maximal sharding core 0 if no sharding is present.
    sharding_for_args.push_back(logical_core_0_sharding);
    func.setArgAttr(index, kShardingAttr,
                    builder->getStringAttr(logical_core_0_sharding));
  }

  cluster_func->setAttr(tensorflow::kInputShardingAttr,
                        builder->getStrArrayAttr(sharding_for_args));
}

// Returns XLA sharding from TPUPartitionedOutput op connected to a
// `tf_device.cluster_func` result value.
llvm::Optional<llvm::StringRef> GetXlaShardingFromResult(Value value) {
  if (!value.hasOneUse()) return llvm::None;

  Operation* user = *value.getUsers().begin();
  if (auto partitioned_output =
          llvm::dyn_cast<TF::TPUPartitionedOutputOp>(user))
    return partitioned_output._XlaSharding();

  return llvm::None;
}

// Returns XLA sharding from XlaSharding op connected to a result value.
// XlaSharding op may be direct user of inputs but it may also be followed by an
// Identity op and, in the case where bfloat16 type is used, Cast op may be
// added right after the input.
//
// TODO(hongjunchoi): Add logic to parse XlaSharding op inside control flow (If,
// Case, While) ops and Caller argument values.
// TODO(hongjunchoi): Consider explicitly checking op patterns to detect sharded
// inputs.
llvm::Optional<StringRef> GetXlaShardingFromRetval(Value value) {
  llvm::SmallPtrSet<Value, 4> visited_values;
  Value value_to_visit = value;
  while (value_to_visit) {
    if (!visited_values.insert(value_to_visit).second) return llvm::None;

    Operation* def = value_to_visit.getDefiningOp();
    if (auto sharding = llvm::dyn_cast_or_null<TF::XlaShardingOp>(def))
      return sharding._XlaSharding();

    if (llvm::isa_and_nonnull<TF::IdentityOp, TF::CastOp>(def)) {
      value_to_visit = def->getOperand(0);
      continue;
    }

    if (auto call_op = llvm::dyn_cast_or_null<CallOpInterface>(def)) {
      FuncOp func = llvm::dyn_cast<FuncOp>(call_op.resolveCallable());
      if (!func) continue;
      value_to_visit = func.front().getTerminator()->getOperand(
          value_to_visit.cast<OpResult>().getResultNumber());
      continue;
    }

    break;
  }

  return llvm::None;
}

// Extracts sharding configurations for all outputs by parsing XlaSharding/
// TPUPartitionedOutput op connected to the retvals/results.
void IdentifyXlaShardingForComputationOutputs(
    StringRef logical_core_0_sharding, bool use_spmd,
    tf_device::ClusterFuncOp cluster_func, FuncOp func, Builder* builder) {
  Block& function_block = func.front();
  Operation* terminator = function_block.getTerminator();
  llvm::SmallVector<llvm::StringRef, 8> sharding_for_rets;
  sharding_for_rets.reserve(terminator->getNumOperands());

  // Iterate through results of `cluster_func`. For output ops, look for
  // TPUPartitionedOutput ops.
  //
  // Replicate sharding is used if `use_spmd` is set.
  //
  // Iterate through operands of the terminator. If the preceding op is
  // XlaShardingOp, then the provided sharding configuration is added to the
  // tf_device.ClusterFunc as an attribute and the function as a result
  // attribute.
  for (auto result_and_retval :
       llvm::zip(cluster_func.results(), terminator->getOpOperands())) {
    Value result = std::get<0>(result_and_retval);
    OpOperand& retval = std::get<1>(result_and_retval);
    const int index = retval.getOperandNumber();

    if (auto result_sharding = GetXlaShardingFromResult(result)) {
      sharding_for_rets.push_back(result_sharding.getValue());
      func.setResultAttr(index, kShardingAttr,
                         builder->getStringAttr(result_sharding.getValue()));
      continue;
    }

    if (use_spmd) {
      // If XLA SPMD is enabled, outputs all should have replicate sharding,
      // unless another sharding is set via a TPUPartitionedOutput op.
      sharding_for_rets.push_back(kReplicateSharding);
      func.setResultAttr(index, kShardingAttr,
                         builder->getStringAttr(kReplicateSharding));
      continue;
    }

    if (auto retval_sharding = GetXlaShardingFromRetval(retval.get())) {
      sharding_for_rets.push_back(retval_sharding.getValue());
      func.setResultAttr(index, kShardingAttr,
                         builder->getStringAttr(retval_sharding.getValue()));
      continue;
    }

    // Default to maximal sharding core 0 if no sharding is present.
    sharding_for_rets.push_back(logical_core_0_sharding);
    func.setResultAttr(index, kShardingAttr,
                       builder->getStringAttr(logical_core_0_sharding));
  }

  cluster_func->setAttr(tensorflow::kOutputShardingAttr,
                        builder->getStrArrayAttr(sharding_for_rets));
}

// Extracts input/output sharding configuration of `cluster_func` by parsing
// XlaSharding ops inside the `cluster_func`.
void IdentifyXlaShardingForTPUComputation(
    Builder* builder, tf_device::ClusterFuncOp cluster_func) {
  // Look up function definition from module.
  FuncOp func = cluster_func->getParentOfType<ModuleOp>().lookupSymbol<FuncOp>(
      cluster_func.func());

  // By default inputs/outputs have maximal sharding and are assigned to logical
  // core 0 if no sharding is defined.
  const std::string logical_core_0_sharding =
      xla::sharding_builder::AssignDevice(0).SerializeAsString();

  bool use_spmd = false;
  if (auto use_spmd_attr = cluster_func->getAttrOfType<BoolAttr>(
          "use_spmd_for_xla_partitioning"))
    use_spmd = use_spmd_attr.getValue();

  IdentifyXlaShardingForComputationInputs(logical_core_0_sharding, use_spmd,
                                          cluster_func, func, builder);

  IdentifyXlaShardingForComputationOutputs(logical_core_0_sharding, use_spmd,
                                           cluster_func, func, builder);
}

void TPUShardingIdentificationPass::runOnOperation() {
  Builder builder(getOperation().getContext());

  getOperation().walk([&](tf_device::ClusterFuncOp cluster_func) {
    IdentifyXlaShardingForTPUComputation(&builder, cluster_func);
  });
}

}  // anonymous namespace

std::unique_ptr<OperationPass<ModuleOp>> CreateTPUShardingIdentificationPass() {
  return std::make_unique<TPUShardingIdentificationPass>();
}

static PassRegistration<TPUShardingIdentificationPass> pass(
    "tf-tpu-sharding-identification",
    "Identifies and handles inputs/outputs of TPU computation that is "
    "sharded across logical cores.");

}  // namespace TFTPU
}  // namespace mlir
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads

// <thread>

// class thread

// template <class F, class ...Args> thread(F&& f, Args&&... args);

// UNSUPPORTED: sanitizer-new-delete

#include <thread>
#include <new>
#include <atomic>
#include <cstdlib>
#include <cassert>

#include "test_macros.h"

std::atomic<unsigned> throw_one(0xFFFF);
std::atomic<unsigned> outstanding_new(0);

void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
{
    if (throw_one == 0)
        TEST_THROW(std::bad_alloc());
    --throw_one;
    ++outstanding_new;
    void* ret = std::malloc(s);
    if (!ret) std::abort(); // placate MSVC's unchecked malloc warning
    return ret;
}

void  operator delete(void* p) TEST_NOEXCEPT
{
    --outstanding_new;
    std::free(p);
}

bool f_run = false;

void f()
{
    f_run = true;
}

class G
{
    int alive_;
public:
    static int n_alive;
    static bool op_run;

    G() : alive_(1) {++n_alive;}
    G(const G& g) : alive_(g.alive_) {++n_alive;}
    ~G() {alive_ = 0; --n_alive;}

    void operator()()
    {
        assert(alive_ == 1);
        assert(n_alive >= 1);
        op_run = true;
    }

    void operator()(int i, double j)
    {
        assert(alive_ == 1);
        assert(n_alive >= 1);
        assert(i == 5);
        assert(j == 5.5);
        op_run = true;
    }
};

int G::n_alive = 0;
bool G::op_run = false;

#if TEST_STD_VER >= 11

class MoveOnly
{
    MoveOnly(const MoveOnly&);
public:
    MoveOnly() {}
    MoveOnly(MoveOnly&&) {}

    void operator()(MoveOnly&&)
    {
    }
};

#endif

// Test throwing std::bad_alloc
//-----------------------------
// Concerns:
//  A Each allocation performed during thread construction should be performed
//    in the parent thread so that std::terminate is not called if
//    std::bad_alloc is thrown by new.
//  B std::thread's constructor should properly handle exceptions and not leak
//    memory.
// Plan:
//  1 Create a thread and count the number of allocations, 'N', it performs.
//  2 For each allocation performed run a test where that allocation throws.
//    2.1 check that the exception can be caught in the parent thread.
//    2.2 Check that the functor has not been called.
//    2.3 Check that no memory allocated by the creation of the thread is leaked.
//  3 Finally check that a thread runs successfully if we throw after 'N+1'
//    allocations.
void test_throwing_new_during_thread_creation() {
#ifndef TEST_HAS_NO_EXCEPTIONS
    throw_one = 0xFFF;
    {
        std::thread t(f);
        t.join();
    }
    const int numAllocs = 0xFFF - throw_one;
    // i <= numAllocs means the last iteration is expected not to throw.
    for (int i=0; i <= numAllocs; ++i) {
        throw_one = i;
        f_run = false;
        unsigned old_outstanding = outstanding_new;
        try {
            std::thread t(f);
            assert(i == numAllocs); // Only final iteration will not throw.
            t.join();
            assert(f_run);
        } catch (std::bad_alloc const&) {
            assert(i < numAllocs);
            assert(!f_run); // (2.2)
        }
        assert(old_outstanding == outstanding_new); // (2.3)
    }
    f_run = false;
    throw_one = 0xFFF;
#endif
}

int main()
{
    test_throwing_new_during_thread_creation();
    {
        std::thread t(f);
        t.join();
        assert(f_run == true);
    }

    {
        assert(G::n_alive == 0);
        assert(!G::op_run);
        std::thread t((G()));
        t.join();
        assert(G::n_alive == 0);
        assert(G::op_run);
    }
    G::op_run = false;
#ifndef TEST_HAS_NO_EXCEPTIONS
    {
        try
        {
            throw_one = 0;
            assert(G::n_alive == 0);
            assert(!G::op_run);
            std::thread t((G()));
            assert(false);
        }
        catch (...)
        {
            throw_one = 0xFFFF;
            assert(G::n_alive == 0);
            assert(!G::op_run);
        }
    }
#endif
#if TEST_STD_VER >= 11
    {
        assert(G::n_alive == 0);
        assert(!G::op_run);
        std::thread t(G(), 5, 5.5);
        t.join();
        assert(G::n_alive == 0);
        assert(G::op_run);
    }
    {
        std::thread t = std::thread(MoveOnly(), MoveOnly());
        t.join();
    }
#endif
}
<commit_msg>Repair thread-unsafe modifications of n_alive in F.pass.cpp<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads

// <thread>

// class thread

// template <class F, class ...Args> thread(F&& f, Args&&... args);

// UNSUPPORTED: sanitizer-new-delete

#include <thread>
#include <new>
#include <atomic>
#include <cstdlib>
#include <cassert>

#include "test_macros.h"

std::atomic<unsigned> throw_one(0xFFFF);
std::atomic<unsigned> outstanding_new(0);

void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
{
    if (throw_one == 0)
        TEST_THROW(std::bad_alloc());
    --throw_one;
    ++outstanding_new;
    void* ret = std::malloc(s);
    if (!ret) std::abort(); // placate MSVC's unchecked malloc warning
    return ret;
}

void  operator delete(void* p) TEST_NOEXCEPT
{
    --outstanding_new;
    std::free(p);
}

bool f_run = false;

void f()
{
    f_run = true;
}

class G
{
    int alive_;
public:
    static int n_alive;
    static bool op_run;

    G() : alive_(1) {++n_alive;}
    G(const G& g) : alive_(g.alive_) {++n_alive;}
    ~G() {alive_ = 0; --n_alive;}

    void operator()()
    {
        assert(alive_ == 1);
        assert(n_alive >= 1);
        op_run = true;
    }

    void operator()(int i, double j)
    {
        assert(alive_ == 1);
        assert(n_alive >= 1);
        assert(i == 5);
        assert(j == 5.5);
        op_run = true;
    }
};

int G::n_alive = 0;
bool G::op_run = false;

#if TEST_STD_VER >= 11

class MoveOnly
{
    MoveOnly(const MoveOnly&);
public:
    MoveOnly() {}
    MoveOnly(MoveOnly&&) {}

    void operator()(MoveOnly&&)
    {
    }
};

#endif

// Test throwing std::bad_alloc
//-----------------------------
// Concerns:
//  A Each allocation performed during thread construction should be performed
//    in the parent thread so that std::terminate is not called if
//    std::bad_alloc is thrown by new.
//  B std::thread's constructor should properly handle exceptions and not leak
//    memory.
// Plan:
//  1 Create a thread and count the number of allocations, 'N', it performs.
//  2 For each allocation performed run a test where that allocation throws.
//    2.1 check that the exception can be caught in the parent thread.
//    2.2 Check that the functor has not been called.
//    2.3 Check that no memory allocated by the creation of the thread is leaked.
//  3 Finally check that a thread runs successfully if we throw after 'N+1'
//    allocations.
void test_throwing_new_during_thread_creation() {
#ifndef TEST_HAS_NO_EXCEPTIONS
    throw_one = 0xFFF;
    {
        std::thread t(f);
        t.join();
    }
    const int numAllocs = 0xFFF - throw_one;
    // i <= numAllocs means the last iteration is expected not to throw.
    for (int i=0; i <= numAllocs; ++i) {
        throw_one = i;
        f_run = false;
        unsigned old_outstanding = outstanding_new;
        try {
            std::thread t(f);
            assert(i == numAllocs); // Only final iteration will not throw.
            t.join();
            assert(f_run);
        } catch (std::bad_alloc const&) {
            assert(i < numAllocs);
            assert(!f_run); // (2.2)
        }
        assert(old_outstanding == outstanding_new); // (2.3)
    }
    f_run = false;
    throw_one = 0xFFF;
#endif
}

int main()
{
    test_throwing_new_during_thread_creation();
    {
        std::thread t(f);
        t.join();
        assert(f_run == true);
    }

    {
        assert(G::n_alive == 0);
        assert(!G::op_run);
        {
            G g;
            std::thread t(g);
            t.join();
        }
        assert(G::n_alive == 0);
        assert(G::op_run);
    }
    G::op_run = false;
#ifndef TEST_HAS_NO_EXCEPTIONS
    {
        try
        {
            throw_one = 0;
            assert(G::n_alive == 0);
            assert(!G::op_run);
            std::thread t((G()));
            assert(false);
        }
        catch (...)
        {
            throw_one = 0xFFFF;
            assert(G::n_alive == 0);
            assert(!G::op_run);
        }
    }
#endif
#if TEST_STD_VER >= 11
    {
        assert(G::n_alive == 0);
        assert(!G::op_run);
        {
            G g;
            std::thread t(g, 5, 5.5);
            t.join();
        }
        assert(G::n_alive == 0);
        assert(G::op_run);
    }
    {
        std::thread t = std::thread(MoveOnly(), MoveOnly());
        t.join();
    }
#endif
}
<|endoftext|>


<commit_before>#include "remoteatcommandresponse.h"
#include "xbeepacket.h"

#include <QDebug>

namespace QtXBee {

RemoteATCommandResponse::RemoteATCommandResponse(QObject *parent) :
    ATCommandResponse(parent)
{
    setFrameType(XBeePacket::RemoteATCommandResponseId);
}

RemoteATCommandResponse::RemoteATCommandResponse(const QByteArray &data, QObject *parent) :
    ATCommandResponse(parent)
{
    setFrameType(XBeePacket::RemoteATCommandResponseId);
    setPacket(data);
}

void RemoteATCommandResponse::clear() {
    ATCommandResponse::clear();
    m_sourceAddress64   = 0;
    m_sourceAddress16   = 0;
}

bool RemoteATCommandResponse::parseApiSpecificData(const QByteArray &data)
Q_DECL_OVERRIDE
{
    escapePacket();
    if(data.size() < 13) {
        qDebug() << Q_FUNC_INFO << "bad data !";
        return false;
    }
    setFrameId(data.at(0));
    setSourceAddress64(data.mid(1, 8).toHex().toULong(0,16));
    setSourceAddress16(data.mid(9, 2).toHex().toUInt(0,16));
    setATCommand((ATCommand::ATCommandType) data.mid(11, 2).toHex().toUInt(0,16));
    setCommandStatus((CommandStatus) data.at(13));
    if(data.size() > 14) {
        for(int i=14; i < data.size(); i++) {
            m_data.append(data.at(i));
        }
    }

    return true;
}

QString RemoteATCommandResponse::toString()
Q_DECL_OVERRIDE
{
    QString str;
    str.append(QString("Raw packet                   : 0x%1\n").arg(QString(packet().toHex())));
    str.append(QString("Start delimiter              : 0x%1\n").arg(QString::number(startDelimiter(), 16)));
    str.append(QString("Frame type                   : %1 (0x%2)\n").arg(frameTypeToString(frameType())).arg(QString::number(frameType(), 16)));
    str.append(QString("Length                       : %1 bytes\n").arg(length()));
    str.append(QString("Frame id                     : %1\n").arg(frameId()));
    if(!m_data.isEmpty())
    str.append(QString("Data                         : 0x%1\n").arg(QString(m_data.toHex())));
    else
    str.append(QString("Data                         : No data\n"));
    str.append(QString("Source Address 64bits        : 0x%1\n").arg(m_sourceAddress64, 0, 16));
    str.append(QString("Source Address 16bits        : 0x%1\n").arg(m_sourceAddress16, 0, 16));
    str.append(QString("AT Command                   : %1 (0x%2)\n").arg(ATCommand::atCommandToString(m_atCommand)).arg(m_atCommand, 0,16));
    str.append(QString("Command Status               : %1 (0x%2)\n").arg(statusToString(m_status)).arg(m_status, 0, 16));
    str.append(QString("Command Data                 : 0x%1 (%2)\n").arg(QString(m_data.toHex())).arg(QString(m_data)));
    str.append(QString("Checksum                     : %1\n").arg(checksum()));

    return  str;
}

// Setters
void RemoteATCommandResponse::setSourceAddress64(const quint64 addr) {
    m_sourceAddress64 = addr;
}

void RemoteATCommandResponse::setSourceAddress16(const quint32 addr) {
    m_sourceAddress16 = addr;
}

// Getters
quint64 RemoteATCommandResponse::sourceAddress64() const {
    return m_sourceAddress64;
}

quint16 RemoteATCommandResponse::sourceAddress16() const {
    return m_sourceAddress16;
}

} // END namepsace
<commit_msg>Fixed RemoteATCommandResponse::toString()<commit_after>#include "remoteatcommandresponse.h"
#include "xbeepacket.h"

#include <QDebug>

namespace QtXBee {

RemoteATCommandResponse::RemoteATCommandResponse(QObject *parent) :
    ATCommandResponse(parent)
{
    setFrameType(XBeePacket::RemoteATCommandResponseId);
}

RemoteATCommandResponse::RemoteATCommandResponse(const QByteArray &data, QObject *parent) :
    ATCommandResponse(parent)
{
    setFrameType(XBeePacket::RemoteATCommandResponseId);
    setPacket(data);
}

void RemoteATCommandResponse::clear() {
    ATCommandResponse::clear();
    m_sourceAddress64   = 0;
    m_sourceAddress16   = 0;
}

bool RemoteATCommandResponse::parseApiSpecificData(const QByteArray &data)
Q_DECL_OVERRIDE
{
    if(data.size() < 13) {
        qDebug() << Q_FUNC_INFO << "bad data !";
        return false;
    }
    setFrameId(data.at(0));
    setSourceAddress64(data.mid(1, 8).toHex().toULong(0,16));
    setSourceAddress16(data.mid(9, 2).toHex().toUInt(0,16));
    setATCommand((ATCommand::ATCommandType) data.mid(11, 2).toHex().toUInt(0,16));
    setCommandStatus((CommandStatus) data.at(13));
    if(data.size() > 14) {
        for(int i=14; i < data.size(); i++) {
            m_data.append(data.at(i));
        }
    }

    return true;
}

QString RemoteATCommandResponse::toString()
Q_DECL_OVERRIDE
{
    QString str;
    str.append(QString("Raw packet                   : 0x%1\n").arg(QString(packet().toHex())));
    str.append(QString("Start delimiter              : 0x%1\n").arg(QString::number(startDelimiter(), 16)));
    str.append(QString("Frame type                   : %1 (0x%2)\n").arg(frameTypeToString(frameType())).arg(QString::number(frameType(), 16)));
    str.append(QString("Length                       : %1 bytes\n").arg(length()));
    str.append(QString("Frame id                     : %1\n").arg(frameId()));
    if(!m_data.isEmpty())
    str.append(QString("Data                         : 0x%1 (%2)\n").arg(QString(m_data.toHex())).arg(QString(m_data)));
    else
    str.append(QString("Data                         : No data\n"));
    str.append(QString("Source Address 64bits        : 0x%1\n").arg(m_sourceAddress64, 0, 16));
    str.append(QString("Source Address 16bits        : 0x%1\n").arg(m_sourceAddress16, 0, 16));
    str.append(QString("AT Command                   : %1 (0x%2)\n").arg(ATCommand::atCommandToString(m_atCommand)).arg(m_atCommand, 0,16));
    str.append(QString("Command Status               : %1 (0x%2)\n").arg(statusToString(m_status)).arg(m_status, 0, 16));
    str.append(QString("Checksum                     : %1\n").arg(checksum()));

    return  str;
}

// Setters
void RemoteATCommandResponse::setSourceAddress64(const quint64 addr) {
    m_sourceAddress64 = addr;
}

void RemoteATCommandResponse::setSourceAddress16(const quint32 addr) {
    m_sourceAddress16 = addr;
}

// Getters
quint64 RemoteATCommandResponse::sourceAddress64() const {
    return m_sourceAddress64;
}

quint16 RemoteATCommandResponse::sourceAddress16() const {
    return m_sourceAddress16;
}

} // END namepsace
<|endoftext|>