\r
#include <iostream>\r
#include <cvconfig.h>\r
+#include "opencv2/core/core.hpp"\r
#include <opencv2/gpu/gpu.hpp>\r
-#include <opencv2/highgui/highgui.hpp>\r
\r
-#ifdef HAVE_CUDA\r
-#include <cuda_runtime.h>\r
-#endif\r
-\r
-using namespace std;\r
-using namespace cv;\r
+#if !defined(HAVE_CUDA) || !defined(HAVE_TBB)\r
\r
int main()\r
{\r
- bool can_run = true;\r
-\r
#if !defined(HAVE_CUDA)\r
cout << "CUDA support is required (CMake key 'WITH_CUDA' must be true).\n";\r
- can_run = false;\r
#endif\r
\r
#if !defined(HAVE_TBB)\r
cout << "TBB support is required (CMake key 'WITH_TBB' must be true).\n";\r
- can_run = false;\r
#endif\r
\r
- if (!can_run)\r
+ return 0;\r
+}\r
+\r
+#else\r
+\r
+#include <cuda.h>\r
+#include <cuda_runtime.h>\r
+#include "opencv2/core/internal.hpp" // For TBB wrappers\r
+\r
+using namespace std;\r
+using namespace cv;\r
+using namespace cv::gpu;\r
+\r
+\r
+void cuSafeCall(int code);\r
+struct Worker { void operator()(int device_id) const; };\r
+void destroy();\r
+\r
+\r
+// Each GPU is associated with its own context\r
+CUcontext contexts[2];\r
+\r
+// Auxiliary variable, stores previusly used context\r
+CUcontext prev_context;\r
+\r
+\r
+int main()\r
+{\r
+ if (getCudaEnabledDeviceCount() < 2)\r
+ {\r
+ cout << "Two or more GPUs are required\n";\r
return -1;\r
+ }\r
+\r
+ // Save the default context\r
+ cuSafeCall(cuCtxAttach(&contexts[0], 0));\r
+ cuSafeCall(cuCtxDetach(contexts[0]));\r
+\r
+ // Create new context for the second GPU\r
+ CUdevice device;\r
+ cuSafeCall(cuDeviceGet(&device, 1));\r
+ cuSafeCall(cuCtxCreate(&contexts[1], 0, device));\r
+\r
+ // Restore the first GPU context\r
+ cuSafeCall(cuCtxPopCurrent(&prev_context));\r
+\r
+ // Run \r
+ int devices[] = {0, 1};\r
+ parallel_do(devices, devices + 2, Worker());\r
+\r
+ // Destroy context of the second GPU\r
+ destroy();\r
\r
return 0;\r
-}
\ No newline at end of file
+}\r
+\r
+\r
+void Worker::operator()(int device_id) const\r
+{\r
+ cout << device_id << endl;\r
+}\r
+\r
+\r
+void cuSafeCall(int code)\r
+{\r
+ if (code != CUDA_SUCCESS) \r
+ {\r
+ cout << "CUDA driver API error: code " << code \r
+ << ", file " << __FILE__ \r
+ << ", line " << __LINE__ << endl;\r
+ destroy();\r
+ exit(-1);\r
+ }\r
+}\r
+\r
+\r
+void destroy() \r
+{\r
+ cuCtxDestroy(contexts[1]);\r
+}\r
+\r
+#endif
\ No newline at end of file