# Usage of UMat and Mat

**URL:** <https://forum.opencv.org/t/usage-of-umat-and-mat/4828>\
**Category:** C++\
**Tags:** mat, opencl\
**Created:** [August 18, 2021, 2:54pm UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828 "2021-08-18T14:54:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mustafa\_Bay](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/mustafa_bay/32/1843_2.png) [@Mustafa\_Bay](https://forum.opencv.org/u/Mustafa_Bay)\
**Post date:** [August 18, 2021, 2:54pm UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828/1 "2021-08-18T14:54:42Z")

</div>

Hi Everyone,

I am using OpenCV 4.1.2 and I want to understand usage of UMat and Mat. I wonder that when I retrieve an UMat from Mat by using getUMat() function, what happen if I make a change on UMat. Is Mat changed at the same time with UMat (I mean is that same operation made on Mat or not)? It is important for me because I have some issues about usage percantage of my CPU. For understand that I made some tests by using google micro benchmark library. I made some resize operations and measure their time. I expected that when I retrieve an Umat from Mat and made operations on it, it will take longer time than a normal UMat which created by using constructer or near time. However, I got some interesting results.

You can find my code below.

```auto
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/highgui.hpp>
#include <string>
#include <iostream>
#include <fstream>
#include <chrono>
#include <benchmark/benchmark.h>

constexpr int inHeight = 1200;
constexpr int inWidth = 1920;
constexpr int outHeight = 600;
constexpr int outWidth = 960;

void resize(cv::UMat umat){
  cv::resize(umat, umat, cv::Size(outWidth, outHeight));
}

void resize(cv::Mat mat){
  cv::resize(mat, mat, cv::Size(outWidth, outHeight));
}

static void BM_ResizeUMatRetrievedFromMat(benchmark::State& state) {
  // Perform setup here
  for (auto _ : state) {
    // This code gets timed
    state.PauseTiming();
    cv::ocl::setUseOpenCL(true);
    cv::Mat mat(inWidth, inHeight, CV_8UC3, cv::Scalar(0,0,0));
    cv::UMat umat = mat.getUMat(cv::ACCESS_RW,
                                cv::USAGE_ALLOCATE_SHARED_MEMORY);
    state.ResumeTiming();
    resize(umat);
  }
}

static void BM_ResizeUMat(benchmark::State& state) {
  // Perform setup here
  for (auto _ : state) {
    // This code gets timed
    state.PauseTiming();
    cv::ocl::setUseOpenCL(true);
    cv::UMat umat(inWidth, inHeight, CV_8UC3, cv::Scalar(0,0,0),
                 cv::USAGE_ALLOCATE_SHARED_MEMORY);
    state.ResumeTiming();
    resize(umat);
  }
}

static void BM_ResizeMat(benchmark::State& state) {
  // Perform setup here
  for (auto _ : state) {
    // This code gets timed
    state.PauseTiming();
    cv::ocl::setUseOpenCL(true);
    cv::Mat mat(inWidth, inHeight, CV_8UC3, cv::Scalar(0,0,0));
    state.ResumeTiming();
    resize(mat);
  }
}

// Register the function as a benchmark
BENCHMARK(BM_ResizeUMatRetrievedFromMat);
// Register the function as a benchmark
BENCHMARK(BM_ResizeUMat);
// Register the function as a benchmark
BENCHMARK(BM_ResizeMat);

// Run the benchmark
BENCHMARK_MAIN();

```

These are my results:  
 ![image](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/a/a0fe6f27cd228d28ab6d409814d2b4c9bb9a0163.png)

You can see that from result, my expectation is wrong.

To sum up, Is there anybody who can explain why BM\_ResizeUMat function took much longer time than BM\_ResizeUMatRetrievedFromMat function and when I retrieve an UMat from Mat by using getUMat() function, what happen to Mat if I make a change on UMat ?

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [August 18, 2021, 6:29pm UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828/2 "2021-08-18T18:29:29Z")

</div>

> [@Mustafa\_Bay](#):
>
> if I make a change on UMat. Is Mat changed at the same time

not at all. Mat is cpu memory, you’e manipulating a UMat **copy** on the gpu

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [August 18, 2021, 6:31pm UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828/3 "2021-08-18T18:31:20Z")

</div>

specifically, those calls cause a copy from device to host memory, or from host memory to device memory

---

<div class="post-metadata">

**Author:** ![Mustafa\_Bay](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/mustafa_bay/32/1843_2.png) [@Mustafa\_Bay](https://forum.opencv.org/u/Mustafa_Bay)\
**Post date:** [August 20, 2021, 5:38am UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828/4 "2021-08-20T05:38:12Z")

</div>

However, when I test that, I mean that I retrieved an UMat from a Mat and made some operations on it. Before and after the operation I check Mat and I saw that this operations also applied on Mat. You can find my code below:

```auto
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/highgui.hpp>
#include <string>
#include <iostream>
#include <fstream>
#include <chrono>
#include <benchmark/benchmark.h>

constexpr int inHeight = 1200;
constexpr int inWidth = 1920;

void copyTo(const cv::UMat &source, cv::UMat &target){
  cv::Rect roi(100,100,100,100);
  source(roi).copyTo(target(roi));
}

int main(){
  cv::UMat img(inWidth, inHeight, CV_8UC3, cv::Scalar(255,255,255),
               cv::USAGE_ALLOCATE_SHARED_MEMORY);
  cv::Mat sceneMat(inWidth, inHeight, CV_8UC3, cv::Scalar(0,0,0));
  cv::UMat sceneUMat = sceneMat.getUMat(cv::ACCESS_RW,
                                        cv::USAGE_ALLOCATE_SHARED_MEMORY);
  cv::imshow("sceneBefore", sceneMat);
  copyTo(img, sceneUMat);
  cv::imshow("img", img);
  cv::imshow("scene", sceneMat);
  cv::waitKey(20000);
}

```

How can it possible?

---

<div class="post-metadata">

**Author:** ![imagine](https://avatars.discourse-cdn.com/v4/letter/i/c89c15/32.png) [@imagine](https://forum.opencv.org/u/imagine)\
**Post date:** [August 31, 2021, 12:04pm UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828/5 "2021-08-31T12:04:16Z")

</div>

It can be possible due to shared memory between host (CPU) and device (GPU). As far as I understand, this is an optional feature in OpenCL, that depends on the Hardware you use. However, you can not rely on this and (for me) it is not transparent how OpenCV uses this feature.

---

<div class="post-metadata">

**Author:** ![kallaballa](https://avatars.discourse-cdn.com/v4/letter/k/7c8e57/32.png) [@kallaballa](https://forum.opencv.org/u/kallaballa)\
**Post date:** [November 11, 2022, 9:17pm UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828/6 "2022-11-11T21:17:12Z")

</div>

Are you talking about OpenCL-SVM?

---

<div class="post-metadata">

**Author:** ![imagine](https://avatars.discourse-cdn.com/v4/letter/i/c89c15/32.png) [@imagine](https://forum.opencv.org/u/imagine)\
**Post date:** [April 24, 2023, 3:13pm UTC](https://forum.opencv.org/t/usage-of-umat-and-mat/4828/7 "2023-04-24T15:13:26Z")

</div>

Yes, this is called Shared Virtual Memory (SVM)
