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

#include "cvmfs_config.h"
#include "catalog_mgr_client.h"

#include "cache.h"
#include "fetch.h"
#include "download.h"
#include "manifest.h"
#include "quota.h"
#include "signature.h"
#include "statistics.h"

using namespace std;  // NOLINT

namespace catalog {

/**
 * Triggered when the catalog is attached (db file opened)
 */
void ClientCatalogManager::ActivateCatalog(Catalog *catalog) {
  const Counters &counters = const_cast<const Catalog*>(catalog)->GetCounters();
  if (catalog->IsRoot()) {
    all_inodes_ = counters.GetAllEntries();
  }
  loaded_inodes_ += counters.GetSelfEntries();
}

ClientCatalogManager::ClientCatalogManager(
  const string &repo_name,
  cvmfs::Fetcher *fetcher,
  signature::SignatureManager *signature_mgr,
  perf::Statistics *statistics)
  : AbstractCatalogManager(statistics)
  , repo_name_(repo_name)
  , fetcher_(fetcher)
  , signature_mgr_(signature_mgr)
  , offline_mode_(false)
  , all_inodes_(0)
  , loaded_inodes_(0)
{
  LogCvmfs(kLogCatalog, kLogDebug, "constructing client catalog manager");
  n_certificate_hits_ = statistics->Register("cache.n_certificate_hits",
    "Number of certificate hits");
  n_certificate_misses_ = statistics->Register("cache.n_certificate_misses",
    "Number of certificate misses");
}

ClientCatalogManager::~ClientCatalogManager() {
  LogCvmfs(kLogCache, kLogDebug, "unpinning / unloading all catalogs");

  for (map<PathString, shash::Any>::iterator i = mounted_catalogs_.begin(),
       iend = mounted_catalogs_.end(); i != iend; ++i)
  {
    fetcher_->cache_mgr()->quota_mgr()->Unpin(i->second);
  }
}

Catalog *ClientCatalogManager::CreateCatalog(
  const PathString  &mountpoint,
  const shash::Any  &catalog_hash,
  catalog::Catalog  *parent_catalog
) {
  mounted_catalogs_[mountpoint] = loaded_catalogs_[mountpoint];
  loaded_catalogs_.erase(mountpoint);
  return new Catalog(mountpoint, catalog_hash, parent_catalog);
}

/**
 * Specialized initialization that uses a fixed root hash.
 */
bool ClientCatalogManager::InitFixed(const shash::Any &root_hash) {
  LogCvmfs(kLogCatalog, kLogDebug, "Initialize catalog with root hash %s",
           root_hash.ToString().c_str());
  WriteLock();
  bool attached = MountCatalog(PathString("", 0), root_hash, NULL);
  Unlock();

  if (!attached) {
    LogCvmfs(kLogCatalog, kLogDebug, "failed to initialize root catalog");
  }

  return attached;
}

LoadError ClientCatalogManager::LoadCatalog(
  const PathString  &mountpoint,
  const shash::Any  &hash,
  std::string *catalog_path,
  shash::Any *catalog_hash)
{
  string cvmfs_path = "file catalog at " + repo_name_ + ":" +
    (mountpoint.IsEmpty() ?
      "/" : string(mountpoint.GetChars(), mountpoint.GetLength()));
  bool retval;

  // send the catalog hash to a blind memory position if it zero (save some ifs)
  shash::Any blind_hash;
  if (catalog_hash == NULL) {
    catalog_hash = &blind_hash;
  }

  // Load a particular catalog
  if (!hash.IsNull()) {
    cvmfs_path += " (" + hash.ToString() + ")";
    LoadError load_error = LoadCatalogCas(hash, cvmfs_path, catalog_path);
    if (load_error == catalog::kLoadNew)
      loaded_catalogs_[mountpoint] = hash;
    *catalog_hash = hash;
    return load_error;
  }

  // Happens only on init/remount, i.e. quota won't delete a cached catalog
  string checksum_dir = ".";
  // TODO(jblomer): move this hack to another place
/*  if (alien_cache_ && !FileExists("cvmfschecksum." + repo_name_)) {
    // In case the alien cache has been preloaded, the .cvmfschecksum file
    // must be read from the alien cache instead of the client cache
    checksum_dir = *cache_path_;
  }*/
  shash::Any cache_hash;
  uint64_t cache_last_modified = 0;

  retval = manifest::Manifest::ReadChecksum(
    repo_name_, checksum_dir, &cache_hash, &cache_last_modified);
  if (retval) {
    LogCvmfs(kLogCache, kLogDebug, "cached copy publish date %s",
             StringifyTime(cache_last_modified, true).c_str());
  } else {
    LogCvmfs(kLogCache, kLogDebug, "unable to read local checksum");
  }

  // Load and verify remote checksum
  manifest::Failures manifest_failure;
  CachedManifestEnsemble ensemble(fetcher_->cache_mgr(), this);
  manifest_failure = manifest::Fetch("", repo_name_, cache_last_modified,
                                     &cache_hash, signature_mgr_,
                                     fetcher_->download_mgr(),
                                     &ensemble);
  if (manifest_failure != manifest::kFailOk) {
    LogCvmfs(kLogCache, kLogDebug, "failed to fetch manifest (%d - %s)",
             manifest_failure, manifest::Code2Ascii(manifest_failure));

    if (catalog_path) {
      LoadError error = LoadCatalogCas(cache_hash, cvmfs_path, catalog_path);
      if (error != catalog::kLoadNew)
        return error;
    }
    loaded_catalogs_[mountpoint] = cache_hash;
    *catalog_hash = cache_hash;
    offline_mode_ = true;
    return catalog::kLoadUp2Date;
  }

  offline_mode_ = false;
  cvmfs_path += " (" + ensemble.manifest->catalog_hash().ToString() + ")";
  LogCvmfs(kLogCache, kLogDebug, "remote checksum is %s",
           ensemble.manifest->catalog_hash().ToString().c_str());

  // Short way out, use cached copy
  if (ensemble.manifest->catalog_hash() == cache_hash) {
    if (catalog_path) {
      LoadError error = LoadCatalogCas(cache_hash, cvmfs_path, catalog_path);
      if (error == catalog::kLoadNew) {
        loaded_catalogs_[mountpoint] = cache_hash;
        *catalog_hash = cache_hash;
        return catalog::kLoadUp2Date;
      }
      LogCvmfs(kLogCache, kLogDebug,
               "unable to open catalog from local checksum, downloading");
    } else {
      loaded_catalogs_[mountpoint] = cache_hash;
      *catalog_hash = cache_hash;
      return catalog::kLoadUp2Date;
    }
  }
  if (!catalog_path)
    return catalog::kLoadNew;

  // Load new catalog
  catalog::LoadError load_retval =
    LoadCatalogCas(ensemble.manifest->catalog_hash(), cvmfs_path, catalog_path);
  if (load_retval != catalog::kLoadNew)
    return load_retval;
  loaded_catalogs_[mountpoint] = ensemble.manifest->catalog_hash();
  *catalog_hash = ensemble.manifest->catalog_hash();

  // Store new manifest and certificate
  fetcher_->cache_mgr()->CommitFromMem(ensemble.manifest->certificate(),
                                       ensemble.cert_buf, ensemble.cert_size,
                                       "certificate for " + repo_name_);
  ensemble.manifest->ExportChecksum(".", 0600);
  return catalog::kLoadNew;
}

LoadError ClientCatalogManager::LoadCatalogCas(
  const shash::Any &hash,
  const string &name,
  string *catalog_path)
{
  assert(hash.suffix == shash::kSuffixCatalog);
  int fd = fetcher_->Fetch(hash, cache::CacheManager::kSizeUnknown, name,
                           cache::CacheManager::kTypeCatalog);
  if (fd >= 0) {
    *catalog_path = "@" + StringifyInt(fd);
    return kLoadNew;
  }

  if (fd == -ENOSPC)
    return kLoadNoSpace;

  return kLoadFail;
}

void ClientCatalogManager::UnloadCatalog(const Catalog *catalog) {
  LogCvmfs(kLogCache, kLogDebug, "unloading catalog %s",
           catalog->path().c_str());

  map<PathString, shash::Any>::iterator iter =
    mounted_catalogs_.find(catalog->path());
  assert(iter != mounted_catalogs_.end());
  fetcher_->cache_mgr()->quota_mgr()->Unpin(iter->second);
  mounted_catalogs_.erase(iter);
  const catalog::Counters &counters = catalog->GetCounters();
  loaded_inodes_ -= counters.GetSelfEntries();
}

//------------------------------------------------------------------------------

void CachedManifestEnsemble::FetchCertificate(const shash::Any &hash) {
  uint64_t size;
  bool retval = cache_mgr_->Open2Mem(hash, &cert_buf, &size);
  cert_size = size;
  if (retval)
    perf::Inc(catalog_mgr_->n_certificate_hits_);
  else
    perf::Inc(catalog_mgr_->n_certificate_misses_);
}

}  // namespace catalog
<commit_msg>add missing method implementation<commit_after>/**
 * This file is part of the CernVM file system.
 */

#include "cvmfs_config.h"
#include "catalog_mgr_client.h"

#include "cache.h"
#include "fetch.h"
#include "download.h"
#include "manifest.h"
#include "quota.h"
#include "signature.h"
#include "statistics.h"

using namespace std;  // NOLINT

namespace catalog {

/**
 * Triggered when the catalog is attached (db file opened)
 */
void ClientCatalogManager::ActivateCatalog(Catalog *catalog) {
  const Counters &counters = const_cast<const Catalog*>(catalog)->GetCounters();
  if (catalog->IsRoot()) {
    all_inodes_ = counters.GetAllEntries();
  }
  loaded_inodes_ += counters.GetSelfEntries();
}

ClientCatalogManager::ClientCatalogManager(
  const string &repo_name,
  cvmfs::Fetcher *fetcher,
  signature::SignatureManager *signature_mgr,
  perf::Statistics *statistics)
  : AbstractCatalogManager(statistics)
  , repo_name_(repo_name)
  , fetcher_(fetcher)
  , signature_mgr_(signature_mgr)
  , offline_mode_(false)
  , all_inodes_(0)
  , loaded_inodes_(0)
{
  LogCvmfs(kLogCatalog, kLogDebug, "constructing client catalog manager");
  n_certificate_hits_ = statistics->Register("cache.n_certificate_hits",
    "Number of certificate hits");
  n_certificate_misses_ = statistics->Register("cache.n_certificate_misses",
    "Number of certificate misses");
}

ClientCatalogManager::~ClientCatalogManager() {
  LogCvmfs(kLogCache, kLogDebug, "unpinning / unloading all catalogs");

  for (map<PathString, shash::Any>::iterator i = mounted_catalogs_.begin(),
       iend = mounted_catalogs_.end(); i != iend; ++i)
  {
    fetcher_->cache_mgr()->quota_mgr()->Unpin(i->second);
  }
}

Catalog *ClientCatalogManager::CreateCatalog(
  const PathString  &mountpoint,
  const shash::Any  &catalog_hash,
  catalog::Catalog  *parent_catalog
) {
  mounted_catalogs_[mountpoint] = loaded_catalogs_[mountpoint];
  loaded_catalogs_.erase(mountpoint);
  return new Catalog(mountpoint, catalog_hash, parent_catalog);
}

shash::Any ClientCatalogManager::GetRootHash() {
  ReadLock();
  shash::Any result = mounted_catalogs_[PathString("", 0)];
  Unlock();
  return result;
}

/**
 * Specialized initialization that uses a fixed root hash.
 */
bool ClientCatalogManager::InitFixed(const shash::Any &root_hash) {
  LogCvmfs(kLogCatalog, kLogDebug, "Initialize catalog with root hash %s",
           root_hash.ToString().c_str());
  WriteLock();
  bool attached = MountCatalog(PathString("", 0), root_hash, NULL);
  Unlock();

  if (!attached) {
    LogCvmfs(kLogCatalog, kLogDebug, "failed to initialize root catalog");
  }

  return attached;
}

LoadError ClientCatalogManager::LoadCatalog(
  const PathString  &mountpoint,
  const shash::Any  &hash,
  std::string *catalog_path,
  shash::Any *catalog_hash)
{
  string cvmfs_path = "file catalog at " + repo_name_ + ":" +
    (mountpoint.IsEmpty() ?
      "/" : string(mountpoint.GetChars(), mountpoint.GetLength()));
  bool retval;

  // send the catalog hash to a blind memory position if it zero (save some ifs)
  shash::Any blind_hash;
  if (catalog_hash == NULL) {
    catalog_hash = &blind_hash;
  }

  // Load a particular catalog
  if (!hash.IsNull()) {
    cvmfs_path += " (" + hash.ToString() + ")";
    LoadError load_error = LoadCatalogCas(hash, cvmfs_path, catalog_path);
    if (load_error == catalog::kLoadNew)
      loaded_catalogs_[mountpoint] = hash;
    *catalog_hash = hash;
    return load_error;
  }

  // Happens only on init/remount, i.e. quota won't delete a cached catalog
  string checksum_dir = ".";
  // TODO(jblomer): move this hack to another place
/*  if (alien_cache_ && !FileExists("cvmfschecksum." + repo_name_)) {
    // In case the alien cache has been preloaded, the .cvmfschecksum file
    // must be read from the alien cache instead of the client cache
    checksum_dir = *cache_path_;
  }*/
  shash::Any cache_hash;
  uint64_t cache_last_modified = 0;

  retval = manifest::Manifest::ReadChecksum(
    repo_name_, checksum_dir, &cache_hash, &cache_last_modified);
  if (retval) {
    LogCvmfs(kLogCache, kLogDebug, "cached copy publish date %s",
             StringifyTime(cache_last_modified, true).c_str());
  } else {
    LogCvmfs(kLogCache, kLogDebug, "unable to read local checksum");
  }

  // Load and verify remote checksum
  manifest::Failures manifest_failure;
  CachedManifestEnsemble ensemble(fetcher_->cache_mgr(), this);
  manifest_failure = manifest::Fetch("", repo_name_, cache_last_modified,
                                     &cache_hash, signature_mgr_,
                                     fetcher_->download_mgr(),
                                     &ensemble);
  if (manifest_failure != manifest::kFailOk) {
    LogCvmfs(kLogCache, kLogDebug, "failed to fetch manifest (%d - %s)",
             manifest_failure, manifest::Code2Ascii(manifest_failure));

    if (catalog_path) {
      LoadError error = LoadCatalogCas(cache_hash, cvmfs_path, catalog_path);
      if (error != catalog::kLoadNew)
        return error;
    }
    loaded_catalogs_[mountpoint] = cache_hash;
    *catalog_hash = cache_hash;
    offline_mode_ = true;
    return catalog::kLoadUp2Date;
  }

  offline_mode_ = false;
  cvmfs_path += " (" + ensemble.manifest->catalog_hash().ToString() + ")";
  LogCvmfs(kLogCache, kLogDebug, "remote checksum is %s",
           ensemble.manifest->catalog_hash().ToString().c_str());

  // Short way out, use cached copy
  if (ensemble.manifest->catalog_hash() == cache_hash) {
    if (catalog_path) {
      LoadError error = LoadCatalogCas(cache_hash, cvmfs_path, catalog_path);
      if (error == catalog::kLoadNew) {
        loaded_catalogs_[mountpoint] = cache_hash;
        *catalog_hash = cache_hash;
        return catalog::kLoadUp2Date;
      }
      LogCvmfs(kLogCache, kLogDebug,
               "unable to open catalog from local checksum, downloading");
    } else {
      loaded_catalogs_[mountpoint] = cache_hash;
      *catalog_hash = cache_hash;
      return catalog::kLoadUp2Date;
    }
  }
  if (!catalog_path)
    return catalog::kLoadNew;

  // Load new catalog
  catalog::LoadError load_retval =
    LoadCatalogCas(ensemble.manifest->catalog_hash(), cvmfs_path, catalog_path);
  if (load_retval != catalog::kLoadNew)
    return load_retval;
  loaded_catalogs_[mountpoint] = ensemble.manifest->catalog_hash();
  *catalog_hash = ensemble.manifest->catalog_hash();

  // Store new manifest and certificate
  fetcher_->cache_mgr()->CommitFromMem(ensemble.manifest->certificate(),
                                       ensemble.cert_buf, ensemble.cert_size,
                                       "certificate for " + repo_name_);
  ensemble.manifest->ExportChecksum(".", 0600);
  return catalog::kLoadNew;
}

LoadError ClientCatalogManager::LoadCatalogCas(
  const shash::Any &hash,
  const string &name,
  string *catalog_path)
{
  assert(hash.suffix == shash::kSuffixCatalog);
  int fd = fetcher_->Fetch(hash, cache::CacheManager::kSizeUnknown, name,
                           cache::CacheManager::kTypeCatalog);
  if (fd >= 0) {
    *catalog_path = "@" + StringifyInt(fd);
    return kLoadNew;
  }

  if (fd == -ENOSPC)
    return kLoadNoSpace;

  return kLoadFail;
}

void ClientCatalogManager::UnloadCatalog(const Catalog *catalog) {
  LogCvmfs(kLogCache, kLogDebug, "unloading catalog %s",
           catalog->path().c_str());

  map<PathString, shash::Any>::iterator iter =
    mounted_catalogs_.find(catalog->path());
  assert(iter != mounted_catalogs_.end());
  fetcher_->cache_mgr()->quota_mgr()->Unpin(iter->second);
  mounted_catalogs_.erase(iter);
  const catalog::Counters &counters = catalog->GetCounters();
  loaded_inodes_ -= counters.GetSelfEntries();
}

//------------------------------------------------------------------------------

void CachedManifestEnsemble::FetchCertificate(const shash::Any &hash) {
  uint64_t size;
  bool retval = cache_mgr_->Open2Mem(hash, &cert_buf, &size);
  cert_size = size;
  if (retval)
    perf::Inc(catalog_mgr_->n_certificate_hits_);
  else
    perf::Inc(catalog_mgr_->n_certificate_misses_);
}

}  // namespace catalog
<|endoftext|>


<commit_before>/*!
	\file TestParser.cpp
	\author Gregory Diamos <gregory.diamos@gatech.edu>
	\date Monday January 19, 2009
	\brief The source file for the TestParser class
*/

#ifndef TEST_PARSER_CPP_INCLUDED
#define TEST_PARSER_CPP_INCLUDED

#include "boost/filesystem.hpp"
#include <queue>
#include <fstream>

#include <ocelot/parser/interface/PTXParser.h>
#include <ocelot/parser/test/TestParser.h>

#include <hydrazine/implementation/ArgumentParser.h>
#include <hydrazine/implementation/macros.h>
#include <hydrazine/implementation/debug.h>

#ifdef REPORT_BASE
#undef REPORT_BASE
#endif

#define REPORT_BASE 0

namespace fs = boost::filesystem;

namespace test
{

	TestParser::StringVector TestParser::_getFileNames() const
	{
		StringVector names;

		fs::path path = input;

		if( fs::is_directory( path ) )
		{
			std::queue< fs::path > directories;
			directories.push( path );

			fs::directory_iterator end;

			while( !directories.empty() )
			{
				for( fs::directory_iterator
					file( directories.front() );
					file != end; ++file )
				{
					if( fs::is_directory( file->status() ) && recursive )
					{
						directories.push( file->path() );
					}
					else if( fs::is_regular_file( file->status() ) )
					{
						if( file->path().extension() == ".ptx" )
						{
							names.push_back( file->path().string() );
						}
					}
				}
				directories.pop();
			}
		}
		else if( fs::is_regular_file( path ) )
		{
			if( path.extension() == ".ptx" )
			{
				names.push_back( path.string() );
			}
		}

		return names;
	}

	bool TestParser::_testParse()
	{
		report( " Parsing file " << ptxFile );

		std::stringstream stream, stream2;
		std::ifstream file( ptxFile.c_str() );

		ir::Module base, first, second;
		base.load(file);

		base.write( stream );
		std::string outputFile = ptxFile + ".parsed";

		if( output )
		{
			std::ofstream outFile( outputFile.c_str() );
			base.write( outFile );
			outFile.close();
		}

		report("  - parsing first");
		first.load(stream);
		first.write(stream2);

		if( output )
		{
			std::string outputFile = ptxFile + ".parsed2";
			std::ofstream outFile( outputFile.c_str() );
			first.write( outFile );
			outFile.close();
		}

		report("  - parsing second");
		second.load(stream2);

// This is no longer an error condition - unnecessary labels may have been removed
//
//		if( first.statements.size() != second.statements.size() )
//		{
//
//			status << "First pass parsed " << first.statements.size()
//				<< " statements while second parsed "
//				<< second.statements.size() << "\n";
//			return false;
//
//		}

		for( ir::Module::StatementVector::iterator
			fi = first.statements.begin(),
			si = second.statements.begin(); fi != first.statements.end() &&
			si != second.statements.end(); ++fi, ++si )
		{

			if( !( si->toString() == fi->toString() ) )
			{

				unsigned int index = fi - first.statements.begin();
				status << "At index " << index << " first pass parsed \""
					<< fi->toString() << "\" while second parsed \""
					<< si->toString() << "\"\n";
				return false;

			}

		}

		return true;
	}

	bool TestParser::doTest()
	{
		StringVector files = _getFileNames();

		report( "Parsing the following files:\n "
			<< hydrazine::toString( files.begin(), files.end(), "\n " )  );

		for( StringVector::iterator fi = files.begin();
			fi != files.end(); ++fi )
		{
			ptxFile = *fi;

			if(  !_testParse( ) )
			{
				status << "For file " << ptxFile
					<< ", Test Point 1 (Parse): Failed\n";
				return false;
			}

			status << "For file " << ptxFile
				<< ", Test Point 1 (Parse): Passed\n";
		}

		return true;
	}

	TestParser::TestParser()
	{
		name = "TestParser";

		description = "A test for the PTXParser class. Test Points: 1) Load a";
		description += " PTX file and run it through the parser generating a";
		description += " module.  Write the module to an intermediate stream.";
		description += "  Parse the stream again generating a new module, ";
		description += "compare both to make sure that they match.";
	}

}

int main( int argc, char** argv )
{
	hydrazine::ArgumentParser parser( argc, argv );
	test::TestParser test;
	parser.description( test.testDescription() );

	parser.parse( "-i", test.input, "../tests/ptx",
		"Input directory to search for ptx files." );
	parser.parse( "-r", test.recursive, true,
		"Recursively search directories.");
	parser.parse( "-o", test.output, false,
		"Print out the internal representation of each parsed file." );
	parser.parse( "-s", test.seed, 0,
		"Set the random seed, 0 implies seed with time." );
	parser.parse( "-v", test.verbose, false, "Print out info after the test." );
	parser.parse();

	test.test();

	return test.passed();
}

#endif

<commit_msg>ENH: In TestParser, readded check that both passes parse vectors of the same length<commit_after>/*!
	\file TestParser.cpp
	\author Gregory Diamos <gregory.diamos@gatech.edu>
	\date Monday January 19, 2009
	\brief The source file for the TestParser class
*/

#ifndef TEST_PARSER_CPP_INCLUDED
#define TEST_PARSER_CPP_INCLUDED

#include "boost/filesystem.hpp"
#include <queue>
#include <fstream>

#include <ocelot/parser/interface/PTXParser.h>
#include <ocelot/parser/test/TestParser.h>

#include <hydrazine/implementation/ArgumentParser.h>
#include <hydrazine/implementation/macros.h>
#include <hydrazine/implementation/debug.h>

#ifdef REPORT_BASE
#undef REPORT_BASE
#endif

#define REPORT_BASE 0

namespace fs = boost::filesystem;

namespace test
{

	TestParser::StringVector TestParser::_getFileNames() const
	{
		StringVector names;

		fs::path path = input;

		if( fs::is_directory( path ) )
		{
			std::queue< fs::path > directories;
			directories.push( path );

			fs::directory_iterator end;

			while( !directories.empty() )
			{
				for( fs::directory_iterator
					file( directories.front() );
					file != end; ++file )
				{
					if( fs::is_directory( file->status() ) && recursive )
					{
						directories.push( file->path() );
					}
					else if( fs::is_regular_file( file->status() ) )
					{
						if( file->path().extension() == ".ptx" )
						{
							names.push_back( file->path().string() );
						}
					}
				}
				directories.pop();
			}
		}
		else if( fs::is_regular_file( path ) )
		{
			if( path.extension() == ".ptx" )
			{
				names.push_back( path.string() );
			}
		}

		return names;
	}

	bool TestParser::_testParse()
	{
		report( " Parsing file " << ptxFile );

		std::stringstream stream, stream2;
		std::ifstream file( ptxFile.c_str() );

		ir::Module base, first, second;
		base.load(file);

		base.write( stream );
		std::string outputFile = ptxFile + ".parsed";

		if( output )
		{
			std::ofstream outFile( outputFile.c_str() );
			base.write( outFile );
			outFile.close();
		}

		report("  - parsing first");
		first.load(stream);
		first.write(stream2);

		if( output )
		{
			std::string outputFile = ptxFile + ".parsed2";
			std::ofstream outFile( outputFile.c_str() );
			first.write( outFile );
			outFile.close();
		}

		report("  - parsing second");
		second.load(stream2);

		if( first.statements.size() != second.statements.size() )
		{

			status << "First pass parsed " << first.statements.size()
				<< " statements while second parsed "
				<< second.statements.size() << "\n";
			return false;

		}

		for( ir::Module::StatementVector::iterator
			fi = first.statements.begin(),
			si = second.statements.begin(); fi != first.statements.end() &&
			si != second.statements.end(); ++fi, ++si )
		{

			if( !( si->toString() == fi->toString() ) )
			{

				unsigned int index = fi - first.statements.begin();
				status << "At index " << index << " first pass parsed \""
					<< fi->toString() << "\" while second parsed \""
					<< si->toString() << "\"\n";
				return false;

			}

		}

		return true;
	}

	bool TestParser::doTest()
	{
		StringVector files = _getFileNames();

		report( "Parsing the following files:\n "
			<< hydrazine::toString( files.begin(), files.end(), "\n " )  );

		for( StringVector::iterator fi = files.begin();
			fi != files.end(); ++fi )
		{
			ptxFile = *fi;

			if(  !_testParse( ) )
			{
				status << "For file " << ptxFile
					<< ", Test Point 1 (Parse): Failed\n";
				return false;
			}

			status << "For file " << ptxFile
				<< ", Test Point 1 (Parse): Passed\n";
		}

		return true;
	}

	TestParser::TestParser()
	{
		name = "TestParser";

		description = "A test for the PTXParser class. Test Points: 1) Load a";
		description += " PTX file and run it through the parser generating a";
		description += " module.  Write the module to an intermediate stream.";
		description += "  Parse the stream again generating a new module, ";
		description += "compare both to make sure that they match.";
	}

}

int main( int argc, char** argv )
{
	hydrazine::ArgumentParser parser( argc, argv );
	test::TestParser test;
	parser.description( test.testDescription() );

	parser.parse( "-i", test.input, "../tests/ptx",
		"Input directory to search for ptx files." );
	parser.parse( "-r", test.recursive, true,
		"Recursively search directories.");
	parser.parse( "-o", test.output, false,
		"Print out the internal representation of each parsed file." );
	parser.parse( "-s", test.seed, 0,
		"Set the random seed, 0 implies seed with time." );
	parser.parse( "-v", test.verbose, false, "Print out info after the test." );
	parser.parse();

	test.test();

	return test.passed();
}

#endif

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007 Tommi Maekitalo
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 */

#include <cxxtools/pipestream.h>
#include <cxxtools/syserror.h>
#include <algorithm>
#include <unistd.h>
#include <cxxtools/log.h>
#include <cstring>

log_define("cxxtools.pipestream")

namespace cxxtools
{
  Pipestreambuf::Pipestreambuf(unsigned bufsize_)
    : bufsize(bufsize_),
      ibuffer(0),
      obuffer(0)
  { }

  Pipestreambuf::~Pipestreambuf()
  {
    log_debug("Pipestreambuf::~Pipestreambuf()");

    delete [] ibuffer;
    delete [] obuffer;

    closeReadFd();
    closeWriteFd();
  }

  std::streambuf::int_type Pipestreambuf::overflow(std::streambuf::int_type ch)
  {
    log_debug("overflow(" << ch << ')');

    if (pptr() != pbase())
    {
      log_debug("write " << (pptr() - pbase()) << " bytes to fd " << getWriteFd());
      ssize_t ret = ::write(getWriteFd(), pbase(), pptr() - pbase());
      if (ret < 0)
        throw SysError("write");
      else if (ret == 0)
        return traits_type::eof();
      else
      {
        log_debug(ret << " bytes written to fd " << getWriteFd());
        if (ret < bufsize)
          std::memmove(obuffer, obuffer + ret, bufsize - ret);
        setp(obuffer + bufsize - ret, obuffer + bufsize);
      }
    }
    else
    {
      log_debug("initialize outputbuffer");
      if (obuffer == 0)
      {
        log_debug("allocate " << bufsize << " bytes output buffer");
        obuffer = new char[bufsize];
      }

      setp(obuffer, obuffer + bufsize);
    }

    if (ch != traits_type::eof())
    {
      *pptr() = traits_type::to_char_type(ch);
      pbump(1);
    }

    return 0;
  }

  std::streambuf::int_type Pipestreambuf::underflow()
  {
    log_debug("underflow()");

    if (ibuffer == 0)
    {
      log_debug("allocate " << bufsize << " bytes input buffer");
      ibuffer = new char[bufsize];
    }

    log_debug("read from fd " << getReadFd());
    int ret = ::read(getReadFd(), ibuffer, bufsize);
    log_debug("read returned " << ret);
    if (ret < 0)
      throw SysError("read");
    else if (ret == 0)
      return traits_type::eof();

    log_debug(ret << " bytes read");
    setg(ibuffer, ibuffer, ibuffer + ret);

    return *gptr();
  }

  int Pipestreambuf::sync()
  {
    log_debug("sync()");
    if (pptr() != pbase())
    {
      char* p = pbase();
      while (p < pptr())
      {
        log_debug("write " << (pptr() - p) << " bytes to fd " << getWriteFd());
        ssize_t ret = ::write(getWriteFd(), p, pptr() - p);
        if (ret < 0)
          throw SysError("write");
        else if (ret == 0)
          return traits_type::eof();

        log_debug(ret << " bytes written to fd " << getWriteFd());
        p += ret;
      }
    }
    return 0;
  }

}
<commit_msg>sync and close before deleting buffers<commit_after>/*
 * Copyright (C) 2007 Tommi Maekitalo
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
 * NON-INFRINGEMENT.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 */

#include <cxxtools/pipestream.h>
#include <cxxtools/syserror.h>
#include <algorithm>
#include <unistd.h>
#include <cxxtools/log.h>
#include <cstring>

log_define("cxxtools.pipestream")

namespace cxxtools
{
  Pipestreambuf::Pipestreambuf(unsigned bufsize_)
    : bufsize(bufsize_),
      ibuffer(0),
      obuffer(0)
  { }

  Pipestreambuf::~Pipestreambuf()
  {
    log_debug("Pipestreambuf::~Pipestreambuf()");

    try
    {
      closeReadFd();
    }
    catch (const std::exception& e)
    {
      log_debug("ignore exception in closing read pipe: " << e.what());
    }

    try
    {
      closeWriteFd();
    }
    catch (const std::exception& e)
    {
      log_debug("ignore exception in closing write pipe: " << e.what());
    }

    delete [] ibuffer;
    delete [] obuffer;
  }

  std::streambuf::int_type Pipestreambuf::overflow(std::streambuf::int_type ch)
  {
    log_debug("overflow(" << ch << ')');

    if (pptr() != pbase())
    {
      log_debug("write " << (pptr() - pbase()) << " bytes to fd " << getWriteFd());
      ssize_t ret = ::write(getWriteFd(), pbase(), pptr() - pbase());
      if (ret < 0)
        throw SysError("write");
      else if (ret == 0)
        return traits_type::eof();
      else
      {
        log_debug(ret << " bytes written to fd " << getWriteFd());
        if (ret < bufsize)
          std::memmove(obuffer, obuffer + ret, bufsize - ret);
        setp(obuffer + bufsize - ret, obuffer + bufsize);
      }
    }
    else
    {
      log_debug("initialize outputbuffer");
      if (obuffer == 0)
      {
        log_debug("allocate " << bufsize << " bytes output buffer");
        obuffer = new char[bufsize];
      }

      setp(obuffer, obuffer + bufsize);
    }

    if (ch != traits_type::eof())
    {
      *pptr() = traits_type::to_char_type(ch);
      pbump(1);
    }

    return 0;
  }

  std::streambuf::int_type Pipestreambuf::underflow()
  {
    log_debug("underflow()");

    if (ibuffer == 0)
    {
      log_debug("allocate " << bufsize << " bytes input buffer");
      ibuffer = new char[bufsize];
    }

    log_debug("read from fd " << getReadFd());
    int ret = ::read(getReadFd(), ibuffer, bufsize);
    log_debug("read returned " << ret);
    if (ret < 0)
      throw SysError("read");
    else if (ret == 0)
      return traits_type::eof();

    log_debug(ret << " bytes read");
    setg(ibuffer, ibuffer, ibuffer + ret);

    return *gptr();
  }

  int Pipestreambuf::sync()
  {
    log_debug("sync()");
    if (pptr() != pbase())
    {
      char* p = pbase();
      while (p < pptr())
      {
        log_debug("write " << (pptr() - p) << " bytes to fd " << getWriteFd());
        ssize_t ret = ::write(getWriteFd(), p, pptr() - p);
        if (ret < 0)
          throw SysError("write");
        else if (ret == 0)
          return traits_type::eof();

        log_debug(ret << " bytes written to fd " << getWriteFd());
        p += ret;
      }
    }
    return 0;
  }

}
<|endoftext|>


<commit_before>
/*
 * apk_test.cpp - This file tests basic APK operation
 */

#include "apk.h"
#include "test_suite.h"

using namespace wangziqi2013;
using namespace android_dalvik_analysis;

/*
 * TestReadFileHeader() - Tests whether file header could be read
 */
void TestReadFileHeader() {
  _PrintTestName();

  ApkArchive("./test.apk");

  try {
    ApkArchive("./corrupt.apk");
  } catch(int) {
    fprintf(stderr, "Successfully caught the exception\n");

    return;
  }

  assert(false);

  return;
}

int main() {
  TestReadFileHeader();

  return 0;
}
<commit_msg>Link file name printing test<commit_after>
/*
 * apk_test.cpp - This file tests basic APK operation
 */

#include "apk.h"
#include "test_suite.h"

using namespace wangziqi2013;
using namespace android_dalvik_analysis;

/*
 * TestReadFileHeader() - Tests whether file header could be read
 */
void TestReadFileHeader() {
  _PrintTestName();

  ApkArchive apk{"./test.apk"};
  apk.DebugPrintAllFileName();

  try {
    ApkArchive("./corrupt.apk");
  } catch(int) {
    fprintf(stderr, "Successfully caught the exception\n");

    return;
  }

  assert(false);

  return;
}

int main() {
  TestReadFileHeader();

  return 0;
}
<|endoftext|>


<commit_before><commit_msg>Fix race condition in OCSPRequestSession.<commit_after><|endoftext|>


<commit_before>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @GFile		g_file.cpp
* @version
* @brief
* @author 	duye
* @date		2013-06-20
* @note
*
*  1. 2013-06-20 duye Created this GFile
*
*/
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <g_file.h>

// default create GFile permissions
static const GUint32 G_FILE_MASK = 0x775;

GResult GFileUtil::createFile(const GInt8* filePath)
{
	return createFile(filePath, 0);
}

GResult GFileUtil::createFile(const GInt8* filePath, const GUint64& initSize)
{
	GInt32 fd = ::creat(filePath, G_FILE_MASK);
	if (fd == -1)
	{
		return G_NO;
	}

	if (ftruncate(fd, initSize) == -1)
	{
		::close(fd);
		return G_NO;
	}

	::close(fd);

	return G_YES;
}

GFile::GFile() : m_fd(-1), m_flags(0), m_pathLen(0)
{
	m_error[0] = 0;
	m_path[0] = 0;
}

GFile::GFile(const GInt8* filePath) : m_fd(-1), m_flags(0), m_pathLen(0)
{
	GUint32 len = strlen(filePath);
	if (len < G_PATH_MAX)
	{
	    memcpy(m_path, filePath, len);
	    m_path[len] = 0;
	    m_pathLen = len;
	}

	m_error[0] = 0;
}

GFile::~GFile()
{
	close();
}

GResult GFile::setPath(const GInt8* filePath)
{
	if (m_pathLen > 0)
	{
	    setError("file path has exist");
	    return G_NO;
	}

	GUint32 len = strlen(filePath);
	if (len < G_PATH_MAX)
	{
	    memcpy(m_path, filePath, len);
	    m_path[len] = 0;
	    m_pathLen = len;
	}
	else
	{
	    setError("file path too long");
	    return G_NO;
	}

	return G_YES;
}

GResult GFile::open(const GUint64 flags)
{
	return open(flags, G_FILE_MASK);
}

GResult GFile::open(const GUint64 flags, const GInt32 mode)
{
	GInt32 openFlags = 0;
	if (flags | G_OPEN_READ)
	{
		openFlags = O_RDONLY;
	}
	else if (flags | G_OPEN_WRITE)
	{
		openFlags = O_WRONLY | O_CREAT;
	}
	else if (flags | G_OPEN_RDWR)
	{
		openFlags = O_RDWR | O_CREAT;
	}
	else if (flags | G_OPEN_APPEND)
	{
		if (openFlags == 0)
		{
			return G_NO;
		}

		openFlags |= O_APPEND;
	}

	if (openFlags == 0)
	{
		setError("input open mode error");
		return G_NO;
	}

	return orgOpen(openFlags, mode);
}

GResult GFile::close()
{
	if (m_fd < 0)
	{
		setError("file don't open");
		return G_NO;
	}

	GResult ret = (::close(m_fd) != -1 ? G_YES : G_NO);

	m_fd = -1;
	m_path[0] = 0;
	m_flags = 0;

	return ret;
}

GInt64 GFile::getSize()
{
	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	return (GInt64)(m_fileStat.st_size);
}

GInt64 GFile::seek(const GInt64 offset, const SeekFlags& flags)
{
	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	GInt32 sysFlags = -1;

	switch(flags)
	{
	case G_SEEK_BEG:
		sysFlags = SEEK_SET;
		break;
	case G_SEEK_CUR:
		sysFlags = SEEK_CUR;
		break;
	case G_SEEK_END:
		sysFlags = SEEK_END;
		break;
	default:
		return G_NO;
		break;
	}

	return ::lseek(m_fd, offset, sysFlags);
}

GInt64 GFile::tell()
{
	return seek(0, G_SEEK_CUR);
}

GInt64 GFile::read(GInt8* buffer, const GUint64 size)
{
	if (buffer == NULL || size <= 0)
	{
		setError("input parameter is error");
		return G_NO;
	}

	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	return ::read(m_fd, buffer, size);
}

GInt64 GFile::write(const GInt8* data, const GUint64 length)
{
	if (data == NULL || length <= 0)
	{
		setError("input parameter is error");
		return G_NO;
	}

	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	return ::write(m_fd, data, length);
}

GInt8* GFile::getError()
{
	return m_error;
}

GResult GFile::orgOpen(const GInt32 flags, const GUint32 mode)
{
	if (m_fd > 0)
	{
		setError("file had opened");
		return G_NO;
	}

	if (m_pathLen == 0)
	{
		setError("hasn't set file path");
		return G_NO;
	}

	m_fd = ::open(m_path, flags, mode);
	if (m_fd > 0)
	{
		m_flags = flags;
		fstat(m_fd, &m_fileStat);
	}
	else
	{
		setError("open file failed, check whether exist this file path");
	}

	return (m_fd != -1 ? true : false);
}

void GFile::setError(const GInt8* args, ...)
{
	GSys::format(m_error, G_ERROR_BUF_SIZE, args);
}
<commit_msg>modify files<commit_after>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @GFile	g_file.cpp
* @version
* @brief
* @author 	duye
* @date		2013-06-20
* @note
*
*  1. 2013-06-20 duye Created this GFile
*
*/
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <g_file.h>

// default create GFile permissions
static const GUint32 G_FILE_MASK = 0x775;

GResult GFileUtil::createFile(const GInt8* filePath)
{
	return createFile(filePath, 0);
}

GResult GFileUtil::createFile(const GInt8* filePath, const GUint64& initSize)
{
	GInt32 fd = ::creat(filePath, G_FILE_MASK);
	if (fd == -1)
	{
		return G_NO;
	}

	if (ftruncate(fd, initSize) == -1)
	{
		::close(fd);
		return G_NO;
	}

	::close(fd);

	return G_YES;
}

GFile::GFile() : m_fd(-1), m_flags(0), m_pathLen(0)
{
	m_error[0] = 0;
	m_path[0] = 0;
}

GFile::GFile(const GInt8* filePath) : m_fd(-1), m_flags(0), m_pathLen(0)
{
	GUint32 len = strlen(filePath);
	if (len < G_PATH_MAX)
	{
	    memcpy(m_path, filePath, len);
	    m_path[len] = 0;
	    m_pathLen = len;
	}

	m_error[0] = 0;
}

GFile::~GFile()
{
	close();
}

GResult GFile::setPath(const GInt8* filePath)
{
	if (m_pathLen > 0)
	{
	    setError("file path has exist");
	    return G_NO;
	}

	GUint32 len = strlen(filePath);
	if (len < G_PATH_MAX)
	{
	    memcpy(m_path, filePath, len);
	    m_path[len] = 0;
	    m_pathLen = len;
	}
	else
	{
	    setError("file path too long");
	    return G_NO;
	}

	return G_YES;
}

GResult GFile::open(const GUint64 flags)
{
	return open(flags, G_FILE_MASK);
}

GResult GFile::open(const GUint64 flags, const GInt32 mode)
{
	GInt32 openFlags = 0;
	if (flags | G_OPEN_READ)
	{
		openFlags = O_RDONLY;
	}
	else if (flags | G_OPEN_WRITE)
	{
		openFlags = O_WRONLY | O_CREAT;
	}
	else if (flags | G_OPEN_RDWR)
	{
		openFlags = O_RDWR | O_CREAT;
	}
	else if (flags | G_OPEN_APPEND)
	{
		if (openFlags == 0)
		{
			return G_NO;
		}

		openFlags |= O_APPEND;
	}

	if (openFlags == 0)
	{
		setError("input open mode error");
		return G_NO;
	}

	return orgOpen(openFlags, mode);
}

GResult GFile::close()
{
	if (m_fd < 0)
	{
		setError("file don't open");
		return G_NO;
	}

	GResult ret = (::close(m_fd) != -1 ? G_YES : G_NO);

	m_fd = -1;
	m_path[0] = 0;
	m_flags = 0;

	return ret;
}

GInt64 GFile::getSize()
{
	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	return (GInt64)(m_fileStat.st_size);
}

GInt64 GFile::seek(const GInt64 offset, const SeekFlags& flags)
{
	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	GInt32 sysFlags = -1;

	switch(flags)
	{
	case G_SEEK_BEG:
		sysFlags = SEEK_SET;
		break;
	case G_SEEK_CUR:
		sysFlags = SEEK_CUR;
		break;
	case G_SEEK_END:
		sysFlags = SEEK_END;
		break;
	default:
		return G_NO;
		break;
	}

	return ::lseek(m_fd, offset, sysFlags);
}

GInt64 GFile::tell()
{
	return seek(0, G_SEEK_CUR);
}

GInt64 GFile::read(GInt8* buffer, const GUint64 size)
{
	if (buffer == NULL || size <= 0)
	{
		setError("input parameter is error");
		return G_NO;
	}

	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	return ::read(m_fd, buffer, size);
}

GInt64 GFile::write(const GInt8* data, const GUint64 length)
{
	if (data == NULL || length <= 0)
	{
		setError("input parameter is error");
		return G_NO;
	}

	if (m_fd <= 0)
	{
		setError("file don't open");
		return G_NO;
	}

	return ::write(m_fd, data, length);
}

GInt8* GFile::getError()
{
	return m_error;
}

GResult GFile::orgOpen(const GInt32 flags, const GUint32 mode)
{
	if (m_fd > 0)
	{
		setError("file had opened");
		return G_NO;
	}

	if (m_pathLen == 0)
	{
		setError("hasn't set file path");
		return G_NO;
	}

	m_fd = ::open(m_path, flags, mode);
	if (m_fd > 0)
	{
		m_flags = flags;
		fstat(m_fd, &m_fileStat);
	}
	else
	{
		setError("open file failed, check whether exist this file path");
	}

	return (m_fd != -1 ? true : false);
}

void GFile::setError(const GInt8* args, ...)
{
	GSys::format(m_error, G_ERROR_BUF_SIZE, args);
}
<|endoftext|>


<commit_before>#include "backends.hpp"

#include<string>
#include<armadillo>

using namespace std;
using namespace arma;

#define DIM_NAME "__hide"
#define ATTR_NAME "sample"
#define ROW_NAME "samples"
#define COL_NAME "channels"
#define RANGE_SIZE 4
#define TILEDB_READ_MODE "r"
#define TILEDB_WRITE_MODE "w"
#define TILEDB_APPEND_MODE "a"

string TileDBBackend::mrn_to_array_name(string mrn)
{
  return _mrn_to_array_name(mrn, "-tiledb");
}

string TileDBBackend::get_array_name(string mrn)
{
  return mrn + "-tiledb";
}

string TileDBBackend::get_workspace()
{
  return DATADIR;
}

string TileDBBackend::get_group()
{
  return "";
}

ArrayMetadata TileDBBackend::get_array_metadata(string mrn)
{
  string array_name = mrn_to_array_name(mrn) + "-metadata";

  ifstream file;
  file.open(array_name, ios::binary);

  uint32_t header_len;
  file.read((char*) &header_len, sizeof(uint32_t));

  string header = "";
  header.resize(header_len, ' ');
  file.read((char*) header.c_str(), header_len);
  file.close();

  string err;
  Json json = Json::parse(header, err);
  int fs = json["fs"].int_value();
  int nsamples = json["nsamples"].int_value();
  int nrows = json["nrows"].int_value();
  int ncols = json["ncols"].int_value();
  return ArrayMetadata(fs, nsamples, nrows, ncols);
}

void TileDBBackend::write_metadata(string mrn, ArrayMetadata* metadata)
{
  ofstream file;
  string path = mrn_to_array_name(mrn) + "-metadata";
  file.open(path, ios::trunc|ios::binary);

  // Store metadata in header;
  string header = metadata->to_string();
  uint32_t header_len = get_byte_aligned_length(header);
  header.resize(header_len, ' ');
  file.write((char*) &header_len, sizeof(uint32_t));
  file.write(header.c_str(), header_len);
  file.close();
}

void TileDBBackend::create_array(string mrn, ArrayMetadata* metadata)
{
  // tmp fix until TileDB metadata is implemented
  write_metadata(mrn, metadata);
  string group = get_group();
  string workspace = get_workspace();
  string array_name = get_array_name(mrn);
  // csv of array schema
  string array_schema_str = array_name + ",1," + ATTR_NAME + ",2," + COL_NAME + "," + ROW_NAME + ",0," + to_string(metadata->ncols) + ",0," + to_string(metadata->nrows) + ",float32,int32,*,column-major,*,*,*,*";

  // Initialize TileDB
  TileDB_CTX* tiledb_ctx;
  tiledb_ctx_init(tiledb_ctx);

  // Store the array schema
  tiledb_array_define(tiledb_ctx, workspace.c_str(), group.c_str(), array_schema_str.c_str());
  tiledb_ctx_finalize(tiledb_ctx);
}

void TileDBBackend::open_array(string mrn)
{
  _open_array(mrn, TILEDB_READ_MODE);
}

void TileDBBackend::_open_array(string mrn, const char* mode)
{
  if (in_cache(mrn))
  {
    return;
  }
  TileDB_CTX* tiledb_ctx;
  tiledb_ctx_init(tiledb_ctx);
  string group = get_group();
  string workspace = get_workspace();
  string array_name = get_array_name(mrn);
  int array_id = tiledb_array_open(tiledb_ctx, workspace.c_str(), group.c_str(), array_name.c_str(), mode);
  put_cache(mrn, tiledb_cache_pair(tiledb_ctx, array_id));
}

void TileDBBackend::read_array(string mrn, int ch, int start_offset, int end_offset, frowvec& buf)
{
  double* range = new double[RANGE_SIZE];
  range[0] = CH_REVERSE_IDX[ch];
  range[1] = CH_REVERSE_IDX[ch];
  range[2] = start_offset;
  range[3] = end_offset;
  _read_array(mrn, range, buf);
}

void TileDBBackend::read_array(string mrn, int start_offset, int end_offset, fmat& buf)
{
  double* range = new double[RANGE_SIZE];
  range[0] = 0;
  range[1] = get_ncols(mrn);
  range[2] = start_offset;
  range[3] = end_offset;
  _read_array(mrn, range, buf);
}

void TileDBBackend::_read_array(string mrn, double* range, fmat& buf)
{
  tiledb_cache_pair cache_pair = get_cache(mrn);
  TileDB_CTX* tiledb_ctx = cache_pair.first;
  int array_id = cache_pair.second;
  const char* dim_names = DIM_NAME;
  int dim_names_num = 1;
  const char* attribute_names = ATTR_NAME;
  int attribute_names_num = 1;
  size_t cell_buf_size = sizeof(float) * buf.n_elem;
  tiledb_subarray_buf(tiledb_ctx, array_id, range,
      RANGE_SIZE, &dim_names, dim_names_num,
      &attribute_names, attribute_names_num,
      buf.memptr(), &cell_buf_size);
}

void TileDBBackend::write_array(string mrn, int ch, int start_offset, int end_offset, fmat& buf)
{
  if (in_cache(mrn))
  {
    close_array(mrn); // we need to reopen in append mode
  }
  _open_array(mrn, TILEDB_APPEND_MODE);
  tiledb_cache_pair pair = get_cache(mrn);
  TileDB_CTX* tiledb_ctx = pair.first;
  int array_id = pair.second;
  cell_t cell;
  if (ch == ALL) {
    buf = buf.t();
  }
  for (uword i = 0; i < buf.n_rows; i++)
  {
    for (uword j = 0; j < buf.n_cols; j++)
    {
      // x (col) coord, y (row) coord, attribute
      cell.x = start_offset + j;
      cell.y = ch == ALL ? i : CH_REVERSE_IDX[ch];
      cell.sample = buf(i, j);
      tiledb_cell_write_sorted(tiledb_ctx, array_id, &cell);
    }
  }

  // Finalize TileDB
  close_array(mrn);
}

void TileDBBackend::close_array(string mrn)
{
  if (in_cache(mrn))
  {
    tiledb_cache_pair pair = get_cache(mrn);
    tiledb_array_close(pair.first, pair.second);
    tiledb_ctx_finalize(pair.first);
    pop_cache(mrn);
  }
}

<commit_msg>Fix annoying bug in tiledb backend<commit_after>#include "backends.hpp"

#include<string>
#include<armadillo>

using namespace std;
using namespace arma;

#define DIM_NAME "__hide"
#define ATTR_NAME "sample"
#define ROW_NAME "samples"
#define COL_NAME "channels"
#define RANGE_SIZE 4
#define TILEDB_READ_MODE "r"
#define TILEDB_WRITE_MODE "w"
#define TILEDB_APPEND_MODE "a"

string TileDBBackend::mrn_to_array_name(string mrn)
{
  return _mrn_to_array_name(mrn, "-tiledb");
}

string TileDBBackend::get_array_name(string mrn)
{
  return mrn + "-tiledb";
}

string TileDBBackend::get_workspace()
{
  return DATADIR;
}

string TileDBBackend::get_group()
{
  return "";
}

ArrayMetadata TileDBBackend::get_array_metadata(string mrn)
{
  string array_name = mrn_to_array_name(mrn) + "-metadata";

  ifstream file;
  file.open(array_name, ios::binary);

  uint32_t header_len;
  file.read((char*) &header_len, sizeof(uint32_t));

  string header = "";
  header.resize(header_len, ' ');
  file.read((char*) header.c_str(), header_len);
  file.close();

  string err;
  Json json = Json::parse(header, err);
  int fs = json["fs"].int_value();
  int nsamples = json["nsamples"].int_value();
  int nrows = json["nrows"].int_value();
  int ncols = json["ncols"].int_value();
  return ArrayMetadata(fs, nsamples, nrows, ncols);
}

void TileDBBackend::write_metadata(string mrn, ArrayMetadata* metadata)
{
  ofstream file;
  string path = mrn_to_array_name(mrn) + "-metadata";
  file.open(path, ios::trunc|ios::binary);

  // Store metadata in header;
  string header = metadata->to_string();
  uint32_t header_len = get_byte_aligned_length(header);
  header.resize(header_len, ' ');
  file.write((char*) &header_len, sizeof(uint32_t));
  file.write(header.c_str(), header_len);
  file.close();
}

void TileDBBackend::create_array(string mrn, ArrayMetadata* metadata)
{
  // tmp fix until TileDB metadata is implemented
  write_metadata(mrn, metadata);
  string group = get_group();
  string workspace = get_workspace();
  string array_name = get_array_name(mrn);
  // csv of array schema
  string array_schema_str = array_name + ",1," + ATTR_NAME + ",2," + COL_NAME + "," + ROW_NAME + ",0," + to_string(metadata->ncols) + ",0," + to_string(metadata->nrows) + ",float32,int32,*,column-major,*,*,*,*";

  // Initialize TileDB
  TileDB_CTX* tiledb_ctx;
  tiledb_ctx_init(tiledb_ctx);

  // Store the array schema
  tiledb_array_define(tiledb_ctx, workspace.c_str(), group.c_str(), array_schema_str.c_str());
  tiledb_ctx_finalize(tiledb_ctx);
}

void TileDBBackend::open_array(string mrn)
{
  _open_array(mrn, TILEDB_READ_MODE);
}

void TileDBBackend::_open_array(string mrn, const char* mode)
{
  if (in_cache(mrn))
  {
    return;
  }
  TileDB_CTX* tiledb_ctx;
  tiledb_ctx_init(tiledb_ctx);
  string group = get_group();
  string workspace = get_workspace();
  string array_name = get_array_name(mrn);
  int array_id = tiledb_array_open(tiledb_ctx, workspace.c_str(), group.c_str(), array_name.c_str(), mode);
  put_cache(mrn, tiledb_cache_pair(tiledb_ctx, array_id));
}

void TileDBBackend::read_array(string mrn, int ch, int start_offset, int end_offset, frowvec& buf)
{
  double* range = new double[RANGE_SIZE];
  range[0] = CH_REVERSE_IDX[ch];
  range[1] = CH_REVERSE_IDX[ch];
  range[2] = start_offset;
  range[3] = end_offset;
  _read_array(mrn, range, buf);
}

void TileDBBackend::read_array(string mrn, int start_offset, int end_offset, fmat& buf)
{
  double* range = new double[RANGE_SIZE];
  range[0] = 0;
  range[1] = get_ncols(mrn);
  range[2] = start_offset;
  range[3] = end_offset;
  _read_array(mrn, range, buf);
}

void TileDBBackend::_read_array(string mrn, double* range, fmat& buf)
{
  tiledb_cache_pair cache_pair = get_cache(mrn);
  TileDB_CTX* tiledb_ctx = cache_pair.first;
  int array_id = cache_pair.second;
  const char* dim_names = DIM_NAME;
  int dim_names_num = 1;
  const char* attribute_names = ATTR_NAME;
  int attribute_names_num = 1;
  size_t cell_buf_size = sizeof(float) * buf.n_elem;
  tiledb_subarray_buf(tiledb_ctx, array_id, range,
      RANGE_SIZE, &dim_names, dim_names_num,
      &attribute_names, attribute_names_num,
      buf.memptr(), &cell_buf_size);
}

void TileDBBackend::write_array(string mrn, int ch, int start_offset, int end_offset, fmat& buf)
{
  if (in_cache(mrn))
  {
    close_array(mrn); // we need to reopen in append mode
  }
  _open_array(mrn, TILEDB_APPEND_MODE);
  tiledb_cache_pair pair = get_cache(mrn);
  TileDB_CTX* tiledb_ctx = pair.first;
  int array_id = pair.second;
  cell_t cell;
  if (ch == ALL) {
    buf = buf.t();
  }
  for (uword i = 0; i < buf.n_rows; i++)
  {
    for (uword j = 0; j < buf.n_cols; j++)
    {
      // x (col) coord, y (row) coord, attribute
      cell.x = ch == ALL ? start_offset + j : CH_REVERSE_IDX[ch];
      cell.y = ch == ALL ? i : start_offset + j;
      cell.sample = buf(i, j);
      tiledb_cell_write_sorted(tiledb_ctx, array_id, &cell);
    }
  }

  // Finalize TileDB
  close_array(mrn);
}

void TileDBBackend::close_array(string mrn)
{
  if (in_cache(mrn))
  {
    tiledb_cache_pair pair = get_cache(mrn);
    tiledb_array_close(pair.first, pair.second);
    tiledb_ctx_finalize(pair.first);
    pop_cache(mrn);
  }
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/

#include <cstdlib>
#include <string>

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
#include "aom_ports/aom_timer.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"

using libaom_test::ACMRandom;

namespace {

typedef void (*clpf_block_t)(const uint8_t *src, uint8_t *dst, int sstride,
                             int dstride, int x0, int y0, int sizex, int sizey,
                             int width, int height, unsigned int strength);

typedef std::tr1::tuple<clpf_block_t, clpf_block_t, int, int>
    clpf_block_param_t;

class ClpfBlockTest : public ::testing::TestWithParam<clpf_block_param_t> {
 public:
  virtual ~ClpfBlockTest() {}
  virtual void SetUp() {
    clpf = GET_PARAM(0);
    ref_clpf = GET_PARAM(1);
    sizex = GET_PARAM(2);
    sizey = GET_PARAM(3);
  }

  virtual void TearDown() { libaom_test::ClearSystemState(); }

 protected:
  int sizex;
  int sizey;
  clpf_block_t clpf;
  clpf_block_t ref_clpf;
};

typedef ClpfBlockTest ClpfSpeedTest;

TEST_P(ClpfBlockTest, TestSIMDNoMismatch) {
  int w = sizex;
  int h = sizey;
  const int size = 32;
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  DECLARE_ALIGNED(16, uint8_t, s[size * size]);
  DECLARE_ALIGNED(16, uint8_t, d[size * size]);
  DECLARE_ALIGNED(16, uint8_t, ref_d[size * size]);
  memset(ref_d, 0, size * size);
  memset(d, 0, size * size);

  int error = 0;
  int pos = 0;
  int strength = 0;
  int xpos = 0, ypos = 0;
  int bits;
  int level;

  // Test every combination of:
  // * Input with 1-8 bits of noise
  // * Noise level around every value from 0 to 255
  // * Blocks anywhere in the frame (along all egdes and also fully inside)
  // * All strengths
  for (level = 0; level < 256 && !error; level++) {
    for (bits = 1; bits < 9 && !error; bits++) {
      for (int i = 0; i < size * size; i++)
        s[i] = clamp((rnd.Rand8() & ((1 << bits) - 1)) + level, 0, 255);

      for (ypos = 0; ypos < size && !error; ypos += h * !error) {
        for (xpos = 0; xpos < size && !error; xpos += w * !error) {
          for (strength = 0; strength < 3 && !error; strength += !error) {
            ref_clpf(s, ref_d, size, size, xpos, ypos, w, h, size, size,
                     1 << strength);
            ASM_REGISTER_STATE_CHECK(clpf(s, d, size, size, xpos, ypos, w, h,
                                          size, size, 1 << strength));

            for (pos = 0; pos < size * size && !error; pos++) {
              error = ref_d[pos] != d[pos];
            }
          }
        }
      }
    }
  }

  EXPECT_EQ(0, error)
      << "Error: ClpfBlockTest, SIMD and C mismatch." << std::endl
      << "First error at " << pos % size << "," << pos / size << " ("
      << (int16_t)ref_d[pos] << " != " << (int16_t)d[pos] << ") " << std::endl
      << "strength: " << (1 << strength) << std::endl
      << "xpos: " << xpos << std::endl
      << "ypos: " << ypos << std::endl
      << "A=" << (pos > size ? (int16_t)s[pos - size] : -1) << std::endl
      << "B=" << (pos % size - 2 >= 0 ? (int16_t)s[pos - 2] : -1) << std::endl
      << "C=" << (pos % size - 1 >= 0 ? (int16_t)s[pos - 1] : -1) << std::endl
      << "X=" << (int16_t)s[pos] << std::endl
      << "D=" << (pos % size + 1 < size ? (int16_t)s[pos + 1] : -1) << std::endl
      << "E=" << (pos % size + 2 < size ? (int16_t)s[pos + 2] : -1) << std::endl
      << "F=" << (pos + size < size * size ? (int16_t)s[pos + size] : -1)
      << std::endl;
}

TEST_P(ClpfSpeedTest, TestSpeed) {
  int w = sizex;
  int h = sizey;
  const int size = 32;
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  DECLARE_ALIGNED(16, uint8_t, s[size * size]);
  DECLARE_ALIGNED(16, uint8_t, d[size * size]);

  int strength;
  int xpos, ypos;

  for (int i = 0; i < size * size; i++) s[i] = rnd.Rand8();

  aom_usec_timer ref_timer;
  aom_usec_timer timer;

  aom_usec_timer_start(&ref_timer);
  for (int c = 0; c < 65536; c++) {
    for (ypos = 0; ypos < size; ypos += h) {
      for (xpos = 0; xpos < size; xpos += w) {
        for (strength = 0; strength < 3; strength++) {
          ref_clpf(s, d, size, size, xpos, ypos, w, h, size, size,
                   1 << strength);
        }
      }
    }
  }
  aom_usec_timer_mark(&ref_timer);
  int ref_elapsed_time = aom_usec_timer_elapsed(&ref_timer);

  aom_usec_timer_start(&timer);
  for (int c = 0; c < 65536; c++) {
    for (ypos = 0; ypos < size; ypos += h) {
      for (xpos = 0; xpos < size; xpos += w) {
        for (strength = 0; strength < 3; strength++) {
          clpf(s, d, size, size, xpos, ypos, w, h, size, size, 1 << strength);
        }
      }
    }
  }
  aom_usec_timer_mark(&timer);
  int elapsed_time = aom_usec_timer_elapsed(&timer);

#if 0
  std::cout << "[          ] C time = " << ref_elapsed_time / 1000
            << " ms, SIMD time = " << elapsed_time / 1000 << " ms" << std::endl;
#endif

  EXPECT_GT(ref_elapsed_time, elapsed_time)
      << "Error: ClpfSpeedTest, SIMD slower than C." << std::endl
      << "C time: " << ref_elapsed_time << "ms" << std::endl
      << "SIMD time: " << elapsed_time << "ms" << std::endl;
}

using std::tr1::make_tuple;

// Test all supported architectures and block sizes
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
    SSE2, ClpfBlockTest,
    ::testing::Values(make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 8, 8),
                      make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 8, 4),
                      make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 4, 8),
                      make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 4,
                                 4)));
#endif

#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(
    SSSE3, ClpfBlockTest,
    ::testing::Values(
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 8, 8),
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 8, 4),
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 4, 8),
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 4, 4)));
#endif

#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
    SSSE4_1, ClpfBlockTest,
    ::testing::Values(
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 8, 8),
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 8, 4),
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 4, 8),
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 4, 4)));
#endif

#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(
    NEON, ClpfBlockTest,
    ::testing::Values(make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 8, 8),
                      make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 8, 4),
                      make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 4, 8),
                      make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 4,
                                 4)));
#endif

// Test speed for all supported architectures
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_sse2,
                                                     &aom_clpf_block_c, 8, 8)));
#endif

#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(SSSE3, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_ssse3,
                                                     &aom_clpf_block_c, 8, 8)));
#endif

#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(SSSE4_1, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_ssse3,
                                                     &aom_clpf_block_c, 8, 8)));
#endif

#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_neon,
                                                     &aom_clpf_block_c, 8, 8)));
#endif
}  // namespace
<commit_msg>Print correct info if CLPF unit tests fail.<commit_after>/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/

#include <cstdlib>
#include <string>

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
#include "aom_ports/aom_timer.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"

using libaom_test::ACMRandom;

namespace {

typedef void (*clpf_block_t)(const uint8_t *src, uint8_t *dst, int sstride,
                             int dstride, int x0, int y0, int sizex, int sizey,
                             int width, int height, unsigned int strength);

typedef std::tr1::tuple<clpf_block_t, clpf_block_t, int, int>
    clpf_block_param_t;

class ClpfBlockTest : public ::testing::TestWithParam<clpf_block_param_t> {
 public:
  virtual ~ClpfBlockTest() {}
  virtual void SetUp() {
    clpf = GET_PARAM(0);
    ref_clpf = GET_PARAM(1);
    sizex = GET_PARAM(2);
    sizey = GET_PARAM(3);
  }

  virtual void TearDown() { libaom_test::ClearSystemState(); }

 protected:
  int sizex;
  int sizey;
  clpf_block_t clpf;
  clpf_block_t ref_clpf;
};

typedef ClpfBlockTest ClpfSpeedTest;

TEST_P(ClpfBlockTest, TestSIMDNoMismatch) {
  int w = sizex;
  int h = sizey;
  const int size = 32;
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  DECLARE_ALIGNED(16, uint8_t, s[size * size]);
  DECLARE_ALIGNED(16, uint8_t, d[size * size]);
  DECLARE_ALIGNED(16, uint8_t, ref_d[size * size]);
  memset(ref_d, 0, size * size);
  memset(d, 0, size * size);

  int error = 0;
  int pos = 0;
  int strength = 0;
  int xpos = 0, ypos = 0;
  int bits;
  int level;

  // Test every combination of:
  // * Input with 1-8 bits of noise
  // * Noise level around every value from 0 to 255
  // * Blocks anywhere in the frame (along all egdes and also fully inside)
  // * All strengths
  for (level = 0; level < 256 && !error; level++) {
    for (bits = 1; bits < 9 && !error; bits++) {
      for (int i = 0; i < size * size; i++)
        s[i] = clamp((rnd.Rand8() & ((1 << bits) - 1)) + level, 0, 255);

      for (ypos = 0; ypos < size && !error; ypos += h * !error) {
        for (xpos = 0; xpos < size && !error; xpos += w * !error) {
          for (strength = 0; strength < 3 && !error; strength += !error) {
            ref_clpf(s, ref_d, size, size, xpos, ypos, w, h, size, size,
                     1 << strength);
            ASM_REGISTER_STATE_CHECK(clpf(s, d, size, size, xpos, ypos, w, h,
                                          size, size, 1 << strength));

            for (pos = 0; pos < size * size && !error; pos++) {
              error = ref_d[pos] != d[pos];
            }
          }
        }
      }
    }
  }

  pos--;
  EXPECT_EQ(0, error)
      << "Error: ClpfBlockTest, SIMD and C mismatch." << std::endl
      << "First error at " << pos % size << "," << pos / size << " ("
      << (int16_t)ref_d[pos] << " != " << (int16_t)d[pos] << ") " << std::endl
      << "strength: " << (1 << strength) << std::endl
      << "xpos: " << xpos << std::endl
      << "ypos: " << ypos << std::endl
      << "A=" << (pos > size ? (int16_t)s[pos - size] : -1) << std::endl
      << "B=" << (pos % size - 2 >= 0 ? (int16_t)s[pos - 2] : -1) << std::endl
      << "C=" << (pos % size - 1 >= 0 ? (int16_t)s[pos - 1] : -1) << std::endl
      << "X=" << (int16_t)s[pos] << std::endl
      << "D=" << (pos % size + 1 < size ? (int16_t)s[pos + 1] : -1) << std::endl
      << "E=" << (pos % size + 2 < size ? (int16_t)s[pos + 2] : -1) << std::endl
      << "F=" << (pos + size < size * size ? (int16_t)s[pos + size] : -1)
      << std::endl;
}

TEST_P(ClpfSpeedTest, TestSpeed) {
  int w = sizex;
  int h = sizey;
  const int size = 32;
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  DECLARE_ALIGNED(16, uint8_t, s[size * size]);
  DECLARE_ALIGNED(16, uint8_t, d[size * size]);

  int strength;
  int xpos, ypos;

  for (int i = 0; i < size * size; i++) s[i] = rnd.Rand8();

  aom_usec_timer ref_timer;
  aom_usec_timer timer;

  aom_usec_timer_start(&ref_timer);
  for (int c = 0; c < 65536; c++) {
    for (ypos = 0; ypos < size; ypos += h) {
      for (xpos = 0; xpos < size; xpos += w) {
        for (strength = 0; strength < 3; strength++) {
          ref_clpf(s, d, size, size, xpos, ypos, w, h, size, size,
                   1 << strength);
        }
      }
    }
  }
  aom_usec_timer_mark(&ref_timer);
  int ref_elapsed_time = aom_usec_timer_elapsed(&ref_timer);

  aom_usec_timer_start(&timer);
  for (int c = 0; c < 65536; c++) {
    for (ypos = 0; ypos < size; ypos += h) {
      for (xpos = 0; xpos < size; xpos += w) {
        for (strength = 0; strength < 3; strength++) {
          clpf(s, d, size, size, xpos, ypos, w, h, size, size, 1 << strength);
        }
      }
    }
  }
  aom_usec_timer_mark(&timer);
  int elapsed_time = aom_usec_timer_elapsed(&timer);

#if 0
  std::cout << "[          ] C time = " << ref_elapsed_time / 1000
            << " ms, SIMD time = " << elapsed_time / 1000 << " ms" << std::endl;
#endif

  EXPECT_GT(ref_elapsed_time, elapsed_time)
      << "Error: ClpfSpeedTest, SIMD slower than C." << std::endl
      << "C time: " << ref_elapsed_time << "ms" << std::endl
      << "SIMD time: " << elapsed_time << "ms" << std::endl;
}

using std::tr1::make_tuple;

// Test all supported architectures and block sizes
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
    SSE2, ClpfBlockTest,
    ::testing::Values(make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 8, 8),
                      make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 8, 4),
                      make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 4, 8),
                      make_tuple(&aom_clpf_block_sse2, &aom_clpf_block_c, 4,
                                 4)));
#endif

#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(
    SSSE3, ClpfBlockTest,
    ::testing::Values(
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 8, 8),
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 8, 4),
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 4, 8),
        make_tuple(&aom_clpf_block_ssse3, &aom_clpf_block_c, 4, 4)));
#endif

#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
    SSSE4_1, ClpfBlockTest,
    ::testing::Values(
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 8, 8),
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 8, 4),
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 4, 8),
        make_tuple(&aom_clpf_block_sse4_1, &aom_clpf_block_c, 4, 4)));
#endif

#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(
    NEON, ClpfBlockTest,
    ::testing::Values(make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 8, 8),
                      make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 8, 4),
                      make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 4, 8),
                      make_tuple(&aom_clpf_block_neon, &aom_clpf_block_c, 4,
                                 4)));
#endif

// Test speed for all supported architectures
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_sse2,
                                                     &aom_clpf_block_c, 8, 8)));
#endif

#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(SSSE3, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_ssse3,
                                                     &aom_clpf_block_c, 8, 8)));
#endif

#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(SSSE4_1, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_ssse3,
                                                     &aom_clpf_block_c, 8, 8)));
#endif

#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, ClpfSpeedTest,
                        ::testing::Values(make_tuple(&aom_clpf_block_neon,
                                                     &aom_clpf_block_c, 8, 8)));
#endif
}  // namespace
<|endoftext|>


<commit_before>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.
 */
#if !defined(XMLPARSERLIAISON_HEADER_GUARD_1357924680)
#define XMLPARSERLIAISON_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/XMLSupport/XMLSupportDefinitions.hpp>

#include <xalanc/XalanDOM/XalanDOMString.hpp>

XALAN_DECLARE_XERCES_CLASS(DocumentHandler)
XALAN_DECLARE_XERCES_CLASS(EntityResolver)
XALAN_DECLARE_XERCES_CLASS(ErrorHandler)
XALAN_DECLARE_XERCES_CLASS(InputSource)

XALAN_CPP_NAMESPACE_BEGIN

typedef XERCES_CPP_NAMESPACE_QUALIFIER DocumentHandler	DocumentHandlerType;
typedef XERCES_CPP_NAMESPACE_QUALIFIER EntityResolver	EntityResolverType;
typedef XERCES_CPP_NAMESPACE_QUALIFIER ErrorHandler		ErrorHandlerType;
typedef XERCES_CPP_NAMESPACE_QUALIFIER InputSource		InputSourceType;

class ExecutionContext;
class FormatterListener;
class XalanAttr;
class XalanDocument;
class XalanElement;

class XALAN_XMLSUPPORT_EXPORT XMLParserLiaison
{
public:

	XMLParserLiaison();

	virtual
	~XMLParserLiaison();

	// These interfaces are inherited from Resettable...

	virtual void
	reset() = 0;

	// These interfaces are new to XMLParserLiaison

	virtual ExecutionContext*
	getExecutionContext() const = 0;

	virtual void
	setExecutionContext(ExecutionContext&	theContext) = 0;

	/**
	 * Parse the text pointed at by the reader as XML, and return a DOM
	 * Document interface.  It is recommended that you pass in some sort of
	 * recognizable name, such as the filename or URI, with which the reader
	 * can be recognized if the parse fails.
	 *
	 * The liaison owns the XalanDocument instance, and will delete it when
	 * when asked (see DestroyDocument()), or when the liaison is reset, or
	 * goes out of scope.
	 *
	 * @param reader     stream that should hold valid XML
	 * @param identifier used for diagnostic purposes only, some sort of
	 *                   identification for error reporting, default an empty
	 *                   string
	 * @return DOM document created
	 */
	virtual XalanDocument*
	parseXMLStream(
			const InputSourceType&	inputSource,
			const XalanDOMString&	identifier = XalanDOMString()) = 0;

	/**
	 * Parse the text pointed at by the reader as XML. It is recommended that
	 * you pass in some sort of recognizable name, such as the filename or URI,
	 * with which the reader can be recognized if the parse fails.
	 *
	 * @param inputSource input source that should hold valid XML
	 * @param handler        instance of a DocumentHandler
	 * @param identifier     used for diagnostic purposes only, some sort of
	 *                       identification for error reporting, default an
	 *                       empty string
	 */
	virtual void
	parseXMLStream(
			const InputSourceType&	inputSource,
			DocumentHandlerType&	handler,
			const XalanDOMString&	identifier = XalanDOMString()) = 0;

	/**
	 * Create an empty DOM Document.  Mainly used for creating an
	 * output document.
	 *
	 * The liaison owns the XalanDocument instance, and will delete it when
	 * when asked (see DestroyDocument()), or when the liaison is reset, or
	 * goes out of scope.
	 *
	 * @return DOM document created
	 */
	virtual XalanDocument*
	createDocument() = 0;

	/**
	 * Get a factory object required to create nodes in the result tree.
	 *
	 * The liaison owns the XalanDocument instance, and will delete it when
	 * when asked (see destroyDocument()), or when the liaison is reset, or
	 * goes out of scope.
	 *
	 * @return A XalanDocument instance.
	 */
	virtual XalanDocument*
	createDOMFactory() = 0;

	/**
	 * Destroy the supplied XalanDocument instance.  It must be an instance that
	 * was created by a previous call to createDocument() or getDOMFactory().
	 *
	 * @param theDocument The XalanDocument instance to destroy.
	 */
	virtual void
	destroyDocument(XalanDocument*	theDocument) = 0;

	/**
	 * Get the amount to indent when indent-result="yes".
	 *
	 * @deprecated
	 *
	 * @return number of characters to indent
	 */
	virtual int
	getIndent() const = 0;

	/**
	 * Set the amount to indent when indent-result="yes".
	 *
	 * @deprecated
	 *
	 * @param i number of characters to indent
	 */
	virtual void
	setIndent(int	i) = 0;

	/**
	 * Get whether or not validation will be performed.  Validation is off by
	 * default.
	 *
	 * @return true to perform validation
	 */
	virtual bool
	getUseValidation() const = 0;

	/**
	 * If set to true, validation will be performed.  Validation is off by
	 * default.
	 *
	 * @param b true to perform validation
	 */
	virtual void
	setUseValidation(bool	b) = 0;

	/**
	 * Return a string suitable for telling the user what parser is being used.
	 *
	 * @return string describing parser
	 */
	virtual const XalanDOMString
	getParserDescription() const = 0;

	/**
	  * This method returns the installed entity resolver.
	  *
	  * @return The pointer to the installed entity resolver object.
	  */
	virtual EntityResolverType*
	getEntityResolver() const = 0;

	/**
	  * This method installs the user specified entity resolver on the
	  * parser. It allows applications to trap and redirect calls to
	  * external entities.
	  *
	  * @param handler A pointer to the entity resolver to be called
	  * 			   when the parser comes across references to
	  * 			   entities in the XML file.
	  */
	virtual void
	setEntityResolver(EntityResolverType*	resolver) = 0;

	/**
	  * This method returns the installed error handler.
	  *
	  * @return The pointer to the installed error handler object.
	  */
	virtual ErrorHandlerType*
	getErrorHandler() const = 0;

	/**
	  * This method installs the user-specified error handler.
	  *
	  * @param handler A pointer to the error handler to be called upon error.
	  */
	virtual void
	setErrorHandler(ErrorHandlerType*	handler) = 0;

private:

	// Not implemented
	XMLParserLiaison(const XMLParserLiaison&);

	XMLParserLiaison&
	operator=(const XMLParserLiaison&);
};

XALAN_CPP_NAMESPACE_END

#endif	// XMLPARSERLIAISON_HEADER_GUARD_1357924680
<commit_msg>Removed createDOMFactory() call, because we cannot truly support it.<commit_after>/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.
 */
#if !defined(XMLPARSERLIAISON_HEADER_GUARD_1357924680)
#define XMLPARSERLIAISON_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/XMLSupport/XMLSupportDefinitions.hpp>

#include <xalanc/XalanDOM/XalanDOMString.hpp>

XALAN_DECLARE_XERCES_CLASS(DocumentHandler)
XALAN_DECLARE_XERCES_CLASS(EntityResolver)
XALAN_DECLARE_XERCES_CLASS(ErrorHandler)
XALAN_DECLARE_XERCES_CLASS(InputSource)

XALAN_CPP_NAMESPACE_BEGIN

typedef XERCES_CPP_NAMESPACE_QUALIFIER DocumentHandler	DocumentHandlerType;
typedef XERCES_CPP_NAMESPACE_QUALIFIER EntityResolver	EntityResolverType;
typedef XERCES_CPP_NAMESPACE_QUALIFIER ErrorHandler		ErrorHandlerType;
typedef XERCES_CPP_NAMESPACE_QUALIFIER InputSource		InputSourceType;

class ExecutionContext;
class FormatterListener;
class XalanAttr;
class XalanDocument;
class XalanElement;

class XALAN_XMLSUPPORT_EXPORT XMLParserLiaison
{
public:

	XMLParserLiaison();

	virtual
	~XMLParserLiaison();

	// These interfaces are inherited from Resettable...

	virtual void
	reset() = 0;

	// These interfaces are new to XMLParserLiaison

	virtual ExecutionContext*
	getExecutionContext() const = 0;

	virtual void
	setExecutionContext(ExecutionContext&	theContext) = 0;

	/**
	 * Parse the text pointed at by the reader as XML, and return a DOM
	 * Document interface.  It is recommended that you pass in some sort of
	 * recognizable name, such as the filename or URI, with which the reader
	 * can be recognized if the parse fails.
	 *
	 * The liaison owns the XalanDocument instance, and will delete it when
	 * when asked (see DestroyDocument()), or when the liaison is reset, or
	 * goes out of scope.
	 *
	 * @param reader     stream that should hold valid XML
	 * @param identifier used for diagnostic purposes only, some sort of
	 *                   identification for error reporting, default an empty
	 *                   string
	 * @return DOM document created
	 */
	virtual XalanDocument*
	parseXMLStream(
			const InputSourceType&	inputSource,
			const XalanDOMString&	identifier = XalanDOMString()) = 0;

	/**
	 * Parse the text pointed at by the reader as XML. It is recommended that
	 * you pass in some sort of recognizable name, such as the filename or URI,
	 * with which the reader can be recognized if the parse fails.
	 *
	 * @param inputSource input source that should hold valid XML
	 * @param handler        instance of a DocumentHandler
	 * @param identifier     used for diagnostic purposes only, some sort of
	 *                       identification for error reporting, default an
	 *                       empty string
	 */
	virtual void
	parseXMLStream(
			const InputSourceType&	inputSource,
			DocumentHandlerType&	handler,
			const XalanDOMString&	identifier = XalanDOMString()) = 0;

	/**
	 * Destroy the supplied XalanDocument instance.  It must be an instance that
	 * was created by a previous call to parseXMLStream().
	 *
	 * @param theDocument The XalanDocument instance to destroy.
	 */
	virtual void
	destroyDocument(XalanDocument*	theDocument) = 0;

	/**
	 * Get the amount to indent when indent-result="yes".
	 *
	 * @deprecated
	 *
	 * @return number of characters to indent
	 */
	virtual int
	getIndent() const = 0;

	/**
	 * Set the amount to indent when indent-result="yes".
	 *
	 * @deprecated
	 *
	 * @param i number of characters to indent
	 */
	virtual void
	setIndent(int	i) = 0;

	/**
	 * Get whether or not validation will be performed.  Validation is off by
	 * default.
	 *
	 * @return true to perform validation
	 */
	virtual bool
	getUseValidation() const = 0;

	/**
	 * If set to true, validation will be performed.  Validation is off by
	 * default.
	 *
	 * @param b true to perform validation
	 */
	virtual void
	setUseValidation(bool	b) = 0;

	/**
	 * Return a string suitable for telling the user what parser is being used.
	 *
	 * @return string describing parser
	 */
	virtual const XalanDOMString
	getParserDescription() const = 0;

	/**
	  * This method returns the installed entity resolver.
	  *
	  * @return The pointer to the installed entity resolver object.
	  */
	virtual EntityResolverType*
	getEntityResolver() const = 0;

	/**
	  * This method installs the user specified entity resolver on the
	  * parser. It allows applications to trap and redirect calls to
	  * external entities.
	  *
	  * @param handler A pointer to the entity resolver to be called
	  * 			   when the parser comes across references to
	  * 			   entities in the XML file.
	  */
	virtual void
	setEntityResolver(EntityResolverType*	resolver) = 0;

	/**
	  * This method returns the installed error handler.
	  *
	  * @return The pointer to the installed error handler object.
	  */
	virtual ErrorHandlerType*
	getErrorHandler() const = 0;

	/**
	  * This method installs the user-specified error handler.
	  *
	  * @param handler A pointer to the error handler to be called upon error.
	  */
	virtual void
	setErrorHandler(ErrorHandlerType*	handler) = 0;

private:

	// Not implemented
	XMLParserLiaison(const XMLParserLiaison&);

	XMLParserLiaison&
	operator=(const XMLParserLiaison&);
};

XALAN_CPP_NAMESPACE_END

#endif	// XMLPARSERLIAISON_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>//****************************************************************************//
// Copyright 2015 MAC0431-PROJECT                                             //
//                                                                            //
// 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.                                             //
//****************************************************************************//

// C headers
#include <omp.h>

// Standard headers
#include <array>
#include <string>
#include <vector>
#include <cstdlib>
#include <fstream>
#include <iostream>

// Waves headers
#include "waves/Drop.hpp"
#include "waves/Lake.hpp"
#include "waves/Dimension.hpp"
#include "waves/WaveProperties.hpp"

int main(int argc, char **argv) {
  if (argc != 2 && argc != 3) {
    std::cerr << "USAGE: " << argv[0] << " param_file num_procs" << std::endl;
    return EXIT_FAILURE;
  }

  std::string input_file(argv[1]);
  int num_threads
    = (argc == 3 && atoi(argv[2]) <= 0) ? atoi(argv[2]) : omp_get_num_threads();

  // OpenMP initialization
  omp_set_num_threads(num_threads);

  waves::Dimension lake_dimensions;
  waves::Dimension matrix_dimensions;
  unsigned int time;
  double speed;
  double height_error;
  unsigned int num_iterations;
  double drop_probability;
  unsigned int seed;

  std::ifstream input(input_file);

  input >> lake_dimensions;
  input >> matrix_dimensions;
  input >> time;
  input >> speed;
  input >> height_error;
  input >> num_iterations;
  input >> drop_probability;
  input >> seed;

  waves::WaveProperties wave_properties(speed, height_error);

  waves::Lake lake(lake_dimensions, matrix_dimensions, wave_properties, seed);
  lake.rainFor(num_iterations, drop_probability);
  lake.printPGM(std::cout);

  return EXIT_SUCCESS;
}
<commit_msg>Rename variable to correspond to real meaning<commit_after>//****************************************************************************//
// Copyright 2015 MAC0431-PROJECT                                             //
//                                                                            //
// 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.                                             //
//****************************************************************************//

// C headers
#include <omp.h>

// Standard headers
#include <array>
#include <string>
#include <vector>
#include <cstdlib>
#include <fstream>
#include <iostream>

// Waves headers
#include "waves/Drop.hpp"
#include "waves/Lake.hpp"
#include "waves/Dimension.hpp"
#include "waves/WaveProperties.hpp"

int main(int argc, char **argv) {
  if (argc != 2 && argc != 3) {
    std::cerr << "USAGE: " << argv[0] << " param_file num_procs" << std::endl;
    return EXIT_FAILURE;
  }

  std::string input_file(argv[1]);
  int num_threads
    = (argc == 3 && atoi(argv[2]) <= 0) ? atoi(argv[2]) : omp_get_num_threads();

  // OpenMP initialization
  omp_set_num_threads(num_threads);

  waves::Dimension lake_dimensions;
  waves::Dimension matrix_dimensions;
  unsigned int time;
  double speed;
  double height_error;
  unsigned int num_iterations;
  double drop_porcentage;
  unsigned int seed;

  std::ifstream input(input_file);

  input >> lake_dimensions;
  input >> matrix_dimensions;
  input >> time;
  input >> speed;
  input >> height_error;
  input >> num_iterations;
  input >> drop_porcentage;
  input >> seed;

  waves::WaveProperties wave_properties(speed, height_error);

  waves::Lake lake(lake_dimensions, matrix_dimensions, wave_properties, seed);
  lake.rainFor(num_iterations, drop_porcentage/100);
  // lake.printPGM(std::cout);

  return EXIT_SUCCESS;
}
<|endoftext|>