<commit_before>//=============================================================================
// ■ VMGS/Scene/scene.cpp
//=============================================================================

#include "../VMGS.hpp"

namespace VM76 {
	namespace SceneManager {
		Scene* context = NULL;
	}

	void Scene::key_callback(int key, int scancode, int action, int mods) {}
	void Scene::update() {}
	Scene::~Scene() {}

	bool SceneManager::render_debug_info = true;

	void SceneManager::load_scene(Scene* c) {
		context = c;
	}

	void SceneManager::update_scene() {
		if (context) context->update();
	}

	void SceneManager::render_scene() {
		if (context) context->render();
		// Render FPS
		if (render_debug_info) {
			VMSC::disable_depth_test();
			char fps[40];
			sprintf(fps, "FPS: %d, %f.4ms", VMDE->fps, VMDE->frame_time);
			trex->instanceRenderText(
				fps, gui_2d_projection,
				glm::mat4(1.0),
				glm::translate(glm::mat4(1.0), glm::vec3(0.01, 0.94, 0.0)),
				0.025, 0.05, TextRenderer::TextDecorationType::OUTLINE
			);
			VMSC::enable_depth_test();
		}
	}

	void SceneManager::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
		if (key == GLFW_KEY_F3 && action == GLFW_PRESS) {
			render_debug_info = !render_debug_info;
			return;
		}
		if (context) context->key_callback(key, scancode, action, mods);
	}
}
<commit_msg>Add Ctrl-Break functionality<commit_after>//=============================================================================
// ■ VMGS/Scene/scene.cpp
//=============================================================================

#include "../VMGS.hpp"

namespace VM76 {
	namespace SceneManager {
		Scene* context = NULL;
	}

	void Scene::key_callback(int key, int scancode, int action, int mods) {}
	void Scene::update() {}
	Scene::~Scene() {}

	bool SceneManager::render_debug_info = true;

	void SceneManager::load_scene(Scene* c) {
		context = c;
	}

	void SceneManager::update_scene() {
		if (context) context->update();
	}

	void SceneManager::render_scene() {
		if (context) context->render();
		// Render FPS
		if (render_debug_info) {
			VMSC::disable_depth_test();
			char fps[40];
			sprintf(fps, "FPS: %d, %f.4ms", VMDE->fps, VMDE->frame_time);
			trex->instanceRenderText(
				fps, gui_2d_projection,
				glm::mat4(1.0),
				glm::translate(glm::mat4(1.0), glm::vec3(0.01, 0.94, 0.0)),
				0.025, 0.05, TextRenderer::TextDecorationType::OUTLINE
			);
			VMSC::enable_depth_test();
		}
	}

	void SceneManager::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
		if (key == GLFW_KEY_PAUSE && action == GLFW_PRESS && (mods & GLFW_MOD_CONTROL)) {
			abort();
		}
		if (key == GLFW_KEY_F3 && action == GLFW_PRESS) {
			render_debug_info = !render_debug_info;
			return;
		}
		if (context) context->key_callback(key, scancode, action, mods);
	}
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstring>
#include <cstdlib>

#include <benejson/pull.hh>
#include "posix.hh"

void OutputValue(BNJ::PullParser& parser){
	const bnj_val& val = parser.GetValue();

	if(val.key_length){
		char key[512];
		BNJ::GetKey(key, 1024, parser);
		fprintf(stdout, "key: '%s'\n", key);
	}

	switch(bnj_val_type(&val)){
		case BNJ_NUMERIC:
			if(val.exp_val){
				double f;
				BNJ::Get(f, parser);
				fprintf(stdout, "double: %g\n", f);
			}
			else{
				if(val.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND){
					int v;
					BNJ::Get(v, parser);
					fprintf(stdout, "integer: %d\n", v);
				}
				else{
					unsigned v;
					BNJ::Get(v, parser);
					fprintf(stdout, "unsigned: %d\n", v);
				}
			}
			break;

		case BNJ_SPECIAL:
			switch(val.significand_val){
				case BNJ_SPC_FALSE:
					fprintf(stdout, "bool: false\n");
					break;
				case BNJ_SPC_TRUE:
					fprintf(stdout, "bool: true\n");
					break;
				case BNJ_SPC_NULL:
					fprintf(stdout, "null\n");
					break;
				case BNJ_SPC_NAN:
					fprintf(stdout, "float: NaN\n");
					break;
				case BNJ_SPC_INFINITY:
					{
						char c = (val.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND) ? '-' : ' ';
						fprintf(stdout, "float: %cInfinity\n", c);
					}
					break;
				default:
					break;
			}
			break;

		case BNJ_ARR_BEGIN:
			break;

		case BNJ_OBJ_BEGIN:
			break;

		case BNJ_STRING:
			{
				/* Can read the length of the string fragment before consuming
				unsigned outlen = bnj_strlen8(&parser.GetValue());
				unsigned outlen = bnj_strlen16(&parser.GetValue());
				unsigned outlen = bnj_strlen32&parser.GetValue());
				*/

				unsigned len;
				char buffer[1024];

				/* Consume/Write loop */
				fprintf(stdout, "string: '");
				while((len = parser.ChunkRead8(buffer, 1024)))
					fwrite(buffer, 1, len, stdout);
				fprintf(stdout, "'\n");
			}
			break;

		default:
			break;
	}
}

int main(int argc, const char* argv[]){

	if(argc < 3){
		fprintf(stderr, "Usage: %s buffer_size stack_depth\n", argv[0]);
		return 1;
	}

	/* Read arguments. */
	char* endptr;
	unsigned buffsize = strtol(argv[1], &endptr, 10);
	unsigned depth = strtol(argv[2], &endptr, 10);

	/* Read json from std input. */
	FD_Reader reader(0);
	uint32_t *pstack = new uint32_t[depth];
	BNJ::PullParser parser(depth, pstack);

	/* Initialize parsing session. buffer is I/O scratch space. */
	uint8_t *buffer = new uint8_t[buffsize];
	parser.Begin(buffer, buffsize, &reader);

	int ret = 0;
	try{
		/* Begin a tree walk. */
		bool running = true;
		while(running){
			switch(parser.Pull()){
				/* Stop when there is no more data. */
				case BNJ::PullParser::ST_NO_DATA:
					running = false;
					break;

				/* Parser pulled a datum. */
				case BNJ::PullParser::ST_DATUM:
					OutputValue(parser);
					break;

				case BNJ::PullParser::ST_MAP:
    			fprintf(stdout, "map open '{'\n");
					break;

				case BNJ::PullParser::ST_LIST:
    			fprintf(stdout, "array open '['\n");
					break;

				case BNJ::PullParser::ST_ASCEND_MAP:
					fprintf(stdout, "map close '}'\n");
					break;

				case BNJ::PullParser::ST_ASCEND_LIST:
					fprintf(stdout, "array close ']'\n");
					break;

				default:
					break;
			}
		}

	}
	catch(const std::exception& e){
		fprintf(stderr, "Runtime Error: %s\n", e.what());
		ret = 1;
	}
	delete [] buffer;
	delete [] pstack;

	return ret;
}
<commit_msg>Print out keys for maps/lists now<commit_after>#include <cstdio>
#include <cstring>
#include <cstdlib>

#include <benejson/pull.hh>
#include "posix.hh"

void OutputValue(BNJ::PullParser& parser){
	const bnj_val& val = parser.GetValue();

	switch(bnj_val_type(&val)){
		case BNJ_NUMERIC:
			if(val.exp_val){
				double f;
				BNJ::Get(f, parser);
				fprintf(stdout, "double: %g\n", f);
			}
			else{
				if(val.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND){
					int v;
					BNJ::Get(v, parser);
					fprintf(stdout, "integer: %d\n", v);
				}
				else{
					unsigned v;
					BNJ::Get(v, parser);
					fprintf(stdout, "unsigned: %d\n", v);
				}
			}
			break;

		case BNJ_SPECIAL:
			switch(val.significand_val){
				case BNJ_SPC_FALSE:
					fprintf(stdout, "bool: false\n");
					break;
				case BNJ_SPC_TRUE:
					fprintf(stdout, "bool: true\n");
					break;
				case BNJ_SPC_NULL:
					fprintf(stdout, "null\n");
					break;
				case BNJ_SPC_NAN:
					fprintf(stdout, "float: NaN\n");
					break;
				case BNJ_SPC_INFINITY:
					{
						char c = (val.type & BNJ_VFLAG_NEGATIVE_SIGNIFICAND) ? '-' : ' ';
						fprintf(stdout, "float: %cInfinity\n", c);
					}
					break;
				default:
					break;
			}
			break;

		case BNJ_ARR_BEGIN:
			break;

		case BNJ_OBJ_BEGIN:
			break;

		case BNJ_STRING:
			{
				/* Can read the length of the string fragment before consuming
				unsigned outlen = bnj_strlen8(&parser.GetValue());
				unsigned outlen = bnj_strlen16(&parser.GetValue());
				unsigned outlen = bnj_strlen32&parser.GetValue());
				*/

				unsigned len;
				char buffer[1024];

				/* Consume/Write loop */
				fprintf(stdout, "string: '");
				while((len = parser.ChunkRead8(buffer, 1024)))
					fwrite(buffer, 1, len, stdout);
				fprintf(stdout, "'\n");
			}
			break;

		default:
			break;
	}
}

int main(int argc, const char* argv[]){

	if(argc < 3){
		fprintf(stderr, "Usage: %s buffer_size stack_depth\n", argv[0]);
		return 1;
	}

	/* Read arguments. */
	char* endptr;
	unsigned buffsize = strtol(argv[1], &endptr, 10);
	unsigned depth = strtol(argv[2], &endptr, 10);

	/* Read json from std input. */
	FD_Reader reader(0);
	uint32_t *pstack = new uint32_t[depth];
	BNJ::PullParser parser(depth, pstack);

	/* Initialize parsing session. buffer is I/O scratch space. */
	uint8_t *buffer = new uint8_t[buffsize];
	parser.Begin(buffer, buffsize, &reader);

	int ret = 0;
	try{
		/* Begin a tree walk. */
		bool running = true;
		while(running){
			unsigned ret = parser.Pull();

			if(parser.ValidValue()){
				const bnj_val& val = parser.GetValue();
				if(val.key_length){
					char key[512];
					BNJ::GetKey(key, 1024, parser);
					fprintf(stdout, "key: '%s'\n", key);
				}
			}

			switch(ret){
				/* Stop when there is no more data. */
				case BNJ::PullParser::ST_NO_DATA:
					running = false;
					break;

				/* Parser pulled a datum. */
				case BNJ::PullParser::ST_DATUM:
					OutputValue(parser);
					break;

				case BNJ::PullParser::ST_MAP:
    			fprintf(stdout, "map open '{'\n");
					break;

				case BNJ::PullParser::ST_LIST:
    			fprintf(stdout, "array open '['\n");
					break;

				case BNJ::PullParser::ST_ASCEND_MAP:
					fprintf(stdout, "map close '}'\n");
					break;

				case BNJ::PullParser::ST_ASCEND_LIST:
					fprintf(stdout, "array close ']'\n");
					break;

				default:
					break;
			}
		}

	}
	catch(const std::exception& e){
		fprintf(stderr, "Runtime Error: %s\n", e.what());
		ret = 1;
	}
	delete [] buffer;
	delete [] pstack;

	return ret;
}
<|endoftext|>


<commit_before>/* Copyright 2017 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/compiler/xla/client/computation_builder.h"
#include "tensorflow/compiler/xla/tests/client_library_test_base.h"
#include "tensorflow/compiler/xla/tests/literal_test_util.h"
#include "tensorflow/compiler/xla/tests/test_macros.h"

namespace xla {
namespace {

class ConditionalOpTest : public ClientLibraryTestBase {
 protected:
  Computation CreateR0F32ConstantComputation(float value) {
    ComputationBuilder builder(client_, "Constant");
    builder.Parameter(0, empty_tuple_, "tuple");
    builder.ConstantR0<float>(value);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateR0F32IdentityComputation() {
    ComputationBuilder builder(client_, "Identity");
    builder.Parameter(0, r0f32_, "x");
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateR0F32CeilComputation() {
    ComputationBuilder builder(client_, "Ceil");
    auto param = builder.Parameter(0, r0f32_, "param");
    builder.Ceil(param);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateR0F32FloorComputation() {
    ComputationBuilder builder(client_, "Ceil");
    auto param = builder.Parameter(0, r0f32_, "param");
    builder.Floor(param);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateAddTupleComputation(const string& computation_name,
                                        const Shape& tuple_shape) {
    ComputationBuilder builder(client_, computation_name);
    auto tuple = builder.Parameter(0, tuple_shape, "tuple");
    auto x = builder.GetTupleElement(tuple, 0);
    auto y = builder.GetTupleElement(tuple, 1);
    builder.Add(x, y);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateAddR0Computation() {
    return CreateAddTupleComputation("AddR0", tuple_2_r0f32_);
  }

  Computation CreateAddR1Computation() {
    return CreateAddTupleComputation("AddR1", tuple_2_r1s2f32_);
  }

  Computation CreateSubTupleComputation(const string& computation_name,
                                        const Shape& tuple_shape) {
    ComputationBuilder builder(client_, computation_name);
    auto tuple = builder.Parameter(0, tuple_shape, "tuple");
    auto x = builder.GetTupleElement(tuple, 0);
    auto y = builder.GetTupleElement(tuple, 1);
    builder.Sub(x, y);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateSubR0Computation() {
    return CreateSubTupleComputation("SubR0", tuple_2_r0f32_);
  }

  Computation CreateSubR1Computation() {
    return CreateSubTupleComputation("SubR1", tuple_2_r1s2f32_);
  }

  Shape r0f32_ = ShapeUtil::MakeShape(F32, {});
  Shape tuple_2_r0f32_ = ShapeUtil::MakeTupleShape(
      {ShapeUtil::MakeShape(F32, {}), ShapeUtil::MakeShape(F32, {})});
  Shape tuple_2_r1s2f32_ = ShapeUtil::MakeTupleShape(
      {ShapeUtil::MakeShape(F32, {2}), ShapeUtil::MakeShape(F32, {2})});
  Shape empty_tuple_ = ShapeUtil::MakeTupleShape({});
  ErrorSpec error_spec_{0.001};
};

// Test true and false computations that do not take any parameters.
XLA_TEST_F(ConditionalOpTest, Parameters0) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operands = builder.Tuple({});
  auto true_computation = CreateR0F32ConstantComputation(56.0f);
  auto false_computation = CreateR0F32ConstantComputation(12.0f);
  auto result = builder.Conditional(pred, operands, true_computation, operands,
                                    false_computation);

  ComputeAndCompareR0<float>(&builder, 56.0f, {}, error_spec_);
}

// Test true and false computations that take in 1 parameter.
XLA_TEST_F(ConditionalOpTest, Parameters1) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto identity = CreateR0F32IdentityComputation();
  auto result =
      builder.Conditional(pred, operand1, identity, operand2, identity);

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test true and false computations that take in 2 parameters and predicate is
// true.
XLA_TEST_F(ConditionalOpTest, Parameters2TrueBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR0Computation(),
                                    operands, CreateSubR0Computation());

  ComputeAndCompareR0<float>(&builder, 68.0f, {}, error_spec_);
}

// Test true and false computations that take in 2 parameters and predicate is
// false.
XLA_TEST_F(ConditionalOpTest, Parameters2FalseBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR0Computation(),
                                    operands, CreateSubR0Computation());

  ComputeAndCompareR0<float>(&builder, 44.0f, {}, error_spec_);
}

// Test true and false computations that take in 2 array parameters and
// predicate is true.
XLA_TEST_F(ConditionalOpTest, Parameters2ArrayTrueBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operand1 = builder.ConstantR1<float>({24.0f, 56.0f});
  auto operand2 = builder.ConstantR1<float>({10.0f, 11.0f});
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR1Computation(),
                                    operands, CreateSubR1Computation());

  ComputeAndCompareR1<float>(&builder, {34.0f, 67.0f}, {}, error_spec_);
}

// Test true and false computations that take in 2 array parameters and
// predicate is false.
XLA_TEST_F(ConditionalOpTest, Parameters2ArrayFalseBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR1<float>({24.0f, 56.0f});
  auto operand2 = builder.ConstantR1<float>({10.0f, 11.0f});
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR1Computation(),
                                    operands, CreateSubR1Computation());

  ComputeAndCompareR1<float>(&builder, {14.0f, 45.0f}, {}, error_spec_);
}

// Test the case where one conditional is nested within another.
XLA_TEST_F(ConditionalOpTest, NestedConditionals) {
  Shape r0bool = ShapeUtil::MakeShape(PRED, {});
  Shape tuple_shape = ShapeUtil::MakeTupleShape({r0bool, r0f32_, r0f32_});
  ComputationBuilder inner_builder(client_, TestName() + ".inner_conditional");
  auto param0 = inner_builder.Parameter(0, tuple_shape, "param0");
  auto pred_cond = inner_builder.GetTupleElement(param0, 0);
  auto true_operand = inner_builder.GetTupleElement(param0, 1);
  auto false_operand = inner_builder.GetTupleElement(param0, 2);
  inner_builder.Conditional(pred_cond, true_operand,
                            CreateR0F32CeilComputation(), false_operand,
                            CreateR0F32FloorComputation());
  auto inner_builder_result = inner_builder.Build();

  ComputationBuilder builder(client_, TestName());
  auto pred1 = builder.ConstantR0<bool>(true);
  auto pred2 = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(1.1f);
  auto operand2 = builder.ConstantR0<float>(12.2f);
  auto operand3 = builder.ConstantR0<float>(43.3f);
  auto tuple_operand = builder.Tuple({pred2, operand1, operand2});
  builder.Conditional(pred1, tuple_operand,
                      inner_builder_result.ConsumeValueOrDie(), operand3,
                      CreateR0F32IdentityComputation());

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test a mismatch in the shape of the true operand and true computation.
XLA_TEST_F(ConditionalOpTest, ShapeMismatch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto operands = builder.Tuple({operand1, operand2});
  builder.Conditional(pred, operands, CreateAddR1Computation(), operands,
                      CreateSubR0Computation());

  auto result = builder.Build();
  EXPECT_FALSE(result.ok());
  EXPECT_THAT(result.status().error_message(),
              ::testing::HasSubstr("true_operand must match the shape of the "
                                   "only parameter of true_computation"));
}

}  // namespace
}  // namespace xla
<commit_msg>[XLA] Adding more tests for conditional.<commit_after>/* Copyright 2017 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/compiler/xla/client/computation_builder.h"
#include "tensorflow/compiler/xla/tests/client_library_test_base.h"
#include "tensorflow/compiler/xla/tests/literal_test_util.h"
#include "tensorflow/compiler/xla/tests/test_macros.h"

namespace xla {
namespace {

class ConditionalOpTest : public ClientLibraryTestBase {
 protected:
  Computation CreateR0F32ConstantComputation(float value) {
    ComputationBuilder builder(client_, "Constant");
    builder.Parameter(0, empty_tuple_, "tuple");
    builder.ConstantR0<float>(value);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateR0F32IdentityComputation() {
    ComputationBuilder builder(client_, "Identity");
    builder.Parameter(0, r0f32_, "x");
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateR0F32CeilComputation() {
    ComputationBuilder builder(client_, "Ceil");
    auto param = builder.Parameter(0, r0f32_, "param");
    builder.Ceil(param);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateR0F32FloorComputation() {
    ComputationBuilder builder(client_, "Ceil");
    auto param = builder.Parameter(0, r0f32_, "param");
    builder.Floor(param);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateAddTupleComputation(const string& computation_name,
                                        const Shape& tuple_shape) {
    ComputationBuilder builder(client_, computation_name);
    auto tuple = builder.Parameter(0, tuple_shape, "tuple");
    auto x = builder.GetTupleElement(tuple, 0);
    auto y = builder.GetTupleElement(tuple, 1);
    builder.Add(x, y);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateAddR0Computation() {
    return CreateAddTupleComputation("AddR0", tuple_2_r0f32_);
  }

  Computation CreateAddR1Computation() {
    return CreateAddTupleComputation("AddR1", tuple_2_r1s2f32_);
  }

  Computation CreateSubTupleComputation(const string& computation_name,
                                        const Shape& tuple_shape) {
    ComputationBuilder builder(client_, computation_name);
    auto tuple = builder.Parameter(0, tuple_shape, "tuple");
    auto x = builder.GetTupleElement(tuple, 0);
    auto y = builder.GetTupleElement(tuple, 1);
    builder.Sub(x, y);
    auto build_status = builder.Build();
    EXPECT_IS_OK(build_status.status());
    return build_status.ConsumeValueOrDie();
  }

  Computation CreateSubR0Computation() {
    return CreateSubTupleComputation("SubR0", tuple_2_r0f32_);
  }

  Computation CreateSubR1Computation() {
    return CreateSubTupleComputation("SubR1", tuple_2_r1s2f32_);
  }

  Shape r0f32_ = ShapeUtil::MakeShape(F32, {});
  Shape tuple_2_r0f32_ = ShapeUtil::MakeTupleShape(
      {ShapeUtil::MakeShape(F32, {}), ShapeUtil::MakeShape(F32, {})});
  Shape tuple_2_r1s2f32_ = ShapeUtil::MakeTupleShape(
      {ShapeUtil::MakeShape(F32, {2}), ShapeUtil::MakeShape(F32, {2})});
  Shape empty_tuple_ = ShapeUtil::MakeTupleShape({});
  ErrorSpec error_spec_{0.001};
};

// Test true and false computations that do not take any parameters.
XLA_TEST_F(ConditionalOpTest, Parameters0) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operands = builder.Tuple({});
  auto true_computation = CreateR0F32ConstantComputation(56.0f);
  auto false_computation = CreateR0F32ConstantComputation(12.0f);
  auto result = builder.Conditional(pred, operands, true_computation, operands,
                                    false_computation);

  ComputeAndCompareR0<float>(&builder, 56.0f, {}, error_spec_);
}

// Test true and false computations that take in 1 parameter.
XLA_TEST_F(ConditionalOpTest, Parameters1) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto identity = CreateR0F32IdentityComputation();
  auto result =
      builder.Conditional(pred, operand1, identity, operand2, identity);

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test conditional with two different computations in the true and false cases
// that take in different arguments.
XLA_TEST_F(ConditionalOpTest, DiffComputationsDiffArgs) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.4f);
  auto operand2 = builder.ConstantR0<float>(12.6f);
  auto result =
      builder.Conditional(pred, operand1, CreateR0F32CeilComputation(),
                          operand2, CreateR0F32FloorComputation());

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test conditional with two different computations in the true and false cases
// that take in the same arguments.
XLA_TEST_F(ConditionalOpTest, DiffComputationsSameArg) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand = builder.ConstantR0<float>(12.6f);
  auto result = builder.Conditional(pred, operand, CreateR0F32CeilComputation(),
                                    operand, CreateR0F32FloorComputation());

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test conditional with the same computation in the true and false cases but
// take in different arguments.
XLA_TEST_F(ConditionalOpTest, SameComputationDiffArgs) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.4f);
  auto operand2 = builder.ConstantR0<float>(12.6f);
  auto floor = CreateR0F32FloorComputation();
  auto result = builder.Conditional(pred, operand1, floor, operand2, floor);

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test conditional with the same computation in the true and false cases that
// take in the same arguments.
XLA_TEST_F(ConditionalOpTest, SameComputationSameArg) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand = builder.ConstantR0<float>(12.6f);
  auto floor = CreateR0F32FloorComputation();
  auto result = builder.Conditional(pred, operand, floor, operand, floor);

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test conditional with different instances of the same computation in the true
// and false cases.
XLA_TEST_F(ConditionalOpTest, SameComputationDiffInstances) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.4f);
  auto operand2 = builder.ConstantR0<float>(12.6f);
  auto result =
      builder.Conditional(pred, operand1, CreateR0F32FloorComputation(),
                          operand2, CreateR0F32FloorComputation());

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test the case when a call invokes a computation that contains a conditional.
XLA_TEST_F(ConditionalOpTest, ConditionalWithCall) {
  Shape r0bool = ShapeUtil::MakeShape(PRED, {});
  ComputationBuilder inner_builder(client_, TestName() + ".inner_conditional");
  auto pred_cond = inner_builder.Parameter(0, r0bool, "param0");
  auto true_operand = inner_builder.Parameter(1, r0f32_, "param1");
  auto false_operand = inner_builder.Parameter(2, r0f32_, "param2");
  inner_builder.Conditional(pred_cond, true_operand,
                            CreateR0F32CeilComputation(), false_operand,
                            CreateR0F32FloorComputation());
  auto inner_builder_result = inner_builder.Build();

  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.4f);
  auto operand2 = builder.ConstantR0<float>(12.6f);
  builder.Call(inner_builder_result.ConsumeValueOrDie(),
               {pred, operand1, operand2});

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test true and false computations that take in 2 parameters and predicate is
// true.
XLA_TEST_F(ConditionalOpTest, Parameters2TrueBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR0Computation(),
                                    operands, CreateSubR0Computation());

  ComputeAndCompareR0<float>(&builder, 68.0f, {}, error_spec_);
}

// Test true and false computations that take in 2 parameters and predicate is
// false.
XLA_TEST_F(ConditionalOpTest, Parameters2FalseBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR0Computation(),
                                    operands, CreateSubR0Computation());

  ComputeAndCompareR0<float>(&builder, 44.0f, {}, error_spec_);
}

// Test true and false computations that take in 2 array parameters and
// predicate is true.
XLA_TEST_F(ConditionalOpTest, Parameters2ArrayTrueBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operand1 = builder.ConstantR1<float>({24.0f, 56.0f});
  auto operand2 = builder.ConstantR1<float>({10.0f, 11.0f});
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR1Computation(),
                                    operands, CreateSubR1Computation());

  ComputeAndCompareR1<float>(&builder, {34.0f, 67.0f}, {}, error_spec_);
}

// Test true and false computations that take in 2 array parameters and
// predicate is false.
XLA_TEST_F(ConditionalOpTest, Parameters2ArrayFalseBranch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR1<float>({24.0f, 56.0f});
  auto operand2 = builder.ConstantR1<float>({10.0f, 11.0f});
  auto operands = builder.Tuple({operand1, operand2});
  auto result = builder.Conditional(pred, operands, CreateAddR1Computation(),
                                    operands, CreateSubR1Computation());

  ComputeAndCompareR1<float>(&builder, {14.0f, 45.0f}, {}, error_spec_);
}

// Test the case where one conditional is nested within another.
XLA_TEST_F(ConditionalOpTest, NestedConditionals) {
  Shape r0bool = ShapeUtil::MakeShape(PRED, {});
  Shape tuple_shape = ShapeUtil::MakeTupleShape({r0bool, r0f32_, r0f32_});
  ComputationBuilder inner_builder(client_, TestName() + ".inner_conditional");
  auto param0 = inner_builder.Parameter(0, tuple_shape, "param0");
  auto pred_cond = inner_builder.GetTupleElement(param0, 0);
  auto true_operand = inner_builder.GetTupleElement(param0, 1);
  auto false_operand = inner_builder.GetTupleElement(param0, 2);
  inner_builder.Conditional(pred_cond, true_operand,
                            CreateR0F32CeilComputation(), false_operand,
                            CreateR0F32FloorComputation());
  auto inner_builder_result = inner_builder.Build();

  ComputationBuilder builder(client_, TestName());
  auto pred1 = builder.ConstantR0<bool>(true);
  auto pred2 = builder.ConstantR0<bool>(false);
  auto operand1 = builder.ConstantR0<float>(1.1f);
  auto operand2 = builder.ConstantR0<float>(12.2f);
  auto operand3 = builder.ConstantR0<float>(43.3f);
  auto tuple_operand = builder.Tuple({pred2, operand1, operand2});
  builder.Conditional(pred1, tuple_operand,
                      inner_builder_result.ConsumeValueOrDie(), operand3,
                      CreateR0F32IdentityComputation());

  ComputeAndCompareR0<float>(&builder, 12.0f, {}, error_spec_);
}

// Test a mismatch in the shape of the true operand and true computation.
XLA_TEST_F(ConditionalOpTest, ShapeMismatch) {
  ComputationBuilder builder(client_, TestName());
  auto pred = builder.ConstantR0<bool>(true);
  auto operand1 = builder.ConstantR0<float>(56.0f);
  auto operand2 = builder.ConstantR0<float>(12.0f);
  auto operands = builder.Tuple({operand1, operand2});
  builder.Conditional(pred, operands, CreateAddR1Computation(), operands,
                      CreateSubR0Computation());

  auto result = builder.Build();
  EXPECT_FALSE(result.ok());
  EXPECT_THAT(result.status().error_message(),
              ::testing::HasSubstr("true_operand must match the shape of the "
                                   "only parameter of true_computation"));
}

}  // namespace
}  // namespace xla
<|endoftext|>


<commit_before><commit_msg>Fix: The invariant mass histograms are empty<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/setup/daemon_controller.h"

#include <unistd.h>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/environment.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/md5.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "base/values.h"
#include "net/base/net_util.h"
#include "remoting/host/host_config.h"
#include "remoting/host/json_host_config.h"
#include "remoting/host/usage_stats_consent.h"

namespace remoting {

namespace {

const char kDaemonScript[] =
    "/opt/google/chrome-remote-desktop/chrome-remote-desktop";

// Timeout for running daemon script.
const int64 kDaemonTimeoutMs = 5000;

// Timeout for commands that require password prompt - 5 minutes.
const int64 kSudoTimeoutSeconds = 5 * 60;

std::string GetMd5(const std::string& value) {
  base::MD5Context ctx;
  base::MD5Init(&ctx);
  base::MD5Update(&ctx, value);
  base::MD5Digest digest;
  base::MD5Final(&digest, &ctx);
  return StringToLowerASCII(base::HexEncode(digest.a, sizeof(digest.a)));
}

class DaemonControllerLinux : public remoting::DaemonController {
 public:
  DaemonControllerLinux();

  virtual State GetState() OVERRIDE;
  virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE;
  virtual void SetConfigAndStart(
      scoped_ptr<base::DictionaryValue> config,
      bool consent,
      const CompletionCallback& done) OVERRIDE;
  virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
                            const CompletionCallback& done_callback) OVERRIDE;
  virtual void Stop(const CompletionCallback& done_callback) OVERRIDE;
  virtual void SetWindow(void* window_handle) OVERRIDE;
  virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE;
  virtual void GetUsageStatsConsent(
      const GetUsageStatsConsentCallback& done) OVERRIDE;

 private:
  base::FilePath GetConfigPath();

  void DoGetConfig(const GetConfigCallback& callback);
  void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
                           const CompletionCallback& done);
  void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
                      const CompletionCallback& done_callback);
  void DoStop(const CompletionCallback& done_callback);
  void DoGetVersion(const GetVersionCallback& done_callback);

  base::Thread file_io_thread_;

  DISALLOW_COPY_AND_ASSIGN(DaemonControllerLinux);
};

DaemonControllerLinux::DaemonControllerLinux()
    : file_io_thread_("DaemonControllerFileIO") {
  file_io_thread_.Start();
}

static bool GetScriptPath(base::FilePath* result) {
  base::FilePath candidate_exe(kDaemonScript);
  if (access(candidate_exe.value().c_str(), X_OK) == 0) {
    *result = candidate_exe;
    return true;
  }
  return false;
}

static bool RunHostScriptWithTimeout(
    const std::vector<std::string>& args,
    base::TimeDelta timeout,
    int* exit_code) {
  DCHECK(exit_code);

  // As long as we're relying on running an external binary from the
  // PATH, don't do it as root.
  if (getuid() == 0) {
    return false;
  }
  base::FilePath script_path;
  if (!GetScriptPath(&script_path)) {
    return false;
  }
  CommandLine command_line(script_path);
  for (unsigned int i = 0; i < args.size(); ++i) {
    command_line.AppendArg(args[i]);
  }
  base::ProcessHandle process_handle;

  // Redirect the child's stdout to the parent's stderr. In the case where this
  // parent process is a Native Messaging host, its stdout is used to send
  // messages to the web-app.
  base::FileHandleMappingVector fds_to_remap;
  fds_to_remap.push_back(std::pair<int, int>(STDERR_FILENO, STDOUT_FILENO));
  base::LaunchOptions options;
  options.fds_to_remap = &fds_to_remap;
  if (!base::LaunchProcess(command_line, options, &process_handle)) {
    return false;
  }

  if (!base::WaitForExitCodeWithTimeout(process_handle, exit_code, timeout)) {
    base::KillProcess(process_handle, 0, false);
    return false;
  }

  return true;
}

static bool RunHostScript(const std::vector<std::string>& args,
                          int* exit_code) {
  return RunHostScriptWithTimeout(
      args, base::TimeDelta::FromMilliseconds(kDaemonTimeoutMs), exit_code);
}

remoting::DaemonController::State DaemonControllerLinux::GetState() {
  std::vector<std::string> args;
  args.push_back("--check-running");
  int exit_code = 0;
  if (!RunHostScript(args, &exit_code)) {
    // TODO(jamiewalch): When we have a good story for installing, return
    // NOT_INSTALLED rather than NOT_IMPLEMENTED (the former suppresses
    // the relevant UI in the web-app).
    return remoting::DaemonController::STATE_NOT_IMPLEMENTED;
  }

  if (exit_code == 0) {
    return remoting::DaemonController::STATE_STARTED;
  } else {
    return remoting::DaemonController::STATE_STOPPED;
  }
}

void DaemonControllerLinux::GetConfig(const GetConfigCallback& callback) {
  // base::Unretained() is safe because we control lifetime of the thread.
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoGetConfig, base::Unretained(this), callback));
}

void DaemonControllerLinux::GetUsageStatsConsent(
    const GetUsageStatsConsentCallback& done) {
  // Crash dump collection is not implemented on Linux yet.
  // http://crbug.com/130678.
  done.Run(false, false, false);
}

void DaemonControllerLinux::SetConfigAndStart(
    scoped_ptr<base::DictionaryValue> config,
    bool /* consent */,
    const CompletionCallback& done) {
  // base::Unretained() is safe because we control lifetime of the thread.
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoSetConfigAndStart, base::Unretained(this),
      base::Passed(&config), done));
}

void DaemonControllerLinux::UpdateConfig(
    scoped_ptr<base::DictionaryValue> config,
    const CompletionCallback& done_callback) {
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoUpdateConfig, base::Unretained(this),
      base::Passed(&config), done_callback));
}

void DaemonControllerLinux::Stop(const CompletionCallback& done_callback) {
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoStop, base::Unretained(this),
      done_callback));
}

void DaemonControllerLinux::SetWindow(void* window_handle) {
  // noop
}

void DaemonControllerLinux::GetVersion(
    const GetVersionCallback& done_callback) {
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoGetVersion, base::Unretained(this),
      done_callback));
}

base::FilePath DaemonControllerLinux::GetConfigPath() {
  std::string filename = "host#" + GetMd5(net::GetHostName()) + ".json";
  return file_util::GetHomeDir().
      Append(".config/chrome-remote-desktop").Append(filename);
}

void DaemonControllerLinux::DoGetConfig(const GetConfigCallback& callback) {
  scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());

  if (GetState() != remoting::DaemonController::STATE_NOT_IMPLEMENTED) {
    JsonHostConfig config(GetConfigPath());
    if (config.Read()) {
      std::string value;
      if (config.GetString(kHostIdConfigPath, &value)) {
        result->SetString(kHostIdConfigPath, value);
      }
      if (config.GetString(kXmppLoginConfigPath, &value)) {
        result->SetString(kXmppLoginConfigPath, value);
      }
    } else {
      result.reset(); // Return NULL in case of error.
    }
  }

  callback.Run(result.Pass());
}

void DaemonControllerLinux::DoSetConfigAndStart(
    scoped_ptr<base::DictionaryValue> config,
    const CompletionCallback& done_callback) {

  // Add the user to chrome-remote-desktop group first.
  std::vector<std::string> args;
  args.push_back("--add-user");
  int exit_code;
  if (!RunHostScriptWithTimeout(
          args, base::TimeDelta::FromSeconds(kSudoTimeoutSeconds),
          &exit_code) ||
      exit_code != 0) {
    LOG(ERROR) << "Failed to add user to chrome-remote-desktop group.";
    done_callback.Run(RESULT_FAILED);
    return;
  }

  // Ensure the configuration directory exists.
  base::FilePath config_dir = GetConfigPath().DirName();
  if (!base::DirectoryExists(config_dir) &&
      !file_util::CreateDirectory(config_dir)) {
    LOG(ERROR) << "Failed to create config directory " << config_dir.value();
    done_callback.Run(RESULT_FAILED);
    return;
  }

  // Write config.
  JsonHostConfig config_file(GetConfigPath());
  if (!config_file.CopyFrom(config.get()) ||
      !config_file.Save()) {
    LOG(ERROR) << "Failed to update config file.";
    done_callback.Run(RESULT_FAILED);
    return;
  }

  // Finally start the host.
  args.clear();
  args.push_back("--start");
  AsyncResult result;
  if (RunHostScript(args, &exit_code)) {
    result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
  } else {
    result = RESULT_FAILED;
  }
  done_callback.Run(result);
}

void DaemonControllerLinux::DoUpdateConfig(
    scoped_ptr<base::DictionaryValue> config,
    const CompletionCallback& done_callback) {
  JsonHostConfig config_file(GetConfigPath());
  if (!config_file.Read() ||
      !config_file.CopyFrom(config.get()) ||
      !config_file.Save()) {
    LOG(ERROR) << "Failed to update config file.";
    done_callback.Run(RESULT_FAILED);
    return;
  }

  std::vector<std::string> args;
  args.push_back("--reload");
  AsyncResult result;
  int exit_code;
  if (RunHostScript(args, &exit_code)) {
    result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
  } else {
    result = RESULT_FAILED;
  }

  done_callback.Run(result);
}

void DaemonControllerLinux::DoStop(const CompletionCallback& done_callback) {
  std::vector<std::string> args;
  args.push_back("--stop");
  int exit_code = 0;
  AsyncResult result;
  if (RunHostScript(args, &exit_code)) {
    result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
  } else {
    result = RESULT_FAILED;
  }
  done_callback.Run(result);
}

void DaemonControllerLinux::DoGetVersion(
    const GetVersionCallback& done_callback) {
  base::FilePath script_path;
  if (!GetScriptPath(&script_path)) {
    done_callback.Run(std::string());
    return;
  }
  CommandLine command_line(script_path);
  command_line.AppendArg("--host-version");

  std::string version;
  int exit_code = 0;
  int result =
      base::GetAppOutputWithExitCode(command_line, &version, &exit_code);
  if (!result || exit_code != 0) {
    LOG(ERROR) << "Failed to run \"" << command_line.GetCommandLineString()
               << "\". Exit code: " << exit_code;
    done_callback.Run(std::string());
    return;
  }

  TrimWhitespaceASCII(version, TRIM_ALL, &version);
  if (!ContainsOnlyChars(version, "0123456789.")) {
    LOG(ERROR) << "Received invalid host version number: " << version;
    done_callback.Run(std::string());
    return;
  }

  done_callback.Run(version);
}

}  // namespace

scoped_ptr<DaemonController> remoting::DaemonController::Create() {
  return scoped_ptr<DaemonController>(new DaemonControllerLinux());
}

}  // namespace remoting
<commit_msg>Increase DaemonControllerLinux timeout for starting host service<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/setup/daemon_controller.h"

#include <unistd.h>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/environment.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/md5.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "base/values.h"
#include "net/base/net_util.h"
#include "remoting/host/host_config.h"
#include "remoting/host/json_host_config.h"
#include "remoting/host/usage_stats_consent.h"

namespace remoting {

namespace {

const char kDaemonScript[] =
    "/opt/google/chrome-remote-desktop/chrome-remote-desktop";

// Timeout for running daemon script. The script itself sets a timeout when
// waiting for the host to come online, so the setting here should be at least
// as long.
const int64 kDaemonTimeoutMs = 60000;

// Timeout for commands that require password prompt - 5 minutes.
const int64 kSudoTimeoutSeconds = 5 * 60;

std::string GetMd5(const std::string& value) {
  base::MD5Context ctx;
  base::MD5Init(&ctx);
  base::MD5Update(&ctx, value);
  base::MD5Digest digest;
  base::MD5Final(&digest, &ctx);
  return StringToLowerASCII(base::HexEncode(digest.a, sizeof(digest.a)));
}

class DaemonControllerLinux : public remoting::DaemonController {
 public:
  DaemonControllerLinux();

  virtual State GetState() OVERRIDE;
  virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE;
  virtual void SetConfigAndStart(
      scoped_ptr<base::DictionaryValue> config,
      bool consent,
      const CompletionCallback& done) OVERRIDE;
  virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
                            const CompletionCallback& done_callback) OVERRIDE;
  virtual void Stop(const CompletionCallback& done_callback) OVERRIDE;
  virtual void SetWindow(void* window_handle) OVERRIDE;
  virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE;
  virtual void GetUsageStatsConsent(
      const GetUsageStatsConsentCallback& done) OVERRIDE;

 private:
  base::FilePath GetConfigPath();

  void DoGetConfig(const GetConfigCallback& callback);
  void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
                           const CompletionCallback& done);
  void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
                      const CompletionCallback& done_callback);
  void DoStop(const CompletionCallback& done_callback);
  void DoGetVersion(const GetVersionCallback& done_callback);

  base::Thread file_io_thread_;

  DISALLOW_COPY_AND_ASSIGN(DaemonControllerLinux);
};

DaemonControllerLinux::DaemonControllerLinux()
    : file_io_thread_("DaemonControllerFileIO") {
  file_io_thread_.Start();
}

static bool GetScriptPath(base::FilePath* result) {
  base::FilePath candidate_exe(kDaemonScript);
  if (access(candidate_exe.value().c_str(), X_OK) == 0) {
    *result = candidate_exe;
    return true;
  }
  return false;
}

static bool RunHostScriptWithTimeout(
    const std::vector<std::string>& args,
    base::TimeDelta timeout,
    int* exit_code) {
  DCHECK(exit_code);

  // As long as we're relying on running an external binary from the
  // PATH, don't do it as root.
  if (getuid() == 0) {
    return false;
  }
  base::FilePath script_path;
  if (!GetScriptPath(&script_path)) {
    return false;
  }
  CommandLine command_line(script_path);
  for (unsigned int i = 0; i < args.size(); ++i) {
    command_line.AppendArg(args[i]);
  }
  base::ProcessHandle process_handle;

  // Redirect the child's stdout to the parent's stderr. In the case where this
  // parent process is a Native Messaging host, its stdout is used to send
  // messages to the web-app.
  base::FileHandleMappingVector fds_to_remap;
  fds_to_remap.push_back(std::pair<int, int>(STDERR_FILENO, STDOUT_FILENO));
  base::LaunchOptions options;
  options.fds_to_remap = &fds_to_remap;
  if (!base::LaunchProcess(command_line, options, &process_handle)) {
    return false;
  }

  if (!base::WaitForExitCodeWithTimeout(process_handle, exit_code, timeout)) {
    base::KillProcess(process_handle, 0, false);
    return false;
  }

  return true;
}

static bool RunHostScript(const std::vector<std::string>& args,
                          int* exit_code) {
  return RunHostScriptWithTimeout(
      args, base::TimeDelta::FromMilliseconds(kDaemonTimeoutMs), exit_code);
}

remoting::DaemonController::State DaemonControllerLinux::GetState() {
  std::vector<std::string> args;
  args.push_back("--check-running");
  int exit_code = 0;
  if (!RunHostScript(args, &exit_code)) {
    // TODO(jamiewalch): When we have a good story for installing, return
    // NOT_INSTALLED rather than NOT_IMPLEMENTED (the former suppresses
    // the relevant UI in the web-app).
    return remoting::DaemonController::STATE_NOT_IMPLEMENTED;
  }

  if (exit_code == 0) {
    return remoting::DaemonController::STATE_STARTED;
  } else {
    return remoting::DaemonController::STATE_STOPPED;
  }
}

void DaemonControllerLinux::GetConfig(const GetConfigCallback& callback) {
  // base::Unretained() is safe because we control lifetime of the thread.
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoGetConfig, base::Unretained(this), callback));
}

void DaemonControllerLinux::GetUsageStatsConsent(
    const GetUsageStatsConsentCallback& done) {
  // Crash dump collection is not implemented on Linux yet.
  // http://crbug.com/130678.
  done.Run(false, false, false);
}

void DaemonControllerLinux::SetConfigAndStart(
    scoped_ptr<base::DictionaryValue> config,
    bool /* consent */,
    const CompletionCallback& done) {
  // base::Unretained() is safe because we control lifetime of the thread.
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoSetConfigAndStart, base::Unretained(this),
      base::Passed(&config), done));
}

void DaemonControllerLinux::UpdateConfig(
    scoped_ptr<base::DictionaryValue> config,
    const CompletionCallback& done_callback) {
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoUpdateConfig, base::Unretained(this),
      base::Passed(&config), done_callback));
}

void DaemonControllerLinux::Stop(const CompletionCallback& done_callback) {
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoStop, base::Unretained(this),
      done_callback));
}

void DaemonControllerLinux::SetWindow(void* window_handle) {
  // noop
}

void DaemonControllerLinux::GetVersion(
    const GetVersionCallback& done_callback) {
  file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
      &DaemonControllerLinux::DoGetVersion, base::Unretained(this),
      done_callback));
}

base::FilePath DaemonControllerLinux::GetConfigPath() {
  std::string filename = "host#" + GetMd5(net::GetHostName()) + ".json";
  return file_util::GetHomeDir().
      Append(".config/chrome-remote-desktop").Append(filename);
}

void DaemonControllerLinux::DoGetConfig(const GetConfigCallback& callback) {
  scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());

  if (GetState() != remoting::DaemonController::STATE_NOT_IMPLEMENTED) {
    JsonHostConfig config(GetConfigPath());
    if (config.Read()) {
      std::string value;
      if (config.GetString(kHostIdConfigPath, &value)) {
        result->SetString(kHostIdConfigPath, value);
      }
      if (config.GetString(kXmppLoginConfigPath, &value)) {
        result->SetString(kXmppLoginConfigPath, value);
      }
    } else {
      result.reset(); // Return NULL in case of error.
    }
  }

  callback.Run(result.Pass());
}

void DaemonControllerLinux::DoSetConfigAndStart(
    scoped_ptr<base::DictionaryValue> config,
    const CompletionCallback& done_callback) {

  // Add the user to chrome-remote-desktop group first.
  std::vector<std::string> args;
  args.push_back("--add-user");
  int exit_code;
  if (!RunHostScriptWithTimeout(
          args, base::TimeDelta::FromSeconds(kSudoTimeoutSeconds),
          &exit_code) ||
      exit_code != 0) {
    LOG(ERROR) << "Failed to add user to chrome-remote-desktop group.";
    done_callback.Run(RESULT_FAILED);
    return;
  }

  // Ensure the configuration directory exists.
  base::FilePath config_dir = GetConfigPath().DirName();
  if (!base::DirectoryExists(config_dir) &&
      !file_util::CreateDirectory(config_dir)) {
    LOG(ERROR) << "Failed to create config directory " << config_dir.value();
    done_callback.Run(RESULT_FAILED);
    return;
  }

  // Write config.
  JsonHostConfig config_file(GetConfigPath());
  if (!config_file.CopyFrom(config.get()) ||
      !config_file.Save()) {
    LOG(ERROR) << "Failed to update config file.";
    done_callback.Run(RESULT_FAILED);
    return;
  }

  // Finally start the host.
  args.clear();
  args.push_back("--start");
  AsyncResult result;
  if (RunHostScript(args, &exit_code)) {
    result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
  } else {
    result = RESULT_FAILED;
  }
  done_callback.Run(result);
}

void DaemonControllerLinux::DoUpdateConfig(
    scoped_ptr<base::DictionaryValue> config,
    const CompletionCallback& done_callback) {
  JsonHostConfig config_file(GetConfigPath());
  if (!config_file.Read() ||
      !config_file.CopyFrom(config.get()) ||
      !config_file.Save()) {
    LOG(ERROR) << "Failed to update config file.";
    done_callback.Run(RESULT_FAILED);
    return;
  }

  std::vector<std::string> args;
  args.push_back("--reload");
  AsyncResult result;
  int exit_code;
  if (RunHostScript(args, &exit_code)) {
    result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
  } else {
    result = RESULT_FAILED;
  }

  done_callback.Run(result);
}

void DaemonControllerLinux::DoStop(const CompletionCallback& done_callback) {
  std::vector<std::string> args;
  args.push_back("--stop");
  int exit_code = 0;
  AsyncResult result;
  if (RunHostScript(args, &exit_code)) {
    result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
  } else {
    result = RESULT_FAILED;
  }
  done_callback.Run(result);
}

void DaemonControllerLinux::DoGetVersion(
    const GetVersionCallback& done_callback) {
  base::FilePath script_path;
  if (!GetScriptPath(&script_path)) {
    done_callback.Run(std::string());
    return;
  }
  CommandLine command_line(script_path);
  command_line.AppendArg("--host-version");

  std::string version;
  int exit_code = 0;
  int result =
      base::GetAppOutputWithExitCode(command_line, &version, &exit_code);
  if (!result || exit_code != 0) {
    LOG(ERROR) << "Failed to run \"" << command_line.GetCommandLineString()
               << "\". Exit code: " << exit_code;
    done_callback.Run(std::string());
    return;
  }

  TrimWhitespaceASCII(version, TRIM_ALL, &version);
  if (!ContainsOnlyChars(version, "0123456789.")) {
    LOG(ERROR) << "Received invalid host version number: " << version;
    done_callback.Run(std::string());
    return;
  }

  done_callback.Run(version);
}

}  // namespace

scoped_ptr<DaemonController> remoting::DaemonController::Create() {
  return scoped_ptr<DaemonController>(new DaemonControllerLinux());
}

}  // namespace remoting
<|endoftext|>


<commit_before>#ifndef __STAN__IO__MCMC__WRITER__HPP
#define __STAN__IO__MCMC__WRITER__HPP

#include <ostream>
#include <iomanip>

#include <vector>
#include <string>

#include <stan/mcmc/sample.hpp>
#include <stan/mcmc/base_mcmc.hpp>
#include <stan/model/prob_grad.hpp>

namespace stan {

  namespace io {

    template <class M>
    class mcmc_writer {

    public:

      mcmc_writer(std::ostream* sample_stream,
                  std::ostream* diagnostic_stream): _sample_stream(sample_stream),
                                                    _diagnostic_stream(diagnostic_stream) {}

      void print_sample_names(stan::mcmc::sample& sample,
                              stan::mcmc::base_mcmc& sampler,
                              M& model) {

        if(!_sample_stream) return;

        std::vector<std::string> names;

        sample.get_sample_param_names(names);
        sampler.get_sampler_param_names(names);
        model.constrained_param_names(names);

        (*_sample_stream) << names.at(0);
        for (int i = 1; i < names.size(); ++i) {
          (*_sample_stream) << "," << names.at(i);
        }
        (*_sample_stream) << std::endl;

      }

      void print_sample_params(stan::mcmc::sample& sample,
                               stan::mcmc::base_mcmc& sampler,
                               M& model) {

        if(!_sample_stream) return;

        std::vector<double> values;

        sample.get_sample_params(values);
        sampler.get_sampler_params(values);

        std::vector<double> model_values;

        model.write_array_params(const_cast<std::vector<double>&>(sample.cont_params()),
                                 const_cast<std::vector<int>&>(sample.disc_params()),
                                 model_values);

        values.insert(values.end(), model_values.begin(), model_values.end());

        (*_sample_stream) << values.at(0);
        for (int i = 1; i < values.size(); ++i) {
          (*_sample_stream) << "," << values.at(i);
        }
        (*_sample_stream) << std::endl;

      }

      void print_adapt_finish(stan::mcmc::base_mcmc& sampler, std::ostream* stream) {

        if(!stream) return;

        *stream << "# Adaptation terminated" << std::endl;
        sampler.write_sampler_state(stream);

      }

      void print_adapt_finish(stan::mcmc::base_mcmc& sampler) {
        print_adapt_finish(sampler, _sample_stream);
        print_adapt_finish(sampler, _diagnostic_stream);
      }

      void print_diagnostic_names(stan::mcmc::sample& sample,
                                  stan::mcmc::base_mcmc& sampler,
                                  M& model) {

        if(!_diagnostic_stream) return;

        std::vector<std::string> names;

        sample.get_sample_param_names(names);
        sampler.get_sampler_param_names(names);

        std::vector<std::string> model_names;
        model.unconstrained_param_names(model_names, false, false);

        sampler.get_sampler_diagnostic_names(model_names, names);

        (*_diagnostic_stream) << names.at(0);
        for (int i = 1; i < names.size(); ++i) {
          (*_diagnostic_stream) << "," << names.at(i);
        }
        (*_diagnostic_stream) << std::endl;

      }

      void print_diagnostic_params(stan::mcmc::sample& sample,
                                    stan::mcmc::base_mcmc& sampler) {

        if(!_diagnostic_stream) return;

        std::vector<double> values;

        sample.get_sample_params(values);
        sampler.get_sampler_params(values);
        sampler.get_sampler_diagnostics(values);

        (*_diagnostic_stream) << values.at(0);
        for (int i = 1; i < values.size(); ++i) {
          (*_diagnostic_stream) << "," << values.at(i);
        }
        (*_diagnostic_stream) << std::endl;

      }

      void print_timing(double warmDeltaT, double sampleDeltaT, std::ostream* stream) {
        if(!stream) return;

        std::string prefix("Elapsed Time: ");

        *stream << std::endl
                << prefix << warmDeltaT
                << " seconds (Warm Up)"  << std::endl
                << std::string(prefix.size(), ' ') << sampleDeltaT
                << " seconds (Sampling)"  << std::endl
                << std::string(prefix.size(), ' ') << warmDeltaT + sampleDeltaT
                << " seconds (Total)"  << std::endl
                << std::endl;
      }

      void print_timing(double warmDeltaT, double sampleDeltaT) {
        print_timing(warmDeltaT, sampleDeltaT, _sample_stream);
        print_timing(warmDeltaT, sampleDeltaT, _diagnostic_stream);
        print_timing(warmDeltaT, sampleDeltaT, &std::cout);
      }

    private:

      std::ostream* _sample_stream;
      std::ostream* _diagnostic_stream;

    };

  } //io

} // stan

#endif<commit_msg>Don't include transformed/generated parameter names in header<commit_after>#ifndef __STAN__IO__MCMC__WRITER__HPP
#define __STAN__IO__MCMC__WRITER__HPP

#include <ostream>
#include <iomanip>

#include <vector>
#include <string>

#include <stan/mcmc/sample.hpp>
#include <stan/mcmc/base_mcmc.hpp>
#include <stan/model/prob_grad.hpp>

namespace stan {

  namespace io {

    template <class M>
    class mcmc_writer {

    public:

      mcmc_writer(std::ostream* sample_stream,
                  std::ostream* diagnostic_stream): _sample_stream(sample_stream),
                                                    _diagnostic_stream(diagnostic_stream) {}

      void print_sample_names(stan::mcmc::sample& sample,
                              stan::mcmc::base_mcmc& sampler,
                              M& model) {

        if(!_sample_stream) return;

        std::vector<std::string> names;

        sample.get_sample_param_names(names);
        sampler.get_sampler_param_names(names);
        model.constrained_param_names(names, false, false);

        (*_sample_stream) << names.at(0);
        for (int i = 1; i < names.size(); ++i) {
          (*_sample_stream) << "," << names.at(i);
        }
        (*_sample_stream) << std::endl;

      }

      void print_sample_params(stan::mcmc::sample& sample,
                               stan::mcmc::base_mcmc& sampler,
                               M& model) {

        if(!_sample_stream) return;

        std::vector<double> values;

        sample.get_sample_params(values);
        sampler.get_sampler_params(values);

        std::vector<double> model_values;

        model.write_array_params(const_cast<std::vector<double>&>(sample.cont_params()),
                                 const_cast<std::vector<int>&>(sample.disc_params()),
                                 model_values);

        values.insert(values.end(), model_values.begin(), model_values.end());

        (*_sample_stream) << values.at(0);
        for (int i = 1; i < values.size(); ++i) {
          (*_sample_stream) << "," << values.at(i);
        }
        (*_sample_stream) << std::endl;

      }

      void print_adapt_finish(stan::mcmc::base_mcmc& sampler, std::ostream* stream) {

        if(!stream) return;

        *stream << "# Adaptation terminated" << std::endl;
        sampler.write_sampler_state(stream);

      }

      void print_adapt_finish(stan::mcmc::base_mcmc& sampler) {
        print_adapt_finish(sampler, _sample_stream);
        print_adapt_finish(sampler, _diagnostic_stream);
      }

      void print_diagnostic_names(stan::mcmc::sample& sample,
                                  stan::mcmc::base_mcmc& sampler,
                                  M& model) {

        if(!_diagnostic_stream) return;

        std::vector<std::string> names;

        sample.get_sample_param_names(names);
        sampler.get_sampler_param_names(names);

        std::vector<std::string> model_names;
        model.unconstrained_param_names(model_names, false, false);

        sampler.get_sampler_diagnostic_names(model_names, names);

        (*_diagnostic_stream) << names.at(0);
        for (int i = 1; i < names.size(); ++i) {
          (*_diagnostic_stream) << "," << names.at(i);
        }
        (*_diagnostic_stream) << std::endl;

      }

      void print_diagnostic_params(stan::mcmc::sample& sample,
                                    stan::mcmc::base_mcmc& sampler) {

        if(!_diagnostic_stream) return;

        std::vector<double> values;

        sample.get_sample_params(values);
        sampler.get_sampler_params(values);
        sampler.get_sampler_diagnostics(values);

        (*_diagnostic_stream) << values.at(0);
        for (int i = 1; i < values.size(); ++i) {
          (*_diagnostic_stream) << "," << values.at(i);
        }
        (*_diagnostic_stream) << std::endl;

      }

      void print_timing(double warmDeltaT, double sampleDeltaT, std::ostream* stream) {
        if(!stream) return;

        std::string prefix("Elapsed Time: ");

        *stream << std::endl
                << prefix << warmDeltaT
                << " seconds (Warm Up)"  << std::endl
                << std::string(prefix.size(), ' ') << sampleDeltaT
                << " seconds (Sampling)"  << std::endl
                << std::string(prefix.size(), ' ') << warmDeltaT + sampleDeltaT
                << " seconds (Total)"  << std::endl
                << std::endl;
      }

      void print_timing(double warmDeltaT, double sampleDeltaT) {
        print_timing(warmDeltaT, sampleDeltaT, _sample_stream);
        print_timing(warmDeltaT, sampleDeltaT, _diagnostic_stream);
        print_timing(warmDeltaT, sampleDeltaT, &std::cout);
      }

    private:

      std::ostream* _sample_stream;
      std::ostream* _diagnostic_stream;

    };

  } //io

} // stan

#endif<|endoftext|>


<commit_before><commit_msg>loplugin:literaltoboolconversion<commit_after><|endoftext|>


<commit_before>/*
* Number Theory Functions
* (C) 1999-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/numthry.h>
#include <botan/reducer.h>
#include <botan/internal/bit_ops.h>
#include <algorithm>

namespace Botan {

namespace {

/*
* Miller-Rabin Primality Tester
*/
class MillerRabin_Test
   {
   public:
      bool is_witness(const BigInt& nonce);
      MillerRabin_Test(const BigInt& num);
   private:
      BigInt n, r, n_minus_1;
      size_t s;
      Fixed_Exponent_Power_Mod pow_mod;
      Modular_Reducer reducer;
   };

/*
* Miller-Rabin Test, as described in Handbook of Applied Cryptography
* section 4.24
*/
bool MillerRabin_Test::is_witness(const BigInt& a)
   {
   if(a < 2 || a >= n_minus_1)
      throw Invalid_Argument("Bad size for nonce in Miller-Rabin test");

   BigInt y = pow_mod(a);
   if(y == 1 || y == n_minus_1)
      return false;

   for(size_t i = 1; i != s; ++i)
      {
      y = reducer.square(y);

      if(y == 1) // found a non-trivial square root
         return true;

      if(y == n_minus_1) // -1, trivial square root, so give up
         return false;
      }

   if(y != n_minus_1) // fails Fermat test
      return true;

   return false;
   }

/*
* Miller-Rabin Constructor
*/
MillerRabin_Test::MillerRabin_Test(const BigInt& num)
   {
   if(num.is_even() || num < 3)
      throw Invalid_Argument("MillerRabin_Test: Invalid number for testing");

   n = num;
   n_minus_1 = n - 1;
   s = low_zero_bits(n_minus_1);
   r = n_minus_1 >> s;

   pow_mod = Fixed_Exponent_Power_Mod(r, n);
   reducer = Modular_Reducer(n);
   }

/*
* Miller-Rabin Iterations
*/
size_t miller_rabin_test_iterations(size_t bits, size_t level)
   {
   struct mapping { size_t bits; size_t verify_iter; size_t check_iter; };

   const mapping tests[] = {
      {   50, 55, 25 },
      {  100, 38, 22 },
      {  160, 32, 18 },
      {  163, 31, 17 },
      {  168, 30, 16 },
      {  177, 29, 16 },
      {  181, 28, 15 },
      {  185, 27, 15 },
      {  190, 26, 15 },
      {  195, 25, 14 },
      {  201, 24, 14 },
      {  208, 23, 14 },
      {  215, 22, 13 },
      {  222, 21, 13 },
      {  231, 20, 13 },
      {  241, 19, 12 },
      {  252, 18, 12 },
      {  264, 17, 12 },
      {  278, 16, 11 },
      {  294, 15, 10 },
      {  313, 14,  9 },
      {  334, 13,  8 },
      {  360, 12,  8 },
      {  392, 11,  7 },
      {  430, 10,  7 },
      {  479,  9,  6 },
      {  542,  8,  6 },
      {  626,  7,  5 },
      {  746,  6,  4 },
      {  926,  5,  3 },
      { 1232,  4,  2 },
      { 1853,  3,  2 },
      {    0,  0,  0 }
   };

   for(size_t i = 0; tests[i].bits; ++i)
      {
      if(bits <= tests[i].bits)
         {
         if(level >= 2)
            return tests[i].verify_iter;
         else if(level == 1)
            return tests[i].check_iter;
         else if(level == 0)
            return std::max<size_t>(tests[i].check_iter / 4, 1);
         }
      }

   return level > 0 ? 2 : 1; // for large inputs
   }

}

/*
* Return the number of 0 bits at the end of n
*/
size_t low_zero_bits(const BigInt& n)
   {
   size_t low_zero = 0;

   if(n.is_positive() && n.is_nonzero())
      {
      for(size_t i = 0; i != n.size(); ++i)
         {
         word x = n[i];

         if(x)
            {
            low_zero += ctz(x);
            break;
            }
         else
            low_zero += BOTAN_MP_WORD_BITS;
         }
      }

   return low_zero;
   }

/*
* Calculate the GCD
*/
BigInt gcd(const BigInt& a, const BigInt& b)
   {
   if(a.is_zero() || b.is_zero()) return 0;
   if(a == 1 || b == 1)           return 1;

   BigInt x = a, y = b;
   x.set_sign(BigInt::Positive);
   y.set_sign(BigInt::Positive);
   size_t shift = std::min(low_zero_bits(x), low_zero_bits(y));

   x >>= shift;
   y >>= shift;

   while(x.is_nonzero())
      {
      x >>= low_zero_bits(x);
      y >>= low_zero_bits(y);
      if(x >= y) { x -= y; x >>= 1; }
      else       { y -= x; y >>= 1; }
      }

   return (y << shift);
   }

/*
* Calculate the LCM
*/
BigInt lcm(const BigInt& a, const BigInt& b)
   {
   return ((a * b) / gcd(a, b));
   }

namespace {

/*
* If the modulus is odd, then we can avoid computing A and C. This is
* a critical path algorithm in some instances and an odd modulus is
* the common case for crypto, so worth special casing. See note 14.64
* in Handbook of Applied Cryptography for more details.
*/
BigInt inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod)
   {
   BigInt u = mod, v = n;
   BigInt B = 0, D = 1;

   while(u.is_nonzero())
      {
      const size_t u_zero_bits = low_zero_bits(u);
      u >>= u_zero_bits;
      for(size_t i = 0; i != u_zero_bits; ++i)
         {
         if(B.is_odd())
            { B -= mod; }
         B >>= 1;
         }

      const size_t v_zero_bits = low_zero_bits(v);
      v >>= v_zero_bits;
      for(size_t i = 0; i != v_zero_bits; ++i)
         {
         if(D.is_odd())
            { D -= mod; }
         D >>= 1;
         }

      if(u >= v) { u -= v; B -= D; }
      else       { v -= u; D -= B; }
      }

   if(v != 1)
      return 0; // no modular inverse

   while(D.is_negative()) D += mod;
   while(D >= mod) D -= mod;

   return D;
   }

}

/*
* Find the Modular Inverse
*/
BigInt inverse_mod(const BigInt& n, const BigInt& mod)
   {
   if(mod.is_zero())
      throw BigInt::DivideByZero();
   if(mod.is_negative() || n.is_negative())
      throw Invalid_Argument("inverse_mod: arguments must be non-negative");

   if(n.is_zero() || (n.is_even() && mod.is_even()))
      return 0; // fast fail checks

   if(mod.is_odd())
      return inverse_mod_odd_modulus(n, mod);

   BigInt u = mod, v = n;
   BigInt A = 1, B = 0, C = 0, D = 1;

   while(u.is_nonzero())
      {
      const size_t u_zero_bits = low_zero_bits(u);
      u >>= u_zero_bits;
      for(size_t i = 0; i != u_zero_bits; ++i)
         {
         if(A.is_odd() || B.is_odd())
            { A += n; B -= mod; }
         A >>= 1; B >>= 1;
         }

      const size_t v_zero_bits = low_zero_bits(v);
      v >>= v_zero_bits;
      for(size_t i = 0; i != v_zero_bits; ++i)
         {
         if(C.is_odd() || D.is_odd())
            { C += n; D -= mod; }
         C >>= 1; D >>= 1;
         }

      if(u >= v) { u -= v; A -= C; B -= D; }
      else       { v -= u; C -= A; D -= B; }
      }

   if(v != 1)
      return 0; // no modular inverse

   while(D.is_negative()) D += mod;
   while(D >= mod) D -= mod;

   return D;
   }

/*
* Modular Exponentiation
*/
BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod)
   {
   Power_Mod pow_mod(mod);

   /*
   * Calling set_base before set_exponent means we end up using a
   * minimal window. This makes sense given that here we know that any
   * precomputation is wasted.
   */
   pow_mod.set_base(base);
   pow_mod.set_exponent(exp);
   return pow_mod.execute();
   }

/*
* Test for primaility using Miller-Rabin
*/
bool primality_test(const BigInt& n,
                    RandomNumberGenerator& rng,
                    size_t level)
   {
   const size_t PREF_NONCE_BITS = 64;

   if(n == 2)
      return true;
   if(n <= 1 || n.is_even())
      return false;

   // Fast path testing for small numbers (<= 65521)
   if(n <= PRIMES[PRIME_TABLE_SIZE-1])
      {
      const word num = n.word_at(0);

      for(size_t i = 0; PRIMES[i]; ++i)
         {
         if(num == PRIMES[i])
            return true;
         if(num < PRIMES[i])
            return false;
         }

      return false;
      }

   if(level > 2)
      level = 2;

   const size_t NONCE_BITS = std::min(n.bits() - 2, PREF_NONCE_BITS);

   MillerRabin_Test mr(n);

   const size_t tests = miller_rabin_test_iterations(n.bits(), level);

   BigInt nonce;
   for(size_t i = 0; i != tests; ++i)
      {
      while(nonce < 2 || nonce >= (n-1))
         nonce.randomize(rng, NONCE_BITS);

      if(mr.is_witness(nonce))
         return false;
      }
   return true;
   }

}
<commit_msg>Increase default Miller-Rabin nonce to 192 bits<commit_after>/*
* Number Theory Functions
* (C) 1999-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/numthry.h>
#include <botan/reducer.h>
#include <botan/internal/bit_ops.h>
#include <algorithm>

namespace Botan {

namespace {

/*
* Miller-Rabin Primality Tester
*/
class MillerRabin_Test
   {
   public:
      bool is_witness(const BigInt& nonce);
      MillerRabin_Test(const BigInt& num);
   private:
      BigInt n, r, n_minus_1;
      size_t s;
      Fixed_Exponent_Power_Mod pow_mod;
      Modular_Reducer reducer;
   };

/*
* Miller-Rabin Test, as described in Handbook of Applied Cryptography
* section 4.24
*/
bool MillerRabin_Test::is_witness(const BigInt& a)
   {
   if(a < 2 || a >= n_minus_1)
      throw Invalid_Argument("Bad size for nonce in Miller-Rabin test");

   BigInt y = pow_mod(a);
   if(y == 1 || y == n_minus_1)
      return false;

   for(size_t i = 1; i != s; ++i)
      {
      y = reducer.square(y);

      if(y == 1) // found a non-trivial square root
         return true;

      if(y == n_minus_1) // -1, trivial square root, so give up
         return false;
      }

   if(y != n_minus_1) // fails Fermat test
      return true;

   return false;
   }

/*
* Miller-Rabin Constructor
*/
MillerRabin_Test::MillerRabin_Test(const BigInt& num)
   {
   if(num.is_even() || num < 3)
      throw Invalid_Argument("MillerRabin_Test: Invalid number for testing");

   n = num;
   n_minus_1 = n - 1;
   s = low_zero_bits(n_minus_1);
   r = n_minus_1 >> s;

   pow_mod = Fixed_Exponent_Power_Mod(r, n);
   reducer = Modular_Reducer(n);
   }

/*
* Miller-Rabin Iterations
*/
size_t miller_rabin_test_iterations(size_t bits, size_t level)
   {
   struct mapping { size_t bits; size_t verify_iter; size_t check_iter; };

   const mapping tests[] = {
      {   50, 55, 25 },
      {  100, 38, 22 },
      {  160, 32, 18 },
      {  163, 31, 17 },
      {  168, 30, 16 },
      {  177, 29, 16 },
      {  181, 28, 15 },
      {  185, 27, 15 },
      {  190, 26, 15 },
      {  195, 25, 14 },
      {  201, 24, 14 },
      {  208, 23, 14 },
      {  215, 22, 13 },
      {  222, 21, 13 },
      {  231, 20, 13 },
      {  241, 19, 12 },
      {  252, 18, 12 },
      {  264, 17, 12 },
      {  278, 16, 11 },
      {  294, 15, 10 },
      {  313, 14,  9 },
      {  334, 13,  8 },
      {  360, 12,  8 },
      {  392, 11,  7 },
      {  430, 10,  7 },
      {  479,  9,  6 },
      {  542,  8,  6 },
      {  626,  7,  5 },
      {  746,  6,  4 },
      {  926,  5,  3 },
      { 1232,  4,  2 },
      { 1853,  3,  2 },
      {    0,  0,  0 }
   };

   for(size_t i = 0; tests[i].bits; ++i)
      {
      if(bits <= tests[i].bits)
         {
         if(level >= 2)
            return tests[i].verify_iter;
         else if(level == 1)
            return tests[i].check_iter;
         else if(level == 0)
            return std::max<size_t>(tests[i].check_iter / 4, 1);
         }
      }

   return level > 0 ? 2 : 1; // for large inputs
   }

}

/*
* Return the number of 0 bits at the end of n
*/
size_t low_zero_bits(const BigInt& n)
   {
   size_t low_zero = 0;

   if(n.is_positive() && n.is_nonzero())
      {
      for(size_t i = 0; i != n.size(); ++i)
         {
         word x = n[i];

         if(x)
            {
            low_zero += ctz(x);
            break;
            }
         else
            low_zero += BOTAN_MP_WORD_BITS;
         }
      }

   return low_zero;
   }

/*
* Calculate the GCD
*/
BigInt gcd(const BigInt& a, const BigInt& b)
   {
   if(a.is_zero() || b.is_zero()) return 0;
   if(a == 1 || b == 1)           return 1;

   BigInt x = a, y = b;
   x.set_sign(BigInt::Positive);
   y.set_sign(BigInt::Positive);
   size_t shift = std::min(low_zero_bits(x), low_zero_bits(y));

   x >>= shift;
   y >>= shift;

   while(x.is_nonzero())
      {
      x >>= low_zero_bits(x);
      y >>= low_zero_bits(y);
      if(x >= y) { x -= y; x >>= 1; }
      else       { y -= x; y >>= 1; }
      }

   return (y << shift);
   }

/*
* Calculate the LCM
*/
BigInt lcm(const BigInt& a, const BigInt& b)
   {
   return ((a * b) / gcd(a, b));
   }

namespace {

/*
* If the modulus is odd, then we can avoid computing A and C. This is
* a critical path algorithm in some instances and an odd modulus is
* the common case for crypto, so worth special casing. See note 14.64
* in Handbook of Applied Cryptography for more details.
*/
BigInt inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod)
   {
   BigInt u = mod, v = n;
   BigInt B = 0, D = 1;

   while(u.is_nonzero())
      {
      const size_t u_zero_bits = low_zero_bits(u);
      u >>= u_zero_bits;
      for(size_t i = 0; i != u_zero_bits; ++i)
         {
         if(B.is_odd())
            { B -= mod; }
         B >>= 1;
         }

      const size_t v_zero_bits = low_zero_bits(v);
      v >>= v_zero_bits;
      for(size_t i = 0; i != v_zero_bits; ++i)
         {
         if(D.is_odd())
            { D -= mod; }
         D >>= 1;
         }

      if(u >= v) { u -= v; B -= D; }
      else       { v -= u; D -= B; }
      }

   if(v != 1)
      return 0; // no modular inverse

   while(D.is_negative()) D += mod;
   while(D >= mod) D -= mod;

   return D;
   }

}

/*
* Find the Modular Inverse
*/
BigInt inverse_mod(const BigInt& n, const BigInt& mod)
   {
   if(mod.is_zero())
      throw BigInt::DivideByZero();
   if(mod.is_negative() || n.is_negative())
      throw Invalid_Argument("inverse_mod: arguments must be non-negative");

   if(n.is_zero() || (n.is_even() && mod.is_even()))
      return 0; // fast fail checks

   if(mod.is_odd())
      return inverse_mod_odd_modulus(n, mod);

   BigInt u = mod, v = n;
   BigInt A = 1, B = 0, C = 0, D = 1;

   while(u.is_nonzero())
      {
      const size_t u_zero_bits = low_zero_bits(u);
      u >>= u_zero_bits;
      for(size_t i = 0; i != u_zero_bits; ++i)
         {
         if(A.is_odd() || B.is_odd())
            { A += n; B -= mod; }
         A >>= 1; B >>= 1;
         }

      const size_t v_zero_bits = low_zero_bits(v);
      v >>= v_zero_bits;
      for(size_t i = 0; i != v_zero_bits; ++i)
         {
         if(C.is_odd() || D.is_odd())
            { C += n; D -= mod; }
         C >>= 1; D >>= 1;
         }

      if(u >= v) { u -= v; A -= C; B -= D; }
      else       { v -= u; C -= A; D -= B; }
      }

   if(v != 1)
      return 0; // no modular inverse

   while(D.is_negative()) D += mod;
   while(D >= mod) D -= mod;

   return D;
   }

/*
* Modular Exponentiation
*/
BigInt power_mod(const BigInt& base, const BigInt& exp, const BigInt& mod)
   {
   Power_Mod pow_mod(mod);

   /*
   * Calling set_base before set_exponent means we end up using a
   * minimal window. This makes sense given that here we know that any
   * precomputation is wasted.
   */
   pow_mod.set_base(base);
   pow_mod.set_exponent(exp);
   return pow_mod.execute();
   }

/*
* Test for primaility using Miller-Rabin
*/
bool primality_test(const BigInt& n,
                    RandomNumberGenerator& rng,
                    size_t level)
   {
   if(n == 2)
      return true;
   if(n <= 1 || n.is_even())
      return false;

   // Fast path testing for small numbers (<= 65521)
   if(n <= PRIMES[PRIME_TABLE_SIZE-1])
      {
      const word num = n.word_at(0);

      for(size_t i = 0; PRIMES[i]; ++i)
         {
         if(num == PRIMES[i])
            return true;
         if(num < PRIMES[i])
            return false;
         }

      return false;
      }

   if(level > 2)
      level = 2;

   const size_t PREF_NONCE_BITS = 192;

   const size_t NONCE_BITS = std::min(n.bits() - 2, PREF_NONCE_BITS);

   MillerRabin_Test mr(n);

   const size_t tests = miller_rabin_test_iterations(n.bits(), level);

   BigInt nonce;
   for(size_t i = 0; i != tests; ++i)
      {
      while(nonce < 2 || nonce >= (n-1))
         nonce.randomize(rng, NONCE_BITS);

      if(mr.is_witness(nonce))
         return false;
      }
   return true;
   }

}
<|endoftext|>


<commit_before>//
//  Copyright Silvin Lubecki 2010
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//

#include "Test.h"
#include "openclam/cl.hpp"
#include <math.h>
#include <CL/cl.h>

namespace
{
    void *srcA, *srcB, *dst;
    void* Golden;

    cl_context cxGPUContext;
    cl_command_queue cqCommandQue;
    cl_device_id* cdDevices;
    cl_program cpProgram;
    cl_kernel ckKernel;
    cl_mem cmDevSrcA;
    cl_mem cmDevSrcB;
    cl_mem cmDevDst;
    size_t szGlobalWorkSize;
    size_t szLocalWorkSize;
    size_t szParmDataBytes;
    size_t szKernelLength;
    cl_int ciErr1, ciErr2;
    char* cPathAndName = NULL;
    char* cSourceCL = NULL;
    int iNumElements = 11444777;

    KERNEL( const char * addKernel,
    void VectorAdd( GLOBAL const float* a, GLOBAL const float* b, GLOBAL float* c, int iNumElements )
    {
        const int iGID = get_global_id( 0 );
        if( iGID >= iNumElements )
            return;
        c[ iGID ] = a[ iGID ] + b[ iGID ];
    } );

    size_t shrRoundUp( int group_size, int global_size )
    {
        int r = global_size % group_size;
        if( r == 0 )
            return global_size;
        return global_size + group_size - r;
    }
    void shrFillArray( float* pfData, int iSize )
    {
        int i;
        const float fScale = 1.0f / (float)RAND_MAX;
        for( i = 0; i < iSize; ++i )
            pfData[i] = fScale * rand();
    }
    int shrDiffArray( const float* pfResult1, const float* pfResult2, int iNumElements )
    {
        int iErrorCount = 0, i;
        for( i = 0; i < iNumElements; i++ )
            if( fabs( pfResult2[ i ] - pfResult1[ i ] ) > 1e-5 )
                iErrorCount++;
        return iErrorCount;
    }
    // "Golden" Host processing vector addition function for comparison purposes
    // *********************************************************************
    void VectorAddHost( const float* pfData1, const float* pfData2, float* pfResult, int iNumElements )
    {
        int i;
        for ( i = 0; i < iNumElements; i++ )
            pfResult[ i ] = pfData1[ i ] + pfData2[ i ];
    }

}

BOOST_AUTO_TEST_CASE( test3 )
{
    // set and log Global and Local work size dimensions
    szLocalWorkSize = 256;
    szGlobalWorkSize = shrRoundUp( (int)szLocalWorkSize, iNumElements );  // rounded up to the nearest multiple of the LocalWorkSize

    // Allocate and initialize host arrays
    srcA = (void *)malloc( sizeof( cl_float ) * szGlobalWorkSize );
    srcB = (void *)malloc( sizeof( cl_float ) * szGlobalWorkSize );
    dst = (void *)malloc( sizeof(cl_float ) * szGlobalWorkSize );
    Golden = (void *)malloc( sizeof(cl_float) * iNumElements );
    shrFillArray( (float*)srcA, iNumElements );
    shrFillArray( (float*)srcB, iNumElements );

    // Create the OpenCL context on a GPU device
    cxGPUContext = clCreateContextFromType( 0, CL_DEVICE_TYPE_GPU, NULL, NULL, &ciErr1 );

    // Get the list of GPU devices associated with context
    ciErr1 = clGetContextInfo( cxGPUContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes );
    cdDevices = ( cl_device_id* )malloc( szParmDataBytes );
    ciErr1 |= clGetContextInfo( cxGPUContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL );

    // Create a command-queue
    cqCommandQue = clCreateCommandQueue( cxGPUContext, cdDevices[ 0 ], 0, &ciErr1 );

    // Allocate the OpenCL buffer memory objects for source and result on the device GMEM
    cmDevSrcA = clCreateBuffer( cxGPUContext, CL_MEM_READ_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr1 );
    cmDevSrcB = clCreateBuffer( cxGPUContext, CL_MEM_READ_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr2 );
    ciErr1 |= ciErr2;
    cmDevDst = clCreateBuffer( cxGPUContext, CL_MEM_WRITE_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr2 );
    ciErr1 |= ciErr2;

    // Create the program
    szKernelLength = strlen( addKernel );
    cpProgram = clCreateProgramWithSource( cxGPUContext, 1, (const char **)&addKernel, &szKernelLength, &ciErr1 );

    // Build the program
    ciErr1 = clBuildProgram( cpProgram, 0, NULL, NULL, NULL, NULL );

    // Create the kernel
    ckKernel = clCreateKernel( cpProgram, "VectorAdd", &ciErr1 );

    // Set the Argument values
    ciErr1 = clSetKernelArg( ckKernel, 0, sizeof(cl_mem), (void*)&cmDevSrcA );
    ciErr1 |= clSetKernelArg( ckKernel, 1, sizeof(cl_mem), (void*)&cmDevSrcB );
    ciErr1 |= clSetKernelArg( ckKernel, 2, sizeof(cl_mem), (void*)&cmDevDst );
    ciErr1 |= clSetKernelArg( ckKernel, 3, sizeof(cl_int), (void*)&iNumElements );

    // --------------------------------------------------------
    // Start Core sequence... copy input data to GPU, compute, copy results back

    // Asynchronous write of data to GPU device
    ciErr1 = clEnqueueWriteBuffer( cqCommandQue, cmDevSrcA, CL_FALSE, 0, sizeof(cl_float) * szGlobalWorkSize, srcA, 0, NULL, NULL );
    ciErr1 |= clEnqueueWriteBuffer( cqCommandQue, cmDevSrcB, CL_FALSE, 0, sizeof(cl_float) * szGlobalWorkSize, srcB, 0, NULL, NULL );

    // Launch kernel
    ciErr1 = clEnqueueNDRangeKernel( cqCommandQue, ckKernel, 1, NULL, &szGlobalWorkSize, &szLocalWorkSize, 0, NULL, NULL );

    // Synchronous/blocking read of results, and check accumulated errors
    ciErr1 = clEnqueueReadBuffer( cqCommandQue, cmDevDst, CL_TRUE, 0, sizeof(cl_float) * szGlobalWorkSize, dst, 0, NULL, NULL );
    //--------------------------------------------------------

    // Compute and compare results for golden-host and report errors and pass/fail
    VectorAddHost( (const float*)srcA, (const float*)srcB, (float*)Golden, iNumElements );
    BOOST_CHECK_EQUAL( 0, shrDiffArray(( const float*)dst, (const float*)Golden, iNumElements ) );
    free( srcA );
    free( srcB );
    free( dst );
    free( Golden );
    free( cdDevices );
}
<commit_msg>clean up<commit_after>//
//  Copyright Silvin Lubecki 2010
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//

#include "Test.h"
#include "openclam/cl.hpp"
#include <CL/cl.h>

namespace
{
    void *srcA, *srcB, *dst;
    void* Golden;

    cl_context cxGPUContext;
    cl_command_queue cqCommandQue;
    cl_device_id* cdDevices;
    cl_program cpProgram;
    cl_kernel ckKernel;
    cl_mem cmDevSrcA;
    cl_mem cmDevSrcB;
    cl_mem cmDevDst;
    size_t szGlobalWorkSize;
    size_t szLocalWorkSize;
    size_t szParmDataBytes;
    size_t szKernelLength;
    cl_int ciErr1, ciErr2;
    char* cPathAndName = NULL;
    char* cSourceCL = NULL;
    int iNumElements = 11444777;

    KERNEL( const char * addKernel,
    void VectorAdd( GLOBAL const float* a, GLOBAL const float* b, GLOBAL float* c, int iNumElements )
    {
        const int iGID = get_global_id( 0 );
        if( iGID >= iNumElements )
            return;
        c[ iGID ] = a[ iGID ] + b[ iGID ];
    } );

    size_t shrRoundUp( int group_size, int global_size )
    {
        int r = global_size % group_size;
        if( r == 0 )
            return global_size;
        return global_size + group_size - r;
    }
    void shrFillArray( float* pfData, int iSize )
    {
        int i;
        const float fScale = 1.0f / (float)RAND_MAX;
        for( i = 0; i < iSize; ++i )
            pfData[i] = fScale * rand();
    }
    int shrDiffArray( const float* pfResult1, const float* pfResult2, int iNumElements )
    {
        int iErrorCount = 0, i;
        for( i = 0; i < iNumElements; i++ )
            if( std::abs( pfResult2[ i ] - pfResult1[ i ] ) > 1e-5 )
                iErrorCount++;
        return iErrorCount;
    }
    // "Golden" Host processing vector addition function for comparison purposes
    // *********************************************************************
    void VectorAddHost( const float* pfData1, const float* pfData2, float* pfResult, int iNumElements )
    {
        int i;
        for ( i = 0; i < iNumElements; i++ )
            pfResult[ i ] = pfData1[ i ] + pfData2[ i ];
    }

}

BOOST_AUTO_TEST_CASE( test3 )
{
    // set and log Global and Local work size dimensions
    szLocalWorkSize = 256;
    szGlobalWorkSize = shrRoundUp( (int)szLocalWorkSize, iNumElements );  // rounded up to the nearest multiple of the LocalWorkSize

    // Allocate and initialize host arrays
    srcA = (void *)malloc( sizeof( cl_float ) * szGlobalWorkSize );
    srcB = (void *)malloc( sizeof( cl_float ) * szGlobalWorkSize );
    dst = (void *)malloc( sizeof(cl_float ) * szGlobalWorkSize );
    Golden = (void *)malloc( sizeof(cl_float) * iNumElements );
    shrFillArray( (float*)srcA, iNumElements );
    shrFillArray( (float*)srcB, iNumElements );

    // Create the OpenCL context on a GPU device
    cxGPUContext = clCreateContextFromType( 0, CL_DEVICE_TYPE_GPU, NULL, NULL, &ciErr1 );

    // Get the list of GPU devices associated with context
    ciErr1 = clGetContextInfo( cxGPUContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes );
    cdDevices = ( cl_device_id* )malloc( szParmDataBytes );
    ciErr1 |= clGetContextInfo( cxGPUContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL );

    // Create a command-queue
    cqCommandQue = clCreateCommandQueue( cxGPUContext, cdDevices[ 0 ], 0, &ciErr1 );

    // Allocate the OpenCL buffer memory objects for source and result on the device GMEM
    cmDevSrcA = clCreateBuffer( cxGPUContext, CL_MEM_READ_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr1 );
    cmDevSrcB = clCreateBuffer( cxGPUContext, CL_MEM_READ_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr2 );
    ciErr1 |= ciErr2;
    cmDevDst = clCreateBuffer( cxGPUContext, CL_MEM_WRITE_ONLY, sizeof(cl_float) * szGlobalWorkSize, NULL, &ciErr2 );
    ciErr1 |= ciErr2;

    // Create the program
    szKernelLength = strlen( addKernel );
    cpProgram = clCreateProgramWithSource( cxGPUContext, 1, (const char **)&addKernel, &szKernelLength, &ciErr1 );

    // Build the program
    ciErr1 = clBuildProgram( cpProgram, 0, NULL, NULL, NULL, NULL );

    // Create the kernel
    ckKernel = clCreateKernel( cpProgram, "VectorAdd", &ciErr1 );

    // Set the Argument values
    ciErr1 = clSetKernelArg( ckKernel, 0, sizeof(cl_mem), (void*)&cmDevSrcA );
    ciErr1 |= clSetKernelArg( ckKernel, 1, sizeof(cl_mem), (void*)&cmDevSrcB );
    ciErr1 |= clSetKernelArg( ckKernel, 2, sizeof(cl_mem), (void*)&cmDevDst );
    ciErr1 |= clSetKernelArg( ckKernel, 3, sizeof(cl_int), (void*)&iNumElements );

    // --------------------------------------------------------
    // Start Core sequence... copy input data to GPU, compute, copy results back

    // Asynchronous write of data to GPU device
    ciErr1 = clEnqueueWriteBuffer( cqCommandQue, cmDevSrcA, CL_FALSE, 0, sizeof(cl_float) * szGlobalWorkSize, srcA, 0, NULL, NULL );
    ciErr1 |= clEnqueueWriteBuffer( cqCommandQue, cmDevSrcB, CL_FALSE, 0, sizeof(cl_float) * szGlobalWorkSize, srcB, 0, NULL, NULL );

    // Launch kernel
    ciErr1 = clEnqueueNDRangeKernel( cqCommandQue, ckKernel, 1, NULL, &szGlobalWorkSize, &szLocalWorkSize, 0, NULL, NULL );

    // Synchronous/blocking read of results, and check accumulated errors
    ciErr1 = clEnqueueReadBuffer( cqCommandQue, cmDevDst, CL_TRUE, 0, sizeof(cl_float) * szGlobalWorkSize, dst, 0, NULL, NULL );
    //--------------------------------------------------------

    // Compute and compare results for golden-host and report errors and pass/fail
    VectorAddHost( (const float*)srcA, (const float*)srcB, (float*)Golden, iNumElements );
    BOOST_CHECK_EQUAL( 0, shrDiffArray(( const float*)dst, (const float*)Golden, iNumElements ) );
    free( srcA );
    free( srcB );
    free( dst );
    free( Golden );
    free( cdDevices );
}
<|endoftext|>