<commit_before>/*
 * Copyright 2009-2011 Red Hat, Inc.
 *
 * 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.
 */

// the implementation class for AviaryJob methods

// condor includes
#include "condor_common.h"
#include "condor_config.h"
#include "condor_attributes.h"

extern bool qmgmt_all_users_trusted;

// local includes
#include "AviaryJobServiceSkeleton.h"
#include <AviaryJob_RemoveJob.h>
#include <AviaryJob_RemoveJobResponse.h>
#include <AviaryJob_ReleaseJob.h>
#include <AviaryJob_ReleaseJobResponse.h>
#include <AviaryJob_SubmitJob.h>
#include <AviaryJob_SubmitJobResponse.h>
#include <AviaryJob_HoldJob.h>
#include <AviaryJob_HoldJobResponse.h>
#include <AviaryJob_SetJobAttribute.h>
#include <AviaryJob_SetJobAttributeResponse.h>
#include "Codec.h"
#include "SchedulerObject.h"

using namespace AviaryJob;
using namespace aviary::codec;
using namespace aviary::job;
using namespace compat_classad;

void
AviaryJobServiceSkeleton::checkForSchedulerID(AviaryCommon::JobID* _jobId, string& _text)
{
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
	if (!(_jobId->getPool() == schedulerObj->getPool()) ||
		!(_jobId->getScheduler() == schedulerObj->getName())) {
	_text = "WARNING: the pool and scheduler names of the requested jobid were empty or did not match this scheduler!";
	}
}

void
AviaryJobServiceSkeleton::buildBasicRequirements(ResourceConstraintVectorType* _constraints, string& _requirements) {
	// TODO: iterate through these and build TARGET.<constraint> like string
}

AviaryJob::SubmitJobResponse*
AviaryJobServiceSkeleton::submitJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::SubmitJob* _submitJob)
{
    AviaryJob::SubmitJobResponse* submitJobResponse = new AviaryJob::SubmitJobResponse();
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    AttributeMapType attrMap;

    // add the simple stuff first
    attrMap[ATTR_JOB_CMD] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getCmd().c_str());
    if (!(_submitJob->isArgsNil() || _submitJob->getArgs().empty())) {
        attrMap[ATTR_JOB_ARGUMENTS1] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getArgs().c_str());
    }
    attrMap[ATTR_OWNER] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getOwner().c_str());
    attrMap[ATTR_JOB_IWD] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getIwd().c_str());

    // build a requirements string and add to it
    string reqBuilder;
    if (!_submitJob->isRequirementsNil()) {
        // TODO: iterate through resource constraints
    }
    else {
        // default
        reqBuilder = "TRUE";
    }
    attrMap[ATTR_REQUIREMENTS] = new AviaryAttribute(AviaryAttribute::EXPR_TYPE, reqBuilder.c_str());
    // TODO: need to add extras attrs also

    // invoke submit
    string jobId, error;
    // TODO: temporary hack for testing
    // until ws-security or something gets turned on
    qmgmt_all_users_trusted = true;
    if (!schedulerObj->submit(attrMap,jobId, error)) {
        submitJobResponse->setStatus(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
    }
    else {
        // TODO: fix up args
        string submissionId = schedulerObj->getName();
		submissionId.append("#");
		submissionId.append(jobId);
        submitJobResponse->setId(new AviaryCommon::JobID(
				schedulerObj->getPool(),schedulerObj->getName(),jobId,
				new AviaryCommon::SubmissionID(submissionId,_submitJob->getOwner().c_str())));
        submitJobResponse->setStatus(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),""));
    }
    qmgmt_all_users_trusted = false;

    return submitJobResponse;
}

// TODO: would be nice to template these next 3
AviaryJob::HoldJobResponse*
AviaryJobServiceSkeleton::holdJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::HoldJob* _holdJob)
{
	AviaryJob::HoldJobResponse* holdJobResponse = new HoldJobResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _holdJob->getHoldJob()->getId();
	string reason = _holdJob->getHoldJob()->getReason();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->hold(cluster_proc,reason,error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject Hold failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	holdJobResponse->setHoldJobResponse(controlJobResponse);
    return holdJobResponse;
}

AviaryJob::ReleaseJobResponse*
AviaryJobServiceSkeleton::releaseJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::ReleaseJob* _releaseJob)
{
	AviaryJob::ReleaseJobResponse* releaseJobResponse = new ReleaseJobResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _releaseJob->getReleaseJob()->getId();
	string reason = _releaseJob->getReleaseJob()->getReason();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->release(cluster_proc,reason,error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject Release failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	releaseJobResponse->setReleaseJobResponse(controlJobResponse);
    return releaseJobResponse;
}

AviaryJob::RemoveJobResponse*
AviaryJobServiceSkeleton::removeJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::RemoveJob* _removeJob)
{
	AviaryJob::RemoveJobResponse* removeJobResponse = new RemoveJobResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _removeJob->getRemoveJob()->getId();
	string reason = _removeJob->getRemoveJob()->getReason();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->remove(cluster_proc,reason,error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject Remove failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	removeJobResponse->setRemoveJobResponse(controlJobResponse);
    return removeJobResponse;
}

AviaryJob::SetJobAttributeResponse*
AviaryJobServiceSkeleton::setJobAttribute(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::SetJobAttribute* _setJobAttribute)
{
	AviaryJob::SetJobAttributeResponse* setAttrResponse = new SetJobAttributeResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _setJobAttribute->getId();
	AviaryCommon::Attribute* attr = _setJobAttribute->getAttribute();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->setAttribute(cluster_proc,attr->getName(),attr->getValue(),error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject SetAttribute failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	setAttrResponse->setSetJobAttributeResponse(controlJobResponse);
    return setAttrResponse;
}
<commit_msg>Fixed a mixup of fields in the job id returned from the aviary schedd plugin submit method<commit_after>/*
 * Copyright 2009-2011 Red Hat, Inc.
 *
 * 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.
 */

// the implementation class for AviaryJob methods

// condor includes
#include "condor_common.h"
#include "condor_config.h"
#include "condor_attributes.h"

extern bool qmgmt_all_users_trusted;

// local includes
#include "AviaryJobServiceSkeleton.h"
#include <AviaryJob_RemoveJob.h>
#include <AviaryJob_RemoveJobResponse.h>
#include <AviaryJob_ReleaseJob.h>
#include <AviaryJob_ReleaseJobResponse.h>
#include <AviaryJob_SubmitJob.h>
#include <AviaryJob_SubmitJobResponse.h>
#include <AviaryJob_HoldJob.h>
#include <AviaryJob_HoldJobResponse.h>
#include <AviaryJob_SetJobAttribute.h>
#include <AviaryJob_SetJobAttributeResponse.h>
#include "Codec.h"
#include "SchedulerObject.h"
#include "stl_string_utils.h"

using namespace AviaryJob;
using namespace aviary::codec;
using namespace aviary::job;
using namespace compat_classad;

void
AviaryJobServiceSkeleton::checkForSchedulerID(AviaryCommon::JobID* _jobId, string& _text)
{
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
	if (!(_jobId->getPool() == schedulerObj->getPool()) ||
		!(_jobId->getScheduler() == schedulerObj->getName())) {
	_text = "WARNING: the pool and scheduler names of the requested jobid were empty or did not match this scheduler!";
	}
}

void
AviaryJobServiceSkeleton::buildBasicRequirements(ResourceConstraintVectorType* _constraints, string& _requirements) {
	// TODO: iterate through these and build TARGET.<constraint> like string
	//ResourceConstraintVectorType::const_iterator it = _constraints->front();
}

AviaryJob::SubmitJobResponse*
AviaryJobServiceSkeleton::submitJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::SubmitJob* _submitJob)
{
    AviaryJob::SubmitJobResponse* submitJobResponse = new AviaryJob::SubmitJobResponse();
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    AttributeMapType attrMap;

    // add the simple stuff first
    attrMap[ATTR_JOB_CMD] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getCmd().c_str());
    if (!(_submitJob->isArgsNil() || _submitJob->getArgs().empty())) {
        attrMap[ATTR_JOB_ARGUMENTS1] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getArgs().c_str());
    }
    attrMap[ATTR_OWNER] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getOwner().c_str());
    attrMap[ATTR_JOB_IWD] = new AviaryAttribute(AviaryAttribute::STRING_TYPE, _submitJob->getIwd().c_str());

    // build a requirements string and add to it
    string reqBuilder;
    if (!_submitJob->isRequirementsNil()) {
        // TODO: iterate through resource constraints
    //    buildBasicRequirements(_submitJob->getRequirements(), reqBuilder);
    }
    else {
        // default
        reqBuilder = "TRUE";
    }
    attrMap[ATTR_REQUIREMENTS] = new AviaryAttribute(AviaryAttribute::EXPR_TYPE, reqBuilder.c_str());
    // TODO: need to add extras attrs also

    // invoke submit
    string jobId, error;
    // TODO: temporary hack for testing
    // until ws-security or something gets turned on
    qmgmt_all_users_trusted = true;
    if (!schedulerObj->submit(attrMap,jobId, error)) {
        submitJobResponse->setStatus(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
    }
    else {
        // TODO: fix up args
        string submissionId = schedulerObj->getName();
		submissionId.append("#");
		submissionId.append(jobId);
        submitJobResponse->setId(new AviaryCommon::JobID(
				jobId,schedulerObj->getPool(),schedulerObj->getName(),
				new AviaryCommon::SubmissionID(submissionId,_submitJob->getOwner().c_str())));
        submitJobResponse->setStatus(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),""));
    }
    qmgmt_all_users_trusted = false;

    return submitJobResponse;
}

// TODO: would be nice to template these next 3
AviaryJob::HoldJobResponse*
AviaryJobServiceSkeleton::holdJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::HoldJob* _holdJob)
{
	AviaryJob::HoldJobResponse* holdJobResponse = new HoldJobResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _holdJob->getHoldJob()->getId();
	string reason = _holdJob->getHoldJob()->getReason();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->hold(cluster_proc,reason,error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject Hold failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	holdJobResponse->setHoldJobResponse(controlJobResponse);
    return holdJobResponse;
}

AviaryJob::ReleaseJobResponse*
AviaryJobServiceSkeleton::releaseJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::ReleaseJob* _releaseJob)
{
	AviaryJob::ReleaseJobResponse* releaseJobResponse = new ReleaseJobResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _releaseJob->getReleaseJob()->getId();
	string reason = _releaseJob->getReleaseJob()->getReason();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->release(cluster_proc,reason,error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject Release failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	releaseJobResponse->setReleaseJobResponse(controlJobResponse);
    return releaseJobResponse;
}

AviaryJob::RemoveJobResponse*
AviaryJobServiceSkeleton::removeJob(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::RemoveJob* _removeJob)
{
	AviaryJob::RemoveJobResponse* removeJobResponse = new RemoveJobResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _removeJob->getRemoveJob()->getId();
	string reason = _removeJob->getRemoveJob()->getReason();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->remove(cluster_proc,reason,error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject Remove failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	removeJobResponse->setRemoveJobResponse(controlJobResponse);
    return removeJobResponse;
}

AviaryJob::SetJobAttributeResponse*
AviaryJobServiceSkeleton::setJobAttribute(wso2wsf::MessageContext* /*outCtx*/ ,AviaryJob::SetJobAttribute* _setJobAttribute)
{
	AviaryJob::SetJobAttributeResponse* setAttrResponse = new SetJobAttributeResponse;
	SchedulerObject* schedulerObj = SchedulerObject::getInstance();
    string error;

	AviaryCommon::JobID* jobId = _setJobAttribute->getId();
	AviaryCommon::Attribute* attr = _setJobAttribute->getAttribute();
	string cluster_proc = jobId->getJob();
	ControlJobResponse* controlJobResponse = NULL;

	checkForSchedulerID(jobId, error);
	if (!schedulerObj->setAttribute(cluster_proc,attr->getName(),attr->getValue(),error)) {
		dprintf(D_FULLDEBUG, "SchedulerObject SetAttribute failed: %s\n", error.c_str());
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("FAIL"),error));
	}
	else {
		// in this case, error may hve been the result of the pool/schedd check
		controlJobResponse = new ControlJobResponse(new AviaryCommon::Status(new AviaryCommon::StatusCodeType("OK"),error));
	}

	setAttrResponse->setSetJobAttributeResponse(controlJobResponse);
    return setAttrResponse;
}
<|endoftext|>


<commit_before>#include <GLXW/glxw.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
//#include <glm/gtx/transform.hpp>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
//#include <GL/gl.h>

static const GLfloat g_vertex_buffer_data[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f,  1.0f, 0.0f,
};

void setWindowSizeCallback(GLFWwindow*, int width, int height) {
  glViewport(0, 0, width, height);
}

bool checkShaderCompileStatus(GLuint obj) {
  GLint status;
  glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
  if(status == GL_FALSE) {
    GLint length;
    glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &length);
    std::vector<char> log((unsigned long)length);
    glGetShaderInfoLog(obj, length, &length, &log[0]);
    std::cerr << &log[0];
    return true;
  }
  return false;
}

bool checkProgramLinkStatus(GLuint obj) {
  GLint status;
  glGetProgramiv(obj, GL_LINK_STATUS, &status);
  if(status == GL_FALSE) {
    GLint length;
    glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &length);
    std::vector<char> log((unsigned long)length);
    glGetProgramInfoLog(obj, length, &length, &log[0]);
    std::cerr << &log[0];
    return true;
  }
  return false;
}

GLuint prepareProgram(bool *errorFlagPtr) {
  *errorFlagPtr = false;

  std::string vertexShaderSource = ""
          "#version 330 core\n"
          "layout(location = 0) in vec3 vertexPosition_modelspace;\n"
          "void main(){\n"
          "  gl_Position.xyz = vertexPosition_modelspace;\n"
          "  gl_Position.w = 1.0;\n"
          "}";

  GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
  char const * vertexShaderSourcePtr = vertexShaderSource.c_str();
  glShaderSource(vertexShaderId, 1, &vertexShaderSourcePtr, nullptr);
  glCompileShader(vertexShaderId);

  *errorFlagPtr = checkShaderCompileStatus(vertexShaderId);
  if(*errorFlagPtr) return 0;

  std::string fragmentShaderSource = ""
          "#version 330 core\n"
          "out vec3 color;\n"
          "void main() { color = vec3(1,0,0); }\n";

  GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
  char const * fragmentShaderSourcePtr = fragmentShaderSource.c_str();
  glShaderSource(fragmentShaderId, 1, &fragmentShaderSourcePtr, nullptr);
  glCompileShader(fragmentShaderId);

  *errorFlagPtr = checkShaderCompileStatus(fragmentShaderId);
  if(*errorFlagPtr) return 0;

  GLuint programId = glCreateProgram();
  glAttachShader(programId, vertexShaderId);
  glAttachShader(programId, fragmentShaderId);
  glLinkProgram(programId);

  *errorFlagPtr = checkProgramLinkStatus(programId);
  if(*errorFlagPtr) return 0;

//  glDeleteShader(vertexShaderId);
//  glDeleteShader(fragmentShaderId);

  return programId;
}

void windowSizeCallback(GLFWwindow *, int width, int height) {
  glViewport(0, 0, width, height);
}

int main() {
  if(glfwInit() == GL_FALSE) {
    std::cerr << "Failed to initialize GLFW" << std::endl;
    return -1;
  }

  glfwDefaultWindowHints();

  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

  GLFWwindow* window = glfwCreateWindow(300, 300, "VAO and Shaders",
                                        nullptr, nullptr);
  if(window == nullptr) {
    std::cerr << "Failed to open GLFW window" << std::endl;
    glfwTerminate();
    return -1;
  }

  glfwMakeContextCurrent(window);

  if(glxwInit()) {
    std::cerr << "Failed to init GLXW" << std::endl;
    glfwDestroyWindow(window);
    glfwTerminate();
    return 1;
  }

  glfwSwapInterval(1);

  glfwSetWindowSizeCallback(window, windowSizeCallback);

  glfwShowWindow(window);

  glEnable(GL_DEPTH_TEST | GL_DOUBLEBUFFER);
  glDepthFunc(GL_LESS);

  glClearColor(0, 0, 0, 1);

//  glm::mat4 m = glm::perspective(45.0f, 4.0f / 3.0f, 1.0f, 100.0f);
//  glMatrixMode(GL_PROJECTION);
//  glLoadMatrixf(glm::value_ptr(m));

//  GLuint VertexArrayID;
//  glGenVertexArrays(1, &VertexArrayID);
//  glBindVertexArray(VertexArrayID);

  bool errorFlag;
  GLuint programId = prepareProgram(&errorFlag);
  if(errorFlag) {
    glfwDestroyWindow(window);
    glfwTerminate();
    return -1;
  }

  GLuint vbo; // vertexbuffer
  glGenBuffers(1, &vbo);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

  // vao and vbo handle
  GLuint vao;

  // generate and bind the vao
  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);

  while(glfwWindowShouldClose(window) == GL_FALSE) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programId);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(
            0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            0,                  // stride
            (void*)0            // array buffer offset
    );

    // Draw the triangle !
    glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

    glDisableVertexAttribArray(0);

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glfwDestroyWindow(window);
  glfwTerminate();
  return 0;
}<commit_msg>Minor changes<commit_after>#include <GLXW/glxw.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
//#include <glm/gtx/transform.hpp>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>

static const GLfloat globVertexBufferData[] = {
  -1.0f, -1.0f,  0.0f,
   1.0f, -1.0f,  0.0f,
   0.0f,  1.0f,  0.0f,
};

bool checkShaderCompileStatus(GLuint obj) {
  GLint status;
  glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
  if(status == GL_FALSE) {
    GLint length;
    glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &length);
    std::vector<char> log((unsigned long)length);
    glGetShaderInfoLog(obj, length, &length, &log[0]);
    std::cerr << &log[0];
    return true;
  }
  return false;
}

bool checkProgramLinkStatus(GLuint obj) {
  GLint status;
  glGetProgramiv(obj, GL_LINK_STATUS, &status);
  if(status == GL_FALSE) {
    GLint length;
    glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &length);
    std::vector<char> log((unsigned long)length);
    glGetProgramInfoLog(obj, length, &length, &log[0]);
    std::cerr << &log[0];
    return true;
  }
  return false;
}

GLuint prepareProgram(bool *errorFlagPtr) {
  *errorFlagPtr = false;

  std::string vertexShaderSource = ""
          "#version 330 core\n"
          "layout(location = 0) in vec3 vertexPosition_modelspace;\n"
          "void main(){\n"
          "  gl_Position.xyz = vertexPosition_modelspace;\n"
          "  gl_Position.w = 1.0;\n"
          "}";

  GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
  char const * vertexShaderSourcePtr = vertexShaderSource.c_str();
  glShaderSource(vertexShaderId, 1, &vertexShaderSourcePtr, nullptr);
  glCompileShader(vertexShaderId);

  *errorFlagPtr = checkShaderCompileStatus(vertexShaderId);
  if(*errorFlagPtr) return 0;

  std::string fragmentShaderSource = ""
          "#version 330 core\n"
          "out vec3 color;\n"
          "void main() { color = vec3(1,0,0); }\n";

  GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
  char const * fragmentShaderSourcePtr = fragmentShaderSource.c_str();
  glShaderSource(fragmentShaderId, 1, &fragmentShaderSourcePtr, nullptr);
  glCompileShader(fragmentShaderId);

  *errorFlagPtr = checkShaderCompileStatus(fragmentShaderId);
  if(*errorFlagPtr) return 0;

  GLuint programId = glCreateProgram();
  glAttachShader(programId, vertexShaderId);
  glAttachShader(programId, fragmentShaderId);
  glLinkProgram(programId);

  *errorFlagPtr = checkProgramLinkStatus(programId);
  if(*errorFlagPtr) return 0;

  glDeleteShader(vertexShaderId);
  glDeleteShader(fragmentShaderId);

  return programId;
}

void windowSizeCallback(GLFWwindow *, int width, int height) {
  glViewport(0, 0, width, height);
}

int main() {
  if(glfwInit() == GL_FALSE) {
    std::cerr << "Failed to initialize GLFW" << std::endl;
    return -1;
  }

  glfwDefaultWindowHints();

  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

  GLFWwindow* window = glfwCreateWindow(300, 300, "VAO and Shaders",
                                        nullptr, nullptr);
  if(window == nullptr) {
    std::cerr << "Failed to open GLFW window" << std::endl;
    glfwTerminate();
    return -1;
  }

  glfwMakeContextCurrent(window);

  if(glxwInit()) {
    std::cerr << "Failed to init GLXW" << std::endl;
    glfwDestroyWindow(window);
    glfwTerminate();
    return 1;
  }

  glfwSwapInterval(1);

  glfwSetWindowSizeCallback(window, windowSizeCallback);

  glfwShowWindow(window);

  glEnable(GL_DEPTH_TEST | GL_DOUBLEBUFFER);
  glDepthFunc(GL_LESS);

  glClearColor(0, 0, 0, 1);

//  glm::mat4 m = glm::perspective(45.0f, 4.0f / 3.0f, 1.0f, 100.0f);
//  glMatrixMode(GL_PROJECTION);
//  glLoadMatrixf(glm::value_ptr(m));

  bool errorFlag;
  GLuint programId = prepareProgram(&errorFlag);
  if(errorFlag) {
    glfwDestroyWindow(window);
    glfwTerminate();
    return -1;
  }

  GLuint vbo;
  glGenBuffers(1, &vbo);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(globVertexBufferData), globVertexBufferData, GL_STATIC_DRAW);

  GLuint vao;
  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);

  while(glfwWindowShouldClose(window) == GL_FALSE) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programId);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(
            0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            0,                  // stride
            nullptr             // array buffer offset
    );

    // Draw the triangle !
    glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

    glDisableVertexAttribArray(0);

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glDeleteVertexArrays(1, &vao);
  glDeleteBuffers(1, &vbo);

//  glDetachShader(shader_program, vertex_shader);
//  glDetachShader(shader_program, fragment_shader);
//  glDeleteShader(vertex_shader);
//  glDeleteShader(fragment_shader);

  glDeleteProgram(programId);

  glfwDestroyWindow(window);
  glfwTerminate();
  return 0;
}<|endoftext|>


<commit_before>acc14d82-2747-11e6-97ca-e0f84713e7b8<commit_msg>bug fix<commit_after>acd264de-2747-11e6-a475-e0f84713e7b8<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 INRA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <vle/dsde.hpp>
#include <vle/common.hpp>
#include <vle/mpi.hpp>
#include <vle/vle.hpp>
#include <chrono>
#include "defs.hpp"
#include "timer.hpp"
#include "models.hpp"
#include <cstdlib>
#include <unistd.h>

static void main_show_version()
{
    std::fprintf(stdout, "Echll_Benchmark version 0.0.0\n");

    std::exit(EXIT_SUCCESS);
}

static void main_show_help()
{
    std::fprintf(stdout, "Echll_Benchmark [-v][-h][-d real]\n"
                 "Options:\n"
                 "  -h          This help\n"
                 "  -v          Version of Echll_Benchmark\n"
                 "  -d integer  Assigning minimal duration to internal transition\n"
                 "              0 means, no duration\n"
                 "  -c integer  Assigning number of run by simulation\n"
                 "  -t integer  0: no thread\n"
                 "              1: using thread for root\n"
                 "              2: using thread for sub-coupled model\n"
                 "              3: all is threaded\n"
                 "  -q integer  Assigning a default level 0 = no verbose,\n"
                 "              3 = fill terminal mode\n"
                 "  -o file     Output results into output file `file'."
                 "              (Default is standard output)\n"
                 "  -s begin,duration Assign the begin and the duration of\n"
                 "              the simulation. Default 0,10\n"
                 "\n"
                 "Examples:\n"
                 "$ Echll_Benchmark -d 100 -c 42 -t 3 root.tgf\n"
                 " -> Launch root.tgf 42 times and 100ms in internal transition"
                 " of atomic models using a linpack mode. Each coupled model uses"
                 " a thread to parallelize DSDE's bags\n\n"
                 "$ Echll_Benchmark root.tgf\n"
                 " -> Launch root.tgf 1 time and using 100 ms in internal transition"
                 " of atomic models. Coupled models uses mono thread approach\n\n");

    std::exit(EXIT_SUCCESS);
}

struct main_parameter
{
    main_parameter() = default;

    double simulation_begin = 0.0;
    double simulation_duration = 10.0;
    long int duration = 100;
    long int counter = 1;
    int verbose_mode = 0;
    bool use_thread_root = false;
    bool use_thread_sub = false;
    FILE *output = stdout;

    void print(const vle::Context& ctx)
    {
        vle_info(ctx,
                 "Flags:\n"
                 "- simulation begin at: %f\n"
                 "- simulation duration: %f\n"
                 "- duration: %ld ms\n"
                 "- counter: %ld runs\n"
                 "- use threaded root: %d\n"
                 "- use threaded coupled: %d\n",
                 simulation_begin, simulation_duration,
                 duration, counter, use_thread_root, use_thread_sub);
    }

    ~main_parameter()
    {
        if (output && output != stdout)
            std::fclose(output);
    }
};

static main_parameter main_getopt(const vle::Context& ctx,
                                  int argc, char* argv[])
{
    main_parameter ret;
    int opt;

    while ((opt = ::getopt(argc, argv, "vhq:d:c:t:o:s:")) != -1) {
        switch (opt) {
        case 'v':
            main_show_version();
            break;
        case 'h':
            main_show_help();
            break;
        case 'q':
            {
                char *nptr;
                ret.verbose_mode = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr,
                                 "-q: Failed to convert %s into verbose mode"
                                 " (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (ret.verbose_mode < 0) {
                    std::fprintf(stderr, "-q: Can not assign negative verbose"
                                 " mode\n");
                    exit(EXIT_FAILURE);
                }
                break;
            }
            break;
        case 'd':
            {
                char *nptr;
                ret.duration = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr,
                                 "-d: Failed to convert %s into millisecond"
                                 " (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (ret.duration < 0) {
                    std::fprintf(stderr, "-d: Can not assign a negative duration\n");
                    exit(EXIT_FAILURE);
                }
                break;
            }
        case 'c':
            {
                char *nptr;
                ret.counter = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr, "-c: Failed to convert %s into"
                                 " a number (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (ret.counter <= 0) {
                    std::fprintf(stderr, "-c: Can not assign zero or a negative"
                                 " counter\n");
                    exit(EXIT_FAILURE);
                }
                break;
            }
        case 't':
            {
                char *nptr;
                int threadmode = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr, "-c: Failed to convert %s into"
                                 " a number (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (threadmode < 0 || threadmode > 3) {
                    std::fprintf(stderr, "-t: thread mode [0..3]\n");
                    exit(EXIT_FAILURE);
                }
                ret.use_thread_root = (threadmode == 1 || threadmode == 3);
                ret.use_thread_sub = (threadmode >= 2);
                break;
            }
            break;
        case 'o':
            {
                char *output = ::optarg;
                FILE *file = std::fopen(output, "w");
                if (!file) {
                    std::fprintf(stderr, "-o: Failed to open output file %s",
                                 output);
                    exit(EXIT_FAILURE);
                }

                ret.output = file;
                break;
            }
        case 's':
            {
                char *nptr;
                errno = 0;
                ret.simulation_begin = strtod(::optarg, &nptr);
                if (errno) {
                    std::fprintf(stderr, "-s: Failed to convert %s into"
                                 " two reals (double,double)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (nptr != NULL) {
                    if (*nptr != ',') {
                        std::fprintf(stderr, "-s: Failed to convert %s into "
                                     " two reals (double,double)\n", ::optarg);
                        exit(EXIT_FAILURE);
                    }
                    nptr++;
                    errno = 0;
                    ret.simulation_duration = strtod(nptr, &nptr);
                    if (errno) {
                        std::fprintf(stderr, "-s: Failed to convert %s into"
                                     " two reals (double, double)\n", ::optarg);
                        exit(EXIT_FAILURE);
                    }
                }

                if (ret.simulation_duration <= 0.0) {
                    std::fprintf(stderr, "-s: simulation duration must be a"
                                 " positive real not null\n");
                    exit(EXIT_FAILURE);
                }

                break;
            }
        }
    }

    if (::optind >= argc) {
        std::fprintf(stderr, "Expected argument after options\n");
        exit(EXIT_FAILURE);
    }

    ctx->set_user_data(ret.simulation_duration);

    return std::move(ret);
}

static vle::CommonPtr main_common_new(long int duration,
                                      std::shared_ptr <bench::Factory> factory)
{
    std::shared_ptr <vle::Common> ret = std::make_shared <vle::Common>();

    ret->emplace("duration", duration);
    ret->emplace("name", std::string("name"));
    ret->emplace("tgf-factory", factory);
    ret->emplace("tgf-source", (int)0);
    ret->emplace("tgf-format", (int)1);
    ret->emplace("tgf-filesource", std::string());

    return std::move(ret);
}

static std::shared_ptr <bench::Factory>
main_factory_new(const vle::Context& ctx,
                 const main_parameter& mp,
                 bool mpi_mode_and_root)
{
    std::shared_ptr <bench::Factory> ret = std::make_shared <bench::Factory>();

    typedef bench::Factory::modelptr modelptr;

    ret->functions.emplace("normal",
                           [&ctx]() -> modelptr
                           {
                               return modelptr(new bench::NormalPixel(ctx));
                           });
    ret->functions.emplace("top",
                           [&ctx]() -> modelptr
                           {
                               return modelptr(new bench::TopPixel(ctx));
                           });

    if (mpi_mode_and_root) {
        ret->functions.emplace("coupled",
                               [&ctx]() -> modelptr
                               {
                                   return modelptr(
                                       new bench::SynchronousProxyModel(ctx));
                               });
    } else {
        if (mp.use_thread_sub) {
            ret->functions.emplace("coupled",
                                   [&ctx]() -> modelptr
                                   {
                                       return modelptr(
                                           new bench::CoupledThread(ctx));
                                   });
        } else {
            ret->functions.emplace("coupled",
                                   [&ctx]() -> modelptr
                                   {
                                       return modelptr(
                                           new bench::CoupledMono(ctx));
                                   });
        }
    }

    return std::move(ret);
}

struct Sample
{
    struct result
    {
        double mean;
        double variance;
        double standard_deviation;
    };

    Sample(std::size_t nb)
        : sample(nb)
    {}

    Sample::result compute() const
    {
        Sample::result ret;

        ret.mean = std::accumulate(sample.cbegin(), sample.cend(), 0.0,
                                   [](double init, double duration)
                                   {
                                       return init + duration;
                                   }) / static_cast <double>(sample.size());

        ret.variance = std::accumulate(sample.cbegin(), sample.cend(), 0.0,
                                       [&ret](double init, double duration)
                                       {
                                           return init + std::pow(duration -
                                                                  ret.mean,
                                                                  2.0);
                                       }) / static_cast <double>(sample.size());

        ret.standard_deviation = std::sqrt(ret.variance);

        return std::move(ret);
    }

    std::vector <double> sample;
};

static int main_mono_mode(const vle::Context& ctx, int argc, char *argv[])
{
    main_parameter mp = main_getopt(ctx, argc, argv);

    vle_info(ctx, "No MPI mode activated\n");
    mp.print(ctx);

    std::shared_ptr <bench::Factory> factory = main_factory_new(ctx, mp, false);
    vle::CommonPtr common = main_common_new(mp.duration, factory);

    for (int i = ::optind; i < argc; ++i) {
        vle_info(ctx, "Run for %s\n", argv[i]);

        common->at("tgf-filesource") = std::string(argv[i]);

        double total_duration = 0.0;
        Sample sample(mp.counter);

        for (long int run = 0; run < mp.counter; ++run) {
            bench::DSDE dsde_engine(common);

            if (mp.use_thread_root) {             // TODO improve !
                bench::Timer timer(&sample.sample[run]);
                bench::RootThread root(ctx);
                vle::SimulationDbg <bench::DSDE> sim(ctx, dsde_engine, root);
                sim.run(mp.simulation_begin,
                        mp.simulation_duration + mp.simulation_begin);
            } else {
                bench::Timer timer(&sample.sample[run]);
                bench::RootMono root(ctx);
                vle::SimulationDbg <bench::DSDE> sim(ctx, dsde_engine, root);
                sim.run(mp.simulation_begin,
                        mp.simulation_duration + mp.simulation_begin);
            }

            if (sample.sample[run] < 0.0) {
                vle_info(ctx, "Simulation failure\n");
                return -ECANCELED;
            }

            total_duration += sample.sample[run];
        }

        auto result = sample.compute();

        std::fprintf(mp.output, "%f;%f;%f;%f\n",
                     total_duration, result.mean, result.variance,
                     result.standard_deviation);
    }

    return 0;
}

static int main_mpi_mode(const vle::Context& ctx, int rank, int size,
                         int argc, char *argv[])
{
    main_parameter mp = main_getopt(ctx, argc, argv);

    if (rank == 0) {
        vle_info(ctx, "MPI mode activated: %d/%d\n", rank, size);
        mp.print(ctx);

        std::shared_ptr <bench::Factory> factory = main_factory_new(ctx, mp, true);
        vle::CommonPtr common = main_common_new(mp.duration, factory);

        common->at("tgf-filesource") = std::string(argv[::optind]);
        bench::DSDE dsde_engine(common);

        if (mp.use_thread_root) {
            bench::RootMPIThread root(ctx);
            vle::SimulationDbg <bench::DSDE> sim(ctx, dsde_engine, root);
            sim.run(mp.simulation_begin,
                    mp.simulation_duration - mp.simulation_begin);
        } else {
            bench::RootMPIMono root(ctx);
            vle::SimulationDbg <bench::DSDE> sim(ctx, dsde_engine, root);
            sim.run(mp.simulation_begin,
                    mp.simulation_duration - mp.simulation_begin);
        }
    } else {
        vle_info(ctx, "Need to start SynchronousProxyModel %d", rank);
        std::shared_ptr <bench::Factory> factory = main_factory_new(ctx, mp, false);
        vle::CommonPtr common = main_common_new(mp.duration, factory);

        common->operator[]("name") = vle::stringf("S%d", rank - 1);
        common->operator[]("tgf-filesource") = vle::stringf("S%d.tgf", rank - 1);

        bench::SynchronousLogicalProcessor sp(common);
        bench::Factory::modelptr coupled = factory->get("coupled");
        sp.parent = 0;
        sp.run(*coupled);
    }

    return 0;
}

int main(int argc, char *argv[])
{
    std::ios::sync_with_stdio(false);

    boost::mpi::environment env(argc, argv);
    boost::mpi::communicator comm;

    vle::Context ctx = std::make_shared <vle::ContextImpl>();
    ctx->set_log_priority(3);

    int ret;

    if (comm.size() == 1)
        ret = main_mono_mode(ctx, argc, argv);
    else
        ret = main_mpi_mode(ctx, comm.rank(), comm.size(), argc, argv);

    return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
<commit_msg>main: switch to Simulation instead of SimulationDbg<commit_after>/*
 * Copyright (C) 2014 INRA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <vle/dsde.hpp>
#include <vle/common.hpp>
#include <vle/mpi.hpp>
#include <vle/vle.hpp>
#include <chrono>
#include "defs.hpp"
#include "timer.hpp"
#include "models.hpp"
#include <cstdlib>
#include <unistd.h>

static void main_show_version()
{
    std::fprintf(stdout, "Echll_Benchmark version 0.0.0\n");

    std::exit(EXIT_SUCCESS);
}

static void main_show_help()
{
    std::fprintf(stdout, "Echll_Benchmark [-v][-h][-d real]\n"
                 "Options:\n"
                 "  -h          This help\n"
                 "  -v          Version of Echll_Benchmark\n"
                 "  -d integer  Assigning minimal duration to internal transition\n"
                 "              0 means, no duration\n"
                 "  -c integer  Assigning number of run by simulation\n"
                 "  -t integer  0: no thread\n"
                 "              1: using thread for root\n"
                 "              2: using thread for sub-coupled model\n"
                 "              3: all is threaded\n"
                 "  -q integer  Assigning a default level 0 = no verbose,\n"
                 "              3 = fill terminal mode\n"
                 "  -o file     Output results into output file `file'."
                 "              (Default is standard output)\n"
                 "  -s begin,duration Assign the begin and the duration of\n"
                 "              the simulation. Default 0,10\n"
                 "\n"
                 "Examples:\n"
                 "$ Echll_Benchmark -d 100 -c 42 -t 3 root.tgf\n"
                 " -> Launch root.tgf 42 times and 100ms in internal transition"
                 " of atomic models using a linpack mode. Each coupled model uses"
                 " a thread to parallelize DSDE's bags\n\n"
                 "$ Echll_Benchmark root.tgf\n"
                 " -> Launch root.tgf 1 time and using 100 ms in internal transition"
                 " of atomic models. Coupled models uses mono thread approach\n\n");

    std::exit(EXIT_SUCCESS);
}

struct main_parameter
{
    main_parameter() = default;

    double simulation_begin = 0.0;
    double simulation_duration = 10.0;
    long int duration = 100;
    long int counter = 1;
    int verbose_mode = 0;
    bool use_thread_root = false;
    bool use_thread_sub = false;
    FILE *output = stdout;

    void print(const vle::Context& ctx)
    {
        vle_info(ctx,
                 "Flags:\n"
                 "- simulation begin at: %f\n"
                 "- simulation duration: %f\n"
                 "- duration: %ld ms\n"
                 "- counter: %ld runs\n"
                 "- use threaded root: %d\n"
                 "- use threaded coupled: %d\n",
                 simulation_begin, simulation_duration,
                 duration, counter, use_thread_root, use_thread_sub);
    }

    ~main_parameter()
    {
        if (output && output != stdout)
            std::fclose(output);
    }
};

static main_parameter main_getopt(const vle::Context& ctx,
                                  int argc, char* argv[])
{
    main_parameter ret;
    int opt;

    while ((opt = ::getopt(argc, argv, "vhq:d:c:t:o:s:")) != -1) {
        switch (opt) {
        case 'v':
            main_show_version();
            break;
        case 'h':
            main_show_help();
            break;
        case 'q':
            {
                char *nptr;
                ret.verbose_mode = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr,
                                 "-q: Failed to convert %s into verbose mode"
                                 " (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (ret.verbose_mode < 0) {
                    std::fprintf(stderr, "-q: Can not assign negative verbose"
                                 " mode\n");
                    exit(EXIT_FAILURE);
                }
                break;
            }
            break;
        case 'd':
            {
                char *nptr;
                ret.duration = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr,
                                 "-d: Failed to convert %s into millisecond"
                                 " (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (ret.duration < 0) {
                    std::fprintf(stderr, "-d: Can not assign a negative duration\n");
                    exit(EXIT_FAILURE);
                }
                break;
            }
        case 'c':
            {
                char *nptr;
                ret.counter = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr, "-c: Failed to convert %s into"
                                 " a number (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (ret.counter <= 0) {
                    std::fprintf(stderr, "-c: Can not assign zero or a negative"
                                 " counter\n");
                    exit(EXIT_FAILURE);
                }
                break;
            }
        case 't':
            {
                char *nptr;
                int threadmode = ::strtol(::optarg, &nptr, 10);
                if (nptr == ::optarg) {
                    std::fprintf(stderr, "-c: Failed to convert %s into"
                                 " a number (integer)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (threadmode < 0 || threadmode > 3) {
                    std::fprintf(stderr, "-t: thread mode [0..3]\n");
                    exit(EXIT_FAILURE);
                }
                ret.use_thread_root = (threadmode == 1 || threadmode == 3);
                ret.use_thread_sub = (threadmode >= 2);
                break;
            }
            break;
        case 'o':
            {
                char *output = ::optarg;
                FILE *file = std::fopen(output, "w");
                if (!file) {
                    std::fprintf(stderr, "-o: Failed to open output file %s",
                                 output);
                    exit(EXIT_FAILURE);
                }

                ret.output = file;
                break;
            }
        case 's':
            {
                char *nptr;
                errno = 0;
                ret.simulation_begin = strtod(::optarg, &nptr);
                if (errno) {
                    std::fprintf(stderr, "-s: Failed to convert %s into"
                                 " two reals (double,double)\n", ::optarg);
                    exit(EXIT_FAILURE);
                }

                if (nptr != NULL) {
                    if (*nptr != ',') {
                        std::fprintf(stderr, "-s: Failed to convert %s into "
                                     " two reals (double,double)\n", ::optarg);
                        exit(EXIT_FAILURE);
                    }
                    nptr++;
                    errno = 0;
                    ret.simulation_duration = strtod(nptr, &nptr);
                    if (errno) {
                        std::fprintf(stderr, "-s: Failed to convert %s into"
                                     " two reals (double, double)\n", ::optarg);
                        exit(EXIT_FAILURE);
                    }
                }

                if (ret.simulation_duration <= 0.0) {
                    std::fprintf(stderr, "-s: simulation duration must be a"
                                 " positive real not null\n");
                    exit(EXIT_FAILURE);
                }

                break;
            }
        }
    }

    if (::optind >= argc) {
        std::fprintf(stderr, "Expected argument after options\n");
        exit(EXIT_FAILURE);
    }

    ctx->set_user_data(ret.simulation_duration);

    return std::move(ret);
}

static vle::CommonPtr main_common_new(long int duration,
                                      std::shared_ptr <bench::Factory> factory)
{
    std::shared_ptr <vle::Common> ret = std::make_shared <vle::Common>();

    ret->emplace("duration", duration);
    ret->emplace("name", std::string("name"));
    ret->emplace("tgf-factory", factory);
    ret->emplace("tgf-source", (int)0);
    ret->emplace("tgf-format", (int)1);
    ret->emplace("tgf-filesource", std::string());

    return std::move(ret);
}

static std::shared_ptr <bench::Factory>
main_factory_new(const vle::Context& ctx,
                 const main_parameter& mp,
                 bool mpi_mode_and_root)
{
    std::shared_ptr <bench::Factory> ret = std::make_shared <bench::Factory>();

    typedef bench::Factory::modelptr modelptr;

    ret->functions.emplace("normal",
                           [&ctx]() -> modelptr
                           {
                               return modelptr(new bench::NormalPixel(ctx));
                           });
    ret->functions.emplace("top",
                           [&ctx]() -> modelptr
                           {
                               return modelptr(new bench::TopPixel(ctx));
                           });

    if (mpi_mode_and_root) {
        ret->functions.emplace("coupled",
                               [&ctx]() -> modelptr
                               {
                                   return modelptr(
                                       new bench::SynchronousProxyModel(ctx));
                               });
    } else {
        if (mp.use_thread_sub) {
            ret->functions.emplace("coupled",
                                   [&ctx]() -> modelptr
                                   {
                                       return modelptr(
                                           new bench::CoupledThread(ctx));
                                   });
        } else {
            ret->functions.emplace("coupled",
                                   [&ctx]() -> modelptr
                                   {
                                       return modelptr(
                                           new bench::CoupledMono(ctx));
                                   });
        }
    }

    return std::move(ret);
}

struct Sample
{
    struct result
    {
        double mean;
        double variance;
        double standard_deviation;
    };

    Sample(std::size_t nb)
        : sample(nb)
    {}

    Sample::result compute() const
    {
        Sample::result ret;

        ret.mean = std::accumulate(sample.cbegin(), sample.cend(), 0.0,
                                   [](double init, double duration)
                                   {
                                       return init + duration;
                                   }) / static_cast <double>(sample.size());

        ret.variance = std::accumulate(sample.cbegin(), sample.cend(), 0.0,
                                       [&ret](double init, double duration)
                                       {
                                           return init + std::pow(duration -
                                                                  ret.mean,
                                                                  2.0);
                                       }) / static_cast <double>(sample.size());

        ret.standard_deviation = std::sqrt(ret.variance);

        return std::move(ret);
    }

    std::vector <double> sample;
};

static int main_mono_mode(const vle::Context& ctx, int argc, char *argv[])
{
    main_parameter mp = main_getopt(ctx, argc, argv);

    vle_info(ctx, "No MPI mode activated\n");
    mp.print(ctx);

    std::shared_ptr <bench::Factory> factory = main_factory_new(ctx, mp, false);
    vle::CommonPtr common = main_common_new(mp.duration, factory);

    for (int i = ::optind; i < argc; ++i) {
        vle_info(ctx, "Run for %s\n", argv[i]);

        common->at("tgf-filesource") = std::string(argv[i]);

        double total_duration = 0.0;
        Sample sample(mp.counter);

        for (long int run = 0; run < mp.counter; ++run) {
            bench::DSDE dsde_engine(common);

            if (mp.use_thread_root) {             // TODO improve !
                bench::Timer timer(&sample.sample[run]);
                bench::RootThread root(ctx);
                vle::Simulation <bench::DSDE> sim(ctx, dsde_engine, root);
                sim.run(mp.simulation_begin,
                        mp.simulation_duration + mp.simulation_begin);
            } else {
                bench::Timer timer(&sample.sample[run]);
                bench::RootMono root(ctx);
                vle::Simulation <bench::DSDE> sim(ctx, dsde_engine, root);
                sim.run(mp.simulation_begin,
                        mp.simulation_duration + mp.simulation_begin);
            }

            if (sample.sample[run] < 0.0) {
                vle_info(ctx, "Simulation failure\n");
                return -ECANCELED;
            }

            total_duration += sample.sample[run];
        }

        auto result = sample.compute();

        std::fprintf(mp.output, "%f;%f;%f;%f\n",
                     total_duration, result.mean, result.variance,
                     result.standard_deviation);
    }

    return 0;
}

static int main_mpi_mode(const vle::Context& ctx, int rank, int size,
                         int argc, char *argv[])
{
    main_parameter mp = main_getopt(ctx, argc, argv);

    if (rank == 0) {
        vle_info(ctx, "MPI mode activated: %d/%d\n", rank, size);
        mp.print(ctx);

        std::shared_ptr <bench::Factory> factory = main_factory_new(ctx, mp, true);
        vle::CommonPtr common = main_common_new(mp.duration, factory);

        common->at("tgf-filesource") = std::string(argv[::optind]);
        bench::DSDE dsde_engine(common);

        if (mp.use_thread_root) {
            bench::RootMPIThread root(ctx);
            vle::Simulation <bench::DSDE> sim(ctx, dsde_engine, root);
            sim.run(mp.simulation_begin,
                    mp.simulation_duration - mp.simulation_begin);
        } else {
            bench::RootMPIMono root(ctx);
            vle::Simulation <bench::DSDE> sim(ctx, dsde_engine, root);
            sim.run(mp.simulation_begin,
                    mp.simulation_duration - mp.simulation_begin);
        }
    } else {
        vle_info(ctx, "Need to start SynchronousProxyModel %d", rank);
        std::shared_ptr <bench::Factory> factory = main_factory_new(ctx, mp, false);
        vle::CommonPtr common = main_common_new(mp.duration, factory);

        common->operator[]("name") = vle::stringf("S%d", rank - 1);
        common->operator[]("tgf-filesource") = vle::stringf("S%d.tgf", rank - 1);

        bench::SynchronousLogicalProcessor sp(common);
        bench::Factory::modelptr coupled = factory->get("coupled");
        sp.parent = 0;
        sp.run(*coupled);
    }

    return 0;
}

int main(int argc, char *argv[])
{
    std::ios::sync_with_stdio(false);

    boost::mpi::environment env(argc, argv);
    boost::mpi::communicator comm;

    vle::Context ctx = std::make_shared <vle::ContextImpl>();
    ctx->set_log_priority(3);

    int ret;

    if (comm.size() == 1)
        ret = main_mono_mode(ctx, argc, argv);
    else
        ret = main_mpi_mode(ctx, comm.rank(), comm.size(), argc, argv);

    return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>626a8a28-ad58-11e7-b9ae-ac87a332f658<commit_msg>We apologise for the previous fix. Those responsible have been sacked<commit_after>62d3d347-ad58-11e7-b85a-ac87a332f658<|endoftext|>


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

struct Vec3
{
    typedef const Vec3& InParam;

    Vec3() {}

    Vec3(const float x, const float y, const float z)
        : x(x)
        , y(y)
        , z(z)
    {
    }

    float x, y, z;
};

Vec3 operator+(Vec3::InParam left, Vec3::InParam right) {
    return Vec3{
        left.x + right.x,
        left.y + right.y,
        left.z + right.z
    };
}

Vec3 operator-(Vec3::InParam left, Vec3::InParam right) {
    return Vec3{
        left.x - right.x,
        left.y - right.y,
        left.z - right.z
    };
}

Vec3 operator*(Vec3::InParam v, const float scale) {
    return Vec3 {
        v.x * scale,
        v.y * scale,
        v.z * scale
    };
}

float dot(Vec3::InParam left, Vec3::InParam right) {
    return left.x*right.x + left.y*right.y + left.z*right.z;
}

// Vec3&& normalize(Vec3&& in) {
//     return Vec3
// }

float distance2d(const float x, const float y) {
    return sqrt(x*x + y*y);
}

float distance3d(const float x, const float y, const float z) {
    return sqrt(x*x + y*y + z*z);
}

float length(Vec3::InParam in) {
    return distance3d(in.x, in.y, in.z);
}

Vec3 normalised(Vec3::InParam in) {
    const float scale = 1.0f / length(in);
    return in * scale;
}

void colourful_square() {
    Vec3 colour(0.0f, 0.0f, 0.0f);
    float increment = 255.f / 512.f;

    for (int x=0; x<512; ++x) {
        colour.x += increment;
        colour.y = 0;
        for (int y=0; y<512; ++y) {
            colour.y += increment;
            colour.z = 64.0f + distance2d(x, y) / 8.0f;
            printf("%c%c%c", int(colour.x), int(colour.y), int(colour.z));
        }
    }
}

Vec3 sample_sky(const Vec3::InParam position, const Vec3::InParam direction) {
    const Vec3 forward{0.0f, 0.0f, 1.0f};
    const Vec3 right{1.0f, 0.0f, 0.0f};
    const Vec3 up{0.0f, 1.0f, 0.0f};

    const float red = 32.0f;
    const float green = 128.0f;
    const float blue = 180.0f + 64.0f * dot(direction, up);

    return Vec3 {red, green, blue};
}

Vec3 sample_ground(
        const Vec3::InParam position,
        const Vec3::InParam direction)
{
    const float inverse_square_scale = 0.1f;
    const int x = fabs(position.x * inverse_square_scale);
    const int y = fabs(position.z * inverse_square_scale);

    if ((x%2) ^ (y%2)) {
        return Vec3 {128.0f, 64.0f, 32.0f};
    } else {
        return Vec3 {32.0f, 64.0f, 128.0f};
    }
}

Vec3 sample(const Vec3::InParam position, const Vec3::InParam direction) {

    // check for collision against ground
    const Vec3 ground_point(0.0f, 0.0f, 0.0f);
    const Vec3 ground_inverse_normal(0.0f, -1.0f, 0.0f);
    const Vec3 to_ground {ground_point - position};
    if (dot(to_ground, direction) > 0.0f) {
        const float distance_to_ground {dot(to_ground, ground_inverse_normal)};
        const float dot_to_ground {dot(direction, ground_inverse_normal)};
        const float distance {distance_to_ground / dot_to_ground};
        const Vec3 ground_intersection {position + direction * distance};
        return sample_ground(ground_intersection, direction);
    }

    return sample_sky(position, direction);
}

void draw_scene(const int image_width, const int image_height) {
    const Vec3 camera_forward{0.0f, 0.0f, 1.0f};
    const Vec3 camera_right{1.0f, 0.0f, 0.0f};
    const Vec3 camera_up{0.0f, 1.0f, 0.0f};
    const Vec3 camera_pos{0.0f, 10.0f, 0.0f};

    const int half_image_width = image_width / 2;
    const int half_image_height = image_height / 2;

    for (int y=image_height-1; y>=0; --y) {
        for (int x=0; x<image_width; ++x) {
            const Vec3 pixel_offset = Vec3 {
                float(x-half_image_width),
                float(y-half_image_height),
                0.0f};

            const Vec3 pixel_direction = normalised(
                camera_forward*image_height + pixel_offset);

            const Vec3 colour = sample(camera_pos, pixel_direction);

            printf("%c%c%c", int(colour.x), int(colour.y), int(colour.z));
        }
    }
}

int main() {
    printf("P6 512 512 255 ");
    draw_scene(512, 512);
}
<commit_msg>basic lighting<commit_after>#include <math.h>
#include <stdio.h>

struct Vec3
{
    typedef const Vec3& InParam;

    Vec3() {}

    Vec3(const float x, const float y, const float z)
        : x(x)
        , y(y)
        , z(z)
    {
    }

    float x, y, z;
};

Vec3 operator+(Vec3::InParam left, Vec3::InParam right) {
    return Vec3{
        left.x + right.x,
        left.y + right.y,
        left.z + right.z
    };
}

Vec3 operator-(Vec3::InParam left, Vec3::InParam right) {
    return Vec3{
        left.x - right.x,
        left.y - right.y,
        left.z - right.z
    };
}

Vec3 operator*(Vec3::InParam v, const float scale) {
    return Vec3 {
        v.x * scale,
        v.y * scale,
        v.z * scale
    };
}

float dot(Vec3::InParam left, Vec3::InParam right) {
    return left.x*right.x + left.y*right.y + left.z*right.z;
}

// Vec3&& normalize(Vec3&& in) {
//     return Vec3
// }

float distance2d(const float x, const float y) {
    return sqrt(x*x + y*y);
}

float distance3d(const float x, const float y, const float z) {
    return sqrt(x*x + y*y + z*z);
}

float length(Vec3::InParam in) {
    return distance3d(in.x, in.y, in.z);
}

Vec3 normalised(Vec3::InParam in) {
    const float scale = 1.0f / length(in);
    return in * scale;
}

Vec3 lerp(Vec3::InParam from, Vec3::InParam to, const float t) {
    return (from * (1.0f - t) + (to * t));
}

void colourful_square() {
    Vec3 colour(0.0f, 0.0f, 0.0f);
    float increment = 255.f / 512.f;

    for (int x=0; x<512; ++x) {
        colour.x += increment;
        colour.y = 0;
        for (int y=0; y<512; ++y) {
            colour.y += increment;
            colour.z = 64.0f + distance2d(x, y) / 8.0f;
            printf("%c%c%c", int(colour.x), int(colour.y), int(colour.z));
        }
    }
}

Vec3 sample_sky(const Vec3::InParam position, const Vec3::InParam direction) {
    const Vec3 forward{0.0f, 0.0f, 1.0f};
    const Vec3 right{1.0f, 0.0f, 0.0f};
    const Vec3 up{0.0f, 1.0f, 0.0f};

    const float red = 32.0f;
    const float green = 128.0f;
    const float blue = 180.0f + 64.0f * dot(direction, up);

    return Vec3 {red, green, blue};
}

Vec3 sample_ground(
        const Vec3::InParam position,
        const Vec3::InParam direction)
{
    const float inverse_square_scale = 0.1f;
    const int x = fabs(position.x * inverse_square_scale);
    const int y = fabs(position.z * inverse_square_scale);

    const Vec3 world_up {0.0f, 1.0f, 0.0f};
    const float dot_up {dot(direction, world_up)};

    if ((x%2) ^ (y%2)) {
        return lerp(
            Vec3 {128.0f, 64.0f, 32.0f},
            Vec3 {255.0f, 128.0f, 64.0f},
            dot_up);
    } else {
        return lerp(
            Vec3 {32.0f, 64.0f, 128.0f},
            Vec3 {64.0f, 128.0f, 255.0f},
            dot_up);
    }
}

Vec3 sample(const Vec3::InParam position, const Vec3::InParam direction) {

    // check for collision against ground
    const Vec3 ground_point(0.0f, 0.0f, 0.0f);
    const Vec3 ground_inverse_normal(0.0f, -1.0f, 0.0f);
    const Vec3 to_ground {ground_point - position};
    if (dot(to_ground, direction) > 0.0f) {
        // hit the ground, figure out where
        const float distance_to_ground {dot(to_ground, ground_inverse_normal)};
        const float dot_to_ground {dot(direction, ground_inverse_normal)};
        const float distance {distance_to_ground / dot_to_ground};
        const Vec3 ground_intersection {position + direction * distance};
        return sample_ground(ground_intersection, direction);
    }

    return sample_sky(position, direction);
}

void draw_scene(const int image_width, const int image_height) {
    const Vec3 camera_forward{0.0f, 0.0f, 1.0f};
    const Vec3 camera_right{1.0f, 0.0f, 0.0f};
    const Vec3 camera_up{0.0f, 1.0f, 0.0f};
    const Vec3 camera_pos{0.0f, 10.0f, 0.0f};

    const int half_image_width = image_width / 2;
    const int half_image_height = image_height / 2;

    for (int y=image_height-1; y>=0; --y) {
        for (int x=0; x<image_width; ++x) {
            const Vec3 pixel_offset = Vec3 {
                float(x-half_image_width),
                float(y-half_image_height),
                0.0f};

            const Vec3 pixel_direction = normalised(
                camera_forward*image_height + pixel_offset);

            const Vec3 colour = sample(camera_pos, pixel_direction);

            printf("%c%c%c", int(colour.x), int(colour.y), int(colour.z));
        }
    }
}

int main() {
    printf("P6 512 512 255 ");
    draw_scene(512, 512);
}
<|endoftext|>


<commit_before>7565f49c-4b02-11e5-8b41-28cfe9171a43<commit_msg>having coffee<commit_after>7570c107-4b02-11e5-8a73-28cfe9171a43<|endoftext|>


<commit_before>4af55517-2748-11e6-aabc-e0f84713e7b8<commit_msg>No longer crashes if X<commit_after>4b071ce3-2748-11e6-8543-e0f84713e7b8<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "TrackedBodyIMU.h"
#include "AngVelTools.h"
#include "TrackedBody.h"
#include "TrackingSystem.h"

// Library/third-party includes
#include <boost/assert.hpp>

// Standard includes
#include <cmath>

namespace osvr {
namespace vbtracker {
    TrackedBodyIMU::TrackedBodyIMU(TrackedBody &body,
                                   double orientationVariance,
                                   double angularVelocityVariance)
        : m_body(body), m_yaw(0),
          m_useOrientation(getParams().imu.useOrientation),
          m_orientationVariance(orientationVariance),
          m_useAngularVelocity(getParams().imu.useAngularVelocity),
          m_angularVelocityVariance(angularVelocityVariance) {}
    void
    TrackedBodyIMU::updatePoseFromOrientation(util::time::TimeValue const &tv,
                                              Eigen::Quaterniond const &quat) {
        if (!m_yawKnown) {
            // This needs to go to calibration instead of to our own pose.
            getBody().getSystem().calibrationHandleIMUData(getBody().getId(),
                                                           tv, quat);
            return;
        }
        // Save some local state: we do have orientation ourselves now.
        m_quat = transformRawIMUOrientation(quat);
        m_hasOrientation = true;
        m_last = tv;

        if (!m_useOrientation) {
            return;
        }
        // Can it and update the pose with it.
        updatePoseFromMeasurement(tv, preprocessOrientation(tv, quat));
    }
    void TrackedBodyIMU::updatePoseFromAngularVelocity(
        util::time::TimeValue const &tv, Eigen::Quaterniond const &deltaquat,
        double dt) {
        if (!m_yawKnown) {
            // No calibration yet, and angular velocity isn't useful there.
            return;
        }

        if (!m_useAngularVelocity) {
            return;
        }
        // Can it and update the pose with it.
        updatePoseFromMeasurement(tv,
                                  preprocessAngularVelocity(tv, deltaquat, dt));
    }

    Eigen::Quaterniond TrackedBodyIMU::transformRawIMUOrientation(
        Eigen::Quaterniond const &input) const {
        BOOST_ASSERT_MSG(
            calibrationYawKnown(),
            "transform called before calibration transform known!");
        return m_yawCorrection * input;
    }

    CannedIMUMeasurement
    TrackedBodyIMU::preprocessOrientation(util::time::TimeValue const &tv,
                                          Eigen::Quaterniond const &quat) {

        auto ret = CannedIMUMeasurement{};
        ret.setOrientation(transformRawIMUOrientation(quat),
                           Eigen::Vector3d::Constant(m_orientationVariance));
        return ret;
    }

    /// Processes an angular velocity
    CannedIMUMeasurement TrackedBodyIMU::preprocessAngularVelocity(
        util::time::TimeValue const &tv, Eigen::Quaterniond const &deltaquat,
        double dt) {
        /// @todo handle transform for off-center velocity!

        /// Transform for yaw correction.
        Eigen::Quaterniond correctedDeltaQuat =
            m_yawCorrection * deltaquat * m_yawCorrection.inverse();

        Eigen::Vector3d rot = incRotToAngVelVec(deltaquat, dt);
        auto ret = CannedIMUMeasurement{};
        ret.setAngVel(rot,
                      Eigen::Vector3d::Constant(m_angularVelocityVariance));
        return ret;
    }

    bool TrackedBodyIMU::updatePoseFromMeasurement(
        util::time::TimeValue const &tv, CannedIMUMeasurement const &meas) {
        if (!meas.orientationValid() && !meas.angVelValid()) {
            return false;
        }
        getBody().incorporateNewMeasurementFromIMU(tv, meas);
        return true;
    }

    ConfigParams const &TrackedBodyIMU::getParams() const {
        return getBody().getParams();
    }
} // namespace vbtracker
} // namespace osvr
<commit_msg>Fix error - not canning the transformed angular velocity<commit_after>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "TrackedBodyIMU.h"
#include "AngVelTools.h"
#include "TrackedBody.h"
#include "TrackingSystem.h"

// Library/third-party includes
#include <boost/assert.hpp>

// Standard includes
#include <cmath>

namespace osvr {
namespace vbtracker {
    TrackedBodyIMU::TrackedBodyIMU(TrackedBody &body,
                                   double orientationVariance,
                                   double angularVelocityVariance)
        : m_body(body), m_yaw(0),
          m_useOrientation(getParams().imu.useOrientation),
          m_orientationVariance(orientationVariance),
          m_useAngularVelocity(getParams().imu.useAngularVelocity),
          m_angularVelocityVariance(angularVelocityVariance) {}
    void
    TrackedBodyIMU::updatePoseFromOrientation(util::time::TimeValue const &tv,
                                              Eigen::Quaterniond const &quat) {
        if (!m_yawKnown) {
            // This needs to go to calibration instead of to our own pose.
            getBody().getSystem().calibrationHandleIMUData(getBody().getId(),
                                                           tv, quat);
            return;
        }
        // Save some local state: we do have orientation ourselves now.
        m_quat = transformRawIMUOrientation(quat);
        m_hasOrientation = true;
        m_last = tv;

        if (!m_useOrientation) {
            return;
        }
        // Can it and update the pose with it.
        updatePoseFromMeasurement(tv, preprocessOrientation(tv, quat));
    }
    void TrackedBodyIMU::updatePoseFromAngularVelocity(
        util::time::TimeValue const &tv, Eigen::Quaterniond const &deltaquat,
        double dt) {
        if (!m_yawKnown) {
            // No calibration yet, and angular velocity isn't useful there.
            return;
        }

        if (!m_useAngularVelocity) {
            return;
        }
        // Can it and update the pose with it.
        updatePoseFromMeasurement(tv,
                                  preprocessAngularVelocity(tv, deltaquat, dt));
    }

    Eigen::Quaterniond TrackedBodyIMU::transformRawIMUOrientation(
        Eigen::Quaterniond const &input) const {
        BOOST_ASSERT_MSG(
            calibrationYawKnown(),
            "transform called before calibration transform known!");
        return m_yawCorrection * input;
    }

    CannedIMUMeasurement
    TrackedBodyIMU::preprocessOrientation(util::time::TimeValue const &tv,
                                          Eigen::Quaterniond const &quat) {

        auto ret = CannedIMUMeasurement{};
        ret.setOrientation(transformRawIMUOrientation(quat),
                           Eigen::Vector3d::Constant(m_orientationVariance));
        return ret;
    }

    /// Processes an angular velocity
    CannedIMUMeasurement TrackedBodyIMU::preprocessAngularVelocity(
        util::time::TimeValue const &tv, Eigen::Quaterniond const &deltaquat,
        double dt) {
        /// @todo handle transform for off-center velocity!

        /// Transform for yaw correction.
        Eigen::Quaterniond correctedDeltaQuat =
            m_yawCorrection * deltaquat * m_yawCorrection.inverse();

        Eigen::Vector3d rot = incRotToAngVelVec(correctedDeltaQuat, dt);
        auto ret = CannedIMUMeasurement{};
        ret.setAngVel(rot,
                      Eigen::Vector3d::Constant(m_angularVelocityVariance));
        return ret;
    }

    bool TrackedBodyIMU::updatePoseFromMeasurement(
        util::time::TimeValue const &tv, CannedIMUMeasurement const &meas) {
        if (!meas.orientationValid() && !meas.angVelValid()) {
            return false;
        }
        getBody().incorporateNewMeasurementFromIMU(tv, meas);
        return true;
    }

    ConfigParams const &TrackedBodyIMU::getParams() const {
        return getBody().getParams();
    }
} // namespace vbtracker
} // namespace osvr
<|endoftext|>


<commit_before>2ce0fed7-ad59-11e7-9851-ac87a332f658<commit_msg>more bug fix<commit_after>2d637fb5-ad59-11e7-8ce2-ac87a332f658<|endoftext|>


<commit_before>c8f5c6b8-ad58-11e7-9099-ac87a332f658<commit_msg>#BUG723 uncommitted code found on my computer Monday morning<commit_after>c95699a1-ad58-11e7-95a4-ac87a332f658<|endoftext|>


<commit_before>a629471c-4b02-11e5-bd38-28cfe9171a43<commit_msg>almost working<commit_after>a6362d30-4b02-11e5-a279-28cfe9171a43<|endoftext|>