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

#include "common/visionbuf.h"
#include "common/visionipc.h"
#include "common/swaglog.h"

#include "models/driving.h"

volatile sig_atomic_t do_exit = 0;

static void set_do_exit(int sig) {
  do_exit = 1;
}

// globals
bool run_model;
mat3 cur_transform;
pthread_mutex_t transform_lock;

void* live_thread(void *arg) {
  int err;
  set_thread_name("live");

  Context * c = Context::create();
  SubSocket * live_calibration_sock = SubSocket::create(c, "liveCalibration");
  assert(live_calibration_sock != NULL);

  Poller * poller = Poller::create({live_calibration_sock});

  /*
     import numpy as np
     from common.transformations.model import medmodel_frame_from_road_frame
     medmodel_frame_from_ground = medmodel_frame_from_road_frame[:, (0, 1, 3)]
     ground_from_medmodel_frame = np.linalg.inv(medmodel_frame_from_ground)
  */
  Eigen::Matrix<float, 3, 3> ground_from_medmodel_frame;
  ground_from_medmodel_frame <<
    0.00000000e+00, 0.00000000e+00, 1.00000000e+00,
    -1.09890110e-03, 0.00000000e+00, 2.81318681e-01,
    -1.84808520e-20, 9.00738606e-04,-4.28751576e-02;

  Eigen::Matrix<float, 3, 3> eon_intrinsics;
  eon_intrinsics <<
    910.0, 0.0, 582.0,
    0.0, 910.0, 437.0,
    0.0,   0.0,   1.0;

  while (!do_exit) {
    for (auto sock : poller->poll(10)){
      Message * msg = sock->receive();

      auto amsg = kj::heapArray<capnp::word>((msg->getSize() / sizeof(capnp::word)) + 1);
      memcpy(amsg.begin(), msg->getData(), msg->getSize());

      capnp::FlatArrayMessageReader cmsg(amsg);
      cereal::Event::Reader event = cmsg.getRoot<cereal::Event>();

      if (event.isLiveCalibration()) {
        pthread_mutex_lock(&transform_lock);

        auto extrinsic_matrix = event.getLiveCalibration().getExtrinsicMatrix();
        Eigen::Matrix<float, 3, 4> extrinsic_matrix_eigen;
        for (int i = 0; i < 4*3; i++){
          extrinsic_matrix_eigen(i / 4, i % 4) = extrinsic_matrix[i];
        }

        auto camera_frame_from_road_frame = eon_intrinsics * extrinsic_matrix_eigen;
        Eigen::Matrix<float, 3, 3> camera_frame_from_ground;
        camera_frame_from_ground.col(0) = camera_frame_from_road_frame.col(0);
        camera_frame_from_ground.col(1) = camera_frame_from_road_frame.col(1);
        camera_frame_from_ground.col(2) = camera_frame_from_road_frame.col(3);

        auto warp_matrix = camera_frame_from_ground * ground_from_medmodel_frame;

        for (int i=0; i<3*3; i++) {
          cur_transform.v[i] = warp_matrix(i / 3, i % 3);
        }

        run_model = true;
        pthread_mutex_unlock(&transform_lock);
      }

      delete msg;
    }

  }

  delete live_calibration_sock;
  delete poller;
  delete c;

  return NULL;
}

int main(int argc, char **argv) {
  int err;
  set_realtime_priority(1);

  // start calibration thread
  pthread_t live_thread_handle;
  err = pthread_create(&live_thread_handle, NULL, live_thread, NULL);
  assert(err == 0);

  // messaging
  Context *msg_context = Context::create();
  PubSocket *model_sock = PubSocket::create(msg_context, "model");
  PubSocket *posenet_sock = PubSocket::create(msg_context, "cameraOdometry");
  SubSocket *pathplan_sock = SubSocket::create(msg_context, "pathPlan", "127.0.0.1", true);

  assert(model_sock != NULL);
  assert(posenet_sock != NULL);
  assert(pathplan_sock != NULL);

  // cl init
  cl_device_id device_id;
  cl_context context;
  cl_command_queue q;
  {
    // TODO: refactor this
    cl_platform_id platform_id[2];
    cl_uint num_devices;
    cl_uint num_platforms;

    err = clGetPlatformIDs(sizeof(platform_id)/sizeof(cl_platform_id), platform_id, &num_platforms);
    assert(err == 0);

    #ifdef QCOM
      int clPlatform = 0;
    #else
      // don't use nvidia on pc, it's broken
      // TODO: write this nicely
      int clPlatform = num_platforms-1;
    #endif

    char cBuffer[1024];
    clGetPlatformInfo(platform_id[clPlatform], CL_PLATFORM_NAME, sizeof(cBuffer), &cBuffer, NULL);
    LOGD("got %d opencl platform(s), using %s", num_platforms, cBuffer);

    err = clGetDeviceIDs(platform_id[clPlatform], CL_DEVICE_TYPE_DEFAULT, 1,
                         &device_id, &num_devices);
    assert(err == 0);

    context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &err);
    assert(err == 0);

    q = clCreateCommandQueue(context, device_id, 0, &err);
    assert(err == 0);
  }

  // init the models
  ModelState model;
  model_init(&model, device_id, context, true);
  LOGW("models loaded, modeld starting");

  // debayering does a 2x downscale
  mat3 yuv_transform = transform_scale_buffer((mat3){{
    1.0, 0.0, 0.0,
    0.0, 1.0, 0.0,
    0.0, 0.0, 1.0,
  }}, 0.5);

  // loop
  VisionStream stream;
  while (!do_exit) {
    VisionStreamBufs buf_info;
    err = visionstream_init(&stream, VISION_STREAM_YUV, true, &buf_info);
    if (err) {
      printf("visionstream connect fail\n");
      usleep(100000);
      continue;
    }
    LOGW("connected with buffer size: %d", buf_info.buf_len);

    // one frame in memory
    cl_mem yuv_cl;
    VisionBuf yuv_ion = visionbuf_allocate_cl(buf_info.buf_len, device_id, context, &yuv_cl);

    double last = 0;
    int desire = -1;
    while (!do_exit) {
      VIPCBuf *buf;
      VIPCBufExtra extra;
      buf = visionstream_get(&stream, &extra);
      if (buf == NULL) {
        printf("visionstream get failed\n");
        visionstream_destroy(&stream);
        break;
      }

      pthread_mutex_lock(&transform_lock);
      mat3 transform = cur_transform;
      const bool run_model_this_iter = run_model;
      pthread_mutex_unlock(&transform_lock);

      Message *msg = pathplan_sock->receive(true);
      if (msg != NULL) {
        // TODO: copy and pasted from camerad/main.cc
        auto amsg = kj::heapArray<capnp::word>((msg->getSize() / sizeof(capnp::word)) + 1);
        memcpy(amsg.begin(), msg->getData(), msg->getSize());

        capnp::FlatArrayMessageReader cmsg(amsg);
        cereal::Event::Reader event = cmsg.getRoot<cereal::Event>();

        // TODO: path planner timeout?
        desire = ((int)event.getPathPlan().getDesire()) - 1;
        delete msg;
      }

      double mt1 = 0, mt2 = 0;
      if (run_model_this_iter) {
        float vec_desire[DESIRE_LEN] = {0};
        if (desire >= 0 && desire < DESIRE_LEN) {
          vec_desire[desire] = 1.0;
        }

        mat3 model_transform = matmul3(yuv_transform, transform);

        mt1 = millis_since_boot();

        // TODO: don't make copies!
        memcpy(yuv_ion.addr, buf->addr, buf_info.buf_len);

        ModelDataRaw model_buf =
            model_eval_frame(&model, q, yuv_cl, buf_info.width, buf_info.height,
                             model_transform, NULL, vec_desire);
        mt2 = millis_since_boot();

        model_publish(model_sock, extra.frame_id, model_buf, extra.timestamp_eof);
        posenet_publish(posenet_sock, extra.frame_id, model_buf, extra.timestamp_eof);

        LOGD("model process: %.2fms, from last %.2fms", mt2-mt1, mt1-last);
        last = mt1;
      }

    }
    visionbuf_free(&yuv_ion);
  }

  visionstream_destroy(&stream);

  delete model_sock;
  delete posenet_sock;
  delete pathplan_sock;
  delete msg_context;

  model_free(&model);

  LOG("joining live_thread");
  err = pthread_join(live_thread_handle, NULL);
  assert(err == 0);

  return 0;
}
<commit_msg>modeld, add cloudlogs<commit_after>#include <stdio.h>
#include <stdlib.h>

#include "common/visionbuf.h"
#include "common/visionipc.h"
#include "common/swaglog.h"

#include "models/driving.h"

volatile sig_atomic_t do_exit = 0;

static void set_do_exit(int sig) {
  do_exit = 1;
}

// globals
bool run_model;
mat3 cur_transform;
pthread_mutex_t transform_lock;

void* live_thread(void *arg) {
  int err;
  set_thread_name("live");

  Context * c = Context::create();
  SubSocket * live_calibration_sock = SubSocket::create(c, "liveCalibration");
  assert(live_calibration_sock != NULL);

  Poller * poller = Poller::create({live_calibration_sock});

  /*
     import numpy as np
     from common.transformations.model import medmodel_frame_from_road_frame
     medmodel_frame_from_ground = medmodel_frame_from_road_frame[:, (0, 1, 3)]
     ground_from_medmodel_frame = np.linalg.inv(medmodel_frame_from_ground)
  */
  Eigen::Matrix<float, 3, 3> ground_from_medmodel_frame;
  ground_from_medmodel_frame <<
    0.00000000e+00, 0.00000000e+00, 1.00000000e+00,
    -1.09890110e-03, 0.00000000e+00, 2.81318681e-01,
    -1.84808520e-20, 9.00738606e-04,-4.28751576e-02;

  Eigen::Matrix<float, 3, 3> eon_intrinsics;
  eon_intrinsics <<
    910.0, 0.0, 582.0,
    0.0, 910.0, 437.0,
    0.0,   0.0,   1.0;

  while (!do_exit) {
    for (auto sock : poller->poll(10)){
      Message * msg = sock->receive();

      auto amsg = kj::heapArray<capnp::word>((msg->getSize() / sizeof(capnp::word)) + 1);
      memcpy(amsg.begin(), msg->getData(), msg->getSize());

      capnp::FlatArrayMessageReader cmsg(amsg);
      cereal::Event::Reader event = cmsg.getRoot<cereal::Event>();

      if (event.isLiveCalibration()) {
        pthread_mutex_lock(&transform_lock);

        auto extrinsic_matrix = event.getLiveCalibration().getExtrinsicMatrix();
        Eigen::Matrix<float, 3, 4> extrinsic_matrix_eigen;
        for (int i = 0; i < 4*3; i++){
          extrinsic_matrix_eigen(i / 4, i % 4) = extrinsic_matrix[i];
        }

        auto camera_frame_from_road_frame = eon_intrinsics * extrinsic_matrix_eigen;
        Eigen::Matrix<float, 3, 3> camera_frame_from_ground;
        camera_frame_from_ground.col(0) = camera_frame_from_road_frame.col(0);
        camera_frame_from_ground.col(1) = camera_frame_from_road_frame.col(1);
        camera_frame_from_ground.col(2) = camera_frame_from_road_frame.col(3);

        auto warp_matrix = camera_frame_from_ground * ground_from_medmodel_frame;

        for (int i=0; i<3*3; i++) {
          cur_transform.v[i] = warp_matrix(i / 3, i % 3);
        }

        run_model = true;
        pthread_mutex_unlock(&transform_lock);
      }

      delete msg;
    }

  }

  delete live_calibration_sock;
  delete poller;
  delete c;

  return NULL;
}

int main(int argc, char **argv) {
  int err;
  set_realtime_priority(1);

  // start calibration thread
  pthread_t live_thread_handle;
  err = pthread_create(&live_thread_handle, NULL, live_thread, NULL);
  assert(err == 0);

  // messaging
  Context *msg_context = Context::create();
  PubSocket *model_sock = PubSocket::create(msg_context, "model");
  PubSocket *posenet_sock = PubSocket::create(msg_context, "cameraOdometry");
  SubSocket *pathplan_sock = SubSocket::create(msg_context, "pathPlan", "127.0.0.1", true);

  assert(model_sock != NULL);
  assert(posenet_sock != NULL);
  assert(pathplan_sock != NULL);

  // cl init
  cl_device_id device_id;
  cl_context context;
  cl_command_queue q;
  {
    // TODO: refactor this
    cl_platform_id platform_id[2];
    cl_uint num_devices;
    cl_uint num_platforms;

    err = clGetPlatformIDs(sizeof(platform_id)/sizeof(cl_platform_id), platform_id, &num_platforms);
    assert(err == 0);

    #ifdef QCOM
      int clPlatform = 0;
    #else
      // don't use nvidia on pc, it's broken
      // TODO: write this nicely
      int clPlatform = num_platforms-1;
    #endif

    char cBuffer[1024];
    clGetPlatformInfo(platform_id[clPlatform], CL_PLATFORM_NAME, sizeof(cBuffer), &cBuffer, NULL);
    LOGD("got %d opencl platform(s), using %s", num_platforms, cBuffer);

    err = clGetDeviceIDs(platform_id[clPlatform], CL_DEVICE_TYPE_DEFAULT, 1,
                         &device_id, &num_devices);
    assert(err == 0);

    context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &err);
    assert(err == 0);

    q = clCreateCommandQueue(context, device_id, 0, &err);
    assert(err == 0);
  }

  // init the models
  ModelState model;
  model_init(&model, device_id, context, true);
  LOGW("models loaded, modeld starting");

  // debayering does a 2x downscale
  mat3 yuv_transform = transform_scale_buffer((mat3){{
    1.0, 0.0, 0.0,
    0.0, 1.0, 0.0,
    0.0, 0.0, 1.0,
  }}, 0.5);

  // loop
  VisionStream stream;
  while (!do_exit) {
    VisionStreamBufs buf_info;
    err = visionstream_init(&stream, VISION_STREAM_YUV, true, &buf_info);
    if (err) {
      LOGW("visionstream connect failed");
      usleep(100000);
      continue;
    }
    LOGW("connected with buffer size: %d", buf_info.buf_len);

    // one frame in memory
    cl_mem yuv_cl;
    VisionBuf yuv_ion = visionbuf_allocate_cl(buf_info.buf_len, device_id, context, &yuv_cl);

    double last = 0;
    int desire = -1;
    while (!do_exit) {
      VIPCBuf *buf;
      VIPCBufExtra extra;
      buf = visionstream_get(&stream, &extra);
      if (buf == NULL) {
        LOGW("visionstream get failed");
        visionstream_destroy(&stream);
        break;
      }

      pthread_mutex_lock(&transform_lock);
      mat3 transform = cur_transform;
      const bool run_model_this_iter = run_model;
      pthread_mutex_unlock(&transform_lock);

      Message *msg = pathplan_sock->receive(true);
      if (msg != NULL) {
        // TODO: copy and pasted from camerad/main.cc
        auto amsg = kj::heapArray<capnp::word>((msg->getSize() / sizeof(capnp::word)) + 1);
        memcpy(amsg.begin(), msg->getData(), msg->getSize());

        capnp::FlatArrayMessageReader cmsg(amsg);
        cereal::Event::Reader event = cmsg.getRoot<cereal::Event>();

        // TODO: path planner timeout?
        desire = ((int)event.getPathPlan().getDesire()) - 1;
        delete msg;
      }

      double mt1 = 0, mt2 = 0;
      if (run_model_this_iter) {
        float vec_desire[DESIRE_LEN] = {0};
        if (desire >= 0 && desire < DESIRE_LEN) {
          vec_desire[desire] = 1.0;
        }

        mat3 model_transform = matmul3(yuv_transform, transform);

        mt1 = millis_since_boot();

        // TODO: don't make copies!
        memcpy(yuv_ion.addr, buf->addr, buf_info.buf_len);

        ModelDataRaw model_buf =
            model_eval_frame(&model, q, yuv_cl, buf_info.width, buf_info.height,
                             model_transform, NULL, vec_desire);
        mt2 = millis_since_boot();

        model_publish(model_sock, extra.frame_id, model_buf, extra.timestamp_eof);
        posenet_publish(posenet_sock, extra.frame_id, model_buf, extra.timestamp_eof);

        LOGD("model process: %.2fms, from last %.2fms", mt2-mt1, mt1-last);
        last = mt1;
      }

    }
    visionbuf_free(&yuv_ion);
  }

  visionstream_destroy(&stream);

  delete model_sock;
  delete posenet_sock;
  delete pathplan_sock;
  delete msg_context;

  model_free(&model);

  LOG("joining live_thread");
  err = pthread_join(live_thread_handle, NULL);
  assert(err == 0);

  return 0;
}
<|endoftext|>


<commit_before>#include <SDL2/SDL.h>
#include <iostream>

#include "core/log.h"
#include "core/str.h"

#include "render/shader.h"
#include "render/spriterender.h"

#include "core/interpolate.h"
#include "core/os.h"
#include "core/componentsystem.h"
#include "core/filesystemimagegenerator.h"
#include "core/filesystemdefaultshaders.h"
#include "core/proto.h"

#include "render/debuggl.h"
#include "render/fonts.h"
#include "render/init.h"
#include "render/fontcache.h"
#include "render/scalablesprite.h"
#include "render/shaderattribute2d.h"
#include "render/texturecache.h"
#include "render/viewport.h"

#include "gui/root.h"
#include "window/key.h"

#include "engine/loadworld.h"
#include "engine/systems.h"
#include "engine/duk.h"
#include "engine/dukintegration.h"
#include "engine/dukmathbindings.h"
#include "engine/input.h"

#include "game.pb.h"

LOG_SPECIFY_DEFAULT_LOGGER("engine")

game::Game
LoadGameData(FileSystem* fs)
{
  game::Game game;
  const auto err = LoadProtoJson(fs, &game, "gamedata.json");
  if(!err.empty())
  {
    LOG_ERROR("Failed to load gamedata.json: " << err);
  }
  return game;
}

struct RunResult
{
  bool        ok;
  std::string message;

  static const RunResult
  Ok()
  {
    return RunResult{true, ""};
  };

  static const RunResult
  Error(const std::string& message)
  {
    return RunResult{false, message};
  };

 private:
  RunResult(bool b, const std::string& str)
      : ok(b)
      , message(str)
  {
  }
};

RunResult
RunMainScriptFile(Duk* duk, FileSystem* fs, const std::string& path)
{
  std::string content;
  const bool  loaded = fs->ReadFileToString(path, &content);
  if(!loaded)
  {
    const std::string error_message = Str() << "Unable to open " << path
                                            << " for running";
    LOG_ERROR(error_message);
    return RunResult::Error(error_message);
  }
  std::string error;
  const bool  eval = duk->eval_string(content, &error, nullptr);
  if(!eval)
  {
    const std::string error_message = Str() << "Failed to run " << path << ": "
                                            << error;
    LOG_ERROR(error_message);
    return RunResult::Error(error_message);
  }

  return RunResult::Ok();
}

int
main(int argc, char** argv)
{
  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0)
  {
    LOG_ERROR("Failed to init SDL: " << SDL_GetError());
    return -1;
  }

  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
  SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);

  const auto current_directory = GetCurrentDirectory();
  FileSystem file_system;
  file_system.SetWrite(
      std::make_shared<FileSystemWriteFolder>(current_directory));
  FileSystemRootFolder::AddRoot(&file_system, current_directory);
  FileSystemImageGenerator::AddRoot(&file_system, "img-plain");
  FileSystemDefaultShaders::AddRoot(&file_system, "shaders");
  auto catalog = FileSystemRootCatalog::AddRoot(&file_system);
  catalog->RegisterFileString(
      "debug_font.json",
      R"(  {"size": 30, "sources": [{"builtin": {}}] }  )");
  TextureCache cache{&file_system};

  game::Game gamedata = LoadGameData(&file_system);

  int width  = 800;
  int height = 600;

  SDL_Window* window = SDL_CreateWindow(
      gamedata.title().c_str(),
      SDL_WINDOWPOS_UNDEFINED,
      SDL_WINDOWPOS_UNDEFINED,
      width,
      height,
      SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);

  if(window == NULL)
  {
    LOG_ERROR("Failed to create window " << SDL_GetError());
    return -1;
  }

  SDL_GL_CreateContext(window);
  Init init{SDL_GL_GetProcAddress, Init::BlendHack::EnableHack};

  if(init.ok == false)
  {
    return -4;
  }

  SetupOpenglDebug();

  // todo: update theese during runtime
  Font font{&file_system, &cache, "debug_font.json"};
  Text crash_message{&font};
  bool has_crashed = false;

  Input input;

  for(const auto& bind : gamedata.binds())
  {
    auto key = ToKey(bind.key());
    if(key == Key::INVALID)
    {
      LOG_ERROR("Invalid key: " << bind.key());
      key = Key::UNBOUND;
    }

    input.Add(std::make_shared<BoundVar>(bind.name(), key));
  }

  Shader shader;
  attributes2d::PrebindShader(&shader);
  shader.Load(&file_system, "shaders/sprite");
  SpriteRenderer renderer(&shader);
  FontCache      font_cache{&file_system, &cache};

  // Sprite player(cache.GetTexture("player.png"));
  // objects.Add(&player);

  Duk duk;
  BindMath(&duk);

  Systems systems;
  AddSystems(&systems, &duk);
  World          world{&systems};
  DukIntegration integration{&systems, &world, &duk};
  const auto error_run_main = RunMainScriptFile(&duk, &file_system, "main.js");
  if(!error_run_main.ok)
  {
    has_crashed = true;
    crash_message.SetText(ParsedText::FromText(error_run_main.message));
  }

  LoadWorld(&file_system, &world, &cache, "game.json");

  const mat4f projection = init.GetOrthoProjection(width, height);
  Use(&shader);
  shader.SetUniform(shader.GetUniform("image"), 0);
  shader.SetUniform(shader.GetUniform("projection"), projection);

  Viewport viewport{
      Recti::FromWidthHeight(width, height).SetBottomLeftToCopy(0, 0)};
  viewport.Activate();

  Uint64 NOW  = SDL_GetPerformanceCounter();
  Uint64 LAST = 0;

  SDL_StartTextInput();

  bool running = true;

  int window_mouse_x = 0;
  int window_mouse_y = 0;
  SDL_GetMouseState(&window_mouse_x, &window_mouse_y);
  bool mouse_lmb_down = false;

  while(running)
  {
    LAST           = NOW;
    NOW            = SDL_GetPerformanceCounter();
    const float dt = (NOW - LAST) * 1.0f / SDL_GetPerformanceFrequency();
    SDL_Event   e;

    if(!has_crashed)
    {
      world.Update(dt);
    }

    while(SDL_PollEvent(&e) != 0)
    {
      if(e.type == SDL_QUIT)
      {
        running = false;
      }
      if(has_crashed)
      {
        if(e.type == SDL_KEYUP)
        {
          const auto key = ToKey(e.key.keysym);
          if(key == Key::ESCAPE)
          {
            running = false;
          }
        }
      }
      else
      {
        if(e.type == SDL_MOUSEMOTION)
        {
          window_mouse_x = e.motion.x;
          window_mouse_y = e.motion.y;
        }
        else if(e.type == SDL_KEYUP || e.type == SDL_KEYDOWN)
        {
          const bool down = e.type == SDL_KEYDOWN;
          const auto key  = ToKey(e.key.keysym);
          input.SetKeyState(key, down ? 1.0f : 0.0f);
        }
        else if(e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP)
        {
          const bool down = e.type == SDL_MOUSEBUTTONDOWN;
          window_mouse_x  = e.button.x;
          window_mouse_y  = e.button.y;
          if(e.button.button == SDL_BUTTON_LEFT)
          {
            mouse_lmb_down = down;
          }
        }
        else if(e.type == SDL_TEXTINPUT)
        {
          const std::string& input = e.text.text;
        }
      }
    }

    if(has_crashed == false)
    {
      integration.BindKeys(&duk, input);
    }

    if(has_crashed)
    {
      // todo: fix crash rendering, perhaps by using a debug gui
      // nothing much is required just a better overflow detection
      // when rendering the error, perhaps making the error more visible
      init.ClearScreen(Color::CornflowerBlue);
      crash_message.Draw(&renderer, vec2f{20, 20}, Color::Black);
    }
    else
    {
      init.ClearScreen(Color::DarkslateGray);
      world.Draw(&renderer);
    }

    SDL_GL_SwapWindow(window);
  }

  SDL_DestroyWindow(window);
  SDL_Quit();
  return 0;
}
<commit_msg>tweaked crash display<commit_after>#include <SDL2/SDL.h>
#include <iostream>

#include "core/log.h"
#include "core/str.h"

#include "render/shader.h"
#include "render/spriterender.h"

#include "core/interpolate.h"
#include "core/os.h"
#include "core/componentsystem.h"
#include "core/filesystemimagegenerator.h"
#include "core/filesystemdefaultshaders.h"
#include "core/proto.h"

#include "render/debuggl.h"
#include "render/fonts.h"
#include "render/init.h"
#include "render/fontcache.h"
#include "render/scalablesprite.h"
#include "render/shaderattribute2d.h"
#include "render/texturecache.h"
#include "render/viewport.h"

#include "gui/root.h"
#include "window/key.h"

#include "engine/loadworld.h"
#include "engine/systems.h"
#include "engine/duk.h"
#include "engine/dukintegration.h"
#include "engine/dukmathbindings.h"
#include "engine/input.h"

#include "game.pb.h"

LOG_SPECIFY_DEFAULT_LOGGER("engine")

game::Game
LoadGameData(FileSystem* fs)
{
  game::Game game;
  const auto err = LoadProtoJson(fs, &game, "gamedata.json");
  if(!err.empty())
  {
    LOG_ERROR("Failed to load gamedata.json: " << err);
  }
  return game;
}

struct RunResult
{
  bool        ok;
  std::string message;

  static const RunResult
  Ok()
  {
    return RunResult{true, ""};
  };

  static const RunResult
  Error(const std::string& message)
  {
    return RunResult{false, message};
  };

 private:
  RunResult(bool b, const std::string& str)
      : ok(b)
      , message(str)
  {
  }
};

RunResult
RunMainScriptFile(Duk* duk, FileSystem* fs, const std::string& path)
{
  std::string content;
  const bool  loaded = fs->ReadFileToString(path, &content);
  if(!loaded)
  {
    const std::string error_message = Str() << "Unable to open " << path
                                            << " for running";
    LOG_ERROR(error_message);
    return RunResult::Error(error_message);
  }
  std::string error;
  const bool  eval = duk->eval_string(content, &error, nullptr);
  if(!eval)
  {
    const std::string error_message = Str() << "Failed to run " << path << ": "
                                            << error;
    LOG_ERROR(error_message);
    return RunResult::Error(error_message);
  }

  return RunResult::Ok();
}

int
main(int argc, char** argv)
{
  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0)
  {
    LOG_ERROR("Failed to init SDL: " << SDL_GetError());
    return -1;
  }

  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 4);
  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0);
  SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
  SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
  SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);

  const auto current_directory = GetCurrentDirectory();
  FileSystem file_system;
  file_system.SetWrite(
      std::make_shared<FileSystemWriteFolder>(current_directory));
  FileSystemRootFolder::AddRoot(&file_system, current_directory);
  FileSystemImageGenerator::AddRoot(&file_system, "img-plain");
  FileSystemDefaultShaders::AddRoot(&file_system, "shaders");
  auto catalog = FileSystemRootCatalog::AddRoot(&file_system);
  catalog->RegisterFileString(
      "debug_font.json",
      R"(  {"size": 30, "sources": [{"builtin": {}}] }  )");
  TextureCache cache{&file_system};

  game::Game gamedata = LoadGameData(&file_system);

  int width  = 800;
  int height = 600;

  SDL_Window* window = SDL_CreateWindow(
      gamedata.title().c_str(),
      SDL_WINDOWPOS_UNDEFINED,
      SDL_WINDOWPOS_UNDEFINED,
      width,
      height,
      SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);

  if(window == NULL)
  {
    LOG_ERROR("Failed to create window " << SDL_GetError());
    return -1;
  }

  SDL_GL_CreateContext(window);
  Init init{SDL_GL_GetProcAddress, Init::BlendHack::EnableHack};

  if(init.ok == false)
  {
    return -4;
  }

  SetupOpenglDebug();

  // todo: update theese during runtime
  Font font{&file_system, &cache, "debug_font.json"};
  Text crash_message{&font};
  bool has_crashed = false;

  Input input;

  for(const auto& bind : gamedata.binds())
  {
    auto key = ToKey(bind.key());
    if(key == Key::INVALID)
    {
      LOG_ERROR("Invalid key: " << bind.key());
      key = Key::UNBOUND;
    }

    input.Add(std::make_shared<BoundVar>(bind.name(), key));
  }

  Shader shader;
  attributes2d::PrebindShader(&shader);
  shader.Load(&file_system, "shaders/sprite");
  SpriteRenderer renderer(&shader);
  FontCache      font_cache{&file_system, &cache};

  // Sprite player(cache.GetTexture("player.png"));
  // objects.Add(&player);

  Duk duk;
  BindMath(&duk);

  Systems systems;
  AddSystems(&systems, &duk);
  World          world{&systems};
  DukIntegration integration{&systems, &world, &duk};
  const auto error_run_main = RunMainScriptFile(&duk, &file_system, "main.js");
  if(!error_run_main.ok)
  {
    has_crashed = true;
    crash_message.SetText(ParsedText::FromText(error_run_main.message));
  }

  LoadWorld(&file_system, &world, &cache, "game.json");

  const mat4f projection = init.GetOrthoProjection(width, height);
  Use(&shader);
  shader.SetUniform(shader.GetUniform("image"), 0);
  shader.SetUniform(shader.GetUniform("projection"), projection);

  Viewport viewport{
      Recti::FromWidthHeight(width, height).SetBottomLeftToCopy(0, 0)};
  viewport.Activate();

  Uint64 NOW  = SDL_GetPerformanceCounter();
  Uint64 LAST = 0;

  SDL_StartTextInput();

  bool running = true;

  int window_mouse_x = 0;
  int window_mouse_y = 0;
  SDL_GetMouseState(&window_mouse_x, &window_mouse_y);
  bool mouse_lmb_down = false;

  while(running)
  {
    LAST           = NOW;
    NOW            = SDL_GetPerformanceCounter();
    const float dt = (NOW - LAST) * 1.0f / SDL_GetPerformanceFrequency();
    SDL_Event   e;

    if(!has_crashed)
    {
      world.Update(dt);
    }

    while(SDL_PollEvent(&e) != 0)
    {
      if(e.type == SDL_QUIT)
      {
        running = false;
      }
      if(has_crashed)
      {
        if(e.type == SDL_KEYUP)
        {
          const auto key = ToKey(e.key.keysym);
          if(key == Key::ESCAPE)
          {
            running = false;
          }
        }
      }
      else
      {
        if(e.type == SDL_MOUSEMOTION)
        {
          window_mouse_x = e.motion.x;
          window_mouse_y = e.motion.y;
        }
        else if(e.type == SDL_KEYUP || e.type == SDL_KEYDOWN)
        {
          const bool down = e.type == SDL_KEYDOWN;
          const auto key  = ToKey(e.key.keysym);
          input.SetKeyState(key, down ? 1.0f : 0.0f);
        }
        else if(e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP)
        {
          const bool down = e.type == SDL_MOUSEBUTTONDOWN;
          window_mouse_x  = e.button.x;
          window_mouse_y  = e.button.y;
          if(e.button.button == SDL_BUTTON_LEFT)
          {
            mouse_lmb_down = down;
          }
        }
        else if(e.type == SDL_TEXTINPUT)
        {
          const std::string& input = e.text.text;
        }
      }
    }

    if(has_crashed == false)
    {
      integration.BindKeys(&duk, input);
    }

    if(has_crashed)
    {
      // todo: fix crash rendering, perhaps by using a debug gui or imgui
      // nothing much is required just a better overflow detection
      // when rendering the error, perhaps making the error more visible
      // though clicking around and debugging might be useful...
      init.ClearScreen(Color::CornflowerBlue);
      crash_message.Draw(&renderer, vec2f{5, height - 20}, Color::Black);
    }
    else
    {
      init.ClearScreen(Color::DarkslateGray);
      world.Draw(&renderer);
    }

    SDL_GL_SwapWindow(window);
  }

  SDL_DestroyWindow(window);
  SDL_Quit();
  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 "tensorflow/lite/tools/signature/signature_def_util.h"

#include <string>

#include "absl/memory/memory.h"
#include "flatbuffers/flatbuffers.h"  // from @flatbuffers
#include "flatbuffers/flexbuffers.h"  // from @flatbuffers
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/protobuf/meta_graph.pb.h"
#include "tensorflow/lite/model_builder.h"
#include "tensorflow/lite/schema/schema_generated.h"

namespace tflite {
namespace {

using tensorflow::Status;
using SerializedSignatureDefMap = std::map<std::string, std::string>;
using SignatureDefMap = std::map<std::string, tensorflow::SignatureDef>;

const Metadata* GetSignatureDefMetadata(const Model* model) {
  if (!model || !model->metadata()) {
    return nullptr;
  }
  for (int i = 0; i < model->metadata()->size(); ++i) {
    const Metadata* metadata = model->metadata()->Get(i);
    if (metadata->name()->str() == kSignatureDefsMetadataName) {
      return metadata;
    }
  }
  return nullptr;
}

Status ReadSignatureDefMap(const Model* model, const Metadata* metadata,
                           SerializedSignatureDefMap* map) {
  if (!model || !metadata || !map) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  const flatbuffers::Vector<uint8_t>* flatbuffer_data =
      model->buffers()->Get(metadata->buffer())->data();
  const auto signature_defs =
      flexbuffers::GetRoot(flatbuffer_data->data(), flatbuffer_data->size())
          .AsMap();
  for (int i = 0; i < signature_defs.Keys().size(); ++i) {
    const std::string key = signature_defs.Keys()[i].AsString().c_str();
    (*map)[key] = signature_defs[key].AsString().c_str();
  }
  return tensorflow::Status::OK();
}

}  // namespace

Status SetSignatureDefMap(const Model* model,
                          const SignatureDefMap& signature_def_map,
                          std::string* model_data_with_signature_def) {
  if (!model || !model_data_with_signature_def) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  if (signature_def_map.empty()) {
    return tensorflow::errors::InvalidArgument(
        "signature_def_map should not be empty");
  }
  flexbuffers::Builder fbb;
  const size_t start_map = fbb.StartMap();
  auto mutable_model = absl::make_unique<ModelT>();
  model->UnPackTo(mutable_model.get(), nullptr);
  int buffer_id = mutable_model->buffers.size();
  const Metadata* metadata = GetSignatureDefMetadata(model);
  if (metadata) {
    buffer_id = metadata->buffer();
  } else {
    auto buffer = absl::make_unique<BufferT>();
    mutable_model->buffers.emplace_back(std::move(buffer));
    auto sigdef_metadata = absl::make_unique<MetadataT>();
    sigdef_metadata->buffer = buffer_id;
    sigdef_metadata->name = kSignatureDefsMetadataName;
    mutable_model->metadata.emplace_back(std::move(sigdef_metadata));
  }
  for (const auto& entry : signature_def_map) {
    fbb.String(entry.first.c_str(), entry.second.SerializeAsString());
  }
  fbb.EndMap(start_map);
  fbb.Finish();
  mutable_model->buffers[buffer_id]->data = fbb.GetBuffer();
  flatbuffers::FlatBufferBuilder builder;
  auto packed_model = Model::Pack(builder, mutable_model.get());
  FinishModelBuffer(builder, packed_model);
  *model_data_with_signature_def =
      std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
                  builder.GetSize());
  return Status::OK();
}

bool HasSignatureDef(const Model* model, const std::string& signature_key) {
  if (!model) {
    return false;
  }
  const Metadata* metadata = GetSignatureDefMetadata(model);
  if (!metadata) {
    return false;
  }
  SerializedSignatureDefMap signature_defs;
  if (ReadSignatureDefMap(model, metadata, &signature_defs) !=
      tensorflow::Status::OK()) {
    return false;
  }
  return (signature_defs.find(signature_key) != signature_defs.end());
}

Status GetSignatureDefMap(const Model* model,
                          SignatureDefMap* signature_def_map) {
  if (!model || !signature_def_map) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  SignatureDefMap retrieved_signature_def_map;
  const Metadata* metadata = GetSignatureDefMetadata(model);
  if (metadata) {
    SerializedSignatureDefMap signature_defs;
    auto status = ReadSignatureDefMap(model, metadata, &signature_defs);
    if (status != tensorflow::Status::OK()) {
      return tensorflow::errors::Internal("Error reading signature def map: %s",
                                          status.error_message());
    }
    for (const auto& entry : signature_defs) {
      tensorflow::SignatureDef signature_def;
      if (!signature_def.ParseFromString(entry.second)) {
        return tensorflow::errors::Internal(
            "Cannot parse signature def found in flatbuffer.");
      }
      retrieved_signature_def_map[entry.first] = signature_def;
    }
    *signature_def_map = retrieved_signature_def_map;
  }
  return Status::OK();
}

Status ClearSignatureDefMap(const Model* model, std::string* model_data) {
  if (!model || !model_data) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  auto mutable_model = absl::make_unique<ModelT>();
  model->UnPackTo(mutable_model.get(), nullptr);
  for (int id = 0; id < model->metadata()->size(); ++id) {
    const Metadata* metadata = model->metadata()->Get(id);
    if (metadata->name()->str() == kSignatureDefsMetadataName) {
      auto* buffers = &(mutable_model->buffers);
      buffers->erase(buffers->begin() + metadata->buffer());
      mutable_model->metadata.erase(mutable_model->metadata.begin() + id);
      break;
    }
  }
  flatbuffers::FlatBufferBuilder builder;
  auto packed_model = Model::Pack(builder, mutable_model.get());
  FinishModelBuffer(builder, packed_model);
  *model_data =
      std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
                  builder.GetSize());
  return Status::OK();
}

}  // namespace tflite
<commit_msg>Fix tensorflow::errors:* calls, which use StrCat instead of StrFormat<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/lite/tools/signature/signature_def_util.h"

#include <string>

#include "absl/memory/memory.h"
#include "flatbuffers/flatbuffers.h"  // from @flatbuffers
#include "flatbuffers/flexbuffers.h"  // from @flatbuffers
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/protobuf/meta_graph.pb.h"
#include "tensorflow/lite/model_builder.h"
#include "tensorflow/lite/schema/schema_generated.h"

namespace tflite {
namespace {

using tensorflow::Status;
using SerializedSignatureDefMap = std::map<std::string, std::string>;
using SignatureDefMap = std::map<std::string, tensorflow::SignatureDef>;

const Metadata* GetSignatureDefMetadata(const Model* model) {
  if (!model || !model->metadata()) {
    return nullptr;
  }
  for (int i = 0; i < model->metadata()->size(); ++i) {
    const Metadata* metadata = model->metadata()->Get(i);
    if (metadata->name()->str() == kSignatureDefsMetadataName) {
      return metadata;
    }
  }
  return nullptr;
}

Status ReadSignatureDefMap(const Model* model, const Metadata* metadata,
                           SerializedSignatureDefMap* map) {
  if (!model || !metadata || !map) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  const flatbuffers::Vector<uint8_t>* flatbuffer_data =
      model->buffers()->Get(metadata->buffer())->data();
  const auto signature_defs =
      flexbuffers::GetRoot(flatbuffer_data->data(), flatbuffer_data->size())
          .AsMap();
  for (int i = 0; i < signature_defs.Keys().size(); ++i) {
    const std::string key = signature_defs.Keys()[i].AsString().c_str();
    (*map)[key] = signature_defs[key].AsString().c_str();
  }
  return tensorflow::Status::OK();
}

}  // namespace

Status SetSignatureDefMap(const Model* model,
                          const SignatureDefMap& signature_def_map,
                          std::string* model_data_with_signature_def) {
  if (!model || !model_data_with_signature_def) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  if (signature_def_map.empty()) {
    return tensorflow::errors::InvalidArgument(
        "signature_def_map should not be empty");
  }
  flexbuffers::Builder fbb;
  const size_t start_map = fbb.StartMap();
  auto mutable_model = absl::make_unique<ModelT>();
  model->UnPackTo(mutable_model.get(), nullptr);
  int buffer_id = mutable_model->buffers.size();
  const Metadata* metadata = GetSignatureDefMetadata(model);
  if (metadata) {
    buffer_id = metadata->buffer();
  } else {
    auto buffer = absl::make_unique<BufferT>();
    mutable_model->buffers.emplace_back(std::move(buffer));
    auto sigdef_metadata = absl::make_unique<MetadataT>();
    sigdef_metadata->buffer = buffer_id;
    sigdef_metadata->name = kSignatureDefsMetadataName;
    mutable_model->metadata.emplace_back(std::move(sigdef_metadata));
  }
  for (const auto& entry : signature_def_map) {
    fbb.String(entry.first.c_str(), entry.second.SerializeAsString());
  }
  fbb.EndMap(start_map);
  fbb.Finish();
  mutable_model->buffers[buffer_id]->data = fbb.GetBuffer();
  flatbuffers::FlatBufferBuilder builder;
  auto packed_model = Model::Pack(builder, mutable_model.get());
  FinishModelBuffer(builder, packed_model);
  *model_data_with_signature_def =
      std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
                  builder.GetSize());
  return Status::OK();
}

bool HasSignatureDef(const Model* model, const std::string& signature_key) {
  if (!model) {
    return false;
  }
  const Metadata* metadata = GetSignatureDefMetadata(model);
  if (!metadata) {
    return false;
  }
  SerializedSignatureDefMap signature_defs;
  if (ReadSignatureDefMap(model, metadata, &signature_defs) !=
      tensorflow::Status::OK()) {
    return false;
  }
  return (signature_defs.find(signature_key) != signature_defs.end());
}

Status GetSignatureDefMap(const Model* model,
                          SignatureDefMap* signature_def_map) {
  if (!model || !signature_def_map) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  SignatureDefMap retrieved_signature_def_map;
  const Metadata* metadata = GetSignatureDefMetadata(model);
  if (metadata) {
    SerializedSignatureDefMap signature_defs;
    auto status = ReadSignatureDefMap(model, metadata, &signature_defs);
    if (status != tensorflow::Status::OK()) {
      return tensorflow::errors::Internal("Error reading signature def map: ",
                                          status.error_message());
    }
    for (const auto& entry : signature_defs) {
      tensorflow::SignatureDef signature_def;
      if (!signature_def.ParseFromString(entry.second)) {
        return tensorflow::errors::Internal(
            "Cannot parse signature def found in flatbuffer.");
      }
      retrieved_signature_def_map[entry.first] = signature_def;
    }
    *signature_def_map = retrieved_signature_def_map;
  }
  return Status::OK();
}

Status ClearSignatureDefMap(const Model* model, std::string* model_data) {
  if (!model || !model_data) {
    return tensorflow::errors::InvalidArgument("Arguments must not be nullptr");
  }
  auto mutable_model = absl::make_unique<ModelT>();
  model->UnPackTo(mutable_model.get(), nullptr);
  for (int id = 0; id < model->metadata()->size(); ++id) {
    const Metadata* metadata = model->metadata()->Get(id);
    if (metadata->name()->str() == kSignatureDefsMetadataName) {
      auto* buffers = &(mutable_model->buffers);
      buffers->erase(buffers->begin() + metadata->buffer());
      mutable_model->metadata.erase(mutable_model->metadata.begin() + id);
      break;
    }
  }
  flatbuffers::FlatBufferBuilder builder;
  auto packed_model = Model::Pack(builder, mutable_model.get());
  FinishModelBuffer(builder, packed_model);
  *model_data =
      std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
                  builder.GetSize());
  return Status::OK();
}

}  // namespace tflite
<|endoftext|>


<commit_before>//************************************************************/
//
//	PDF Error Type Implementation
//
//	Implements the SPXPDFErrorType class, which describes the PDF
//	error type. The options are 'alpha_s' or 'pdf_band'
//
//	@Author: 	J. Gibson, C. Embree, T. Carli - CERN ATLAS
//	@Date:		29.09.2014
//	@Email:		gibsjose@mail.gvsu.edu
//
//************************************************************/

#include <iostream>
#include <sstream>

#include "SPXPDFErrorType.h"
#include "SPXException.h"

//Class name for debug statements
const std::string cn = "SPXPDFErrorType::";

//Must define the static debug variable in the implementation
bool SPXPDFErrorType::debug;

//Constructs an SPXPDFErrorType object with a given string (effectively
//	calls the Parse() method on the input string)
SPXPDFErrorType::SPXPDFErrorType(std::string s) {
	this->Clear();
	this->Parse(s);
}

//Takes a string argument in the form:
//	alpha_s XOR pdf_band
//
// Sets the type based on the input string
void SPXPDFErrorType::Parse(std::string s) {
	std::string mn = "Parse: ";

	if(debug) std::cout << cn << mn << "Parsing configuration string: " << s << std::endl;

	//Clear the type each time it is parsed
	this->Clear();

	if(!s.compare("alpha_s")) {
		if(debug) std::cout << cn << mn << "Successfully matched type string: \"alpha_s\"" << std::endl;
		type = ET_ALPHA_S;
		if(debug) std::cout << cn << mn << "PDF Error Type successfully set to \"alpha_s\"" << std::endl;
	}
	else if(!s.compare("pdf_band")) {
		if(debug) std::cout << cn << mn << "Successfully matched type string: \"pdf_band\"" << std::endl;
		type = ET_PDF_BAND;
		if(debug) std::cout << cn << mn << "PDF Error Type successfully set to \"pdf_band\"" << std::endl;
	}
	else {
		type = ET_INVALID;

		std::ostringstream oss;
		oss << "Incorrect PDF Error Type: Unrecognized type option: \"" << s << "\" is invalid";
		throw SPXINIParseException("PDF", "pdf_error_type", oss.str());
	}
}

//Print displays the output of ToString to the console
void SPXPDFErrorType::Print(void) {
	std::string mn = "Print: ";
	std::cout << this->ToString() << std::endl;
}

//ToString does the opposite of Parse: it assembles a string based on
// the object's type data
std::string SPXPDFErrorType::ToString(void) {
	std::string mn = "ToString: ";

	//Empty style
	if(this->IsEmpty()) {
		return "";
	}

	//Check for validity
	if(!this->IsValid()) {
		return "INVALID_PDF_ERROR_TYPE";
	}

	if(type == ET_ALPHA_S) {
		return "alpha_s";
	}
	if(type == ET_PDF_BAND) {
		return "pdf_band";
	}

	return "INVALID_PDF_ERROR_TYPE";
}

//Determines whether the error type is empty or not
bool SPXPDFErrorType::IsEmpty(void) {
	std::string mn = "IsEmpty: ";

	return !(bool)type;
}

//Determines the validity of the error type
bool SPXPDFErrorType::IsValid(void) {
	std::string mn = "IsValid: ";

	//Empty style: valid, but empty
	if(this->IsEmpty()){
		if(debug) std::cout << cn << mn << "PDF Error Type is empty" << std::endl;
		return true;
	}

	if(type == ET_INVALID) {
		if(debug) std::cout << cn << mn << "PDF Error Type is invalid: Set to ET_INVALID (-1)" << std::endl;
		return false;
	}

	if(type >= (ET_ALPHA_S | ET_PDF_BAND)) {
		if(debug) std::cout << cn << mn << "PDF Error Type is invalid: Type is set to unknown value: " << type << std::endl;
		return false;
	}

	return true;
}

<commit_msg>Changed ::ToString method for PDFErrorTYpe to represent the strings used in former MyPDF class<commit_after>//************************************************************/
//
//	PDF Error Type Implementation
//
//	Implements the SPXPDFErrorType class, which describes the PDF
//	error type. The options are 'alpha_s' or 'pdf_band'
//
//	@Author: 	J. Gibson, C. Embree, T. Carli - CERN ATLAS
//	@Date:		29.09.2014
//	@Email:		gibsjose@mail.gvsu.edu
//
//************************************************************/

#include <iostream>
#include <sstream>

#include "SPXPDFErrorType.h"
#include "SPXException.h"

//Class name for debug statements
const std::string cn = "SPXPDFErrorType::";

//Must define the static debug variable in the implementation
bool SPXPDFErrorType::debug;

//Constructs an SPXPDFErrorType object with a given string (effectively
//	calls the Parse() method on the input string)
SPXPDFErrorType::SPXPDFErrorType(std::string s) {
	this->Clear();
	this->Parse(s);
}

//Takes a string argument in the form:
//	alpha_s XOR pdf_band
//
// Sets the type based on the input string
void SPXPDFErrorType::Parse(std::string s) {
	std::string mn = "Parse: ";

	if(debug) std::cout << cn << mn << "Parsing configuration string: " << s << std::endl;

	//Clear the type each time it is parsed
	this->Clear();

	if(!s.compare("alpha_s")) {
		if(debug) std::cout << cn << mn << "Successfully matched type string: \"alpha_s\"" << std::endl;
		type = ET_ALPHA_S;
		if(debug) std::cout << cn << mn << "PDF Error Type successfully set to \"alpha_s\"" << std::endl;
	}
	else if(!s.compare("pdf_band")) {
		if(debug) std::cout << cn << mn << "Successfully matched type string: \"pdf_band\"" << std::endl;
		type = ET_PDF_BAND;
		if(debug) std::cout << cn << mn << "PDF Error Type successfully set to \"pdf_band\"" << std::endl;
	}
	else {
		type = ET_INVALID;

		std::ostringstream oss;
		oss << "Incorrect PDF Error Type: Unrecognized type option: \"" << s << "\" is invalid";
		throw SPXINIParseException("PDF", "pdf_error_type", oss.str());
	}
}

//Print displays the output of ToString to the console
void SPXPDFErrorType::Print(void) {
	std::string mn = "Print: ";
	std::cout << this->ToString() << std::endl;
}

//ToString does the opposite of Parse: it assembles a string based on
// the object's type data
std::string SPXPDFErrorType::ToString(void) {
	std::string mn = "ToString: ";

	//Empty style
	if(this->IsEmpty()) {
		return "";
	}

	//Check for validity
	if(!this->IsValid()) {
		return "INVALID_PDF_ERROR_TYPE";
	}

	if(type == ET_ALPHA_S) {
		return "AlphaS";
	}
	if(type == ET_PDF_BAND) {
		return "PDFBand";
	}

	return "INVALID_PDF_ERROR_TYPE";
}

//Determines whether the error type is empty or not
bool SPXPDFErrorType::IsEmpty(void) {
	std::string mn = "IsEmpty: ";

	return !(bool)type;
}

//Determines the validity of the error type
bool SPXPDFErrorType::IsValid(void) {
	std::string mn = "IsValid: ";

	//Empty style: valid, but empty
	if(this->IsEmpty()){
		if(debug) std::cout << cn << mn << "PDF Error Type is empty" << std::endl;
		return true;
	}

	if(type == ET_INVALID) {
		if(debug) std::cout << cn << mn << "PDF Error Type is invalid: Set to ET_INVALID (-1)" << std::endl;
		return false;
	}

	if(type >= (ET_ALPHA_S | ET_PDF_BAND)) {
		if(debug) std::cout << cn << mn << "PDF Error Type is invalid: Type is set to unknown value: " << type << std::endl;
		return false;
	}

	return true;
}

<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Heiko Strathmann
 */

#include <shogun/kernel/GaussianKernel.h>
#include <shogun/kernel/CustomKernel.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/features/IndexFeatures.h>
#include <shogun/features/streaming/generators/MeanShiftDataGenerator.h>
#include <gtest/gtest.h>

using namespace shogun;

TEST(CustomKernelTest,add_row_subset)
{
	index_t m=3;
	CMeanShiftDataGenerator* gen=new CMeanShiftDataGenerator(0, 2);
	CFeatures* feats=gen->get_streamed_features(m);
	SG_REF(feats);

	CGaussianKernel* gauss=new CGaussianKernel(10, 3);
	gauss->init(feats, feats);
	CCustomKernel* custom=new CCustomKernel(gauss);

	SGVector<index_t> inds(m);
	inds.range_fill();

	index_t num_runs=10;
	for (index_t i=0; i<num_runs; ++i)
	{
		inds.permute();

		feats->add_subset(inds);
		custom->add_row_subset(inds);
		custom->add_col_subset(inds);
		gauss->init(feats, feats); // to make sure digonal is fine

		SGMatrix<float64_t> gauss_matrix=gauss->get_kernel_matrix();
		SGMatrix<float64_t> custom_matrix=custom->get_kernel_matrix();
//		gauss_matrix.display_matrix("gauss");
//		gauss_matrix.display_matrix("custom");
		for (index_t j=0; j<m*m; ++j)
			EXPECT_LE(CMath::abs(gauss_matrix.matrix[j]-custom_matrix.matrix[j]), 1E-6);

		feats->remove_subset();
		custom->remove_row_subset();
		custom->remove_col_subset();
	}

	SG_UNREF(gen);
	SG_UNREF(feats);
	SG_UNREF(gauss);
	SG_UNREF(custom);
}

TEST(CustomKernelTest,add_row_subset_constructor)
{
	index_t n=4;
	CMeanShiftDataGenerator* gen=new CMeanShiftDataGenerator(1, 2, 0);
	CDenseFeatures<float64_t>* feats=
			(CDenseFeatures<float64_t>*)gen->get_streamed_features(n);
	CGaussianKernel* gaussian=new CGaussianKernel(feats, feats, 2, 10);
	CCustomKernel* main_kernel=new CCustomKernel(gaussian);

	/* create custom kernel copy of gaussien and assert equalness */
	SGMatrix<float64_t> kmg=gaussian->get_kernel_matrix();
	SGMatrix<float64_t> km=main_kernel->get_kernel_matrix();
	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_LE(CMath::abs(kmg(i, j)-km(i, j)), 1E-7);
	}

	/* create copy of custom kernel and assert equalness */
	CCustomKernel* copy=new CCustomKernel(km);
	SGMatrix<float64_t> kmc=copy->get_kernel_matrix();
	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_EQ(km(i, j), kmc(i, j));
	}

	/* add a subset to the custom kernel, create copy, create another kernel
	 * from this, assert equalness */
	SGVector<index_t> inds(n);
	inds.range_fill();
	inds.permute();
	main_kernel->add_row_subset(inds);
	SGMatrix<float64_t> main_subset_matrix=main_kernel->get_kernel_matrix();
	main_kernel->remove_row_subset();
	CCustomKernel* main_subset_copy=new CCustomKernel(main_subset_matrix);
	SGMatrix<float64_t> main_subset_copy_matrix=main_subset_copy->get_kernel_matrix();
	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_EQ(main_subset_matrix(i, j), main_subset_copy_matrix(i, j));
	}

	SG_UNREF(main_subset_copy);
	SG_UNREF(gaussian);
	SG_UNREF(main_kernel);
	SG_UNREF(copy);
	SG_UNREF(gen);
}

//Generate the Data
void generate_data(SGMatrix<float64_t> &data)
{
	data(0,0)=0.044550005575722;
	data(1,0)=-0.433969606728583;
	data(2,0)=-0.397935396933392;
	data(0,1)=-0.778754072066602;
	data(1,1)=-0.620105076569903;
	data(2,1)=-0.542538248707627;
	data(0,2)=0.334313094513960;
	data(1,2)=0.421985645755003;
	data(2,2)=0.263031426076997;
	data(0,3)=0.516043376162584;
	data(1,3)=0.159041471773470;
	data(2,3)=0.691318725364356;
	data(0,4)=-0.116152404185664;
	data(1,4)=0.473047565770014;
	data(2,4)=-0.013876505800334;
}

TEST(CustomKernelTest,index_features_subset)
{
	float64_t epsilon=1e-7;
	index_t n=5;
	SGMatrix<float64_t> data(3,n);
	CDenseFeatures<float64_t>* feats=new CDenseFeatures<float64_t>(data);
	SG_REF(feats);
	CGaussianKernel* gaussian=new CGaussianKernel(feats, feats, 2, 10);
	SG_REF(gaussian);
	CCustomKernel* main_kernel=new CCustomKernel(gaussian);
	SG_REF(main_kernel);

	/* create custom kernel copy of gaussien and assert equalness */
	SGMatrix<float64_t> kmg=gaussian->get_kernel_matrix();
	SGMatrix<float64_t> km=main_kernel->get_kernel_matrix();

	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_NEAR(kmg(i, j), km(i, j), epsilon);
	}

	/* add a subset to the custom kernel, create copy, create another kernel
	 * from this, assert equalness */
	SGVector<index_t> r_idx(n);
	SGVector<index_t> c_idx(n);
	r_idx.range_fill();
	r_idx.permute();
	c_idx.range_fill();
	c_idx.permute();

	/* Create IndexFeatures instances */
	CIndexFeatures * feat_r_idx = new CIndexFeatures(r_idx);
	CIndexFeatures * feat_c_idx = new CIndexFeatures(c_idx);
	SG_REF(feat_r_idx);
	SG_REF(feat_c_idx);

	main_kernel->init(feat_r_idx,feat_c_idx);
	SGMatrix<float64_t> main_subset_matrix = main_kernel->get_kernel_matrix();

	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_NEAR(main_subset_matrix(i, j), kmg(r_idx[i], c_idx[j]), epsilon);
	}

	SG_UNREF(gaussian);
	SG_UNREF(main_kernel);
	SG_UNREF(feats);
	SG_UNREF(feat_r_idx);
	SG_UNREF(feat_c_idx);
}
<commit_msg>Fix CustomKernel-unittest bug.<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Heiko Strathmann
 */

#include <shogun/kernel/GaussianKernel.h>
#include <shogun/kernel/CustomKernel.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/features/IndexFeatures.h>
#include <shogun/features/streaming/generators/MeanShiftDataGenerator.h>
#include <gtest/gtest.h>

using namespace shogun;

TEST(CustomKernelTest,add_row_subset)
{
	index_t m=3;
	CMeanShiftDataGenerator* gen=new CMeanShiftDataGenerator(0, 2);
	CFeatures* feats=gen->get_streamed_features(m);
	SG_REF(feats);

	CGaussianKernel* gauss=new CGaussianKernel(10, 3);
	gauss->init(feats, feats);
	CCustomKernel* custom=new CCustomKernel(gauss);

	SGVector<index_t> inds(m);
	inds.range_fill();

	index_t num_runs=10;
	for (index_t i=0; i<num_runs; ++i)
	{
		inds.permute();

		feats->add_subset(inds);
		custom->add_row_subset(inds);
		custom->add_col_subset(inds);
		gauss->init(feats, feats); // to make sure digonal is fine

		SGMatrix<float64_t> gauss_matrix=gauss->get_kernel_matrix();
		SGMatrix<float64_t> custom_matrix=custom->get_kernel_matrix();
//		gauss_matrix.display_matrix("gauss");
//		gauss_matrix.display_matrix("custom");
		for (index_t j=0; j<m*m; ++j)
			EXPECT_LE(CMath::abs(gauss_matrix.matrix[j]-custom_matrix.matrix[j]), 1E-6);

		feats->remove_subset();
		custom->remove_row_subset();
		custom->remove_col_subset();
	}

	SG_UNREF(gen);
	SG_UNREF(feats);
	SG_UNREF(gauss);
	SG_UNREF(custom);
}

TEST(CustomKernelTest,add_row_subset_constructor)
{
	index_t n=4;
	CMeanShiftDataGenerator* gen=new CMeanShiftDataGenerator(1, 2, 0);
	CDenseFeatures<float64_t>* feats=
			(CDenseFeatures<float64_t>*)gen->get_streamed_features(n);
	CGaussianKernel* gaussian=new CGaussianKernel(feats, feats, 2, 10);
	CCustomKernel* main_kernel=new CCustomKernel(gaussian);

	/* create custom kernel copy of gaussien and assert equalness */
	SGMatrix<float64_t> kmg=gaussian->get_kernel_matrix();
	SGMatrix<float64_t> km=main_kernel->get_kernel_matrix();
	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_LE(CMath::abs(kmg(i, j)-km(i, j)), 1E-7);
	}

	/* create copy of custom kernel and assert equalness */
	CCustomKernel* copy=new CCustomKernel(km);
	SGMatrix<float64_t> kmc=copy->get_kernel_matrix();
	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_EQ(km(i, j), kmc(i, j));
	}

	/* add a subset to the custom kernel, create copy, create another kernel
	 * from this, assert equalness */
	SGVector<index_t> inds(n);
	inds.range_fill();
	inds.permute();
	main_kernel->add_row_subset(inds);
	SGMatrix<float64_t> main_subset_matrix=main_kernel->get_kernel_matrix();
	main_kernel->remove_row_subset();
	CCustomKernel* main_subset_copy=new CCustomKernel(main_subset_matrix);
	SGMatrix<float64_t> main_subset_copy_matrix=main_subset_copy->get_kernel_matrix();
	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_EQ(main_subset_matrix(i, j), main_subset_copy_matrix(i, j));
	}

	SG_UNREF(main_subset_copy);
	SG_UNREF(gaussian);
	SG_UNREF(main_kernel);
	SG_UNREF(copy);
	SG_UNREF(gen);
}

//Generate the Data
void generate_data(SGMatrix<float64_t> &data)
{
	data(0,0)=0.044550005575722;
	data(1,0)=-0.433969606728583;
	data(2,0)=-0.397935396933392;
	data(0,1)=-0.778754072066602;
	data(1,1)=-0.620105076569903;
	data(2,1)=-0.542538248707627;
	data(0,2)=0.334313094513960;
	data(1,2)=0.421985645755003;
	data(2,2)=0.263031426076997;
	data(0,3)=0.516043376162584;
	data(1,3)=0.159041471773470;
	data(2,3)=0.691318725364356;
	data(0,4)=-0.116152404185664;
	data(1,4)=0.473047565770014;
	data(2,4)=-0.013876505800334;
}

TEST(CustomKernelTest,index_features_subset)
{
	float64_t epsilon=1e-7;
	index_t n=5;

	// Generate the features
	SGMatrix<float64_t> data(3,n);
	generate_data(data);
	CDenseFeatures<float64_t>* feats=new CDenseFeatures<float64_t>(data);
	SG_REF(feats);

	// Generate the Kernels
	CGaussianKernel* gaussian=new CGaussianKernel(feats, feats, 2, 10);
	SG_REF(gaussian);
	CCustomKernel* main_kernel=new CCustomKernel(gaussian);
	SG_REF(main_kernel);

	/* create custom kernel copy of gaussien and assert equalness */
	SGMatrix<float64_t> kmg=gaussian->get_kernel_matrix();
	SGMatrix<float64_t> km=main_kernel->get_kernel_matrix();

	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_NEAR(kmg(i, j), km(i, j), epsilon);
	}

	/* add a subset to the custom kernel, create copy, create another kernel
	 * from this, assert equalness */
	SGVector<index_t> r_idx(n);
	SGVector<index_t> c_idx(n);
	r_idx.range_fill();
	r_idx.permute();
	c_idx.range_fill();
	c_idx.permute();

	/* Create IndexFeatures instances */
	CIndexFeatures * feat_r_idx = new CIndexFeatures(r_idx);
	CIndexFeatures * feat_c_idx = new CIndexFeatures(c_idx);
	SG_REF(feat_r_idx);
	SG_REF(feat_c_idx);

	main_kernel->init(feat_r_idx,feat_c_idx);
	SGMatrix<float64_t> main_subset_matrix = main_kernel->get_kernel_matrix();

	for (index_t i=0; i<n; ++i)
	{
		for (index_t j=0; j<n; ++j)
			EXPECT_NEAR(main_subset_matrix(i, j), kmg(r_idx[i], c_idx[j]), epsilon);
	}

	SG_UNREF(gaussian);
	SG_UNREF(main_kernel);
	SG_UNREF(feats);
	SG_UNREF(feat_r_idx);
	SG_UNREF(feat_c_idx);
}
<|endoftext|>


<commit_before>#include <sch/S_Object/S_Cone.h>

using namespace sch;

S_Cone::S_Cone(const Scalar& angle, const Scalar &  height)

{
  if (fabs(angle) >= M_PI/2)
  {
    throw std::domain_error("Ivalig angle for a cone. It should be < M_PI/2");
  }

  angle_=fabs(angle);
  height_=fabs(angle);
  angleTan_=tan(angle_);
  baseRadius_=height_*angleTan_;

  slices_ = 100;
  stacks_ = 4; /// we don't need many stacks to display a cone
}

S_Cone::~S_Cone(void)
{
}

Point3 S_Cone::l_Support(const Vector3& v, int& /*lastFeature*/)const
{
  Scalar norm = sqrt(v[0] * v[0] + v[1] * v[1]);
  if (norm < sch::epsilon)
  {
    if (v[2] >= 0)
    {
      return Point3(0., 0., height_);
    }
    else
    {
      return Point3(0., 0., 0.);
    }
  }
  else
  {
    if ( v[2] < - angleTan_ * norm)
    {
      return Point3(0., 0., 0.);
    }
    else
    {
      Scalar normInverse = 1 / norm;
      return Point3(normInverse * v[0]*baseRadius_, normInverse * v[1]*baseRadius_, height_);
    }
  }

}

S_Object::S_ObjectType S_Cone::getType() const
{
  return S_Object::TCone;
}

Scalar S_Cone::getAngle() const
{
  return angle_;
}

Scalar S_Cone::getHeight() const
{
  return height_;
}
<commit_msg>Fix copy paste error<commit_after>#include <sch/S_Object/S_Cone.h>

using namespace sch;

S_Cone::S_Cone(const Scalar& angle, const Scalar &  height)

{
  if (fabs(angle) >= M_PI/2)
  {
    throw std::domain_error("Invalid angle for a cone. It should be < M_PI/2");
  }

  angle_=fabs(angle);
  height_=fabs(height);
  angleTan_=tan(angle_);
  baseRadius_=height_*angleTan_;

  slices_ = 100;
  stacks_ = 4; /// we don't need many stacks to display a cone
}

S_Cone::~S_Cone(void)
{
}

Point3 S_Cone::l_Support(const Vector3& v, int& /*lastFeature*/)const
{
  Scalar norm = sqrt(v[0] * v[0] + v[1] * v[1]);
  if (norm < sch::epsilon)
  {
    if (v[2] >= 0)
    {
      return Point3(0., 0., height_);
    }
    else
    {
      return Point3(0., 0., 0.);
    }
  }
  else
  {
    if ( v[2] < - angleTan_ * norm)
    {
      return Point3(0., 0., 0.);
    }
    else
    {
      Scalar normInverse = 1 / norm;
      return Point3(normInverse * v[0]*baseRadius_, normInverse * v[1]*baseRadius_, height_);
    }
  }

}

S_Object::S_ObjectType S_Cone::getType() const
{
  return S_Object::TCone;
}

Scalar S_Cone::getAngle() const
{
  return angle_;
}

Scalar S_Cone::getHeight() const
{
  return height_;
}
<|endoftext|>


<commit_before>//Author: Stefan Toman

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

using namespace std;

int main() {
	int t;
	scanf("%d", &t);
	for (int i = 0; i < t; ++i) {
        long long n1, n2, m;
		scanf("%I64d %I64d %I64d", &n1, &n2, &m);
		long long stones = m*(m+1)/2;
		printf("%I64d\n", n1 + n2 - 2*min(min(n1, n2), stones));
	}
	return 0;
}
<commit_msg>fix problem chefandthestones<commit_after>//Author: Stefan Toman

#include <iostream>
#include <string.h>
#include <algorithm>

using namespace std;

int main() {
	int t;
	cin >> t;
	for (int i = 0; i < t; ++i) {
        long long n1, n2, m;
		cin >> n1 >> n2 >> m;
		long long stones = m*(m+1)/2;
		cout << n1 + n2 - 2*min(min(n1, n2), stones) << endl;
	}
	return 0;
}
<|endoftext|>


<commit_before>//===-- TargetAsmInfo.cpp - Asm Info ---------------------------------------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target asm properties related what form asm statements
// should take.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include <cctype>
#include <cstring>
using namespace llvm;

TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm)
  : TM(tm)
{
  BSSSection = "\t.bss";
  BSSSection_ = 0;
  ReadOnlySection = 0;
  TLSDataSection = 0;
  TLSBSSSection = 0;
  ZeroFillDirective = 0;
  NonexecutableStackDirective = 0;
  NeedsSet = false;
  MaxInstLength = 4;
  PCSymbol = "$";
  SeparatorChar = ';';
  CommentColumn = 60;
  CommentString = "#";
  FirstOperandColumn = 0;
  MaxOperandLength = 0;
  GlobalPrefix = "";
  PrivateGlobalPrefix = ".";
  LinkerPrivateGlobalPrefix = "";
  JumpTableSpecialLabelPrefix = 0;
  GlobalVarAddrPrefix = "";
  GlobalVarAddrSuffix = "";
  FunctionAddrPrefix = "";
  FunctionAddrSuffix = "";
  PersonalityPrefix = "";
  PersonalitySuffix = "";
  NeedsIndirectEncoding = false;
  InlineAsmStart = "#APP";
  InlineAsmEnd = "#NO_APP";
  AssemblerDialect = 0;
  AllowQuotesInName = false;
  ZeroDirective = "\t.zero\t";
  ZeroDirectiveSuffix = 0;
  AsciiDirective = "\t.ascii\t";
  AscizDirective = "\t.asciz\t";
  Data8bitsDirective = "\t.byte\t";
  Data16bitsDirective = "\t.short\t";
  Data32bitsDirective = "\t.long\t";
  Data64bitsDirective = "\t.quad\t";
  AlignDirective = "\t.align\t";
  AlignmentIsInBytes = true;
  TextAlignFillValue = 0;
  SwitchToSectionDirective = "\t.section\t";
  TextSectionStartSuffix = "";
  DataSectionStartSuffix = "";
  SectionEndDirectiveSuffix = 0;
  ConstantPoolSection = "\t.section .rodata";
  JumpTableDataSection = "\t.section .rodata";
  JumpTableDirective = 0;
  CStringSection = 0;
  CStringSection_ = 0;
  // FIXME: Flags are ELFish - replace with normal section stuff.
  StaticCtorsSection = "\t.section .ctors,\"aw\",@progbits";
  StaticDtorsSection = "\t.section .dtors,\"aw\",@progbits";
  GlobalDirective = "\t.globl\t";
  SetDirective = 0;
  LCOMMDirective = 0;
  COMMDirective = "\t.comm\t";
  COMMDirectiveTakesAlignment = true;
  HasDotTypeDotSizeDirective = true;
  HasSingleParameterDotFile = true;
  UsedDirective = 0;
  WeakRefDirective = 0;
  WeakDefDirective = 0;
  // FIXME: These are ELFish - move to ELFTAI.
  HiddenDirective = "\t.hidden\t";
  ProtectedDirective = "\t.protected\t";
  AbsoluteDebugSectionOffsets = false;
  AbsoluteEHSectionOffsets = false;
  HasLEB128 = false;
  HasDotLocAndDotFile = false;
  SupportsDebugInformation = false;
  SupportsExceptionHandling = false;
  DwarfRequiresFrameSection = true;
  DwarfUsesInlineInfoSection = false;
  Is_EHSymbolPrivate = true;
  GlobalEHDirective = 0;
  SupportsWeakOmittedEHFrame = true;
  DwarfSectionOffsetDirective = 0;
  DwarfAbbrevSection = ".debug_abbrev";
  DwarfInfoSection = ".debug_info";
  DwarfLineSection = ".debug_line";
  DwarfFrameSection = ".debug_frame";
  DwarfPubNamesSection = ".debug_pubnames";
  DwarfPubTypesSection = ".debug_pubtypes";
  DwarfDebugInlineSection = ".debug_inlined";
  DwarfStrSection = ".debug_str";
  DwarfLocSection = ".debug_loc";
  DwarfARangesSection = ".debug_aranges";
  DwarfRangesSection = ".debug_ranges";
  DwarfMacroInfoSection = ".debug_macinfo";
  DwarfEHFrameSection = ".eh_frame";
  DwarfExceptionSection = ".gcc_except_table";
  AsmTransCBE = 0;
  TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
  DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable);
}

TargetAsmInfo::~TargetAsmInfo() {
}

/// Measure the specified inline asm to determine an approximation of its
/// length.
/// Comments (which run till the next SeparatorChar or newline) do not
/// count as an instruction.
/// Any other non-whitespace text is considered an instruction, with
/// multiple instructions separated by SeparatorChar or newlines.
/// Variable-length instructions are not handled here; this function
/// may be overloaded in the target code to do that.
unsigned TargetAsmInfo::getInlineAsmLength(const char *Str) const {
  // Count the number of instructions in the asm.
  bool atInsnStart = true;
  unsigned Length = 0;
  for (; *Str; ++Str) {
    if (*Str == '\n' || *Str == SeparatorChar)
      atInsnStart = true;
    if (atInsnStart && !isspace(*Str)) {
      Length += MaxInstLength;
      atInsnStart = false;
    }
    if (atInsnStart && strncmp(Str, CommentString, strlen(CommentString))==0)
      atInsnStart = false;
  }

  return Length;
}

unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
                                              bool Global) const {
  return dwarf::DW_EH_PE_absptr;
}

static bool isSuitableForBSS(const GlobalVariable *GV) {
  if (!GV->hasInitializer())
    return true;

  // Leave constant zeros in readonly constant sections, so they can be shared
  Constant *C = GV->getInitializer();
  return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
}

static bool isConstantString(const Constant *C) {
  // First check: is we have constant array of i8 terminated with zero
  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
  // Check, if initializer is a null-terminated string
  if (CVA && CVA->isCString())
    return true;

  // Another possibility: [1 x i8] zeroinitializer
  if (isa<ConstantAggregateZero>(C)) {
    if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType())) {
      return (Ty->getElementType() == Type::Int8Ty &&
              Ty->getNumElements() == 1);
    }
  }

  return false;
}

SectionKind::Kind
TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
  // Early exit - functions should be always in text sections.
  if (isa<Function>(GV))
    return SectionKind::Text;

  const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV);
  bool isThreadLocal = GVar->isThreadLocal();
  assert(GVar && "Invalid global value for section selection");

  if (isSuitableForBSS(GVar)) {
    // Variable can be easily put to BSS section.
    return isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS;
  } else if (GVar->isConstant() && !isThreadLocal) {
    // Now we know, that variable has initializer and it is constant. We need to
    // check its initializer to decide, which section to output it into. Also
    // note, there is no thread-local r/o section.
    Constant *C = GVar->getInitializer();
    if (C->getRelocationInfo() != 0) {
      // Decide whether it is still possible to put symbol into r/o section.
      if (TM.getRelocationModel() != Reloc::Static)
        return SectionKind::Data;
      else
        return SectionKind::ROData;
    } else {
      // Check, if initializer is a null-terminated string
      if (isConstantString(C))
        return SectionKind::RODataMergeStr;
      else
        return SectionKind::RODataMergeConst;
    }
  }

  // Variable either is not constant or thread-local - output to data section.
  return isThreadLocal ? SectionKind::ThreadData : SectionKind::Data;
}

unsigned
TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
                                     const char* Name) const {
  unsigned Flags = SectionFlags::None;

  // Decode flags from global itself.
  if (GV) {
    SectionKind::Kind Kind = SectionKindForGlobal(GV);
    switch (Kind) {
    case SectionKind::Text:
      Flags |= SectionFlags::Code;
      break;
    case SectionKind::ThreadData:
    case SectionKind::ThreadBSS:
      Flags |= SectionFlags::TLS;
      // FALLS THROUGH
    case SectionKind::Data:
    case SectionKind::DataRel:
    case SectionKind::DataRelLocal:
    case SectionKind::DataRelRO:
    case SectionKind::DataRelROLocal:
    case SectionKind::BSS:
      Flags |= SectionFlags::Writeable;
      break;
    case SectionKind::ROData:
    case SectionKind::RODataMergeStr:
    case SectionKind::RODataMergeConst:
      // No additional flags here
      break;
    default:
      llvm_unreachable("Unexpected section kind!");
    }

    if (GV->isWeakForLinker())
      Flags |= SectionFlags::Linkonce;
  }

  // Add flags from sections, if any.
  if (Name && *Name) {
    Flags |= SectionFlags::Named;

    // Some lame default implementation based on some magic section names.
    if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
        strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
        strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
        strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
      Flags |= SectionFlags::BSS;
    else if (strcmp(Name, ".tdata") == 0 ||
             strncmp(Name, ".tdata.", 7) == 0 ||
             strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
             strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
      Flags |= SectionFlags::TLS;
    else if (strcmp(Name, ".tbss") == 0 ||
             strncmp(Name, ".tbss.", 6) == 0 ||
             strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
             strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
      Flags |= SectionFlags::BSS | SectionFlags::TLS;
  }

  return Flags;
}

const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
  // Select section name
  if (GV->hasSection()) {
    // Honour section already set, if any.
    unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str());
    return getNamedSection(GV->getSection().c_str(), Flags);
  }

  // If this global is linkonce/weak and the target handles this by emitting it
  // into a 'uniqued' section name, create and return the section now.
  if (GV->isWeakForLinker()) {
    if (const char *Prefix =
          getSectionPrefixForUniqueGlobal(SectionKindForGlobal(GV))) {
      // FIXME: Use mangler interface (PR4584).
      std::string Name = Prefix+GV->getName();
      unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str());
      return getNamedSection(Name.c_str(), Flags);
    }
  }

  // Use default section depending on the 'type' of global
  return SelectSectionForGlobal(GV);
}

// Lame default implementation. Calculate the section name for global.
const Section*
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
  SectionKind::Kind Kind = SectionKindForGlobal(GV);

  if (Kind == SectionKind::Text)
    return getTextSection();

  if (isBSS(Kind))
    if (const Section *S = getBSSSection_())
      return S;

  if (SectionKind::isReadOnly(Kind))
    if (const Section *S = getReadOnlySection())
      return S;

  return getDataSection();
}

/// getSectionForMergableConstant - Given a mergable constant with the
/// specified size and relocation information, return a section that it
/// should be placed in.
const Section *
TargetAsmInfo::getSectionForMergableConstant(uint64_t Size,
                                             unsigned ReloInfo) const {
  // FIXME: Support data.rel stuff someday
  // Lame default implementation. Calculate the section name for machine const.
  return getDataSection();
}

const char *
TargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
  switch (Kind) {
  default: llvm_unreachable("Unknown section kind");
  case SectionKind::Text:             return ".gnu.linkonce.t.";
  case SectionKind::Data:             return ".gnu.linkonce.d.";
  case SectionKind::DataRel:          return ".gnu.linkonce.d.rel.";
  case SectionKind::DataRelLocal:     return ".gnu.linkonce.d.rel.local.";
  case SectionKind::DataRelRO:        return ".gnu.linkonce.d.rel.ro.";
  case SectionKind::DataRelROLocal:   return ".gnu.linkonce.d.rel.ro.local.";
  case SectionKind::BSS:              return ".gnu.linkonce.b.";
  case SectionKind::ROData:
  case SectionKind::RODataMergeConst:
  case SectionKind::RODataMergeStr:   return ".gnu.linkonce.r.";
  case SectionKind::ThreadData:       return ".gnu.linkonce.td.";
  case SectionKind::ThreadBSS:        return ".gnu.linkonce.tb.";
  }
}

const Section *TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags,
                                              bool Override) const {
  Section &S = Sections[Name];

  // This is newly-created section, set it up properly.
  if (S.Flags == SectionFlags::Invalid || Override) {
    S.Flags = Flags | SectionFlags::Named;
    S.Name = Name;
  }

  return &S;
}

const Section*
TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags,
                                 bool Override) const {
  Section& S = Sections[Directive];

  // This is newly-created section, set it up properly.
  if (S.Flags == SectionFlags::Invalid || Override) {
    S.Flags = Flags & ~SectionFlags::Named;
    S.Name = Directive;
  }

  return &S;
}

const std::string&
TargetAsmInfo::getSectionFlags(unsigned Flags) const {
  SectionFlags::FlagsStringsMapType::iterator I = FlagsStrings.find(Flags);

  // We didn't print these flags yet, print and save them to map. This reduces
  // amount of heap trashing due to std::string construction / concatenation.
  if (I == FlagsStrings.end())
    I = FlagsStrings.insert(std::make_pair(Flags,
                                           printSectionFlags(Flags))).first;

  return I->second;
}

unsigned TargetAsmInfo::getULEB128Size(unsigned Value) {
  unsigned Size = 0;
  do {
    Value >>= 7;
    Size += sizeof(int8_t);
  } while (Value);
  return Size;
}

unsigned TargetAsmInfo::getSLEB128Size(int Value) {
  unsigned Size = 0;
  int Sign = Value >> (8 * sizeof(Value) - 1);
  bool IsMore;

  do {
    unsigned Byte = Value & 0x7f;
    Value >>= 7;
    IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
    Size += sizeof(int8_t);
  } while (IsMore);
  return Size;
}
<commit_msg>Another getName -> getNameStr<commit_after>//===-- TargetAsmInfo.cpp - Asm Info ---------------------------------------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target asm properties related what form asm statements
// should take.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include <cctype>
#include <cstring>
using namespace llvm;

TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm)
  : TM(tm)
{
  BSSSection = "\t.bss";
  BSSSection_ = 0;
  ReadOnlySection = 0;
  TLSDataSection = 0;
  TLSBSSSection = 0;
  ZeroFillDirective = 0;
  NonexecutableStackDirective = 0;
  NeedsSet = false;
  MaxInstLength = 4;
  PCSymbol = "$";
  SeparatorChar = ';';
  CommentColumn = 60;
  CommentString = "#";
  FirstOperandColumn = 0;
  MaxOperandLength = 0;
  GlobalPrefix = "";
  PrivateGlobalPrefix = ".";
  LinkerPrivateGlobalPrefix = "";
  JumpTableSpecialLabelPrefix = 0;
  GlobalVarAddrPrefix = "";
  GlobalVarAddrSuffix = "";
  FunctionAddrPrefix = "";
  FunctionAddrSuffix = "";
  PersonalityPrefix = "";
  PersonalitySuffix = "";
  NeedsIndirectEncoding = false;
  InlineAsmStart = "#APP";
  InlineAsmEnd = "#NO_APP";
  AssemblerDialect = 0;
  AllowQuotesInName = false;
  ZeroDirective = "\t.zero\t";
  ZeroDirectiveSuffix = 0;
  AsciiDirective = "\t.ascii\t";
  AscizDirective = "\t.asciz\t";
  Data8bitsDirective = "\t.byte\t";
  Data16bitsDirective = "\t.short\t";
  Data32bitsDirective = "\t.long\t";
  Data64bitsDirective = "\t.quad\t";
  AlignDirective = "\t.align\t";
  AlignmentIsInBytes = true;
  TextAlignFillValue = 0;
  SwitchToSectionDirective = "\t.section\t";
  TextSectionStartSuffix = "";
  DataSectionStartSuffix = "";
  SectionEndDirectiveSuffix = 0;
  ConstantPoolSection = "\t.section .rodata";
  JumpTableDataSection = "\t.section .rodata";
  JumpTableDirective = 0;
  CStringSection = 0;
  CStringSection_ = 0;
  // FIXME: Flags are ELFish - replace with normal section stuff.
  StaticCtorsSection = "\t.section .ctors,\"aw\",@progbits";
  StaticDtorsSection = "\t.section .dtors,\"aw\",@progbits";
  GlobalDirective = "\t.globl\t";
  SetDirective = 0;
  LCOMMDirective = 0;
  COMMDirective = "\t.comm\t";
  COMMDirectiveTakesAlignment = true;
  HasDotTypeDotSizeDirective = true;
  HasSingleParameterDotFile = true;
  UsedDirective = 0;
  WeakRefDirective = 0;
  WeakDefDirective = 0;
  // FIXME: These are ELFish - move to ELFTAI.
  HiddenDirective = "\t.hidden\t";
  ProtectedDirective = "\t.protected\t";
  AbsoluteDebugSectionOffsets = false;
  AbsoluteEHSectionOffsets = false;
  HasLEB128 = false;
  HasDotLocAndDotFile = false;
  SupportsDebugInformation = false;
  SupportsExceptionHandling = false;
  DwarfRequiresFrameSection = true;
  DwarfUsesInlineInfoSection = false;
  Is_EHSymbolPrivate = true;
  GlobalEHDirective = 0;
  SupportsWeakOmittedEHFrame = true;
  DwarfSectionOffsetDirective = 0;
  DwarfAbbrevSection = ".debug_abbrev";
  DwarfInfoSection = ".debug_info";
  DwarfLineSection = ".debug_line";
  DwarfFrameSection = ".debug_frame";
  DwarfPubNamesSection = ".debug_pubnames";
  DwarfPubTypesSection = ".debug_pubtypes";
  DwarfDebugInlineSection = ".debug_inlined";
  DwarfStrSection = ".debug_str";
  DwarfLocSection = ".debug_loc";
  DwarfARangesSection = ".debug_aranges";
  DwarfRangesSection = ".debug_ranges";
  DwarfMacroInfoSection = ".debug_macinfo";
  DwarfEHFrameSection = ".eh_frame";
  DwarfExceptionSection = ".gcc_except_table";
  AsmTransCBE = 0;
  TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
  DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable);
}

TargetAsmInfo::~TargetAsmInfo() {
}

/// Measure the specified inline asm to determine an approximation of its
/// length.
/// Comments (which run till the next SeparatorChar or newline) do not
/// count as an instruction.
/// Any other non-whitespace text is considered an instruction, with
/// multiple instructions separated by SeparatorChar or newlines.
/// Variable-length instructions are not handled here; this function
/// may be overloaded in the target code to do that.
unsigned TargetAsmInfo::getInlineAsmLength(const char *Str) const {
  // Count the number of instructions in the asm.
  bool atInsnStart = true;
  unsigned Length = 0;
  for (; *Str; ++Str) {
    if (*Str == '\n' || *Str == SeparatorChar)
      atInsnStart = true;
    if (atInsnStart && !isspace(*Str)) {
      Length += MaxInstLength;
      atInsnStart = false;
    }
    if (atInsnStart && strncmp(Str, CommentString, strlen(CommentString))==0)
      atInsnStart = false;
  }

  return Length;
}

unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
                                              bool Global) const {
  return dwarf::DW_EH_PE_absptr;
}

static bool isSuitableForBSS(const GlobalVariable *GV) {
  if (!GV->hasInitializer())
    return true;

  // Leave constant zeros in readonly constant sections, so they can be shared
  Constant *C = GV->getInitializer();
  return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
}

static bool isConstantString(const Constant *C) {
  // First check: is we have constant array of i8 terminated with zero
  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
  // Check, if initializer is a null-terminated string
  if (CVA && CVA->isCString())
    return true;

  // Another possibility: [1 x i8] zeroinitializer
  if (isa<ConstantAggregateZero>(C)) {
    if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType())) {
      return (Ty->getElementType() == Type::Int8Ty &&
              Ty->getNumElements() == 1);
    }
  }

  return false;
}

SectionKind::Kind
TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
  // Early exit - functions should be always in text sections.
  if (isa<Function>(GV))
    return SectionKind::Text;

  const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV);
  bool isThreadLocal = GVar->isThreadLocal();
  assert(GVar && "Invalid global value for section selection");

  if (isSuitableForBSS(GVar)) {
    // Variable can be easily put to BSS section.
    return isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS;
  } else if (GVar->isConstant() && !isThreadLocal) {
    // Now we know, that variable has initializer and it is constant. We need to
    // check its initializer to decide, which section to output it into. Also
    // note, there is no thread-local r/o section.
    Constant *C = GVar->getInitializer();
    if (C->getRelocationInfo() != 0) {
      // Decide whether it is still possible to put symbol into r/o section.
      if (TM.getRelocationModel() != Reloc::Static)
        return SectionKind::Data;
      else
        return SectionKind::ROData;
    } else {
      // Check, if initializer is a null-terminated string
      if (isConstantString(C))
        return SectionKind::RODataMergeStr;
      else
        return SectionKind::RODataMergeConst;
    }
  }

  // Variable either is not constant or thread-local - output to data section.
  return isThreadLocal ? SectionKind::ThreadData : SectionKind::Data;
}

unsigned
TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
                                     const char* Name) const {
  unsigned Flags = SectionFlags::None;

  // Decode flags from global itself.
  if (GV) {
    SectionKind::Kind Kind = SectionKindForGlobal(GV);
    switch (Kind) {
    case SectionKind::Text:
      Flags |= SectionFlags::Code;
      break;
    case SectionKind::ThreadData:
    case SectionKind::ThreadBSS:
      Flags |= SectionFlags::TLS;
      // FALLS THROUGH
    case SectionKind::Data:
    case SectionKind::DataRel:
    case SectionKind::DataRelLocal:
    case SectionKind::DataRelRO:
    case SectionKind::DataRelROLocal:
    case SectionKind::BSS:
      Flags |= SectionFlags::Writeable;
      break;
    case SectionKind::ROData:
    case SectionKind::RODataMergeStr:
    case SectionKind::RODataMergeConst:
      // No additional flags here
      break;
    default:
      llvm_unreachable("Unexpected section kind!");
    }

    if (GV->isWeakForLinker())
      Flags |= SectionFlags::Linkonce;
  }

  // Add flags from sections, if any.
  if (Name && *Name) {
    Flags |= SectionFlags::Named;

    // Some lame default implementation based on some magic section names.
    if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
        strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
        strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
        strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
      Flags |= SectionFlags::BSS;
    else if (strcmp(Name, ".tdata") == 0 ||
             strncmp(Name, ".tdata.", 7) == 0 ||
             strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
             strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
      Flags |= SectionFlags::TLS;
    else if (strcmp(Name, ".tbss") == 0 ||
             strncmp(Name, ".tbss.", 6) == 0 ||
             strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
             strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
      Flags |= SectionFlags::BSS | SectionFlags::TLS;
  }

  return Flags;
}

const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
  // Select section name
  if (GV->hasSection()) {
    // Honour section already set, if any.
    unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str());
    return getNamedSection(GV->getSection().c_str(), Flags);
  }

  // If this global is linkonce/weak and the target handles this by emitting it
  // into a 'uniqued' section name, create and return the section now.
  if (GV->isWeakForLinker()) {
    if (const char *Prefix =
          getSectionPrefixForUniqueGlobal(SectionKindForGlobal(GV))) {
      // FIXME: Use mangler interface (PR4584).
      std::string Name = Prefix+GV->getNameStr();
      unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str());
      return getNamedSection(Name.c_str(), Flags);
    }
  }

  // Use default section depending on the 'type' of global
  return SelectSectionForGlobal(GV);
}

// Lame default implementation. Calculate the section name for global.
const Section*
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
  SectionKind::Kind Kind = SectionKindForGlobal(GV);

  if (Kind == SectionKind::Text)
    return getTextSection();

  if (isBSS(Kind))
    if (const Section *S = getBSSSection_())
      return S;

  if (SectionKind::isReadOnly(Kind))
    if (const Section *S = getReadOnlySection())
      return S;

  return getDataSection();
}

/// getSectionForMergableConstant - Given a mergable constant with the
/// specified size and relocation information, return a section that it
/// should be placed in.
const Section *
TargetAsmInfo::getSectionForMergableConstant(uint64_t Size,
                                             unsigned ReloInfo) const {
  // FIXME: Support data.rel stuff someday
  // Lame default implementation. Calculate the section name for machine const.
  return getDataSection();
}

const char *
TargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
  switch (Kind) {
  default: llvm_unreachable("Unknown section kind");
  case SectionKind::Text:             return ".gnu.linkonce.t.";
  case SectionKind::Data:             return ".gnu.linkonce.d.";
  case SectionKind::DataRel:          return ".gnu.linkonce.d.rel.";
  case SectionKind::DataRelLocal:     return ".gnu.linkonce.d.rel.local.";
  case SectionKind::DataRelRO:        return ".gnu.linkonce.d.rel.ro.";
  case SectionKind::DataRelROLocal:   return ".gnu.linkonce.d.rel.ro.local.";
  case SectionKind::BSS:              return ".gnu.linkonce.b.";
  case SectionKind::ROData:
  case SectionKind::RODataMergeConst:
  case SectionKind::RODataMergeStr:   return ".gnu.linkonce.r.";
  case SectionKind::ThreadData:       return ".gnu.linkonce.td.";
  case SectionKind::ThreadBSS:        return ".gnu.linkonce.tb.";
  }
}

const Section *TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags,
                                              bool Override) const {
  Section &S = Sections[Name];

  // This is newly-created section, set it up properly.
  if (S.Flags == SectionFlags::Invalid || Override) {
    S.Flags = Flags | SectionFlags::Named;
    S.Name = Name;
  }

  return &S;
}

const Section*
TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags,
                                 bool Override) const {
  Section& S = Sections[Directive];

  // This is newly-created section, set it up properly.
  if (S.Flags == SectionFlags::Invalid || Override) {
    S.Flags = Flags & ~SectionFlags::Named;
    S.Name = Directive;
  }

  return &S;
}

const std::string&
TargetAsmInfo::getSectionFlags(unsigned Flags) const {
  SectionFlags::FlagsStringsMapType::iterator I = FlagsStrings.find(Flags);

  // We didn't print these flags yet, print and save them to map. This reduces
  // amount of heap trashing due to std::string construction / concatenation.
  if (I == FlagsStrings.end())
    I = FlagsStrings.insert(std::make_pair(Flags,
                                           printSectionFlags(Flags))).first;

  return I->second;
}

unsigned TargetAsmInfo::getULEB128Size(unsigned Value) {
  unsigned Size = 0;
  do {
    Value >>= 7;
    Size += sizeof(int8_t);
  } while (Value);
  return Size;
}

unsigned TargetAsmInfo::getSLEB128Size(int Value) {
  unsigned Size = 0;
  int Sign = Value >> (8 * sizeof(Value) - 1);
  bool IsMore;

  do {
    unsigned Byte = Value & 0x7f;
    Value >>= 7;
    IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
    Size += sizeof(int8_t);
  } while (IsMore);
  return Size;
}
<|endoftext|>


<commit_before>//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements methods that make it really easy to deal with intrinsic
// functions.
//
// All intrinsic function calls are instances of the call instruction, so these
// are all subclasses of the CallInst class.  Note that none of these classes
// has state or virtual methods, which is an important part of this gross/neat
// hack working.
//
// In some cases, arguments to intrinsics need to be generic and are defined as
// type pointer to empty struct { }*.  To access the real item of interest the
// cast instruction needs to be stripped away.
//
//===----------------------------------------------------------------------===//

#include "llvm/IntrinsicInst.h"
#include "llvm/Constants.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
/// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
///

static Value *CastOperand(Value *C) {
  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
    if (CE->isCast())
      return CE->getOperand(0);
  return NULL;
}

Value *DbgInfoIntrinsic::StripCast(Value *C) {
  if (Value *CO = CastOperand(C)) {
    C = StripCast(CO);
  } else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
    if (GV->hasInitializer())
      if (Value *CO = CastOperand(GV->getInitializer()))
        C = StripCast(CO);
  }
  return dyn_cast<GlobalVariable>(C);
}

//===----------------------------------------------------------------------===//
/// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
///

Value *DbgDeclareInst::getAddress() const {
  if (MDNode* MD = cast_or_null<MDNode>(getOperand(1)))
    return MD->getOperand(0);
  else
    return NULL;
}

//===----------------------------------------------------------------------===//
/// DbgValueInst - This represents the llvm.dbg.value instruction.
///

const Value *DbgValueInst::getValue() const {
  return cast<MDNode>(getOperand(1))->getOperand(0);
}

Value *DbgValueInst::getValue() {
  return cast<MDNode>(getOperand(1))->getOperand(0);
}
<commit_msg>fix some pointless layering violations.<commit_after>//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements methods that make it really easy to deal with intrinsic
// functions.
//
// All intrinsic function calls are instances of the call instruction, so these
// are all subclasses of the CallInst class.  Note that none of these classes
// has state or virtual methods, which is an important part of this gross/neat
// hack working.
//
// In some cases, arguments to intrinsics need to be generic and are defined as
// type pointer to empty struct { }*.  To access the real item of interest the
// cast instruction needs to be stripped away.
//
//===----------------------------------------------------------------------===//

#include "llvm/IntrinsicInst.h"
#include "llvm/Constants.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Metadata.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
/// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
///

static Value *CastOperand(Value *C) {
  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
    if (CE->isCast())
      return CE->getOperand(0);
  return NULL;
}

Value *DbgInfoIntrinsic::StripCast(Value *C) {
  if (Value *CO = CastOperand(C)) {
    C = StripCast(CO);
  } else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
    if (GV->hasInitializer())
      if (Value *CO = CastOperand(GV->getInitializer()))
        C = StripCast(CO);
  }
  return dyn_cast<GlobalVariable>(C);
}

//===----------------------------------------------------------------------===//
/// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
///

Value *DbgDeclareInst::getAddress() const {
  if (MDNode* MD = cast_or_null<MDNode>(getOperand(1)))
    return MD->getOperand(0);
  else
    return NULL;
}

//===----------------------------------------------------------------------===//
/// DbgValueInst - This represents the llvm.dbg.value instruction.
///

const Value *DbgValueInst::getValue() const {
  return cast<MDNode>(getOperand(1))->getOperand(0);
}

Value *DbgValueInst::getValue() {
  return cast<MDNode>(getOperand(1))->getOperand(0);
}
<|endoftext|>