<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iomanip>
#include "orc_proto.pb.h"

using namespace org::apache::hadoop::hive::ql::io::orc;

long getTotalPaddingSize(Footer footer);
StripeFooter readStripeFooter(StripeInformation stripe);

std::ifstream input;

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

	// Read the input arguments
	const char ROWINDEX_PREFIX[] = "--rowindex=";
	const int ROWINDEX_PREFIX_LENGTH = strlen(ROWINDEX_PREFIX);

	std::vector<char*> files;
	std::vector<int> rowIndexCols;

	char* pChar ;
	for (int i=1; i<argc; i++)
	{
		if (argv[i][0]=='-' & argv[i][1]=='-') {
			pChar = strstr(argv[i], ROWINDEX_PREFIX);
			if (pChar == argv[i]) {	// the argument string starts with ROWINDEX_PREFIX
				pChar = strtok(argv[i]+ROWINDEX_PREFIX_LENGTH,",");
				while (pChar != NULL)
				{
					rowIndexCols.push_back(atoi(pChar));
					pChar = strtok(NULL,",");
				};
			} else {
				std::cout << "Unknown argument " << argv[i] << std::endl ;
				std::cout << "Usage: localfiledump <filename1> [... <filenameN>] [--rowindex=i1,i2,...,iN]" << std::endl ;
			};
		} else {
			files.push_back(argv[i]);
		};
	};

	for(int fileIx=0; fileIx<files.size(); fileIx++) {
		std::cout << "Structure for " << files[fileIx] << std::endl;

		// FIXIT: Instead of allocating memory for each part of the ORC file (postscript, footer, etc),
		// find a way to provide the stream + initial position + length to the ParseFromXXX() functions
		// Java implementation of protobuf has it, but C++ seems to lack.
		char* buffer ;

		// Determine the file size
		// FIXIT: Should be done using filesystem info
		input.open(files[fileIx], std::ios::in | std::ios::binary);
		input.seekg(0,input.end);
		unsigned int fileSize = input.tellg();

		// Read the postscript size
		input.seekg(fileSize-1);
		unsigned int postscriptSize = (int)input.get() ;

		// Read the postscript
		input.seekg(fileSize - postscriptSize-1);
		buffer = new char[postscriptSize];
		input.read(buffer, postscriptSize);
		PostScript postscript ;
		postscript.ParseFromArray(buffer, postscriptSize);
		delete[] buffer;

		// Everything but the postscript is compressed
		//CompressionCodec codec ;
		switch (postscript.compression())
		{
			  case NONE:
				  //codec = NULL;
				  break;
			  case ZLIB:
				  //codec = ZlibCodec(); break;
			  case SNAPPY:
				  //codec = SnappyCodec(); break;
			  case LZO:
				  //codec = LzoCodec(); break;
			  default:
				  std::cout << "Unsupported compression!" << std::endl ;
				  input.close();
				  return -1;
		};

		int footerSize = postscript.footerlength();
		int metadataSize = postscript.metadatalength();

		// Read the metadata
		input.seekg(fileSize - 1 - postscriptSize - footerSize - metadataSize);
		buffer = new char[metadataSize];
		input.read(buffer, metadataSize);
		Metadata metadata ;
		metadata.ParseFromArray(buffer, metadataSize);
		delete[] buffer;

		// Read the footer
		//input.seekg(fileSize -1 - postscriptSize-footerSize);
		buffer = new char[footerSize];
		input.read(buffer, footerSize);
		Footer footer ;
		footer.ParseFromArray(buffer, footerSize);
		delete[] buffer;

		std::cout << "Rows: " << footer.numberofrows() << std::endl;
		std::cout << "Compression: " << postscript.compression() << std::endl;
		if (postscript.compression() != NONE)
			std::cout << "Compression size: " << postscript.compressionblocksize() << std::endl;
		std::cout << "Type: " ;
		for (int typeIx=0; typeIx < footer.types_size(); typeIx++) {
			Type type = footer.types(typeIx);
			type.PrintDebugString();
		};

		std::cout << "\nStripe Statistics:" << std::endl;

		StripeInformation stripe ;
		Stream section;
		ColumnEncoding encoding;
		for (int stripeIx=0; stripeIx<footer.stripes_size(); stripeIx++)
		{
			std::cout << "  Stripe " << stripeIx+1 <<": " << std::endl ;
			stripe = footer.stripes(stripeIx);
			stripe.PrintDebugString();

			long offset = stripe.offset() + stripe.indexlength() + stripe.datalength();
			int tailLength = stripe.footerlength();

			// read the stripe footer
			input.seekg(offset);
			buffer = new char[tailLength];
			input.read(buffer, tailLength);

			StripeFooter stripeFooter;
			stripeFooter.ParseFromArray(buffer, tailLength);
			//stripeFooter.PrintDebugString();
			long stripeStart = stripe.offset();
			long sectionStart = stripeStart;
			for (int streamIx=0; streamIx<stripeFooter.streams_size(); streamIx++) {
				section = stripeFooter.streams(streamIx);
				std::cout << "    Stream: column " << section.column()  << " section "
						  << section.kind() << " start: " << sectionStart << " length " << section.length() << std::endl;
				sectionStart += section.length();
			};
			for (int columnIx=0; columnIx<stripeFooter.columns_size(); columnIx++) {
				encoding = stripeFooter.columns(columnIx);
				std::cout << "    Encoding column " << columnIx << ": " << encoding.kind() ;
				if (encoding.kind() == ColumnEncoding_Kind_DICTIONARY || encoding.kind() == ColumnEncoding_Kind_DICTIONARY_V2)
					std::cout << "[" << encoding.dictionarysize() << "]";
				std::cout << std::endl;
			};

			/*
	        if (!rowIndexCols.empty()) {
	        	std::vector<RowIndex> indices;
	        	long offset = stripeStart;

	        	stripeFooter = readStripeFooter(stripe);

	        	for(int streamIx=0; streamIx< stripeFooter.streams_size();streamIx++) {
	        		section = stripeFooter.streams(streamIx);
	        		if (section.kind() == Stream_Kind_ROW_INDEX) {
	        			int col = section.column();

	        			int streamLength = section.length();
	        			char* bufferRowIndex = new char[streamLength];
	        			input.seekg(offset);
	        			input.read(bufferRowIndex, streamLength);
	        			RowIndex rowIndex;
	        			rowIndex.ParseFromArray(bufferRowIndex, streamLength);
	        			delete[] bufferRowIndex ;
	        			indices.push_back(rowIndex);
	        		};
	        		offset += section.length();
	        	};

	        	for (int rowIx = 0; rowIx < rowIndexCols.size(); rowIx++) {
	        		int col = rowIndexCols[rowIx];
	        		std::cout << "    Row group index column " << col << ":" ;
	        		if (col >= indices.size())  {
	        			std::cout << " not found" << std::endl ;
	        			continue;
	        		};
	        		RowIndex index = indices[col];
	        		for (int entryIx = 0; entryIx < index.entry_size(); ++entryIx) {
	        			std::cout << "\n      Entry " << entryIx << ":";
	        			RowIndexEntry entry = index.entry(entryIx);
	        			ColumnStatistics colStats = entry.statistics();
	        			std::cout << " number of values: " << colStats.numberofvalues() ;
	        			for (int posIx = 0; posIx < entry.positions_size(); ++posIx) {
	        				if (posIx != 0)
	        					std::cout << ",";
	        				std::cout << entry.positions(posIx);
	        			};
	        		};
	        		std::cout <<std::endl ;
	        	};
	        };*/
		};

		long paddedBytes = getTotalPaddingSize(footer);
		// empty ORC file is ~45 bytes. Assumption here is file length always >0
		double percentPadding = ((double) paddedBytes / (double) fileSize) * 100;
		std::cout << "File length: " << fileSize << " bytes" << std::endl;
		std::cout <<"Padding length: " << paddedBytes << " bytes" << std::endl;
		std::cout <<"Padding ratio: " << std::fixed << std::setprecision(2) << percentPadding << " %" << std::endl;

		input.close();
	};

	google::protobuf::ShutdownProtobufLibrary();

    return 0;
}

StripeFooter readStripeFooter(StripeInformation stripe) {
	long offset = stripe.offset() + stripe.indexlength() + stripe.datalength();
	int tailLength = (int) stripe.footerlength();

	char* buffer = new char[tailLength];
	input.seekg(offset);
	input.read(buffer, tailLength);
	StripeFooter stripeFooter ;
	stripeFooter.ParseFromArray(buffer, tailLength);
	delete[] buffer;

	return stripeFooter;
}

long getTotalPaddingSize(Footer footer) {
	long paddedBytes = 0;
	StripeInformation stripe;
	for (int stripeIx=1; stripeIx<footer.stripes_size(); stripeIx++) {
		stripe = footer.stripes(stripeIx-1);
		long prevStripeOffset = stripe.offset();
		long prevStripeLen = stripe.datalength() + stripe.indexlength() + stripe.footerlength();
		paddedBytes += footer.stripes(stripeIx).offset() - (prevStripeOffset + prevStripeLen);
	};
	return paddedBytes;
}

<commit_msg>Modified LocalFileDump.cc to print more detailed metadata information.<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iomanip>
#include "orc_proto.pb.h"

using namespace org::apache::hadoop::hive::ql::io::orc;

long getTotalPaddingSize(Footer footer);
StripeFooter readStripeFooter(StripeInformation stripe);

std::ifstream input;

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

	// Read the input arguments
	const char ROWINDEX_PREFIX[] = "--rowindex=";
	const int ROWINDEX_PREFIX_LENGTH = strlen(ROWINDEX_PREFIX);

	std::vector<char*> files;
	std::vector<int> rowIndexCols;

	char* pChar ;
	for (int i=1; i<argc; i++)
	{
		if (argv[i][0]=='-' & argv[i][1]=='-') {
			pChar = strstr(argv[i], ROWINDEX_PREFIX);
			if (pChar == argv[i]) {	// the argument string starts with ROWINDEX_PREFIX
				pChar = strtok(argv[i]+ROWINDEX_PREFIX_LENGTH,",");
				while (pChar != NULL)
				{
					rowIndexCols.push_back(atoi(pChar));
					pChar = strtok(NULL,",");
				};
			} else {
				std::cout << "Unknown argument " << argv[i] << std::endl ;
				std::cout << "Usage: localfiledump <filename1> [... <filenameN>] [--rowindex=i1,i2,...,iN]" << std::endl ;
			};
		} else {
			files.push_back(argv[i]);
		};
	};

	for(int fileIx=0; fileIx<files.size(); fileIx++) {
		std::cout << "Structure for " << files[fileIx] << std::endl;

		// FIXIT: Instead of allocating memory for each part of the ORC file (postscript, footer, etc),
		// find a way to provide the stream + initial position + length to the ParseFromXXX() functions
		// Java implementation of protobuf has it, but C++ seems to lack.
		char* buffer ;

		// Determine the file size
		// FIXIT: Should be done using filesystem info
		input.open(files[fileIx], std::ios::in | std::ios::binary);
		input.seekg(0,input.end);
		unsigned int fileSize = input.tellg();

		// Read the postscript size
		input.seekg(fileSize-1);
		unsigned int postscriptSize = (int)input.get() ;

		// Read the postscript
		input.seekg(fileSize - postscriptSize-1);
		buffer = new char[postscriptSize];
		input.read(buffer, postscriptSize);
		PostScript postscript ;
		postscript.ParseFromArray(buffer, postscriptSize);
		delete[] buffer;
		std::cout << std::endl << "Postscript: " << std::endl ;
		postscript.PrintDebugString();

		// Everything but the postscript is compressed
		//CompressionCodec codec ;
		switch (postscript.compression())
		{
			  case NONE:
				  //codec = NULL;
				  break;
			  case ZLIB:
				  //codec = ZlibCodec(); break;
			  case SNAPPY:
				  //codec = SnappyCodec(); break;
			  case LZO:
				  //codec = LzoCodec(); break;
			  default:
				  std::cout << "Unsupported compression!" << std::endl ;
				  input.close();
				  return -1;
		};

		int footerSize = postscript.footerlength();
		int metadataSize = postscript.metadatalength();

		// Read the metadata
		input.seekg(fileSize - 1 - postscriptSize - footerSize - metadataSize);
		buffer = new char[metadataSize];
		input.read(buffer, metadataSize);
		Metadata metadata ;
		metadata.ParseFromArray(buffer, metadataSize);
		delete[] buffer;
		std::cout << std::endl << "Metadata: " << std::endl ;
		postscript.PrintDebugString();

		// Read the footer
		//input.seekg(fileSize -1 - postscriptSize-footerSize);
		buffer = new char[footerSize];
		input.read(buffer, footerSize);
		Footer footer ;
		footer.ParseFromArray(buffer, footerSize);
		delete[] buffer;
		std::cout << std::endl << "Footer: " << std::endl ;
		postscript.PrintDebugString();

		std::cout << std::endl << "Rows: " << footer.numberofrows() << std::endl;
		std::cout << "Compression: " << postscript.compression() << std::endl;
		if (postscript.compression() != NONE)
			std::cout << "Compression size: " << postscript.compressionblocksize() << std::endl;
		std::cout << "Type: " ;
		for (int typeIx=0; typeIx < footer.types_size(); typeIx++) {
			Type type = footer.types(typeIx);
			type.PrintDebugString();
		};

		std::cout << "\nStripe Statistics:" << std::endl;

		StripeInformation stripe ;
		Stream section;
		ColumnEncoding encoding;
		for (int stripeIx=0; stripeIx<footer.stripes_size(); stripeIx++)
		{
			std::cout << "  Stripe " << stripeIx+1 <<": " << std::endl ;
			stripe = footer.stripes(stripeIx);
			stripe.PrintDebugString();

			long offset = stripe.offset() + stripe.indexlength() + stripe.datalength();
			int tailLength = stripe.footerlength();

			// read the stripe footer
			input.seekg(offset);
			buffer = new char[tailLength];
			input.read(buffer, tailLength);

			StripeFooter stripeFooter;
			stripeFooter.ParseFromArray(buffer, tailLength);
			//stripeFooter.PrintDebugString();
			long stripeStart = stripe.offset();
			long sectionStart = stripeStart;
			for (int streamIx=0; streamIx<stripeFooter.streams_size(); streamIx++) {
				section = stripeFooter.streams(streamIx);
				std::cout << "    Stream: column " << section.column()  << " section "
						  << section.kind() << " start: " << sectionStart << " length " << section.length() << std::endl;
				sectionStart += section.length();
			};
			for (int columnIx=0; columnIx<stripeFooter.columns_size(); columnIx++) {
				encoding = stripeFooter.columns(columnIx);
				std::cout << "    Encoding column " << columnIx << ": " << encoding.kind() ;
				if (encoding.kind() == ColumnEncoding_Kind_DICTIONARY || encoding.kind() == ColumnEncoding_Kind_DICTIONARY_V2)
					std::cout << "[" << encoding.dictionarysize() << "]";
				std::cout << std::endl;
			};

			/*
	        if (!rowIndexCols.empty()) {
	        	std::vector<RowIndex> indices;
	        	long offset = stripeStart;

	        	stripeFooter = readStripeFooter(stripe);

	        	for(int streamIx=0; streamIx< stripeFooter.streams_size();streamIx++) {
	        		section = stripeFooter.streams(streamIx);
	        		if (section.kind() == Stream_Kind_ROW_INDEX) {
	        			int col = section.column();

	        			int streamLength = section.length();
	        			char* bufferRowIndex = new char[streamLength];
	        			input.seekg(offset);
	        			input.read(bufferRowIndex, streamLength);
	        			RowIndex rowIndex;
	        			rowIndex.ParseFromArray(bufferRowIndex, streamLength);
	        			delete[] bufferRowIndex ;
	        			indices.push_back(rowIndex);
	        		};
	        		offset += section.length();
	        	};

	        	for (int rowIx = 0; rowIx < rowIndexCols.size(); rowIx++) {
	        		int col = rowIndexCols[rowIx];
	        		std::cout << "    Row group index column " << col << ":" ;
	        		if (col >= indices.size())  {
	        			std::cout << " not found" << std::endl ;
	        			continue;
	        		};
	        		RowIndex index = indices[col];
	        		for (int entryIx = 0; entryIx < index.entry_size(); ++entryIx) {
	        			std::cout << "\n      Entry " << entryIx << ":";
	        			RowIndexEntry entry = index.entry(entryIx);
	        			ColumnStatistics colStats = entry.statistics();
	        			std::cout << " number of values: " << colStats.numberofvalues() ;
	        			for (int posIx = 0; posIx < entry.positions_size(); ++posIx) {
	        				if (posIx != 0)
	        					std::cout << ",";
	        				std::cout << entry.positions(posIx);
	        			};
	        		};
	        		std::cout <<std::endl ;
	        	};
	        };*/
		};

		long paddedBytes = getTotalPaddingSize(footer);
		// empty ORC file is ~45 bytes. Assumption here is file length always >0
		double percentPadding = ((double) paddedBytes / (double) fileSize) * 100;
		std::cout << "File length: " << fileSize << " bytes" << std::endl;
		std::cout <<"Padding length: " << paddedBytes << " bytes" << std::endl;
		std::cout <<"Padding ratio: " << std::fixed << std::setprecision(2) << percentPadding << " %" << std::endl;

		input.close();
	};

	google::protobuf::ShutdownProtobufLibrary();

    return 0;
}

StripeFooter readStripeFooter(StripeInformation stripe) {
	long offset = stripe.offset() + stripe.indexlength() + stripe.datalength();
	int tailLength = (int) stripe.footerlength();

	char* buffer = new char[tailLength];
	input.seekg(offset);
	input.read(buffer, tailLength);
	StripeFooter stripeFooter ;
	stripeFooter.ParseFromArray(buffer, tailLength);
	delete[] buffer;

	return stripeFooter;
}

long getTotalPaddingSize(Footer footer) {
	long paddedBytes = 0;
	StripeInformation stripe;
	for (int stripeIx=1; stripeIx<footer.stripes_size(); stripeIx++) {
		stripe = footer.stripes(stripeIx-1);
		long prevStripeOffset = stripe.offset();
		long prevStripeLen = stripe.datalength() + stripe.indexlength() + stripe.footerlength();
		paddedBytes += footer.stripes(stripeIx).offset() - (prevStripeOffset + prevStripeLen);
	};
	return paddedBytes;
}

<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <string>

#include <mesos/secret/resolver.hpp>

#include <process/future.hpp>
#include <process/gtest.hpp>

#include <stout/gtest.hpp>

#include "tests/mesos.hpp"

using process::Future;
using process::Owned;

using mesos::internal::slave::Fetcher;
using mesos::internal::slave::MesosContainerizer;

using mesos::master::detector::MasterDetector;

using std::string;

namespace mesos {
namespace internal {
namespace tests {

const char SECRET_VALUE[] = "password";
const char SECRET_ENV_NAME[] = "My_SeCrEt";

class EnvironmentSecretIsolatorTest : public MesosTest {};

// This test verifies that the environment secrets are resolved when launching a
// task.
TEST_F(EnvironmentSecretIsolatorTest, ResolveSecret)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  mesos::internal::slave::Flags flags = CreateSlaveFlags();

  Fetcher fetcher(flags);
  Try<SecretResolver*> secretResolver = SecretResolver::create();
  EXPECT_SOME(secretResolver);

  Try<MesosContainerizer*> containerizer =
    MesosContainerizer::create(flags, false, &fetcher, secretResolver.get());
  EXPECT_SOME(containerizer);

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave =
    StartSlave(detector.get(), containerizer.get());
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched, registered(&driver, _, _));

  Future<std::vector<Offer>> offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(offers);
  EXPECT_FALSE(offers->empty());

  const string commandString = strings::format(
      "env; test \"$%s\" = \"%s\"",
      SECRET_ENV_NAME,
      SECRET_VALUE).get();

  CommandInfo command;
  command.set_value(commandString);

  // Request a secret.
  // TODO(kapil): Update createEnvironment() to support secrets.
  mesos::Environment::Variable *env =
    command.mutable_environment()->add_variables();
  env->set_name(SECRET_ENV_NAME);
  env->set_type(mesos::Environment::Variable::SECRET);

  mesos::Secret* secret = env->mutable_secret();
  secret->set_type(Secret::VALUE);
  secret->mutable_value()->set_data(SECRET_VALUE);

  TaskInfo task = createTask(
      offers.get()[0].slave_id(),
      Resources::parse("cpus:0.1;mem:32").get(),
      command);

  // NOTE: Successful tasks will output two status updates.
  Future<TaskStatus> statusRunning;
  Future<TaskStatus> statusFinished;
  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillOnce(FutureArg<1>(&statusFinished));

  driver.launchTasks(offers.get()[0].id(), {task});

  AWAIT_READY(statusRunning);
  EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());
  AWAIT_READY(statusFinished);
  EXPECT_EQ(TASK_FINISHED, statusFinished.get().state());

  driver.stop();
  driver.join();
}

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<commit_msg>Added a test that uses environment secrets and the DefaultExecutor.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <string>

#include <mesos/secret/resolver.hpp>

#include <process/future.hpp>
#include <process/gtest.hpp>

#include <stout/gtest.hpp>

#include "tests/mesos.hpp"

using process::Future;
using process::Owned;

using mesos::internal::slave::Fetcher;
using mesos::internal::slave::MesosContainerizer;

using mesos::master::detector::MasterDetector;

using std::string;

namespace mesos {
namespace internal {
namespace tests {

const char SECRET_VALUE[] = "password";
const char SECRET_ENV_NAME[] = "My_SeCrEt";

class EnvironmentSecretIsolatorTest : public MesosTest {};

// This test verifies that the environment secrets are resolved when launching a
// task.
TEST_F(EnvironmentSecretIsolatorTest, ResolveSecret)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  mesos::internal::slave::Flags flags = CreateSlaveFlags();

  Fetcher fetcher(flags);
  Try<SecretResolver*> secretResolver = SecretResolver::create();
  EXPECT_SOME(secretResolver);

  Try<MesosContainerizer*> containerizer =
    MesosContainerizer::create(flags, false, &fetcher, secretResolver.get());
  EXPECT_SOME(containerizer);

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave =
    StartSlave(detector.get(), containerizer.get());
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched, registered(&driver, _, _));

  Future<std::vector<Offer>> offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(offers);
  EXPECT_FALSE(offers->empty());

  const string commandString = strings::format(
      "env; test \"$%s\" = \"%s\"",
      SECRET_ENV_NAME,
      SECRET_VALUE).get();

  CommandInfo command;
  command.set_value(commandString);

  // Request a secret.
  // TODO(kapil): Update createEnvironment() to support secrets.
  mesos::Environment::Variable *env =
    command.mutable_environment()->add_variables();
  env->set_name(SECRET_ENV_NAME);
  env->set_type(mesos::Environment::Variable::SECRET);

  mesos::Secret* secret = env->mutable_secret();
  secret->set_type(Secret::VALUE);
  secret->mutable_value()->set_data(SECRET_VALUE);

  TaskInfo task = createTask(
      offers.get()[0].slave_id(),
      Resources::parse("cpus:0.1;mem:32").get(),
      command);

  // NOTE: Successful tasks will output two status updates.
  Future<TaskStatus> statusRunning;
  Future<TaskStatus> statusFinished;
  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillOnce(FutureArg<1>(&statusFinished));

  driver.launchTasks(offers.get()[0].id(), {task});

  AWAIT_READY(statusRunning);
  EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());
  AWAIT_READY(statusFinished);
  EXPECT_EQ(TASK_FINISHED, statusFinished.get().state());

  driver.stop();
  driver.join();
}

// This test verifies that the environment secrets are resolved when launching
// a task using the DefaultExecutor.
TEST_F(EnvironmentSecretIsolatorTest, ResolveSecretDefaultExecutor)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  mesos::internal::slave::Flags flags = CreateSlaveFlags();

#ifndef USE_SSL_SOCKET
  // Disable operator API authentication for the default executor. Executor
  // authentication currently has SSL as a dependency, so we cannot require
  // executors to authenticate with the agent operator API if Mesos was not
  // built with SSL support.
  flags.authenticate_http_readwrite = false;
#endif // USE_SSL_SOCKET

  Fetcher fetcher(flags);
  Try<SecretResolver*> secretResolver = SecretResolver::create();
  EXPECT_SOME(secretResolver);

  Try<MesosContainerizer*> containerizer =
    MesosContainerizer::create(flags, true, &fetcher, secretResolver.get());
  EXPECT_SOME(containerizer);

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave =
    StartSlave(detector.get(), containerizer.get(), flags);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));

  Future<std::vector<Offer>> offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(frameworkId);

  AWAIT_READY(offers);
  ASSERT_FALSE(offers->empty());

  Resources resources = Resources::parse("cpus:0.1;mem:32;disk:32").get();

  ExecutorInfo executorInfo;
  executorInfo.set_type(ExecutorInfo::DEFAULT);
  executorInfo.mutable_executor_id()->CopyFrom(DEFAULT_EXECUTOR_ID);
  executorInfo.mutable_framework_id()->CopyFrom(frameworkId.get());
  executorInfo.mutable_resources()->CopyFrom(resources);

  const string commandString = strings::format(
      "env; test \"$%s\" = \"%s\"",
      SECRET_ENV_NAME,
      SECRET_VALUE).get();

  CommandInfo command;
  command.set_value(commandString);

  // Request a secret.
  // TODO(kapil): Update createEnvironment() to support secrets.
  mesos::Environment::Variable *env =
    command.mutable_environment()->add_variables();
  env->set_name(SECRET_ENV_NAME);
  env->set_type(mesos::Environment::Variable::SECRET);

  mesos::Secret* secret = env->mutable_secret();
  secret->set_type(Secret::VALUE);
  secret->mutable_value()->set_data(SECRET_VALUE);

  const Offer& offer = offers->front();
  const SlaveID& slaveId = offer.slave_id();

  TaskInfo task = createTask(
      slaveId,
      Resources::parse("cpus:0.1;mem:32").get(),
      command);

  // NOTE: Successful tasks will output two status updates.
  Future<TaskStatus> statusRunning;
  Future<TaskStatus> statusFinished;
  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillOnce(FutureArg<1>(&statusFinished));

  TaskGroupInfo taskGroup = createTaskGroupInfo({task});

  driver.acceptOffers({offer.id()}, {LAUNCH_GROUP(executorInfo, taskGroup)});

  AWAIT_READY(statusRunning);
  EXPECT_EQ(TASK_RUNNING, statusRunning->state());
  AWAIT_READY(statusFinished);
  EXPECT_EQ(TASK_FINISHED, statusFinished->state());

  driver.stop();
  driver.join();
}

} // namespace tests {
} // namespace internal {
} // namespace mesos {
<|endoftext|>


<commit_before>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "util.h"
#include "metaenumvariable_p.h"

#include <QStringList>

QString Grantlee::unescapeStringLiteral( const QString &input )
{
  return input.mid( 1, input.size() - 2 )
         .replace( "\\\'", QChar( '\'' ) )
         .replace( "\\\"", QChar( '"' ) )
         .replace( "\\\\", QChar( '\\' ) );
}

bool Grantlee::variantIsTrue( const QVariant &variant )
{

  if ( !variant.isValid() )
    return false;
  switch ( variant.userType() ) {
  case QVariant::Bool: {
    return variant.toBool();
  }
  case QVariant::Int: {
    return ( variant.toInt() > 0 );
  }
  case QVariant::Double: {
    return ( variant.toDouble() > 0 );
  }
  case QMetaType::QObjectStar: {
    QObject *obj = variant.value<QObject *>();
    if ( !obj )
      return false;

    if ( obj->property( "__true__" ).isValid() ) {
      return obj->property( "__true__" ).toBool();
    }
    return true;
  }
  case QVariant::List: {
    return ( variant.toList().size() > 0 );
  }
  case QVariant::Hash: {
    return ( variant.toHash().size() > 0 );
  }
  }

  return !getSafeString( variant ).get().isEmpty();
}

QVariantList Grantlee::variantToList( const QVariant &var )
{

  if ( !var.isValid() )
    return QVariantList();

  if ( var.type() == QVariant::List ) {
    return var.toList();
  }

  if ( var.type() == QVariant::StringList ) {
    QVariantList list;
    foreach(const QString &_string, var.toStringList())
      list << _string;
    return list;
  }

  if ( var.type() == QVariant::Hash ) {
    const QVariantHash varHash = var.toHash();
    QVariantList list;

    QVariantHash::const_iterator it = varHash.constBegin();
    for ( ; it != varHash.constEnd(); ++it )
      list << it.key();

    return list;
  }

  if ( var.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    const MetaEnumVariable mev = var.value<MetaEnumVariable>();
    if (mev.value != -1)
      return QVariantList();

    QVariantList list;
    for (int row = 0; row < mev.enumerator.keyCount(); ++row) {
      list << QVariant::fromValue( MetaEnumVariable( mev.enumerator, row ) );
    }
    return list;
  }

  if ( var.userType() == QMetaType::QObjectStar ) {
    QObject *obj = var.value<QObject*>();
    if ( obj->property( "__list__" ).isValid() ) {
      return obj->property( "__list__" ).toList();
    }
  } else {
    return QVariantList() << var;
  }
  return QVariantList();
}

Grantlee::SafeString Grantlee::markSafe( const Grantlee::SafeString &input )
{
  Grantlee::SafeString sret = input;
  sret.setSafety( Grantlee::SafeString::IsSafe );
  return sret;
}

Grantlee::SafeString Grantlee::markForEscaping( const Grantlee::SafeString &input )
{
  Grantlee::SafeString temp = input;
  if ( input.isSafe() || input.needsEscape() )
    return input;

  temp.setNeedsEscape( true );
  return temp;
}

Grantlee::SafeString Grantlee::getSafeString( const QVariant &input )
{
  if ( input.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    return input.value<Grantlee::SafeString>();
  } else {
    return input.toString();
  }
}

bool Grantlee::isSafeString( const QVariant &input )
{
  const int type = input.userType();
  return (( type == qMetaTypeId<Grantlee::SafeString>() )
          || type == QVariant::String );
}

static QList<int> getPrimitives()
{
  QList<int> primitives;
  primitives << qMetaTypeId<Grantlee::SafeString>()
             << QVariant::Bool
             << QVariant::Int
             << QVariant::Double
             << QVariant::DateTime;
  return primitives;
}

bool Grantlee::supportedOutputType( const QVariant &input )
{
  static const QList<int> primitives = getPrimitives();
  return primitives.contains( input.userType() );
}

bool Grantlee::equals( const QVariant &lhs, const QVariant &rhs )
{

  // TODO: Redesign...

  // QVariant doesn't use operator== to compare its held data, so we do it manually instead for SafeString.
  bool equal = false;
  if ( lhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.value<Grantlee::SafeString>() );
    } else if ( rhs.userType() == QVariant::String ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.toString() );
    }
  } else if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() && lhs.userType() == QVariant::String ) {
    equal = ( rhs.value<Grantlee::SafeString>() == lhs.toString() );
  } else if ( rhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if (lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.value<MetaEnumVariable>() );
    } else if ( lhs.type() == QVariant::Int ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.toInt() );
    }
  } else if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if ( rhs.type() == QVariant::Int ) {
      equal = ( lhs.value<MetaEnumVariable>() == rhs.toInt() );
    }
  } else {
    equal = (( lhs == rhs ) && ( lhs.userType() == rhs.userType() ) );
  }
  return equal;
}

Grantlee::SafeString Grantlee::toString( const QVariantList &list )
{
  QString output( '[' );
  QVariantList::const_iterator it = list.constBegin();
  const QVariantList::const_iterator end = list.constEnd();
  while ( it != end ) {
    const QVariant item = *it;
    if ( isSafeString( item ) ) {
      output.append( "u\'" );
      output.append( getSafeString( item ) );
      output.append( '\'' );
      if (( it + 1 ) != end )
        output.append( ", " );
    }
    if ( item.type() == QVariant::List ) {
      output.append( toString( item.toList() ) );
      output.append( ", " );
    }
    ++it;
  }

  return output.append( ']' );
}

<commit_msg>More explict latin1.<commit_after>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "util.h"
#include "metaenumvariable_p.h"
#include "grantlee_latin1literal_p.h"

#include <QStringList>

QString Grantlee::unescapeStringLiteral( const QString &input )
{
  return input.mid( 1, input.size() - 2 )
         .replace( QLatin1String( "\\\'" ), QChar::fromLatin1( '\'' ) )
         .replace( QLatin1String( "\\\"" ), QChar::fromLatin1( '"' ) )
         .replace( QLatin1String( "\\\\" ), QChar::fromLatin1( '\\' ) );
}

bool Grantlee::variantIsTrue( const QVariant &variant )
{

  if ( !variant.isValid() )
    return false;
  switch ( variant.userType() ) {
  case QVariant::Bool: {
    return variant.toBool();
  }
  case QVariant::Int: {
    return ( variant.toInt() > 0 );
  }
  case QVariant::Double: {
    return ( variant.toDouble() > 0 );
  }
  case QMetaType::QObjectStar: {
    QObject *obj = variant.value<QObject *>();
    if ( !obj )
      return false;

    if ( obj->property( "__true__" ).isValid() ) {
      return obj->property( "__true__" ).toBool();
    }
    return true;
  }
  case QVariant::List: {
    return ( variant.toList().size() > 0 );
  }
  case QVariant::Hash: {
    return ( variant.toHash().size() > 0 );
  }
  }

  return !getSafeString( variant ).get().isEmpty();
}

QVariantList Grantlee::variantToList( const QVariant &var )
{

  if ( !var.isValid() )
    return QVariantList();

  if ( var.type() == QVariant::List ) {
    return var.toList();
  }

  if ( var.type() == QVariant::StringList ) {
    QVariantList list;
    foreach(const QString &_string, var.toStringList())
      list << _string;
    return list;
  }

  if ( var.type() == QVariant::Hash ) {
    const QVariantHash varHash = var.toHash();
    QVariantList list;

    QVariantHash::const_iterator it = varHash.constBegin();
    for ( ; it != varHash.constEnd(); ++it )
      list << it.key();

    return list;
  }

  if ( var.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    const MetaEnumVariable mev = var.value<MetaEnumVariable>();
    if (mev.value != -1)
      return QVariantList();

    QVariantList list;
    for (int row = 0; row < mev.enumerator.keyCount(); ++row) {
      list << QVariant::fromValue( MetaEnumVariable( mev.enumerator, row ) );
    }
    return list;
  }

  if ( var.userType() == QMetaType::QObjectStar ) {
    QObject *obj = var.value<QObject*>();
    if ( obj->property( "__list__" ).isValid() ) {
      return obj->property( "__list__" ).toList();
    }
  } else {
    return QVariantList() << var;
  }
  return QVariantList();
}

Grantlee::SafeString Grantlee::markSafe( const Grantlee::SafeString &input )
{
  Grantlee::SafeString sret = input;
  sret.setSafety( Grantlee::SafeString::IsSafe );
  return sret;
}

Grantlee::SafeString Grantlee::markForEscaping( const Grantlee::SafeString &input )
{
  Grantlee::SafeString temp = input;
  if ( input.isSafe() || input.needsEscape() )
    return input;

  temp.setNeedsEscape( true );
  return temp;
}

Grantlee::SafeString Grantlee::getSafeString( const QVariant &input )
{
  if ( input.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    return input.value<Grantlee::SafeString>();
  } else {
    return input.toString();
  }
}

bool Grantlee::isSafeString( const QVariant &input )
{
  const int type = input.userType();
  return (( type == qMetaTypeId<Grantlee::SafeString>() )
          || type == QVariant::String );
}

static QList<int> getPrimitives()
{
  QList<int> primitives;
  primitives << qMetaTypeId<Grantlee::SafeString>()
             << QVariant::Bool
             << QVariant::Int
             << QVariant::Double
             << QVariant::DateTime;
  return primitives;
}

bool Grantlee::supportedOutputType( const QVariant &input )
{
  static const QList<int> primitives = getPrimitives();
  return primitives.contains( input.userType() );
}

bool Grantlee::equals( const QVariant &lhs, const QVariant &rhs )
{

  // TODO: Redesign...

  // QVariant doesn't use operator== to compare its held data, so we do it manually instead for SafeString.
  bool equal = false;
  if ( lhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
    if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.value<Grantlee::SafeString>() );
    } else if ( rhs.userType() == QVariant::String ) {
      equal = ( lhs.value<Grantlee::SafeString>() == rhs.toString() );
    }
  } else if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() && lhs.userType() == QVariant::String ) {
    equal = ( rhs.value<Grantlee::SafeString>() == lhs.toString() );
  } else if ( rhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if (lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.value<MetaEnumVariable>() );
    } else if ( lhs.type() == QVariant::Int ) {
      equal = ( rhs.value<MetaEnumVariable>() == lhs.toInt() );
    }
  } else if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
    if ( rhs.type() == QVariant::Int ) {
      equal = ( lhs.value<MetaEnumVariable>() == rhs.toInt() );
    }
  } else {
    equal = (( lhs == rhs ) && ( lhs.userType() == rhs.userType() ) );
  }
  return equal;
}

Grantlee::SafeString Grantlee::toString( const QVariantList &list )
{
  QString output( QLatin1Char( '[' ) );
  QVariantList::const_iterator it = list.constBegin();
  const QVariantList::const_iterator end = list.constEnd();
  while ( it != end ) {
    const QVariant item = *it;
    if ( isSafeString( item ) ) {
      output += QLatin1Literal( "u\'" )
              + static_cast<QString>( getSafeString( item ).get() )
              + QLatin1Char( '\'' )
              + ( ( it + 1 ) != end ? QLatin1Literal( ", " ) : QLatin1Literal( "" ) );
    }
    if ( item.type() == QVariant::List ) {
      output += static_cast<QString>( toString( item.toList() ).get() ) + QLatin1Literal( ", " );
    }
    ++it;
  }

  return output.append( QLatin1Char( ']' ) );
}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <random>
#include <sstream>

#include "slitherlink/sl_dictionary.h"
#include "slitherlink/sl_generator.h"
#include "slitherlink/sl_generator_option.h"
#include "slitherlink/sl_clue_placement.h"
#include "slitherlink/sl_problem.h"

namespace
{
void ShowUsage(int argc, char** argv)
{
	std::cerr << "Usage: " << argv[0] << " [options] [file]" << std::endl;
	std::cerr << "Options:\n\
  -o <file>     Place the output into <file>\n\
  -a            Generate the clue placement automatically\n\
  -h <height>   Set the height of the problem <height>\n\
  -w <width>    Set the width of the problem <width>\n\
  -c <num>      Set the minimum number of the clues <num>\n\
  -C <num>      Set the maximum number of the clues <num>\n\
\n\
Options -h, -w, -c and -C are valid only if -a is specified.\n\
If -a is not specified, the input file should be specified for the clue placement." << std::endl;
}
bool GenerateWithCluePlacement(
	penciloid::slitherlink::CluePlacement &placement,
	penciloid::slitherlink::GeneratorOption &opt,
	std::mt19937 *rnd,
	penciloid::slitherlink::Problem *problem,
	int n_trial = -1)
{
	if (n_trial < 0) {
		while (!penciloid::slitherlink::GenerateByLocalSearch(placement, opt, rnd, problem));
		return true;
	}
	while (n_trial) {
		if (penciloid::slitherlink::GenerateByLocalSearch(placement, opt, rnd, problem)) {
			return true;
		}
		--n_trial;
	}
	return false;
}
void GenerateAuto(
	int height,
	int width,
	int n_clue_lo,
	int n_clue_hi,
	int symmetry,
	penciloid::slitherlink::GeneratorOption &opt,
	std::mt19937 *rnd,
	penciloid::slitherlink::Problem *problem)
{
	using namespace penciloid;
	using namespace slitherlink;
	for (;;) {
		int n_clues = std::uniform_int_distribution<int>(n_clue_lo, n_clue_hi)(*rnd);
		CluePlacement placement = GenerateCluePlacement(Y(height), X(width), n_clues, symmetry, rnd);
		if (GenerateWithCluePlacement(placement, opt, rnd, problem, 3)) {
			break;
		}
	}
}
}

int main(int argc, char** argv)
{
	if (argc < 2) {
		ShowUsage(argc, argv);
		return 0;
	}

	std::string in_filename = "", out_filename = "";
	int height = -1, width = -1, n_clue_lo = -1, n_clue_hi = -1;
	bool gen_clue_auto = false;

	// parse options
	int arg_idx = 1;
	for (; arg_idx < argc; ++arg_idx) {
		if (argv[arg_idx][0] != '-') {
			// option ended
			break;
		}
		bool is_next_int = false;
		int val_next_int;
		if (arg_idx + 1 < argc) {
			std::istringstream iss(argv[arg_idx + 1]);
			iss >> val_next_int;
			if (!iss.fail()) is_next_int = true;
		}

		char opt = argv[arg_idx][1];
		switch (opt)
		{
		case 'o':
			// specify the output file
			if (arg_idx + 1 >= argc) {
				std::cerr << "error: missing value after -o" << std::endl;
				return 0;
			}
			out_filename = argv[arg_idx + 1];
			++arg_idx;
			break;
		case 'a':
			// generate clue placement automatically
			gen_clue_auto = true;
			break;
		case 'h':
			// specify the height of the generated problem (enabled only if '-a' is specified)
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -h" << std::endl;
				return 0;
			}
			height = val_next_int;
			++arg_idx;
			break;
		case 'w':
			// specify the width of the generated problem (enabled only if '-a' is specified)
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -w" << std::endl;
				return 0;
			}
			width = val_next_int;
			++arg_idx;
			break;
		case 'c':
			// specify the minimum number of the clues
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -c" << std::endl;
				return 0;
			}
			n_clue_lo = val_next_int;
			++arg_idx;
			break;
		case 'C':
			// specify the maximum number of the clues
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -C" << std::endl;
				return 0;
			}
			n_clue_hi = val_next_int;
			++arg_idx;
			break;
		default:
			std::cerr << "error: unrecognized option '" << argv[arg_idx] << "'" << std::endl;
			return 0;
		}
	}
	if (gen_clue_auto) {
		if (out_filename.empty()) {
			std::cerr << "error: -o must be specified if -a is specified." << std::endl;
			return 0;
		}
	}
	if (!gen_clue_auto) {
		in_filename = argv[arg_idx];
	}

	using namespace penciloid;
	using namespace slitherlink;

	GeneratorOption opt;
	Dictionary dic;
	dic.CreateDefault();
	opt.field_dictionary = &dic;

	Problem problem;
	std::random_device dev;
	std::mt19937 rnd(dev());

	if (!gen_clue_auto) {
		std::ifstream ifs(in_filename);
		if (ifs.fail()) {
			std::cerr << "error: couldn't open file '" << in_filename << "'" << std::endl;
			return 0;
		}
		ifs >> height >> width;
		if (ifs.fail() || height <= 0 || width <= 0) {
			std::cerr << "error: invalid input format" << std::endl;
			return 0;
		}
		CluePlacement clue_placement{ Y(height), X(width) };
		for (Y y(0); y < height; ++y) {
			for (X x(0); x < width; ++x) {
				std::string token;
				ifs >> token;
				if (ifs.fail()) {
					std::cerr << "error: invalid input format" << std::endl;
					return 0;
				}

				if (token[0] >= '0' && token[0] <= '3') {
					clue_placement.SetClue(CellPosition(y, x), Clue(static_cast<int>(token[0] - '0')));
				} else if (token[0] == '5') {
					clue_placement.SetClue(CellPosition(y, x), kSomeClue);
				} else {
					std::cerr << "error: invalid input format" << std::endl;
					return 0;
				}
			}
		}

		GenerateWithCluePlacement(clue_placement, opt, &rnd, &problem);
	} else {
		if (n_clue_lo == -1 || n_clue_hi == -1) {
			n_clue_lo = static_cast<int>(height * width * 0.3);
			n_clue_hi = static_cast<int>(height * width * 0.4);
		}
		GenerateAuto(height, width, n_clue_lo, n_clue_hi, penciloid::slitherlink::kSymmetryDyad, opt, &rnd, &problem);
	}

	if (out_filename.empty()) {
		out_filename = in_filename + ".generated.txt";
	}
	std::ofstream ofs(out_filename);
	if (!ofs.good()) {
		std::cerr << "error: couldn't open file '" << in_filename << "'" << std::endl;
		return 0;
	}
	ofs << height << std::endl;
	ofs << width << std::endl;
	for (Y y(0); y < height; ++y) {
		for (X x(0); x < width; ++x) {
			Clue c = problem.GetClue(CellPosition(y, x));
			if (c == kNoClue) ofs << ". ";
			else ofs << static_cast<int>(c) << " ";
		}
		ofs << std::endl;
	}
	return 0;
}
<commit_msg>frontend_slitherlink_generator: switch -> if<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <random>
#include <sstream>

#include "slitherlink/sl_dictionary.h"
#include "slitherlink/sl_generator.h"
#include "slitherlink/sl_generator_option.h"
#include "slitherlink/sl_clue_placement.h"
#include "slitherlink/sl_problem.h"

namespace
{
void ShowUsage(int argc, char** argv)
{
	std::cerr << "Usage: " << argv[0] << " [options] [file]" << std::endl;
	std::cerr << "Options:\n\
  --help        Display this information\n\
  -o <file>     Place the output into <file>\n\
  -a            Generate the clue placement automatically\n\
  -h <height>   Set the height of the problem <height>\n\
  -w <width>    Set the width of the problem <width>\n\
  -c <num>      Set the minimum number of the clues <num>\n\
  -C <num>      Set the maximum number of the clues <num>\n\
\n\
Options -h, -w, -c and -C are valid only if -a is specified.\n\
If -a is not specified, the input file should be specified for the clue placement." << std::endl;
}
bool GenerateWithCluePlacement(
	penciloid::slitherlink::CluePlacement &placement,
	penciloid::slitherlink::GeneratorOption &opt,
	std::mt19937 *rnd,
	penciloid::slitherlink::Problem *problem,
	int n_trial = -1)
{
	if (n_trial < 0) {
		while (!penciloid::slitherlink::GenerateByLocalSearch(placement, opt, rnd, problem));
		return true;
	}
	while (n_trial) {
		if (penciloid::slitherlink::GenerateByLocalSearch(placement, opt, rnd, problem)) {
			return true;
		}
		--n_trial;
	}
	return false;
}
void GenerateAuto(
	int height,
	int width,
	int n_clue_lo,
	int n_clue_hi,
	int symmetry,
	penciloid::slitherlink::GeneratorOption &opt,
	std::mt19937 *rnd,
	penciloid::slitherlink::Problem *problem)
{
	using namespace penciloid;
	using namespace slitherlink;
	for (;;) {
		int n_clues = std::uniform_int_distribution<int>(n_clue_lo, n_clue_hi)(*rnd);
		CluePlacement placement = GenerateCluePlacement(Y(height), X(width), n_clues, symmetry, rnd);
		if (GenerateWithCluePlacement(placement, opt, rnd, problem, 3)) {
			break;
		}
	}
}
}

int main(int argc, char** argv)
{
	if (argc < 2) {
		ShowUsage(argc, argv);
		return 0;
	}

	std::string in_filename = "", out_filename = "";
	int height = -1, width = -1, n_clue_lo = -1, n_clue_hi = -1;
	bool gen_clue_auto = false;

	// parse options
	int arg_idx = 1;
	for (; arg_idx < argc; ++arg_idx) {
		if (argv[arg_idx][0] != '-') {
			// option ended
			break;
		}
		bool is_next_int = false;
		int val_next_int;
		if (arg_idx + 1 < argc) {
			std::istringstream iss(argv[arg_idx + 1]);
			iss >> val_next_int;
			if (!iss.fail()) is_next_int = true;
		}

		std::string opt = argv[arg_idx];
		if (opt == "-o") {
			if (arg_idx + 1 >= argc) {
				std::cerr << "error: missing value after -o" << std::endl;
				return 0;
			}
			out_filename = argv[arg_idx + 1];
			++arg_idx;
		} else if (opt == "-a") {
			gen_clue_auto = true;
		} else if (opt == "-h") {
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -h" << std::endl;
				return 0;
			}
			height = val_next_int;
			++arg_idx;
		} else if (opt == "-w") {
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -w" << std::endl;
				return 0;
			}
			width = val_next_int;
			++arg_idx;
		} else if (opt == "-c") {
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -c" << std::endl;
				return 0;
			}
			n_clue_lo = val_next_int;
			++arg_idx;
		} else if (opt == "-C") {
			if (!is_next_int) {
				std::cerr << "error: missing integer value after -C" << std::endl;
				return 0;
			}
			n_clue_hi = val_next_int;
			++arg_idx;
		} else if (opt == "--help") {
			ShowUsage(argc, argv);
			return 0;
		} else {
			std::cerr << "error: unrecognized option '" << argv[arg_idx] << "'" << std::endl;
			return 0;
		}
	}
	if (gen_clue_auto) {
		if (out_filename.empty()) {
			std::cerr << "error: -o must be specified if -a is specified." << std::endl;
			return 0;
		}
	}
	if (!gen_clue_auto) {
		if (arg_idx < argc) {
			in_filename = argv[arg_idx];
		} else {
			std::cerr << "error: no input file" << std::endl;
			return 0;
		}
	}

	using namespace penciloid;
	using namespace slitherlink;

	GeneratorOption opt;
	Dictionary dic;
	dic.CreateDefault();
	opt.field_dictionary = &dic;

	Problem problem;
	std::random_device dev;
	std::mt19937 rnd(dev());

	if (!gen_clue_auto) {
		std::ifstream ifs(in_filename);
		if (ifs.fail()) {
			std::cerr << "error: couldn't open file '" << in_filename << "'" << std::endl;
			return 0;
		}
		ifs >> height >> width;
		if (ifs.fail() || height <= 0 || width <= 0) {
			std::cerr << "error: invalid input format" << std::endl;
			return 0;
		}
		CluePlacement clue_placement{ Y(height), X(width) };
		for (Y y(0); y < height; ++y) {
			for (X x(0); x < width; ++x) {
				std::string token;
				ifs >> token;
				if (ifs.fail()) {
					std::cerr << "error: invalid input format" << std::endl;
					return 0;
				}

				if (token[0] >= '0' && token[0] <= '3') {
					clue_placement.SetClue(CellPosition(y, x), Clue(static_cast<int>(token[0] - '0')));
				} else if (token[0] == '5') {
					clue_placement.SetClue(CellPosition(y, x), kSomeClue);
				} else {
					std::cerr << "error: invalid input format" << std::endl;
					return 0;
				}
			}
		}

		GenerateWithCluePlacement(clue_placement, opt, &rnd, &problem);
	} else {
		if (n_clue_lo == -1 || n_clue_hi == -1) {
			n_clue_lo = static_cast<int>(height * width * 0.3);
			n_clue_hi = static_cast<int>(height * width * 0.4);
		}
		GenerateAuto(height, width, n_clue_lo, n_clue_hi, penciloid::slitherlink::kSymmetryDyad, opt, &rnd, &problem);
	}

	if (out_filename.empty()) {
		out_filename = in_filename + ".generated.txt";
	}
	std::ofstream ofs(out_filename);
	if (!ofs.good()) {
		std::cerr << "error: couldn't open file '" << in_filename << "'" << std::endl;
		return 0;
	}
	ofs << height << std::endl;
	ofs << width << std::endl;
	for (Y y(0); y < height; ++y) {
		for (X x(0); x < width; ++x) {
			Clue c = problem.GetClue(CellPosition(y, x));
			if (c == kNoClue) ofs << ". ";
			else ofs << static_cast<int>(c) << " ";
		}
		ofs << std::endl;
	}
	return 0;
}
<|endoftext|>


<commit_before><commit_msg>Cover NaN case for reference and sensors data<commit_after><|endoftext|>


<commit_before>#include "chrono_parallel/solver/ChSolverParallel.h"

using namespace chrono;

ChSolverParallel::ChSolverParallel() {
  max_iteration = 100;
  current_iteration = 0;
  rigid_rigid = NULL;
  bilateral = NULL;
}
ChSolverParallel::~ChSolverParallel() {}
void ChSolverParallel::Setup(ChParallelDataManager* data_container_) {
  data_container = data_container_;
  Initialize();
}

void ChSolverParallel::Project(real* gamma) {
  data_container->system_timer.start("ChSolverParallel_Project");
  rigid_rigid->Project(gamma);
  data_container->system_timer.stop("ChSolverParallel_Project");
}
void ChSolverParallel::Project_Single(int index, real* gamma) {
  data_container->system_timer.start("ChSolverParallel_Project");
  rigid_rigid->Project_Single(index, gamma);
  data_container->system_timer.stop("ChSolverParallel_Project");
}
//=================================================================================================================================

void ChSolverParallel::shurA(blaze::DynamicVector<real>& x, blaze::DynamicVector<real>& out) { out = data_container->host_data.M_invD * x; }

void ChSolverParallel::ComputeSRhs(custom_vector<real>& gamma, const custom_vector<real>& rhs, custom_vector<real3>& vel_data, custom_vector<real3>& omg_data, custom_vector<real>& b) {
  // TODO change SHRS to use blaze
  // ComputeImpulses(gamma, vel_data, omg_data);
  // rigid_rigid->ComputeS(rhs, vel_data, omg_data, b);
}
void ChSolverParallel::ShurProduct(const blaze::DynamicVector<real>& x, blaze::DynamicVector<real>& output) {
  data_container->system_timer.start("ShurProduct");
  output = data_container->host_data.D_T * data_container->host_data.M_invD * x + data_container->host_data.E * x;
  data_container->system_timer.stop("ShurProduct");
}

void ChSolverParallel::ShurBilaterals(const blaze::DynamicVector<real>& x, blaze::DynamicVector<real>& output) {
  CompressedMatrix<real>& D_T = data_container->host_data.D_T;
  CompressedMatrix<real>& M_invD = data_container->host_data.M_invD;
  uint& num_bodies = data_container->num_bodies;
  uint& num_unilaterals = data_container->num_unilaterals;
  uint& num_bilaterals = data_container->num_bilaterals;

  blaze::SparseSubmatrix<CompressedMatrix<real> > D_T_sub = blaze::submatrix(D_T, num_unilaterals, 0, num_bilaterals, num_bodies * 6);
  blaze::SparseSubmatrix<CompressedMatrix<real> > M_invD_sub = blaze::submatrix(M_invD, 0, num_unilaterals, num_bodies * 6, num_bilaterals);
  output = D_T_sub * M_invD_sub * x;
}

//=================================================================================================================================

void ChSolverParallel::UpdatePosition(custom_vector<real>& x) {
  //
  //   if (rigid_rigid->solve_sliding == true || rigid_rigid->solve_spinning ==
  //   true) {
  //      return;
  //   }
  //   shurA(x.data());
  //
  //   data_container->host_data.vel_new_data =
  //   data_container->host_data.vel_data + data_container->host_data.QXYZ_data;
  //   data_container->host_data.omg_new_data +
  //   data_container->host_data.omg_data + data_container->host_data.QUVW_data;
  //
  //#pragma omp parallel for
  //   for (int i = 0; i < data_container->num_bodies; i++) {
  //
  //      data_container->host_data.pos_new_data[i] =
  //      data_container->host_data.pos_data[i] +
  //      data_container->host_data.vel_new_data[i] * step_size;
  //      //real3 dp =
  //      data_container->host_data.pos_new_data[i]-data_container->host_data.pos_data[i];
  //      //cout<<dp<<endl;
  //      real4 moldrot = data_container->host_data.rot_data[i];
  //      real3 newwel = data_container->host_data.omg_new_data[i];
  //
  //      M33 A = AMat(moldrot);
  //      real3 newwel_abs = MatMult(A, newwel);
  //      real mangle = length(newwel_abs) * step_size;
  //      newwel_abs = normalize(newwel_abs);
  //      real4 mdeltarot = Q_from_AngAxis(mangle, newwel_abs);
  //      real4 mnewrot = mdeltarot % moldrot;
  //      data_container->host_data.rot_new_data[i] = mnewrot;
  //   }
}

void ChSolverParallel::UpdateContacts() {
  ////TODO: Re-implement this using new dispatch
  //   if (rigid_rigid->solve_sliding == true || rigid_rigid->solve_spinning ==
  //   true) {
  //      return;
  //   }
  //
  //   //// TODO:  This ASSUMES that we are using an MPR narrowphase!!
  //   ////        Instead of constructing a narrowphaseMPR object here,
  //   ////        modify so that we can use the CHCNarrowphase object
  //   ////        from the CollisionSystemParallel.
  //   collision::ChCNarrowphaseMPR narrowphase;
  //   narrowphase.SetCollisionEnvelope(data_container->settings.collision.collision_envelope);
  //   narrowphase.Update(data_container);
  //
  //   rigid_rigid->UpdateJacobians();
  //   rigid_rigid->UpdateRHS();
}

uint ChSolverParallel::SolveStab(const uint max_iter, const uint size, const blaze::DenseSubvector<DynamicVector<real> >& mb, blaze::DenseSubvector<DynamicVector<real> >& x) {
  real& residual = data_container->measures.solver.residual;
  custom_vector<real>& iter_hist = data_container->measures.solver.iter_hist;

  uint N = mb.size();

  blaze::DynamicVector<real> v(N, 0), v_hat(x.size()), w(N, 0), w_old, xMR, v_old, Av(x.size()), w_oold;
  real beta, c = 1, eta, norm_rMR, norm_r0, c_old = 1, s_old = 0, s = 0, alpha, beta_old, c_oold, s_oold, r1_hat, r1, r2, r3;
  ShurBilaterals(x, v_hat);
  v_hat = mb - v_hat;
  beta = sqrt((v_hat, v_hat));
  w_old = w;
  eta = beta;
  xMR = x;
  norm_rMR = beta;
  norm_r0 = beta;

  if (beta == 0 || norm_rMR / norm_r0 < data_container->settings.solver.tolerance) {
    return 0;
  }

  for (current_iteration = 0; current_iteration < max_iter; current_iteration++) {
    //// Lanczos
    v_old = v;
    v = 1.0 / beta * v_hat;
    ShurBilaterals(v, Av);
    alpha = (v, Av);
    v_hat = Av - alpha * v - beta * v_old;
    beta_old = beta;
    beta = sqrt((v_hat, v_hat));
    //// QR factorization
    c_oold = c_old;
    c_old = c;
    s_oold = s_old;
    s_old = s;
    r1_hat = c_old * alpha - c_oold * s_old * beta_old;
    r1 = 1 / sqrt(r1_hat * r1_hat + beta * beta);
    r2 = s_old * alpha + c_oold * c_old * beta_old;
    r3 = s_oold * beta_old;
    //// Givens Rotation
    c = r1_hat * r1;
    s = beta * r1;
    //// update
    w_oold = w_old;
    w_old = w;
    w = r1 * (v - r3 * w_oold - r2 * w_old);
    x = x + c * eta * w;
    norm_rMR = norm_rMR * std::abs(s);
    eta = -s * eta;
    residual = norm_rMR / norm_r0;

    real maxdeltalambda = 0;    // CompRes(mb, num_contacts);      //NormInf(ms);
    AtIterationEnd(residual, maxdeltalambda, iter_hist.size() + current_iteration);

    if (residual < data_container->settings.solver.tolerance) {
      break;
    }
  }
  return current_iteration;
}
<commit_msg>Fix for Visual Studio 12:  must explicitly group matrix * matrix * vector operations<commit_after>#include "chrono_parallel/solver/ChSolverParallel.h"

using namespace chrono;

ChSolverParallel::ChSolverParallel() {
  max_iteration = 100;
  current_iteration = 0;
  rigid_rigid = NULL;
  bilateral = NULL;
}
ChSolverParallel::~ChSolverParallel() {}
void ChSolverParallel::Setup(ChParallelDataManager* data_container_) {
  data_container = data_container_;
  Initialize();
}

void ChSolverParallel::Project(real* gamma) {
  data_container->system_timer.start("ChSolverParallel_Project");
  rigid_rigid->Project(gamma);
  data_container->system_timer.stop("ChSolverParallel_Project");
}
void ChSolverParallel::Project_Single(int index, real* gamma) {
  data_container->system_timer.start("ChSolverParallel_Project");
  rigid_rigid->Project_Single(index, gamma);
  data_container->system_timer.stop("ChSolverParallel_Project");
}
//=================================================================================================================================

void ChSolverParallel::shurA(blaze::DynamicVector<real>& x, blaze::DynamicVector<real>& out) { out = data_container->host_data.M_invD * x; }

void ChSolverParallel::ComputeSRhs(custom_vector<real>& gamma, const custom_vector<real>& rhs, custom_vector<real3>& vel_data, custom_vector<real3>& omg_data, custom_vector<real>& b) {
  // TODO change SHRS to use blaze
  // ComputeImpulses(gamma, vel_data, omg_data);
  // rigid_rigid->ComputeS(rhs, vel_data, omg_data, b);
}
void ChSolverParallel::ShurProduct(const blaze::DynamicVector<real>& x, blaze::DynamicVector<real>& output) {
  data_container->system_timer.start("ShurProduct");
  output = data_container->host_data.D_T * ( data_container->host_data.M_invD * x ) + data_container->host_data.E * x;
  data_container->system_timer.stop("ShurProduct");
}

void ChSolverParallel::ShurBilaterals(const blaze::DynamicVector<real>& x, blaze::DynamicVector<real>& output) {
  CompressedMatrix<real>& D_T = data_container->host_data.D_T;
  CompressedMatrix<real>& M_invD = data_container->host_data.M_invD;
  uint& num_bodies = data_container->num_bodies;
  uint& num_unilaterals = data_container->num_unilaterals;
  uint& num_bilaterals = data_container->num_bilaterals;

  blaze::SparseSubmatrix<CompressedMatrix<real> > D_T_sub = blaze::submatrix(D_T, num_unilaterals, 0, num_bilaterals, num_bodies * 6);
  blaze::SparseSubmatrix<CompressedMatrix<real> > M_invD_sub = blaze::submatrix(M_invD, 0, num_unilaterals, num_bodies * 6, num_bilaterals);
  output = D_T_sub * ( M_invD_sub * x );
}

//=================================================================================================================================

void ChSolverParallel::UpdatePosition(custom_vector<real>& x) {
  //
  //   if (rigid_rigid->solve_sliding == true || rigid_rigid->solve_spinning ==
  //   true) {
  //      return;
  //   }
  //   shurA(x.data());
  //
  //   data_container->host_data.vel_new_data =
  //   data_container->host_data.vel_data + data_container->host_data.QXYZ_data;
  //   data_container->host_data.omg_new_data +
  //   data_container->host_data.omg_data + data_container->host_data.QUVW_data;
  //
  //#pragma omp parallel for
  //   for (int i = 0; i < data_container->num_bodies; i++) {
  //
  //      data_container->host_data.pos_new_data[i] =
  //      data_container->host_data.pos_data[i] +
  //      data_container->host_data.vel_new_data[i] * step_size;
  //      //real3 dp =
  //      data_container->host_data.pos_new_data[i]-data_container->host_data.pos_data[i];
  //      //cout<<dp<<endl;
  //      real4 moldrot = data_container->host_data.rot_data[i];
  //      real3 newwel = data_container->host_data.omg_new_data[i];
  //
  //      M33 A = AMat(moldrot);
  //      real3 newwel_abs = MatMult(A, newwel);
  //      real mangle = length(newwel_abs) * step_size;
  //      newwel_abs = normalize(newwel_abs);
  //      real4 mdeltarot = Q_from_AngAxis(mangle, newwel_abs);
  //      real4 mnewrot = mdeltarot % moldrot;
  //      data_container->host_data.rot_new_data[i] = mnewrot;
  //   }
}

void ChSolverParallel::UpdateContacts() {
  ////TODO: Re-implement this using new dispatch
  //   if (rigid_rigid->solve_sliding == true || rigid_rigid->solve_spinning ==
  //   true) {
  //      return;
  //   }
  //
  //   //// TODO:  This ASSUMES that we are using an MPR narrowphase!!
  //   ////        Instead of constructing a narrowphaseMPR object here,
  //   ////        modify so that we can use the CHCNarrowphase object
  //   ////        from the CollisionSystemParallel.
  //   collision::ChCNarrowphaseMPR narrowphase;
  //   narrowphase.SetCollisionEnvelope(data_container->settings.collision.collision_envelope);
  //   narrowphase.Update(data_container);
  //
  //   rigid_rigid->UpdateJacobians();
  //   rigid_rigid->UpdateRHS();
}

uint ChSolverParallel::SolveStab(const uint max_iter, const uint size, const blaze::DenseSubvector<DynamicVector<real> >& mb, blaze::DenseSubvector<DynamicVector<real> >& x) {
  real& residual = data_container->measures.solver.residual;
  custom_vector<real>& iter_hist = data_container->measures.solver.iter_hist;

  uint N = mb.size();

  blaze::DynamicVector<real> v(N, 0), v_hat(x.size()), w(N, 0), w_old, xMR, v_old, Av(x.size()), w_oold;
  real beta, c = 1, eta, norm_rMR, norm_r0, c_old = 1, s_old = 0, s = 0, alpha, beta_old, c_oold, s_oold, r1_hat, r1, r2, r3;
  ShurBilaterals(x, v_hat);
  v_hat = mb - v_hat;
  beta = sqrt((v_hat, v_hat));
  w_old = w;
  eta = beta;
  xMR = x;
  norm_rMR = beta;
  norm_r0 = beta;

  if (beta == 0 || norm_rMR / norm_r0 < data_container->settings.solver.tolerance) {
    return 0;
  }

  for (current_iteration = 0; current_iteration < max_iter; current_iteration++) {
    //// Lanczos
    v_old = v;
    v = 1.0 / beta * v_hat;
    ShurBilaterals(v, Av);
    alpha = (v, Av);
    v_hat = Av - alpha * v - beta * v_old;
    beta_old = beta;
    beta = sqrt((v_hat, v_hat));
    //// QR factorization
    c_oold = c_old;
    c_old = c;
    s_oold = s_old;
    s_old = s;
    r1_hat = c_old * alpha - c_oold * s_old * beta_old;
    r1 = 1 / sqrt(r1_hat * r1_hat + beta * beta);
    r2 = s_old * alpha + c_oold * c_old * beta_old;
    r3 = s_oold * beta_old;
    //// Givens Rotation
    c = r1_hat * r1;
    s = beta * r1;
    //// update
    w_oold = w_old;
    w_old = w;
    w = r1 * (v - r3 * w_oold - r2 * w_old);
    x = x + c * eta * w;
    norm_rMR = norm_rMR * std::abs(s);
    eta = -s * eta;
    residual = norm_rMR / norm_r0;

    real maxdeltalambda = 0;    // CompRes(mb, num_contacts);      //NormInf(ms);
    AtIterationEnd(residual, maxdeltalambda, iter_hist.size() + current_iteration);

    if (residual < data_container->settings.solver.tolerance) {
      break;
    }
  }
  return current_iteration;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <iostream>
#include <fstream>
#include <boost/algorithm/string.hpp>

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include "dlpolytopologyreader.h"
#ifdef DLPOLY
#include "dlpoly/dlp_io_layer.h"
#endif

namespace votca { namespace csg {

bool DLPOLYTopologyReader::ReadTopology(string file, Topology &top)
{
#ifdef DLPOLY
    struct FieldSpecsT  FieldBase;
    struct FrameSpecsT  FrameBase;
    struct MolecSpecsT *MolecBase;
    struct FieldSiteT  *FieldSite;
    struct FrameSiteT  *FrameSite;

    int idnode,matms,natms,nmols,nmolt;
    int istateF;

    int inode=matms=natms=nmols=nmolt=0;

    // TODO: istateF must be an enum!
    istateF=1;

    // TODO: we need to fix the file naming!
    field_scan_(&istateF,&matms,&natms,&nmolt);

    MolecBase = new MolecSpecsT[nmolt];
    FieldSite = new FieldSiteT[natms];

    FieldBase.nmols = nmolt;
    FieldBase.natms = natms;

    field_read_(&istateF,&FieldBase,MolecBase,FieldSite);

    // AB: if on return istateF < 0  => in the next F-call the relevant F-arrays will be deallocated (at the end)
    // AB: NOT TO RE-/DE-ALLOCATE F-arrays in the next F-call, reset istateF = 0
    istateF = 0;

    // TODO: fix residue naming / assignment
    Residue *res = top.CreateResidue("no");

    // read the atoms
    int is=0;
    for(int im=0; im<nmolt; im++){
        for(int imr=0; imr<MolecBase[im].nrept; ++imr) {
            Molecule *mi = top.CreateMolecule(MolecBase[im].name);
            for(int ims=0; ims<MolecBase[im].nsites; ims++) {

                BeadType *type = top.GetOrCreateBeadType(FieldSite[is].name); // what is
                Bead *bead = top.CreateBead(1, FieldSite[is].type, type, res->getId(), FieldSite[is].m, FieldSite[is].q);

                stringstream nm;
                nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
                mi->AddBead(bead, nm.str());
            }
        }
    }

    delete [] MolecBase;
    delete [] FieldSite;
#else
    // TODO: fix residue naming / assignment
    Residue *res = top.CreateResidue("no");

    std::ifstream fl;
    fl.open("FIELD");
    if (!fl.is_open()){
      throw std::runtime_error("could open dlpoly file FIELD");
    } else {
      string line;
      getline(fl, line); //title
      getline(fl, line); //unit line
      fl >> line;
      if (line != "MOLECULES")
          throw std::runtime_error("unexpected line in dlpoly file FIELD, expected 'MOLECULES' got" + line);
      int nmol_types;
      fl >> nmol_types;
      getline(fl, line); //rest of MOLECULES line
      int id=0;
      for (int nmol_type=0;nmol_type<nmol_types; nmol_type++){
	string mol_name;
        getline(fl, mol_name); //molecule name might incl. spaces
	boost::erase_all(mol_name, " ");
        Molecule *mi = top.CreateMolecule(mol_name);
        fl >> line;
        if (line != "NUMMOLS")
          throw std::runtime_error("unexpected line in dlpoly file FIELD, expected 'NUMMOLS' got" + line);
	int nreplica;
	fl >> nreplica;
	fl >> line;
        if (line != "ATOMS")
          throw std::runtime_error("unexpected line in dlpoly file FIELD, expected 'ATOMS' got" + line);
	int natoms;
	fl >> natoms;
	//read molecule
	for (int i=0;i<natoms;){//i is altered in reapeater loop
	  string beadtype;
	  fl >> beadtype;
	  BeadType *type = top.GetOrCreateBeadType(beadtype);
	  double mass;
	  fl >> mass;
	  double charge;
	  fl >> charge;
          getline(fl,line); //rest of the atom line
          Tokenizer tok(line, " ");
          vector<int> fields;
          tok.ConvertToVector<int>(fields);
	  int repeater=1;
	  if (fields.size() > 1)
	    repeater=fields[0];
	  for(int j=0;j<repeater;j++){
	    string beadname = beadtype + boost::lexical_cast<string>(j+1);
	    Bead *bead = top.CreateBead(1, beadname , type, res->getId(), mass, charge);
            stringstream nm;
            nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
            mi->AddBead(bead, nm.str());
	    i++;
	  }
	}
	while (line != "FINISH"){
	  fl >> line;
	  if (fl.eof())
            throw std::runtime_error("unexpected end of dlpoly file FIELD while scanning for 'FINISH'");
	}
	//replicate molecule
	for (int replica=1;replica<nreplica;replica++){
          Molecule *mi_replica = top.CreateMolecule(mol_name);
	  for(int i=0;i<mi->BeadCount();i++){
	    Bead *bead=mi->getBead(i);
	    BeadType *type = top.GetOrCreateBeadType(bead->Type()->getName());
	    string beadname=mi->getBeadName(i);
	    Bead *bead_replica = top.CreateBead(1, bead->getName(), type, res->getId(), bead->getM(), bead->getQ());
	    mi_replica->AddBead(bead_replica,beadname);
	  }
	}
      }
    }
    //we don't need the rest.
    fl.close();
#endif
    fl.open("CONFIG");
    if(fl.is_open()) {
      string line;
      getline(fl, line); //title
      getline(fl, line); // 2nd header line
      vec box_vectors[3];
      for (int i=0;i<3;i++){ // read 3 box lines
        getline(fl, line);
        if(fl.eof())
          throw std::runtime_error("unexpected end of file in dlpoly file CONFIG, when reading box vector"  +
              boost::lexical_cast<string>(i));
        Tokenizer tok(line, " ");
        vector<double> fields;
        tok.ConvertToVector<double>(fields);
        box_vectors[i]=vec(fields[0],fields[1],fields[2]);
      }
      matrix box(box_vectors[0],box_vectors[1],box_vectors[2]);
      top.setBox(box);
    }
    else {
      cout << "NOTE: Could open dlploy file CONFIG, so no boundary conditions, where set in the topology" << endl;
    }
    fl.close();

    return true;
}

}}

<commit_msg>dlpolytopologyreader: fixes multiple molecule reading<commit_after>/*
 * Copyright 2009-2013 The VOTCA Development Team (http://www.votca.org)
 *
 * 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 <iostream>
#include <fstream>
#include <boost/algorithm/string.hpp>

#ifndef HAVE_NO_CONFIG
#include <votca_config.h>
#endif

#include "dlpolytopologyreader.h"
#ifdef DLPOLY
#include "dlpoly/dlp_io_layer.h"
#endif

namespace votca { namespace csg {

bool DLPOLYTopologyReader::ReadTopology(string file, Topology &top)
{
    std::ifstream fl;
#ifdef DLPOLY
    struct FieldSpecsT  FieldBase;
    struct FrameSpecsT  FrameBase;
    struct MolecSpecsT *MolecBase;
    struct FieldSiteT  *FieldSite;
    struct FrameSiteT  *FrameSite;

    int idnode,matms,natms,nmols,nmolt;
    int istateF;

    int inode=matms=natms=nmols=nmolt=0;

    // TODO: istateF must be an enum!
    istateF=1;

    // TODO: we need to fix the file naming!
    field_scan_(&istateF,&matms,&natms,&nmolt);

    MolecBase = new MolecSpecsT[nmolt];
    FieldSite = new FieldSiteT[natms];

    FieldBase.nmols = nmolt;
    FieldBase.natms = natms;

    field_read_(&istateF,&FieldBase,MolecBase,FieldSite);

    // AB: if on return istateF < 0  => in the next F-call the relevant F-arrays will be deallocated (at the end)
    // AB: NOT TO RE-/DE-ALLOCATE F-arrays in the next F-call, reset istateF = 0
    istateF = 0;

    // TODO: fix residue naming / assignment
    Residue *res = top.CreateResidue("no");

    // read the atoms
    int is=0;
    for(int im=0; im<nmolt; im++){
        for(int imr=0; imr<MolecBase[im].nrept; ++imr) {
            Molecule *mi = top.CreateMolecule(MolecBase[im].name);
            for(int ims=0; ims<MolecBase[im].nsites; ims++) {

                BeadType *type = top.GetOrCreateBeadType(FieldSite[is].name); // what is
                Bead *bead = top.CreateBead(1, FieldSite[is].type, type, res->getId(), FieldSite[is].m, FieldSite[is].q);

                stringstream nm;
                nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
                mi->AddBead(bead, nm.str());
            }
        }
    }

    delete [] MolecBase;
    delete [] FieldSite;
#else
    // TODO: fix residue naming / assignment
    Residue *res = top.CreateResidue("no");

    fl.open("FIELD");
    if (!fl.is_open()){
      throw std::runtime_error("could open dlpoly file FIELD");
    } else {
      string line;
      getline(fl, line); //title
      getline(fl, line); //unit line
      fl >> line;
      if (line != "MOLECULES")
          throw std::runtime_error("unexpected line in dlpoly file FIELD, expected 'MOLECULES' got" + line);
      int nmol_types;
      fl >> nmol_types;
      getline(fl, line); //rest of MOLECULES line
      int id=0;
      for (int nmol_type=0;nmol_type<nmol_types; nmol_type++){
	string mol_name;
        getline(fl, mol_name); //molecule name might incl. spaces
	boost::erase_all(mol_name, " ");
        Molecule *mi = top.CreateMolecule(mol_name);
        fl >> line;
        if (line != "NUMMOLS")
          throw std::runtime_error("unexpected line in dlpoly file FIELD, expected 'NUMMOLS' got" + line);
	int nreplica;
	fl >> nreplica;
	fl >> line;
        if (line != "ATOMS")
          throw std::runtime_error("unexpected line in dlpoly file FIELD, expected 'ATOMS' got" + line);
	int natoms;
	fl >> natoms;
	//read molecule
	for (int i=0;i<natoms;){//i is altered in reapeater loop
	  string beadtype;
	  fl >> beadtype;
	  BeadType *type = top.GetOrCreateBeadType(beadtype);
	  double mass;
	  fl >> mass;
	  double charge;
	  fl >> charge;
          getline(fl,line); //rest of the atom line
          Tokenizer tok(line, " ");
          vector<int> fields;
          tok.ConvertToVector<int>(fields);
	  int repeater=1;
	  if (fields.size() > 1)
	    repeater=fields[0];
	  for(int j=0;j<repeater;j++){
	    string beadname = beadtype + boost::lexical_cast<string>(j+1);
	    Bead *bead = top.CreateBead(1, beadname , type, res->getId(), mass, charge);
            stringstream nm;
            nm << bead->getResnr() + 1 << ":" <<  top.getResidue(bead->getResnr())->getName() << ":" << bead->getName();
            mi->AddBead(bead, nm.str());
	    i++;
	  }
	}
	while (line != "FINISH"){
	  fl >> line;
	  if (fl.eof())
            throw std::runtime_error("unexpected end of dlpoly file FIELD while scanning for 'FINISH'");
	}
	getline(fl, line); //rest of the FINISH line
	//replicate molecule
	for (int replica=1;replica<nreplica;replica++){
          Molecule *mi_replica = top.CreateMolecule(mol_name);
	  for(int i=0;i<mi->BeadCount();i++){
	    Bead *bead=mi->getBead(i);
	    BeadType *type = top.GetOrCreateBeadType(bead->Type()->getName());
	    string beadname=mi->getBeadName(i);
	    Bead *bead_replica = top.CreateBead(1, bead->getName(), type, res->getId(), bead->getM(), bead->getQ());
	    mi_replica->AddBead(bead_replica,beadname);
	  }
	}
      }
    }
    //we don't need the rest.
    fl.close();
#endif
    fl.open("CONFIG");
    if(fl.is_open()) {
      string line;
      getline(fl, line); //title
      getline(fl, line); // 2nd header line
      vec box_vectors[3];
      for (int i=0;i<3;i++){ // read 3 box lines
        getline(fl, line);
        if(fl.eof())
          throw std::runtime_error("unexpected end of file in dlpoly file CONFIG, when reading box vector"  +
              boost::lexical_cast<string>(i));
        Tokenizer tok(line, " ");
        vector<double> fields;
        tok.ConvertToVector<double>(fields);
        box_vectors[i]=vec(fields[0],fields[1],fields[2]);
      }
      matrix box(box_vectors[0],box_vectors[1],box_vectors[2]);
      top.setBox(box);
    }
    else {
      cout << "NOTE: Could open dlploy file CONFIG, so no boundary conditions, where set in the topology" << endl;
    }
    fl.close();

    return true;
}

}}

<|endoftext|>


<commit_before>/**
* Copyright 2016 Colin Doig.  Distributed under the MIT license.
*/
#include <iomanip>
#include <sstream>

#include "MatchedOrder.h"
#include "Util.h"

#include "entity/Config.h"

namespace greenthumb {

MatchedOrder::MatchedOrder(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
    long style, const wxString& name) : CurrentOrder(parent, id, pos, size, style, name) {

    wxFlexGridSizer* sizer = new wxFlexGridSizer(6, 5, 5);
    sizer->AddGrowableCol(0, 1);
    SetSizer(sizer);

    runnerName = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
    runnerName->SetMinSize(wxSize(150, -1));

    sizer->Add(runnerName, 0, wxALIGN_CENTRE_VERTICAL);

    price = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
    sizer->Add(price, 0, wxALIGN_CENTRE_VERTICAL);

    wxStaticText* stakeLabel = new wxStaticText(this, wxID_ANY, "Stake: ");
    sizer->Add(stakeLabel, 0, wxALIGN_CENTRE_VERTICAL);
    stake = new wxStaticText(this, wxID_ANY, wxEmptyString);
    sizer->Add(stake, 0, wxALIGN_CENTRE_VERTICAL);

    profitOrLiabilityLabel = new wxStaticText(this, wxID_ANY, wxEmptyString);
    profitOrLiabilityLabel->SetMinSize(wxSize(75, -1));
    sizer->Add(profitOrLiabilityLabel, 0, wxALIGN_CENTRE_VERTICAL);
    profitOrLiability = new wxStaticText(this, wxID_ANY, wxEmptyString);
    sizer->Add(profitOrLiability, 0, wxALIGN_CENTRE_VERTICAL);

}

void MatchedOrder::SetCurrentOrderSummary(const greentop::CurrentOrderSummary& cos) {
    currentOrderSummary = cos;

    if (market.HasRunner(currentOrderSummary.getSelectionId())) {
        greentop::RunnerCatalog runner = market.GetRunner(currentOrderSummary.getSelectionId());

        wxString label(runner.getRunnerName().c_str(), wxConvUTF8);
        runnerName->SetLabel(currentOrderSummary.getSide().getValue() + " " + label);

        std::ostringstream priceLabelStream;
        priceLabelStream << std::fixed << std::setprecision(2) << currentOrderSummary.getPriceSize().getPrice();
        wxString priceLabel(priceLabelStream.str().c_str(), wxConvUTF8);
        price->SetLabel(priceLabel);

        std::string currencySymbol = GetCurrencySymbol(entity::Config::GetConfigValue<std::string>("accountCurrency", "?"));

        std::ostringstream stakeLabelStream;
        double sizeMatched = 0;
        greentop::Optional<double> optionalSizeMatched = currentOrderSummary.getSizeMatched();
        if (optionalSizeMatched.isValid()) {
            sizeMatched = optionalSizeMatched.getValue();
        }
        stakeLabelStream << currencySymbol << std::fixed << std::setprecision(2) << sizeMatched;
        wxString stakeLabel(stakeLabelStream.str().c_str(), wxConvUTF8);

        stake->SetLabel(stakeLabel);

        if (currentOrderSummary.getSide() == greentop::Side::BACK) {
            profitOrLiabilityLabel->SetLabel(_("Profit: "));
            SetBackgroundColour(wxColour(227, 235, 255));
        } else if (currentOrderSummary.getSide() == greentop::Side::LAY) {
            profitOrLiabilityLabel->SetLabel(_("Liability: "));
            SetBackgroundColour(wxColour(255, 224, 255));
        }

        UpdateProfitOrLiability();

    }
}

void MatchedOrder::UpdateProfitOrLiability() {

    std::string currencySymbol = GetCurrencySymbol(entity::Config::GetConfigValue<std::string>("accountCurrency", "?"));

    std::ostringstream profitOrLiabilityStream;

    double profit;

    double sizeMatched = 0;
    greentop::Optional<double> optionalSizeMatched = currentOrderSummary.getSizeMatched();
    if (optionalSizeMatched.isValid()) {
        sizeMatched = optionalSizeMatched.getValue();
    }

    if (currentOrderSummary.getSide() == greentop::Side::BACK) {
        profit = sizeMatched * (currentOrderSummary.getPriceSize().getPrice() - 1);
    } else if (currentOrderSummary.getSide() == greentop::Side::LAY) {
        profit = sizeMatched * (currentOrderSummary.getPriceSize().getPrice() - 1);
    }

    profitOrLiabilityStream << currencySymbol << std::fixed << std::setprecision(2) << profit;

    wxString label(profitOrLiabilityStream.str().c_str(), wxConvUTF8);
    profitOrLiability->SetLabel(label);

}

}
<commit_msg>show price matched instead of price requested in matched orders<commit_after>/**
* Copyright 2016 Colin Doig.  Distributed under the MIT license.
*/
#include <iomanip>
#include <sstream>

#include "MatchedOrder.h"
#include "Util.h"

#include "entity/Config.h"

namespace greenthumb {

MatchedOrder::MatchedOrder(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
    long style, const wxString& name) : CurrentOrder(parent, id, pos, size, style, name) {

    wxFlexGridSizer* sizer = new wxFlexGridSizer(6, 5, 5);
    sizer->AddGrowableCol(0, 1);
    SetSizer(sizer);

    runnerName = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
    runnerName->SetMinSize(wxSize(150, -1));

    sizer->Add(runnerName, 0, wxALIGN_CENTRE_VERTICAL);

    price = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
    sizer->Add(price, 0, wxALIGN_CENTRE_VERTICAL);

    wxStaticText* stakeLabel = new wxStaticText(this, wxID_ANY, "Stake: ");
    sizer->Add(stakeLabel, 0, wxALIGN_CENTRE_VERTICAL);
    stake = new wxStaticText(this, wxID_ANY, wxEmptyString);
    sizer->Add(stake, 0, wxALIGN_CENTRE_VERTICAL);

    profitOrLiabilityLabel = new wxStaticText(this, wxID_ANY, wxEmptyString);
    profitOrLiabilityLabel->SetMinSize(wxSize(75, -1));
    sizer->Add(profitOrLiabilityLabel, 0, wxALIGN_CENTRE_VERTICAL);
    profitOrLiability = new wxStaticText(this, wxID_ANY, wxEmptyString);
    sizer->Add(profitOrLiability, 0, wxALIGN_CENTRE_VERTICAL);

}

void MatchedOrder::SetCurrentOrderSummary(const greentop::CurrentOrderSummary& cos) {
    currentOrderSummary = cos;

    if (market.HasRunner(currentOrderSummary.getSelectionId())) {
        greentop::RunnerCatalog runner = market.GetRunner(currentOrderSummary.getSelectionId());

        wxString label(runner.getRunnerName().c_str(), wxConvUTF8);
        runnerName->SetLabel(currentOrderSummary.getSide().getValue() + " " + label);

        std::ostringstream priceLabelStream;
        priceLabelStream << std::fixed << std::setprecision(2) << currentOrderSummary.getAveragePriceMatched();
        wxString priceLabel(priceLabelStream.str().c_str(), wxConvUTF8);
        price->SetLabel(priceLabel);

        std::string currencySymbol = GetCurrencySymbol(entity::Config::GetConfigValue<std::string>("accountCurrency", "?"));

        std::ostringstream stakeLabelStream;
        double sizeMatched = 0;
        greentop::Optional<double> optionalSizeMatched = currentOrderSummary.getSizeMatched();
        if (optionalSizeMatched.isValid()) {
            sizeMatched = optionalSizeMatched.getValue();
        }
        stakeLabelStream << currencySymbol << std::fixed << std::setprecision(2) << sizeMatched;
        wxString stakeLabel(stakeLabelStream.str().c_str(), wxConvUTF8);

        stake->SetLabel(stakeLabel);

        if (currentOrderSummary.getSide() == greentop::Side::BACK) {
            profitOrLiabilityLabel->SetLabel(_("Profit: "));
            SetBackgroundColour(wxColour(227, 235, 255));
        } else if (currentOrderSummary.getSide() == greentop::Side::LAY) {
            profitOrLiabilityLabel->SetLabel(_("Liability: "));
            SetBackgroundColour(wxColour(255, 224, 255));
        }

        UpdateProfitOrLiability();

    }
}

void MatchedOrder::UpdateProfitOrLiability() {

    std::string currencySymbol = GetCurrencySymbol(entity::Config::GetConfigValue<std::string>("accountCurrency", "?"));

    std::ostringstream profitOrLiabilityStream;

    double profit;

    double sizeMatched = 0;
    greentop::Optional<double> optionalSizeMatched = currentOrderSummary.getSizeMatched();
    if (optionalSizeMatched.isValid()) {
        sizeMatched = optionalSizeMatched.getValue();
    }

    if (currentOrderSummary.getSide() == greentop::Side::BACK) {
        profit = sizeMatched * (currentOrderSummary.getPriceSize().getPrice() - 1);
    } else if (currentOrderSummary.getSide() == greentop::Side::LAY) {
        profit = sizeMatched * (currentOrderSummary.getPriceSize().getPrice() - 1);
    }

    profitOrLiabilityStream << currencySymbol << std::fixed << std::setprecision(2) << profit;

    wxString label(profitOrLiabilityStream.str().c_str(), wxConvUTF8);
    profitOrLiability->SetLabel(label);

}

}
<|endoftext|>


<commit_before>#include "CodeGen_C.h"
#include "StmtToHtml.h"
#include "Output.h"
#include "LLVM_Headers.h"
#include "LLVM_Output.h"

#include <fstream>

using namespace llvm;

namespace Halide {

namespace {

// Define the mex wrapper API call for the given func with name pipeline_name.
llvm::Function *define_mex_wrapper(const std::string &pipeline_name, llvm::Module *module) {
    LLVMContext &ctx = module->getContext();

    llvm::Function *pipeline = module->getFunction(pipeline_name + "_argv");
    internal_assert(pipeline) << "Did not find function '" << pipeline_name << "_argv' in module.\n";
    llvm::Function *mex_call_pipeline = module->getFunction("halide_mex_call_pipeline");
    internal_assert(mex_call_pipeline) << "Did not find function 'halide_mex_call_pipeline' in module.\n";
    llvm::Value *metadata = module->getGlobalVariable(pipeline_name + "_metadata");
    internal_assert(metadata) << "Did not find global variable '" << pipeline_name << "_metadata' in module.\n";

    llvm::Type *void_ty = llvm::Type::getVoidTy(ctx);
    llvm::Type *i8_ty = llvm::Type::getInt8Ty(ctx);
    llvm::Type *i32_ty = llvm::Type::getInt32Ty(ctx);
    Value *user_context = ConstantPointerNull::get(i8_ty->getPointerTo());

    llvm::Type *mxArray_ty = module->getTypeByName("struct.mxArray");
    internal_assert(mxArray_ty) << "Did not find mxArray in initial module";
    llvm::Type *mxArray_ptr_ty = mxArray_ty->getPointerTo();
    llvm::Type *mxArray_ptr_ptr_ty = mxArray_ptr_ty->getPointerTo();

    // Create the mexFunction function.
    llvm::Type *mex_arg_types[] = {
        i32_ty,
        mxArray_ptr_ptr_ty,
        i32_ty,
        mxArray_ptr_ptr_ty,
    };
    FunctionType *mex_ty = FunctionType::get(void_ty, mex_arg_types, false);
    llvm::Function *mex = llvm::Function::Create(mex_ty, llvm::GlobalValue::ExternalLinkage, "mexFunction", module);
    BasicBlock *entry = BasicBlock::Create(ctx, "entry", mex);

    // Extract the argument values.
    llvm::Function::arg_iterator mex_args = mex->arg_begin();
    Value *nlhs = mex_args++;
    Value *plhs = mex_args++;
    Value *nrhs = mex_args++;
    Value *prhs = mex_args++;

    IRBuilder<> ir(ctx);
    ir.SetInsertPoint(entry);

    Value *call_pipeline_args[] = {
        user_context,
        pipeline,
        metadata,
        nlhs,
        plhs,
        nrhs,
        prhs,
    };
    ir.CreateCall(mex_call_pipeline, call_pipeline_args);
    ir.CreateRetVoid();

    return mex;
}

}  // namespace

void compile_module_to_matlab_object(const Module &module, const std::string &pipeline_name,
                                     const std::string &filename) {
    llvm::LLVMContext context;
    llvm::Module *llvm_module = compile_module_to_llvm_module(module, context);
    define_mex_wrapper(pipeline_name, llvm_module);
    compile_llvm_module_to_object(llvm_module, filename);
    delete llvm_module;
}

}  // namespace Halide
<commit_msg>Removed unused headers.<commit_after>#include "Output.h"
#include "LLVM_Headers.h"
#include "LLVM_Output.h"

using namespace llvm;

namespace Halide {

namespace {

// Define the mex wrapper API call for the given func with name pipeline_name.
llvm::Function *define_mex_wrapper(const std::string &pipeline_name, llvm::Module *module) {
    LLVMContext &ctx = module->getContext();

    llvm::Function *pipeline = module->getFunction(pipeline_name + "_argv");
    internal_assert(pipeline) << "Did not find function '" << pipeline_name << "_argv' in module.\n";
    llvm::Function *mex_call_pipeline = module->getFunction("halide_mex_call_pipeline");
    internal_assert(mex_call_pipeline) << "Did not find function 'halide_mex_call_pipeline' in module.\n";
    llvm::Value *metadata = module->getGlobalVariable(pipeline_name + "_metadata");
    internal_assert(metadata) << "Did not find global variable '" << pipeline_name << "_metadata' in module.\n";

    llvm::Type *void_ty = llvm::Type::getVoidTy(ctx);
    llvm::Type *i8_ty = llvm::Type::getInt8Ty(ctx);
    llvm::Type *i32_ty = llvm::Type::getInt32Ty(ctx);
    Value *user_context = ConstantPointerNull::get(i8_ty->getPointerTo());

    llvm::Type *mxArray_ty = module->getTypeByName("struct.mxArray");
    internal_assert(mxArray_ty) << "Did not find mxArray in initial module";
    llvm::Type *mxArray_ptr_ty = mxArray_ty->getPointerTo();
    llvm::Type *mxArray_ptr_ptr_ty = mxArray_ptr_ty->getPointerTo();

    // Create the mexFunction function.
    llvm::Type *mex_arg_types[] = {
        i32_ty,
        mxArray_ptr_ptr_ty,
        i32_ty,
        mxArray_ptr_ptr_ty,
    };
    FunctionType *mex_ty = FunctionType::get(void_ty, mex_arg_types, false);
    llvm::Function *mex = llvm::Function::Create(mex_ty, llvm::GlobalValue::ExternalLinkage, "mexFunction", module);
    BasicBlock *entry = BasicBlock::Create(ctx, "entry", mex);

    // Extract the argument values.
    llvm::Function::arg_iterator mex_args = mex->arg_begin();
    Value *nlhs = mex_args++;
    Value *plhs = mex_args++;
    Value *nrhs = mex_args++;
    Value *prhs = mex_args++;

    IRBuilder<> ir(ctx);
    ir.SetInsertPoint(entry);

    Value *call_pipeline_args[] = {
        user_context,
        pipeline,
        metadata,
        nlhs,
        plhs,
        nrhs,
        prhs,
    };
    ir.CreateCall(mex_call_pipeline, call_pipeline_args);
    ir.CreateRetVoid();

    return mex;
}

}  // namespace

void compile_module_to_matlab_object(const Module &module, const std::string &pipeline_name,
                                     const std::string &filename) {
    llvm::LLVMContext context;
    llvm::Module *llvm_module = compile_module_to_llvm_module(module, context);
    define_mex_wrapper(pipeline_name, llvm_module);
    compile_llvm_module_to_object(llvm_module, filename);
    delete llvm_module;
}

}  // namespace Halide
<|endoftext|>