diff --git a/llvm/test/VISC/parboil/benchmarks/kmeans/Makefile b/llvm/test/VISC/parboil/benchmarks/kmeans/Makefile
index cf8d1daa15339d54626fcddbf613334f39b8c079..9b0242c6e7273999cc79771f222531c7d108235c 100644
--- a/llvm/test/VISC/parboil/benchmarks/kmeans/Makefile
+++ b/llvm/test/VISC/parboil/benchmarks/kmeans/Makefile
@@ -1,25 +1,34 @@
-include ../../common/make.config
-# C compiler
-CC = g++
-CC_FLAGS = -g -O2 
+PARBOIL_ROOT = $(LLVM_SRC_ROOT)/test/VISC/parboil
+APP = kmeans
 
-kmeans: cluster.o getopt.o read_input.o kmeans_clustering.o rmse.o
-	$(CC) $(KERNEL_DIM) $(CC_FLAGS) -lOpenCL kmeans.cpp cluster.o getopt.o read_input.o kmeans_clustering.o rmse.o -o kmeans -I$(OPENCL_INC) -I$(OPENCL_DIR)/shared/inc/ -L$(OPENCL_LIB)
+# Default compile visc
+ifeq ($(VERSION),)
+  VERSION = opencl
+endif
 
-%.o: %.[ch]
-	$(CC) $(CC_FLAGS) $< -c
+# Default use small test case
+ifeq ($(TEST),)
+  TEST = small
+endif
 
-cluster.o: cluster.c 
-	$(CC) $(CC_FLAGS) cluster.c -c
+ifeq ($(PLATFORM),)
+PLATFORM=default
+endif
 
-getopt.o: getopt.c 
-	$(CC) $(CC_FLAGS) getopt.c -c
+BIN = $(addsuffix -$(VERSION), $(APP))
 
-kmeans.o: kmeans.c 
-	$(CC) $(CC_FLAGS) read_input.c -c
+SRCDIR = src/$(VERSION)
+BUILDDIR = build/$(VERSION)_$(PLATFORM)
+DATASET_DIR = $(PARBOIL_ROOT)/datasets/$(APP)
 
-rmse.o: rmse.c
-	$(CC) $(CC_FLAGS) rmse.c -c
+ifeq ($(TEST),small)
+  INPUT = $(DATASET_DIR)/input/kdd_cup
+  REF_OUTPUT = $(DATASET_DIR)/output/kdd_cup.out
+  RUNDIR = run/$(VERSION)/small
+  OUTPUT = $(RUNDIR)/kdd_cup.out
+endif
 
-clean:
-	rm -f *.o *~ kmeans *.linkinfo
+ARGS = -i $(INPUT) -o $(OUTPUT)
+TOOL = tools/compare-output
+
+include $(PARBOIL_ROOT)/common/mk/Makefile
diff --git a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/Makefile b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/Makefile
index 4d28522a8c3a6cbd3538f03697efcde5c4a40f01..255f7328c8f3d7d1c99a6c74bde1ef1a9c3ca584 100755
--- a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/Makefile
+++ b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/Makefile
@@ -1,26 +1,7 @@
-include ../../../../common/Makefile.conf
-# C compiler
-CC = clang++
-CC_FLAGS = -g -O2 
-OPENCL_INC = $(OPENCL_PATH)/include
+# (c) 2010 The Board of Trustees of the University of Illinois.
 
-kmeans: cluster.o getopt.o read_input.o kmeans_clustering.o rmse.o
-	$(CC) $(KERNEL_DIM) $(CC_FLAGS) -lOpenCL kmeans.cpp cluster.o getopt.o read_input.o kmeans_clustering.o rmse.o -o kmeans -I$(OPENCL_INC) -I$(OPENCL_PATH)/shared/inc/ -L$(OPENCL_LIB_PATH)
-
-%.o: %.[ch]
-	$(CC) $(CC_FLAGS) $< -c
-
-cluster.o: cluster.c 
-	$(CC) $(CC_FLAGS) cluster.c -c
-
-getopt.o: getopt.c 
-	$(CC) $(CC_FLAGS) getopt.c -c
-
-kmeans.o: kmeans.c 
-	$(CC) $(CC_FLAGS) read_input.c -c
-
-rmse.o: rmse.c
-	$(CC) $(CC_FLAGS) rmse.c -c
-
-clean:
-	rm -f *.o *~ kmeans *.linkinfo
+LANGUAGE=opencl
+SRCDIR_OBJS=kmeans.o cluster.o getopt.o read_input.o kmeans_clustering.o rmse.o #compute_gold.o
+APP_CUDALDFLAGS=-lm -lstdc++
+APP_CFLAGS= -O2
+APP_CXXFLAGS= -O2
diff --git a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.cpp b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.cpp
index 5807a7e3ff66c8fd0c116e39c2d6612446b26698..1488340f4582d42b7022d7699dfbb15f2ccca025 100644
--- a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.cpp
+++ b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.cpp
@@ -149,7 +149,7 @@ int allocate(int n_points, int n_features, int n_clusters, float **feature)
     }
 
     // read the kernel core source
-    char * tempchar = "./kmeans.cl";
+    char * tempchar = "src/opencl/kmeans.cl";
     FILE * fp = fopen(tempchar, "rb");
     if(!fp) {
         printf("ERROR: unable to open '%s'\n", tempchar);
@@ -267,7 +267,7 @@ int main( int argc, char** argv)
     shutdown();
 }
 
-int	kmeansOCL(float **feature,    /* in: [npoints][nfeatures] */
+int kmeansOCL(float **feature,    /* in: [npoints][nfeatures] */
               int     n_features,
               int     n_points,
               int     n_clusters,
diff --git a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.h b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.h
index 4ba920ee80b087b813f7d61362c855aaf637c57c..0397992475a6023e2958c99b3098680d90285e5c 100644
--- a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.h
+++ b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/kmeans.h
@@ -49,10 +49,16 @@ float   euclid_dist_2        (float*, float*, int);
 int     find_nearest_point   (float* , int, float**, int);
 float	rms_err(float**, int, int, float**, int);
 int     cluster(int, int, float**, int, int, float, int*, float***, float*, int, int);
-int setup(int argc, char** argv);
-int allocate(int npoints, int nfeatures, int nclusters, float **feature);
-void deallocateMemory();
-int	kmeansOCL(float **feature, int nfeatures, int npoints, int nclusters, int *membership, float **clusters, int *new_centers_len, float  **new_centers);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  int setup(int argc, char** argv);
+  int allocate(int npoints, int nfeatures, int nclusters, float **feature);
+  void deallocateMemory();
+  int kmeansOCL(float **feature, int nfeatures, int npoints, int nclusters, int *membership, float **clusters, int *new_centers_len, float  **new_centers);
+#ifdef __cplusplus
+}
+#endif
 float** kmeans_clustering(float **feature, int nfeatures, int npoints, int nclusters, float threshold, int *membership);
 
 #endif
diff --git a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/read_input.c b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/read_input.c
index 2da5f2234371adefccc5a8edb36d09eaaf02e444..e29032cc9c535b28a940597df9bc6beed4fbb3e5 100644
--- a/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/read_input.c
+++ b/llvm/test/VISC/parboil/benchmarks/kmeans/src/opencl/read_input.c
@@ -105,6 +105,7 @@ int setup(int argc, char **argv) {
     int		opt;
     extern char   *optarg;
     char   *filename = 0;
+    char* outfilename = 0;
     float  *buf;
     char	line[1024];
     int		isBinaryFile = 0;
@@ -129,7 +130,7 @@ int setup(int argc, char **argv) {
     //float	cluster_timing, io_timing;
 
     /* obtain command line arguments and change appropriate options */
-    while ( (opt=getopt(argc,argv,"i:t:m:n:l:bro"))!= EOF) {
+    while ( (opt=getopt(argc,argv,"i:t:m:n:l:o:br"))!= EOF) {
         switch (opt) {
         case 'i':
             filename=optarg;
@@ -151,6 +152,7 @@ int setup(int argc, char **argv) {
             break;
         case 'o':
             isOutput = 1;
+            outfilename = optarg;
             break;
         case 'l':
             nloops = atoi(optarg);
@@ -265,15 +267,27 @@ int setup(int argc, char **argv) {
 
     /* cluster center coordinates
        :displayed only for when k=1*/
+
+    //printf("Input file = %s\n", filename);
+    //printf("Output file = %s\n", outfilename);
     if((min_nclusters == max_nclusters) && (isOutput == 1)) {
-        printf("\n================= Centroid Coordinates =================\n");
-        for(i = 0; i < max_nclusters; i++) {
-            printf("%d:", i);
-            for(j = 0; j < nfeatures; j++) {
-                printf(" %.2f", cluster_centres[i][j]);
-            }
-            printf("\n\n");
+        FILE *outfile;
+        if ((outfile = fopen(outfilename, "w")) == NULL) {
+            fprintf(stderr, "Error: no such file (%s)\n", outfilename);
+            exit(1);
         }
+        fwrite(&max_nclusters, sizeof(int), 1, outfile);
+        fwrite(&nfeatures, sizeof(int), 1, outfile);
+        fwrite(cluster_centres, sizeof(float), max_nclusters*nfeatures, outfile);
+        fclose(outfile);
+        //printf("\n================= Centroid Coordinates =================\n");
+        //for(i = 0; i < max_nclusters; i++) {
+            //printf("%d:", i);
+            //for(j = 0; j < nfeatures; j++) {
+                //printf(" %.2f", cluster_centres[i][j]);
+            //}
+            //printf("\n\n");
+        //}
     }
 
     len = (float) ((max_nclusters - min_nclusters + 1)*nloops);
diff --git a/llvm/test/VISC/parboil/benchmarks/kmeans/tools/compare-output b/llvm/test/VISC/parboil/benchmarks/kmeans/tools/compare-output
new file mode 100755
index 0000000000000000000000000000000000000000..bec108bbc3d35ac2e2a303068b32c54798ec6ee1
--- /dev/null
+++ b/llvm/test/VISC/parboil/benchmarks/kmeans/tools/compare-output
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import struct
+
+tol_diff = 0.001
+tol_ratio = 0.002
+
+def Exit(b):
+  if b:
+    print "Pass"
+    sys.exit(0)
+  else:
+    print "Mismatch"
+    sys.exit(1)
+
+def Run():
+  try:
+    hx = open(sys.argv[1], 'rb')
+    hy = open(sys.argv[2], 'rb')
+  except:
+    Exit(False)
+
+  try:
+    # size (int)
+    dx = hx.read(8)
+    dy = hy.read(8)
+
+    lx = struct.unpack("i", dx[0:4])[0]
+    ly = struct.unpack("i", dy[0:4])[0]
+    fx = struct.unpack("i", dx[4:8])[0]
+    fy = struct.unpack("i", dy[4:8])[0]
+  except:
+    Exit(False)
+
+  data_r = hx.read()
+  data_c = hy.read()
+
+  hx.close()
+  hy.close()
+
+  if lx != ly or fx != fy:
+    print "Reference and compare are different in size"
+    Exit(False)
+  if len(data_r) != 4 * lx * fx:
+    print "Reference: sanity check failed"
+    Exit(False)
+  if len(data_c) != 4 * ly * fy:
+    print "Compare: sanity check failed"
+    Exit(False)
+
+  for i in range(0, lx*fx*4, 4):
+    r = struct.unpack('f', data_r[i:i+4])[0]
+    c = struct.unpack('f', data_c[i:i+4])[0]
+
+    diff = abs(r - c)
+    if not (diff <= tol_diff or diff < tol_ratio * abs(r)):
+      print r, c, "at" , (i/4)/fx, (i/4)%fx
+      Exit(False)
+
+  Exit(True)
+
+Run()
+