Added IPP Async converters, doc and sample
authorElena Gvozdeva <elena.gvozdeva@itseez.com>
Mon, 24 Feb 2014 06:44:54 +0000 (10:44 +0400)
committerElena Gvozdeva <elena.gvozdeva@itseez.com>
Tue, 1 Apr 2014 12:47:29 +0000 (16:47 +0400)
14 files changed:
CMakeLists.txt
cmake/OpenCVFindIPPAsync.cmake [new file with mode: 0644]
cmake/OpenCVFindLibsPerf.cmake
cmake/templates/cvconfig.h.in
doc/conf.py
doc/tutorials/core/how_to_use_ippa_conversion/how_to_use_ippa_conversion.rst [new file with mode: 0644]
doc/tutorials/core/how_to_use_ippa_conversion/images/How_To_Use_IPPA_Result.jpg [new file with mode: 0644]
doc/tutorials/core/table_of_content_core/images/How_To_Use_IPPA.jpg [new file with mode: 0644]
doc/tutorials/core/table_of_content_core/table_of_content_core.rst
modules/core/doc/core.rst
modules/core/doc/ipp_async_converters.rst [new file with mode: 0644]
modules/core/include/opencv2/core/ippasync.hpp [new file with mode: 0644]
modules/core/test/test_ippasync.cpp [new file with mode: 0644]
samples/cpp/tutorial_code/core/ippasync/ippasync_sample.cpp [new file with mode: 0644]

index 442edf3..6c36347 100644 (file)
@@ -157,7 +157,7 @@ OCV_OPTION(WITH_OPENCLAMDFFT   "Include AMD OpenCL FFT library support"      ON
 OCV_OPTION(WITH_OPENCLAMDBLAS  "Include AMD OpenCL BLAS library support"     ON   IF (NOT ANDROID AND NOT IOS) )
 OCV_OPTION(WITH_DIRECTX        "Include DirectX support"                     ON   IF WIN32 )
 OCV_OPTION(WITH_INTELPERC      "Include Intel Perceptual Computing support"  OFF  IF WIN32 )
-
+OCV_OPTION(WITH_IPP_A          "Include Intel IPP_A support"                 OFF  IF (MSVC OR X86 OR X86_64) )
 
 # OpenCV build components
 # ===================================================
@@ -923,6 +923,10 @@ else()
   status("    Use IPP:"   WITH_IPP AND NOT IPP_FOUND THEN "IPP not found" ELSE NO)
 endif()
 
+if(DEFINED WITH_IPP_A)
+status("    Use IPP Async:"  HAVE_IPP_A       THEN "YES" ELSE NO)
+endif(DEFINED WITH_IPP_A)
+
 status("    Use Eigen:"      HAVE_EIGEN       THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO)
 status("    Use TBB:"        HAVE_TBB         THEN "YES (ver ${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} interface ${TBB_INTERFACE_VERSION})" ELSE NO)
 status("    Use OpenMP:"     HAVE_OPENMP      THEN YES ELSE NO)
diff --git a/cmake/OpenCVFindIPPAsync.cmake b/cmake/OpenCVFindIPPAsync.cmake
new file mode 100644 (file)
index 0000000..0b5751b
--- /dev/null
@@ -0,0 +1,45 @@
+# Main variables:
+# IPP_A_LIBRARIES and IPP_A_INCLUDE to use IPP Async
+# HAVE_IPP_A for conditional compilation OpenCV with/without IPP Async
+
+# IPPAROOT - root of IPP Async installation
+
+if(X86_64)
+    find_path(
+    IPP_A_INCLUDE_DIR
+    NAMES ipp_async_defs.h
+    PATHS $ENV{IPPAROOT}
+    PATH_SUFFIXES include
+    DOC "Path to Intel IPP Async interface headers")
+    
+    find_file(
+    IPP_A_LIBRARIES
+    NAMES ipp_async_preview.lib
+    PATHS $ENV{IPPAROOT}
+    PATH_SUFFIXES lib/intel64
+    DOC "Path to Intel IPP Async interface libraries")
+    
+else()
+    find_path(
+    IPP_A_INCLUDE_DIR
+    NAMES ipp_async_defs.h
+    PATHS $ENV{IPPAROOT}
+    PATH_SUFFIXES include
+    DOC "Path to Intel IPP Async interface headers")
+    
+    find_file(
+    IPP_A_LIBRARIES
+    NAMES ipp_async_preview.lib
+    PATHS $ENV{IPPAROOT}
+    PATH_SUFFIXES lib/ia32
+    DOC "Path to Intel IPP Async interface libraries")
+endif()
+
+if(IPP_A_INCLUDE_DIR AND IPP_A_LIBRARIES)
+    set(HAVE_IPP_A TRUE)
+else()
+    set(HAVE_IPP_A FALSE)
+    message(WARNING "Intel IPP Async library directory (set by IPP_A_LIBRARIES_DIR variable) is not found or does not have Intel IPP Async libraries.")
+endif()
+
+mark_as_advanced(FORCE IPP_A_LIBRARIES IPP_A_INCLUDE_DIR)
\ No newline at end of file
index 4b80b1f..7d7b239 100644 (file)
@@ -19,6 +19,17 @@ if(WITH_IPP)
   endif()
 endif(WITH_IPP)
 
+# --- IPP Async ---
+
+if(WITH_IPP_A)
+  include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPPAsync.cmake")
+  if(IPP_A_INCLUDE_DIR AND IPP_A_LIBRARIES)
+    ocv_include_directories(${IPP_A_INCLUDE_DIR})
+    link_directories(${IPP_A_LIBRARIES})
+    set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${IPP_A_LIBRARIES})
+   endif()
+endif(WITH_IPP_A)
+
 # --- CUDA ---
 if(WITH_CUDA)
   include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCUDA.cmake")
index 3f316da..c02d9f6 100644 (file)
@@ -94,6 +94,9 @@
 /* Intel Integrated Performance Primitives */
 #cmakedefine HAVE_IPP
 
+/* Intel IPP Async */
+#cmakedefine HAVE_IPP_A
+
 /* JPEG-2000 codec */
 #cmakedefine HAVE_JASPER
 
index 0112725..08c6d12 100755 (executable)
@@ -416,5 +416,7 @@ extlinks = {
             'background_subtractor' : ('http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html?highlight=backgroundsubtractor#backgroundsubtractor%s', None),
             'background_subtractor_mog' : ('http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html?highlight=backgroundsubtractorMOG#backgroundsubtractormog%s', None),
             'background_subtractor_mog_two' : ('http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html?highlight=backgroundsubtractorMOG2#backgroundsubtractormog2%s', None),
-            'video_capture' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=videocapture#videocapture%s', None)
+            'video_capture' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=videocapture#videocapture%s', None),
+            'ippa_convert': ('http://docs.opencv.org/modules/core/doc/ipp_async_converters.html#%s', None),
+            'ptr':('http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=Ptr#Ptr%s', None)
            }
diff --git a/doc/tutorials/core/how_to_use_ippa_conversion/how_to_use_ippa_conversion.rst b/doc/tutorials/core/how_to_use_ippa_conversion/how_to_use_ippa_conversion.rst
new file mode 100644 (file)
index 0000000..bbdaa24
--- /dev/null
@@ -0,0 +1,156 @@
+.. _howToUseIPPAconversion:
+
+Intel® IPP Asynchronous C/C++ library in OpenCV
+***********************************************
+
+Goal
+====
+
+.. _hppiSobel: http://software.intel.com/en-us/node/474701
+.. _hppiMatrix: http://software.intel.com/en-us/node/501660
+
+The tutorial demonstrates the `Intel® IPP Asynchronous C/C++ <http://software.intel.com/en-us/intel-ipp-preview>`_ library usage with OpenCV. 
+The code example below illustrates implementation of the Sobel operation, accelerated with Intel® IPP Asynchronous C/C++ functions.
+In this code example, :ippa_convert:`hpp::getMat <>` and :ippa_convert:`hpp::getHpp <>` functions are used for data conversion between hppiMatrix_ and ``Mat`` matrices.
+
+Code
+====
+
+You may also find the source code in the :file:`samples/cpp/tutorial_code/core/ippasync/ippasync_sample.cpp` 
+file of the OpenCV source library or :download:`download it from here
+<../../../../samples/cpp/tutorial_code/core/ippasync/ippasync_sample.cpp>`.
+
+.. literalinclude:: ../../../../samples/cpp/tutorial_code/core/ippasync/ippasync_sample.cpp
+   :language: cpp
+   :linenos:
+   :tab-width: 4
+   
+Explanation
+===========
+
+#. Create parameters for OpenCV:
+
+   .. code-block:: cpp
+
+      VideoCapture cap;
+      Mat image, gray, result;
+
+   and IPP Async:
+
+   .. code-block:: cpp
+   
+      Ptr<hppiMatrix> src, dst;
+      hppAccel accel = 0;
+      hppAccelType accelType;
+      hppStatus sts;
+      hppiVirtualMatrix * virtMatrix;
+
+#. Load input image or video. How to open and read video stream you can see in the :ref:`videoInputPSNRMSSIM` tutorial.
+   
+   .. code-block:: cpp
+   
+      if( useCamera )
+      {
+         printf("used camera\n");
+         cap.open(0);
+      }
+      else
+      {
+         printf("used image %s\n", file.c_str());
+         cap.open(file.c_str());
+      }
+
+      if( !cap.isOpened() )
+      {
+         printf("can not open camera or video file\n");
+         return -1;
+      }
+   
+#. Create accelerator instance using `hppCreateInstance <http://software.intel.com/en-us/node/501686>`_:
+
+   .. code-block:: cpp
+   
+      accelType = sAccel == "cpu" ? HPP_ACCEL_TYPE_CPU:
+                  sAccel == "gpu" ? HPP_ACCEL_TYPE_GPU:
+                                    HPP_ACCEL_TYPE_ANY;
+                                    
+      //Create accelerator instance
+      sts = hppCreateInstance(accelType, 0, &accel);
+      CHECK_STATUS(sts, "hppCreateInstance");
+   
+#. Create an array of virtual matrices using `hppiCreateVirtualMatrices <http://software.intel.com/en-us/node/501700>`_ function.
+
+   .. code-block:: cpp
+
+      virtMatrix = hppiCreateVirtualMatrices(accel, 1);
+   
+#. Prepare a matrix for input and output data:
+
+   .. code-block:: cpp
+
+      cap >> image;
+      if(image.empty())
+         break;
+
+      cvtColor( image, gray, COLOR_BGR2GRAY );
+
+      result.create( image.rows, image.cols, CV_8U);
+   
+#. Convert ``Mat`` to hppiMatrix_ using :ippa_convert:`getHpp <>` and call hppiSobel_ function.
+
+   .. code-block:: cpp
+
+      //convert Mat to hppiMatrix
+      src = getHpp(gray);
+      dst = getHpp(result);
+
+      sts = hppiSobel(accel,src, HPP_MASK_SIZE_3X3,HPP_NORM_L1,virtMatrix[0]);
+      CHECK_STATUS(sts,"hppiSobel");
+
+      sts = hppiConvert(accel, virtMatrix[0], 0, HPP_RND_MODE_NEAR, dst, HPP_DATA_TYPE_8U);
+      CHECK_STATUS(sts,"hppiConvert");
+
+      // Wait for tasks to complete
+      sts = hppWait(accel, HPP_TIME_OUT_INFINITE);
+      CHECK_STATUS(sts, "hppWait");
+   
+   We use `hppiConvert <http://software.intel.com/en-us/node/501746>`_ because hppiSobel_ returns destination
+   matrix with ``HPP_DATA_TYPE_16S`` data type for source matrix with ``HPP_DATA_TYPE_8U`` type.
+   You should check ``hppStatus`` after each call IPP Async function.
+
+#. Create windows and show the images, the usual way.
+
+   .. code-block:: cpp
+
+      imshow("image", image);
+      imshow("rez", result);
+
+      waitKey(15);
+   
+#. Delete virtual matrices and accelerator instance.
+
+   .. code-block:: cpp
+
+      if (virtMatrix)
+      {
+         sts = hppiDeleteVirtualMatrices(accel, virtMatrix);
+         CHECK_DEL_STATUS(sts,"hppiDeleteVirtualMatrices");
+      }
+
+      if (accel)
+      {
+         sts = hppDeleteInstance(accel);
+         CHECK_DEL_STATUS(sts, "hppDeleteInstance");
+      }
+
+   We shouldn't delete hppiMatrix_ because we use :ptr:`Ptr <>` and so `hppiFreeMatrix <http://software.intel.com/en-us/node/501699>`_ will be called implicitly.
+
+Result
+=======
+
+After compiling the code above we can execute it giving an image or video path and accelerator type as an argument. 
+For this tutorial we use baboon.png image as input. The result is below.
+
+  .. image:: images/How_To_Use_IPPA_Result.jpg
+    :alt: Final Result
+    :align: center
\ No newline at end of file
diff --git a/doc/tutorials/core/how_to_use_ippa_conversion/images/How_To_Use_IPPA_Result.jpg b/doc/tutorials/core/how_to_use_ippa_conversion/images/How_To_Use_IPPA_Result.jpg
new file mode 100644 (file)
index 0000000..2bdeb83
Binary files /dev/null and b/doc/tutorials/core/how_to_use_ippa_conversion/images/How_To_Use_IPPA_Result.jpg differ
diff --git a/doc/tutorials/core/table_of_content_core/images/How_To_Use_IPPA.jpg b/doc/tutorials/core/table_of_content_core/images/How_To_Use_IPPA.jpg
new file mode 100644 (file)
index 0000000..8bba605
Binary files /dev/null and b/doc/tutorials/core/table_of_content_core/images/How_To_Use_IPPA.jpg differ
index 4150265..62a0e4f 100644 (file)
@@ -200,8 +200,28 @@ Here you will learn the about the basic building blocks of the library. A must r
                    :height: 90pt
                    :width:  90pt
 
+  =============== ======================================================
++
+  .. tabularcolumns:: m{100pt} m{300pt}
+  .. cssclass:: toctableopencv
+  
+  =============== ======================================================
+   |IPPIma|       **Title:** :ref:`howToUseIPPAconversion`
+
+                  *Compatibility:* > OpenCV 2.0
+
+                  *Author:* |Author_ElenaG|
 
+                  You will see how to use the IPP Async with OpenCV.
+                  
+  =============== ======================================================
+  
+  .. |IPPIma| image:: images/How_To_Use_IPPA.jpg
+                   :height: 90pt
+                   :width:  90pt
+  .. |Author_ElenaG| unicode:: Elena U+0020 Gvozdeva              
 
+  =============== ======================================================
 .. raw:: latex
 
    \pagebreak
@@ -219,3 +239,4 @@ Here you will learn the about the basic building blocks of the library. A must r
    ../discrete_fourier_transform/discrete_fourier_transform
    ../file_input_output_with_xml_yml/file_input_output_with_xml_yml
    ../interoperability_with_OpenCV_1/interoperability_with_OpenCV_1
+   ../how_to_use_ippa_conversion/how_to_use_ippa_conversion
index 73bfc35..669fddd 100644 (file)
@@ -16,3 +16,4 @@ core. The Core Functionality
     clustering
     utility_and_system_functions_and_macros
     opengl_interop
+    ipp_async_converters
diff --git a/modules/core/doc/ipp_async_converters.rst b/modules/core/doc/ipp_async_converters.rst
new file mode 100644 (file)
index 0000000..6fac234
--- /dev/null
@@ -0,0 +1,62 @@
+Intel® IPP Asynchronous C/C++ Converters
+========================================
+
+.. highlight:: cpp
+
+General Information
+-------------------
+
+This section describes conversion between OpenCV and `Intel® IPP Asynchronous C/C++ <http://software.intel.com/en-us/intel-ipp-preview>`_ library. 
+`Getting Started Guide <http://registrationcenter.intel.com/irc_nas/3727/ipp_async_get_started.htm>`_ help you to install the library, configure header and library build paths.
+
+hpp::getHpp
+-----------
+Create ``hppiMatrix`` from ``Mat``.
+
+.. ocv:function:: Ptr<hppiMatrix> hpp::getHpp(const Mat& src)
+
+    :param src: input matrix.
+
+This function allocates and initializes the ``hppiMatrix`` that has the same size and type as input matrix, returns the ``Ptr<hppiMatrix>``.
+Supports ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32S``, ``CV_32F``, ``CV_64F``.
+
+.. note:: The ``hppiMatrix`` pointer to the image buffer in system memory refers to the ``src.data``. Control the lifetime of the matrix and don't change its data, if there is no special need. 
+.. seealso:: :ref:`howToUseIPPAconversion`, :ocv:func:`hpp::getMat`
+
+
+hpp::getMat
+-----------
+Create ``Mat`` from ``hppiMatrix``.
+
+.. ocv:function:: Mat hpp::getMat(hppiMatrix* src, hppAccel accel, int cn)
+
+    :param src: input hppiMatrix.
+
+    :param accel: accelerator instance.
+
+    :param cn: number of channels.
+
+This function allocates and initializes the ``Mat`` that has the same size and type as input matrix. 
+Supports ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32S``, ``CV_32F``, ``CV_64F``.
+
+.. seealso:: :ref:`howToUseIPPAconversion`, :ocv:func:`hpp::copyHppToMat`, :ocv:func:`hpp::getHpp`.
+
+
+hpp::copyHppToMat
+-----------------
+Convert ``hppiMatrix`` to ``Mat``.
+
+.. ocv:function:: void hpp::copyHppToMat(hppiMatrix* src, Mat& dst, hppAccel accel, int cn)
+
+    :param src: input hppiMatrix.
+    
+    :param dst: output matrix.
+
+    :param accel: accelerator instance.
+
+    :param cn: number of channels.
+
+This function allocates and initializes new matrix (if needed) that has the same size and type as input matrix. 
+Supports ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32S``, ``CV_32F``, ``CV_64F``.
+
+.. seealso:: :ref:`howToUseIPPAconversion`, :ocv:func:`hpp::getMat`, :ocv:func:`hpp::getHpp`.
\ No newline at end of file
diff --git a/modules/core/include/opencv2/core/ippasync.hpp b/modules/core/include/opencv2/core/ippasync.hpp
new file mode 100644 (file)
index 0000000..b17a803
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef __OPENCV_CORE_IPPASYNC_HPP__
+#define __OPENCV_CORE_IPPASYNC_HPP__
+
+#include "opencv2/core.hpp"
+#include <ipp_async_op.h>
+#include <ipp_async_accel.h>
+
+namespace cv
+{
+    void DefaultDeleter<hppiMatrix>::operator () (hppiMatrix* p) const
+    {
+        hppiFreeMatrix(p);
+    }
+
+namespace hpp
+{
+    //convert OpenCV data type to hppDataType
+    inline int toHppType(const int cvType)
+    {
+        int depth = CV_MAT_DEPTH(cvType);
+        int hppType = depth == CV_8U ? HPP_DATA_TYPE_8U :
+                     depth == CV_16U ? HPP_DATA_TYPE_16U :
+                     depth == CV_16S ? HPP_DATA_TYPE_16S :
+                     depth == CV_32S ? HPP_DATA_TYPE_32S :
+                     depth == CV_32F ? HPP_DATA_TYPE_32F :
+                     depth == CV_64F ? HPP_DATA_TYPE_64F : -1;
+        CV_Assert( hppType >= 0 );
+        return hppType; 
+    }
+
+    //convert hppDataType to OpenCV data type
+    inline int toCvType(const int hppType)
+    {
+        int cvType = hppType == HPP_DATA_TYPE_8U ? CV_8U :
+                    hppType == HPP_DATA_TYPE_16U ? CV_16U :
+                    hppType == HPP_DATA_TYPE_16S ? CV_16S :
+                    hppType == HPP_DATA_TYPE_32S ? CV_32S :
+                    hppType == HPP_DATA_TYPE_32F ? CV_32F :
+                    hppType == HPP_DATA_TYPE_64F ? CV_64F : -1;
+        CV_Assert( cvType >= 0 );
+        return cvType;
+    }
+
+    inline void copyHppToMat(hppiMatrix* src, Mat& dst, hppAccel accel, int cn)
+    {
+        hppDataType type;
+        hpp32u width, height;
+        hppStatus sts;
+
+        CV_Assert(src!=NULL);
+
+        sts = hppiInquireMatrix(src, &type, &width, &height);
+
+        CV_Assert( sts == HPP_STATUS_NO_ERROR);
+
+        int matType = CV_MAKETYPE(toCvType(type), cn);
+
+        CV_Assert(width%cn == 0);
+
+        width /= cn;
+
+        dst.create((int)height, (int)width, (int)matType);
+
+        size_t newSize = (size_t)(height*(hpp32u)(dst.step));
+
+        sts = hppiGetMatrixData(accel,src,(hpp32u)(dst.step),dst.data,&newSize);
+
+        CV_Assert( sts == HPP_STATUS_NO_ERROR);
+    }
+
+    //create cv::Mat from hppiMatrix
+    inline Mat getMat(hppiMatrix* src, hppAccel accel, int cn)
+    {
+        Mat dst;
+        copyHppToMat(src, dst, accel, cn);
+        return dst;
+    }
+
+     //create hppiMatrix from cv::Mat
+    inline Ptr<hppiMatrix> getHpp(const Mat& src)
+    {
+        int htype = toHppType(src.type());
+        int cn = src.channels();
+
+        CV_Assert(src.data);
+        hppiMatrix *dst = hppiCreateMatrix(htype, src.cols*cn, src.rows, src.data, (hpp32s)(src.step));
+
+        return Ptr<hppiMatrix>(dst);
+    }
+}}
+
+#endif
\ No newline at end of file
diff --git a/modules/core/test/test_ippasync.cpp b/modules/core/test/test_ippasync.cpp
new file mode 100644 (file)
index 0000000..61e407a
--- /dev/null
@@ -0,0 +1,116 @@
+#include "test_precomp.hpp"
+#include "opencv2/ts/ocl_test.hpp"
+
+#include "opencv2/core/ippasync.hpp"
+
+using namespace cv;
+using namespace std;
+using namespace cvtest;
+
+namespace cvtest {
+namespace ocl {
+
+PARAM_TEST_CASE(IPPAsync, MatDepth, Channels, hppAccelType)
+{
+    int type;
+    int cn;
+    int depth;
+    hppAccelType accelType;
+
+    Mat matrix, result;
+    Ptr<hppiMatrix> hppMat;
+    hppAccel accel;
+    hppiVirtualMatrix * virtMatrix;
+    hppStatus sts;
+
+    virtual void SetUp()
+    {
+        type = CV_MAKE_TYPE(GET_PARAM(0), GET_PARAM(1));
+        depth = GET_PARAM(0);
+        cn = GET_PARAM(1);
+        accelType = GET_PARAM(2);
+    }
+
+    virtual void generateTestData()
+    {
+        Size matrix_Size = randomSize(2, 100);
+        const double upValue = 100;
+
+        matrix = randomMat(matrix_Size, type, -upValue, upValue);
+    }
+
+    void Near(double threshold = 0.0)
+    {
+        EXPECT_MAT_NEAR(matrix, result, threshold);
+    }
+};
+
+TEST_P(IPPAsync, accuracy)
+{
+    if (depth==CV_32S || depth==CV_64F)
+        return;
+    
+    sts = hppCreateInstance(accelType, 0, &accel);
+    CV_Assert(sts==HPP_STATUS_NO_ERROR);
+    virtMatrix = hppiCreateVirtualMatrices(accel, 2);
+
+    for (int j = 0; j < test_loop_times; j++)
+    {
+        generateTestData();
+        hppMat = hpp::getHpp(matrix);
+
+        hppScalar a = 3;
+
+        sts = hppiAddC(accel, hppMat, a, 0, virtMatrix[0]);
+        CV_Assert(sts==HPP_STATUS_NO_ERROR);
+        sts = hppiSubC(accel, virtMatrix[0], a, 0, virtMatrix[1]);
+        CV_Assert(sts==HPP_STATUS_NO_ERROR);
+
+        sts = hppWait(accel, HPP_TIME_OUT_INFINITE);
+        CV_Assert(sts==HPP_STATUS_NO_ERROR);
+        
+        result = hpp::getMat(virtMatrix[1], accel, cn);
+
+        Near(5.0e-6);
+    }
+
+    sts = hppiDeleteVirtualMatrices(accel, virtMatrix);
+    CV_Assert(sts==HPP_STATUS_NO_ERROR);
+    sts = hppDeleteInstance(accel);
+    CV_Assert(sts==HPP_STATUS_NO_ERROR);
+}
+
+TEST_P(IPPAsync, conversion)
+{
+    sts = hppCreateInstance(accelType, 0, &accel);
+    CV_Assert(sts==HPP_STATUS_NO_ERROR);
+    virtMatrix = hppiCreateVirtualMatrices(accel, 1);
+
+    for (int j = 0; j < test_loop_times; j++)
+    {
+        generateTestData();
+        hppMat = hpp::getHpp(matrix);
+
+        sts = hppiCopy (accel, hppMat, virtMatrix[0]);
+        CV_Assert(sts==HPP_STATUS_NO_ERROR);
+
+        sts = hppWait(accel, HPP_TIME_OUT_INFINITE);
+        CV_Assert(sts==HPP_STATUS_NO_ERROR);
+        
+        result = hpp::getMat(virtMatrix[0], accel, cn);
+
+        Near();
+    }
+
+    sts = hppiDeleteVirtualMatrices(accel, virtMatrix);
+    CV_Assert(sts==HPP_STATUS_NO_ERROR);
+    sts = hppDeleteInstance(accel);
+    CV_Assert(sts==HPP_STATUS_NO_ERROR);
+}
+
+INSTANTIATE_TEST_CASE_P(IppATest, IPPAsync, Combine(Values(CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F),
+                                                   Values(1, 2, 3, 4),
+                                                   Values( HPP_ACCEL_TYPE_CPU, HPP_ACCEL_TYPE_GPU)));
+
+}
+}
\ No newline at end of file
diff --git a/samples/cpp/tutorial_code/core/ippasync/ippasync_sample.cpp b/samples/cpp/tutorial_code/core/ippasync/ippasync_sample.cpp
new file mode 100644 (file)
index 0000000..f7bc80a
--- /dev/null
@@ -0,0 +1,149 @@
+#include <stdio.h>
+
+#include "opencv2/core/utility.hpp"
+#include "opencv2/core/ippasync.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/highgui.hpp"
+
+#define CHECK_STATUS(STATUS, NAME)\
+    if(STATUS!=HPP_STATUS_NO_ERROR){ printf("%s error %d\n", NAME, STATUS);\
+    if (virtMatrix) {hppStatus delSts = hppiDeleteVirtualMatrices(accel, virtMatrix); CHECK_DEL_STATUS(delSts,"hppiDeleteVirtualMatrices");}\
+    if (accel)      {hppStatus delSts = hppDeleteInstance(accel); CHECK_DEL_STATUS(delSts, "hppDeleteInstance");}\
+    return -1;}
+
+#define CHECK_DEL_STATUS(STATUS, NAME)\
+    if(STATUS!=HPP_STATUS_NO_ERROR){ printf("%s error %d\n", NAME, STATUS); return -1;}
+
+using namespace std;
+using namespace cv;
+using namespace hpp;
+
+static void help()
+{
+ printf("\nThis program shows how to use the conversion for IPP Async.\n"
+"This example uses the Sobel filter.\n"
+"You can use cv::Sobel or hppiSobel.\n"
+"Usage: \n"
+"./ipp_async_sobel [--camera]=<use camera,if this key is present>, \n"
+"                  [--file_name]=<path to movie or image file>\n"
+"                  [--accel]=<accelerator type: auto (default), cpu, gpu>\n\n");
+}
+
+const char* keys =
+{
+    "{c  camera   |           | use camera or not}"
+    "{fn file_name|baboon.jpg | image file       }"
+    "{a accel     |cpu        | accelerator type: auto (default), cpu, gpu}"
+};
+
+//this is a sample for hppiSobel functions
+int main(int argc, const char** argv)
+{
+    help();
+
+    VideoCapture cap;
+    Mat image, gray, result;
+
+    Ptr<hppiMatrix> src, dst;
+    hppAccel accel = 0;
+    hppAccelType accelType;
+    hppStatus sts;
+    hppiVirtualMatrix * virtMatrix;
+
+    CommandLineParser parser(argc, argv, keys);
+    bool useCamera = parser.has("camera");
+    string file = parser.get<string>("file_name");
+    string sAccel = parser.get<string>("accel");
+
+    parser.printMessage();
+
+    if( useCamera )
+    {
+        printf("used camera\n");
+        cap.open(0);
+    }
+    else
+    {
+        printf("used image %s\n", file.c_str());
+        cap.open(file.c_str());
+    }
+
+    if( !cap.isOpened() )
+    {
+        printf("can not open camera or video file\n");
+        return -1;
+    }
+
+    accelType = sAccel == "cpu" ? HPP_ACCEL_TYPE_CPU:
+                sAccel == "gpu" ? HPP_ACCEL_TYPE_GPU:
+                                  HPP_ACCEL_TYPE_ANY;
+
+    //Create accelerator instance
+    sts = hppCreateInstance(accelType, 0, &accel);
+    CHECK_STATUS(sts, "hppCreateInstance");
+
+    accelType = hppQueryAccelType(accel);
+
+    sAccel = accelType == HPP_ACCEL_TYPE_CPU ? "cpu":
+             accelType == HPP_ACCEL_TYPE_GPU ? "gpu":
+             accelType == HPP_ACCEL_TYPE_GPU_VIA_DX9 ? "gpu":
+             accelType == HPP_ACCEL_TYPE_OCL ? "ocl": "?";
+
+    printf("accelType %s\n", sAccel.c_str());
+
+    virtMatrix = hppiCreateVirtualMatrices(accel, 1);
+
+    for(;;)
+    {
+        cap >> image;
+        if(image.empty())
+            break;
+
+        cvtColor( image, gray, COLOR_BGR2GRAY );
+
+        result.create( image.rows, image.cols, CV_8U);
+
+        double execTime = (double)getTickCount();
+            
+        //convert Mat to hppiMatrix
+        src = getHpp(gray);
+        dst = getHpp(result);
+
+        sts = hppiSobel(accel,src, HPP_MASK_SIZE_3X3,HPP_NORM_L1,virtMatrix[0]);
+        CHECK_STATUS(sts,"hppiSobel");
+
+        sts = hppiConvert(accel, virtMatrix[0], 0, HPP_RND_MODE_NEAR, dst, HPP_DATA_TYPE_8U);
+        CHECK_STATUS(sts,"hppiConvert");
+
+        // Wait for tasks to complete
+        sts = hppWait(accel, HPP_TIME_OUT_INFINITE);
+        CHECK_STATUS(sts, "hppWait");
+
+        execTime = ((double)getTickCount() - execTime)*1000./getTickFrequency();
+
+        printf("Time : %0.3fms\n", execTime);
+
+        imshow("image", image);
+        imshow("rez", result);
+
+        waitKey(15);
+    }
+
+    if (!useCamera)
+        waitKey(0);
+
+    if (virtMatrix)
+    {
+        sts = hppiDeleteVirtualMatrices(accel, virtMatrix);
+        CHECK_DEL_STATUS(sts,"hppiDeleteVirtualMatrices");
+    }
+
+    if (accel)
+    {
+        sts = hppDeleteInstance(accel);
+        CHECK_DEL_STATUS(sts, "hppDeleteInstance");
+    }
+
+    printf("SUCCESS\n");
+    return -1;
+}
\ No newline at end of file