diff --git a/hpvm/test/README.md b/hpvm/test/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b391bd2186b696685adb2645c288c01ea7006850
--- /dev/null
+++ b/hpvm/test/README.md
@@ -0,0 +1,35 @@
+# Using HPVM
+Tests are provided, along with a template Makefile for user projects.
+
+## Parboil
+Several tests from the [parboil suite](http://impact.crhc.illinois.edu/parboil/parboil.aspx) have been ported to HPVM.
+To run one of these tests, navigate to its directory under `parboil/benchmarks/`.
+Tests may be built for the cpu or gpu with hpvm, and openCL versions are provided for comparison.
+Check under the `src/` directory in each benchmark to see which versions are available,
+denoted by the names of the subdirectories.
+```
+# sgemm example
+cd parboil/benchmarks/sgemm
+# HPVM cpu
+make TARGET=seq VERSION=visc
+make run TARGET=seq VERSION=visc
+# HPVM gpu
+make TARGET=gpu VERSION=visc
+make run TARGET=gpu VERSION=visc
+# openCL
+make VERSION=opencl_base
+make run VERSION=opencl_base
+```
+
+## Cava
+TODO
+
+## Pipeline
+```
+make TARGET={seq, gpu}
+ ./pipeline-{seq, gpu} datasets/big/input/formula1_scaled.mp4
+```
+
+## Your own project
+See `template/` for an example Makefile and config.
+Include `visc.h` to use HPVM intrinsics, found in the `test/include/visc.h`.
diff --git a/hpvm/test/template/Makefile b/hpvm/test/template/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..82d7c61e2b77947da770aab506c45919ee139a63
--- /dev/null
+++ b/hpvm/test/template/Makefile
@@ -0,0 +1,117 @@
+# This Makefile compiles an HPVM project.
+# It builds HPVM-related dependencies, then the user provided code.
+#
+# Paths to some dependencies (e.g., HPVM, LLVM) must exist in Makefile.config,
+# which can be copied from Makefile.config.example for a start.
+
+CONFIG_FILE := Makefile.config
+
+ifeq ($(wildcard $(CONFIG_FILE)),)
+    $(error $(CONFIG_FILE) not found. See $(CONFIG_FILE).example)
+endif
+include $(CONFIG_FILE)
+
+# Replace this with the name of your program
+EXE_NAME = "exe"
+
+# Compiler Flags
+LFLAGS += -lm -lrt
+
+# Build dirs
+SRC_DIR = src/
+BUILD_DIR = build/$(TARGET)
+CURRENT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+
+EXE = $(EXE_NAME)-$(TARGET)
+
+INCLUDES += -I$(SRC_DIR)
+INCLUDES += -I$(LLVM_SRC_ROOT)/include -I../include -I$(VISC_BUILD_DIR)/include
+
+## BEGIN HPVM MAKEFILE
+SRCDIR_OBJS= io.ll
+OBJS_SRC=src/io.cc
+VISC_OBJS=main.visc.ll
+APP = $(EXE)
+APP_CFLAGS += $(INCLUDES) -ffast-math -O3 -fno-lax-vector-conversions -fno-vectorize -fno-slp-vectorize
+APP_CXXFLAGS += $(INCLUDES) -ffast-math -O3 -fno-lax-vector-conversions -fno-vectorize -fno-slp-vectorize
+APP_LDFLAGS=`pkg-config opencv --libs`
+
+CFLAGS = $(APP_CFLAGS) $(PLATFORM_CFLAGS)
+OBJS_CFLAGS = $(APP_CFLAGS) $(PLATFORM_CFLAGS)
+CXXFLAGS = $(APP_CXXFLAGS) $(PLATFORM_CXXFLAGS)
+LDFLAGS= $(APP_LDFLAGS) $(PLATFORM_LDFLAGS)
+
+VISC_RT_PATH = $(LLVM_SRC_ROOT)/tools/hpvm/projects/visc-rt
+VISC_RT_LIB = $(VISC_RT_PATH)/visc-rt.ll
+
+TESTGEN_OPTFLAGS = -load LLVMGenVISC.so -genvisc -globaldce
+
+ifeq ($(TARGET),seq)
+  DEVICE = CPU_TARGET
+  VISC_OPTFLAGS = -load LLVMBuildDFG.so -load LLVMDFG2LLVM_X86.so -load LLVMClearDFG.so -dfg2llvm-x86 -clearDFG
+  VISC_OPTFLAGS += -visc-timers-x86
+else
+  DEVICE = GPU_TARGET
+  VISC_OPTFLAGS = -load LLVMBuildDFG.so -load LLVMLocalMem.so -load LLVMDFG2LLVM_NVPTX.so -load LLVMDFG2LLVM_X86.so -load LLVMClearDFG.so -localmem -dfg2llvm-nvptx -dfg2llvm-x86 -clearDFG
+  VISC_OPTFLAGS += -visc-timers-x86 -visc-timers-ptx
+endif
+  TESTGEN_OPTFLAGS += -visc-timers-gen
+
+CFLAGS += -DDEVICE=$(DEVICE)
+CXXFLAGS += -DDEVICE=$(DEVICE)
+
+# Add BUILDDIR as a prefix to each element of $1
+INBUILDDIR=$(addprefix $(BUILD_DIR)/,$(1))
+
+.PRECIOUS: $(BUILD_DIR)/%.ll
+
+OBJS = $(call INBUILDDIR,$(SRCDIR_OBJS))
+TEST_OBJS = $(call INBUILDDIR,$(VISC_OBJS))
+KERNEL = $(TEST_OBJS).kernels.ll
+
+ifeq ($(TARGET),seq)
+else
+  KERNEL_LINKED = $(BUILD_DIR)/$(APP).kernels.linked.ll
+  KERNEL_OCL = $(TEST_OBJS).kernels.cl
+endif
+
+HOST_LINKED = $(BUILD_DIR)/$(APP).linked.ll
+HOST = $(BUILD_DIR)/$(APP).host.ll
+
+ifeq ($(OPENCL_PATH),)
+FAILSAFE=no_opencl
+else 
+FAILSAFE=
+endif
+
+# Targets
+default: $(FAILSAFE) $(BUILD_DIR) $(KERNEL_OCL) $(EXE)
+
+$(KERNEL_OCL) : $(KERNEL)
+	$(OCLBE) -debug $< -o $@
+
+$(EXE) : $(HOST_LINKED)
+	$(CXX) -O3 $(LDFLAGS) $< -o $@
+
+$(HOST_LINKED) : $(HOST) $(OBJS) $(VISC_RT_LIB)
+	$(LLVM_LINK) $^ -S -o $@
+
+$(VISC_RT_LIB) : $(VISC_RT_PATH)/visc-rt.cpp
+	make -C $(LLVM_LIB_PATH)
+
+$(HOST) $(KERNEL): $(BUILD_DIR)/$(VISC_OBJS)
+	$(OPT) -debug $(VISC_OPTFLAGS) -S $< -o $(HOST)
+
+$(BUILD_DIR):
+	mkdir -p $(BUILD_DIR)
+
+$(BUILD_DIR)/%.ll : $(SRC_DIR)/%.cc
+	$(CC) $(OBJS_CFLAGS) -emit-llvm -S -o $@ $<
+
+$(BUILD_DIR)/main.ll : $(SRC_DIR)/main.cc
+	$(CC) $(CXXFLAGS) -emit-llvm -S -o $@ $<
+
+$(BUILD_DIR)/main.visc.ll : $(BUILD_DIR)/main.ll
+	$(OPT) -debug-only=genvisc $(TESTGEN_OPTFLAGS) $< -S -o $@
+
+## END HPVM MAKEFILE
diff --git a/hpvm/test/template/Makefile.config.example b/hpvm/test/template/Makefile.config.example
new file mode 100644
index 0000000000000000000000000000000000000000..269f0b7df273c958f0cd20a0f935716a329e00ae
--- /dev/null
+++ b/hpvm/test/template/Makefile.config.example
@@ -0,0 +1,25 @@
+CUDA_PATH=/usr/local/cuda 
+CUDA_LIB_PATH=/usr/local/cuda/lib64
+OPENCL_PATH=/opt/intelFPGA_pro/18.0/hld/host/linux64
+OPENCL_LIB_PATH=$(OPENCL_PATH)/lib
+
+# NOTE: You may need to configure this based on your root path.
+VISC_SRC_ROOT=$(LLVM_SRC_ROOT)
+
+VISC_BUILD_DIR =$(VISC_SRC_ROOT)/build
+CC = $(VISC_BUILD_DIR)/bin/clang
+PLATFORM_CFLAGS = -I$(LLVM_SRC_ROOT)/include -I$(VISC_BUILD_DIR)/include
+
+CXX = $(VISC_BUILD_DIR)/bin/clang++
+PLATFORM_CXXFLAGS = -I$(LLVM_SRC_ROOT)/include -I$(VISC_BUILD_DIR)/include
+
+LINKER = $(VISC_BUILD_DIR)/bin/clang++
+PLATFORM_LDFLAGS = -lm -lpthread -lrt -lOpenCL -L$(OPENCL_LIB_PATH)
+
+LLVM_LIB_PATH = $(VISC_BUILD_DIR)/lib
+LLVM_BIN_PATH = $(VISC_BUILD_DIR)/bin
+
+OPT = $(LLVM_BIN_PATH)/opt
+LLVM_LINK = $(LLVM_BIN_PATH)/llvm-link
+LLVM_AS = $(LLVM_BIN_PATH)/llvm-as
+LIT = $(LLVM_BIN_PATH)/llvm-lit