diff --git a/.travis/regression.sh b/.travis/regression.sh
index da8431965..5d9be167d 100755
--- a/.travis/regression.sh
+++ b/.travis/regression.sh
@@ -11,12 +11,12 @@ compiled_file="compiled_$benchmark"
tb_formal_postfix="_top_formal_verification_random_tb"
verilog_output_dirname="${benchmark}_Verilog"
log_file="${benchmark}_sim.log"
+new_reg_sh="my_regression.sh"
cd $fpga_flow_scripts
-perl rewrite_path_in_file.pl -i $vpr_path/regression_verilog.sh
-perl rewrite_path_in_file.pl -i $vpr_path/VerilogNetlists/ff.v
+perl rewrite_path_in_file.pl -i $vpr_path/regression_verilog.sh -o $vpr_path/$new_reg_sh
cd $my_pwd
@@ -28,7 +28,7 @@ rm -f $log_file
rm -f $compiled_file
# Start the script -> run the fpga generation -> run the simulation -> check the log file
-source regression_verilog.sh
+source $new_reg_sh
iverilog -o $compiled_file $verilog_output_dirname/SRC/$benchmark$include_netlists -s $benchmark$tb_formal_postfix
vvp $compiled_file -j 16 >> $log_file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cff30ba79..f3d4730f9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -137,6 +137,7 @@ enable_testing()
add_subdirectory(yosys)
add_subdirectory(abc)
add_subdirectory(ace2)
+add_subdirectory(libs)
add_subdirectory(vpr7_x2p)
# run make to extract compiler options, linker options and list of source files
@@ -175,8 +176,13 @@ set_target_properties(libace ace
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ace2"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ace2")
-
# Set output locations to be in the main source tree under the relevant folder
+set_target_properties(libvtrutil
+ PROPERTIES
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/libs/libvtrutil"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/libs/libvtrutil"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/libs/libvtrutil")
+
set_target_properties(libarchfpga read_arch
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/vpr7_x2p/libarchfpga"
diff --git a/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml b/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml
index b7630261f..a56d6b3cb 100644
--- a/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml
+++ b/fpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml
@@ -330,7 +330,7 @@
-
+
@@ -372,7 +372,7 @@
-
+
diff --git a/fpga_flow/benchmarks/Blif/Test_Modes/test_modes.power b/fpga_flow/benchmarks/Blif/Test_Modes/test_modes.power
deleted file mode 100644
index b9730e324..000000000
--- a/fpga_flow/benchmarks/Blif/Test_Modes/test_modes.power
+++ /dev/null
@@ -1,172 +0,0 @@
------------------------------------ Summary ------------------------------------
-Circuit: /research/ece/lnis/USERS/tang/github/OpenFPGA/fpga_flow/benchmarks/Blif/Test_Modes/test_modes
-Architecture: k6_N10_sram_chain_HC_template.xml
-Technology (nm): 45
-Voltage: 0.90
-Temperature: 85
-Critical Path: 5.8141e-09
-Size of FPGA: 2 x 2
-Channel Width: 200
-
------------------------------------ Warnings -----------------------------------
-No transistor counter function for BLIF model: .frac_lut6
-No transistor counter function for BLIF model: .subckt adder
-No transistor counter function for BLIF model: .subckt shift
-Attempted to search for a transistor with a capacitance smaller than the smallest in the technology file.
-
-No dynamic power defined for BLIF model: .subckt adder
-No leakage power defined for BLIF model: .subckt adder
-No dynamic power defined for BLIF model: .frac_lut6
-No leakage power defined for BLIF model: .frac_lut6
-No dynamic power defined for BLIF model: .subckt shift
-No leakage power defined for BLIF model: .subckt shift
-
-------------------------------- Power Breakdown --------------------------------
-Component Power (W) %-Total %-Dynamic Method
-
-Total 0.0002701 1 0.7897
- Routing 0.0001289 0.4773 0.7668
- Switch Box 2.212e-05 0.08191 0
- Connection Box 0.0001068 0.3954 0.9256
- Global Wires 0 0 -nan
- PB Types 8.066e-05 0.2986 0.6884
- Primitives 4.913e-05 0.1819 0.8837
- Interc Structures 8.866e-06 0.03283 0.5489
- Buffers and Wires 2.266e-05 0.08389 0.3197
- Other Estimation Methods 0 0 -nan
- Clock 6.051e-05 0.224 0.9736
-
----------------------------- Power Breakdown by PB -----------------------------
-This sections provides a detailed breakdown of power usage by PB (physical
-block). For each PB, the power is listed, which is the sum power of all
-instances of the block. It also indicates its percentage of total power (entire
-FPGA), as well as the percentage of its power that is dynamic (vs. static). It
-also indicates the method used for power estimation.
-
-The data includes:
- Modes: When a pb contains multiple modes, each mode is listed, with
- its power statistics.
- Bufs/Wires: Power of all local buffers and local wire switching
- (transistor-level estimation only).
- Interc: Power of local interconnect multiplexers (transistor-
- level estimation only)
-
-Description of Estimation Methods:
- Transistor Auto-Size: Transistor-level power estimation. Local buffers and
- wire lengths are automatically sized. This is the default estimation
- method.
- Transistor Specify-Size: Transistor-level power estimation. Local buffers
- and wire lengths are only inserted where specified by the user in the
- architecture file.
- Pin-Toggle: Dynamic power is calculated using enery-per-toggle of the PB
- input pins. Static power is absolute.
- C-Internal: Dynamic power is calculated using an internal equivalent
- capacitance for PB type. Static power is absolute.
- Absolute: Dynamic and static power are absolutes from the architecture file.
- Sum of Children: Power of PB is only the sum of all child PBs; interconnect
- between the PB and its children is ignored.
- Ignore: Power of PB is ignored.
-
-
-Component Power (W) %-Total %-Dynamic Method
-
-io 0 0 -nan Ignore
-clb 8.066e-05 0.2986 0.6884 Transistor Auto-Size
- Bufs/Wires 1.43e-05 0.05294 0.2804
- Interc: 8.462e-06 0.03133 0.542
- crossbar0 3.015e-06 0.01116 0.5188
- crossbar1 3.264e-06 0.01208 0.5568
- crossbar2 1.076e-06 0.003984 0.5484
- crossbar3 8.245e-07 0.003053 0.5364
- crossbar4 0 0 -nan
- crossbar5 0 0 -nan
- clks 0 0 -nan
- carry_in 2.821e-07 0.001045 0.6112
- fle 5.79e-05 0.2144 0.8106 Transistor Auto-Size
- Bufs/Wires 6.769e-06 0.02506 0.3446
- Mode:fle_phy 3.361e-05 0.1244 0.9139
- Interc: 0 0 -nan
- direct_clk 0 0 -nan
- mux1 0 0 -nan
- mux2 0 0 -nan
- frac_logic 3.388e-07 0.001254 0 Transistor Auto-Size
- Bufs/Wires 3.388e-07 0.001254 0
- Interc: 0 0 -nan
- mux1 0 0 -nan
- mux2 0 0 -nan
- frac_lut6 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- adder_phy 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- ff_phy 3.327e-05 0.1232 0.9232 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:n2_lut5 1.741e-05 0.06444 0.7925
- Interc: 0 0 -nan
- lut5inter 1.741e-05 0.06444 0.7925 Transistor Auto-Size
- Bufs/Wires 5.658e-07 0.002095 0.6977
- Interc: 0 0 -nan
- complete1 0 0 -nan
- ble5 1.684e-05 0.06235 0.7956 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:blut5 1.12e-05 0.04146 0.8091
- Interc: 0 0 -nan
- flut5 1.12e-05 0.04146 0.8091 Transistor Auto-Size
- Bufs/Wires 2.007e-07 0.000743 0.7628
- Interc: 2.646e-07 0.0009797 0.684
- mux1 2.646e-07 0.0009797 0.684
- lut5 1.655e-06 0.006127 0.2417 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:wire 0 0 -nan
- Interc: 0 0 -nan
- complete:lut5 0 0 -nan
- Mode:lut5 1.655e-06 0.006127 0.2417
- Interc: 0 0 -nan
- lut 1.655e-06 0.006127 0.2417 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- ff 9.079e-06 0.03361 0.9173 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:arithmetic 5.641e-06 0.02088 0.7689
- Interc: 0 0 -nan
- arithmetic 5.641e-06 0.02088 0.7689 Transistor Auto-Size
- Bufs/Wires 3.732e-07 0.001382 0.7081
- Interc: 1.399e-07 0.0005179 0.708
- sumout 1.399e-07 0.0005179 0.708
- lut4 7.913e-07 0.00293 0 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:wire 0 0 -nan
- Interc: 0 0 -nan
- complete:lut4 0 0 -nan
- Mode:lut4 7.913e-07 0.00293 0
- Interc: 0 0 -nan
- lut 7.913e-07 0.00293 0 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- adder 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- ff 4.336e-06 0.01606 0.9163 Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:n1_lut6 0 0 -nan
- Interc: 0 0 -nan
- ble6 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Interc: 0 0 -nan
- mux1 0 0 -nan
- lut6 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:wire 0 0 -nan
- Interc: 0 0 -nan
- complete:lut6 0 0 -nan
- Mode:lut6 0 0 -nan
- Interc: 0 0 -nan
- lut 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- ff 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
- Mode:shift_register 1.134e-07 0.0004199 0.7826
- Interc: 0 0 -nan
- ble_shift 1.134e-07 0.0004199 0.7826 Transistor Auto-Size
- Bufs/Wires 1.134e-07 0.0004199 0.7826
- Interc: 0 0 -nan
- direct3 0 0 -nan
- ff 0 0 -nan Transistor Auto-Size
- Bufs/Wires 0 0 -nan
-
diff --git a/fpga_flow/scripts/arch_rewrite.pl b/fpga_flow/scripts/arch_rewrite.pl
deleted file mode 100644
index 0a3274f50..000000000
--- a/fpga_flow/scripts/arch_rewrite.pl
+++ /dev/null
@@ -1,122 +0,0 @@
-#!usr/bin/perl -w
-use strict;
-use Cwd;
-#use Shell;
-use FileHandle;
-#Use the time
-use Time::gmtime;
-
-my $arch_file;
-my $new_arch_file;
-my $overwrite = "TRUE";
-my $keyword = "OPENFPGAPATHKEYWORD";
-my $folder_top = "OpenFPGA";
-
-sub print_usage()
-{
- print "Usage:\n";
- print " perl [-options]\n";
- print " Options:(Mandatory!)\n";
- print " -i \n";
- print " Options:(Optional)\n";
- print " -o \n";
- print "\n";
- return;
-}
-
-sub opts_read()
-{
- if ($#ARGV == -1){
- print "Error: Not enough input argument!\n";
- &print_usage();
- exit(1);
- } else {
- for (my $iargv = 0; $iargv < $#ARGV+1; $iargv++){
- if ("-i" eq $ARGV[$iargv]){
- $arch_file = $ARGV[$iargv+1];
- $iargv++;
- } elsif ("-o" eq $ARGV[$iargv]){
- $new_arch_file = $ARGV[$iargv+1];
- $overwrite = "FALSE";
- $iargv++;
- } else {
- die "WRONG ARGUMENT";
- }
- }
- }
- return;
-}
-
-sub rewriting_required_check($)
-{
- my ($arch) = @_;
- open(F, $arch);
- my @lines=;
- close F;
- my $grep_result = grep ($keyword, @lines);
- if($grep_result >= 1){
- print "Rewrite needed\n";
- return 1;
- } else {
- print "Rewrite NOT needed\n";
- return 0;
- }
-}
-
-sub save_original($)
-{
- my ($template) = @_;
- my $renamed_template = "$template".".bak";
- rename($template, $renamed_template);
-
- return $renamed_template;
-}
-
-sub findPath(){
- my $path;
- my $dir = cwd;
- my @folders = split("/", $dir);
- for(my $count = 0; $count < ($#folders -1); $count++){
- print "path fragment = $folders[$count]\n";
- if($folders[$count] eq ""){
- } else {
- $path = "$path"."/"."$folders[$count]";
- if($folders[$count] eq $folder_top){
- print "$path\n";
- return $path;
- }
- }
- }
- die "ERROR: Script launched from the outside of the $folder_top folder!\n";
-}
-
-sub rewrite_file($ $)
-{
- my ($arch, $template) = @_;
- my $myPath = &findPath();
- open(IN, '<'.$template);
- open(OUT, '>'.$arch);
- while(){
- $_ =~ s/$keyword/$myPath/g;
- print OUT $_;
- }
- return;
-}
-
-sub main()
-{
- &opts_read();
- my $rewrite_needed = &rewriting_required_check($arch_file);
- if($rewrite_needed == 1){
- if($overwrite eq "true"){
- my $template_file = &save_original($arch_file);
- &rewrite_file($arch_file, $template_file);
- } else {
- &rewrite_file($new_arch_file, $arch_file);
- }
- }
- return;
-}
-
-&main();
-exit(1);
diff --git a/fpga_flow/scripts/rewrite_path_in_file.pl b/fpga_flow/scripts/rewrite_path_in_file.pl
index fadedb606..b65868f60 100644
--- a/fpga_flow/scripts/rewrite_path_in_file.pl
+++ b/fpga_flow/scripts/rewrite_path_in_file.pl
@@ -6,8 +6,12 @@ use FileHandle;
#Use the time
use Time::gmtime;
-my $my_file;
+my $arch_file;
+my $new_arch_file;
+my $overwrite = "TRUE";
my $keyword = "OPENFPGAPATHKEYWORD";
+my $default_keyword = "TRUE";
+my $change_to;
my $folder_top = "OpenFPGA";
sub print_usage()
@@ -15,7 +19,10 @@ sub print_usage()
print "Usage:\n";
print " perl [-options]\n";
print " Options:(Mandatory!)\n";
- print " -i \n";
+ print " -i \n";
+ print " Options:(Optional)\n";
+ print " -o \n";
+ print " -k \n";
print "\n";
return;
}
@@ -29,7 +36,17 @@ sub opts_read()
} else {
for (my $iargv = 0; $iargv < $#ARGV+1; $iargv++){
if ("-i" eq $ARGV[$iargv]){
- $my_file = $ARGV[$iargv+1];
+ $arch_file = $ARGV[$iargv+1];
+ $iargv++;
+ } elsif ("-o" eq $ARGV[$iargv]){
+ $new_arch_file = $ARGV[$iargv+1];
+ $overwrite = "FALSE";
+ $iargv++;
+ } elsif ("-k" eq $ARGV[$iargv]){
+ $keyword = $ARGV[$iargv+1];
+ $change_to = $ARGV[$iargv+2];
+ $default_keyword = "FALSE";
+ $iargv++;
$iargv++;
} else {
die "WRONG ARGUMENT";
@@ -41,8 +58,8 @@ sub opts_read()
sub rewriting_required_check($)
{
- my ($file) = @_;
- open(F, $file);
+ my ($arch) = @_;
+ open(F, $arch);
my @lines=;
close F;
my $grep_result = grep ($keyword, @lines);
@@ -68,7 +85,7 @@ sub findPath(){
my $path;
my $dir = cwd;
my @folders = split("/", $dir);
- for(my $count = 0; $count < $#folders; $count++){
+ for(my $count = 0; $count < ($#folders -1); $count++){
if($folders[$count] eq ""){
} else {
$path = "$path"."/"."$folders[$count]";
@@ -81,15 +98,23 @@ sub findPath(){
die "ERROR: Script launched from the outside of the $folder_top folder!\n";
}
-sub create_new($ $)
+sub rewrite_file($ $)
{
- my ($file, $template) = @_;
- my $myPath = &findPath();
+ my ($arch, $template) = @_;
open(IN, '<'.$template);
- open(OUT, '>'.$file);
- while(){
- $_ =~ s/$keyword/$myPath/g;
- print OUT $_;
+ open(OUT, '>'.$arch);
+
+ if($default_keyword eq "TRUE"){
+ my $myPath = &findPath();
+ while(){
+ $_ =~ s/$keyword/$myPath/g;
+ print OUT $_;
+ }
+ } else {
+ while(){
+ $_ =~ s/$keyword/$change_to/g;
+ print OUT $_;
+ }
}
return;
}
@@ -97,12 +122,17 @@ sub create_new($ $)
sub main()
{
&opts_read();
- my $rewrite_needed = &rewriting_required_check($my_file);
+ my $rewrite_needed = &rewriting_required_check($arch_file);
if($rewrite_needed == 1){
- my $template_file = &save_original($my_file);
- &create_new($my_file, $template_file);
+ if($overwrite eq "TRUE"){
+ my $template_file = &save_original($arch_file);
+ &rewrite_file($arch_file, $template_file);
+ } else {
+ &rewrite_file($new_arch_file, $arch_file);
+ }
}
return;
}
&main();
+exit(1);
diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt
new file mode 100644
index 000000000..aed5d49c0
--- /dev/null
+++ b/libs/CMakeLists.txt
@@ -0,0 +1,10 @@
+#VTR developed libraries
+#add_subdirectory(libarchfpga)
+add_subdirectory(libvtrutil)
+add_subdirectory(liblog)
+#add_subdirectory(libpugiutil)
+#add_subdirectory(libeasygl)
+#add_subdirectory(librtlnumber)
+
+#Externally developed libraries
+#add_subdirectory(EXTERNAL)
diff --git a/libs/liblog/CMakeLists.txt b/libs/liblog/CMakeLists.txt
new file mode 100644
index 000000000..b0d9ace35
--- /dev/null
+++ b/libs/liblog/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project("liblog")
+
+file(GLOB_RECURSE EXEC_SOURCES src/main.cpp)
+file(GLOB_RECURSE LIB_SOURCES src/*.cpp)
+file(GLOB_RECURSE LIB_HEADERS src/*.h)
+files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
+
+#Remove test executable from library
+list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES})
+
+#Create the library
+add_library(liblog STATIC
+ ${LIB_HEADERS}
+ ${LIB_SOURCES})
+target_include_directories(liblog PUBLIC ${LIB_INCLUDE_DIRS})
+set_target_properties(liblog PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
+
+#Create the test executable
+add_executable(test_log ${EXEC_SOURCES})
+target_link_libraries(test_log liblog)
+
+install(TARGETS test_log liblog DESTINATION bin)
diff --git a/libs/liblog/LICENSE.txt b/libs/liblog/LICENSE.txt
new file mode 100644
index 000000000..41116e903
--- /dev/null
+++ b/libs/liblog/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Jason Luu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/libs/liblog/Readme.txt b/libs/liblog/Readme.txt
new file mode 100644
index 000000000..8f89aafdb
--- /dev/null
+++ b/libs/liblog/Readme.txt
@@ -0,0 +1,13 @@
+Simple Logger Library
+
+Author: Jason Luu
+Date: Sept 5, 2014
+
+This library provides simple logging operations.
+
+- Output messages to both file and terminal
+- Tag messages based on feedback type (eg. info, warning, or error)
+- Track number of warnings and errors
+
+Specialized programming knowledge:
+- Requires usage of variable arguments in standard C library to properly wrap printf and fprintf
diff --git a/libs/liblog/src/log.cpp b/libs/liblog/src/log.cpp
new file mode 100644
index 000000000..f301f0598
--- /dev/null
+++ b/libs/liblog/src/log.cpp
@@ -0,0 +1,121 @@
+/**
+ * Lightweight logging tool. Automatically prepend messages with prefixes and store in log file.
+ *
+ * Author: Jason Luu
+ * Date: Sept 5, 2014
+ */
+
+
+#include
+#include /* Allows for variable arguments, necessary for wrapping printf */
+#include "log.h"
+
+#define LOG_DEFAULT_FILE_NAME "output.log"
+
+static int log_warning = 0;
+static int log_error = 0;
+FILE *log_stream = nullptr;
+
+
+static void check_init();
+
+/* Set the output file of logger.
+ If different than current log file, close current log file and reopen to new log file
+*/
+void log_set_output_file(const char *filename) {
+ if(log_stream != nullptr) {
+ fclose(log_stream);
+ }
+
+ if (filename == nullptr) {
+ log_stream = nullptr;
+ } else {
+
+ log_stream = fopen(filename, "w");
+ if(log_stream == nullptr) {
+ printf("Error writing to file %s\n\n", filename);
+ }
+ }
+}
+
+void log_print_direct(const char* message, ...) {
+ va_list args;
+ va_start(args, message);
+ vprintf(message, args);
+ va_end(args);
+}
+
+void log_print_info(const char* message, ...) {
+ check_init(); /* Check if output log file setup, if not, then this function also sets it up */
+
+ va_list args;
+ va_start(args, message);
+ vprintf(message, args);
+ va_end(args);
+
+ if (log_stream) {
+ va_start(args, message); /* Must reset variable arguments so that they can be read again */
+ vfprintf(log_stream, message, args);
+ va_end(args);
+
+ fflush(log_stream);
+ }
+}
+
+void log_print_warning(const char* /*filename*/, unsigned int /*line_num*/, const char* message, ...) {
+ check_init(); /* Check if output log file setup, if not, then this function also sets it up */
+
+ va_list args;
+ va_start(args, message);
+ log_warning++;
+
+ printf("Warning %d: ", log_warning);
+ vprintf(message, args);
+ va_end(args);
+
+ if (log_stream) {
+ va_start(args, message); /* Must reset variable arguments so that they can be read again */
+ fprintf(log_stream, "Warning %d: ", log_warning);
+ vfprintf(log_stream, message, args);
+
+ va_end(args);
+ fflush(log_stream);
+ }
+}
+
+void log_print_error(const char* /*filename*/, unsigned int /*line_num*/, const char* message, ...) {
+ check_init(); /* Check if output log file setup, if not, then this function also sets it up */
+
+ va_list args;
+ va_start(args, message);
+ log_error++;
+
+ check_init();
+ fprintf(stderr, "Error %d: ", log_error);
+ vfprintf(stderr, message, args);
+ va_end(args);
+
+ if (log_stream) {
+ va_start(args, message); /* Must reset variable arguments so that they can be read again */
+ fprintf(log_stream, "Error %d: ", log_error);
+ vfprintf(log_stream, message, args);
+
+ va_end(args);
+
+ fflush(log_stream);
+ }
+}
+
+/**
+ * Check if output log file setup, if not, then this function also sets it up
+ */
+static void check_init() {
+ //We now allow a nullptr log_stream (i.e. no log file) so nothing to do here
+}
+
+
+void log_close() {
+ if (log_stream) {
+ fclose(log_stream);
+ }
+}
diff --git a/libs/liblog/src/log.h b/libs/liblog/src/log.h
new file mode 100644
index 000000000..3d152fb21
--- /dev/null
+++ b/libs/liblog/src/log.h
@@ -0,0 +1,22 @@
+/**
+ * Lightweight logging tool. Automatically prepend messages with prefixes and store in log file.
+ *
+ * Init/Change name of log file using log_set_output_file, when done, call log_close
+ *
+ * Author: Jason Luu
+ * Date: Sept 5, 2014
+ */
+
+#ifndef LOG_H
+#define LOG_H
+
+void log_set_output_file(const char *filename);
+
+void log_print_direct(const char* message, ...);
+void log_print_info(const char* message, ...);
+void log_print_warning(const char* filename, unsigned int line_num, const char* message, ...);
+void log_print_error(const char* filename, unsigned int line_num, const char* message, ...);
+
+void log_close();
+
+#endif
diff --git a/libs/liblog/src/main.cpp b/libs/liblog/src/main.cpp
new file mode 100644
index 000000000..ecb7d9ab6
--- /dev/null
+++ b/libs/liblog/src/main.cpp
@@ -0,0 +1,18 @@
+/** Jason Luu
+ * Test program for logger
+ */
+
+#include "log.h"
+
+int main() {
+ int x = 10, y = 20;
+ float a = 1.5f, b = -2.01f;
+ log_print_info("Testing logger\n\n");
+ log_print_info("Output separate strings: %s %s\n", "pass", "[PASS]");
+ log_print_info("Output two integers: x = %d y = %d\n", x, y);
+ log_print_warning(__FILE__, __LINE__, "Test warning on floating point arguments %g %g\n", a, b);
+ log_print_error(__FILE__, __LINE__, "Test error on two variables %g %g \n\n", a - x, b + y);
+
+ log_print_info("Test complete\n");
+ return 0;
+}
\ No newline at end of file
diff --git a/libs/libvtrutil/CMakeLists.txt b/libs/libvtrutil/CMakeLists.txt
new file mode 100644
index 000000000..4b689150c
--- /dev/null
+++ b/libs/libvtrutil/CMakeLists.txt
@@ -0,0 +1,91 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project("libvtrutil")
+
+#Version info
+set(VTR_VERSION_FILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/src/vtr_version.cpp.in)
+set(VTR_VERSION_FILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/vtr_version.cpp)
+
+#Compiler info
+set(VTR_COMPILER_INFO "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} on ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR}")
+
+#Set default version numbers in case not specified
+if(NOT DEFINED VTR_VERSION_MAJOR)
+ set(VTR_VERSION_MAJOR 0)
+endif()
+
+if(NOT DEFINED VTR_VERSION_MINOR)
+ set(VTR_VERSION_MINOR 0)
+endif()
+
+if(NOT DEFINED VTR_VERSION_PATCH)
+ set(VTR_VERSION_PATCH 0)
+endif()
+
+# We always update the vtr_version.cpp file every time the project is built,
+# to ensure the git revision and dirty status are up to date.
+#
+# We need to do this in two stages:
+#
+# 1) We a custom target 'version' (which is always out of date) so it will always be run.
+# It touches the unprocessed version input file so it too will always be out of date.
+#
+# 2) The custom command depends on the touched version input file and generates the processed
+# version file, with updated values. The custom command uses the configure_version.cmake
+# script to generate the up-to-date vtr_version.cpp
+add_custom_target(version ALL
+ COMMAND ${CMAKE_COMMAND} -E touch ${VTR_VERSION_FILE_IN})
+
+add_custom_command(OUTPUT ${VTR_VERSION_FILE_OUT}
+ COMMAND ${CMAKE_COMMAND}
+ -D IN_FILE=${VTR_VERSION_FILE_IN}
+ -D OUT_FILE=${VTR_VERSION_FILE_OUT}
+ -D VTR_VERSION_MAJOR=${VTR_VERSION_MAJOR}
+ -D VTR_VERSION_MINOR=${VTR_VERSION_MINOR}
+ -D VTR_VERSION_PATCH=${VTR_VERSION_PATCH}
+ -D VTR_VERSION_PRERELEASE=${VTR_VERSION_PRERELEASE}
+ -D VTR_COMPILER_INFO=${VTR_COMPILER_INFO}
+ -D VTR_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/configure_version.cmake
+ MAIN_DEPENDENCY ${VTR_VERSION_FILE_IN}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ VERBATIM)
+
+
+#
+# Source files and library
+#
+file(GLOB_RECURSE LIB_SOURCES src/*.cpp)
+file(GLOB_RECURSE LIB_HEADERS src/*.hpp src/*.h)
+files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
+
+#Add the version file to the sources
+list(APPEND LIB_SOURCES ${VTR_VERSION_FILE_OUT})
+
+#Create the library
+add_library(libvtrutil STATIC
+ ${LIB_HEADERS}
+ ${LIB_SOURCES})
+target_include_directories(libvtrutil PUBLIC ${LIB_INCLUDE_DIRS})
+set_target_properties(libvtrutil PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
+
+#Ensure version is always up to date by requiring version to be run first
+add_dependencies(libvtrutil version)
+
+#Specify link-time dependancies
+target_link_libraries(libvtrutil
+ liblog)
+
+install(TARGETS libvtrutil DESTINATION bin)
+
+#
+# Unit Tests
+#
+#file(GLOB_RECURSE TEST_SOURCES test/*.cpp)
+#add_executable(test_vtrutil ${TEST_SOURCES})
+#target_link_libraries(test_vtrutil
+# libvtrutil
+# libcatch)
+
+#add_test(NAME test_vtrutil COMMAND test_vtrutil --use-colour=yes)
+
diff --git a/libs/libvtrutil/cmake/modules/configure_version.cmake b/libs/libvtrutil/cmake/modules/configure_version.cmake
new file mode 100644
index 000000000..72519f2c3
--- /dev/null
+++ b/libs/libvtrutil/cmake/modules/configure_version.cmake
@@ -0,0 +1,40 @@
+#
+# Versioning information
+#
+#Figure out the git revision
+find_package(Git QUIET)
+if(GIT_FOUND)
+ exec_program(${GIT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}
+ ARGS describe --always --long --dirty
+ OUTPUT_VARIABLE VTR_VCS_REVISION
+ RETURN_VALUE GIT_DESCRIBE_RETURN_VALUE)
+
+ if(NOT GIT_DESCRIBE_RETURN_VALUE EQUAL 0)
+ #Git describe failed, usually this means we
+ #aren't in a git repo -- so don't set a VCS
+ #revision
+ set(VTR_VCS_REVISION "unkown")
+ endif()
+else()
+ #Couldn't find git, so can't look-up VCS revision
+ set(VTR_VCS_REVISION "unkown")
+endif()
+
+
+#Set the version according to semver.org
+set(VTR_VERSION "${VTR_VERSION_MAJOR}.${VTR_VERSION_MINOR}.${VTR_VERSION_PATCH}")
+if(VTR_VERSION_PRERELEASE)
+ set(VTR_VERSION "${VTR_VERSION}-${VTR_VERSION_PRERELEASE}")
+endif()
+set(VTR_VERSION_SHORT ${VTR_VERSION})
+if(VTR_VCS_REVISION)
+ set(VTR_VERSION "${VTR_VERSION}+${VTR_VCS_REVISION}")
+endif()
+
+#Other build meta-data
+string(TIMESTAMP VTR_BUILD_TIMESTAMP)
+set(VTR_BUILD_TIMESTAMP "${VTR_BUILD_TIMESTAMP} (${VTR_BUILD_TYPE} build)")
+
+message(STATUS "VTR Version: ${VTR_VERSION}")
+
+configure_file(${IN_FILE} ${OUT_FILE})
diff --git a/libs/libvtrutil/src/picosha2.h b/libs/libvtrutil/src/picosha2.h
new file mode 100644
index 000000000..7ebe499c5
--- /dev/null
+++ b/libs/libvtrutil/src/picosha2.h
@@ -0,0 +1,366 @@
+/*
+The MIT License (MIT)
+
+Copyright (C) 2014 okdshin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+#ifndef PICOSHA2_H
+#define PICOSHA2_H
+//picosha2:20140213
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace picosha2
+{
+typedef unsigned long word_t;
+typedef unsigned char byte_t;
+
+namespace detail
+{
+inline byte_t mask_8bit(byte_t x){
+ return x&0xff;
+}
+
+inline word_t mask_32bit(word_t x){
+ return x&0xffffffff;
+}
+
+const word_t add_constant[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+const word_t initial_message_digest[8] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+};
+
+inline word_t ch(word_t x, word_t y, word_t z){
+ return (x&y)^((~x)&z);
+}
+
+inline word_t maj(word_t x, word_t y, word_t z){
+ return (x&y)^(x&z)^(y&z);
+}
+
+inline word_t rotr(word_t x, std::size_t n){
+ assert(n < 32);
+ return mask_32bit((x>>n)|(x<<(32-n)));
+}
+
+inline word_t bsig0(word_t x){
+ return rotr(x, 2)^rotr(x, 13)^rotr(x, 22);
+}
+
+inline word_t bsig1(word_t x){
+ return rotr(x, 6)^rotr(x, 11)^rotr(x, 25);
+}
+
+inline word_t shr(word_t x, std::size_t n){
+ assert(n < 32);
+ return x >> n;
+}
+
+inline word_t ssig0(word_t x){
+ return rotr(x, 7)^rotr(x, 18)^shr(x, 3);
+}
+
+inline word_t ssig1(word_t x){
+ return rotr(x, 17)^rotr(x, 19)^shr(x, 10);
+}
+
+template
+void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 /*last*/){
+ word_t w[64];
+ std::fill(w, w+64, 0);
+ for(std::size_t i = 0; i < 16; ++i){
+ w[i] = (static_cast(mask_8bit(*(first+i*4)))<<24)
+ |(static_cast(mask_8bit(*(first+i*4+1)))<<16)
+ |(static_cast(mask_8bit(*(first+i*4+2)))<<8)
+ |(static_cast(mask_8bit(*(first+i*4+3))));
+ }
+ for(std::size_t i = 16; i < 64; ++i){
+ w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]);
+ }
+
+ word_t a = *message_digest;
+ word_t b = *(message_digest+1);
+ word_t c = *(message_digest+2);
+ word_t d = *(message_digest+3);
+ word_t e = *(message_digest+4);
+ word_t f = *(message_digest+5);
+ word_t g = *(message_digest+6);
+ word_t h = *(message_digest+7);
+
+ for(std::size_t i = 0; i < 64; ++i){
+ word_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i];
+ word_t temp2 = bsig0(a)+maj(a,b,c);
+ h = g;
+ g = f;
+ f = e;
+ e = mask_32bit(d+temp1);
+ d = c;
+ c = b;
+ b = a;
+ a = mask_32bit(temp1+temp2);
+ }
+ *message_digest += a;
+ *(message_digest+1) += b;
+ *(message_digest+2) += c;
+ *(message_digest+3) += d;
+ *(message_digest+4) += e;
+ *(message_digest+5) += f;
+ *(message_digest+6) += g;
+ *(message_digest+7) += h;
+ for(std::size_t i = 0; i < 8; ++i){
+ *(message_digest+i) = mask_32bit(*(message_digest+i));
+ }
+}
+
+}//namespace detail
+
+template
+void output_hex(InIter first, InIter last, std::ostream& os){
+ std::ios::fmtflags orig_flags = os.flags();
+ std::streamsize orig_width = os.width();
+ char orig_fill = os.fill();
+
+
+ os.setf(std::ios::hex, std::ios::basefield);
+ while(first != last){
+ os.width(2);
+ os.fill('0');
+ os << static_cast(*first);
+ ++first;
+ }
+ os.flags(orig_flags);
+ os.fill(orig_fill);
+ os.width(orig_width);
+}
+
+template
+void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){
+ std::ostringstream oss;
+ output_hex(first, last, oss);
+ hex_str.assign(oss.str());
+}
+
+template
+void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){
+ bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);
+}
+
+template
+std::string bytes_to_hex_string(InIter first, InIter last){
+ std::string hex_str;
+ bytes_to_hex_string(first, last, hex_str);
+ return hex_str;
+}
+
+template
+std::string bytes_to_hex_string(const InContainer& bytes){
+ std::string hex_str;
+ bytes_to_hex_string(bytes, hex_str);
+ return hex_str;
+}
+
+class hash256_one_by_one {
+public:
+ hash256_one_by_one(){
+ init();
+ }
+
+ void init(){
+ buffer_.clear();
+ std::fill(data_length_digits_, data_length_digits_+4, 0);
+ std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_);
+ }
+
+ template
+ void process(RaIter first, RaIter last){
+ add_to_data_length(std::distance(first, last));
+ std::copy(first, last, std::back_inserter(buffer_));
+ std::size_t i = 0;
+ for(;i+64 <= buffer_.size(); i+=64){
+ detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64);
+ }
+ buffer_.erase(buffer_.begin(), buffer_.begin()+i);
+ }
+
+ void finish(){
+ byte_t temp[64];
+ std::fill(temp, temp+64, 0);
+ std::size_t remains = buffer_.size();
+ std::copy(buffer_.begin(), buffer_.end(), temp);
+ temp[remains] = 0x80;
+
+ if(remains > 55){
+ std::fill(temp+remains+1, temp+64, 0);
+ detail::hash256_block(h_, temp, temp+64);
+ std::fill(temp, temp+64-4, 0);
+ }
+ else {
+ std::fill(temp+remains+1, temp+64-4, 0);
+ }
+
+ write_data_bit_length(&(temp[56]));
+ detail::hash256_block(h_, temp, temp+64);
+ }
+
+ template
+ void get_hash_bytes(OutIter first, OutIter last)const{
+ for(const word_t* iter = h_; iter != h_+8; ++iter){
+ for(std::size_t i = 0; i < 4 && first != last; ++i){
+ *(first++) = detail::mask_8bit(static_cast((*iter >> (24-8*i))));
+ }
+ }
+ }
+
+private:
+ void add_to_data_length(word_t n) {
+ word_t carry = 0;
+ data_length_digits_[0] += n;
+ for(std::size_t i = 0; i < 4; ++i) {
+ data_length_digits_[i] += carry;
+ if(data_length_digits_[i] >= 65536u) {
+ carry = data_length_digits_[i]>>16;
+ data_length_digits_[i] &= 65535u;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ void write_data_bit_length(byte_t* begin) {
+ word_t data_bit_length_digits[4];
+ std::copy(
+ data_length_digits_, data_length_digits_+4,
+ data_bit_length_digits
+ );
+
+ // convert byte length to bit length (multiply 8 or shift 3 times left)
+ word_t carry = 0;
+ for(std::size_t i = 0; i < 4; ++i) {
+ word_t before_val = data_bit_length_digits[i];
+ data_bit_length_digits[i] <<= 3;
+ data_bit_length_digits[i] |= carry;
+ data_bit_length_digits[i] &= 65535u;
+ carry = (before_val >> (16-3)) & 65535u;
+ }
+
+ // write data_bit_length
+ for(int i = 3; i >= 0; --i) {
+ (*begin++) = static_cast(data_bit_length_digits[i] >> 8);
+ (*begin++) = static_cast(data_bit_length_digits[i]);
+ }
+ }
+ std::vector buffer_;
+ word_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer)
+ word_t h_[8];
+};
+
+inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){
+ byte_t hash[32];
+ hasher.get_hash_bytes(hash, hash+32);
+ return bytes_to_hex_string(hash, hash+32, hex_str);
+}
+
+inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){
+ std::string hex_str;
+ get_hash_hex_string(hasher, hex_str);
+ return hex_str;
+}
+
+template
+void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){
+ hash256_one_by_one hasher;
+ //hasher.init();
+ hasher.process(first, last);
+ hasher.finish();
+ hasher.get_hash_bytes(first2, last2);
+}
+
+template
+void hash256(RaIter first, RaIter last, OutContainer& dst){
+ hash256(first, last, dst.begin(), dst.end());
+}
+
+template
+void hash256(const RaContainer& src, OutIter first, OutIter last){
+ hash256(src.begin(), src.end(), first, last);
+}
+
+template
+void hash256(const RaContainer& src, OutContainer& dst){
+ hash256(src.begin(), src.end(), dst.begin(), dst.end());
+}
+
+
+template
+void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){
+ byte_t hashed[32];
+ hash256(first, last, hashed, hashed+32);
+ std::ostringstream oss;
+ output_hex(hashed, hashed+32, oss);
+ hex_str.assign(oss.str());
+}
+
+template
+std::string hash256_hex_string(RaIter first, RaIter last){
+ std::string hex_str;
+ hash256_hex_string(first, last, hex_str);
+ return hex_str;
+}
+
+inline void hash256_hex_string(const std::string& src, std::string& hex_str){
+ hash256_hex_string(src.begin(), src.end(), hex_str);
+}
+
+template
+void hash256_hex_string(const RaContainer& src, std::string& hex_str){
+ hash256_hex_string(src.begin(), src.end(), hex_str);
+}
+
+template
+std::string hash256_hex_string(const RaContainer& src){
+ return hash256_hex_string(src.begin(), src.end());
+}
+
+}//namespace picosha2
+
+#endif //PICOSHA2_H
diff --git a/libs/libvtrutil/src/vtr_assert.cpp b/libs/libvtrutil/src/vtr_assert.cpp
new file mode 100644
index 000000000..abe884f0b
--- /dev/null
+++ b/libs/libvtrutil/src/vtr_assert.cpp
@@ -0,0 +1,21 @@
+#include "vtr_assert.h"
+
+#include //fprintf, stderr
+#include //abort
+
+namespace vtr { namespace assert {
+
+void handle_assert(const char* expr, const char* file, unsigned int line, const char* function, const char* msg) {
+ fprintf(stderr, "%s:%d", file, line);
+ if(function) {
+ fprintf(stderr, " %s:", function);
+ }
+ fprintf(stderr, " Assertion '%s' failed", expr);
+ if(msg) {
+ fprintf(stderr, " (%s)", msg);
+ }
+ fprintf(stderr, ".\n");
+ std::abort();
+}
+
+}} //namespace
diff --git a/libs/libvtrutil/src/vtr_assert.h b/libs/libvtrutil/src/vtr_assert.h
new file mode 100644
index 000000000..8fea7a4af
--- /dev/null
+++ b/libs/libvtrutil/src/vtr_assert.h
@@ -0,0 +1,133 @@
+#ifndef VTR_ASSERT_H
+#define VTR_ASSERT_H
+/*
+ * The header defines useful assertion macros for VTR projects.
+ *
+ * Three types of assertions are defined:
+ * VTR_ASSERT_OPT - low overhead assertions that should always be enabled
+ * VTR_ASSERT - medium overhead assertions that are usually be enabled
+ * VTR_ASSERT_SAFE - high overhead assertions typically enabled only for debugging
+ * VTR_ASSERT_DEBUG - very high overhead assertions typically enabled only for extreme debugging
+ * Each of the above assertions also have a *_MSG variants (e.g. VTR_ASSERT_MSG(expr, msg))
+ * which takes an additional argument specifying additional message text to be shown.
+ * By convention the message should state the condition *being checked* (and not the failure condition),
+ * since that the condition failed is obvious from the assertion failure itself.
+ *
+ * The macro VTR_ASSERT_LEVEL specifies the level of assertion checking desired:
+ *
+ * VTR_ASSERT_LEVEL == 4: VTR_ASSERT_OPT, VTR_ASSERT, VTR_ASSERT_SAFE, VTR_ASSERT_DEBUG enabled
+ * VTR_ASSERT_LEVEL == 3: VTR_ASSERT_OPT, VTR_ASSERT, VTR_ASSERT_SAFE enabled
+ * VTR_ASSERT_LEVEL == 2: VTR_ASSERT_OPT, VTR_ASSERT enabled
+ * VTR_ASSERT_LEVEL == 1: VTR_ASSERT_OPT enabled
+ * VTR_ASSERT_LEVEL == 0: No assertion checking enabled
+ * Note that an assertion levels beyond 4 are currently treated the same as level 4
+ */
+
+//Set a default assertion level if none is specified
+#ifndef VTR_ASSERT_LEVEL
+# define VTR_ASSERT_LEVEL 2
+#endif
+
+//Enable the assertions based on the specified level
+#if VTR_ASSERT_LEVEL >= 4
+# define VTR_ASSERT_DEBUG_ENABLED
+#endif
+
+#if VTR_ASSERT_LEVEL >= 3
+# define VTR_ASSERT_SAFE_ENABLED
+#endif
+
+#if VTR_ASSERT_LEVEL >= 2
+#define VTR_ASSERT_ENABLED
+#endif
+
+#if VTR_ASSERT_LEVEL >= 1
+# define VTR_ASSERT_OPT_ENABLED
+#endif
+
+//Define the user assertion macros
+#ifdef VTR_ASSERT_DEBUG_ENABLED
+# define VTR_ASSERT_DEBUG(expr) VTR_ASSERT_IMPL(expr, nullptr)
+# define VTR_ASSERT_DEBUG_MSG(expr, msg) VTR_ASSERT_IMPL(expr, msg)
+#else
+# define VTR_ASSERT_DEBUG(expr) VTR_ASSERT_IMPL_NOP(expr, nullptr)
+# define VTR_ASSERT_DEBUG_MSG(expr, msg) VTR_ASSERT_IMPL_NOP(expr, msg)
+#endif
+
+#ifdef VTR_ASSERT_SAFE_ENABLED
+# define VTR_ASSERT_SAFE(expr) VTR_ASSERT_IMPL(expr, nullptr)
+# define VTR_ASSERT_SAFE_MSG(expr, msg) VTR_ASSERT_IMPL(expr, msg)
+#else
+# define VTR_ASSERT_SAFE(expr) VTR_ASSERT_IMPL_NOP(expr, nullptr)
+# define VTR_ASSERT_SAFE_MSG(expr, msg) VTR_ASSERT_IMPL_NOP(expr, msg)
+#endif
+
+#ifdef VTR_ASSERT_ENABLED
+# define VTR_ASSERT(expr) VTR_ASSERT_IMPL(expr, nullptr)
+# define VTR_ASSERT_MSG(expr, msg) VTR_ASSERT_IMPL(expr, msg)
+#else
+# define VTR_ASSERT(expr) VTR_ASSERT_IMPL_NOP(expr, nullptr)
+# define VTR_ASSERT_MSG(expr, msg) VTR_ASSERT_IMPL_NOP(expr, msg)
+#endif
+
+#ifdef VTR_ASSERT_OPT_ENABLED
+# define VTR_ASSERT_OPT(expr) VTR_ASSERT_IMPL(expr, nullptr)
+# define VTR_ASSERT_OPT_MSG(expr, msg) VTR_ASSERT_IMPL(expr, msg)
+#else
+# define VTR_ASSERT_OPT(expr) VTR_ASSERT_IMPL_NOP(expr, nullptr)
+# define VTR_ASSERT_OPT_MSG(expr, msg) VTR_ASSERT_IMPL_NOP(expr, msg)
+#endif
+
+
+//Define the assertion implementation macro
+// We wrap the check in a do {} while() to ensure the function-like
+// macro can be always be followed by a ';'
+#define VTR_ASSERT_IMPL(expr, msg) do { \
+ if(!(expr)) { \
+ vtr::assert::handle_assert(#expr, __FILE__, __LINE__, VTR_ASSERT_FUNCTION, msg); \
+ } \
+ } while(false)
+
+//Define the no-op assertion implementation macro
+// We wrap the check in a do {} while() to ensure the function-like
+// macro can be always be followed by a ';'
+//
+// Note that to avoid 'unused' variable warnings when assertions are
+// disabled, we pass the expr and msg to sizeof(). We use sizeof specifically
+// since it accepts expressions, and the C++ standard gaurentees sizeof's arguments
+// are never evaluated (ensuring any expensive expressions are not evaluated when
+// assertions are disabled). To avoid warnings about the unused result of sizeof()
+// we cast it to void.
+#define VTR_ASSERT_IMPL_NOP(expr, msg) do { \
+ static_cast(sizeof(expr)); \
+ static_cast(sizeof(msg)); \
+ } while(false)
+
+//Figure out what macro to use to get the name of the current function
+// We default to __func__ which is defined in C99
+//
+// g++ > 2.6 define __PRETTY_FUNC__ which includes class/namespace/overload
+// information, so we prefer to use it if possible
+#define VTR_ASSERT_FUNCTION __func__
+#ifdef __GNUC__
+# ifdef __GNUC_MINOR__
+# if __GNUC__ >= 2 && __GNUC_MINOR__ > 6
+# undef VTR_ASSERT_FUNCTION
+# define VTR_ASSERT_FUNCTION __PRETTY_FUNCTION__
+# endif
+# endif
+#endif
+
+namespace vtr { namespace assert {
+ //Assertion handling routine
+ //
+ //Note that we mark the routine with the standard C++11
+ //attribute 'noreturn' which tells the compiler this
+ //function will never return. This should ensure the
+ //compiler won't warn about detected conditions such as
+ //dead-code or potential null pointer dereferences
+ //which are gaurded against by assertions.
+ [[noreturn]] void handle_assert(const char* expr, const char* file, unsigned int line, const char* function, const char* msg);
+}} //namespace
+
+#endif //VTR_ASSERT_H
diff --git a/libs/libvtrutil/src/vtr_bimap.h b/libs/libvtrutil/src/vtr_bimap.h
new file mode 100644
index 000000000..cf3d8c9af
--- /dev/null
+++ b/libs/libvtrutil/src/vtr_bimap.h
@@ -0,0 +1,142 @@
+#ifndef VTR_BIMAP
+#define VTR_BIMAP
+#include