Build OpenCV with OpenCL support - c++

in CMake, I built OpenCV with OpenCL Enable ON(It automatically detected the OPENCL_INCLUDE_DIR path but the OPENCL_LIBRARY was empty, even after clicking config. for OPENCL_LIBRARY i don't see browse button either .. after generating opencv binaries then i run the below code
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>
int main()
{
if (!cv::ocl::haveOpenCL())
cout << "OpenCL is not avaiable..." << endl;
else cout << "OpenCL is AVAILABLE! :) " << endl; //this is the output
cv::ocl::setUseOpenCL(true);
cout << context.ndevices() << " GPU devices are detected." << endl;
for (int i = 0; i < context.ndevices(); i++)
{
cv::ocl::Device device = context.device(i);
cout << "name: " << device.name() << endl;
cout << "available: " << device.available() << endl;
cout << "imageSupport: " << device.imageSupport() << endl;
cout << "OpenCL_C_Version: " << device.OpenCL_C_Version() << endl;
cout << endl;
} //this works & i can see my video card name & opencl version
cv::ocl::Device(context.device(0));
}
When i make use of UMat to measure the performance, the performance with(UMat) or without(Mat) OpenCL did not make any difference.
I downloaded AMD-APP-SDK from this link and tried to build but there was no OpenCL binaries (instead i saw opengl dll files[glew32.dll & glut32.dll]. How do i build OpenCV with OpenCL by linking the OPENCL_LIBRARY?

I believe you have OpenCL, hence the result of your call to haveOpenCL and from the version request. I'm not sure the results of your performance test equate that you don't have OpenCL.
If you want to understand OpenCL, I would take a step back and figure it out first and then try to understand OpenCV with it.
Your link didn't work, did you try this. It has a link to the current AMD APP SDK (3.0) I would go through that setup and make sure you can make the OpenCL samples build/work on your system and then you should be able to troubleshoot why it isn't working in OpenCV (if it truly isn't).
As to performance, well, it depends. Every time you send data to and from the the graphics card it comes at a cost; the Transparent API was designed to make that choice for you: if sending it to the card for faster processing is worth the trip there and back... if it is not worth the trip you will actually have poorer performance. Additionally, not all of the library will run on the GPU. See some of the explanation on opencv.org.

Related

Read GPU Information from Console C++

I want to create my own Overclocking Monitor for which I need to read information like the current voltage, clockspeeds and others.
In C++ I can easily get the Information from Nvidia-smi with typing for example:
console("nvidia-smi -q -i voltage");
Which then displays me:
==============NVSMI LOG==============
Timestamp : Tue Dec 13 17:55:54 2022
Driver Version : 526.47
CUDA Version : 12.0
Attached GPUs : 1
GPU 00000000:01:00.0
Voltage
Graphics : 806.250 mV
From that I need only the voltage number, in this case "806.25".
I´ve investigated a bit into <cctype> which was something I´ve read about, but I´m not making any progress.
So how can I import only that number into my c++ Program? I´d just guess that the process will be the same for the other commands.
I don't currently have an Nvidia GPU to test this (stuck with Intel integrated graphics), so I can't import cuda.h but feel free to test this and let me know if it works or not.
#include <iostream>
#include <chrono>
#include <cuda.h>
int main() {
// Get the current timestamp
auto current_time = std::chrono::system_clock::now();
// Get the current driver version
int driver_version;
cudaDriverGetVersion(&driver_version);
// Get the current CUDA version
int cuda_version;
cudaRuntimeGetVersion(&cuda_version);
// Get the name of the attached GPU
cudaDeviceProp device_properties;
cudaGetDeviceProperties(&device_properties, 0);
std::string gpu_name = device_properties.name;
// Get the current voltage
int power_usage;
cudaDeviceGetPowerUsage(&power_usage, 0);
int voltage = power_usage / current;
// Output the overclocking data
std::cout << "Timestamp: " << current_time << std::endl;
std::cout << "Driver version: " << driver_version << std::endl;
std::cout << "CUDA version: " << cuda_version << std::endl;
std::cout << "Attached GPU: " << gpu_name << std::endl;
std::cout << "Voltage: " << voltage << std::endl;
return 0;
}
If it works then your voltage can be accessed from int voltage.

blkid on docker container

I am working on a legacy C++ project which uses functions from blkid/blkid.h to access files on the local hard disk.
Since the project is quite big and hard to compile/run, I thought it would be a good idea to run it in a container. Creating the dockerfile to create the images went fine, the problems started when actually running the legacy project in a container.
I get errors when trying to access files on the disk using "blkid_devno_to_devname" to get the device id on which to write.
Here is a sample program that reproduces my problem
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <blkid/blkid.h>
int main() {
struct stat st;
std::string path = "my_file_path";
if (stat(path.data(), &st))
{
std::cout << "cannot get file statistics for file " << path << std::endl;
}
char *device_path = blkid_devno_to_devname(st.st_dev);
if(device_path == NULL)
{
std::cout << "cannot get device path for device ID " + std::to_string(st.st_dev) << std::endl;
}
}
On a regular file on my machine the device_path is not null, but running it on a docker always returns null.
What is not clear to me is how a docker container sees the disks it writes to.
To dig in, I looked into the different macros coming with stat (https://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h), I printed them on files on a container with different type of files (symlink, file, directory).
I modified the above little program to add this:
std::cout << "mode:" << st.st_mode << std::endl;
std::cout << "S_ISREG:" << S_ISREG(st.st_mode) << std::endl;
std::cout << "S_ISDIR:" << S_ISDIR(st.st_mode) << std::endl;
std::cout << "S_ISCHR:" << S_ISCHR(st.st_mode) << std::endl;
std::cout << "S_ISBLK:" << S_ISBLK(st.st_mode) << std::endl;
std::cout << "S_ISFIFO:" << S_ISFIFO(st.st_mode) << std::endl;
std::cout << "S_ISLNK:" << S_ISLNK(st.st_mode) << std::endl;
std::cout << "S_ISSOCK:" << S_ISSOCK(st.st_mode) << std::endl;
I thought there would be a difference depending on the type of layer the docker writes to, but I don't see any.
Be it on a volume, mount, or even on container layer (I mean on files neither on a volume nor mount).
On a mount, I would have expected the device id to be correct since as I understand it the mount is giving the container access to a physical drive (at least in my case - may not be true in general).
So why is blkid_devno_to_devname not returning anything on a docker container?
What am I not understanding properly?
P.S. for the record, blkid or /etc/fstab don't return anything on a container either.
Notes to the readers about my system:
working on a VM on windows (Oracle VM) with ubuntu 18 installed.
docker version: 19.03.6
Driver: overlay2

Only display output for a given time

I just started learning c++ and am using codeblocks. I'm just wondering if there was a way to set my output to display for only a certain amount of time.
For example, I have the code
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
cout << "You need to learn C++!" << endl;
return 0;
}
Now when I hit build and run, it displays the code and says "Press any key to continue". I want to know if there is a way I can set a timer for that display to go away instead of pressing a key.
Thank you!
Closing the window is not the responsibility of the program to do, it's the user responsibility. Anyway, you could stop the program for the time you want using for stopping the program and for measuring the time you want it to stop. If you double click the .exe file generated after compilation it will automatically close after execution, otherwise you will have to close the window by yourself.
More information here, about the std::thread method: http://www.cplusplus.com/reference/thread/this_thread/sleep_for/
And here about the chrono library:https://en.cppreference.com/w/cpp/chrono/duration
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main(){
cout << "Hello world!" << endl;
cout << "You need to learn C++!" << endl;
this_thread::sleep_for (chrono::seconds(3));
cout<<"Program finished!";
return 0;
}
You could also use chrono::miliseconds or chrono::minutes or chrono::hours
There may also be a platform dependent library for closing the window . You could have one for windows, another for linux, but anyway you shouldn't be worrying about that as a beginner.

Making it beep in c++

I've recently picked up C++ and I am using a Mac with Xcode to start learning.
One of the problems I am having is making it BEEP!!
I know there is a lot of StackOverflow questions for this and the most popular seems to be std::cout << "\007"
#include < iostream >
int main() {
std::cout << "\007";
return 0;
}
Is there something I am missing?
Try cout << '\a' << flush; instead. You can make a system call like system("say beep"); but this is very OS dependent and will not work on all machines.

How do I get PCRE to work correctly with Code::blocks?

I am facing some problems while working with PCRE in Code::blocks. I have downloaded PCRE from here. And did all the steps mentioned here. However I am getting a pcr3.dll missing error during execution.
The program can't start because pcre3.dll is missing from your
computer. Try reinstalling the program to fix this problem.
My code:
#include <iostream>
#include <regex.h>
using namespace std;
int main(){
regex_t reg;
string pattern = "[^tpr]{2,}";
string str = "topcoder";
regmatch_t matches[1];
regcomp(&reg,pattern.c_str(),REG_EXTENDED|REG_ICASE);
if (regexec(&reg,str.c_str(),1,matches,0)==0) {
cout << "Match " ;
cout << str.substr(matches[0].rm_so,matches[0].rm_eo-matches[0].rm_so) ;
cout << " found starting at: " ;
cout << matches[0].rm_so ;
cout << " and ending at " ;
cout << matches[0].rm_eo ;
cout << endl;
} else {
cout << "Match not found.";
cout << endl;
}
regfree(&reg);
return 0;
}
I am not sure how to fix this, any ideas?
PS: Above mentioned code is taken from this tutorial.
Copy the DLL to the same directory as the executable that you are running. If that works, you didn't install the DLL correctly or at least not in a way that it can be found by the programs in general. Check out the documentation of the DLL Search Order to get an idea how else you can make the system find the DLL. In particular, you need to know that there is a linker and a loader (aka dynamic/runtime linker/loader), but only one of them is configured inside CodeBlocks!