<commit_before>#include "stdafx.h"
#include "NvApi.h"

NvApi::NvApi() {
	// Try loading the 64 bit library.
	hDll = LoadLibraryA("nvapi64.dll");

	// A 32 bit calling application on 64 bit OS will fail to LoadLibrary.
	// Try to load the 32 bit library (nvapi.dll) instead.
	if (hDll == nullptr) {
		hDll = LoadLibraryA("nvapi.dll");
	}

	// Try loading the query function pointer.
	NvAPI_QueryInterface = reinterpret_cast<NvAPI_QueryInterface_t>(GetProcAddress(hDll, "nvapi_QueryInterface"));

	// Use the query funtion to get the pointers to the used functions.
	// The offset of each function in the NvApi can be found at:
	// https://github.com/jNizM/AHK_NVIDIA_NvAPI/blob/master/src/Class_NvAPI.ahk
	NvAPI_Initialize                       = reinterpret_cast<NvAPI_Initialize_t>(                      (*NvAPI_QueryInterface)(0x0150E828));
	NvAPI_Unload                           = reinterpret_cast<NvAPI_Unload_t>(                          (*NvAPI_QueryInterface)(0xD22BDD7E));
	NvAPI_GetDVCInfoEx                     = reinterpret_cast<NvAPI_GetDVCInfoEx_t>(                    (*NvAPI_QueryInterface)(0x0E45002D));
	NvAPI_SetDVCLevel                      = reinterpret_cast<NvAPI_SetDVCLevel_t>(                     (*NvAPI_QueryInterface)(0x172409B4));
	NvAPI_EnumNvidiaDisplayHandle          = reinterpret_cast<NvAPI_EnumNvidiaDisplayHandle_t>(         (*NvAPI_QueryInterface)(0x9ABDD40D));
	NvAPI_EnumPhysicalGPUs                 = reinterpret_cast<NvAPI_EnumPhysicalGPUs_t>(                (*NvAPI_QueryInterface)(0xE5AC921F));
	NvAPI_GetAssociatedNvidiaDisplayHandle = reinterpret_cast<NvAPI_GetAssociatedNvidiaDisplayHandle_t>((*NvAPI_QueryInterface)(0x35C29134));
	NvAPI_GetAssociatedNvidiaDisplayName   = reinterpret_cast<NvAPI_GetAssociatedNvidiaDisplayName_t>(  (*NvAPI_QueryInterface)(0x22A78B05));
	NvAPI_GPU_GetSystemType                = reinterpret_cast<NvAPI_GPU_GetSystemType_t>(               (*NvAPI_QueryInterface)(0xBAAABFCC));

	NvAPI_Initialize();

	// Only desktop GPUs support changing the digital vibrance.
	if (IsDesktopGPU()) {
		// Add all displays to the display names vector.
		int counter = 0;
		NvDisplayHandle handle = nullptr;
		char name[64] = {0};
		std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
		int status = (*NvAPI_EnumNvidiaDisplayHandle)(counter, &handle);

		while (status != NVAPI_END_ENUMERATION) {
			NvAPI_GetAssociatedNvidiaDisplayName(handle, name);
			displayNames.push_back(converter.from_bytes(name));
			status = (*NvAPI_EnumNvidiaDisplayHandle)(++counter, &handle);
		}
	}
}

NvApi::~NvApi() {
	NvAPI_Unload();
	FreeLibrary(hDll);
}

std::vector<std::wstring> NvApi::GetDisplayNames() const {
	return displayNames;
}

DriverInterface::FeatureValues NvApi::GetDigitalVibranceInfo(const std::wstring displayName) const {
	NV_DISPLAY_DVC_INFO_EX info = {};
	info.version = sizeof(NV_DISPLAY_DVC_INFO_EX) | 0x10000;
	NvAPI_GetDVCInfoEx(GetHandle(displayName), 0, &info);

	// HACK: The reported min digital vibrance of 0 sets the vibrance to 50.
	info.currentLevel = 2 * (info.currentLevel - 50);
	info.defaultLevel -= 50;

	return {info.currentLevel, info.defaultLevel, info.minLevel, info.maxLevel};
}

void NvApi::SetDigitalVibrance(const std::wstring displayName, const int newValue) const {
	// HACK: The reported max digital vibrance of 100 gets already set with the newValue 63.
	NvAPI_SetDVCLevel(GetHandle(displayName), 0, newValue * 0.63);
}

NvApi::NvDisplayHandle NvApi::GetHandle(const std::wstring displayName) const {
	std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
	NvDisplayHandle handle = nullptr;
	NvAPI_GetAssociatedNvidiaDisplayHandle(converter.to_bytes(displayName).c_str(), &handle);
	return handle;
}

bool NvApi::IsDesktopGPU() const {
	int count, system_type;
	NvPhysicalGpuHandle handles[64] = {nullptr};

	NvAPI_EnumPhysicalGPUs(handles, &count);
	NvAPI_GPU_GetSystemType(handles[0], &system_type);

	return system_type == NV_SYSTEM_TYPE_DESKTOP;
}
<commit_msg>Fix conversion warning<commit_after>#include "stdafx.h"
#include "NvApi.h"

NvApi::NvApi() {
	// Try loading the 64 bit library.
	hDll = LoadLibraryA("nvapi64.dll");

	// A 32 bit calling application on 64 bit OS will fail to LoadLibrary.
	// Try to load the 32 bit library (nvapi.dll) instead.
	if (hDll == nullptr) {
		hDll = LoadLibraryA("nvapi.dll");
	}

	// Try loading the query function pointer.
	NvAPI_QueryInterface = reinterpret_cast<NvAPI_QueryInterface_t>(GetProcAddress(hDll, "nvapi_QueryInterface"));

	// Use the query funtion to get the pointers to the used functions.
	// The offset of each function in the NvApi can be found at:
	// https://github.com/jNizM/AHK_NVIDIA_NvAPI/blob/master/src/Class_NvAPI.ahk
	NvAPI_Initialize                       = reinterpret_cast<NvAPI_Initialize_t>(                      (*NvAPI_QueryInterface)(0x0150E828));
	NvAPI_Unload                           = reinterpret_cast<NvAPI_Unload_t>(                          (*NvAPI_QueryInterface)(0xD22BDD7E));
	NvAPI_GetDVCInfoEx                     = reinterpret_cast<NvAPI_GetDVCInfoEx_t>(                    (*NvAPI_QueryInterface)(0x0E45002D));
	NvAPI_SetDVCLevel                      = reinterpret_cast<NvAPI_SetDVCLevel_t>(                     (*NvAPI_QueryInterface)(0x172409B4));
	NvAPI_EnumNvidiaDisplayHandle          = reinterpret_cast<NvAPI_EnumNvidiaDisplayHandle_t>(         (*NvAPI_QueryInterface)(0x9ABDD40D));
	NvAPI_EnumPhysicalGPUs                 = reinterpret_cast<NvAPI_EnumPhysicalGPUs_t>(                (*NvAPI_QueryInterface)(0xE5AC921F));
	NvAPI_GetAssociatedNvidiaDisplayHandle = reinterpret_cast<NvAPI_GetAssociatedNvidiaDisplayHandle_t>((*NvAPI_QueryInterface)(0x35C29134));
	NvAPI_GetAssociatedNvidiaDisplayName   = reinterpret_cast<NvAPI_GetAssociatedNvidiaDisplayName_t>(  (*NvAPI_QueryInterface)(0x22A78B05));
	NvAPI_GPU_GetSystemType                = reinterpret_cast<NvAPI_GPU_GetSystemType_t>(               (*NvAPI_QueryInterface)(0xBAAABFCC));

	NvAPI_Initialize();

	// Only desktop GPUs support changing the digital vibrance.
	if (IsDesktopGPU()) {
		// Add all displays to the display names vector.
		int counter = 0;
		NvDisplayHandle handle = nullptr;
		char name[64] = {0};
		std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
		int status = (*NvAPI_EnumNvidiaDisplayHandle)(counter, &handle);

		while (status != NVAPI_END_ENUMERATION) {
			NvAPI_GetAssociatedNvidiaDisplayName(handle, name);
			displayNames.push_back(converter.from_bytes(name));
			status = (*NvAPI_EnumNvidiaDisplayHandle)(++counter, &handle);
		}
	}
}

NvApi::~NvApi() {
	NvAPI_Unload();
	FreeLibrary(hDll);
}

std::vector<std::wstring> NvApi::GetDisplayNames() const {
	return displayNames;
}

DriverInterface::FeatureValues NvApi::GetDigitalVibranceInfo(const std::wstring displayName) const {
	NV_DISPLAY_DVC_INFO_EX info = {};
	info.version = sizeof(NV_DISPLAY_DVC_INFO_EX) | 0x10000;
	NvAPI_GetDVCInfoEx(GetHandle(displayName), 0, &info);

	// HACK: The reported min digital vibrance of 0 sets the vibrance to 50.
	info.currentLevel = 2 * (info.currentLevel - 50);
	info.defaultLevel -= 50;

	return {info.currentLevel, info.defaultLevel, info.minLevel, info.maxLevel};
}

void NvApi::SetDigitalVibrance(const std::wstring displayName, const int newValue) const {
	// HACK: The reported max digital vibrance of 100 gets already set with the newValue 63.
	NvAPI_SetDVCLevel(GetHandle(displayName), 0, static_cast<int>(newValue * 0.63));
}

NvApi::NvDisplayHandle NvApi::GetHandle(const std::wstring displayName) const {
	std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
	NvDisplayHandle handle = nullptr;
	NvAPI_GetAssociatedNvidiaDisplayHandle(converter.to_bytes(displayName).c_str(), &handle);
	return handle;
}

bool NvApi::IsDesktopGPU() const {
	int count, system_type;
	NvPhysicalGpuHandle handles[64] = {nullptr};

	NvAPI_EnumPhysicalGPUs(handles, &count);
	NvAPI_GPU_GetSystemType(handles[0], &system_type);

	return system_type == NV_SYSTEM_TYPE_DESKTOP;
}
<|endoftext|>


<commit_before>//============================================================================
// Name        : MediaEval-PlacingTask.cpp
// Author      : Andrés Pérez
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C, Ansi-style
//============================================================================

#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <ctime>
#include <sys/stat.h>

#include <opencv2/core/internal.hpp>
#include <opencv2/extensions/features2d.hpp>
#include <opencv2/flann/flann.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <opencv2/nonfree/nonfree.hpp>

// KMajority
#include <Clustering.h>
#include <BOWKmajorityTrainer.h>

// VocabTree
#include <VocabTree.h>

// DBoW2
//#include <DBoW2.h>
//#include <DUtilsCV.h>
//#include <DVision.h>

#include <FileUtils.hpp>

using cv::Mat;
using std::vector;

double mytime;

int main(int argc, char **argv) {

	// Initiating non-free module, it's necessary for using SIFT and SURF
//	cv::initModule_nonfree();

//	printf("-- Loading image [%s]\n", argv[1]);

//	mytime = (double) cv::getTickCount();
//	Mat img_1 = cv::imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;

//	if (img_1.empty()) {
//		fprintf(stderr, "-- Error reading image [%s]\n", argv[1]);
//	}
//	printf("-- Image loaded in [%lf] ms\n", mytime);

// Step 1/5: detect keypoints using FAST or AGAST
//	std::vector<cv::KeyPoint> keypoints;
//	cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create(
//			"AGAST");
//	printParams(detector);

//	mytime = cv::getTickCount();
//	detector->detect(img_1, keypoints);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;
//	printf("-- Detected [%zu] keypoints in [%lf] ms\n", keypoints.size(),
//			mytime);

// Step 2/5: extract descriptors using BRIEF or DBRIEF
//	cv::Ptr<cv::DescriptorExtractor> extractor =
//			cv::DescriptorExtractor::create("BRIEF");

//	Mat descriptors;

//	mytime = cv::getTickCount();
//	extractor->compute(img_1, keypoints, descriptors);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;

// Notice that number of keypoints might be reduced due to border effect
//	printf(
//			"-- Extracted [%d] descriptors of size [%d] and type [%s] in [%lf] ms\n",
//			descriptors.rows, descriptors.cols,
//			descriptors.type() == CV_8U ? "binary" : "real-valued", mytime);

// Step 3/5: Show keypoints

//	cv::drawKeypoints(img_1, keypoints, img_1, cv::Scalar::all(-1));
//	cv::namedWindow("Image keypoints", CV_WINDOW_NORMAL);
//	cv::imshow("Image keypoints", img_1);

//	cv::waitKey(0);

// Step 4/5: save descriptors into a file for later use
//	FileUtils::save("test.xml.gz", keypoints, descriptors);

// Step 5/5: Cluster descriptors using binary vocabulary tree aided by k-means

// Transform descriptors to a suitable structure for DBoW2
//	printf("-- Transforming descriptors to a suitable structure for DBoW2\n");
//	vector<vector<DVision::BRIEF::bitset> > features;
//	features.resize(1);
//
//	features[0].resize(descriptors.rows);
//
//	for (unsigned int i = 0; (int) i < descriptors.rows * descriptors.cols;
//			i++) {
//		int row = (int) i / descriptors.cols;
//		int col = (int) i % descriptors.cols;
//		if (col == 0) {
//			(features[0])[row].resize(descriptors.cols * 8);
//			(features[0])[row].reset();
//		}
//		unsigned char byte = descriptors.at<uchar>(row, col);
//		for (int i = 0 + (descriptors.cols - 1 - col) * 8;
//				i <= 7 + (descriptors.cols - 1 - col) * 8; i++) {
//			((features[0])[row])[i] = byte & 1;
//			byte >>= 1;
//		}
//	}
//
//	printf("   Obtained [%zu] vectors\n", features.size());
//
//	const int k = 6;
//	const int L = 3;
//	const DBoW2::WeightingType weight = DBoW2::TF_IDF;
//	const DBoW2::ScoringType score = DBoW2::L1_NORM;
//
//	BriefVocabulary voc(k, L, weight, score);
//	mytime = cv::getTickCount();
//	voc.create(features);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;
//	printf(
//			"-- Vocabulary created in [%lf] ms with NWORDS=%u BRANCHING=%d DEPTH=%d SCORING=%s WEIGHTING=%s\n",
//			mytime, voc.size(), k, L,
//			weight == DBoW2::TF_IDF ? "tf-idf" : weight == DBoW2::TF ? "tf" :
//			weight == DBoW2::IDF ? "idf" :
//			weight == DBoW2::BINARY ? "binary" : "unknown",
//			score == DBoW2::L1_NORM ? "L1-norm" :
//			score == DBoW2::L2_NORM ? "L2-norm" :
//			score == DBoW2::CHI_SQUARE ? "Chi square distance" :
//			score == DBoW2::KL ? "KL-divergence" :
//			score == DBoW2::BHATTACHARYYA ? "Bhattacharyya coefficient" :
//			score == DBoW2::DOT_PRODUCT ? "Dot product" : "unknown");

	if (argc != 6) {
		printf("Usage: %s <list.in> <depth> <branching_factor> "
				"<restarts> <tree.out>\n", argv[0]);
		return EXIT_FAILURE;
	}

	const char *list_in = argv[1];
	int depth = atoi(argv[2]);
	int branchFactor = atoi(argv[3]);
	int restarts = atoi(argv[4]);
	const char *tree_out = argv[5];

	printf("-- Building tree with depth: %d, branching factor: %d, "
			"and restarts: %d\n", depth, branchFactor, restarts);

	// Step 1: read list of key files that shall be used to build the tree
	std::vector<std::string> keysFilenames;
	std::ifstream keysList(list_in, std::fstream::in);

	if (keysList.is_open() == false) {
		fprintf(stderr, "Error opening file [%s] for reading", list_in);
	}

	// Loading file names in list into a vector
	std::string line;
	while (getline(keysList, line)) {
		struct stat buffer;
		// Checking if file exist, if not print error and exit
		if (stat(line.c_str(), &buffer) == 0) {
			keysFilenames.push_back(line);
		} else {
			fprintf(stderr, "Found invalid keypoints file [%s]", line.c_str());
			return EXIT_FAILURE;
		}
	}
	// Close file
	keysList.close();

	// Step 2: read key files
	std::vector<cv::KeyPoint> keypoints;
	cv::Mat descriptors, mergedDescriptors;

	for (std::string keyFileName : keysFilenames) {
		// Initialize keypoints and descriptors
		keypoints.clear();
		descriptors = cv::Mat();
		FileUtils::loadFeatures(keyFileName, keypoints, descriptors);
		// Check that keypoints and descriptors have same length
		CV_Assert((int )keypoints.size() == descriptors.rows);
//		tree.add(descriptors);
	}

	// Step 3: build tree

//	// Cluster descriptors using Vocabulary Tree
//	cvflann::VocabTreeParams params;
//	// TODO Add method for composing descriptors big matrix from the list of descriptors references
//	cvflann::VocabTree tree(descriptors, params);
//
//	printf(
//			"-- Creating vocabulary tree using [%d] feature vectors, branch factor [%d], max iterations [%d], depth [%d], centers init algorithm [%s]\n",
//			descriptors.rows, params["branching"].cast<int>(),
//			params["iterations"].cast<int>(), params["depth"].cast<int>(),
//			params["centers_init"].cast<cvflann::flann_centers_init_t>()
//					== cvflann::FLANN_CENTERS_RANDOM ? "random" :
//			params["centers_init"].cast<cvflann::flann_centers_init_t>()
//					== cvflann::FLANN_CENTERS_GONZALES ? "gonzalez" :
//			params["centers_init"].cast<cvflann::flann_centers_init_t>()
//					== cvflann::FLANN_CENTERS_KMEANSPP ?
//					"k-means++" : "unknown");
//
//	mytime = cv::getTickCount();
//	tree.build();
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;
//	printf("   Vocabulary created in [%lf] ms with [%lu] words\n", mytime,
//			tree.size());
//
//	std::string treeOut = "tree.yaml.gz";
//	printf("   Saving tree to [%s]\n", treeOut.c_str());
//	tree.save(treeOut);

	delete list_in;
	delete tree_out;

	return EXIT_SUCCESS;
}
<commit_msg>VocabLearn/VocabLearn.cpp * Changed usage instructions.<commit_after>//============================================================================
// Name        : MediaEval-PlacingTask.cpp
// Author      : Andrés Pérez
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C, Ansi-style
//============================================================================

#include <bitset>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <ctime>
#include <sys/stat.h>

#include <opencv2/core/internal.hpp>
#include <opencv2/extensions/features2d.hpp>
#include <opencv2/flann/flann.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <opencv2/nonfree/nonfree.hpp>

// KMajority
#include <Clustering.h>
#include <BOWKmajorityTrainer.h>

// VocabTree
#include <VocabTree.h>

// DBoW2
//#include <DBoW2.h>
//#include <DUtilsCV.h>
//#include <DVision.h>

#include <FileUtils.hpp>

using cv::Mat;
using std::vector;

double mytime;

int main(int argc, char **argv) {

	// Initiating non-free module, it's necessary for using SIFT and SURF
//	cv::initModule_nonfree();

//	printf("-- Loading image [%s]\n", argv[1]);

//	mytime = (double) cv::getTickCount();
//	Mat img_1 = cv::imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;

//	if (img_1.empty()) {
//		fprintf(stderr, "-- Error reading image [%s]\n", argv[1]);
//	}
//	printf("-- Image loaded in [%lf] ms\n", mytime);

// Step 1/5: detect keypoints using FAST or AGAST
//	std::vector<cv::KeyPoint> keypoints;
//	cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create(
//			"AGAST");
//	printParams(detector);

//	mytime = cv::getTickCount();
//	detector->detect(img_1, keypoints);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;
//	printf("-- Detected [%zu] keypoints in [%lf] ms\n", keypoints.size(),
//			mytime);

// Step 2/5: extract descriptors using BRIEF or DBRIEF
//	cv::Ptr<cv::DescriptorExtractor> extractor =
//			cv::DescriptorExtractor::create("BRIEF");

//	Mat descriptors;

//	mytime = cv::getTickCount();
//	extractor->compute(img_1, keypoints, descriptors);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;

// Notice that number of keypoints might be reduced due to border effect
//	printf(
//			"-- Extracted [%d] descriptors of size [%d] and type [%s] in [%lf] ms\n",
//			descriptors.rows, descriptors.cols,
//			descriptors.type() == CV_8U ? "binary" : "real-valued", mytime);

// Step 3/5: Show keypoints

//	cv::drawKeypoints(img_1, keypoints, img_1, cv::Scalar::all(-1));
//	cv::namedWindow("Image keypoints", CV_WINDOW_NORMAL);
//	cv::imshow("Image keypoints", img_1);

//	cv::waitKey(0);

// Step 4/5: save descriptors into a file for later use
//	FileUtils::save("test.xml.gz", keypoints, descriptors);

// Step 5/5: Cluster descriptors using binary vocabulary tree aided by k-means

// Transform descriptors to a suitable structure for DBoW2
//	printf("-- Transforming descriptors to a suitable structure for DBoW2\n");
//	vector<vector<DVision::BRIEF::bitset> > features;
//	features.resize(1);
//
//	features[0].resize(descriptors.rows);
//
//	for (unsigned int i = 0; (int) i < descriptors.rows * descriptors.cols;
//			i++) {
//		int row = (int) i / descriptors.cols;
//		int col = (int) i % descriptors.cols;
//		if (col == 0) {
//			(features[0])[row].resize(descriptors.cols * 8);
//			(features[0])[row].reset();
//		}
//		unsigned char byte = descriptors.at<uchar>(row, col);
//		for (int i = 0 + (descriptors.cols - 1 - col) * 8;
//				i <= 7 + (descriptors.cols - 1 - col) * 8; i++) {
//			((features[0])[row])[i] = byte & 1;
//			byte >>= 1;
//		}
//	}
//
//	printf("   Obtained [%zu] vectors\n", features.size());
//
//	const int k = 6;
//	const int L = 3;
//	const DBoW2::WeightingType weight = DBoW2::TF_IDF;
//	const DBoW2::ScoringType score = DBoW2::L1_NORM;
//
//	BriefVocabulary voc(k, L, weight, score);
//	mytime = cv::getTickCount();
//	voc.create(features);
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;
//	printf(
//			"-- Vocabulary created in [%lf] ms with NWORDS=%u BRANCHING=%d DEPTH=%d SCORING=%s WEIGHTING=%s\n",
//			mytime, voc.size(), k, L,
//			weight == DBoW2::TF_IDF ? "tf-idf" : weight == DBoW2::TF ? "tf" :
//			weight == DBoW2::IDF ? "idf" :
//			weight == DBoW2::BINARY ? "binary" : "unknown",
//			score == DBoW2::L1_NORM ? "L1-norm" :
//			score == DBoW2::L2_NORM ? "L2-norm" :
//			score == DBoW2::CHI_SQUARE ? "Chi square distance" :
//			score == DBoW2::KL ? "KL-divergence" :
//			score == DBoW2::BHATTACHARYYA ? "Bhattacharyya coefficient" :
//			score == DBoW2::DOT_PRODUCT ? "Dot product" : "unknown");

	if (argc != 6) {
		printf("\nUsage:\n"
				"\t%s <list.in> <depth>"
				" <branching_factor> <restarts>"
				" <tree.out>\n\n", argv[0]);
		return EXIT_FAILURE;
	}

	const char *list_in = argv[1];
	int depth = atoi(argv[2]);
	int branchFactor = atoi(argv[3]);
	int restarts = atoi(argv[4]);
	const char *tree_out = argv[5];

	printf("-- Building tree with depth: %d, branching factor: %d, "
			"and restarts: %d\n", depth, branchFactor, restarts);

	// Step 1: read list of key files that shall be used to build the tree
	std::vector<std::string> keysFilenames;
	std::ifstream keysList(list_in, std::fstream::in);

	if (keysList.is_open() == false) {
		fprintf(stderr, "Error opening file [%s] for reading", list_in);
	}

	// Loading file names in list into a vector
	std::string line;
	while (getline(keysList, line)) {
		struct stat buffer;
		// Checking if file exist, if not print error and exit
		if (stat(line.c_str(), &buffer) == 0) {
			keysFilenames.push_back(line);
		} else {
			fprintf(stderr, "Found invalid keypoints file [%s]", line.c_str());
			return EXIT_FAILURE;
		}
	}
	// Close file
	keysList.close();

	// Step 2: read key files
	std::vector<cv::KeyPoint> keypoints;
	cv::Mat descriptors, mergedDescriptors;

	for (std::string keyFileName : keysFilenames) {
		// Initialize keypoints and descriptors
		keypoints.clear();
		descriptors = cv::Mat();
		FileUtils::loadFeatures(keyFileName, keypoints, descriptors);
		// Check that keypoints and descriptors have same length
		CV_Assert((int )keypoints.size() == descriptors.rows);
//		tree.add(descriptors);
	}

	// Step 3: build tree

//	// Cluster descriptors using Vocabulary Tree
//	cvflann::VocabTreeParams params;
//	// TODO Add method for composing descriptors big matrix from the list of descriptors references
//	cvflann::VocabTree tree(descriptors, params);
//
//	printf(
//			"-- Creating vocabulary tree using [%d] feature vectors, branch factor [%d], max iterations [%d], depth [%d], centers init algorithm [%s]\n",
//			descriptors.rows, params["branching"].cast<int>(),
//			params["iterations"].cast<int>(), params["depth"].cast<int>(),
//			params["centers_init"].cast<cvflann::flann_centers_init_t>()
//					== cvflann::FLANN_CENTERS_RANDOM ? "random" :
//			params["centers_init"].cast<cvflann::flann_centers_init_t>()
//					== cvflann::FLANN_CENTERS_GONZALES ? "gonzalez" :
//			params["centers_init"].cast<cvflann::flann_centers_init_t>()
//					== cvflann::FLANN_CENTERS_KMEANSPP ?
//					"k-means++" : "unknown");
//
//	mytime = cv::getTickCount();
//	tree.build();
//	mytime = ((double) cv::getTickCount() - mytime) / cv::getTickFrequency()
//			* 1000;
//	printf("   Vocabulary created in [%lf] ms with [%lu] words\n", mytime,
//			tree.size());
//
//	std::string treeOut = "tree.yaml.gz";
//	printf("   Saving tree to [%s]\n", treeOut.c_str());
//	tree.save(treeOut);

	delete list_in;
	delete tree_out;

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>Fix broken bootloader config.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: b2dpolypolygon.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 20:46:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser 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, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BGFX_POLYGON_B2DPOLYPOLYGON_HXX
#include <basegfx/polygon/b2dpolypolygon.hxx>
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX
#include <basegfx/polygon/b2dpolygon.hxx>
#endif

#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#endif

#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif

#include <vector>

//////////////////////////////////////////////////////////////////////////////

class ImplB2DPolyPolygon
{
    typedef ::std::vector< ::basegfx::B2DPolygon >  PolygonVector;

    PolygonVector                                   maPolygons;
    sal_uInt32                                      mnRefCount;

public:
    // This constructor is only used from the static identity polygon, thus
    // the RefCount is set to 1 to never 'delete' this static incarnation.
    ImplB2DPolyPolygon()
    :   mnRefCount(1)
    {
        // complete initialization with defaults
    }

    ImplB2DPolyPolygon(const ImplB2DPolyPolygon& rToBeCopied)
    :   mnRefCount(0)
    {
        // complete initialization using copy
        maPolygons = rToBeCopied.maPolygons;
    }

    ImplB2DPolyPolygon(const ::basegfx::B2DPolygon& rToBeCopied)
    :   mnRefCount(0)
    {
        // complete initialization using copy
        maPolygons.push_back( rToBeCopied );
    }

    ~ImplB2DPolyPolygon()
    {
    }

    const sal_uInt32 getRefCount() const { return mnRefCount; }
    void incRefCount() { mnRefCount++; }
    void decRefCount() { mnRefCount--; }

    bool isEqual(const ImplB2DPolyPolygon& rPolygonList) const
    {
        // same polygon count?
        if(maPolygons.size() != rPolygonList.maPolygons.size())
            return false;

        // if zero polygons the polys are equal
        if(!maPolygons.size())
            return true;

        // compare polygon content
        if(maPolygons != rPolygonList.maPolygons)
            return false;

        return true;
    }

    const ::basegfx::B2DPolygon& getB2DPolygon(sal_uInt32 nIndex) const
    {
        return maPolygons[nIndex];
    }

    void setB2DPolygon(sal_uInt32 nIndex, const ::basegfx::B2DPolygon& rPolygon)
    {
        maPolygons[nIndex] = rPolygon;
    }

    void insert(sal_uInt32 nIndex, const ::basegfx::B2DPolygon& rPolygon, sal_uInt32 nCount)
    {
        if(nCount)
        {
            // add nCount copies of rPolygon
            PolygonVector::iterator aIndex(maPolygons.begin());
            aIndex += nIndex;
            maPolygons.insert(aIndex, nCount, rPolygon);
        }
    }

    void insert(sal_uInt32 nIndex, const ::basegfx::B2DPolyPolygon& rPolyPolygon)
    {
        const sal_uInt32 nCount = rPolyPolygon.count();

        if(nCount)
        {
            // add nCount polygons from rPolyPolygon
            maPolygons.reserve(maPolygons.size() + nCount);
            PolygonVector::iterator aIndex(maPolygons.begin());
            aIndex += nIndex;

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                maPolygons.insert(aIndex, rPolyPolygon.getB2DPolygon(a));
                aIndex++;
            }
        }
    }

    void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
    {
        if(nCount)
        {
            // remove polygon data
            PolygonVector::iterator aStart(maPolygons.begin());
            aStart += nIndex;
            const PolygonVector::iterator aEnd(aStart + nCount);

            maPolygons.erase(aStart, aEnd);
        }
    }

    sal_uInt32 count() const
    {
        return maPolygons.size();
    }

    void setClosed(bool bNew)
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].setClosed(bNew);
        }
    }

    void flip()
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].flip();
        }
    }

    void removeDoublePoints()
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].removeDoublePoints();
        }
    }

    void transform(const ::basegfx::B2DHomMatrix& rMatrix)
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].transform(rMatrix);
        }
    }
};

//////////////////////////////////////////////////////////////////////////////

namespace { struct DefaultPolyPolygon: public rtl::Static<ImplB2DPolyPolygon, DefaultPolyPolygon> {}; }

namespace basegfx
{
    void B2DPolyPolygon::implForceUniqueCopy()
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
            mpPolyPolygon = new ImplB2DPolyPolygon(*mpPolyPolygon);
        }
    }

    B2DPolyPolygon::B2DPolyPolygon()
    :   mpPolyPolygon(&DefaultPolyPolygon::get())
    {
        mpPolyPolygon->incRefCount();
    }

    B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon& rPolyPolygon)
    :   mpPolyPolygon(rPolyPolygon.mpPolyPolygon)
    {
        mpPolyPolygon->incRefCount();
    }

    B2DPolyPolygon::B2DPolyPolygon(const B2DPolygon& rPolygon)
    :   mpPolyPolygon( new ImplB2DPolyPolygon(rPolygon) )
    {
    }

    B2DPolyPolygon::~B2DPolyPolygon()
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
        }
        else
        {
            delete mpPolyPolygon;
        }
    }

    B2DPolyPolygon& B2DPolyPolygon::operator=(const B2DPolyPolygon& rPolyPolygon)
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
        }
        else
        {
            delete mpPolyPolygon;
        }

        mpPolyPolygon = rPolyPolygon.mpPolyPolygon;
        mpPolyPolygon->incRefCount();

        return *this;
    }

    bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
    {
        if(mpPolyPolygon == rPolyPolygon.mpPolyPolygon)
        {
            return true;
        }

        return mpPolyPolygon->isEqual(*(rPolyPolygon.mpPolyPolygon));
    }

    bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
    {
        if(mpPolyPolygon == rPolyPolygon.mpPolyPolygon)
        {
            return false;
        }

        return !mpPolyPolygon->isEqual(*(rPolyPolygon.mpPolyPolygon));
    }

    sal_uInt32 B2DPolyPolygon::count() const
    {
        return mpPolyPolygon->count();
    }

    B2DPolygon B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex) const
    {
        OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");

        return mpPolyPolygon->getB2DPolygon(nIndex);
    }

    void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& rPolygon)
    {
        OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");

        if(mpPolyPolygon->getB2DPolygon(nIndex) != rPolygon)
        {
            implForceUniqueCopy();
            mpPolyPolygon->setB2DPolygon(nIndex, rPolygon);
        }
    }

    bool B2DPolyPolygon::areControlVectorsUsed() const
    {
        for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
        {
            const ::basegfx::B2DPolygon& rPolygon = mpPolyPolygon->getB2DPolygon(a);

            if(rPolygon.areControlVectorsUsed())
            {
                return true;
            }
        }

        return false;
    }

    void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, sal_uInt32 nCount)
    {
        OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");

        if(nCount)
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(nIndex, rPolygon, nCount);
        }
    }

    void B2DPolyPolygon::append(const B2DPolygon& rPolygon, sal_uInt32 nCount)
    {
        if(nCount)
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount);
        }
    }

    void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolyPolygon& rPolyPolygon)
    {
        OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");

        if(rPolyPolygon.count())
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(nIndex, rPolyPolygon);
        }
    }

    void B2DPolyPolygon::append(const B2DPolyPolygon& rPolyPolygon)
    {
        if(rPolyPolygon.count())
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon);
        }
    }

    void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
    {
        OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B2DPolyPolygon Remove outside range (!)");

        if(nCount)
        {
            implForceUniqueCopy();
            mpPolyPolygon->remove(nIndex, nCount);
        }
    }

    void B2DPolyPolygon::clear()
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
        }
        else
        {
            delete mpPolyPolygon;
        }

        mpPolyPolygon = &DefaultPolyPolygon::get();
        mpPolyPolygon->incRefCount();
    }

    bool B2DPolyPolygon::isClosed() const
    {
        bool bRetval(true);

        // PolyPOlygon is closed when all contained Polygons are closed or
        // no Polygon exists.
        for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
        {
            if(!(mpPolyPolygon->getB2DPolygon(a)).isClosed())
            {
                bRetval = false;
            }
        }

        return bRetval;
    }

    void B2DPolyPolygon::setClosed(bool bNew)
    {
        if(bNew != isClosed())
        {
            implForceUniqueCopy();
            mpPolyPolygon->setClosed(bNew);
        }
    }

    void B2DPolyPolygon::flip()
    {
        implForceUniqueCopy();
        mpPolyPolygon->flip();
    }

    bool B2DPolyPolygon::hasDoublePoints() const
    {
        bool bRetval(false);

        for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
        {
            if((mpPolyPolygon->getB2DPolygon(a)).hasDoublePoints())
            {
                bRetval = true;
            }
        }

        return bRetval;
    }

    void B2DPolyPolygon::removeDoublePoints()
    {
        if(hasDoublePoints())
        {
            implForceUniqueCopy();
            mpPolyPolygon->removeDoublePoints();
        }
    }

    void B2DPolyPolygon::transform(const ::basegfx::B2DHomMatrix& rMatrix)
    {
        implForceUniqueCopy();
        mpPolyPolygon->transform(rMatrix);
    }
} // end of namespace basegfx

// eof
<commit_msg>INTEGRATION: CWS canvas02 (1.12.24); FILE MERGED 2005/10/08 13:19:50 thb 1.12.24.2: RESYNC: (1.12-1.13); FILE MERGED 2005/07/28 10:10:20 thb 1.12.24.1: Join from cws_src680_aw024: #i48939# and new rendering subsystem need AW's clipper changes<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: b2dpolypolygon.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: kz $ $Date: 2005-11-02 13:58:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser 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, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _BGFX_POLYGON_B2DPOLYPOLYGON_HXX
#include <basegfx/polygon/b2dpolypolygon.hxx>
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX
#include <basegfx/polygon/b2dpolygon.hxx>
#endif

#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#endif

#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif

#include <vector>

//////////////////////////////////////////////////////////////////////////////

class ImplB2DPolyPolygon
{
    typedef ::std::vector< ::basegfx::B2DPolygon >  PolygonVector;

    PolygonVector                                   maPolygons;
    sal_uInt32                                      mnRefCount;

public:
    // This constructor is only used from the static identity polygon, thus
    // the RefCount is set to 1 to never 'delete' this static incarnation.
    ImplB2DPolyPolygon()
    :   mnRefCount(1)
    {
        // complete initialization with defaults
    }

    ImplB2DPolyPolygon(const ImplB2DPolyPolygon& rToBeCopied)
    :   mnRefCount(0)
    {
        // complete initialization using copy
        maPolygons = rToBeCopied.maPolygons;
    }

    ImplB2DPolyPolygon(const ::basegfx::B2DPolygon& rToBeCopied)
    :   mnRefCount(0)
    {
        // initialization using given Polygon
        maPolygons.push_back( rToBeCopied );
    }

    ~ImplB2DPolyPolygon()
    {
    }

    const sal_uInt32 getRefCount() const { return mnRefCount; }
    void incRefCount() { mnRefCount++; }
    void decRefCount() { mnRefCount--; }

    bool isEqual(const ImplB2DPolyPolygon& rPolygonList) const
    {
        // same polygon count?
        if(maPolygons.size() != rPolygonList.maPolygons.size())
            return false;

        // if zero polygons the polys are equal
        if(!maPolygons.size())
            return true;

        // compare polygon content
        if(maPolygons != rPolygonList.maPolygons)
            return false;

        return true;
    }

    const ::basegfx::B2DPolygon& getB2DPolygon(sal_uInt32 nIndex) const
    {
        return maPolygons[nIndex];
    }

    void setB2DPolygon(sal_uInt32 nIndex, const ::basegfx::B2DPolygon& rPolygon)
    {
        maPolygons[nIndex] = rPolygon;
    }

    void insert(sal_uInt32 nIndex, const ::basegfx::B2DPolygon& rPolygon, sal_uInt32 nCount)
    {
        if(nCount)
        {
            // add nCount copies of rPolygon
            PolygonVector::iterator aIndex(maPolygons.begin());
            aIndex += nIndex;
            maPolygons.insert(aIndex, nCount, rPolygon);
        }
    }

    void insert(sal_uInt32 nIndex, const ::basegfx::B2DPolyPolygon& rPolyPolygon)
    {
        const sal_uInt32 nCount = rPolyPolygon.count();

        if(nCount)
        {
            // add nCount polygons from rPolyPolygon
            maPolygons.reserve(maPolygons.size() + nCount);
            PolygonVector::iterator aIndex(maPolygons.begin());
            aIndex += nIndex;

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                maPolygons.insert(aIndex, rPolyPolygon.getB2DPolygon(a));
                aIndex++;
            }
        }
    }

    void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
    {
        if(nCount)
        {
            // remove polygon data
            PolygonVector::iterator aStart(maPolygons.begin());
            aStart += nIndex;
            const PolygonVector::iterator aEnd(aStart + nCount);

            maPolygons.erase(aStart, aEnd);
        }
    }

    sal_uInt32 count() const
    {
        return maPolygons.size();
    }

    void setClosed(bool bNew)
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].setClosed(bNew);
        }
    }

    void flip()
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].flip();
        }
    }

    void removeDoublePoints()
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].removeDoublePoints();
        }
    }

    void transform(const ::basegfx::B2DHomMatrix& rMatrix)
    {
        for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
        {
            maPolygons[a].transform(rMatrix);
        }
    }
};

//////////////////////////////////////////////////////////////////////////////

namespace { struct DefaultPolyPolygon: public rtl::Static<ImplB2DPolyPolygon, DefaultPolyPolygon> {}; }

namespace basegfx
{
    void B2DPolyPolygon::implForceUniqueCopy()
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
            mpPolyPolygon = new ImplB2DPolyPolygon(*mpPolyPolygon);
        }
    }

    B2DPolyPolygon::B2DPolyPolygon()
    :   mpPolyPolygon(&DefaultPolyPolygon::get())
    {
        mpPolyPolygon->incRefCount();
    }

    B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon& rPolyPolygon)
    :   mpPolyPolygon(rPolyPolygon.mpPolyPolygon)
    {
        mpPolyPolygon->incRefCount();
    }

    B2DPolyPolygon::B2DPolyPolygon(const B2DPolygon& rPolygon)
    :   mpPolyPolygon( new ImplB2DPolyPolygon(rPolygon) )
    {
    }

    B2DPolyPolygon::~B2DPolyPolygon()
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
        }
        else
        {
            delete mpPolyPolygon;
        }
    }

    B2DPolyPolygon& B2DPolyPolygon::operator=(const B2DPolyPolygon& rPolyPolygon)
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
        }
        else
        {
            delete mpPolyPolygon;
        }

        mpPolyPolygon = rPolyPolygon.mpPolyPolygon;
        mpPolyPolygon->incRefCount();

        return *this;
    }

    bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
    {
        if(mpPolyPolygon == rPolyPolygon.mpPolyPolygon)
        {
            return true;
        }

        return mpPolyPolygon->isEqual(*(rPolyPolygon.mpPolyPolygon));
    }

    bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
    {
        if(mpPolyPolygon == rPolyPolygon.mpPolyPolygon)
        {
            return false;
        }

        return !mpPolyPolygon->isEqual(*(rPolyPolygon.mpPolyPolygon));
    }

    sal_uInt32 B2DPolyPolygon::count() const
    {
        return mpPolyPolygon->count();
    }

    B2DPolygon B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex) const
    {
        OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");

        return mpPolyPolygon->getB2DPolygon(nIndex);
    }

    void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& rPolygon)
    {
        OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");

        if(mpPolyPolygon->getB2DPolygon(nIndex) != rPolygon)
        {
            implForceUniqueCopy();
            mpPolyPolygon->setB2DPolygon(nIndex, rPolygon);
        }
    }

    bool B2DPolyPolygon::areControlVectorsUsed() const
    {
        for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
        {
            const ::basegfx::B2DPolygon& rPolygon = mpPolyPolygon->getB2DPolygon(a);

            if(rPolygon.areControlVectorsUsed())
            {
                return true;
            }
        }

        return false;
    }

    void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, sal_uInt32 nCount)
    {
        OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");

        if(nCount)
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(nIndex, rPolygon, nCount);
        }
    }

    void B2DPolyPolygon::append(const B2DPolygon& rPolygon, sal_uInt32 nCount)
    {
        if(nCount)
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount);
        }
    }

    void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolyPolygon& rPolyPolygon)
    {
        OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B2DPolyPolygon Insert outside range (!)");

        if(rPolyPolygon.count())
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(nIndex, rPolyPolygon);
        }
    }

    void B2DPolyPolygon::append(const B2DPolyPolygon& rPolyPolygon)
    {
        if(rPolyPolygon.count())
        {
            implForceUniqueCopy();
            mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon);
        }
    }

    void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
    {
        OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B2DPolyPolygon Remove outside range (!)");

        if(nCount)
        {
            implForceUniqueCopy();
            mpPolyPolygon->remove(nIndex, nCount);
        }
    }

    void B2DPolyPolygon::clear()
    {
        if(mpPolyPolygon->getRefCount())
        {
            mpPolyPolygon->decRefCount();
        }
        else
        {
            delete mpPolyPolygon;
        }

        mpPolyPolygon = &DefaultPolyPolygon::get();
        mpPolyPolygon->incRefCount();
    }

    bool B2DPolyPolygon::isClosed() const
    {
        bool bRetval(true);

        // PolyPOlygon is closed when all contained Polygons are closed or
        // no Polygon exists.
        for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
        {
            if(!(mpPolyPolygon->getB2DPolygon(a)).isClosed())
            {
                bRetval = false;
            }
        }

        return bRetval;
    }

    void B2DPolyPolygon::setClosed(bool bNew)
    {
        if(bNew != isClosed())
        {
            implForceUniqueCopy();
            mpPolyPolygon->setClosed(bNew);
        }
    }

    void B2DPolyPolygon::flip()
    {
        implForceUniqueCopy();
        mpPolyPolygon->flip();
    }

    bool B2DPolyPolygon::hasDoublePoints() const
    {
        bool bRetval(false);

        for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
        {
            if((mpPolyPolygon->getB2DPolygon(a)).hasDoublePoints())
            {
                bRetval = true;
            }
        }

        return bRetval;
    }

    void B2DPolyPolygon::removeDoublePoints()
    {
        if(hasDoublePoints())
        {
            implForceUniqueCopy();
            mpPolyPolygon->removeDoublePoints();
        }
    }

    void B2DPolyPolygon::transform(const ::basegfx::B2DHomMatrix& rMatrix)
    {
        implForceUniqueCopy();
        mpPolyPolygon->transform(rMatrix);
    }
} // end of namespace basegfx

// eof
<|endoftext|>


<commit_before>/*
 Copyright 2015 Nervana Systems Inc.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

#include <assert.h>

#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cstdio>
#include <iostream>
#include <chrono>
#include <utility>
#include <algorithm>

#include "reader.hpp"
#include "decoder.hpp"
#include "matrix.hpp"
#include "device.hpp"

using std::thread;
using std::mutex;
using std::condition_variable;
using std::unique_lock;
using std::lock_guard;

class ThreadPool {
public:
    explicit ThreadPool(int count)
    : _count(count), _done(false) {
        _stopped = new bool[count];
        for (int i = 0; i < count; i++) {
            _stopped[i] = false;
        }
    }

    virtual ~ThreadPool() {
        for (auto t : _threads) {
            t->join();
            delete t;
        }
        delete[] _stopped;
    }

    virtual void start() {
        for (int i = 0; i < _count; i++) {
            _threads.push_back(new thread(&ThreadPool::run, this, i));
        }
    }

    virtual void stop() {
        _done = true;
    }

    bool stopped() {
        for (int i = 0; i < _count; i++) {
            if (_stopped[i] == false) {
                return false;
            }
        }
        return true;
    }

    void join() {
        for (auto t : _threads) {
            t->join();
        }
    }

protected:
    virtual void work(int id) = 0;

    void run(int id) {
        while (_done == false) {
            work(id);
        }
        _stopped[id] = true;
    }

protected:
    int                         _count;
    vector<thread*>             _threads;
    bool                        _done;
    bool*                       _stopped;
};

class DecodeThreadPool : public ThreadPool {
public:
    DecodeThreadPool(int count, int minibatchSize,
                     int outputItemSize, int labelSize, int labelCount,
                     BufferPool& in, BufferPool& out,
                     Device* device, Decoder* decoder)
    : ThreadPool(count),
      _itemsPerThread((minibatchSize - 1) / count + 1),
      _in(in), _out(out), _endSignaled(0),
      _manager(0), _stopManager(false), _managerStopped(false), _inputBuf(0),
      _bufferIndex(0), _minibatchSize(minibatchSize),
      _outputItemSize(outputItemSize),
      _labelChunkSize(labelSize * labelCount),
      _device(device), _decoder(decoder) {
        assert(_itemsPerThread * count >= _minibatchSize);
        assert(_itemsPerThread * (count - 1) < _minibatchSize);
        for (int i = 0; i < count; i++) {
            _startSignaled.push_back(0);
            _startInds.push_back(0);
            _endInds.push_back(0);
            _dataOffsets.push_back(0);
            _labelOffsets.push_back(0);
            _labelSpans.push_back(0);
        }
    }

    virtual ~DecodeThreadPool() {
        if (_manager != 0) {
            _manager->join();
            delete _manager;
        }
        // The other thread objects are freed in the destructor
        // of the parent class.
    }

    virtual void start() {
        for (int i = 0; i < _count; i++) {
            _threads.push_back(new thread(&DecodeThreadPool::run, this, i));
        }
        _manager = new thread(&DecodeThreadPool::manage, this);
    }

    virtual void stop() {
        ThreadPool::stop();
        while (stopped() == false) {
            std::this_thread::yield();
            _in.advanceWritePos();
            _in.signalNonEmpty();
        }

        _stopManager = true;
        while (_managerStopped == false) {
            std::this_thread::yield();
            _in.advanceWritePos();
            _in.signalNonEmpty();
            _endSignaled++;
            _ended.notify_one();
        }
    }

protected:
    virtual void run(int id) {
        assert(id < _count);
        _startInds[id] = id * _itemsPerThread;
        int itemCount = _itemsPerThread;
        if (id == _count - 1) {
            itemCount = _minibatchSize - id * _itemsPerThread;
        }

        _endInds[id] = _startInds[id] + itemCount;
        _dataOffsets[id] = _startInds[id] * _outputItemSize;
        _labelOffsets[id] = _startInds[id] * _labelChunkSize;
        _labelSpans[id] = itemCount * _labelChunkSize;
        while (_done == false) {
            work(id);
        }

        _stopped[id] = true;
    }

    virtual void work(int id) {
        // Thread function.
        {
            unique_lock<mutex> lock(_mutex);
            while (_startSignaled[id] == 0) {
                _started.wait(lock);
                if (_done == true) {
                    return;
                }
            }
            _startSignaled[id]--;
            assert(_startSignaled[id] == 0);
        }

        int start = _startInds[id];
        int end = _endInds[id];
        // No locking required because threads
        // write into non-overlapping regions.
        BufferPair& outBuf = _out.getForWrite();
        char* dataBuf = outBuf.first->_data + _dataOffsets[id];
        for (int i = start; i < end; i++) {
            // Handle the data.
            int itemSize = 0;
            char* item = _inputBuf->first->getItem(i, itemSize);
            if (item == 0) {
                return;
            }
            _decoder->decode(item, itemSize, dataBuf);
            dataBuf += _outputItemSize;
        }

        // Handle the targets.
        char* labelDst = outBuf.second->_data + _labelOffsets[id];
        int labelChunkSize = 0;
        char* labelSrc = _inputBuf->second->getItem(start, labelChunkSize);
        assert(labelChunkSize == _labelChunkSize);
        memcpy(labelDst, labelSrc, _labelSpans[id]);

        {
            lock_guard<mutex> lock(_mutex);
            _endSignaled++;
            assert(_endSignaled <= _count);
        }
        _ended.notify_one();
    }

    void produce() {
        // Produce a minibatch.
        {
            unique_lock<mutex> lock(_out.getMutex());
            while (_out.full() == true) {
                _out.waitForNonFull(lock);
            }
            {
                lock_guard<mutex> lock(_mutex);
                assert(_endSignaled == 0);
                for (unsigned int i = 0; i < _startSignaled.size(); i++) {
                    _startSignaled[i] = 1;
                }
            }
            _started.notify_all();
            {
                unique_lock<mutex> lock(_mutex);
                while (_endSignaled < _count) {
                    _ended.wait(lock);
                }
                _endSignaled = 0;
            }
            // At this point, we have decoded data for the whole minibatch.
            BufferPair& outBuf = _out.getForWrite();
            Matrix<char>::transpose(outBuf.first->_data,
                                    _minibatchSize, _outputItemSize);
            // Copy to device.
            _device->copyData(_bufferIndex, outBuf.first->_data,
                              outBuf.first->_size);
            _device->copyLabels(_bufferIndex, outBuf.second->_data,
                                outBuf.second->_size);
            _bufferIndex = (_bufferIndex == 0) ? 1 : 0;
            _out.advanceWritePos();
        }
        _out.signalNonEmpty();
    }

    void consume() {
        // Consume an input buffer.
        {
            unique_lock<mutex> lock(_in.getMutex());
            while (_in.empty() == true) {
                _in.waitForNonEmpty(lock);
                if (_stopManager == true) {
                    return;
                }
            }
            _inputBuf = &_in.getForRead();
            produce();
            _in.advanceReadPos();
        }
        _in.signalNonFull();
    }

    void manage() {
        // Thread function.
        int result = _device->init();
        if (result != 0) {
            _stopManager = true;
        }
        while (_stopManager == false) {
            consume();
        }
        _managerStopped = true;
    }

private:
    int                         _itemsPerThread;
    BufferPool&                 _in;
    BufferPool&                 _out;
    mutex                       _mutex;
    condition_variable          _started;
    condition_variable          _ended;
    vector<int>                 _startSignaled;
    int                         _endSignaled;
    thread*                     _manager;
    bool                        _stopManager;
    bool                        _managerStopped;
    BufferPair*                 _inputBuf;
    int                         _bufferIndex;
    int                         _minibatchSize;
    vector<int>                 _startInds;
    vector<int>                 _endInds;
    vector<int>                 _dataOffsets;
    vector<int>                 _labelOffsets;
    vector<int>                 _labelSpans;
    int                         _outputItemSize;
    int                         _labelChunkSize;
    Device*                     _device;
    Decoder*                    _decoder;
};

class ReadThreadPool : public ThreadPool {
public:
    ReadThreadPool(BufferPool& out, Reader* reader)
    : ThreadPool(1), _out(out), _reader(reader) {
        assert(_count == 1);
    }

protected:
    virtual void work(int id) {
        produce();
    }

    void produce() {
        // Fill input buffers.
        {
            unique_lock<mutex> lock(_out.getMutex());
            while (_out.full() == true) {
                _out.waitForNonFull(lock);
            }
            BufferPair bufPair = _out.getForWrite();
            int result = _reader->read(bufPair.first, bufPair.second);
            if (result == -1) {
                _done = true;
                throw std::runtime_error("Could not read data\n");
            }
            _out.advanceWritePos();
        }
        _out.signalNonEmpty();
    }

private:
    BufferPool&                 _out;
    Reader*                     _reader;
};

class Loader {
public:
    Loader(int minibatchSize, int readMaxSize, int itemMaxSize, int labelSize,
           int labelCount, Device* device, Reader* reader, Decoder* decoder)
    : _first(true),
      _minibatchSize(minibatchSize),
      _readMaxSize(readMaxSize), _itemMaxSize(itemMaxSize),
      _labelSize(labelSize), _labelCount(labelCount),
      _readBufs(0), _decodeBufs(0),
      _readPool(0), _decodePool(0),
      _device(device), _reader(reader), _decoder(decoder) {
    }

    virtual ~Loader() {
        delete _readBufs;
        delete _readPool;
        delete _decodeBufs;
        delete _decodePool;
        delete _device;
        delete _reader;
        delete _decoder;
    }

    int start() {
        _first = true;
        try {
            _readBufs =
                new BufferPool(_minibatchSize * _readMaxSize,
                               _labelCount * _minibatchSize * _labelSize);
            _readPool =
                new ReadThreadPool(*_readBufs, _reader);
            bool pinned = (_device->_type != CPU);
            _decodeBufs =
                new BufferPool(_minibatchSize * _itemMaxSize,
                               _labelCount * _minibatchSize * _labelSize,
                               pinned);
            int numCores = thread::hardware_concurrency();
            int itemsPerThread = (_minibatchSize - 1) /  numCores + 1;
            int threadCount =  (_minibatchSize - 1) / itemsPerThread + 1;
            threadCount = std::min(threadCount, _minibatchSize);
            _decodePool =
                new DecodeThreadPool(threadCount, _minibatchSize, _itemMaxSize,
                                     _labelSize, _labelCount,
                                     *_readBufs, *_decodeBufs,
                                     _device, _decoder);
        } catch(std::bad_alloc&) {
            return -1;
        }
        _decodePool->start();
        _readPool->start();
        return 0;
    }

    void stop() {
        _readPool->stop();
        while (_readPool->stopped() == false) {
            std::this_thread::yield();
            drain();
        }
        while ((_decodeBufs->empty() == false) ||
               (_readBufs->empty() == false)) {
            drain();
        }
        _decodePool->stop();

        delete _readBufs;
        delete _readPool;
        delete _decodeBufs;
        delete _decodePool;
        _readBufs = 0;
        _readPool = 0;
        _decodeBufs = 0;
        _decodePool = 0;
    }

    int reset() {
        stop();
        _reader->reset();
        start();
        return 0;
    }

    void next(Buffer<char>* dataBuf, Buffer<char>* labelBuf) {
        // Copy minibatch data into the buffers passed in.
        // Only used for testing purposes.
        {
            unique_lock<mutex> lock(_decodeBufs->getMutex());
            while (_decodeBufs->empty()) {
                _decodeBufs->waitForNonEmpty(lock);
            }
            Buffer<char>* data = _decodeBufs->getForRead().first;
            memcpy(dataBuf->_data, data->_data, dataBuf->_size);
            Buffer<char>* labels = _decodeBufs->getForRead().second;
            memcpy(labelBuf->_data, labels->_data, labelBuf->_size);
            _decodeBufs->advanceReadPos();
        }
        _decodeBufs->signalNonFull();
    }

    void next() {
        unique_lock<mutex> lock(_decodeBufs->getMutex());
        if (_first == true) {
            _first = false;
        } else {
            // Unlock the buffer used for the previous minibatch.
            _decodeBufs->advanceReadPos();
            _decodeBufs->signalNonFull();
        }
        while (_decodeBufs->empty()) {
            _decodeBufs->waitForNonEmpty(lock);
        }
    }

private:
    void drain() {
        {
            unique_lock<mutex> lock(_decodeBufs->getMutex());
            if (_decodeBufs->empty() == true) {
                return;
            }
            _decodeBufs->advanceReadPos();
        }
        _decodeBufs->signalNonFull();
    }

private:
    bool                        _first;
    int                         _minibatchSize;
    int                         _readMaxSize;
    int                         _itemMaxSize;
    int                         _labelSize;
    int                         _labelCount;
    BufferPool*                 _readBufs;
    BufferPool*                 _decodeBufs;
    ReadThreadPool*             _readPool;
    DecodeThreadPool*           _decodePool;
    Device*                     _device;
    Reader*                     _reader;
    Decoder*                    _decoder;
};
<commit_msg>Delete assertion that is no longer valid<commit_after>/*
 Copyright 2015 Nervana Systems Inc.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

#include <assert.h>

#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cstdio>
#include <iostream>
#include <chrono>
#include <utility>
#include <algorithm>

#include "reader.hpp"
#include "decoder.hpp"
#include "matrix.hpp"
#include "device.hpp"

using std::thread;
using std::mutex;
using std::condition_variable;
using std::unique_lock;
using std::lock_guard;

class ThreadPool {
public:
    explicit ThreadPool(int count)
    : _count(count), _done(false) {
        _stopped = new bool[count];
        for (int i = 0; i < count; i++) {
            _stopped[i] = false;
        }
    }

    virtual ~ThreadPool() {
        for (auto t : _threads) {
            t->join();
            delete t;
        }
        delete[] _stopped;
    }

    virtual void start() {
        for (int i = 0; i < _count; i++) {
            _threads.push_back(new thread(&ThreadPool::run, this, i));
        }
    }

    virtual void stop() {
        _done = true;
    }

    bool stopped() {
        for (int i = 0; i < _count; i++) {
            if (_stopped[i] == false) {
                return false;
            }
        }
        return true;
    }

    void join() {
        for (auto t : _threads) {
            t->join();
        }
    }

protected:
    virtual void work(int id) = 0;

    void run(int id) {
        while (_done == false) {
            work(id);
        }
        _stopped[id] = true;
    }

protected:
    int                         _count;
    vector<thread*>             _threads;
    bool                        _done;
    bool*                       _stopped;
};

class DecodeThreadPool : public ThreadPool {
public:
    DecodeThreadPool(int count, int minibatchSize,
                     int outputItemSize, int labelSize, int labelCount,
                     BufferPool& in, BufferPool& out,
                     Device* device, Decoder* decoder)
    : ThreadPool(count),
      _itemsPerThread((minibatchSize - 1) / count + 1),
      _in(in), _out(out), _endSignaled(0),
      _manager(0), _stopManager(false), _managerStopped(false), _inputBuf(0),
      _bufferIndex(0), _minibatchSize(minibatchSize),
      _outputItemSize(outputItemSize),
      _labelChunkSize(labelSize * labelCount),
      _device(device), _decoder(decoder) {
        assert(_itemsPerThread * count >= _minibatchSize);
        assert(_itemsPerThread * (count - 1) < _minibatchSize);
        for (int i = 0; i < count; i++) {
            _startSignaled.push_back(0);
            _startInds.push_back(0);
            _endInds.push_back(0);
            _dataOffsets.push_back(0);
            _labelOffsets.push_back(0);
            _labelSpans.push_back(0);
        }
    }

    virtual ~DecodeThreadPool() {
        if (_manager != 0) {
            _manager->join();
            delete _manager;
        }
        // The other thread objects are freed in the destructor
        // of the parent class.
    }

    virtual void start() {
        for (int i = 0; i < _count; i++) {
            _threads.push_back(new thread(&DecodeThreadPool::run, this, i));
        }
        _manager = new thread(&DecodeThreadPool::manage, this);
    }

    virtual void stop() {
        ThreadPool::stop();
        while (stopped() == false) {
            std::this_thread::yield();
            _in.advanceWritePos();
            _in.signalNonEmpty();
        }

        _stopManager = true;
        while (_managerStopped == false) {
            std::this_thread::yield();
            _in.advanceWritePos();
            _in.signalNonEmpty();
            _endSignaled++;
            _ended.notify_one();
        }
    }

protected:
    virtual void run(int id) {
        assert(id < _count);
        _startInds[id] = id * _itemsPerThread;
        int itemCount = _itemsPerThread;
        if (id == _count - 1) {
            itemCount = _minibatchSize - id * _itemsPerThread;
        }

        _endInds[id] = _startInds[id] + itemCount;
        _dataOffsets[id] = _startInds[id] * _outputItemSize;
        _labelOffsets[id] = _startInds[id] * _labelChunkSize;
        _labelSpans[id] = itemCount * _labelChunkSize;
        while (_done == false) {
            work(id);
        }

        _stopped[id] = true;
    }

    virtual void work(int id) {
        // Thread function.
        {
            unique_lock<mutex> lock(_mutex);
            while (_startSignaled[id] == 0) {
                _started.wait(lock);
                if (_done == true) {
                    return;
                }
            }
            _startSignaled[id]--;
            assert(_startSignaled[id] == 0);
        }

        int start = _startInds[id];
        int end = _endInds[id];
        // No locking required because threads
        // write into non-overlapping regions.
        BufferPair& outBuf = _out.getForWrite();
        char* dataBuf = outBuf.first->_data + _dataOffsets[id];
        for (int i = start; i < end; i++) {
            // Handle the data.
            int itemSize = 0;
            char* item = _inputBuf->first->getItem(i, itemSize);
            if (item == 0) {
                return;
            }
            _decoder->decode(item, itemSize, dataBuf);
            dataBuf += _outputItemSize;
        }

        // Handle the targets.
        char* labelDst = outBuf.second->_data + _labelOffsets[id];
        int labelChunkSize = 0;
        char* labelSrc = _inputBuf->second->getItem(start, labelChunkSize);
        assert(labelChunkSize == _labelChunkSize);
        memcpy(labelDst, labelSrc, _labelSpans[id]);

        {
            lock_guard<mutex> lock(_mutex);
            _endSignaled++;
            assert(_endSignaled <= _count);
        }
        _ended.notify_one();
    }

    void produce() {
        // Produce a minibatch.
        {
            unique_lock<mutex> lock(_out.getMutex());
            while (_out.full() == true) {
                _out.waitForNonFull(lock);
            }
            {
                lock_guard<mutex> lock(_mutex);
                for (unsigned int i = 0; i < _startSignaled.size(); i++) {
                    _startSignaled[i] = 1;
                }
            }
            _started.notify_all();
            {
                unique_lock<mutex> lock(_mutex);
                while (_endSignaled < _count) {
                    _ended.wait(lock);
                }
                _endSignaled = 0;
            }
            // At this point, we have decoded data for the whole minibatch.
            BufferPair& outBuf = _out.getForWrite();
            Matrix<char>::transpose(outBuf.first->_data,
                                    _minibatchSize, _outputItemSize);
            // Copy to device.
            _device->copyData(_bufferIndex, outBuf.first->_data,
                              outBuf.first->_size);
            _device->copyLabels(_bufferIndex, outBuf.second->_data,
                                outBuf.second->_size);
            _bufferIndex = (_bufferIndex == 0) ? 1 : 0;
            _out.advanceWritePos();
        }
        _out.signalNonEmpty();
    }

    void consume() {
        // Consume an input buffer.
        {
            unique_lock<mutex> lock(_in.getMutex());
            while (_in.empty() == true) {
                _in.waitForNonEmpty(lock);
                if (_stopManager == true) {
                    return;
                }
            }
            _inputBuf = &_in.getForRead();
            produce();
            _in.advanceReadPos();
        }
        _in.signalNonFull();
    }

    void manage() {
        // Thread function.
        int result = _device->init();
        if (result != 0) {
            _stopManager = true;
        }
        while (_stopManager == false) {
            consume();
        }
        _managerStopped = true;
    }

private:
    int                         _itemsPerThread;
    BufferPool&                 _in;
    BufferPool&                 _out;
    mutex                       _mutex;
    condition_variable          _started;
    condition_variable          _ended;
    vector<int>                 _startSignaled;
    int                         _endSignaled;
    thread*                     _manager;
    bool                        _stopManager;
    bool                        _managerStopped;
    BufferPair*                 _inputBuf;
    int                         _bufferIndex;
    int                         _minibatchSize;
    vector<int>                 _startInds;
    vector<int>                 _endInds;
    vector<int>                 _dataOffsets;
    vector<int>                 _labelOffsets;
    vector<int>                 _labelSpans;
    int                         _outputItemSize;
    int                         _labelChunkSize;
    Device*                     _device;
    Decoder*                    _decoder;
};

class ReadThreadPool : public ThreadPool {
public:
    ReadThreadPool(BufferPool& out, Reader* reader)
    : ThreadPool(1), _out(out), _reader(reader) {
        assert(_count == 1);
    }

protected:
    virtual void work(int id) {
        produce();
    }

    void produce() {
        // Fill input buffers.
        {
            unique_lock<mutex> lock(_out.getMutex());
            while (_out.full() == true) {
                _out.waitForNonFull(lock);
            }
            BufferPair bufPair = _out.getForWrite();
            int result = _reader->read(bufPair.first, bufPair.second);
            if (result == -1) {
                _done = true;
                throw std::runtime_error("Could not read data\n");
            }
            _out.advanceWritePos();
        }
        _out.signalNonEmpty();
    }

private:
    BufferPool&                 _out;
    Reader*                     _reader;
};

class Loader {
public:
    Loader(int minibatchSize, int readMaxSize, int itemMaxSize, int labelSize,
           int labelCount, Device* device, Reader* reader, Decoder* decoder)
    : _first(true),
      _minibatchSize(minibatchSize),
      _readMaxSize(readMaxSize), _itemMaxSize(itemMaxSize),
      _labelSize(labelSize), _labelCount(labelCount),
      _readBufs(0), _decodeBufs(0),
      _readPool(0), _decodePool(0),
      _device(device), _reader(reader), _decoder(decoder) {
    }

    virtual ~Loader() {
        delete _readBufs;
        delete _readPool;
        delete _decodeBufs;
        delete _decodePool;
        delete _device;
        delete _reader;
        delete _decoder;
    }

    int start() {
        _first = true;
        try {
            _readBufs =
                new BufferPool(_minibatchSize * _readMaxSize,
                               _labelCount * _minibatchSize * _labelSize);
            _readPool =
                new ReadThreadPool(*_readBufs, _reader);
            bool pinned = (_device->_type != CPU);
            _decodeBufs =
                new BufferPool(_minibatchSize * _itemMaxSize,
                               _labelCount * _minibatchSize * _labelSize,
                               pinned);
            int numCores = thread::hardware_concurrency();
            int itemsPerThread = (_minibatchSize - 1) /  numCores + 1;
            int threadCount =  (_minibatchSize - 1) / itemsPerThread + 1;
            threadCount = std::min(threadCount, _minibatchSize);
            _decodePool =
                new DecodeThreadPool(threadCount, _minibatchSize, _itemMaxSize,
                                     _labelSize, _labelCount,
                                     *_readBufs, *_decodeBufs,
                                     _device, _decoder);
        } catch(std::bad_alloc&) {
            return -1;
        }
        _decodePool->start();
        _readPool->start();
        return 0;
    }

    void stop() {
        _readPool->stop();
        while (_readPool->stopped() == false) {
            std::this_thread::yield();
            drain();
        }
        while ((_decodeBufs->empty() == false) ||
               (_readBufs->empty() == false)) {
            drain();
        }
        _decodePool->stop();

        delete _readBufs;
        delete _readPool;
        delete _decodeBufs;
        delete _decodePool;
        _readBufs = 0;
        _readPool = 0;
        _decodeBufs = 0;
        _decodePool = 0;
    }

    int reset() {
        stop();
        _reader->reset();
        start();
        return 0;
    }

    void next(Buffer<char>* dataBuf, Buffer<char>* labelBuf) {
        // Copy minibatch data into the buffers passed in.
        // Only used for testing purposes.
        {
            unique_lock<mutex> lock(_decodeBufs->getMutex());
            while (_decodeBufs->empty()) {
                _decodeBufs->waitForNonEmpty(lock);
            }
            Buffer<char>* data = _decodeBufs->getForRead().first;
            memcpy(dataBuf->_data, data->_data, dataBuf->_size);
            Buffer<char>* labels = _decodeBufs->getForRead().second;
            memcpy(labelBuf->_data, labels->_data, labelBuf->_size);
            _decodeBufs->advanceReadPos();
        }
        _decodeBufs->signalNonFull();
    }

    void next() {
        unique_lock<mutex> lock(_decodeBufs->getMutex());
        if (_first == true) {
            _first = false;
        } else {
            // Unlock the buffer used for the previous minibatch.
            _decodeBufs->advanceReadPos();
            _decodeBufs->signalNonFull();
        }
        while (_decodeBufs->empty()) {
            _decodeBufs->waitForNonEmpty(lock);
        }
    }

private:
    void drain() {
        {
            unique_lock<mutex> lock(_decodeBufs->getMutex());
            if (_decodeBufs->empty() == true) {
                return;
            }
            _decodeBufs->advanceReadPos();
        }
        _decodeBufs->signalNonFull();
    }

private:
    bool                        _first;
    int                         _minibatchSize;
    int                         _readMaxSize;
    int                         _itemMaxSize;
    int                         _labelSize;
    int                         _labelCount;
    BufferPool*                 _readBufs;
    BufferPool*                 _decodeBufs;
    ReadThreadPool*             _readPool;
    DecodeThreadPool*           _decodePool;
    Device*                     _device;
    Reader*                     _reader;
    Decoder*                    _decoder;
};
<|endoftext|>


<commit_before>#pragma once

#include "../std/stdint.hpp"
#include "../std/string.hpp"
#include "../std/stdint.hpp"

namespace my
{

/// Cross platform timer
class Timer
{
  double m_startTime;

  static double LocalTime();

public:
  Timer();

  double ElapsedSeconds() const;
  void Reset();
};

string FormatCurrentTime();
uint32_t TodayAsYYMMDD();

}
<commit_msg>changed visibility of Timer::LocalTime method.<commit_after>#pragma once

#include "../std/stdint.hpp"
#include "../std/string.hpp"
#include "../std/stdint.hpp"

namespace my
{

/// Cross platform timer
class Timer
{
  double m_startTime;

public:
  Timer();

  static double LocalTime();
  double ElapsedSeconds() const;
  void Reset();
};

string FormatCurrentTime();
uint32_t TodayAsYYMMDD();

}
<|endoftext|>


<commit_before><commit_msg>Coverity: Remove the check for index < 0 because index is a size_t and can never be < 0.<commit_after><|endoftext|>


<commit_before>// gnu.cc
// tcheck and print routines for gnu.ast/gnu.gr extensions

#include "generic_aux.h"      // C++ AST, and genericPrintAmbiguities, etc.
#include "cc_env.h"           // Env
#include "cc_print.h"         // olayer, PrintEnv
#include "generic_amb.h"      // resolveAmbiguity, etc.
#include "cc_tcheck.h"        // computeArraySizeFromCompoundInit

// -------------------- tcheck --------------------
ASTTypeof *ASTTypeof::tcheck(Env &env, DeclFlags dflags)
{
  if (!ambiguity) {
    mid_tcheck(env, dflags);
    return this;
  }

  return resolveAmbiguity(this, env, "ASTTypeof", false /*priority*/, dflags);
}

void ASTTypeof::mid_tcheck(Env &env, DeclFlags &dflags)
{
  type = itcheck(env, dflags);
}

Type *TS_typeof_expr::itcheck(Env &env, DeclFlags dflags)
{
  // FIX: dflags discarded?
  expr->tcheck(env);
  // FIX: check the asRval(); A use in kernel suggests it should be
  // there as otherwise you get "error: cannot create a pointer to a
  // reference" when used to specify the type in a declarator that
  // comes from a de-reference (which yeilds a reference).
  return expr->getType()->asRval();
}

Type *TS_typeof_type::itcheck(Env &env, DeclFlags dflags)
{
  ASTTypeId::Tcheck tc(DF_NONE /*dflags don't apply to this type*/,
                       DC_TS_TYPEOF_TYPE);
  atype = atype->tcheck(env, tc);
  Type *t = atype->getType();
  return t;
}

Type *TS_typeof::itcheck(Env &env, DeclFlags dflags)
{
  atype = atype->tcheck(env, dflags);
  return atype->type;
}

Type *E_compoundLit::itcheck_x(Env &env, Expression *&replacement)
{
  ASTTypeId::Tcheck tc(DF_NONE, DC_E_COMPOUNDLIT);
  stype = stype->tcheck(env, tc);
  init->tcheck(env, NULL);

  return computeArraySizeFromCompoundInit(env, env.loc(), stype->getType(), stype->getType(), init);
  // TODO: check that the cast (literal) makes sense
}

Type *E___builtin_constant_p::itcheck_x(Env &env, Expression *&replacement)
{
  expr->tcheck(env, expr);

//    // TODO: this will fail an assertion if someone asks for the
//    // size of a variable of template-type-parameter type..
//    // dsw: If this is turned back on, be sure to catch the possible
//    // XReprSize exception and add its message to the env.error-s
//    size = expr->type->asRval()->reprSize();
//    TRACE("sizeof", "sizeof(" << expr->exprToString() <<
//                    ") is " << size);

  // dsw: the type of a __builtin_constant_p is an int:
  // http://gcc.gnu.org/onlinedocs/gcc-3.2.2/gcc/Other-Builtins.html#Other%20Builtins
  // TODO: is this right?
  return expr->type->isError()?
           expr->type : env.getSimpleType(SL_UNKNOWN, ST_UNSIGNED_INT);
}

Type *E_alignofType::itcheck_x(Env &env, Expression *&replacement)
{
  ASTTypeId::Tcheck tc(DF_NONE, DC_E_ALIGNOFTYPE);
  atype = atype->tcheck(env, tc);
  Type *t = atype->getType();
  // dsw: If this is turned back on, be sure to catch the possible
  // XReprSize exception and add its message to the env.error-s
//    size = t->reprSize();

  return t->isError()? t : env.getSimpleType(SL_UNKNOWN, ST_UNSIGNED_INT);
}

Type *E_statement::itcheck_x(Env &env, Expression *&replacement)
{
  s = s->tcheck(env)->asS_compound();
  if (s->stmts.count() < 1) {
    return env.error("`({ ... })' cannot be empty");
  }

  Statement *last = s->stmts.last();
  if (last->isS_expr()) {
    return last->asS_expr()->expr->getType();
  }
  else {
    return env.error("last thing in `({ ... })' must be an expression");
  }
}

static void compile_time_compute_int_expr(Env &env, Expression *e, int &x, char *error_msg) {
  e->tcheck(env, e);
  if (!e->constEval(env, x)) env.error(error_msg);
}

static void check_designator_list(Env &env, FakeList<Designator> *dl)
{
  xassert(dl);
  FAKELIST_FOREACH_NC(Designator, dl, d) {
    if (SubscriptDesignator *sd = dynamic_cast<SubscriptDesignator*>(d)) {
      compile_time_compute_int_expr(env, sd->idx_expr, sd->idx_computed,
                                    "compile-time computation of range start designator array index fails");
      if (sd->idx_expr2) {
        compile_time_compute_int_expr(env, sd->idx_expr2, sd->idx_computed2,
                                      "compile-time computation of range end designator array index fails");
      }
    }
    // nothing to do for FieldDesignator-s
  }
}

void IN_designated::tcheck(Env &env, Type *type)
{
  init->tcheck(env, type);
  check_designator_list(env, designator_list);
}

// ------------------------ print --------------------------
void TS_typeof::print(PrintEnv &env)
{
  xassert(0);                   // I'll bet this is never called.
//    olayer ol("TS_typeof_expr");
}

void ASTTypeof::printAmbiguities(ostream &os, int indent) const
{
  genericPrintAmbiguities(this, "TypeSpecifier", os, indent);

  // sm: what was this here for?
  //genericCheckNexts(this);
}

void ASTTypeof::addAmbiguity(ASTTypeof *alt)
{
  //genericAddAmbiguity(this, alt);

  // insert 'alt' at the head of the 'ambiguity' list
  xassert(alt->ambiguity == NULL);
  alt->ambiguity = ambiguity;
  ambiguity = alt;
}

void E_compoundLit::iprint(PrintEnv &env)
{
  olayer ol("E_compoundLit::iprint");
  {
    codeout co(env, "", "(", ")");
    stype->print(env);
  }
  init->print(env);
}

void E___builtin_constant_p::iprint(PrintEnv &env)
{
  olayer ol("E___builtin_constant_p::iprint");
  codeout co(env, "__builtin_constant_p", "(", ")");
  expr->print(env);
}

void E_alignofType::iprint(PrintEnv &env)
{
  olayer ol("E_alignofType::iprint");
  codeout co(env, "__alignof__", "(", ")");
  atype->print(env);
}

void E_statement::iprint(PrintEnv &env)
{
  olayer ol("E_statement::iprint");
  codeout co(env, "", "(", ")");
  s->iprint(env);
}

// prints designators in the new C99 style, not the obsolescent ":"
// style
static void print_DesignatorList(PrintEnv &env, FakeList<Designator> *dl) {
  xassert(dl);
  FAKELIST_FOREACH_NC(Designator, dl, d) d->print(env);
  env << "=";
}

void IN_designated::print(PrintEnv &env)
{
  print_DesignatorList(env, designator_list);
  init->print(env);
}

// -------------------- Designator ---------------

void FieldDesignator::print(PrintEnv &env)
{
  olayer ol("FieldDesignator");
  xassert(id);
  env << "." << id;
}

void SubscriptDesignator::print(PrintEnv &env)
{
  olayer ol("SubscriptDesignator");
  xassert(idx_expr);
  codeout co(env, "", "[", "]");
  idx_expr->print(env);
  if (idx_expr2) {
    env << " ... ";
    idx_expr2->print(env);
  }
}

void Designator::printAmbiguities(ostream &os, int indent) const
{
  genericPrintAmbiguities(this, "Designator", os, indent);

  genericCheckNexts(this);
}

void Designator::addAmbiguity(Designator *alt)
{
  genericAddAmbiguity(this, alt);
}

void Designator::setNext(Designator *newNext)
{
  genericSetNext(this, newNext);
}

<commit_msg>Turned off assertion that the last thing in a '({ ... })' must be a S_expr; if not I return ST_VOID<commit_after>// gnu.cc
// tcheck and print routines for gnu.ast/gnu.gr extensions

#include "generic_aux.h"      // C++ AST, and genericPrintAmbiguities, etc.
#include "cc_env.h"           // Env
#include "cc_print.h"         // olayer, PrintEnv
#include "generic_amb.h"      // resolveAmbiguity, etc.
#include "cc_tcheck.h"        // computeArraySizeFromCompoundInit

// -------------------- tcheck --------------------
ASTTypeof *ASTTypeof::tcheck(Env &env, DeclFlags dflags)
{
  if (!ambiguity) {
    mid_tcheck(env, dflags);
    return this;
  }

  return resolveAmbiguity(this, env, "ASTTypeof", false /*priority*/, dflags);
}

void ASTTypeof::mid_tcheck(Env &env, DeclFlags &dflags)
{
  type = itcheck(env, dflags);
}

Type *TS_typeof_expr::itcheck(Env &env, DeclFlags dflags)
{
  // FIX: dflags discarded?
  expr->tcheck(env);
  // FIX: check the asRval(); A use in kernel suggests it should be
  // there as otherwise you get "error: cannot create a pointer to a
  // reference" when used to specify the type in a declarator that
  // comes from a de-reference (which yeilds a reference).
  return expr->getType()->asRval();
}

Type *TS_typeof_type::itcheck(Env &env, DeclFlags dflags)
{
  ASTTypeId::Tcheck tc(DF_NONE /*dflags don't apply to this type*/,
                       DC_TS_TYPEOF_TYPE);
  atype = atype->tcheck(env, tc);
  Type *t = atype->getType();
  return t;
}

Type *TS_typeof::itcheck(Env &env, DeclFlags dflags)
{
  atype = atype->tcheck(env, dflags);
  return atype->type;
}

Type *E_compoundLit::itcheck_x(Env &env, Expression *&replacement)
{
  ASTTypeId::Tcheck tc(DF_NONE, DC_E_COMPOUNDLIT);
  stype = stype->tcheck(env, tc);
  init->tcheck(env, NULL);

  return computeArraySizeFromCompoundInit(env, env.loc(), stype->getType(), stype->getType(), init);
  // TODO: check that the cast (literal) makes sense
}

Type *E___builtin_constant_p::itcheck_x(Env &env, Expression *&replacement)
{
  expr->tcheck(env, expr);

//    // TODO: this will fail an assertion if someone asks for the
//    // size of a variable of template-type-parameter type..
//    // dsw: If this is turned back on, be sure to catch the possible
//    // XReprSize exception and add its message to the env.error-s
//    size = expr->type->asRval()->reprSize();
//    TRACE("sizeof", "sizeof(" << expr->exprToString() <<
//                    ") is " << size);

  // dsw: the type of a __builtin_constant_p is an int:
  // http://gcc.gnu.org/onlinedocs/gcc-3.2.2/gcc/Other-Builtins.html#Other%20Builtins
  // TODO: is this right?
  return expr->type->isError()?
           expr->type : env.getSimpleType(SL_UNKNOWN, ST_UNSIGNED_INT);
}

Type *E_alignofType::itcheck_x(Env &env, Expression *&replacement)
{
  ASTTypeId::Tcheck tc(DF_NONE, DC_E_ALIGNOFTYPE);
  atype = atype->tcheck(env, tc);
  Type *t = atype->getType();
  // dsw: If this is turned back on, be sure to catch the possible
  // XReprSize exception and add its message to the env.error-s
//    size = t->reprSize();

  return t->isError()? t : env.getSimpleType(SL_UNKNOWN, ST_UNSIGNED_INT);
}

Type *E_statement::itcheck_x(Env &env, Expression *&replacement)
{
  s = s->tcheck(env)->asS_compound();
  if (s->stmts.count() < 1) {
    return env.error("`({ ... })' cannot be empty");
  }

  Statement *last = s->stmts.last();
  if (last->isS_expr()) {
    return last->asS_expr()->expr->getType();
  }
  else {
    return env.getSimpleType(env.loc(), ST_VOID, CV_NONE);
    // There are examples that do not end with an S_expr.
//      return env.error("last thing in `({ ... })' must be an expression");
  }
}

static void compile_time_compute_int_expr(Env &env, Expression *e, int &x, char *error_msg) {
  e->tcheck(env, e);
  if (!e->constEval(env, x)) env.error(error_msg);
}

static void check_designator_list(Env &env, FakeList<Designator> *dl)
{
  xassert(dl);
  FAKELIST_FOREACH_NC(Designator, dl, d) {
    if (SubscriptDesignator *sd = dynamic_cast<SubscriptDesignator*>(d)) {
      compile_time_compute_int_expr(env, sd->idx_expr, sd->idx_computed,
                                    "compile-time computation of range start designator array index fails");
      if (sd->idx_expr2) {
        compile_time_compute_int_expr(env, sd->idx_expr2, sd->idx_computed2,
                                      "compile-time computation of range end designator array index fails");
      }
    }
    // nothing to do for FieldDesignator-s
  }
}

void IN_designated::tcheck(Env &env, Type *type)
{
  init->tcheck(env, type);
  check_designator_list(env, designator_list);
}

// ------------------------ print --------------------------
void TS_typeof::print(PrintEnv &env)
{
  xassert(0);                   // I'll bet this is never called.
//    olayer ol("TS_typeof_expr");
}

void ASTTypeof::printAmbiguities(ostream &os, int indent) const
{
  genericPrintAmbiguities(this, "TypeSpecifier", os, indent);

  // sm: what was this here for?
  //genericCheckNexts(this);
}

void ASTTypeof::addAmbiguity(ASTTypeof *alt)
{
  //genericAddAmbiguity(this, alt);

  // insert 'alt' at the head of the 'ambiguity' list
  xassert(alt->ambiguity == NULL);
  alt->ambiguity = ambiguity;
  ambiguity = alt;
}

void E_compoundLit::iprint(PrintEnv &env)
{
  olayer ol("E_compoundLit::iprint");
  {
    codeout co(env, "", "(", ")");
    stype->print(env);
  }
  init->print(env);
}

void E___builtin_constant_p::iprint(PrintEnv &env)
{
  olayer ol("E___builtin_constant_p::iprint");
  codeout co(env, "__builtin_constant_p", "(", ")");
  expr->print(env);
}

void E_alignofType::iprint(PrintEnv &env)
{
  olayer ol("E_alignofType::iprint");
  codeout co(env, "__alignof__", "(", ")");
  atype->print(env);
}

void E_statement::iprint(PrintEnv &env)
{
  olayer ol("E_statement::iprint");
  codeout co(env, "", "(", ")");
  s->iprint(env);
}

// prints designators in the new C99 style, not the obsolescent ":"
// style
static void print_DesignatorList(PrintEnv &env, FakeList<Designator> *dl) {
  xassert(dl);
  FAKELIST_FOREACH_NC(Designator, dl, d) d->print(env);
  env << "=";
}

void IN_designated::print(PrintEnv &env)
{
  print_DesignatorList(env, designator_list);
  init->print(env);
}

// -------------------- Designator ---------------

void FieldDesignator::print(PrintEnv &env)
{
  olayer ol("FieldDesignator");
  xassert(id);
  env << "." << id;
}

void SubscriptDesignator::print(PrintEnv &env)
{
  olayer ol("SubscriptDesignator");
  xassert(idx_expr);
  codeout co(env, "", "[", "]");
  idx_expr->print(env);
  if (idx_expr2) {
    env << " ... ";
    idx_expr2->print(env);
  }
}

void Designator::printAmbiguities(ostream &os, int indent) const
{
  genericPrintAmbiguities(this, "Designator", os, indent);

  genericCheckNexts(this);
}

void Designator::addAmbiguity(Designator *alt)
{
  genericAddAmbiguity(this, alt);
}

void Designator::setNext(Designator *newNext)
{
  genericSetNext(this, newNext);
}

<|endoftext|>