diff --git a/.gitmodules b/.gitmodules index 017da1fd..7f58798a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "ocelot/hydrazine"] - path = ocelot/ThirdParty/hydrazine - url = https://github.com/gpuocelot/hydrazine.git [submodule "ocelot/ThirdParty/res_embed"] path = ocelot/ThirdParty/res_embed url = https://github.com/dmikushin/res_embed.git diff --git a/ocelot/ThirdParty/hydrazine b/ocelot/ThirdParty/hydrazine deleted file mode 160000 index 41b21fee..00000000 --- a/ocelot/ThirdParty/hydrazine +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 41b21feea2db24144e0034b88ae0556080b5030f diff --git a/ocelot/ThirdParty/hydrazine/CMakeLists.txt b/ocelot/ThirdParty/hydrazine/CMakeLists.txt new file mode 100644 index 00000000..4a61586f --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.8.12) + +project(hydrazine CXX) + +find_package(Boost COMPONENTS thread REQUIRED) +find_package(OpenGL REQUIRED) + +file(GLOB SRCS "src/*.cpp") +add_library(${PROJECT_NAME} STATIC ${SRCS}) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) +set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) +target_link_libraries(${PROJECT_NAME} Boost::thread OpenGL::GL) + +include(CTest) + +file(GLOB TESTS "test/*.cpp") +foreach(TEST ${TESTS}) + get_filename_component(TEST_WE ${TEST} NAME_WE) + set(TEST_NAME ${PROJECT_NAME}_${TEST_WE}) + add_executable(${TEST_NAME} ${TEST}) + target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) + set_property(TARGET ${TEST_NAME} PROPERTY CXX_STANDARD 11) + target_link_libraries(${TEST_NAME} ${PROJECT_NAME}) + add_test(NAME ${TEST_NAME} COMMAND $ -v) +endforeach() diff --git a/ocelot/ThirdParty/hydrazine/README.md b/ocelot/ThirdParty/hydrazine/README.md new file mode 100644 index 00000000..3e804b7f --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/README.md @@ -0,0 +1,38 @@ +# Hydrazine + +A utility library for GPUOcelot. + +## Building + +``` +mkdir build +cd build +cmake .. +make -j8 +``` + +## Testing + +``` +cd build +ctests +``` + +## Known issues + +* `TestActiveTimer` deadlocks with `-v` verbose mode enabled +* `TestBTree` crashes + +## Components + +* **Threading**: A wrapper around pthreads providing a message passing interface rather than a locking based interface. +* **Argument Parser**: A parser for command line arguments. +* **B-Tree**: A replacement for std::map implementing the complete ISO/IEC 14882:2003 standard with a Btree relying on mmapped pages. +* **Debugging**: Conditional debugging messages as well as a more informative version of assert (assert.h). +* **Timer**: Interface to high precision linux timers as well as rdtsc timers on x86 processors. +* **Active Timer**: A wrapper around pthreads providing an asynchronous split-phase interface rather than a locking interface. +* **XML Parser**: Basic parser for XML. + +## Original author + +* Gregory Daimos diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/ArgumentParser.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/ArgumentParser.h new file mode 100644 index 00000000..8ff507cc --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/ArgumentParser.h @@ -0,0 +1,328 @@ +/*! \file ArgumentParser.h + \brief Header file for The ArgumentParser class. + \author Gregory Diamos + \date : 9/27/2007 +*/ + +#ifndef ARGUMENT_PARSER_H_INCLUDED +#define ARGUMENT_PARSER_H_INCLUDED + +#define MESSAGE_OFFSET 22 +#define SCREEN_WIDTH 80 + +#include +#include +#include +#include "debug.h" +#include + +#ifdef REPORT_BASE +#undef REPORT_BASE +#endif + +#define REPORT_BASE 0 + +/*! + \brief a namespace for common classes and functions +*/ +namespace hydrazine +{ + /*! + \class ArgumentParser + \brief A class that can be used to parse arguments from argv and argc + */ + class ArgumentParser + { + private: + /*! number of strings contained in argv + */ + int argc; + /*! pointer to character array of arguments + */ + char** argv; + + /*! A string to hold the descriptions of arguments + */ + std::stringstream arguments; + /*! \brief Format a string to fit a specific length. */ + + /*! + \brief A string to hold the description of the program. + */ + std::string _description; + + private: + + /*! A function for parsing an argument + \param identifier a string used to + match strings in argv. + \param value The value to set if the identifier is found + + */ + template + void find( const std::string& identifier, T& value ); + + /*! A function determining if an argument is present + \param identifier a string used to + match strings in argv. + \return true if the identifier was found in argv false otherwise + + */ + bool isPresent(const std::string& identifier); + + /*! \brief Set the value of an arbitrary type given a string */ + template< typename T > + void setValue(T& value, const std::string& s); + + /*! \brief override the default for strings */ + void setValue(std::string& value, const std::string& s); + + public: + + /*! The constructor used to initialize an argument parser + */ + ArgumentParser(int argc, char** argv); + + /*! + + \brief Set the description for the program. + + */ + void description( const std::string& d ); + + /*! + + \brief Parse a bool from the command line + + \param identifier a string used to match + strings in argv. + \param b A bool to set to true if the argument is found, + false otherwise + \param string The help message to print out when the + help function is called + + */ + void parse(const std::string& identifier, bool& b, bool starting, + const std::string& string); + + /*! + + \brief Parse a bool from the command line + + \param identifier a string used to match + strings in argv. + \param longIdentifier A long string used to match strings in + argv. Must begin with "--". + \param b A bool to set to true if the argument is found, + false otherwise + \param string The help message to print out when the + help function is called + + */ + void parse(const std::string& identifier, + const std::string& longIdentifier, bool& b, bool starting, + const std::string& string); + + /*! + + \brief Parse an argument from the command line + + \param identifier A string used to match strings in argv. Must + be a '-' followed by a single character or blank + \param i A refernce to an argument to set to the parsed value + \param starting The value to assign to i if the identifier is + not found in argv + \param string The help message to print out when the help + function is called + + */ + template< class T, class V > + void parse(const std::string& identifier, T& i, const V& starting, + const std::string& string); + + /*! + + \brief Parse a long argument from the command line + + \param identifier A string used to match strings in argv. Must + be a '-' followed by a single character or blank + \param longIdentifier A long string used to match strings in + argv. Must begin with "--". + \param i A refernce to an argument to set to the parsed value + \param starting The value to assign to i if the identifier is + not found in argv + \param string The help message to print out when the help + function is called + + */ + template< class T, class V > + void parse(const std::string& identifier, + const std::string& longIdentifier, T& i, const V& starting, + const std::string& string); + + /*! + + \brief Create a help message describing the program. + \return A help message stored in a string. + */ + std::string help() const; + + /*! + \brief Signal that there will be no more rules added. It + is now safe to search for help messages. + */ + void parse(); + + }; + + template< typename T > + void ArgumentParser::setValue(T& value, const std::string& s) + { + std::stringstream stream(s); + stream >> value; + } + + void setValue(std::string& value, const std::string& s); + + template< typename T > + void ArgumentParser::find(const std::string& identifier, T& value) + { + std::string str; + + bool found = false; + + for(int i = 0; i < argc; i++) + { + str = argv[i]; + if( str.size() > 0 ) + { + if( str[0] == '-' ) + { + str = str.substr( 1 ); + if( str.size() > 0 ) + { + if( str[0] == '-' ) + { + str = str.substr( 1 ); + } + } + } + else + { + continue; + } + } + + report( "Searching for " << identifier << " in " << str ); + + size_t pos = str.find(identifier); + if( pos == 0 ) + { + report( " Found " << identifier ); + if( str.size() == identifier.size() ) + { + if( i < argc - 1 ) + { + found = true; + str = argv[i+1]; + report( " Setting to next value " << str ); + break; + } + } + else + { + pos = identifier.size(); + if( pos < str.size() ) + { + if( str[pos] == '=' ) + { + ++pos; + } + } + if( identifier == str ) + { + found = true; + str = str.substr( pos ); + report( " Setting to substring " << str ); + break; + } + } + } + } + + if( found ) + { + setValue(value, str); + } + + } + + template< class T, class V > + void ArgumentParser::parse(const std::string& _identifier, T& i, + const V& starting, const std::string& _string) + { + assert( _identifier.size() == 2 ); + assert( _identifier[0] == '-' ); + + i = starting; + find( _identifier.substr(1), i ); + + std::string identifier( ' ' + _identifier ); + + int prefixSpacing = MESSAGE_OFFSET - ( int )identifier.size(); + + std::string prefix( MAX( prefixSpacing, 0 ), ' ' ); + std::string regularPrefix( MESSAGE_OFFSET, ' ' ); + + std::stringstream secondStream( _string + '\n' ); + + std::string result = format( secondStream.str(), prefix, + regularPrefix, SCREEN_WIDTH ); + + std::stringstream thirdStream; + thirdStream << result << regularPrefix << "value = " << i << "\n"; + + arguments << identifier << thirdStream.str() << "\n"; + } + + template< class T, class V > + void ArgumentParser::parse(const std::string& _identifier, + const std::string& _longIdentifier, T& i, + const V& starting, const std::string& _string) + { + i = starting; + + if( !_identifier.empty() ) + { + assert( _identifier.size() == 2 ); + assert( _identifier[0] == '-' ); + find( _identifier.substr(1), i ); + } + + assert( _longIdentifier.size() > 2 ); + assert( 0 == _longIdentifier.find( "--" ) ); + + find( _longIdentifier.substr(2), i ); + + std::string identifier( ' ' + _identifier + + '(' + _longIdentifier + ')' ); + + int prefixSpacing = MESSAGE_OFFSET - ( int )identifier.size(); + + std::string prefix( MAX( prefixSpacing, 0 ), ' ' ); + std::string regularPrefix( MESSAGE_OFFSET, ' ' ); + + std::stringstream secondStream( _string + '\n' ); + + std::string result = format( secondStream.str(), prefix, + regularPrefix, SCREEN_WIDTH ); + + std::stringstream thirdStream; + thirdStream << result << regularPrefix << "value = " << i << "\n"; + + arguments << identifier << thirdStream.str() << "\n"; + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Casts.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/Casts.h new file mode 100644 index 00000000..58f74cd5 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Casts.h @@ -0,0 +1,43 @@ +/*! + \file Casts.h + \date Monday October 19, 2009 + \author Gregory Diamos + \brief The header file for a set of non-standard casts +*/ + +#ifndef CASTS_H_INCLUDED +#define CASTS_H_INCLUDED + +#include + +namespace hydrazine +{ + template< typename To, typename From > + class UnionCast + { + public: + union + { + To to; + From from; + }; + }; + + + template< typename To, typename From > + To bit_cast( const From & from ) + { + UnionCast< To, From > cast; + cast.to = 0; + cast.from = from; + return cast.to; + } + + template< typename To, typename From > + void bit_cast(To& to, const From& from) + { + to = bit_cast(from); + } +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Configurable.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/Configurable.h new file mode 100644 index 00000000..45358228 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Configurable.h @@ -0,0 +1,135 @@ +/*! + + \file Configurable.h + + \author Gregory Diamos + + \date Wednesday October 22, 2008 + + \brief The header file for the Configurable class. + +*/ + +#ifndef CONFIGURABLE_H_INCLUDED +#define CONFIGURABLE_H_INCLUDED + +#include +#include +#include + +#include + +#ifdef REPORT_BASE +#undef REPORT_BASE +#endif + +#define REPORT_BASE 0 + +namespace hydrazine +{ + + /*! + + \brief A class that can be configured via a map from parameter names + to values. + + */ + class Configurable + { + + public: + + /*! + + \brief A configuration is a map from identifiers to values. + + */ + typedef std::map< std::string, std::string > Configuration; + + protected: + + /*! + + \brief Parse a value from a configuration. + + \param identifier The identifier to search for in the + Configuration + + \param defaultValue The value to set if the identifier is not + found in the map. + + \param value The value to set. + + \param configuration The Configuration to look for the + identifier in. + + */ + template< class T, class V > + void parse( const std::string& identifier, T& value, + const V& defaultValue, const Configuration& configuration ); + + void parseString( const std::string& identifier, std::string& value, + const std::string& defaultValue, + const Configuration& configuration ); + + + public: + + /*! + + \brief Convert a configuration to a string. + + */ + static std::string toString( const Configuration& configuration ); + + public: + + /*! + + \brief Virtual destructor + + */ + virtual ~Configurable() {} + + /*! + + \brief Configure the class from a specified Configuration. + + \param configuration The specified Configuration. + + */ + virtual void configure( const Configuration& configuration ) = 0; + + }; + + template< class T, class V > + void Configurable::parse( const std::string& identifier, T& value, + const V& defaultValue, + const Configurable::Configuration& configuration ) + { + + Configuration::const_iterator fi = configuration.find( identifier ); + + if( fi != configuration.end() ) + { + + report( "Found parameter " << fi->first << " set to " + << fi->second ); + std::stringstream stream( fi->second ); + stream >> value; + + } + else + { + + report( "Did not find parameter " << identifier << " set to " + << defaultValue ); + value = defaultValue; + + } + + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/ELF.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/ELF.h new file mode 100644 index 00000000..a365a67c --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/ELF.h @@ -0,0 +1,388 @@ +/* \file ELF.h + \author Gregory Diamos + \date Thursday March 17, 2011 + \brief The header file containing ELF file definitions. + + See the document 'ELF-64 Object File Format Version 1.5 Draft 2 (May 1998)' + for details. +*/ + +#ifndef ELF_H_INCLUDED +#define ELF_H_INCLUDED + +namespace hydrazine +{ + +/*! \brief A namespace for ELF file types */ +namespace elf +{ + +// basic types +typedef int int32; +typedef unsigned int uint32; +typedef long long int int64; +typedef long long unsigned int uint64; +typedef unsigned short uint16; + +typedef uint32 Elf32_Addr; // Program address +typedef uint16 Elf32_Half; +typedef uint32 Elf32_Off; // File offset +typedef int32 Elf32_Sword; +typedef uint32 Elf32_Word; + +typedef uint64 Elf64_Addr; +typedef uint64 Elf64_Off; +typedef int32 Elf64_Sword; +typedef uint32 Elf64_Word; +typedef int64 Elf64_Sxword; +typedef uint64 Elf64_Xword; +typedef uint16 Elf64_Half; + +// Object file magic string. +static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' }; + +// e_ident size and indices. +enum { + EI_MAG0 = 0, // File identification index. + EI_MAG1 = 1, // File identification index. + EI_MAG2 = 2, // File identification index. + EI_MAG3 = 3, // File identification index. + EI_CLASS = 4, // File class. + EI_DATA = 5, // Data encoding. + EI_VERSION = 6, // File version. + EI_OSABI = 7, // OS/ABI identification. + EI_ABIVERSION = 8, // ABI version. + EI_PAD = 9, // Start of padding bytes. + EI_NIDENT = 16 // Number of bytes in e_ident. +}; + +struct Elf32_Ehdr { + unsigned char e_ident[EI_NIDENT]; // ELF Identification bytes + Elf32_Half e_type; // Type of file (see ET_* below) + Elf32_Half e_machine; // Machine architecture + Elf32_Word e_version; // ELF Version (1 is supported) + Elf32_Addr e_entry; // Address to jump to in order to start program + Elf32_Off e_phoff; // Program header table's file offset, in bytes + Elf32_Off e_shoff; // Section header table's file offset, in bytes + Elf32_Word e_flags; // Processor-specific flags + Elf32_Half e_ehsize; // Size of ELF header, in bytes + Elf32_Half e_phentsize; // Size of an entry in the program header table + Elf32_Half e_phnum; // Number of entries in the program header table + Elf32_Half e_shentsize; // Size of an entry in the section header table + Elf32_Half e_shnum; // Number of entries in the section header table + Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table +}; + +// 64-bit ELF header. Fields are the same as for ELF32, but with different +// types (see above). +struct Elf64_Ehdr { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +}; + +// File types +enum { + ET_NONE = 0, // No file type + ET_REL = 1, // Relocatable file + ET_EXEC = 2, // Executable file + ET_DYN = 3, // Shared object file + ET_CORE = 4, // Core file + ET_LOPROC = 0xff00, // Beginning of processor-specific codes + ET_HIPROC = 0xffff // Processor-specific +}; + +// Versioning +enum { + EV_NONE = 0, + EV_CURRENT = 1 +}; + +// Object file classes. +enum { + ELFCLASSNONE = 0, + ELFCLASS32 = 1, // 32-bit object file + ELFCLASS64 = 2 // 64-bit object file +}; + +// Object file byte orderings. +enum { + ELFDATANONE = 0, // Invalid data encoding. + ELFDATA2LSB = 1, // Little-endian object file + ELFDATA2MSB = 2 // Big-endian object file +}; + +// Section header for ELF32 +struct Elf32_Shdr { + Elf32_Word sh_name; // Section name (index into string table) + Elf32_Word sh_type; // Section type (SHT_*) + Elf32_Word sh_flags; // Section flags (SHF_*) + Elf32_Addr sh_addr; // Address where section is to be loaded + Elf32_Off sh_offset; // File offset of section data, in bytes + Elf32_Word sh_size; // Size of section, in bytes + Elf32_Word sh_link; // Section type-specific header table index link + Elf32_Word sh_info; // Section type-specific extra information + Elf32_Word sh_addralign; // Section address alignment + Elf32_Word sh_entsize; // Size of records contained within the section +}; + +// Section header for ELF64 +struct Elf64_Shdr { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +}; + +// Special section indices. +enum { + SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless + SHN_LORESERVE = 0xff00, // Lowest reserved index + SHN_LOPROC = 0xff00, // Lowest processor-specific index + SHN_HIPROC = 0xff1f, // Highest processor-specific index + SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation + SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables + SHN_XINDEX = 0xffff, // Mark that the index is >= SHN_LORESERVE + SHN_HIRESERVE = 0xffff // Highest reserved index +}; + +// Section types. +enum { + SHT_NULL = 0, // No associated section (inactive entry). + SHT_PROGBITS = 1, // Program-defined contents. + SHT_SYMTAB = 2, // Symbol table. + SHT_STRTAB = 3, // String table. + SHT_RELA = 4, // Relocation entries; explicit addends. + SHT_HASH = 5, // Symbol hash table. + SHT_DYNAMIC = 6, // Information for dynamic linking. + SHT_NOTE = 7, // Information about the file. + SHT_NOBITS = 8, // Data occupies no space in the file. + SHT_REL = 9, // Relocation entries; no explicit addends. + SHT_SHLIB = 10, // Reserved. + SHT_DYNSYM = 11, // Symbol table. + SHT_INIT_ARRAY = 14, // Pointers to initialisation functions. + SHT_FINI_ARRAY = 15, // Pointers to termination functions. + SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions. + SHT_GROUP = 17, // Section group. + SHT_SYMTAB_SHNDX = 18, // Indicies for SHN_XINDEX entries. + //SHT_LOOS = 0x60000000, // Lowest operating system-specific type. + //SHT_HIOS = 0x6fffffff, // Highest operating system-specific type. + //SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type. + //SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type. + //SHT_LOUSER = 0x80000000, // Lowest type reserved for applications. + //SHT_HIUSER = 0xffffffff // Highest type reserved for applications. + SHT_LOOS = 19, // Lowest operating system-specific type. + SHT_HIOS = 20, // Highest operating system-specific type. + SHT_LOPROC = 21, // Lowest processor architecture-specific type. + SHT_HIPROC = 22, // Highest processor architecture-specific type. + SHT_LOUSER = 23, // Lowest type reserved for applications. + SHT_HIUSER = 24 // Highest type reserved for applications. +}; + +// Section flags. +enum { + // Section data should be writable during execution. + SHF_WRITE = 0x1, + + // Section occupies memory during program execution. + SHF_ALLOC = 0x2, + + // Section contains executable machine instructions. + SHF_EXECINSTR = 0x4 +}; + +// Symbol table entries for ELF32. +struct Elf32_Sym { + Elf32_Word st_name; // Symbol name (index into string table) + Elf32_Addr st_value; // Value or address associated with the symbol + Elf32_Word st_size; // Size of the symbol + unsigned char st_info; // Symbol's type and binding attributes + unsigned char st_other; // Must be zero; reserved + Elf32_Half st_shndx; // Which section (header table index) it's defined in +}; + +// Symbol table entries for ELF64. +struct Elf64_Sym { + Elf64_Word st_name; // Symbol name (index into string table) + unsigned char st_info; // Symbol's type and binding attributes + unsigned char st_other; // Must be zero; reserved + Elf64_Half st_shndx; // Which section (header table index) it's defined in + Elf64_Addr st_value; // Value or address associated with the symbol + Elf64_Xword st_size; // Size of the symbol +}; + +// Symbol bindings. +enum { + STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def + STB_GLOBAL = 1, // Global symbol, visible to all object files being combined + STB_WEAK = 2, // Weak symbol, like global but lower-precedence + STB_LOPROC = 13, // Lowest processor-specific binding type + STB_HIPROC = 15 // Highest processor-specific binding type +}; + +// Symbol types. +enum { + STT_NOTYPE = 0, // Symbol's type is not specified + STT_OBJECT = 1, // Symbol is a data object (variable, array, etc.) + STT_FUNC = 2, // Symbol is executable code (function, etc.) + STT_SECTION = 3, // Symbol refers to a section + STT_FILE = 4, // Local, absolute symbol that refers to a file + STT_LOPROC = 13, // Lowest processor-specific symbol type + STT_HIPROC = 15 // Highest processor-specific symbol type +}; + +// Relocation entry, without explicit addend. +struct Elf32_Rel { + Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf32_Word r_info; // Symbol table index and type of relocation to apply +}; + +// Relocation entry with explicit addend. +struct Elf32_Rela { + Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf32_Word r_info; // Symbol table index and type of relocation to apply + Elf32_Sword r_addend; // Compute value for relocatable field by adding this +}; + +// Relocation entry, without explicit addend. +struct Elf64_Rel { + Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr). + Elf64_Xword r_info; // Symbol table index and type of relocation to apply. +}; + +// Relocation entry with explicit addend. +struct Elf64_Rela { + Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr). + Elf64_Xword r_info; // Symbol table index and type of relocation to apply. + Elf64_Sxword r_addend; // Compute value for relocatable field by adding this. +}; + +// Program header for ELF32. +struct Elf32_Phdr { + Elf32_Word p_type; // Type of segment + Elf32_Off p_offset; // File offset where segment is located, in bytes + Elf32_Addr p_vaddr; // Virtual address of beginning of segment + Elf32_Addr p_paddr; // Physical address of beginning of segment (OS-specific) + Elf32_Word p_filesz; // Num. of bytes in file image of segment (may be zero) + Elf32_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) + Elf32_Word p_flags; // Segment flags + Elf32_Word p_align; // Segment alignment constraint +}; + +// Program header for ELF64. +struct Elf64_Phdr { + Elf64_Word p_type; // Type of segment + Elf64_Word p_flags; // Segment flags + Elf64_Off p_offset; // File offset where segment is located, in bytes + Elf64_Addr p_vaddr; // Virtual address of beginning of segment + Elf64_Addr p_paddr; // Physical address of beginning of segment (OS-specific) + Elf64_Xword p_filesz; // Num. of bytes in file image of segment (may be zero) + Elf64_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero) + Elf64_Xword p_align; // Segment alignment constraint +}; + +// Segment types. +enum { + PT_NULL = 0, // Unused segment. + PT_LOAD = 1, // Loadable segment. + PT_DYNAMIC = 2, // Dynamic linking information. + PT_INTERP = 3, // Interpreter pathname. + PT_NOTE = 4, // Note sections. + PT_SHLIB = 5, // Reserved. + PT_PHDR = 6, // The program header table itself. + PT_LOOS = 0x60000000, // env specific use. + PT_HIOS = 0x6fffffff, // env specific use. + PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type. + PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type. +}; + +// Segment flag bits. +enum { + PF_X = 1, // Execute + PF_W = 2, // Write + PF_R = 4, // Read + PF_MASKOS = 0x00ff0000, // Unspecified + PF_MASKPROC = 0xff000000 // Unspecified +}; + +// Dynamic table entry for ELF32. +struct Elf32_Dyn +{ + Elf32_Sword d_tag; // Type of dynamic table entry. + union + { + Elf32_Word d_val; // Integer value of entry. + Elf32_Addr d_ptr; // Pointer value of entry. + } d_un; +}; + +// Dynamic table entry for ELF64. +struct Elf64_Dyn +{ + Elf64_Sxword d_tag; // Type of dynamic table entry. + union + { + Elf64_Xword d_val; // Integer value of entry. + Elf64_Addr d_ptr; // Pointer value of entry. + } d_un; +}; + +// Dynamic table entry tags. +enum { + DT_NULL = 0, // Marks end of dynamic array. + DT_NEEDED = 1, // String table offset of needed library. + DT_PLTRELSZ = 2, // Size of relocation entries in PLT. + DT_PLTGOT = 3, // Address associated with linkage table. + DT_HASH = 4, // Address of symbolic hash table. + DT_STRTAB = 5, // Address of dynamic string table. + DT_SYMTAB = 6, // Address of dynamic symbol table. + DT_RELA = 7, // Address of relocation table (Rela entries). + DT_RELASZ = 8, // Size of Rela relocation table. + DT_RELAENT = 9, // Size of a Rela relocation entry. + DT_STRSZ = 10, // Total size of the string table. + DT_SYMENT = 11, // Size of a symbol table entry. + DT_INIT = 12, // Address of initialization function. + DT_FINI = 13, // Address of termination function. + DT_SONAME = 14, // String table offset of a shared objects name. + DT_RPATH = 15, // String table offset of library search path. + DT_SYMBOLIC = 16, // Changes symbol resolution algorithm. + DT_REL = 17, // Address of relocation table (Rel entries). + DT_RELSZ = 18, // Size of Rel relocation table. + DT_RELENT = 19, // Size of a Rel relocation entry. + DT_PLTREL = 20, // Type of relocation entry used for linking. + DT_DEBUG = 21, // Reserved for debugger. + DT_TEXTREL = 22, // Relocations exist for non-writable segements. + DT_JMPREL = 23, // Address of relocations associated with PLT. + DT_BIND_NOW = 24, // Process all relocations before execution. + DT_INIT_ARRAY = 25, // Pointer to array of initialization functions. + DT_FINI_ARRAY = 26, // Pointer to array of termination functions. + DT_INIT_ARRAYSZ = 27, // Size of DT_INIT_ARRAY. + DT_FINI_ARRAYSZ = 28, // Size of DT_FINI_ARRAY. + DT_LOOS = 0x60000000, // Start of environment specific tags. + DT_HIOS = 0x6FFFFFFF, // End of environment specific tags. + DT_LOPROC = 0x70000000, // Start of processor specific tags. + DT_HIPROC = 0x7FFFFFFF // End of processor specific tags. +}; + +} // end elf + +} // end hydrazine + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/ELFFile.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/ELFFile.h new file mode 100644 index 00000000..47c49bae --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/ELFFile.h @@ -0,0 +1,204 @@ +/* \file ELFFile.h + \author Gregory Diamos + \date Thursday March 17, 2011 + \brief The header file for the ELFFile class. +*/ + +#ifndef ELF_FILE_H_INCLUDED +#define ELF_FILE_H_INCLUDED + +// Hydrazine Includes +#include + +// Standard Library Includes +#include +#include + +namespace hydrazine +{ + +/*! \brief A class for parsing and interpretting an ELF file */ +class ELFFile +{ +public: + /*! \brief Represents the ELF file header */ + class Header + { + public: + /*! \brief Create a new header from a header data struct */ + Header(const void* data = 0, + const elf::Elf64_Ehdr& header = elf::Elf64_Ehdr()); + + public: + /*! \brief Get access to the raw header data */ + const elf::Elf64_Ehdr& header() const; + + /*! \brief Does the magic word agree that this is an ELF binary? */ + bool checkMagic() const; + + public: + /*! \brief Easier access to the underlying data (section count) */ + unsigned int sectionHeaders() const; + + /*! \brief Easier access to the underlying data (program count) */ + unsigned int programHeaders() const; + + private: + /*! \brief The raw data */ + elf::Elf64_Ehdr _header; + }; + + /*! \brief A header for a symbol table entry */ + class SymbolHeader + { + public: + SymbolHeader(const void* data = 0, long long unsigned int byte = 0, + const elf::Elf64_Sym& header = elf::Elf64_Sym()); + + public: + /*! \brief Get access to the raw header data */ + const elf::Elf64_Sym& header() const; + + public: + /*! \brief Get the type */ + int type() const; + + private: + /*! \brief The raw header data */ + elf::Elf64_Sym _header; + }; + + /*! \brief Represents an ELF section header */ + class SectionHeader + { + public: + SectionHeader(const void* data = 0, long long unsigned int byte = 0, + const elf::Elf64_Shdr& header = elf::Elf64_Shdr()); + + public: + /*! \brief Get access to the raw header data */ + const elf::Elf64_Shdr& header() const; + + private: + /*! \brief The raw header data */ + elf::Elf64_Shdr _header; + }; + + /*! \brief Represents an ELF section header */ + class ProgramHeader + { + public: + ProgramHeader(const void* data = 0, long long unsigned int byte = 0, + const elf::Elf64_Phdr& header = elf::Elf64_Phdr()); + + public: + /*! \brief Get access to the raw header data */ + const elf::Elf64_Phdr& header() const; + + private: + /*! \brief The raw header data */ + elf::Elf64_Phdr _header; + + }; + +public: + /*! \brief Create a new ELF, bind it to a mmapped or in-memory file */ + ELFFile(const void* fileData = 0); + +public: + /*! \brief Get a reference to the header */ + const Header& header() const; + +public: + /*! \brief Get the number of sections in the ELF file */ + unsigned int sections() const; + /*! \brief Get a specific section header */ + SectionHeader& sectionHeader(unsigned int header); + +public: + /*! \brief Get the number of program headers in the ELF file */ + unsigned int programs() const; + /*! \brief Get a specific program header */ + ProgramHeader& programHeader(unsigned int header); + +public: + /*! \brief Get end of the elf file */ + const void* endOfFile(); + +public: + /*! \brief Get the number of non-null symbols in the ELF file */ + unsigned int symbols(); + /*! \brief Get a specific symbol header (the null symbol is skipped) */ + SymbolHeader& symbolHeader(unsigned int header); + +public: + /*! \brief Get access to a string within the string table (in range) */ + const char* getSectionHeaderStringAtOffset(long long unsigned int offset); + /*! \brief Get access to a string within the string table (in range) */ + const char* getSymbolStringAtOffset(long long unsigned int offset); + +public: + /*! \brief Write out the elf file in a human-readale format */ + void write(std::ostream& stream); + +public: + /*! \brief Get a string representation of a program type */ + static std::string programTypeToString(int type); + /*! \brief Get a string representation of a section type */ + static std::string sectionTypeToString(int type); + /*! \brief Does this section type have a link? */ + static bool sectionTypeHasLink(int type); + /*! \brief Get a string representation of a section linkage */ + static std::string sectionLinkToString(int type); + /*! \brief Get a string representation of a symbol type */ + static std::string symbolTypeToString(int type); + +private: + /*! \brief A vector of section headers */ + typedef std::vector SectionHeaderVector; + /*! \brief A vector of program headers */ + typedef std::vector ProgramHeaderVector; + /*! \brief A vector of program headers */ + typedef std::vector SymbolHeaderVector; + /*! \brief A vector of program headers */ + typedef std::vector BitVector; + +private: + /*! \brief Load a program from the header table at the given index */ + void _loadProgram(unsigned int header); + /*! \brief Load a section from the header table at the given index */ + void _loadSection(unsigned int header); + /*! \brief Load a symbol from the symbol table at the given index */ + void _loadSymbol(unsigned int header); + /*! \brief Find the symbol table, set the value of the offset */ + void _findSymbolTable(); + +private: + /*! \brief A reference to the file data for lazy access */ + const void* _elfdata; + /*! \brief The ELF file header */ + Header _header; + /*! \brief The set of sections in the file */ + SectionHeaderVector _sections; + /*! \brief The set of programs in the file */ + ProgramHeaderVector _programs; + /*! \brief Keeps track of the program headers that have been loaded */ + BitVector _loadedPrograms; + /*! \brief Keeps track of the program headers that have been loaded */ + BitVector _loadedSections; + /*! \brief The symbol table */ + SymbolHeaderVector _symbols; + /*! \brief A vector of symbol headers */ + BitVector _loadedSymbols; + /*! \brief The symbol table offset or -1 if unknown */ + long long unsigned int _symbolTableOffset; + /*! \brief The string table for the symbol table */ + long long unsigned int _symbolStringTableOffset; + +}; + +} + +std::ostream& operator<<(std::ostream& out, hydrazine::ELFFile& elf); + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Exception.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/Exception.h new file mode 100644 index 00000000..337285de --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Exception.h @@ -0,0 +1,30 @@ +/*! \file Exception.h + \brief Header file for the Exception class. + \author Gregory Diamos +*/ + +#ifndef EXCEPTION_H_INCLUDED +#define EXCEPTION_H_INCLUDED + +// Standard Library Includes +#include +#include + + +/*! \brief a namespace for common classes and functions */ +namespace hydrazine +{ + /*! \brief An Exception with a variable message */ + class Exception : public std::exception + { + public: + Exception( const std::string& message ); + virtual ~Exception() throw(); + virtual const char* what() const throw(); + + private: + std::string _message; + }; +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/FloatingPoint.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/FloatingPoint.h new file mode 100644 index 00000000..46277b69 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/FloatingPoint.h @@ -0,0 +1,54 @@ +/*! \file FloatingPoint.h + \date Friday August 26, 2011 + \author Gregory Diamos + \brief The header file for platform independent floating point modifiers. +*/ + +#ifndef FLOATING_POINT_H_INCLUDED +#define FLOATING_POINT_H_INCLUDED + +#ifndef _WIN32 +#include +#else + +#define FE_TONEAREST 0 +#define FE_TOWARDZERO 0 +#define FE_DOWNWARD 0 +#define FE_UPWARD 0 + +#endif + + +namespace hydrazine +{ + /*! \brief Get the current floating point rounding mode */ + int fegetround(); + /*! \brief Set the current floating point rounding mode */ + int fesetround(int value); + + /*! \brief Copy the sign */ + float copysign(float value, float sign); + + /*! \brief Is the value not a number? */ + bool isnan(float value); + /*! \brief Is the value infinite? */ + bool isinf(float value); + /*! \brief Is the value normal? */ + bool isnormal(float value); + + /*! \brief Round to nearest int */ + float nearbyintf(float value); + /*! \brief Round to nearest int */ + double nearbyintf(double value); + /*! \brief Round to negative infinity */ + float trunc(float value); + /*! \brief Round to negative infinity */ + double trunc(double value); + + /*! \brief two to the power of */ + float exp2f(float value); + /*! \brief log base 2 */ + float log2f(float value); +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Iterator.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/Iterator.h new file mode 100644 index 00000000..84379355 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Iterator.h @@ -0,0 +1,281 @@ +/*! + \file Iterator.h + \date Tuesday March 12, 2009 + \author Gregory Diamos + \brief Header file for Iterator classes and concepts +*/ + +#ifndef ITERATOR_H_INCLUDED +#define ITERATOR_H_INCLUDED + +#include + +namespace hydrazine +{ + + + /*! + \brief Define typedefs for iterator classes + */ + template< typename Category, typename T, typename Distance, + typename Pointer, typename Reference > + struct Iterator + { + //! Concept + typedef Category iterator_category; + //! The type "pointed to" by the iterator. + typedef T value_type; + //! Distance between iterators is represented as this type. + typedef Distance difference_type; + //! This type represents a pointer-to-value_type. + typedef Pointer pointer; + //! This type represents a reference-to-value_type. + typedef Reference reference; + }; + + /*! + \brief A class for specializing pointer and reference types + */ + template< typename Pointer > + struct IteratorTraits + { + typedef typename Pointer::iterator_category iterator_category; + typedef typename Pointer::value_type value_type; + typedef typename Pointer::difference_type difference_type; + typedef typename Pointer::pointer pointer; + typedef typename Pointer::reference reference; + }; + + template< typename T > + struct IteratorTraits< T* > + { + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef T& reference; + }; + + template< typename T > + struct IteratorTraits< const T* > + { + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const T* pointer; + typedef const T& reference; + }; + + /*! + \brief A generic iterator class wrapper for iterators derived from + pointers. + + Container is here so that different iterator types get instantiated + for containers using the same underlying pointer as in GCC-4.3.3 + */ + template< typename Type, typename Container > + class PointerIterator + { + protected: + Type _current; + + public: + typedef Type iterator_type; + typedef typename IteratorTraits< Type >::iterator_category + iterator_category; + typedef typename IteratorTraits< Type >::value_type value_type; + typedef typename IteratorTraits< Type >::difference_type + difference_type; + typedef typename IteratorTraits< Type >::pointer pointer; + typedef typename IteratorTraits< Type >::reference reference; + + public: + PointerIterator() : _current( Type() ) {} + + explicit PointerIterator( const Type& it ) : _current( it ) + {} + + template< typename _Assignee > + PointerIterator( const PointerIterator< _Assignee, + typename Container::type >& it ) : _current( it.base() ) + { + + } + + reference operator*() const + { + return *_current; + } + + pointer operator->() const + { + return _current; + } + + PointerIterator& operator++() + { + ++_current; + return *this; + } + + PointerIterator operator++( int ) + { + return PointerIterator( _current++ ); + } + + PointerIterator& operator--() + { + --_current; + return *this; + } + + PointerIterator operator--( int ) + { + return PointerIterator( _current-- ); + } + + reference operator[]( const difference_type& n ) + { + return _current[ n ]; + } + + PointerIterator& operator+=( const difference_type& n ) + { + _current += n; + return *this; + } + + PointerIterator operator+( const difference_type& n ) + { + return PointerIterator( _current + n ); + } + + PointerIterator& operator-=( const difference_type& n ) + { + _current -= n; + return *this; + } + + PointerIterator operator-( const difference_type& n ) + { + return PointerIterator( _current - n ); + } + + const Type& base() const + { + return _current; + } + + }; + + template + inline bool operator==(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() == right.base(); + } + + template + inline bool operator==(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() == right.base(); + } + + template + inline bool operator!=(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() != right.base(); + } + + template + inline bool operator!=(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() != right.base(); + } + + template + inline bool operator<(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() < right.base(); + } + + template + inline bool operator<(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() < right.base(); + } + + template + inline bool operator>(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() > right.base(); + } + + template + inline bool operator>(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() > right.base(); + } + + template + inline bool operator<=(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() <= right.base(); + } + + template + inline bool operator<=(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() <= right.base(); + } + + template + inline bool operator>=(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() >= right.base(); + } + + template + inline bool operator>=(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() >= right.base(); + } + + template + inline typename PointerIterator::difference_type + operator-(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() - right.base(); + } + + template + inline typename PointerIterator::difference_type + operator-(const PointerIterator& left, + const PointerIterator& right) + { + return left.base() - right.base(); + } + + template + inline PointerIterator + operator+(typename PointerIterator::difference_type + n, const PointerIterator& it ) + { + return PointerIterator( it.base() + n ); + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/LowLevelTimer.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/LowLevelTimer.h new file mode 100644 index 00000000..894ea44a --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/LowLevelTimer.h @@ -0,0 +1,113 @@ +/*! \file LowLevelTimer.h + \brief Header file for the LowLevelTimer set of functions + \author Gregory Diamos + \date : Monday May 4, 2009 +*/ + +#ifndef LOW_LEVEL_TIMER_H_INCLUDED +#define LOW_LEVEL_TIMER_H_INCLUDED + +#include + +#ifndef TIMER_SMALL_SECOND + #define TIMER_SMALL_SECOND DBL_MIN +#endif + +#ifndef TIMER_LARGE_SECOND + #define TIMER_LARGE_SECOND DBL_MAX +#endif + +#ifndef TIMER_SMALL_SECOND + #define TIMER_SMALL_SECOND 5e-324 +#endif + +#ifndef TIMER_LARGE_SECOND + #define TIMER_LARGE_SECOND 5e324 +#endif + +#include + +namespace hydrazine +{ + + class LowLevelTimer + { + public: + /*! \brief A type for seconds */ + typedef double Second; + + /*! \brief A type for representing clock ticks */ + typedef long long unsigned Cycle; + + private: + /*! An integer representing the value of the cycle counter when the + last start() function was called + */ + Cycle beginning; + + /*! An integer representing the value of the cycle counter when the + last stop() function was called + */ + Cycle ending; + + /*! A floating point number representing the value of the system + clock when the last start() function was called + */ + Second beginningS; + + /*! A floating point number representing the value of the system + clock when the last stop() function was called + */ + Second endingS; + + /*! Read a cycle counter using either assembly or an OS interface. + \return a 64 bit value representing the current number of + clock cycles since the last reset + */ + static Cycle rdtsc(); + + /*! \brief Is the Timer running? */ + bool running; + + public: + + /*! \brief The constructor initializes the private variables + and makes sure that the Timer is not running. + */ + LowLevelTimer(); + + /*! A function that is used to set beginning to the value of + the hardware Timer + */ + void start(); + + /*! A function that is used to set ending to the value of + the hardware Timer + */ + void stop(); + + /*! A function that is used to determine the number of clock cycles + between the last time start was called and the last time that + end was called. + \return the difference between ending and beginning + */ + Cycle cycles() const; + + /*! A function that is used to determine the number of seconds + between the last time start was called and the last time that + end was called. + \return the difference between ending and beginning + */ + Second seconds() const; + + /*! \brief Get the absolute number of seconds elapsed since system + start + \return That time + */ + Second absolute() const; + + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/MetaProgramming.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/MetaProgramming.h new file mode 100644 index 00000000..1515c331 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/MetaProgramming.h @@ -0,0 +1,80 @@ +/*! \file MetaProgramming.h + \date Thursday May 27, 2010 + \author Gregory Diamos + \brief The header file for template meta programming related classes +*/ + +#ifndef META_PROGRAMMING_H_INCLUDED +#define META_PROGRAMMING_H_INCLUDED + +#include + +namespace hydrazine +{ + +/*! \brief Convert a signed type to an unsigned type */ +template +class SignedToUnsigned +{ + public: + typedef T type; +}; + +template<> +class SignedToUnsigned +{ + public: + typedef uint8_t type; +}; + +template<> +class SignedToUnsigned +{ + public: + typedef uint16_t type; +}; + +template<> +class SignedToUnsigned +{ + public: + typedef uint32_t type; +}; + +template<> +class SignedToUnsigned +{ + public: + typedef uint64_t type; +}; + +/*! \brief Determine if an integer type is negative */ +template +bool isNegative(T t) +{ + return t < 0; +} + +inline bool isNegative(unsigned char) +{ + return false; +} + +inline bool isNegative(unsigned short) +{ + return false; +} + +inline bool isNegative(unsigned int) +{ + return false; +} + +inline bool isNegative(long long unsigned int) +{ + return false; +} + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/MmapAllocator.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/MmapAllocator.h new file mode 100644 index 00000000..699fe9d6 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/MmapAllocator.h @@ -0,0 +1,99 @@ +/*! + \file MmapAllocator.h + \date Wednesday May 13, 2009 + \author Gregory Diamos + \brief The header file for the MmapAllocator class +*/ + +#ifndef MMAP_ALLOCATOR_H_INCLUDED +#define MMAP_ALLOCATOR_H_INCLUDED + +#include +#include + +namespace hydrazine +{ + /*! + \brief An allocator that draws from blocks of file backed memory + */ + template< typename T > + class MmapAllocator + { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + + public: + template< typename NewT > + struct rebind + { + typedef MmapAllocator< NewT > other; + }; + + MmapAllocator() throw() {} + MmapAllocator( const MmapAllocator& ) throw() {} + + template< typename SomeT > + MmapAllocator( const MmapAllocator< SomeT >& ) throw() {} + + ~MmapAllocator() throw() {} + + pointer address( reference r ) { return &r; } + const_pointer address( const_reference r ) { return &r; } + + pointer allocate( size_type n, const void* = 0 ) + { + if( n > max_size() ) + { + throw std::bad_alloc(); + } + return static_cast< pointer >( mmap( 0, + n * sizeof( value_type ), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 ) ); + } + + void deallocate( pointer p, size_type s ) + { + munmap( p, s * sizeof( value_type ) ); + } + + size_type max_size() const throw() + { + return size_type( -1 ) / sizeof( value_type ); + } + + void construct( pointer p, const_reference val ) + { + ::new(p) value_type( val ); + } + + void destroy( pointer p ) + { + p->~value_type(); + } + + }; + + template< typename T > + inline bool operator==( const MmapAllocator< T >&, + const MmapAllocator< T >& ) + { + return true; + } + + template< typename T > + inline bool operator!=( const MmapAllocator< T >&, + const MmapAllocator< T >& ) + { + return false; + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/StatisticDatabase.cpp b/ocelot/ThirdParty/hydrazine/include/hydrazine/StatisticDatabase.cpp new file mode 100644 index 00000000..924934f7 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/StatisticDatabase.cpp @@ -0,0 +1,226 @@ +/*! + \file StatisticDatabase.cpp + + \author Gregory Diamos + \date Saturday March 28, 2009 + + \brief The source file for the StatisticDatabase class +*/ + +#ifndef STATISTIC_DATABSE_CPP_INCLUDED +#define STATISTIC_DATABSE_CPP_INCLUDED + +#include +#include +#include +#include + +#ifdef REPORT_BASE +#undef REPORT_BASE +#endif + +#define REPORT_BASE 0 + +namespace hydrazine +{ + + StatisticDatabase::Statistic::Statistic( Type _type, Id _id ) : + type( _type ), id( _id ) + { + + } + + StatisticDatabase::Statistic::~Statistic() + { + + } + + void StatisticDatabase::Statistic::aggregate( const Statistic& ) + { + + } + + hydrazine::StatisticDatabase::Statistic* + StatisticDatabase::Statistic::clone( bool copy ) const + { + + return new Statistic( type, id ); + + } + + std::string StatisticDatabase::Statistic::toString() const + { + return ""; + } + + StatisticDatabase::Generator::Generator( StatisticDatabase& database ) : + _database( database ), _databaseRegistered( &database != 0 ) + { + + } + + StatisticDatabase::IdMap StatisticDatabase::_emptyMap; + + StatisticDatabase::StatisticDatabase() + { + + _size = 0; + _aggregate = new Statistic( STATISTIC_INVALID_TYPE, + STATISTIC_INVALID_ID ); + + } + + StatisticDatabase::~StatisticDatabase() + { + + for( StatisticMap::iterator statistic = _map.begin(); + statistic != _map.end(); ++statistic ) + { + for( IdMap::iterator fi = statistic->second.begin(); + fi != statistic->second.end(); ++fi ) + { + delete fi->second; + } + } + + delete _aggregate; + } + + void StatisticDatabase::insert( Statistic* statistic ) + { + StatisticMap::iterator map = _map.find( statistic->type ); + + if( map == _map.end() ) + { + IdMap newMap; + map = _map.insert( std::make_pair( statistic->type, + newMap ) ).first; + } + + assert( map->second.count( statistic->id ) == 0 ); + + map->second.insert( std::make_pair( statistic->id, + statistic->clone( true ) ) ); + ++_size; + } + + const StatisticDatabase::IdMap& + StatisticDatabase::find( Statistic::Type type ) + { + StatisticMap::iterator map = _map.find( type ); + + if( map == _map.end() ) + { + return _emptyMap; + } + + return map->second; + } + + StatisticDatabase::Statistic* StatisticDatabase::find( Statistic::Type type, + Statistic::Id id ) + { + StatisticMap::iterator map = _map.find( type ); + + if( map == _map.end() ) + { + return 0; + } + + IdMap::iterator statistic = map->second.find( id ); + + if( statistic == map->second.end() ) + { + return 0; + } + + report( "Looked up statistic : " << statistic->second->toString() ); + + return statistic->second; + } + + void StatisticDatabase::erase( Statistic* statistic ) + { + StatisticMap::iterator map = _map.find( statistic->type ); + assert( map != _map.end() ); + + IdMap::iterator fi = map->second.find( statistic->id ); + assert( fi != map->second.end() ); + + map->second.erase( fi ); + + if( map->second.empty() ) + { + _map.erase( map ); + } + + --_size; + } + + const StatisticDatabase::Statistic* + StatisticDatabase::aggregate( Statistic::Type type ) + { + delete _aggregate; + + StatisticMap::iterator map = _map.find( type ); + assert( map != _map.end() ); + assert( !map->second.empty() ); + + IdMap::iterator statistic = map->second.begin(); + + _aggregate = static_cast< Statistic* >( ( + statistic->second )->clone( true ) ); + + for( ; statistic != map->second.end(); ++statistic ) + { + _aggregate->aggregate( *statistic->second ); + } + + return _aggregate; + } + + bool StatisticDatabase::empty() const + { + return _size == 0; + } + + unsigned int StatisticDatabase::size() const + { + return _size; + } + + void StatisticDatabase::clear() + { + for( StatisticMap::iterator statistic = _map.begin(); + statistic != _map.end(); ++statistic ) + { + for( IdMap::iterator fi = statistic->second.begin(); + fi != statistic->second.end(); ++fi ) + { + delete fi->second; + } + } + + _size = 0; + } + + std::string StatisticDatabase::toString() const + { + std::string result; + + for( StatisticMap::const_iterator statistic = _map.begin(); + statistic != _map.end(); ++statistic ) + { + for( IdMap::const_iterator fi = statistic->second.begin(); + fi != statistic->second.end(); ++fi ) + { + result += fi->second->toString() + "\n\n"; + } + } + + return result; + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/StatisticDatabase.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/StatisticDatabase.h new file mode 100644 index 00000000..0f7f8c2e --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/StatisticDatabase.h @@ -0,0 +1,171 @@ +/*! + \file StatisticDatabase.h + \author Gregory Diamos + \date Saturday March 28, 2009 + \brief The header file for the StatisticDatabase class +*/ + +#ifndef STATISTIC_DATABSE_H_INCLUDED +#define STATISTIC_DATABSE_H_INCLUDED + +#include + +#define STATISTIC_INVALID_TYPE 0xffffffff +#define STATISTIC_INVALID_ID 0xffffffff + +namespace hydrazine +{ + + /*! + \brief A collection of different type of statistics to support + aggregation across different types. + */ + class StatisticDatabase + { + + public: + /*! \brief A collection of information of a given type */ + class Statistic + { + public: + /*! \brief A unique type for a derived class of Statistic */ + typedef unsigned int Type; + + /*! \brief A unique Id within a type for a Statistic */ + typedef unsigned int Id; + + public: + /*! \brief The type of this Statistic. + + Statistics of the same type can be aggregated. + */ + const Type type; + + /*! \brief The Id of the statistic */ + const Id id; + + public: + + /*! \brief Constructor for setting the type */ + Statistic( Type type, Id id ); + + /*! \brief Virtual destructor */ + virtual ~Statistic(); + + /*! \brief Aggregate the values in this statistic with + another of the same type. + */ + virtual void aggregate( const Statistic& statistic ); + + public: + virtual Statistic* clone( bool copy = true ) const; + std::string toString() const; + + }; + + /*! + \brief A class that generates Statistics for a specific databse + */ + class Generator + { + protected: + /*! \brief Reference to the connected StatisticDatabase */ + StatisticDatabase& _database; + + /*! \brief Set to true if the StatisticDatabase is valid */ + const bool _databaseRegistered; + + public: + /*! \brief The constructor registers the class with a + database + + \param database A reference to the database being + registered. Should be a null pointer if invalid. + */ + Generator( StatisticDatabase& database ); + + }; + + private: + typedef std::unordered_map< Statistic::Id, Statistic* > IdMap; + typedef std::unordered_map< Statistic::Type, IdMap > StatisticMap; + + private: + static IdMap _emptyMap; + + private: + Statistic* _aggregate; + StatisticMap _map; + unsigned int _size; + + public: + /*! \brief Constructor */ + StatisticDatabase(); + + /*! \brief Destructor */ + ~StatisticDatabase(); + + /*! \brief Insert a new statistic into the database. + + \param statistic The Statistic being observed. + */ + void insert( Statistic* statistic ); + + /*! \brief Find a statistic in the database + + \param type The type of statistic being looked up + \return Reference to a map of statistics with this type + */ + const IdMap& find( Statistic::Type type ); + + /*! \brief Find a statistic in the database + + \param type The Type of statistic being looked up + \param id The Id of Statistic being looked up + \return Pointer to the Statistic with this type and id + + This will be zero if the statistic does not exist + + */ + Statistic* find( Statistic::Type type, Statistic::Id id ); + + /*! \brief Erase a single statistic + + \param statistic A pointer to the statistic being erased. + */ + void erase( Statistic* statistic ); + + /*! \brief Aggregate all of the statistics contained of a specific + type. + + This returns a locally owned object. It is only valid until + the next call to aggregate. + + \param type The statistic type to aggregate over. + \return A pointer to the newly aggregated Statistic + */ + const Statistic* aggregate( Statistic::Type type ); + + /*! \brief Is the database empty + \return True if empty + */ + bool empty() const; + + /*! \brief Get the number of Statistics in the database + \return The number of Statistics + */ + unsigned int size() const; + + /*! \brief Clear all Statistics from the database */ + void clear(); + + public: + + /*! \brief Create a string representation of all statistics */ + std::string toString() const; + + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/SystemCompatibility.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/SystemCompatibility.h new file mode 100644 index 00000000..c663c574 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/SystemCompatibility.h @@ -0,0 +1,37 @@ +/*! \file SystemCompatibility.h + \date Monday August 2, 2010 + \author Gregory Diamos + \brief The header file for hacked code required to assist windows + compilaiton +*/ + +#ifndef SYSTEM_COMPATIBILITY_H_INCLUDED +#define SYSTEM_COMPATIBILITY_H_INCLUDED + +// Standard Library Includes +#include +#include +#include + +/*****************************************************************************\ + Standard Library Includes +\*****************************************************************************/ + +namespace hydrazine +{ + /*! \brief Get the number of hardware threads */ + unsigned int getHardwareThreadCount(); + /*! \brief Get the full path to the named executable */ + std::string getExecutablePath(const std::string& executableName); + /*! \brief The the amount of free physical memory */ + long long unsigned int getFreePhysicalMemory(); + /*! \brief Has there been an OpenGL context bound to this process */ + bool isAnOpenGLContextAvailable(); + /*! \brief Is a string name mangled? */ + bool isMangledCXXString(const std::string& string); + /*! \brief Demangle a string */ + std::string demangleCXXString(const std::string& string); + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Test.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/Test.h new file mode 100644 index 00000000..034ec65d --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Test.h @@ -0,0 +1,86 @@ +/*! + \file Test.h + \author Gregory Diamos + \date July 4 2008 + \brief Contains the class prototype for the Test infertace +*/ + +#ifndef TEST_H_INCLUDED +#define TEST_H_INCLUDED + +#include +#include +#include +#include + +/*! \brief A namespace for creating test programs for individual classes. */ +namespace test +{ + + /*! + \brief An interface for generating a test for a specific class. + + The idea here it to make tests of individual classes all have a single + interface for running the test and gathering functional and performance + information about whether or not the test passed and if it failed, + why it failed. + */ + class Test + { + public: + typedef boost::random::mersenne_twister + < + unsigned int, + 32, + 351, + 175, + 19, + 0xccab8ee7, + 11, + 7, + 0x31b6ab00, + 15, + 0xffe50000, + 17, + 0xa37d3c92 + > + MersenneTwister; + + private: + + hydrazine::Timer::Second _time; + bool _testRun; + bool _passed; + + protected: + std::string name; + std::string description; + std::stringstream status; + MersenneTwister random; + + protected: + virtual bool doTest( ) = 0; + void _seed(); + + public: + unsigned int seed; + bool verbose; + + public: + Test(); + virtual ~Test(); + + void test(); + std::string toString() const; + std::string testStatus() const; + const std::string& testName() const; + std::string testDescription() const; + bool passed() const; + bool run() const; + hydrazine::Timer::Second time() const; + + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Thread.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/Thread.h new file mode 100644 index 00000000..9a7c8d04 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Thread.h @@ -0,0 +1,333 @@ +/*! \file Thread.h + \author Gregory Diamos + \date 4/10/2008 + \brief The header file for the thread class +*/ + +#ifndef HYDRAZINE_THREAD_H_INCLUDED +#define HYDRAZINE_THREAD_H_INCLUDED + +#include +#include + +#include +#include + +#define THREAD_CONTROLLER_ID 0 +#define THREAD_START_ID ( THREAD_CONTROLLER_ID + 1 ) +#define THREAD_ANY_ID 0xffffffff + +namespace hydrazine +{ + + /*! + \brief A wrapper class around pthreads + + Essentially this is just a front end interface in the main process + and a thread asociated with it, running in the background. This + class provides an api for communication between the main process + and the associated thread via message passing. The message passing + model assumes that the main process owns sections of memory. The act of + sending a message from the main process to the thread transfers + ownership a specified section of memory from the main process to the + thread. Threads can receive these memory segments, do some processing + on them, and possibly pass ownership back to the main process via their + own version of the send function. All sends should be implemented via + mutexes, condition variables, and should pass pointers rather than + doing copies. + + The point here is to create a clean programming model for dealing with + parallelism. Each thread owns sections of memory and must use + sends and recieves to transfer ownership. No need to ever worry about + aquiring locks for dealing with shared data. It's up to the programmer + to ensure that the implementation scales, but mutexes won't be the + bottleneck. + + Remimplementing this class requires + the remiplementation of the execute function which corresponds to the + function that is executed by the spawned thread when it is created + from the main process. + + Threads are referred to by id and many threads can be grouped together. + Once this has been done, messages can be sent from any of the + thread objects in the main process to any of the threads in the group. + + Similarly, once threads have been grouped together, the entire group + can be tested to see if there are any messages from any of the threads + that can be received. + */ + class Thread + { + public: + /*! \brief A type for thread ids */ + typedef unsigned int Id; + + /*! \brief A type for a message's payload data */ + typedef void* MessageData; + + private: + class Message + { + public: + enum Type + { + Invalid, + Regular + }; + + public: + MessageData payload; + Id source; + Id destination; + Type type; + }; + + class Queue + { + private: + friend class Group; + + private: + typedef std::list< Message > MessageQueue; + + private: + boost::condition_variable _condition; + boost::mutex _mutex; + + private: + MessageQueue _queue; + + public: + Queue(); + ~Queue(); + + void push( const Message& ); + Message pull( Id ); + bool test( Id&, bool block = false ); + + }; + + class Group + { + private: + boost::mutex _mutex; + + public: + typedef std::unordered_map< Id, Thread* > ThreadMap; + + private: + ThreadMap _threads; + Queue _controllerQueue; + + public: + Group(); + ~Group(); + + void add( Thread* ); + void remove( Thread* ); + Thread* find( Id ); + + void push( const Message& ); + Message pull( Id ); + bool test( Id&, bool ); + + bool empty() const; + unsigned int size() const; + }; + + private: + /*! \brief The next id */ + static Id _nextId; + + private: + /*! \brief Pthread create needs a static function to launch + the thread with + + \return Void pointer required by pthreads. + + \param argument The argument passed to the thread. + + */ + static void* _launch( void* argument ); + + /*! \brief Compare two ids */ + static bool _compare( Id, Id ); + + private: + /*! \brief Is the thread running */ + bool _running; + + /*! \brief Queue of messages to be delivered to the thread */ + Queue _threadQueue; + + /*! \brief Group of threads + + Should be set to 0 if threads are not grouped + */ + Group* _group; + + /*! \brief The thread handle */ + boost::thread* _thread; + + /*! \brief The thread id */ + Id _id; + + protected: + + /*! \brief This is the function that is executed in a separate + thread when the run command is sent. + */ + virtual void execute() = 0; + + protected: + + /*!\brief Test to see if there are any messages that can be + received + + \return True if there is a message that can be received + + \param The id to receive from + + \param any Receive a message from any id + + */ + bool threadTest( Id id = THREAD_ANY_ID ); + + /*! \brief Receive a message in this thread. + + This method will block until the message is received + + \return the id of the message source + + \param The id to receive from + + */ + template + Id threadReceive( T*& message, Id id = THREAD_ANY_ID ); + + /*! \brief Send a message to the controller thread + + This method will not block even if the message was not received + by the controller. + + \param id The thread id to send the message to. + + */ + void threadSend( MessageData message, + Id id = THREAD_CONTROLLER_ID ); + + /*! \brief All associated threads will block here until all other + threads have hit the barrier */ + void barrier(); + + public: + + /*! \brief Constructor */ + Thread(); + + /*! \brief Copy constructor */ + Thread( const Thread& ); + + /*! \brief Assignment operator */ + const Thread& operator=( const Thread& ); + + /*! \brief Destructor */ + virtual ~Thread(); + + /*! \brief Start the thread */ + void start(); + + /*! \brief Block until the thread returns */ + void join(); + + /*! \brief Associate this thread with another thread + + This is used for collective operations + + \param The thread to associate with + */ + void associate( Thread* t ); + + /*! \brief Remove this thread from any groups that it is + associated with + */ + void remove(); + + /*! \brief Send a message to this thread + + This method will not block until the message is received by the + thread + + \param The message being sent + */ + void send( MessageData message ); + + /*! \brief Test to see if there are any messages that can be + received + + \param Block until there is a message + + \return True if there is a message that can be received + */ + bool test( bool block = false ); + + /*! \brief Test to see if there are any messages in any of the + queues of the threads in the current group. + + \param id Test for messages send by a specific thread + + \param block Should the function block until it returns true? + + \return True if there is a message in the receive queue of any + thread in the group along with it's id + + */ + std::pair< Id, bool > testGroup( bool block = false, + Id source = THREAD_ANY_ID ); + + /*! \brief Receive a message from this thread. + + This method will block until the message is received + + \param message A pointer to the message being received + + */ + template + void receive( T*& message ); + + /*! \brief Get the id of this thread. + + \return The id of this thread. + */ + Id id() const; + + /*! \brief Is the thread running + + \return true if it is running + */ + bool started() const; + + /*! \brief Was the thread killed? + + \return true if it has been killed + */ + bool killed() const; + + /*! \brief Get a pointer to a thread in the group associated with a + specific id. + + \param id The id of the thread in the group to look up. + + \return the pointer to the correct thread. + + should return 0 if thread does not exist + */ + Thread* find( Id id ); + + }; + +} + +#include "Thread.hpp" + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Thread.hpp b/ocelot/ThirdParty/hydrazine/include/hydrazine/Thread.hpp new file mode 100644 index 00000000..f573bb4a --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Thread.hpp @@ -0,0 +1,63 @@ +/*! +* \file Thread.hpp +* +* \author Gregory Diamos +* \date Wednesday November 12, 2008 +* +* +* +* +* \brief The template source file for the Thread interface; +*/ + +#ifndef THREAD_HPP_INCLUDED +#define THREAD_HPP_INCLUDED + +#include "Thread.h" + +#include + +#ifdef REPORT_BASE +#undef REPORT_BASE +#endif + +#define REPORT_BASE 0 + +//////////////////////////////////////////////////////////////////////////////// + +namespace hydrazine +{ + + template < class T > + Thread::Id Thread::threadReceive( T*& data, Thread::Id id ) + { + + report( "Thread " << _id << " thread blocking receive." ); + + Message message = _threadQueue.pull( id ); + assert( message.destination == _id ); + + data = static_cast< T* >( message.payload ); + + return message.source; + + } + + + template < class T > + void Thread::receive( T*& data ) + { + + report( "Thread " << _id << " controller blocking receive." ); + + Message message = _group->pull( THREAD_ANY_ID ); + assert( message.destination == THREAD_CONTROLLER_ID ); + + data = reinterpret_cast< T* >( message.payload ); + + } + +} + +//////////////////////////////////////////////////////////////////////////////// +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/Timer.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/Timer.h new file mode 100644 index 00000000..d7c18555 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/Timer.h @@ -0,0 +1,32 @@ +/*! \file Timer.h +* +* \brief Header file for the Timer class +* +* \author Gregory Diamos +* +* \date : 9/27/2007 +* +*/ + +#ifndef TIMER_H_INCLUDED +#define TIMER_H_INCLUDED + +#include +#include + +/*! + \brief a namespace for hydrazine classes and functions +*/ +namespace hydrazine +{ + + + class Timer : public LowLevelTimer + { + public: + std::string toString() const; + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/ValueCompare.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/ValueCompare.h new file mode 100644 index 00000000..0e6265b5 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/ValueCompare.h @@ -0,0 +1,69 @@ +/*! + \file ValueCompare.h + \date Wednesday May 27, 2009 + \author Gregory Diamos + \brief The header file for the ValueCompare class. +*/ +#ifndef VALUE_COMPARE_H_INCLUDED +#define VALUE_COMPARE_H_INCLUDED + +#include + +namespace hydrazine +{ + /*! + \brief A class for comparing key/value pairs based on the key only + */ + template< typename Compare, typename Container > + class ValueCompare : + public std::binary_function< typename Container::value_type, + typename Container::value_type, bool >, + public std::binary_function< typename Container::value_type, + typename Container::key_type, bool >, + public std::binary_function< typename Container::key_type, + typename Container::value_type, bool > + { + public: + typedef size_t size_type; + typedef typename Container::key_type key_type; + typedef typename Container::mapped_type mapped_type; + typedef typename Container::value_type value_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef const value_type* const_pointer; + typedef const value_type& const_reference; + + protected: + Compare _compare; + + public: + const Compare& compare() const + { + return _compare; + } + + public: + explicit ValueCompare( const Compare& c ) : _compare( c ) {} + ValueCompare() {} + + public: + bool operator()( const_reference x, const_reference y ) const + { + return _compare( x.first, y.first ); + } + + bool operator()( const key_type& x, const_reference y ) const + { + return _compare( x, y.first ); + } + + bool operator()( const_reference x, const key_type& y ) const + { + return _compare( x.first, y ); + } + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlArgumentParser.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlArgumentParser.h new file mode 100644 index 00000000..546b25b6 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlArgumentParser.h @@ -0,0 +1,58 @@ +/*! + + \file XmlArgumentParser.h + + \date Monday September 15, 2008 + + \author Gregory Diamos + + \brief The header file for the XmlArgumentParser class. + +*/ + +#ifndef XML_ARGUMENT_PARSER_H_INCLUDED +#define XML_ARGUMENT_PARSER_H_INCLUDED + +#include "XmlParser.h" +#include + +namespace hydrazine +{ + + class XmlArgumentParser + { + + private: + + XmlTree _tree; + XmlTree::iterator _treeIterator; + + public: + + XmlArgumentParser( const std::string& fileName ); + ~XmlArgumentParser(); + + void reset(); + void ascend( ); + void descend( const std::string& tag ); + const std::string& tag() const; + const XmlTree& tree() const; + + template< class T > + void parse( T& i ) const; + + + }; + + template< class T > + void XmlArgumentParser::parse( T& i ) const + { + + std::stringstream stream( _treeIterator.leaf() ); + stream >> i; + + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlLexer.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlLexer.h new file mode 100644 index 00000000..6078bfdf --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlLexer.h @@ -0,0 +1,78 @@ +/*! + + \file XmlLexer.h + + \date Saturday September 13, 2008 + + \author Gregory Diamos + + \brief The header file for the XmlLexer class. + +*/ + +#ifndef XML_LEXER_H_INCLUDED +#define XML_LEXER_H_INCLUDED + +#include +#include + +namespace hydrazine +{ + + class XmlLexer + { + + public: + + class Token + { + + public: + + enum Type + { + + CARET_OPEN = '<', + CARET_CLOSE = '>', + BACKSLASH = '/', + IDENTIFIER, + END_OF_FILE = -1, + INVALID + + }; + + Type type; + unsigned int column; + unsigned int line; + std::string lineText; + std::string string; + + }; + + private: + + Token _token; + std::ifstream file; + std::string _fileName; + + private: + + bool devourComment(); + void devourWhiteSpace(); + void tokenizeIdentifier(); + void peekline( std::string& string ); + + public: + + XmlLexer( const std::string& fileName ); + ~XmlLexer(); + + bool next(); + const Token& token() const; + const std::string& fileName() const; + + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlParser.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlParser.h new file mode 100644 index 00000000..0b493a5b --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlParser.h @@ -0,0 +1,81 @@ +/*! + + \file XmlParser.h + + \date Sunday September 14, 2008 + + \author Gregory Diamos + + \brief The header file for the XmlParser class. + +*/ + +#ifndef XML_PARSER_H_INCLUDED +#define XML_PARSER_H_INCLUDED + +#include "XmlTree.h" +#include "XmlLexer.h" + +namespace hydrazine +{ + + class XmlParser + { + + private: + + enum State + { + + BeginCaretOpen = 0, + BeginIdentifier = 1, + BeginCaretClose = 2, + + IntermediateCaretOpenOrIdentifier = 3, + IntermediateCaretOpenThenIdentifierOrBackslash = 4, + IntermediateCaretOpenThenIdentifierThenCaretClose = 5, + IntermediateCaretOpenThenBackslashThenIdentifier = 6, + IntermediateCaretOpenThenBackslashThenIdentifierThenCaretClose = 7, + + IntermediateCaretOpen = 8, + + Finished + + }; + + State _state; + std::stack< std::string > _identifierStack; + + private: + + void _beginCaretOpen( ); + void _beginIdentifier( ); + void _beginCaretClose( ); + void _intermediateCaretOpenOrIdentifier( ); + void _intermediateCaretOpenThenIdentifierOrBackslash( ); + void _intermediateCaretOpenThenIdentifierThenCaretClose( ); + void _intermediateCaretOpenThenBackslashThenIdentifier( ); + void _intermediateCaretOpenThenBackslashThenIdentifierThenCaretClose( ); + void _intermediateIdentifier( ); + void _intermediateCaretOpen( ); + + void _handleToken(); + + private: + + XmlLexer* _lexer; + XmlTree _tree; + XmlTree::iterator _treeIterator; + + public: + + XmlParser( const std::string& fileName ); + ~XmlParser(); + + const XmlTree& tree() const; + + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlTree.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlTree.h new file mode 100644 index 00000000..29d005d6 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/XmlTree.h @@ -0,0 +1,132 @@ +/*! + + \file XmlTree.h + + \date Saturday September 13, 2008 + + \author Gregory Diamos + + \brief The header file for the XmlTree class. + +*/ + +#ifndef XML_TREE_H_INCLUDED +#define XML_TREE_H_INCLUDED + +#include +#include +#include +#include + +namespace hydrazine +{ + + class XmlTree + { + + public: + + class XmlTreeNode + { + + public: + + typedef std::list< XmlTreeNode > List; + typedef List::iterator Iterator; + typedef std::multimap< std::string, Iterator > Map; + typedef Map::iterator SuccessorIterator; + typedef Map::const_iterator ConstSuccessorIterator; + + enum Type + { + + Root = 0, + Leaf = 1, + Intermediate = 2, + End = 3, + Unspecified + + }; + + friend class XmlTree; + + private: + + Type type; + Map successors; + Iterator parent; + unsigned int leaves; + + public: + + Type getType() const; + std::string identifier; + + }; + + class iterator + { + + private: + + XmlTreeNode::Iterator node; + std::stack< XmlTreeNode::SuccessorIterator > successor; + + friend class XmlTree; + + public: + + iterator& operator=( const iterator& i ); + XmlTreeNode& operator*() const; + XmlTreeNode* operator->() const; + bool operator==( const iterator& i ) const; + bool operator!=( const iterator& i ) const; + iterator& operator++(); + iterator operator++( int ); + + void descend( std::string tag ); + void ascend( ); + const std::string& leaf() const; + bool isLeaf() const; + std::map< std::string, std::string > map() const; + + }; + + private: + + typedef XmlTreeNode::Iterator Iterator; + typedef XmlTreeNode::SuccessorIterator SuccessorIterator; + typedef XmlTreeNode::ConstSuccessorIterator ConstSuccessorIterator; + XmlTreeNode::List nodes; + Iterator rootNode; + Iterator endNode; + + private: + + void init( const iterator& fi ); + + public: + + XmlTree(); + ~XmlTree(); + + XmlTree( const XmlTree& tree ); + XmlTree& operator=( const XmlTree& tree ); + + iterator begin(); + iterator end(); + iterator insert( std::string tag ); + iterator insert( std::string tag, iterator& base, + XmlTreeNode::Type type = XmlTreeNode::Unspecified ); + iterator erase( iterator& i ); + unsigned int size() const; + void clear(); + void toStream( std::ostream& stream ); + + XmlTree subtree( const iterator& base ); + + }; + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/common.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/common.h new file mode 100644 index 00000000..a06a4369 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/common.h @@ -0,0 +1,30 @@ +/*! + + \file common.h + + \date Friday October 31, 2008 + + \author Gregory Diamos + + \brief The header file for the common library + +*/ + +#ifndef LIB_COMMON_H_INCLUDED +#define LIB_COMMON_H_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/compression.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/compression.h new file mode 100644 index 00000000..ee1555fe --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/compression.h @@ -0,0 +1,18 @@ +/*! \file compression.h + \date Wednesday December 5, 2012 + \author Gregory Diamos + \brief The header file the hydrazine compression abstraction +*/ + +#pragma once + +// Standard Library Includes +#include + +namespace hydrazine +{ + +void decompress(void* output, uint64_t& outputSize, const void* input, + uint64_t inputSize); + +} diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/debug.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/debug.h new file mode 100644 index 00000000..0c923a62 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/debug.h @@ -0,0 +1,237 @@ + +/*! \file debug.h +* +* \brief Header file for common debug macros +* +* \author Gregory Diamos +* +* \date : Sunday November 16, 2008 +* +*/ + + +#ifndef DEBUG_H_INCLUDED +#define DEBUG_H_INCLUDED + +#include +#include +#include +#include + +#include + +namespace hydrazine +{ + /*! \brief Global report timer */ + extern Timer _ReportTimer; + + /*! \brief Return a string representing the current system time */ + extern std::string _debugTime(); + + /*! \brief Return a formatted line number and file name. */ + extern std::string _debugFile( const std::string& file, unsigned int line ); + + /*! \brief Convert an iterable range to a string + + T must implement the concept of a forward iterator and the object being + pointed to must be able to be accepted by operator<< + + \param begin Iterator to the start of the range + \param end Iterator to the end of the range + \param space The string used as a space + + \return A string representation of the specified range. + */ + template < typename T > std::string toString( T begin, T end, + std::string space = " ", unsigned int limit = 80 ) + { + std::stringstream stream; + + if( begin != end ) + { + stream << *begin; + ++begin; + } + + for( T iterator = begin; iterator != end; ++iterator ) + { + stream << space; + stream << *iterator; + if( stream.str().size() > limit ) + { + break; + } + } + + return stream.str(); + } + + /*! \brief Convert an iterable range to a string using a formatting functor + + T must implement the concept of a forward iterator and the object being + pointed to must be able to be accepted + by operator<< format( object ) + + \param begin Iterator to the start of the range + \param end Iterator to the end of the range + \param space The string used as a space + + \return A string representation of the specified range. + + */ + template < typename T, typename Format > std::string toFormattedString( + T begin, T end, Format format, std::string space = " ", + unsigned int limit = 80 ) + { + std::stringstream stream; + + if( begin != end ) + { + stream << format( begin ); + ++begin; + } + + for( T iterator = begin; iterator != end; ++iterator ) + { + stream << space; + stream << format( iterator ); + if( stream.str().size() > limit ) + { + break; + } + } + + return stream.str(); + } + + /*! + \brief Strip the front of a file + */ + template< char delimiter > + std::string stripReportPath( const std::string& string ) + { + size_t found = string.find_last_of(delimiter); + std::string result = string.substr(found+1); + return result; + } + struct NullStream : std::ostream {}; + + /*! \brief Return the stream with the current name */ + extern std::ostream& _getStream(const std::string& name); + + #if 0 + extern NullStream nullstream; + + inline std::ostream& log(const std::string& path) + { + return nullstream; + } + #else + inline std::ostream& log(const std::string& path) + { + return _getStream(path); + } + #endif + + extern void enableAllLogs(); + extern void enableLog(const std::string& logName); + +} + +// Swallow all types +template +hydrazine::NullStream & operator<<(hydrazine::NullStream & s, T const &) +{ + return s; +} + +// Swallow manipulator templates +inline hydrazine::NullStream & operator<<(hydrazine::NullStream & s, + std::ostream &(std::ostream&)) +{ + return s; +} + +/*! + + \def REPORT_ERROR_LEVEL + + \brief The threshold to print out the debugging message. + + If the debugging error levels is less than this, it will not be printed out. + +*/ + +#ifndef REPORT_ERROR_LEVEL +#define REPORT_ERROR_LEVEL 1 +#endif + +/*! + \def reportE(x,y) + \brief a MACRO that prints a string to stdio if DEBUG is defined and x is + greater than REPORT_ERROR_LEVEL, or exits the program if the error level + is greater than EXIT_ERROR_LEVEL. + + If MPI_DEBUG is defined, it appends the rank to the beginning of the error + message. + + \param x The error level + \param y The message to print. You can use the << operators to send + multiple arguments +*/ + +#ifndef NDEBUG + #define reportE(x, y) \ + if(REPORT_BASE >= REPORT_ERROR_LEVEL && (x) >= REPORT_ERROR_LEVEL)\ + { \ + {\ + std::cout << "(" << hydrazine::_debugTime() << ") " \ + << hydrazine::_debugFile( __FILE__, __LINE__ ) \ + << " " << y << "\n";\ + }\ + \ + } +#else + #define reportE(x, y) +#endif + +/*! + \def report(a) + \brief a MACRO that prints a string to stdio if DEBUG is defined + \param a a string +*/ + +#ifndef NDEBUG + #define report(y) \ + if(REPORT_BASE >= REPORT_ERROR_LEVEL)\ + { \ + {\ + std::cout << "(" << hydrazine::_debugTime() << ") " \ + << hydrazine::_debugFile( __FILE__, __LINE__ ) \ + << " " << y << "\n";\ + }\ + \ + } +#else + #define report(y) +#endif + +/*! \brief An assertion with a message */ +#ifndef NDEBUG + + #define assertM(x,y) \ + if(!(x))\ + { \ + {\ + std::cout << "(" << hydrazine::_debugTime() << ") " \ + << hydrazine::_debugFile( __FILE__, __LINE__ ) \ + << " Assertion message: " << y << "\n";\ + }\ + assert(x);\ + \ + } +#else + #define assertM(x,y) +#endif + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/json.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/json.h new file mode 100644 index 00000000..6a95ff9f --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/json.h @@ -0,0 +1,352 @@ +/*! + \file json.h + + \author Andrew Kerr + + \brief defines a JSON parser and emitter + + \date 27 Oct 2009 +*/ + +#ifndef HYDRAZINE_JSON_H_INCLUDED +#define HYDRAZINE_JSON_H_INCLUDED + +#include +#include +#include +#include +#include + +namespace hydrazine { +namespace json { + + /*! + Base value type - True, False, and Null do not have derived classes + */ + class Value { + public: + enum Type { + Object, + Array, + DenseArray, + Number, + String, + True, + False, + Null, + Type_invalid + }; + + public: + Value(); + Value(Type type); + virtual ~Value(); + + /*! + makes a deep copy of the value + */ + virtual Value *clone() const; + + public: + /* + accessors perform cast if possible or throw an exception + */ + + //! returns an integer if the value is a Number and an integer + unsigned long long int as_integer() const; + + //! returns a double if the value is a Number and a real + double as_real() const; + + //! returns a double if the value is a Number; casts to double if an integer + double as_number() const; + + //! returns a string representation if the value is a String + const std::string& as_string() const; + + //! returns a vector of values if the value is an array + const std::vector< Value *>& as_array() const; + + //! returns a vector of integers if the value is a dense array + const std::vector< int >& as_dense_array() const; + + //! returns a dictionary of values if the value is an object + const std::map< std::string, Value *>& as_object() const; + + //! returns true or false if the value is true or false respectively + bool as_boolean() const; + + //! returns true if the value is null, false if not - doesn't throw exception + bool is_null() const; + + public: + + Type type; + }; + + /*! + Numeric scalar value + */ + class Number : public Value { + public: + enum NumberType { + Integer, + Real, + Number_invalid + }; + + public: + + Number(); + Number(double real_value); + Number(int int_value); + virtual ~Number(); + + virtual Value *clone() const; + + public: + + NumberType number_type; + + double value_real; + + unsigned long long int value_integer; + }; + + /*! + Represents an ordered list of values + */ + class Array : public Value { + public: + + typedef std::vector< Value * > ValueVector; + + typedef ValueVector::iterator iterator; + typedef ValueVector::const_iterator const_iterator; + + public: + Array(); + Array(const ValueVector &values); + virtual ~Array(); + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + size_t size() const; + + virtual Value *clone() const; + + public: + + ValueVector sequence; + }; + + /*! + Represents an ordered list of integer values + */ + class DenseArray : public Value { + public: + + typedef std::vector< int > IntVector; + + typedef IntVector::iterator iterator; + typedef IntVector::const_iterator const_iterator; + + public: + DenseArray(); + DenseArray(const IntVector &values); + virtual ~DenseArray(); + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + Value* number(int index); + + virtual Value *clone() const; + + public: + IntVector sequence; + + private: + json::Number _temp; + }; + + /*! + Represents a string scalar value + */ + class String : public Value { + public: + String(); + String(const std::string &string_value); + virtual ~String(); + + virtual Value *clone() const; + + public: + + std::string value_string; + }; + + /*! + A dictionary mapping unique strings onto values + */ + class Object : public Value { + public: + typedef std::pair< std::string, Value *> KeyValuePair; + typedef std::map< std::string, Value *> Dictionary; + + typedef Dictionary::iterator iterator; + typedef Dictionary::const_iterator const_iterator; + + public: + Object(); + Object(const Dictionary &object); + virtual ~Object(); + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + virtual Value *clone() const; + + public: + Dictionary dictionary; + }; + + /*! + Parses an istream into a JSON array + */ + class Parser { + public: + Parser(); + ~Parser(); + + /*! + parses an istream into a JSON array + */ + Array *parse(std::istream &input); + + int line_number; + + public: + + int get_non_whitespace_char(std::istream &input); + int get_char(std::istream &input); + void putback(std::istream &input, int ch); + + Value *parse_value(std::istream &input); + Value *parse_array(std::istream &input); + Object *parse_object(std::istream &input); + Number *parse_number(std::istream &input); + String *parse_string(std::istream &input); + String *parse_identifier(std::istream &input); + }; + + /*! + Emits a JSON object to an ostream + */ + class Emitter { + public: + Emitter(); + ~Emitter(); + + /*! + Emits a JSON value to an ostream + */ + std::ostream & emit(std::ostream &output, Value *value); + + void emit_pretty(std::ostream &output, const Value *value, int indent_level = 0); + void emit_compact(std::ostream &output, const Value *value); + + void emit_array_pretty(std::ostream &output, const Array *object, int indent_level=0); + void emit_dense_array_pretty(std::ostream &output, const DenseArray *object, int indent_level=0); + void emit_object_pretty(std::ostream &output, const Object *object, int indent_level=0); + void emit_number(std::ostream &output, const Number *number); + void emit_string(std::ostream &output, const std::string &str); + + void emit_indents(std::ostream &output, int indents); + + public: + + /*! + If true, indents with tab (\t) character. If false, indents with space (0x20) + */ + bool use_tabs; + + /*! + Number of space (0x20) or tab (\t) characters to indent nested objects + */ + int indent_size; + + }; + + /*! + Class wrapping value structure enabling programmer-friendly access. Methods throw + common::exception if accesses are invalid + */ + class Visitor { + public: + Visitor(); + ~Visitor(); + + Visitor(Value *value); + + Value *find(const std::string & obj) const; + + //! assuming value is an Object, returns a Visitor for the named value + Visitor operator[](const char *) const; + + //! assuming value is an Array, returns a Visitor for the indexed value + Visitor operator[](int ) const; + + //! returns true if value is Null + bool is_null() const; + + //! casts value to boolean, assuming it is either True or False + operator bool() const; + + //! casts value to an integer, assuming it is a Number + operator int() const; + + //! casts values to an integer, assuming it is a Number + operator uint64_t() const; + + //! casts value to a double, assuming it is a Number + operator double() const; + + //! casts value to a string, assuming it is a String + operator std::string() const; + + Array::iterator begin_array(); + Array::const_iterator begin_array() const; + Array::iterator end_array(); + Array::const_iterator end_array() const; + size_t size_array() const; + + Object::iterator begin_object(); + Object::const_iterator begin_object() const; + Object::iterator end_object(); + Object::const_iterator end_object() const; + + + template T parse(const char *key, T defaultValue) const { + if (find(key)) { + return (T)(*this)[key]; + } + return defaultValue; + } + + public: + + //! value mapped to visitor + Value *value; + }; +} +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/macros.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/macros.h new file mode 100644 index 00000000..d63cbc66 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/macros.h @@ -0,0 +1,71 @@ +/*! \file macros.h +* +* \brief Header file for common preprocessor macros +* +* \author Gregory Diamos +* +* \date : 9/27/2007 +* +*/ + +#ifndef MACROS_H_INCLUDED +#define MACROS_H_INCLUDED + +/*! + \def MAX(a,b) + \brief a MACRO that returns the max of two numbers + \param a an untyped argument + \param b an untyped argument +*/ + +#define MAX(a,b) (((a)<(b))?(b):(a)) + + +/*! + \def MIN(a,b) + \brief a MACRO that returns the max of two numbers +*/ + +#define MIN(a,b) (((a)<(b))?(a):(b)) + + +/*! + \def CEIL_DIV(a,b) + \brief Do a divide of a over b but round up instead of down + +*/ +#define CEIL_DIV(a,b) (((a) == ((a)/(b)) * (b)) ? ((a)/(b)):((a)/(b)+1) ) + + +/*! + + \brief Fast swap using XOR + +*/ +#define SWAP(a,b) \ +{\ + (a) ^= (b);\ + (b) ^= (a);\ + (a) ^= (b);\ +} + +/*! + + \brief Fast absolute value for ints + +*/ +#define INT_ABS(x) \ +{\ + ( x ^ ( x >> ( sizeof( int ) * 8 - 1 ) ) ) - ( x >> ( sizeof( int ) * 8 - 1 ) )\ +} + +/*! + + \brief Regular ABS + +*/ +#ifndef ABS +#define ABS(x) ( ( ( x ) < 0 ) ? ( ( -( x ) ) ) : ( x ) ) +#endif + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/math.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/math.h new file mode 100644 index 00000000..7fa7fbee --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/math.h @@ -0,0 +1,496 @@ +/*! \file math.h +* +* \brief Header file for common math functions. +* +* \author Gregory Diamos +* +* \date : 9/27/2007 +* \date : 10/24/2007 : added exceptions +* \date : 5/27/2010 : added extended precision multiply +* \date : 8/26/2011 : added fenv +* +*/ + +#ifndef MATH_H_INCLUDED +#define MATH_H_INCLUDED + +#include +#include +#include + +/*! \brief a namespace for common classes and functions */ +namespace hydrazine +{ + + /*! \brief Check to see if an int is a power of two */ + inline bool isPowerOfTwo (int value); + + /*! \brief Check to see if an unsigned int is a power of two */ + inline bool isPowerOfTwo (unsigned int value); + + /*! \brief Mod a power of power of two */ + inline unsigned int modPowerOfTwo( unsigned int value1, + unsigned int value ); + + /*! \brief Mod a power of power of two */ + inline int modPowerOfTwo( int value1, int value ); + + /*! \brief Compute the next highest power of two */ + inline unsigned int powerOfTwo( unsigned int value ) + { + value--; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value++; + return value; + } + + /*! \brief Modes for permute instructions */ + enum PermuteMode + { + DefaultPermute, + ForwardFourExtract, + BackwardFourExtract, + ReplicateEight, + EdgeClampLeft, + EdgeClampRight, + ReplicateSixteen + }; + + /*! \brief Read a byte from a 64-bit word depending on the mode */ + template< PermuteMode mode > + unsigned int readBytes( long long unsigned int value, unsigned int control, + unsigned int byte ); + + /*! \brief Permute bytes from a pair of 32-bit operands */ + template< PermuteMode mode > + unsigned int permute( unsigned int a, unsigned int b, + unsigned int control ); + + /*! \brief Insert a bit-field in an operand */ + template< typename type > + type bitFieldInsert( type a, type b, unsigned int c, unsigned int d); + + /*! \brief Reverse the bits in the operand */ + template< typename type > + type brev( type value ); + + /*! \brief Get a bit at a single position */ + template< typename type > + type bitExtract( type value, unsigned int position ); + + /*! \brief Set a bit at a single position */ + template< typename type > + type bitInsert( type value, unsigned int position ); + + /*! \brief Extract a bit field */ + template< typename type > + type bfe( type value, unsigned int position, unsigned int length, bool isSigned ); + + /*! \brief Compute the number of bits set in the operand */ + template< typename type > + unsigned int bfind( type value, bool shiftAmount ); + + /*! \brief Compute the number of bits set in the operand */ + template< typename type > + unsigned int popc( type value ); + + /*! \brief Compute the number of leading zeros in the operand */ + template< typename type > + unsigned int countLeadingZeros( type value ); + + /*! \brief Perform extended precision multiply */ + template< typename type > + void multiplyHiLo( type& hi, type& lo, type r0, type r1 ); + + /*! \brief Perform extended precision add */ + template< typename type > + void addHiLo( type& hi, type& lo, type r0 ); + + //////////////////////////////////////////////////////////////////////////// + // Power of two checks + inline bool isPowerOfTwo( int value ) + { + return (value & (~value+1)) == value; + } + + inline bool isPowerOfTwo( unsigned int value ) + { + return (value & (~value+1)) == value; + } + + inline unsigned int modPowerOfTwo( unsigned int value1, unsigned int value ) + { + assert( value != 0 ); + return value1 & ( value - 1 ); + } + + inline int modPowerOfTwo( int value1, int value ) + { + assert( value != 0 ); + return value1 & ( value - 1 ); + } + + inline unsigned int nextPowerOfTwo( unsigned int value ) + { + value--; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value++; + return value; + } + //////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // Bit Manipulation + template< typename type > + unsigned int countLeadingZeros( type value ) + { + unsigned int count = 0; + unsigned int max = 8 * sizeof( type ); + type mask = ( ( type ) 1 ) << ( max - 1 ); + + while( count < max && ( ( value & mask ) == 0 ) ) + { + ++count; + value <<= 1; + } + + return count; + } + + template< typename type > + unsigned int popc( type value ) + { + unsigned int count = 0; + + while( value != 0 ) + { + if( value & 1 ) ++count; + value >>= 1; + } + + return count; + } + + template< typename type > + class InvertIfNegative + { + public: + type invert(const type& t) { return t; } + }; + + template< > + class InvertIfNegative + { + public: + int32_t invert(const int32_t& t) { return t < 0 ? -t : t; } + }; + + template< > + class InvertIfNegative + { + public: + int64_t invert(const int64_t& t) { return t < 0 ? -t : t; } + }; + + template< typename type > + unsigned int bfind( type value, bool shiftAmount ) + { + unsigned int d = -1; + int64_t msb = 8 * sizeof( type ) - 1; + + InvertIfNegative< type > inverter; + + value = inverter.invert( value ); + + for( int64_t i = msb; i >= 0; --i ) + { + if( value & ( 1ULL << i ) ) + { + d = i; + break; + } + } + + if( shiftAmount ) + { + if( d != ( unsigned int ) - 1 ) + { + d = msb - d; + } + } + + return d; + } + + template< typename type > + type bitExtract( type value, unsigned int position ) + { + value >>= position; + value &= 1; + return value; + } + + template< typename type > + type bitInsert( type value, type bit, unsigned int position ) + { + bit &= 1; + bit <<= position; + type mask = ~((type)1 << position); + value &= mask; + value |= bit; + return value; + } + + template< typename type > + type brev( type value ) + { + type msb = sizeof( type ) * 8 - 1; + + type result = 0; + for( unsigned int i = 0; i <= msb; ++i ) + { + result = bitInsert( result, bitExtract( value, msb - i ), i ); + } + + return result; + } + + template< typename type > + type bfe( type value , unsigned int pos, unsigned int len, bool isSigned) + { + pos = pos & 0xff; + len = len & 0xff; + type result = 0; + unsigned int msb = sizeof( type ) * 8 - 1; + unsigned int spos = ((pos + len - 1) > msb) ? msb : pos + len - 1; + type sbit = (!isSigned || (len==0)) ? 0 : bitExtract(value,spos); + + for(unsigned int i = 0 ; i<=msb; ++i) + { + if(i < len && (pos + i)<=msb) + { + result = bitInsert(result, bitExtract(value,pos + i),i); + } + else + { + result = bitInsert(result, sbit, i); + } + } + + return result; + } + + template< typename type > + type bitFieldInsert( type a, type b, + unsigned int position, unsigned int length) + { + unsigned int msb = sizeof( type ) * 8 - 1; + + type result = b; + + for( unsigned int i = 0; i < length && ( i + position ) <= msb; ++i ) + { + result = bitInsert( result, bitExtract( a, i ), i + position ); + } + + return result; + } + + template< PermuteMode mode > + unsigned int readByte( long long unsigned int value, unsigned int control, + unsigned int byte ) + { + long long unsigned int result = value; + switch( mode ) + { + case DefaultPermute: + { + result >>= (control & 0x7) * 8; + if((control >> 3) & 1) + { + if(((result & 0xff) >> 7) & 1) + { + result = 0xff; + } + else + { + result = 0x0; + } + } + break; + } + case ForwardFourExtract: + { + result >>= ( control + byte ) * 8; + break; + } + case BackwardFourExtract: + { + result >>= ( ( 8 + control - byte ) & 0x7 ) * 8; + break; + } + case ReplicateEight: + { + result >>= control * 8; + break; + } + case EdgeClampLeft: + { + result >>= std::max( control, byte ) * 8; + break; + } + case EdgeClampRight: + { + result >>= std::min( control, byte ) * 8; + break; + } + case ReplicateSixteen: + { + result >>= (( byte & 0x1 ) + ( ( control & 0x1 ) << 1 )) * 8; + break; + } + } + return result & 0xff; + } + + template< PermuteMode mode > + unsigned int permute( unsigned int a, unsigned int b, unsigned int control ) + { + long long unsigned int extended = + ( ( ( long long unsigned int ) b ) << 32 ) + | ( long long unsigned ) a; + + if( mode == DefaultPermute ) + { + unsigned int control0 = (control >> 0) & 0xf; + unsigned int control1 = (control >> 4) & 0xf; + unsigned int control2 = (control >> 8) & 0xf; + unsigned int control3 = (control >> 12) & 0xf; + + unsigned int result = readByte< mode >( extended, control0, 0 ); + result |= readByte< mode >( extended, control1, 1 ) << 8; + result |= readByte< mode >( extended, control2, 2 ) << 16; + result |= readByte< mode >( extended, control3, 3 ) << 24; + + return result; + } + else + { + control &= 0x3; + + unsigned int result = readByte< mode >( extended, control, 0 ); + result |= readByte< mode >( extended, control, 1 ) << 8; + result |= readByte< mode >( extended, control, 2 ) << 16; + result |= readByte< mode >( extended, control, 3 ) << 24; + + return result; + } + } + //////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // Extended precision + template< typename type > + void multiplyHiLo( type& hi, type& lo, type r0, type r1 ) + { + bool r0Signed = isNegative( r0 ); + bool r1Signed = isNegative( r1 ); + + r0 = ( r0Signed ) ? -r0 : r0; + r1 = ( r1Signed ) ? -r1 : r1; + + typedef typename SignedToUnsigned< type >::type utype; + + bool negative = ( r0Signed && !r1Signed ) || ( r1Signed && !r0Signed ); + + unsigned int bits = sizeof( type ) * 4; + utype mask = ( ( type ) 1 << bits ) - 1; + + // A B + // C D + // + // DA DB + // CA CB + + utype a = ( utype ) r0 >> bits; + utype b = ( utype ) r0 & mask; + utype c = ( utype ) r1 >> bits; + utype d = ( utype ) r1 & mask; + + // + + utype da = d * a; + utype db = d * b; + utype ca = c * a; + utype cb = c * b; + + utype totalBits = ( sizeof( type ) * 8 - 1); + utype upperMask = ( ( type ) 1 << totalBits ) - 1; + utype daUpper = da >> totalBits; + utype cbUpper = cb >> totalBits; + utype xCarryIn = ( ( da & upperMask ) + + ( cb & upperMask ) ) >> totalBits; + utype xCarryOut = ( daUpper + cbUpper + xCarryIn ) >> 1; + + utype x = da + cb; + + utype xUpper = x >> totalBits; + utype yCarryIn = ( ( x & upperMask ) + ( db >> bits ) ) >> totalBits; + utype yCarryOut = ( yCarryIn + xUpper ) >> 1; + + utype y = ( db >> bits ) + x; + + lo = ( db & mask ) | ( ( y & mask ) << bits ); + hi = ( y >> bits ) + ca + ( ( yCarryOut + xCarryOut ) << bits ); + + utype loUpperBit = ( utype )( ~( utype ) lo ) >> totalBits; + utype signCarryIn = ( ( ( utype ) ( ~( utype ) lo ) + & upperMask ) + 1 ) >> totalBits; + utype signCarryOut = ( loUpperBit + signCarryIn ) >> 1; + + lo = ( negative ) ? -lo : lo; + hi = ( negative ) ? ( utype )( ~( utype ) hi ) + signCarryOut : hi; + } + + template< typename type > + void addHiLo( type& hi, type& lo, type r0 ) + { + typedef typename SignedToUnsigned< type >::type utype; + + utype uHi = hi; + utype uLo = lo; + utype uR0 = r0; + + utype loResult = uR0 + uLo; + utype carry = (loResult < uR0 || loResult < uLo) ? 1 : 0; + utype hiResult = uHi + carry; + + hi = hiResult; + lo = loResult; + } + + template< typename type > + void add(type& result, type& carry, type r1, type r0, type cIn) + { + typedef typename SignedToUnsigned< type >::type utype; + utype uR0 = r0; + utype uR1 = r1; + + utype loResult = uR0 + uR1 + cIn; + carry = (loResult < uR0 || loResult < uR1) ? 1 : 0; + + result = loResult; + } + //////////////////////////////////////////////////////////////////////////// + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/include/hydrazine/string.h b/ocelot/ThirdParty/hydrazine/include/hydrazine/string.h new file mode 100644 index 00000000..f42a53f4 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/include/hydrazine/string.h @@ -0,0 +1,52 @@ +/*! \file string.h + \date Friday February 13, 2009 + \author Gregory Diamos + \brief Function headers for common C string manipulations +*/ + +#ifndef STRING_H_INCLUDED +#define STRING_H_INCLUDED + +#include +#include + +namespace hydrazine +{ + /*! \brief A vector of strings */ + typedef std::vector< std::string > StringVector; + + /*! \brief Safe string copy + + \param destination The target string + \param source The source string + \param max The max number of characters to copy + */ + void strlcpy( char* destination, const char* source, unsigned int max ); + + /*! \brief Split a string into substrings divided on a delimiter */ + StringVector split( const std::string& string, + const std::string& delimiter = " " ); + + /*! \brief Strip out substrings in a string */ + std::string strip( const std::string& string, + const std::string& delimiter = " "); + + /*! \brief Format a string to fit a specific character width */ + std::string format( const std::string& input, + const std::string& firstPrefix = "", const std::string& prefix = "", + unsigned int width = 80 ); + + /*! \brief Parse a string specifying a binary number, return the number */ + long long unsigned int binaryToUint( const std::string& ); + + /*! \brief Convert a string to a label that can be parsed by graphviz */ + std::string toGraphVizParsableLabel( const std::string& ); + + /*! \brief Add line numbers to a very large string */ + std::string addLineNumbers( const std::string&, unsigned int begin = 1 ); + + /*! \brief Convert a raw data stream into a hex representation */ + std::string dataToString(const void* data, unsigned int bytes); +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/ArgumentParser.cpp b/ocelot/ThirdParty/hydrazine/src/ArgumentParser.cpp new file mode 100644 index 00000000..b61e7994 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/ArgumentParser.cpp @@ -0,0 +1,167 @@ +/*! \file ArgumentParser.cpp + \brief Source file for the ArgumentParser class. +*/ + +#ifndef ARGUMENT_PARSER_CPP_INCLUDED +#define ARGUMENT_PARSER_CPP_INCLUDED + +#include + +// Standard Library Includes +#include + +namespace hydrazine +{ + + //////////////////////////////////////////////////////////////////////////// + // Argument parser + ArgumentParser::ArgumentParser(int _argc, char* _argv[]) + { + argc = _argc; + argv = _argv; + description( "No description provided." ); + } + + void ArgumentParser::description( const std::string& d ) + { + std::string desc = " Description: "; + std::stringstream stream( d ); + int repetition = MESSAGE_OFFSET - ( int )desc.size(); + std::string prefix( MAX( repetition, 0 ), ' ' ); + std::string regularPrefix( MESSAGE_OFFSET, ' ' ); + + _description = format( stream.str(), desc + prefix, + regularPrefix, SCREEN_WIDTH ) + "\n"; + } + + + bool ArgumentParser::isPresent(const std::string& identifier) + { + bool found = false; + + report( "Searching for " << identifier ); + + for(int i = 0; i < argc; i++) + { + std::string str = argv[i]; + size_t pos = str.find(identifier); + if( pos == 0 && str.size() == identifier.size() ) + { + report( "Found in " << str ); + found = true; + break; + } + } + + return found; + } + + void ArgumentParser::setValue(std::string& value, const std::string& s) + { + value = s; + } + + std::string ArgumentParser::help() const + { + std::stringstream stream; + stream << "\nProgram : " << argv[0] << "\n\n"; + stream << _description; + stream << "Arguments : \n\n"; + stream << arguments.str(); + stream << "\n"; + return stream.str(); + } + + void ArgumentParser::parse(const std::string& _identifier, bool& b, + bool starting, const std::string& string) + { + assert( _identifier.size() == 2 ); + assert( _identifier[0] == '-' ); + + if( isPresent( _identifier ) ) + { + report( " is present" ); + b = !starting; + } + else + { + b = starting; + } + + std::string identifier( ' ' + _identifier ); + + int prefixSpacing = MESSAGE_OFFSET - ( int )identifier.size(); + + std::string prefix( MAX( prefixSpacing, 0 ), ' ' ); + std::string regularPrefix( MESSAGE_OFFSET, ' ' ); + + std::stringstream secondStream( string + '\n' ); + + std::string result = format( secondStream.str(), prefix, + regularPrefix, SCREEN_WIDTH ); + + std::stringstream thirdStream; + thirdStream << result << regularPrefix << "value = " << std::boolalpha + << b << "\n"; + + arguments << identifier << thirdStream.str() << "\n"; + } + + void ArgumentParser::parse(const std::string& _identifier, + const std::string& _longIdentifier, bool& b, bool starting, + const std::string& string) + { + bool inFirst = false; + + if( !_identifier.empty() ) + { + assert( _identifier.size() == 2 ); + assert( _identifier[0] == '-' ); + inFirst = isPresent( _identifier ); + } + + if( inFirst || isPresent( _longIdentifier ) ) + { + report( " is present" ); + b = !starting; + } + else + { + b = starting; + } + + std::string identifier( ' ' + _identifier + '(' + + _longIdentifier + ')' ); + + int prefixSpacing = MESSAGE_OFFSET - ( int )identifier.size(); + + std::string prefix( MAX( prefixSpacing, 0 ), ' ' ); + std::string regularPrefix( MESSAGE_OFFSET, ' ' ); + + std::stringstream secondStream( string + '\n' ); + + std::string result = format( secondStream.str(), prefix, + regularPrefix, SCREEN_WIDTH ); + + std::stringstream thirdStream; + thirdStream << result << regularPrefix << "value = " << std::boolalpha + << b << "\n"; + + arguments << identifier << thirdStream.str() << "\n"; + } + + void ArgumentParser::parse() + { + bool printHelp; + parse( "-h", "--help", printHelp, false, "Print this help message." ); + if( printHelp ) + { + std::cout << help(); + std::exit(0); + } + } + //////////////////////////////////////////////////////////////////////////////// + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/Configurable.cpp b/ocelot/ThirdParty/hydrazine/src/Configurable.cpp new file mode 100644 index 00000000..abea4017 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/Configurable.cpp @@ -0,0 +1,67 @@ +/*! + + \file Configurable.cpp + + \author Gregory Diamos + + \date Friday October 31, 2008 + + \brief The source file for the Configurable class. + +*/ + +#ifndef CONFIGURABLE_CPP_INCLUDED +#define CONFIGURABLE_CPP_INCLUDED + +#include + +namespace hydrazine +{ + + std::string Configurable::toString( const Configuration& configuration ) + { + + std::stringstream stream; + + for( Configuration::const_iterator fi = configuration.begin(); + fi != configuration.end(); ++fi ) + { + + stream << " " << fi->first << " = " << fi->second << "\n"; + + } + + return stream.str(); + + } + + void Configurable::parseString( + const std::string& identifier, std::string& value, + const std::string& defaultValue, + const Configurable::Configuration& configuration ) + { + + Configuration::const_iterator fi = configuration.find( identifier ); + + if( fi != configuration.end() ) + { + + report( "Found parameter " << fi->first << " set to " + << fi->second ); + value = fi->second; + + } + else + { + + report( "Did not find parameter " << identifier << " set to " + << defaultValue ); + value = defaultValue; + + } + + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/ELFFile.cpp b/ocelot/ThirdParty/hydrazine/src/ELFFile.cpp new file mode 100644 index 00000000..04de4ae5 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/ELFFile.cpp @@ -0,0 +1,436 @@ +/* \file ELFFile.cpp + \author Gregory Diamos + \date Thursday March 17, 2011 + \brief The source file for the ELFFile class. +*/ + +#ifndef ELF_FILE_CPP_INCLUDED +#define ELF_FILE_CPP_INCLUDED + +// Hydrazine Includes +#include +#include + +// Standard Library Includes +#include + +// Preprocessor Macros +#ifdef REPORT_BASE +#undef REPORT_BASE +#endif + +#define REPORT_BASE 0 + +namespace hydrazine +{ + +ELFFile::Header::Header(const void* d, const elf::Elf64_Ehdr& h) +: _header(h) +{ + if(d != 0) + { + std::memcpy(&_header, d, sizeof(elf::Elf64_Ehdr)); + } + + assertM(!checkMagic() || _header.e_type == elf::ELFCLASS64, + "Only 64-bit ELF files are supported for now."); + assertM(!checkMagic() || _header.e_ident[5] == elf::ELFDATA2LSB, + "No support for big-endian ELF files." ); +} + +const elf::Elf64_Ehdr& ELFFile::Header::header() const +{ + return _header; +} + +bool ELFFile::Header::checkMagic() const +{ + bool isMagic = ( + header().e_ident[0] == elf::ElfMagic[0] + && header().e_ident[1] == elf::ElfMagic[1] + && header().e_ident[2] == elf::ElfMagic[2] + && header().e_ident[3] == elf::ElfMagic[3] ); + + return isMagic; +} + +unsigned int ELFFile::Header::sectionHeaders() const +{ + return header().e_shnum; +} + +unsigned int ELFFile::Header::programHeaders() const +{ + return header().e_phnum; +} + +ELFFile::SymbolHeader::SymbolHeader(const void* d, long long unsigned int b, + const elf::Elf64_Sym& h) +: _header(h) +{ + if(d != 0) + { + std::memcpy(&_header, (char*)d + b, sizeof(elf::Elf64_Sym)); + } +} + +const elf::Elf64_Sym& ELFFile::SymbolHeader::header() const +{ + return _header; +} + +int ELFFile::SymbolHeader::type() const +{ + return _header.st_info & 0xf; +} + +ELFFile::SectionHeader::SectionHeader(const void* d, long long unsigned int b, + const elf::Elf64_Shdr& h) +: _header(h) +{ + if(d != 0) + { + std::memcpy(&_header, (char*)d + b, sizeof(elf::Elf64_Shdr)); + } +} + +const elf::Elf64_Shdr& ELFFile::SectionHeader::header() const +{ + return _header; +} + +ELFFile::ProgramHeader::ProgramHeader(const void* d, long long unsigned int b, + const elf::Elf64_Phdr& h) +: _header(h) +{ + if(d != 0) + { + std::memcpy(&_header, (char*)d + b, sizeof(elf::Elf64_Phdr)); + } +} + +const elf::Elf64_Phdr& ELFFile::ProgramHeader::header() const +{ + return _header; +} + +ELFFile::ELFFile(const void* d) +: _elfdata(d), _header(d), _symbolTableOffset(-1) +{ + _loadedPrograms.resize(programs(), false); + _programs.resize(programs()); + + _loadedSections.resize(sections(), false); + _sections.resize(sections()); + + report("Loading ELF file: \n" << *this); +} + +const ELFFile::Header& ELFFile::header() const +{ + return _header; +} + +unsigned int ELFFile::sections() const +{ + return header().sectionHeaders(); +} + +ELFFile::SectionHeader& ELFFile::sectionHeader(unsigned int h) +{ + _loadSection(h); + + return _sections[h]; +} + +unsigned int ELFFile::programs() const +{ + return header().programHeaders(); +} + +ELFFile::ProgramHeader& ELFFile::programHeader(unsigned int h) +{ + _loadProgram(h); + + return _programs[h]; +} + +const void* ELFFile::endOfFile() +{ + return (const char*) _elfdata + header().header().e_phoff + + sizeof(elf::Elf64_Phdr) * (programs() + 1); +} + +unsigned int ELFFile::symbols() +{ + _findSymbolTable(); + + return _symbols.size(); +} + +ELFFile::SymbolHeader& ELFFile::symbolHeader(unsigned int h) +{ + _loadSymbol(h); + + return _symbols[h]; +} + +const char* ELFFile::getSectionHeaderStringAtOffset( + long long unsigned int offset) +{ + SectionHeader& stringTableSection = sectionHeader( + header().header().e_shstrndx); + + return (const char*) _elfdata + + stringTableSection.header().sh_offset + offset; +} + +const char* ELFFile::getSymbolStringAtOffset( + long long unsigned int offset) +{ + _findSymbolTable(); + + report("Getting symbol string at " << std::hex + << (_symbolStringTableOffset + offset) << std::dec); + + return (const char*) _elfdata + _symbolStringTableOffset + offset; +} + +void ELFFile::write(std::ostream& out) +{ + out << "ELF Header:\n"; + out << " data sections: " << sections() << "\n"; + out << " program sections: " << programs() << "\n"; + out << " symbols: " << symbols() << "\n"; + out << " program header table offset: " + << std::hex << header().header().e_phoff << std::dec << "\n"; + out << " section header table offset: " + << std::hex << header().header().e_shoff << std::dec << "\n"; + + out << "\n"; + + for(unsigned int s = 0; s < sections(); ++s) + { + int type = sectionHeader(s).header().sh_type; + out << "Section " << s << " Header:\n"; + out << " name: '" + << getSectionHeaderStringAtOffset(sectionHeader(s).header().sh_name) + << "'\n"; + out << " type: '" + << sectionTypeToString(type) << "'\n"; + out << " size in memory: " + << sectionHeader(s).header().sh_size << "\n"; + out << " offset: " + << std::hex << sectionHeader(s).header().sh_offset + << std::dec << "\n"; + if(sectionTypeHasLink(type)) + { + out << " link: " << sectionLinkToString(type) + << " (section " << sectionHeader(s).header().sh_link << ")" + << "\n"; + } + out << "\n"; + } + + for(unsigned int p = 0; p < programs(); ++p) + { + out << "Program " << p << " Header:\n"; + out << " type: '" + << programTypeToString(programHeader(p).header().p_type) << "'\n"; + out << " size in memory: " << programHeader(p).header().p_memsz << "\n"; + out << " offset: " + << std::hex << programHeader(p).header().p_offset + << std::dec << "\n"; + out << "\n"; + } + + for(unsigned int s = 0; s < symbols(); ++s) + { + out << "Symbol " << s << " Header:\n"; + out << " name: '" + << getSymbolStringAtOffset(symbolHeader(s).header().st_name) + << "'\n"; + out << " type: '" + << symbolTypeToString(symbolHeader(s).type()) << "'\n"; + out << " size in memory: " + << symbolHeader(s).header().st_size << "\n"; + out << " value: " + << symbolHeader(s).header().st_value << "\n"; + out << " containing section: " + << symbolHeader(s).header().st_shndx << "\n"; + + out << "\n"; + } +} + +std::string ELFFile::programTypeToString(int type) +{ + switch(type) + { + case elf::PT_NULL: return "unused entry"; + case elf::PT_LOAD: return "loadable segment"; + case elf::PT_DYNAMIC: return "dynamic linking information"; + case elf::PT_INTERP: return "interpreter pathname"; + case elf::PT_NOTE: return "a note"; + case elf::PT_SHLIB: return "reserved"; + case elf::PT_PHDR: return "the program header table"; + case elf::PT_LOOS: return "low operating system"; + case elf::PT_HIOS: return "high operating system"; + case elf::PT_LOPROC: return "lowest processor specific program"; + case elf::PT_HIPROC: return "highest processor specific program"; + default: break; + } + + return ""; +} + +std::string ELFFile::sectionTypeToString(int type) +{ + switch(type) + { + case elf::SHT_NULL: return "null section"; + case elf::SHT_PROGBITS: return "program defined"; + case elf::SHT_SYMTAB: return "symbol table"; + case elf::SHT_STRTAB: return "string table"; + case elf::SHT_RELA: return "relocations (addends)"; + case elf::SHT_HASH: return "symbol hash table"; + case elf::SHT_DYNAMIC: return "dynamic linking information"; + case elf::SHT_NOTE: return "information about the file"; + case elf::SHT_NOBITS: return "blank data with 0 size"; + case elf::SHT_REL: return "relocations"; + case elf::SHT_SHLIB: return "reserved"; + case elf::SHT_DYNSYM: return "dynamic symbol table"; + case elf::SHT_INIT_ARRAY: return "pointers to initialization functions"; + case elf::SHT_FINI_ARRAY: return "pointers to termination functions"; + case elf::SHT_PREINIT_ARRAY: return "pointers to pre-init functions"; + case elf::SHT_GROUP: return "section group"; + case elf::SHT_SYMTAB_SHNDX: return "SHNDX entries"; + case elf::SHT_LOOS: return "lowest OS type"; + case elf::SHT_HIOS: return "highest OS type"; + case elf::SHT_LOPROC: return "lowest processor type"; + case elf::SHT_HIPROC: return "highest processor type"; + case elf::SHT_LOUSER: return "lowest application type"; + case elf::SHT_HIUSER: return "highest application type"; + default: break; + } + + return ""; +} + +std::string ELFFile::sectionLinkToString(int type) +{ + switch(type) + { + case elf::SHT_DYNAMIC: return "string table used by entries"; + case elf::SHT_HASH: return "symbol table that the has applies to"; + case elf::SHT_REL: return "symbol table referenced by relocs"; + case elf::SHT_RELA: return "symbol table referenced by relocs"; + case elf::SHT_SYMTAB: return "string table used by entries"; + case elf::SHT_DYNSYM: return "string table used by entries"; + default: break; + } + + return "undefined"; +} + +bool ELFFile::sectionTypeHasLink(int type) +{ + return type == elf::SHT_DYNAMIC + || type == elf::SHT_HASH + || type == elf::SHT_REL + || type == elf::SHT_RELA + || type == elf::SHT_SYMTAB + || type == elf::SHT_DYNSYM; +} + +std::string ELFFile::symbolTypeToString(int type) +{ + switch(type) + { + case elf::STT_NOTYPE: return "type not specified"; + case elf::STT_OBJECT: return "data object"; + case elf::STT_FUNC: return "executable object (code)"; + case elf::STT_SECTION: return "a section"; + case elf::STT_FILE: return "local absolute reference to a file"; + case elf::STT_LOPROC: return "lowest processor specific type"; + case elf::STT_HIPROC: return "highest processor specific type"; + default: break; + } + + return ""; +} + +void ELFFile::_loadProgram(unsigned int h) +{ + assert(h < programs()); + + if(!_loadedPrograms[h]) + { + long long unsigned int offset = header().header().e_phoff + + h * header().header().e_phentsize; + _programs[h] = ProgramHeader(_elfdata, offset); + _loadedPrograms[h] = true; + } +} + +void ELFFile::_loadSection(unsigned int h) +{ + assert(h < sections()); + + if(!_loadedSections[h]) + { + long long unsigned int offset = header().header().e_shoff + + h * header().header().e_shentsize; + _sections[h] = SectionHeader(_elfdata, offset); + _loadedSections[h] = true; + } +} + +void ELFFile::_loadSymbol(unsigned int h) +{ + _findSymbolTable(); + + assert(h < symbols()); + + if(!_loadedSymbols[h]) + { + long long unsigned int offset = _symbolTableOffset + + (h + 1) * sizeof(elf::Elf64_Sym); + _symbols[h] = SymbolHeader(_elfdata, offset); + _loadedSymbols[h] = true; + } +} + +void ELFFile::_findSymbolTable() +{ + if(_symbolTableOffset != (long long unsigned int)-1) return; + + for(unsigned int s = 0; s < sections(); ++s) + { + const elf::Elf64_Shdr& header = sectionHeader(s).header(); + if(header.sh_type == elf::SHT_SYMTAB) + { + _symbolTableOffset = header.sh_offset; + _symbolStringTableOffset = + sectionHeader(header.sh_link).header().sh_offset; + unsigned int symbols = + (header.sh_size / sizeof(elf::Elf64_Sym)) - 1; + _symbols.resize(symbols); + _loadedSymbols.resize(symbols, false); + break; + } + } + + report("Found " << _symbols.size() << " symbols of size " + << sizeof(elf::Elf64_Sym)); +} + +} + +std::ostream& operator<<(std::ostream& out, hydrazine::ELFFile& elf) +{ + elf.write(out); + return out; +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/Exception.cpp b/ocelot/ThirdParty/hydrazine/src/Exception.cpp new file mode 100644 index 00000000..4ad0b34f --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/Exception.cpp @@ -0,0 +1,38 @@ +/*! \file Exception.cpp +* +* \brief Source file for the Exception class. +* +* \author Gregory Diamos +* +* +*/ + +#ifndef EXCEPTION_CPP_INCLUDED +#define EXCEPTION_CPP_INCLUDED + +#include + + +namespace hydrazine +{ + const char* Exception::what() const throw() + { + return _message.c_str(); + + } + + Exception::~Exception() throw() + { + + } + + Exception::Exception( const std::string& m ) : + _message( m ) + { + + + + } +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/FloatingPoint.cpp b/ocelot/ThirdParty/hydrazine/src/FloatingPoint.cpp new file mode 100644 index 00000000..e7197abd --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/FloatingPoint.cpp @@ -0,0 +1,163 @@ +/*! \file FloatingPoint.cpp + \date Friday August 26, 2011 + \author Gregory Diamos + \brief The source file for platform independent floating point modifiers. +*/ + +#ifndef FLOATING_POINT_CPP_INCLUDED +#define FLOATING_POINT_CPP_INCLUDED + +// Hydrazine Includes +#include +#include + +// Standard Library Includes +#include +#include +#include + +namespace hydrazine +{ + +int fegetround() +{ + #ifndef _WIN32 + return ::fegetround(); + #else + return 0; // TODO fix this + #endif +} + +int fesetround(int value) +{ + #ifndef _WIN32 + return ::fesetround(value); + #else + return 0; // TODO fix this + #endif +} + +float copysign(float value, float sign) +{ + #ifndef _WIN32 + return std::copysign(value, sign); + #else + // This is why I think that windows code is ugly... + return ::_copysign(value, sign); + #endif +} + +bool isnan(float value) +{ + #ifndef _WIN32 + return std::isnan(value); + #else + return ::_isnan(value); + #endif +} + +bool isinf(float value) +{ + #ifndef _WIN32 + return std::isinf(value); + #else + return !::_finite(value); + #endif +} + +bool isnormal(float value) +{ + #ifndef _WIN32 + return std::isnormal(value); + #else + return ::_fpclass(value) & (_FPCLASS_NN | _FPCLASS_PN); + #endif +} + +float nearbyintf(float value) +{ + float result = 0.0f; + + #ifndef _WIN32 + result = std::nearbyintf(value); + #else + if(0.5f == (value - std::floor(value))) + { + // Round up if odd, down if even + result = (uint64_t(std::floor(value)) & 1) ? /* if odd */ + (std::floor(value) + 1.0f) : /* rount to next val */ + std::floor(value); /* round to num */ + } + else if(-0.5 == (value + std::ceil(value))) + { + // Round down if odd, up if even + result = (uint64_t(std::ceil(value)) & 1) ? /* if odd */ + (std::ceil(value) - 1.0f) : /* rount to next val */ + std::ceil(value); /* round to num */ + } + else + { + // Round to nearest + if(value < 0.0f) + { + result = std::ceil(value - 0.5); + } + else + { + result = std::floor(value + 0.5); + } + } + + #endif + + return result; +} + +double nearbyintf(double value) +{ + #ifndef _WIN32 + return std::nearbyint(value); + #else + return value; // TODO fix this + #endif +} + +float trunc(float value) +{ + #ifndef _WIN32 + return std::trunc(value); + #else + return value; // TODO fix this + #endif +} + +double trunc(double value) +{ + #ifndef _WIN32 + return std::trunc(value); + #else + return value; // TODO fix this + #endif +} + +float exp2f(float value) +{ + #ifndef _WIN32 + return std::exp2f(value); + #else + return powf(2,value); + #endif +} + +float log2f(float value) +{ + #ifndef _WIN32 + return std::log2f(value); + #else + return ::logf(value) * 1.44269504088896340736f; + #endif +} + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/LowLevelTimer.cpp b/ocelot/ThirdParty/hydrazine/src/LowLevelTimer.cpp new file mode 100644 index 00000000..11da3ccb --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/LowLevelTimer.cpp @@ -0,0 +1,115 @@ +/*! \file LowLevelTimer.cpp +* +* \brief Source file for the LowLevelTimer class +* +* Author: Gregory Diamos +* +* +*/ + +#ifndef LOW_LEVEL_TIMER_CPP_INCLUDED +#define LOW_LEVEL_TIMER_CPP_INCLUDED + +#ifdef _WIN32 + #include +#elif __APPLE__ + #include +#endif + +#include + +namespace hydrazine +{ + + LowLevelTimer::LowLevelTimer() + { + start(); + } + + void LowLevelTimer::start() + { + beginning = rdtsc(); + beginningS = ( beginning + 0.0 ) * 1.0e-9; + running = true; + } + + void LowLevelTimer::stop() + { + ending = rdtsc(); + + endingS = ( ending + 0.0 ) * 1.0e-9; + + running = false; + } + + LowLevelTimer::Cycle LowLevelTimer::cycles() const + { + if( running ) + { + return ( rdtsc() - beginning ); + } + else + { + return ( ending - beginning ); + } + } + + LowLevelTimer::Second LowLevelTimer::seconds() const + { + if( running ) + { + return ( ( ( rdtsc() + 0.0 ) * 1.0e-9 ) - beginningS ); + } + else + { + return endingS - beginningS; + } + } + + LowLevelTimer::Second LowLevelTimer::absolute() const + { + if( running ) + { + return ( ( ( rdtsc() + 0.0 ) * 1.0e-9 ) ); + } + else + { + return endingS; + } + } + + extern "C" + { + LowLevelTimer::Cycle LowLevelTimer::rdtsc() + { +#ifdef _WIN32 + Cycle cycles = 0; + Cycle frequency = 0; + QueryPerformanceFrequency((LARGE_INTEGER*) &frequency); + QueryPerformanceCounter((LARGE_INTEGER*) &cycles); + return cycles / frequency; + +#elif __APPLE__ + uint64_t absolute_time = mach_absolute_time(); + mach_timebase_info_data_t info = {0,0}; + + if (info.denom == 0) mach_timebase_info(&info); + uint64_t elapsednano = absolute_time * (info.numer / info.denom); + + timespec spec; + spec.tv_sec = elapsednano * 1e-9; + spec.tv_nsec = elapsednano - (spec.tv_sec * 1e9); + return spec.tv_nsec + (Cycle)spec.tv_sec * 1e9; +#else + timespec spec; + + clock_gettime( CLOCK_REALTIME, &spec ); + + return spec.tv_nsec + (Cycle)spec.tv_sec * 1e9; +#endif + + } + } +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/SystemCompatibility.cpp b/ocelot/ThirdParty/hydrazine/src/SystemCompatibility.cpp new file mode 100644 index 00000000..e2022fdf --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/SystemCompatibility.cpp @@ -0,0 +1,112 @@ +/*! \file SystemCompatibility.h + \date Monday August 2, 2010 + \author Gregory Diamos + \brief The header file for hacked code required to assist windows + compilaiton +*/ + +#ifndef SYSTEM_COMPATIBILITY_CPP_INCLUDED +#define SYSTEM_COMPATIBILITY_CPP_INCLUDED + +// Hydrazine includes +#include + +#if __APPLE__ + #include + #include +#elif __GNUC__ + #include + #include + #include + #include +#else + #error "Unknown system/compiler (APPLE and GNUC are supported)." +#endif + +namespace hydrazine +{ + unsigned int getHardwareThreadCount() + { + #if __APPLE__ + int nm[2]; + size_t len = 4; + uint32_t count; + + nm[0] = CTL_HW; + nm[1] = HW_AVAILCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + + if(count < 1) + { + nm[1] = HW_NCPU; + sysctl(nm, 2, &count, &len, NULL, 0); + if(count < 1) + { + count = 1; + } + } + return count; + #elif __GNUC__ + return sysconf(_SC_NPROCESSORS_ONLN); + #endif + } + + std::string getExecutablePath(const std::string& executableName) + { + return executableName; + } + + long long unsigned int getFreePhysicalMemory() + { + #if __APPLE__ + int mib[2]; + uint64_t physical_memory; + size_t length; + // Get the Physical memory size + mib[0] = CTL_HW; + mib[1] = HW_USERMEM; // HW_MEMSIZE -> physical memory + length = sizeof(uint64_t); + sysctl(mib, 2, &physical_memory, &length, NULL, 0); + return physical_memory; + #elif __GNUC__ + return get_avphys_pages() * getpagesize(); + #endif + } + + bool isAnOpenGLContextAvailable() + { + #if __APPLE__ + // TODO fill this in + return false; + #elif __GNUC__ + GLXContext openglContext = glXGetCurrentContext(); + return (openglContext != 0); + #endif + } + + bool isMangledCXXString(const std::string& string) + { + return string.find("_Z") == 0; + } + + std::string demangleCXXString(const std::string& string) + { + #if __APPLE__ + // TODO fill this in + return string; + #elif __GNUC__ + int status = 0; + std::string name = abi::__cxa_demangle(string.c_str(), + 0, 0, &status); + if(status < 0) + { + name = string; + } + + return name; + #endif + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/Test.cpp b/ocelot/ThirdParty/hydrazine/src/Test.cpp new file mode 100644 index 00000000..48811be9 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/Test.cpp @@ -0,0 +1,123 @@ +/*! + \file Test.cpp + \author Gregory Diamos + \date July 4 2008 + \brief Contains the class implementation for the Test infertace +*/ + +#ifndef TEST_CPP_INCLUDED +#define TEST_CPP_INCLUDED + +#include +#include +#include +#include + +namespace test +{ + + void Test::_seed() + { + if( seed == 0 ) + { + seed = (unsigned int) std::time( 0 ); + } + random.seed( seed ); + } + + Test::Test() + { + _testRun = false; + _passed = false; + verbose = false; + seed = 0; + } + + Test::~Test() + { + + } + + void Test::test() + { + assert( !_testRun ); + hydrazine::Timer Timer; + + _seed(); + Timer.start(); + _passed = doTest( ); + Timer.stop(); + _time = Timer.seconds(); + _testRun = true; + + if( verbose ) + { + std::cout << toString() << std::flush; + } + } + + std::string Test::toString() const + { + std::stringstream stream; + if( _testRun ) + { + if( _passed ) + { + stream << "Pass/Fail : Pass\n\n"; + } + else + { + stream << "Pass/Fail : Fail\n\n"; + } + } + + stream << "\nName : " << name << "\n\n"; + stream << testDescription() << "\n\n"; + + if( _testRun ) + { + stream << "Test Seed : " << seed << "\n"; + stream << "Test time : " << _time << "\n\n"; + stream << "Status : " << status.str() << "\n\n"; + } + + return stream.str(); + } + + std::string Test::testStatus() const + { + assert( _testRun ); + return status.str(); + } + + const std::string& Test::testName() const + { + return name; + } + + std::string Test::testDescription() const + { + return hydrazine::format( description, "Description: ", + " " ); + } + + bool Test::passed() const + { + assert( _testRun ); + return !_passed; + } + + bool Test::run() const + { + return _testRun; + } + + hydrazine::Timer::Second Test::time() const + { + assert( _testRun ); + return _time; + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/Thread.cpp b/ocelot/ThirdParty/hydrazine/src/Thread.cpp new file mode 100644 index 00000000..d6af9df9 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/Thread.cpp @@ -0,0 +1,429 @@ +/*! + \file Thread.cpp + + \author Gregory Diamos + \date 4/10/2008 + + \brief The source file for the thread class + This file provides a class wrapper for pthreads +*/ + +#ifndef THREAD_CPP_INCLUDED +#define THREAD_CPP_INCLUDED + +#include + +#include +#include + +#ifdef _WIN32 +#include +#endif + +#ifdef REPORT_BASE +#undef REPORT_BASE +#endif + +#define REPORT_BASE 0 + +namespace hydrazine +{ + + Thread::Queue::Queue() + { + + } + + Thread::Queue::~Queue() + { + assert( _queue.empty() ); + + } + + void Thread::Queue::push( const Message& message ) + { + _mutex.lock(); + + _queue.push_back( message ); + + _condition.notify_all(); + _mutex.unlock(); + } + + Thread::Message Thread::Queue::pull( Id id ) + { + Message result; + result.type = Message::Invalid; + + // lock is implied + boost::unique_lock lock(_mutex); + + while( result.type == Message::Invalid ) + { + for( MessageQueue::iterator message = _queue.begin(); + message != _queue.end(); ++message ) + { + if( _compare( message->source, id ) ) + { + assert( message->type != Message::Invalid ); + result = *message; + _queue.erase( message ); + break; + } + } + + if( result.type == Message::Invalid ) + { + _condition.wait( lock ); + } + } + + lock.unlock(); + + return result; + } + + bool Thread::Queue::test( Id& id, bool block ) + { + bool found = false; + + // lock is implied + boost::unique_lock lock( _mutex ); + + do + { + for( MessageQueue::iterator message = _queue.begin(); + message != _queue.end(); ++message ) + { + if( _compare( message->source, id ) ) + { + assert( message->type != Message::Invalid ); + id = message->source; + found = true; + break; + } + } + + if( block && !found ) + { + _condition.wait( lock ); + } + } + while( block && !found ); + + lock.unlock(); + + return found; + } + + Thread::Group::Group() + { + + } + + Thread::Group::~Group() + { + assert( empty() ); + } + + void Thread::Group::add( Thread* thread ) + { + _mutex.lock(); + + assert( _threads.count( thread->id() ) == 0 ); + + _threads.insert( std::make_pair( thread->id(), thread ) ); + + _mutex.unlock(); + } + + void Thread::Group::remove( Thread* thread ) + { + _mutex.lock(); + + assert( _threads.count( thread->id() ) != 0 ); + + _threads.erase( thread->id() ); + + _mutex.unlock(); + } + + Thread* Thread::Group::find( Id id ) + { + Thread* result = 0; + + _mutex.lock(); + + ThreadMap::iterator thread = _threads.find( id ); + + if( thread != _threads.end() ) + { + result = thread->second; + } + + _mutex.unlock(); + + return result; + } + + void Thread::Group::push( const Message& message ) + { + assert( message.destination != THREAD_ANY_ID ); + + if( message.destination == THREAD_CONTROLLER_ID ) + { + assert( _threads.count( message.source ) != 0 ); + _controllerQueue.push( message ); + } + else + { + _mutex.lock(); + + ThreadMap::iterator thread = _threads.find( message.destination ); + assert( thread != _threads.end() ); + + thread->second->_threadQueue.push( message ); + + _mutex.unlock(); + } + } + + Thread::Message Thread::Group::pull( Id source ) + { + return _controllerQueue.pull( source ); + } + + bool Thread::Group::test( Id& source, bool block ) + { + return _controllerQueue.test( source, block ); + } + + bool Thread::Group::empty() const + { + return _threads.empty(); + } + + unsigned int Thread::Group::size() const + { + return _threads.size(); + } + + Thread::Id Thread::_nextId = THREAD_START_ID; + + void* Thread::_launch( void* argument ) + { + Thread* thread = static_cast< Thread* >( argument ); + thread->execute(); + return 0; + } + + bool Thread::_compare( Id one, Id two ) + { + return one == two || one == THREAD_ANY_ID || two == THREAD_ANY_ID; + } + + bool Thread::threadTest( Id id ) + { + bool null = false; + return _threadQueue.test( id, null ); + } + + void Thread::threadSend( MessageData data, Thread::Id id ) + { + + assert( id != THREAD_ANY_ID ); + assert( _id != id ); + + Message message; + message.source = _id; + message.destination = id; + message.payload = data; + message.type = Message::Regular; + + report( "Thread " << _id << " sending message to " + << message.destination << "." ); + assert( _group != 0 ); + _group->push( message ); + + } + + Thread::Thread() + { + _id = _nextId++; + _running = false; + _group = new Group; + _group->add( this ); + _thread = 0; + } + + Thread::Thread( const Thread& t ) + { + _id = _nextId++; + _running = false; + _group = new Group; + _group->add( this ); + _thread = 0; + } + + const Thread& Thread::operator=( const Thread& t ) + { + assert( _running == false ); + assert( _group->size() == 1 ); + assert( t._group->size() == 1 ); + assert( t._running == false ); + return *this; + } + + Thread::~Thread() + { + if( _running ) + { + join(); + } + + assert( !_running ); + + _group->remove( this ); + + if( _group->empty() ) + { + delete _group; + } + } + + void Thread::start() + { + assert( !_running ); + + _running = true; + + report( "Thread " << _id << " starting." ); + + _thread = new boost::thread( Thread::_launch, this ); + } + + void Thread::join() + { + assert( _running ); + + report( "Thread " << _id << " joining." ); + + _thread->join(); + delete _thread; + _thread = 0; + + _running = false; + } + + void Thread::associate( Thread* t ) + { + assert( _group->size() == 1 || t->_group->size() == 1 ); + assert( id() != t->id() ); + + if( _group->size() == 1 ) + { + report( "Thread " << _id << " joining group with thread " + << t->id() << "." ); + _group->remove( this ); + delete _group; + _group = t->_group; + _group->add( this ); + } + else + { + report( "Thread " << t->id() << " joining group with thread " + << id() << "." ); + t->_group->remove( t ); + delete t->_group; + t->_group = _group; + _group->add( t ); + } + } + + void Thread::remove() + { + report( "Thread " << _id << " leaving group." ); + assert( !_group->empty() ); + + if( _group->size() > 1 ) + { + report( " Thread " << _id << " destroying group." ); + + _group->remove( this ); + _group = new Group; + } + } + + void Thread::send( MessageData data ) + { + report( "Thread " << _id + << " sending message from controller to local thread." ); + + Message message; + message.source = THREAD_CONTROLLER_ID; + message.destination = _id; + message.payload = data; + message.type = Message::Regular; + + _group->push( message ); + } + + bool Thread::test( bool block ) + { + return _group->test( _id, block ); + } + + std::pair< Thread::Id, bool > Thread::testGroup( bool block, Id source ) + { + std::pair< Id, bool > result; + + result.first = source; + result.second = _group->test( result.first, block ); + + assert( !block || result.second ); + + return result; + } + + Thread::Id Thread::id() const + { + return _id; + } + + bool Thread::started() const + { + return _running; + } + + bool Thread::killed() const + { + if(!started()) + { + return true; + } + else + { + #ifdef _WIN32 + DWORD code = 0; + GetExitCodeThread(_thread->native_handle(), &code); + return code != STILL_ACTIVE; + #else + return false; + #endif + } + } + + Thread* Thread::find( Thread::Id id ) + { + report( "Looking up thread with id " << id ); + + if( id == _id ) + { + return this; + } + return _group->find( id ); + } +} + +//////////////////////////////////////////////////////////////////////////////// +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/Timer.cpp b/ocelot/ThirdParty/hydrazine/src/Timer.cpp new file mode 100644 index 00000000..6076ffbe --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/Timer.cpp @@ -0,0 +1,28 @@ +/*! \file Timer.cpp +* +* \brief Source file for the Timer class +* +* Author: Gregory Diamos +* +* +*/ + +#ifndef TIMER_CPP_INCLUDED +#define TIMER_CPP_INCLUDED + +#include +#include + +namespace hydrazine +{ + std::string Timer::toString() const + { + std::stringstream stream; + + stream << seconds() << "s (" << cycles() << " ns)"; + + return stream.str(); + } +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/XmlArgumentParser.cpp b/ocelot/ThirdParty/hydrazine/src/XmlArgumentParser.cpp new file mode 100644 index 00000000..e5ebaf47 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/XmlArgumentParser.cpp @@ -0,0 +1,73 @@ +/*! + + \file XmlArgumentParser.cpp + + \date Monday September 15, 2008 + + \author Gregory Diamos + + \brief The source file for the XmlArgumentParser class. + +*/ + +#ifndef XML_ARGUMENT_PARSER_CPP_INCLUDED +#define XML_ARGUMENT_PARSER_CPP_INCLUDED + +#include + +namespace hydrazine +{ + + XmlArgumentParser::XmlArgumentParser( const std::string& fileName ) + { + + XmlParser parser( fileName ); + _tree = parser.tree(); + _treeIterator = _tree.begin(); + + } + + XmlArgumentParser::~XmlArgumentParser() + { + + + } + + void XmlArgumentParser::ascend( ) + { + + _treeIterator.ascend( ); + + } + + void XmlArgumentParser::reset( ) + { + + _treeIterator = _tree.begin(); + + } + + void XmlArgumentParser::descend( const std::string& tag ) + { + + _treeIterator.descend( tag ); + + } + + const std::string& XmlArgumentParser::tag() const + { + + return _treeIterator->identifier; + + } + + const XmlTree& XmlArgumentParser::tree() const + { + + return _tree; + + } + +} + +#endif diff --git a/ocelot/ThirdParty/hydrazine/src/XmlLexer.cpp b/ocelot/ThirdParty/hydrazine/src/XmlLexer.cpp new file mode 100644 index 00000000..a5cce996 --- /dev/null +++ b/ocelot/ThirdParty/hydrazine/src/XmlLexer.cpp @@ -0,0 +1,436 @@ +/*! + + \file XmlLexer.cpp + + \date Saturday September 13, 2008 + + \author Gregory Diamos + + \brief The source file for the XmlLexer class. + +*/ + +#ifndef XML_LEXER_CPP_INCLUDED +#define XML_LEXER_CPP_INCLUDED + +#include +#include +#include + +#include + +#ifdef REPORT_BASE +#undef REPORT_BASE +#endif + +#define REPORT_BASE 0 + +namespace hydrazine +{ + + bool XmlLexer::devourComment() + { + + report( "Checking for comments." ); + + devourWhiteSpace(); + + char commentBegin[5]; + commentBegin[4] = 0; + std::streampos position = file.tellg(); + file.readsome( commentBegin, 4 ); + + if( file.gcount() == 4 ) + { + + if( !strcmp( "