diff --git a/client/tests/kvm/kvm_tests.cfg.sample b/client/tests/kvm/kvm_tests.cfg.sample
index 285a38f..0b2ab37 100644
--- a/client/tests/kvm/kvm_tests.cfg.sample
+++ b/client/tests/kvm/kvm_tests.cfg.sample
@@ -90,6 +90,10 @@ variants:
             - disktest:
                 test_name = disktest
                 test_control_file = disktest.control
+            - npb:
+                test_name = npb
+                test_control_file = npb.control
+                extra_params += " -smp 2"
 
     - linux_s3:     install setup
         type = linux_s3
diff --git a/client/tests/npb/control b/client/tests/npb/control
new file mode 100644
index 0000000..d6c2adb
--- /dev/null
+++ b/client/tests/npb/control
@@ -0,0 +1,28 @@
+NAME = "NAS Parallel Benchmarks"
+AUTHOR = "Cao, Chen <kcao@redhat.com>"
+TEST_TYPE = "CLIENT"
+TEST_CLASS = "HARDWARE"
+TEST_CATEGORY = "BENCHMARK"
+TIME = "MEDIUM"
+DOC = """\
+Using NPB, OpenMP implementation.
+
+See http://www.nas.nasa.gov/Software/NPB/
+"""
+
+# Supported tests (benchmarks):
+#   bt.A bt.B bt.C bt.D bt.E bt.S bt.W
+#   cg.A cg.B cg.C cg.S cg.W
+#   dc.A dc.B dc.S dc.W
+#   ep.A ep.B ep.C ep.D ep.E ep.S ep.W
+#   ft.A ft.B ft.S ft.W
+#   is.A is.B is.C is.S is.W
+#   lu.A lu.B lu.C lu.S lu.W
+#   mg.A mg.B mg.S mg.W
+#   sp.A sp.B sp.C sp.D sp.E sp.S sp.W
+#   ua.A ua.B ua.C ua.S ua.W
+#
+# Please refer to npb.py for more infomation about
+# the arguments.
+job.run_test(url='npb', tests='ep.A ep.B', ratio=0.5)
+
diff --git a/client/tests/npb/enable-all-tests.patch b/client/tests/npb/enable-all-tests.patch
new file mode 100644
index 0000000..f08a9d3
--- /dev/null
+++ b/client/tests/npb/enable-all-tests.patch
@@ -0,0 +1,233 @@
+diff --git a/NPB3.3-OMP/config/make.def b/NPB3.3-OMP/config/make.def
+new file mode 100644
+index 0000000..afffe7d
+--- /dev/null
++++ b/NPB3.3-OMP/config/make.def
+@@ -0,0 +1,161 @@
++#---------------------------------------------------------------------------
++#
++#                SITE- AND/OR PLATFORM-SPECIFIC DEFINITIONS. 
++#
++#---------------------------------------------------------------------------
++
++#---------------------------------------------------------------------------
++# Items in this file will need to be changed for each platform.
++#---------------------------------------------------------------------------
++
++#---------------------------------------------------------------------------
++# Parallel Fortran:
++#
++# For CG, EP, FT, MG, LU, SP, BT and UA, which are in Fortran, the following 
++# must be defined:
++#
++# F77        - Fortran compiler
++# FFLAGS     - Fortran compilation arguments
++# F_INC      - any -I arguments required for compiling Fortran 
++# FLINK      - Fortran linker
++# FLINKFLAGS - Fortran linker arguments
++# F_LIB      - any -L and -l arguments required for linking Fortran 
++# 
++# compilations are done with $(F77) $(F_INC) $(FFLAGS) or
++#                            $(F77) $(FFLAGS)
++# linking is done with       $(FLINK) $(F_LIB) $(FLINKFLAGS)
++#---------------------------------------------------------------------------
++
++#---------------------------------------------------------------------------
++# This is the fortran compiler used for Fortran programs
++#---------------------------------------------------------------------------
++F77 = gfortran
++# This links fortran programs; usually the same as ${F77}
++FLINK	= $(F77)
++
++#---------------------------------------------------------------------------
++# These macros are passed to the linker 
++#---------------------------------------------------------------------------
++F_LIB  =
++
++#---------------------------------------------------------------------------
++# These macros are passed to the compiler 
++#---------------------------------------------------------------------------
++F_INC =
++
++#---------------------------------------------------------------------------
++# Global *compile time* flags for Fortran programs
++#---------------------------------------------------------------------------
++FFLAGS	= -O -fopenmp 
++
++#---------------------------------------------------------------------------
++# Global *link time* flags. Flags for increasing maximum executable 
++# size usually go here. 
++#---------------------------------------------------------------------------
++FLINKFLAGS = -O -fopenmp 
++
++
++#---------------------------------------------------------------------------
++# Parallel C:
++#
++# For IS and DC, which are in C, the following must be defined:
++#
++# CC         - C compiler 
++# CFLAGS     - C compilation arguments
++# C_INC      - any -I arguments required for compiling C 
++# CLINK      - C linker
++# CLINKFLAGS - C linker flags
++# C_LIB      - any -L and -l arguments required for linking C 
++#
++# compilations are done with $(CC) $(C_INC) $(CFLAGS) or
++#                            $(CC) $(CFLAGS)
++# linking is done with       $(CLINK) $(C_LIB) $(CLINKFLAGS)
++#---------------------------------------------------------------------------
++
++#---------------------------------------------------------------------------
++# This is the C compiler used for C programs
++#---------------------------------------------------------------------------
++CC = cc
++# This links C programs; usually the same as ${CC}
++CLINK	= $(CC)
++
++#---------------------------------------------------------------------------
++# These macros are passed to the linker 
++#---------------------------------------------------------------------------
++C_LIB  = -lm
++
++#---------------------------------------------------------------------------
++# These macros are passed to the compiler 
++#---------------------------------------------------------------------------
++C_INC =
++
++#---------------------------------------------------------------------------
++# Global *compile time* flags for C programs
++# DC inspects the following flags (preceded by "-D"):
++#
++# IN_CORE - computes all views and checksums in main memory (if there is 
++# enough memory)
++#
++# VIEW_FILE_OUTPUT - forces DC to write the generated views to disk
++#
++# OPTIMIZATION - turns on some nonstandard DC optimizations
++#
++# _FILE_OFFSET_BITS=64 
++# _LARGEFILE64_SOURCE - are standard compiler flags which allow to work with 
++# files larger than 2GB.
++#---------------------------------------------------------------------------
++CFLAGS	= -O
++
++#---------------------------------------------------------------------------
++# Global *link time* flags. Flags for increasing maximum executable 
++# size usually go here. 
++#---------------------------------------------------------------------------
++CLINKFLAGS = -O
++
++
++#---------------------------------------------------------------------------
++# Utilities C:
++#
++# This is the C compiler used to compile C utilities.  Flags required by 
++# this compiler go here also; typically there are few flags required; hence 
++# there are no separate macros provided for such flags.
++#---------------------------------------------------------------------------
++UCC	= cc
++
++
++#---------------------------------------------------------------------------
++# Destination of executables, relative to subdirs of the main directory. . 
++#---------------------------------------------------------------------------
++BINDIR	= ../bin
++
++
++#---------------------------------------------------------------------------
++# The variable RAND controls which random number generator 
++# is used. It is described in detail in README.install. 
++# Use "randi8" unless there is a reason to use another one. 
++# Other allowed values are "randi8_safe", "randdp" and "randdpvec"
++#---------------------------------------------------------------------------
++RAND   = randi8
++# The following is highly reliable but may be slow:
++# RAND   = randdp
++
++
++#---------------------------------------------------------------------------
++# The variable WTIME is the name of the wtime source code module in the
++# common directory.  
++# For most machines,       use wtime.c
++# For SGI power challenge: use wtime_sgi64.c
++#---------------------------------------------------------------------------
++WTIME  = wtime.c
++
++
++#---------------------------------------------------------------------------
++# Enable if either Cray (not Cray-X1) or IBM: 
++# (no such flag for most machines: see common/wtime.h)
++# This is used by the C compiler to pass the machine name to common/wtime.h,
++# where the C/Fortran binding interface format is determined
++#---------------------------------------------------------------------------
++# MACHINE	=	-DCRAY
++# MACHINE	=	-DIBM
++
++
+diff --git a/NPB3.3-OMP/config/suite.def b/NPB3.3-OMP/config/suite.def
+new file mode 100644
+index 0000000..7342195
+--- /dev/null
++++ b/NPB3.3-OMP/config/suite.def
+@@ -0,0 +1,60 @@
++# config/suite.def
++# This file is used to build several benchmarks with a single command. 
++# Typing "make suite" in the main directory will build all the benchmarks
++# specified in this file. 
++# Each line of this file contains a benchmark name and the class.
++# The name is one of "cg", "is", "dc", "ep", mg", "ft", "sp",
++#  "bt", "lu", and "ua". 
++# The class is one of "S", "W", "A" through "E" 
++# (except that no classes C,D,E for DC and no class E for IS and UA).
++# No blank lines. 
++# The following example builds sample sizes of all benchmarks. 
++ft	A
++ft	B
++ft	S
++ft	W
++mg	A
++mg	B
++mg	S
++mg	W
++sp	A
++sp	B
++sp	C
++sp	S
++sp	W
++lu	A
++lu	B
++lu	C
++lu	S
++lu	W
++bt	A
++bt	B
++bt	C
++bt	S
++bt	W
++is	A
++is	B
++is	C
++is	S
++is	W
++ep	A
++ep	B
++ep	C
++ep	D
++ep	E
++ep	S
++ep	W
++cg	A
++cg	B
++cg	C
++cg	S
++cg	W
++ua	A
++ua	B
++ua	C
++ua	S
++ua	W
++dc	A
++dc	B
++dc	S
++dc	W
diff --git a/client/tests/npb/npb.py b/client/tests/npb/npb.py
new file mode 100644
index 0000000..7eb22d0
--- /dev/null
+++ b/client/tests/npb/npb.py
@@ -0,0 +1,95 @@
+import os, shutil, logging, re
+from autotest_lib.client.bin import test, utils
+from autotest_lib.client.common_lib import error
+
+class npb(test.test):
+    """
+    Run NAS Parallel Benchmarks as client test.
+
+    NOTE: Since we use gfortran to complie these benchmarks,
+    this test might not be able to run on old OSes.
+    """
+    version = 1
+
+    # http://www.nas.nasa.gov/Resources/Software/npb.html
+    def setup(self, tarball='NPB3.3.tar.gz', tests='', ratio=0.5):
+        # get the parameters for run_once()
+        self.tests = tests
+        self.ratio = ratio
+
+        tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
+        utils.extract_tarball_to_dir(tarball, self.srcdir)
+        os.chdir(self.srcdir)
+
+        # prepare the makefile and benchmarks to generate.
+        utils.system('patch -p1 < ../enable-all-tests.patch')
+        utils.system('cd NPB3.3-OMP && make suite', timeout=1800)
+
+
+    def run_once(self):
+        """
+        Run each benchmark twice, with different number of threads, and
+        compare the durations.
+        """
+        os.chdir(self.srcdir)
+
+        # get the tests to run
+        tests_list = self.tests.split()
+        if len(tests_list) == 0:
+            logging.warn('No tests (benchmarks) provided. exit.')
+            return
+
+        # run all tests
+        #
+        #   first with the default OMP_NUM_THREADS = cpu_nr of target machine.
+        #   then, with OMP_NUM_THREADS = 1
+        #
+        #   comparing the duration (Time in seconds) of the two runs.
+        #   if duration(cpu_nr) / duration(1) < cpu_nr * (1 - ratio) \
+        #           or duration(cpu_nr) / duration(1) > cpu_nr * (1 + ratio):
+        #       raise error
+        for itest in tests_list:
+            itest_cmd = os.path.join('NPB3.3-OMP/bin/', itest)
+            result = utils.run(itest_cmd, timeout=1800, ignore_status=True)
+            if result.exit_status != 0:
+                raise error.TestFail('%s failed\noutput:\n%s' % \
+                                                (itest_cmd, result.stdout))
+            logging.info(result.stdout)
+
+            # get cpu number of current machine,
+            # which is default thread number.
+            m = re.search('Total threads\s*=\s*(.*)\n', result.stdout)
+            # We will use this integer with float point vars later.
+            full_thrds = float(m.groups()[0])
+
+            # get duration for full_threads running.
+            m = re.search('Time in seconds\s*=\s*(.*)\n', result.stdout)
+            time_full_thrds = float(m.groups()[0])
+
+            # repeat the execution with single thread.
+            itest_cmd = ''.join(['OMP_NUM_THREADS=1 ', itest_cmd])
+            result = utils.run(itest_cmd, timeout=1800, ignore_status=True)
+            if result.exit_status != 0:
+                raise error.TestFail('%s failed\noutput:\n%s' % \
+                                                (itest_cmd, result.stdout))
+            logging.info(result.stdout)
+
+            m = re.search('Time in seconds\s*=\s*(.*)\n', result.stdout)
+            time_one_thrd = float(m.groups()[0])
+
+            # check durations
+            ratio = self.ratio
+            if time_one_thrd / time_full_thrds > full_thrds * (1 + ratio) or \
+                time_one_thrd / time_full_thrds < full_thrds * (1 - ratio):
+                raise error.TestFail('NPB failed, durations violates threads')
+
+            logging.info('%s succeeded.' % itest)
+
+
+    def cleanup(self):
+        """
+        Cleans up source directory.
+        """
+        if os.path.isdir(self.srcdir):
+            shutil.rmtree(self.srcdir)
+
