From f58b1f88d9e1b1d79cc18b33d96ff96aa26083e9 Mon Sep 17 00:00:00 2001 From: Canming Huang Date: Wed, 6 May 2020 10:56:20 -0400 Subject: [PATCH] Added Ocl Context and Ocl Program. --- Emgu.CV.Extern/core/ocl_c.cpp | 136 ++++++++----- Emgu.CV.Extern/core/ocl_c.h | 23 +++ Emgu.CV.Test/AutoTestOpenCL.cs | 258 ++++++++++++++----------- Emgu.CV/Ocl/Context.cs | 101 ++++++++++ Emgu.CV/Ocl/Device.cs | 338 ++++++++++++++++----------------- Emgu.CV/Ocl/Program.cs | 79 ++++++++ 6 files changed, 610 insertions(+), 325 deletions(-) create mode 100644 Emgu.CV/Ocl/Context.cs create mode 100644 Emgu.CV/Ocl/Program.cs diff --git a/Emgu.CV.Extern/core/ocl_c.cpp b/Emgu.CV.Extern/core/ocl_c.cpp index 4fe4aa1fe..799a4e38b 100644 --- a/Emgu.CV.Extern/core/ocl_c.cpp +++ b/Emgu.CV.Extern/core/ocl_c.cpp @@ -9,25 +9,25 @@ void oclGetPlatformsInfo(std::vector* oclPlatforms) { - cv::ocl::getPlatfomsInfo(*oclPlatforms); + cv::ocl::getPlatfomsInfo(*oclPlatforms); } bool cveHaveOpenCL() { - return cv::ocl::haveOpenCL(); + return cv::ocl::haveOpenCL(); } bool cveUseOpenCL() { - return cv::ocl::useOpenCL(); + return cv::ocl::useOpenCL(); } void cveSetUseOpenCL(bool flag) { - return cv::ocl::setUseOpenCL(flag); + return cv::ocl::setUseOpenCL(flag); } void cveOclFinish() { - cv::ocl::finish(); + cv::ocl::finish(); } //---------------------------------------------------------------------------- @@ -38,31 +38,31 @@ void cveOclFinish() void oclPlatformInfoGetVersion(cv::ocl::PlatformInfo* oclPlatformInfo, cv::String* platformVersion) { - *platformVersion = oclPlatformInfo->version(); + *platformVersion = oclPlatformInfo->version(); } void oclPlatformInfoGetName(cv::ocl::PlatformInfo* oclPlatformInfo, cv::String* platformName) { - *platformName = oclPlatformInfo->name(); + *platformName = oclPlatformInfo->name(); } void oclPlatformInfoGetVender(cv::ocl::PlatformInfo* oclPlatformInfo, cv::String* platformVender) { - *platformVender = oclPlatformInfo->vendor(); + *platformVender = oclPlatformInfo->vendor(); } int oclPlatformInfoDeviceNumber(cv::ocl::PlatformInfo* platformInfo) { - return platformInfo->deviceNumber(); + return platformInfo->deviceNumber(); } void oclPlatformInfoGetDevice(cv::ocl::PlatformInfo* platformInfo, cv::ocl::Device* device, int d) { - platformInfo->getDevice(*device, d); + platformInfo->getDevice(*device, d); } void oclPlatformInfoRelease(cv::ocl::PlatformInfo** platformInfo) { - delete *platformInfo; + delete* platformInfo; } //---------------------------------------------------------------------------- @@ -72,27 +72,76 @@ void oclPlatformInfoRelease(cv::ocl::PlatformInfo** platformInfo) //---------------------------------------------------------------------------- cv::ocl::Device* oclDeviceCreate() { - return new cv::ocl::Device(); + return new cv::ocl::Device(); } void oclDeviceSet(cv::ocl::Device* device, void* p) { - device->set(p); + device->set(p); } const cv::ocl::Device* oclDeviceGetDefault() { - return &cv::ocl::Device::getDefault(); + return &cv::ocl::Device::getDefault(); } void oclDeviceRelease(cv::ocl::Device** device) { - delete *device; - *device = 0; + delete* device; + *device = 0; } void* oclDeviceGetPtr(cv::ocl::Device* device) { - return device->ptr(); + return device->ptr(); } +//---------------------------------------------------------------------------- +// +// OclContext +// +//---------------------------------------------------------------------------- +cv::ocl::Context* oclContextCreate() +{ + return new cv::ocl::Context(); +} +const cv::ocl::Context* oclContextGetDefault(bool initialize) +{ + return &cv::ocl::Context::getDefault(initialize); +} +void oclContextRelease(cv::ocl::Context** context) +{ + delete* context; + *context = 0; +} +const cv::ocl::Program* oclContextGetProg( + cv::ocl::Context* context, + cv::ocl::ProgramSource* prog, + cv::String* buildopt, + cv::String* errmsg) +{ + cv::String tmp; + errmsg = errmsg ? errmsg : &tmp; + cv::ocl::Program program = context->getProg(*prog, *buildopt, *errmsg); + cv::ocl::Program* p = new cv::ocl::Program(program); + return p; +} + +//---------------------------------------------------------------------------- +// +// OclProgram +// +//---------------------------------------------------------------------------- +cv::ocl::Program* oclProgramCreate() +{ + return new cv::ocl::Program(); +} +void oclProgramRelease(cv::ocl::Program** program) +{ + delete* program; + *program = 0; +} +void oclProgramGetBinary(cv::ocl::Program* program, std::vector* binary) +{ + program->getBinary(*binary); +} //---------------------------------------------------------------------------- // @@ -101,16 +150,16 @@ void* oclDeviceGetPtr(cv::ocl::Device* device) //---------------------------------------------------------------------------- cv::ocl::ProgramSource* oclProgramSourceCreate(cv::String* source) { - return new cv::ocl::ProgramSource(*source); + return new cv::ocl::ProgramSource(*source); } void oclProgramSourceRelease(cv::ocl::ProgramSource** programSource) { - delete *programSource; - *programSource = 0; + delete* programSource; + *programSource = 0; } const cv::String* oclProgramSourceGetSource(cv::ocl::ProgramSource* programSource) { - return &programSource->source(); + return &programSource->source(); } //---------------------------------------------------------------------------- @@ -120,36 +169,37 @@ const cv::String* oclProgramSourceGetSource(cv::ocl::ProgramSource* programSourc //---------------------------------------------------------------------------- cv::ocl::Kernel* oclKernelCreateDefault() { - return new cv::ocl::Kernel(); + return new cv::ocl::Kernel(); } bool oclKernelCreate(cv::ocl::Kernel* kernel, cv::String* kname, cv::ocl::ProgramSource* source, cv::String* buildOpts, cv::String* errmsg) { - return kernel->create(kname->c_str(), *source, *buildOpts, errmsg); + + return kernel->create(kname->c_str(), *source, *buildOpts, errmsg); } void oclKernelRelease(cv::ocl::Kernel** kernel) { - delete *kernel; - *kernel = 0; + delete* kernel; + *kernel = 0; } int oclKernelSetImage2D(cv::ocl::Kernel* kernel, int i, cv::ocl::Image2D* image2D) { - return kernel->set(i, *image2D); + return kernel->set(i, *image2D); } int oclKernelSetUMat(cv::ocl::Kernel* kernel, int i, cv::UMat* umat) { - return kernel->set(i, *umat); + return kernel->set(i, *umat); } int oclKernelSet(cv::ocl::Kernel* kernel, int i, void* value, int size) { - return kernel->set(i, value, static_cast(size)); + return kernel->set(i, value, static_cast(size)); } int oclKernelSetKernelArg(cv::ocl::Kernel* kernel, int i, cv::ocl::KernelArg* kernelArg) { - return kernel->set(i, *kernelArg); + return kernel->set(i, *kernelArg); } bool oclKernelRun(cv::ocl::Kernel* kernel, int dims, size_t* globalsize, size_t* localsize, bool sync, cv::ocl::Queue* q) { - return kernel->run(dims, globalsize, localsize, sync, q ? *q : cv::ocl::Queue()); + return kernel->run(dims, globalsize, localsize, sync, q ? *q : cv::ocl::Queue()); } //---------------------------------------------------------------------------- // @@ -158,13 +208,13 @@ bool oclKernelRun(cv::ocl::Kernel* kernel, int dims, size_t* globalsize, size_t* //---------------------------------------------------------------------------- cv::ocl::Image2D* oclImage2DFromUMat(cv::UMat* src, bool norm, bool alias) { - cv::ocl::Image2D* img2d = new cv::ocl::Image2D(*src, norm, alias); - return img2d; + cv::ocl::Image2D* img2d = new cv::ocl::Image2D(*src, norm, alias); + return img2d; } void oclImage2DRelease(cv::ocl::Image2D** image2D) { - delete *image2D; - *image2D = 0; + delete* image2D; + *image2D = 0; } //---------------------------------------------------------------------------- @@ -174,12 +224,12 @@ void oclImage2DRelease(cv::ocl::Image2D** image2D) //---------------------------------------------------------------------------- cv::ocl::KernelArg* oclKernelArgCreate(int flags, cv::UMat* m, int wscale, int iwscale, const void* obj, size_t sz) { - return new cv::ocl::KernelArg(flags, m, wscale, iwscale, obj, sz); + return new cv::ocl::KernelArg(flags, m, wscale, iwscale, obj, sz); } void oclKernelArgRelease(cv::ocl::KernelArg** k) { - delete *k; - *k = 0; + delete* k; + *k = 0; } //---------------------------------------------------------------------------- @@ -189,21 +239,21 @@ void oclKernelArgRelease(cv::ocl::KernelArg** k) //---------------------------------------------------------------------------- cv::ocl::Queue* oclQueueCreate() { - return new cv::ocl::Queue(); + return new cv::ocl::Queue(); } void oclQueueFinish(cv::ocl::Queue* queue) { - queue->finish(); + queue->finish(); } void oclQueueRelease(cv::ocl::Queue** queue) { - delete *queue; - *queue = 0; + delete* queue; + *queue = 0; } void oclTypeToString(int type, cv::String* str) { - const char* s = cv::ocl::typeToStr(type); - *str = s; + const char* s = cv::ocl::typeToStr(type); + *str = s; } \ No newline at end of file diff --git a/Emgu.CV.Extern/core/ocl_c.h b/Emgu.CV.Extern/core/ocl_c.h index bcdc935b8..e0d3403a2 100644 --- a/Emgu.CV.Extern/core/ocl_c.h +++ b/Emgu.CV.Extern/core/ocl_c.h @@ -58,6 +58,29 @@ CVAPI(const cv::ocl::Device*) oclDeviceGetDefault(); CVAPI(void) oclDeviceRelease(cv::ocl::Device** device); CVAPI(void*) oclDeviceGetPtr(cv::ocl::Device* device); +//---------------------------------------------------------------------------- +// +// OclContext +// +//---------------------------------------------------------------------------- +CVAPI(cv::ocl::Context*) oclContextCreate(); +CVAPI(const cv::ocl::Context*) oclContextGetDefault(bool initialize); +CVAPI(void) oclContextRelease(cv::ocl::Context** context); +CVAPI(const cv::ocl::Program*) oclContextGetProg( + cv::ocl::Context* context, + cv::ocl::ProgramSource* prog, + cv::String* buildopt, + cv::String* errmsg); + +//---------------------------------------------------------------------------- +// +// OclProgram +// +//---------------------------------------------------------------------------- +CVAPI(cv::ocl::Program*) oclProgramCreate(); +CVAPI(void) oclProgramRelease(cv::ocl::Program** program); +CVAPI(void) oclProgramGetBinary(cv::ocl::Program* program, std::vector* binary); + //---------------------------------------------------------------------------- // // OclProgramSource diff --git a/Emgu.CV.Test/AutoTestOpenCL.cs b/Emgu.CV.Test/AutoTestOpenCL.cs index 39c8c891f..602de7a06 100644 --- a/Emgu.CV.Test/AutoTestOpenCL.cs +++ b/Emgu.CV.Test/AutoTestOpenCL.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; +using System.IO; using System.Runtime.InteropServices; using System.Text; using Emgu.CV.CvEnum; @@ -13,6 +14,7 @@ using Emgu.CV.OCR; using Emgu.CV.Structure; using Emgu.CV.Util; using Emgu.CV.Features2D; +using Emgu.CV.Ocl; using Emgu.CV.XFeatures2D; @@ -30,35 +32,21 @@ using NUnit.Framework; namespace Emgu.CV.Test { - [TestFixture] - public class AutoTestOpenCL - { - [Test] - public void TestOclInfo() - { - Trace.WriteLine(CvInvoke.OclGetPlatformsSummary()); - } - - [Test] - public void TestOclKernel() - { - if (CvInvoke.HaveOpenCL && CvInvoke.UseOpenCL) - { - - Ocl.Device defaultDevice = Ocl.Device.Default; - - Mat img = EmguAssert.LoadMat("lena.jpg"); - Mat imgGray = new Mat(); - CvInvoke.CvtColor(img, imgGray, ColorConversion.Bgr2Gray); - Mat imgFloat = new Mat(); - imgGray.ConvertTo(imgFloat, DepthType.Cv32F, 1.0/255); - UMat umat = imgFloat.GetUMat(AccessType.Read, UMat.Usage.AllocateDeviceMemory); - UMat umatDst = new UMat(); - umatDst.Create(umat.Rows, umat.Cols, DepthType.Cv32F, umat.NumberOfChannels, UMat.Usage.AllocateDeviceMemory); - - String buildOpts = String.Format("-D dstT={0}", Ocl.OclInvoke.TypeToString(umat.Depth)); - - String sourceStr = @" + [TestFixture] + public class AutoTestOpenCL + { + [Test] + public void TestOclInfo() + { + Trace.WriteLine(CvInvoke.OclGetPlatformsSummary()); + } + + [Test] + public void TestOclProgramCompile() + { + if (CvInvoke.HaveOpenCL && CvInvoke.UseOpenCL) + { + String sourceStr = @" __kernel void magnitude_filter_8u( __global const uchar* src, int src_step, int src_offset, __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols, @@ -82,94 +70,138 @@ __kernel void magnitude_filter_8u( } } }"; + Ocl.Context context = Context.Default; + String buildOpts = String.Format("-D dstT={0}", Ocl.OclInvoke.TypeToString(DepthType.Cv8U)); + using (Ocl.ProgramSource ps = new Ocl.ProgramSource(sourceStr)) + using (CvString errorMsg = new CvString()) + using (Program p = context.GetProgram(ps, buildOpts, errorMsg)) + { + byte[] binary = p.Binary; + } + } + } - using (CvString errorMsg = new CvString()) - using (Ocl.ProgramSource ps = new Ocl.ProgramSource(sourceStr)) - using (Ocl.Kernel kernel = new Ocl.Kernel()) - using (Ocl.Image2D image2d = new Ocl.Image2D(umat)) - using (Ocl.KernelArg ka = new Ocl.KernelArg(Ocl.KernelArg.Flags.ReadWrite, umatDst)) + [Test] + public void TestOclKernel() + { + if (CvInvoke.HaveOpenCL && CvInvoke.UseOpenCL) { - float shiftX = 100.5f; - float shiftY = -50.0f; - - bool success = kernel.Create("myshift", ps, buildOpts, errorMsg); - EmguAssert.IsTrue(success, errorMsg.ToString()); - int idx = 0; - idx = kernel.Set(idx, image2d); - idx = kernel.Set(idx, ref shiftX); - idx = kernel.Set(idx, ref shiftY); - idx = kernel.Set(idx, ka); - IntPtr[] globalThreads = new IntPtr[] {new IntPtr(umat.Cols), new IntPtr(umat.Rows), new IntPtr(1) }; - success = kernel.Run(globalThreads, null, true); - EmguAssert.IsTrue(success, "Failed to run the kernel"); - using (Mat matDst = umatDst.GetMat(AccessType.Read)) - using (Mat saveMat = new Mat()) - { - matDst.ConvertTo(saveMat, DepthType.Cv8U, 255.0); - saveMat.Save("tmp.jpg"); - } + Ocl.Device defaultDevice = Ocl.Device.Default; + + Mat img = EmguAssert.LoadMat("lena.jpg"); + Mat imgGray = new Mat(); + CvInvoke.CvtColor(img, imgGray, ColorConversion.Bgr2Gray); + Mat imgFloat = new Mat(); + imgGray.ConvertTo(imgFloat, DepthType.Cv32F, 1.0 / 255); + UMat umat = imgFloat.GetUMat(AccessType.Read, UMat.Usage.AllocateDeviceMemory); + UMat umatDst = new UMat(); + umatDst.Create(umat.Rows, umat.Cols, DepthType.Cv32F, umat.NumberOfChannels, + UMat.Usage.AllocateDeviceMemory); + + String buildOpts = String.Format("-D dstT={0}", Ocl.OclInvoke.TypeToString(umat.Depth)); + + String sourceStr = @" +__constant sampler_t samplerLN = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR; +__kernel void myshift(const image2d_t src, float shift_x, float shift_y, __global uchar* dst, int dst_step, int dst_offset, int dst_rows, int dst_cols) +{ + int x = get_global_id(0); + int y = get_global_id(1); + if (x >= dst_cols) return; + int dst_index = mad24(y, dst_step, mad24(x, (int)sizeof(dstT), dst_offset)); + __global dstT *dstf = (__global dstT *)(dst + dst_index); + float2 coord = (float2)((float)x+0.5f+shift_x, (float)y+0.5f+shift_y); + dstf[0] = (dstT)read_imagef(src, samplerLN, coord).x; +}"; + + + using (CvString errorMsg = new CvString()) + using (Ocl.ProgramSource ps = new Ocl.ProgramSource(sourceStr)) + using (Ocl.Kernel kernel = new Ocl.Kernel()) + using (Ocl.Image2D image2d = new Ocl.Image2D(umat)) + using (Ocl.KernelArg ka = new Ocl.KernelArg(Ocl.KernelArg.Flags.ReadWrite, umatDst)) + { + float shiftX = 100.5f; + float shiftY = -50.0f; + + bool success = kernel.Create("myshift", ps, buildOpts, errorMsg); + EmguAssert.IsTrue(success, errorMsg.ToString()); + int idx = 0; + idx = kernel.Set(idx, image2d); + idx = kernel.Set(idx, ref shiftX); + idx = kernel.Set(idx, ref shiftY); + idx = kernel.Set(idx, ka); + IntPtr[] globalThreads = new IntPtr[] { new IntPtr(umat.Cols), new IntPtr(umat.Rows), new IntPtr(1) }; + success = kernel.Run(globalThreads, null, true); + EmguAssert.IsTrue(success, "Failed to run the kernel"); + using (Mat matDst = umatDst.GetMat(AccessType.Read)) + using (Mat saveMat = new Mat()) + { + matDst.ConvertTo(saveMat, DepthType.Cv8U, 255.0); + FileInfo fi = new FileInfo("tmp.jpg"); + saveMat.Save(fi.FullName); + } + } } - } - } - - [Test] - public void TestOclChangeDefaultDevice() - { - if (CvInvoke.HaveOpenCL && CvInvoke.UseOpenCL) - { - using (VectorOfOclPlatformInfo oclPlatformInfos = Ocl.OclInvoke.GetPlatformsInfo()) + } + + [Test] + public void TestOclChangeDefaultDevice() + { + if (CvInvoke.HaveOpenCL && CvInvoke.UseOpenCL) { - if (oclPlatformInfos.Size > 0) - { - for (int i = 0; i < oclPlatformInfos.Size; i++) - { - Ocl.PlatformInfo platformInfo = oclPlatformInfos[i]; - - for (int j = 0; j < platformInfo.DeviceNumber; j++) - { - Ocl.Device device = platformInfo.GetDevice(j); - - Trace.WriteLine(String.Format("{0}Setting device to {1}", Environment.NewLine, device.Name)); - //OclDevice d = new OclDevice(); - //d.Set(device.NativeDevicePointer); - - - Ocl.Device defaultDevice = Ocl.Device.Default; - defaultDevice.Set(device.NativeDevicePointer); - - Trace.WriteLine(String.Format("Current OpenCL default device: {0}", defaultDevice.Name)); - - UMat m = new UMat(2048, 2048, DepthType.Cv8U, 3); - m.SetTo(new MCvScalar(100, 100, 100)); - CvInvoke.GaussianBlur(m, m, new Size(3, 3), 3); - - Stopwatch watch = Stopwatch.StartNew(); - m.SetTo(new MCvScalar(100, 100, 100)); - CvInvoke.GaussianBlur(m, m, new Size(3, 3), 3); - watch.Stop(); - Trace.WriteLine(String.Format("Device '{0}' time: {1} milliseconds", defaultDevice.Name, - watch.ElapsedMilliseconds)); - CvInvoke.OclFinish(); - } - } - } - - Trace.WriteLine(Environment.NewLine + "Disable OpenCL"); - CvInvoke.UseOpenCL = false; - UMat m2 = new UMat(2048, 2048, DepthType.Cv8U, 3); - m2.SetTo(new MCvScalar(100, 100, 100)); - CvInvoke.GaussianBlur(m2, m2, new Size(3, 3), 3); - - Stopwatch watch2 = Stopwatch.StartNew(); - m2.SetTo(new MCvScalar(100, 100, 100)); - CvInvoke.GaussianBlur(m2, m2, new Size(3, 3), 3); - watch2.Stop(); - Trace.WriteLine(String.Format("CPU time: {0} milliseconds", watch2.ElapsedMilliseconds)); - CvInvoke.UseOpenCL = true; + using (VectorOfOclPlatformInfo oclPlatformInfos = Ocl.OclInvoke.GetPlatformsInfo()) + { + if (oclPlatformInfos.Size > 0) + { + for (int i = 0; i < oclPlatformInfos.Size; i++) + { + Ocl.PlatformInfo platformInfo = oclPlatformInfos[i]; + + for (int j = 0; j < platformInfo.DeviceNumber; j++) + { + Ocl.Device device = platformInfo.GetDevice(j); + + Trace.WriteLine(String.Format("{0}Setting device to {1}", Environment.NewLine, device.Name)); + //OclDevice d = new OclDevice(); + //d.Set(device.NativeDevicePointer); + + + Ocl.Device defaultDevice = Ocl.Device.Default; + defaultDevice.Set(device.NativeDevicePointer); + + Trace.WriteLine(String.Format("Current OpenCL default device: {0}", defaultDevice.Name)); + + UMat m = new UMat(2048, 2048, DepthType.Cv8U, 3); + m.SetTo(new MCvScalar(100, 100, 100)); + CvInvoke.GaussianBlur(m, m, new Size(3, 3), 3); + + Stopwatch watch = Stopwatch.StartNew(); + m.SetTo(new MCvScalar(100, 100, 100)); + CvInvoke.GaussianBlur(m, m, new Size(3, 3), 3); + watch.Stop(); + Trace.WriteLine(String.Format("Device '{0}' time: {1} milliseconds", defaultDevice.Name, + watch.ElapsedMilliseconds)); + CvInvoke.OclFinish(); + } + } + } + + Trace.WriteLine(Environment.NewLine + "Disable OpenCL"); + CvInvoke.UseOpenCL = false; + UMat m2 = new UMat(2048, 2048, DepthType.Cv8U, 3); + m2.SetTo(new MCvScalar(100, 100, 100)); + CvInvoke.GaussianBlur(m2, m2, new Size(3, 3), 3); + + Stopwatch watch2 = Stopwatch.StartNew(); + m2.SetTo(new MCvScalar(100, 100, 100)); + CvInvoke.GaussianBlur(m2, m2, new Size(3, 3), 3); + watch2.Stop(); + Trace.WriteLine(String.Format("CPU time: {0} milliseconds", watch2.ElapsedMilliseconds)); + CvInvoke.UseOpenCL = true; + } } - } - } + } - - } + + } } diff --git a/Emgu.CV/Ocl/Context.cs b/Emgu.CV/Ocl/Context.cs new file mode 100644 index 000000000..a33e4c948 --- /dev/null +++ b/Emgu.CV/Ocl/Context.cs @@ -0,0 +1,101 @@ +//---------------------------------------------------------------------------- +// Copyright (C) 2004-2020 by EMGU Corporation. All rights reserved. +//---------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Text; +using Emgu.CV; +using Emgu.Util; +using System.Runtime.InteropServices; + +namespace Emgu.CV.Ocl +{ + /// + /// This class contains ocl context information + /// + public partial class Context : UnmanagedObject + { + private static Context _defaultContext = new Context(OclInvoke.oclContextGetDefault(), false); + + private bool _needDispose; + + /// + /// Create a empty OclContext object + /// + public Context() + : this(OclInvoke.oclContextCreate(), true) + { + } + + /// + /// Get the default OclContext. Do not dispose this context. + /// + public static Context Default + { + get + { + return _defaultContext; + } + } + + internal Context(IntPtr ptr, bool needDispose) + { + _ptr = ptr; + _needDispose = needDispose; + } + + /// + /// Release all the unmanaged memory associated with this OclContext + /// + protected override void DisposeObject() + { + if (_needDispose) + { + if (_ptr != IntPtr.Zero) + { + OclInvoke.oclContextRelease(ref _ptr); + } + } + } + + /// + /// Compile the program + /// + /// The program source + /// The build option + /// Error message + /// The compiled program + public Program GetProgram(ProgramSource prog, String buildOpt, CvString errMsg) + { + using (CvString csBuildOpt = new CvString(buildOpt)) + { + return new Program(OclInvoke.oclContextGetProg(_ptr, prog, csBuildOpt, errMsg)); + } + } + + } + + /// + /// Class that contains ocl functions + /// + public static partial class OclInvoke + { + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern IntPtr oclContextCreate(); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern IntPtr oclContextGetDefault(); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern void oclContextRelease(ref IntPtr oclContext); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern IntPtr oclContextGetProg( + IntPtr context, + IntPtr prog, + IntPtr buildopt, + IntPtr errmsg); + + } +} diff --git a/Emgu.CV/Ocl/Device.cs b/Emgu.CV/Ocl/Device.cs index 35e534006..5b0808b13 100644 --- a/Emgu.CV/Ocl/Device.cs +++ b/Emgu.CV/Ocl/Device.cs @@ -11,175 +11,175 @@ using System.Runtime.InteropServices; namespace Emgu.CV.Ocl { - /// - /// This class contains ocl runtime information - /// - public partial class Device : UnmanagedObject - { - private static Device _defaultDevice = new Device(OclInvoke.oclDeviceGetDefault(), false); - - private bool _needDispose; - - /// - /// Create a empty OclDevice object - /// - public Device() - : this(OclInvoke.oclDeviceCreate(), true) - { - } - - /// - /// Get the default OclDevice. Do not dispose this device. - /// - public static Device Default - { - get - { - return _defaultDevice; - } - } - - internal Device(IntPtr ptr, bool needDispose) - { - _ptr = ptr; - _needDispose = needDispose; - } - - /// - /// Release all the unmanaged memory associated with this OclInfo - /// - protected override void DisposeObject() - { - if (_needDispose) - { - if (_ptr != IntPtr.Zero) + /// + /// This class contains ocl device information + /// + public partial class Device : UnmanagedObject + { + private static Device _defaultDevice = new Device(OclInvoke.oclDeviceGetDefault(), false); + + private bool _needDispose; + + /// + /// Create a empty OclDevice object + /// + public Device() + : this(OclInvoke.oclDeviceCreate(), true) + { + } + + /// + /// Get the default OclDevice. Do not dispose this device. + /// + public static Device Default + { + get { - OclInvoke.oclDeviceRelease(ref _ptr); + return _defaultDevice; } - } - } - - /// - /// Get the native device pointer - /// - public IntPtr NativeDevicePointer - { - get { return OclInvoke.oclDeviceGetPtr(_ptr); } - } - - /// - /// Set the native device pointer - /// - /// - public void Set(IntPtr nativeDevicePointer) - { - OclInvoke.oclDeviceSet(_ptr, nativeDevicePointer); - } - - /// - /// Get the string representation of this oclDevice - /// - /// A string representation of this oclDevice - public override string ToString() - { - return String.Format("{0} {1}.{2} ({3}):Version - {4}; Global memory - {5}; Local memory - {6}; Max image size - {7}x{8}; DoubleFpConfig: {9}", Name, DeviceVersionMajor, DeviceVersionMinor, Type, Version, GlobalMemSize, LocalMemSize, Image2DMaxWidth, Image2DMaxHeight, DoubleFPConfig); - } - } - - - /// - /// Ocl Device Type - /// - public enum DeviceType - { - /// - /// Default - /// - Default = (1 << 0), - /// - /// Cpu - /// - Cpu = (1 << 1), - /// - /// Gpu - /// - Gpu = (1 << 2), - /// - /// Accerlerator - /// - Accelerator = (1 << 3), - /// - /// DGpu - /// - DGpu = Gpu | (1 << 16), - /// - /// IGpu - /// - IGpu = Gpu | (1 << 17), - /// - /// All - /// - All = -1 //0xFFFFFFFF - } - - /// - /// Floating point configuration - /// - [Flags] - public enum FpConfig - { - /// - /// Denorm - /// - Denorm = (1 << 0), - /// - /// inf, nan - /// - InfNan = (1 << 1), - /// - /// round to nearest - /// - RoundToNearest = (1 << 2), - /// - /// round to zero - /// - RoundToZero = (1 << 3), - /// - /// round to infinite - /// - RoundToInf = (1 << 4), - /// - /// FMA - /// - Fma = (1 << 5), - /// - /// soft float - /// - SoftFloat = (1 << 6), - /// - /// Correctly rounded divide sqrt - /// - CorrectlyRoundedDivideSqrt = (1 << 7) - } - - /// - /// Class that contains ocl functions - /// - public static partial class OclInvoke - { - [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] - internal static extern IntPtr oclDeviceCreate(); - - [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] - internal static extern void oclDeviceSet(IntPtr device, IntPtr p); - - [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] - internal static extern IntPtr oclDeviceGetDefault(); - - [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] - internal static extern void oclDeviceRelease(ref IntPtr oclDevice); - - [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] - internal static extern IntPtr oclDeviceGetPtr(IntPtr device); - } + } + + internal Device(IntPtr ptr, bool needDispose) + { + _ptr = ptr; + _needDispose = needDispose; + } + + /// + /// Release all the unmanaged memory associated with this OclDevice + /// + protected override void DisposeObject() + { + if (_needDispose) + { + if (_ptr != IntPtr.Zero) + { + OclInvoke.oclDeviceRelease(ref _ptr); + } + } + } + + /// + /// Get the native device pointer + /// + public IntPtr NativeDevicePointer + { + get { return OclInvoke.oclDeviceGetPtr(_ptr); } + } + + /// + /// Set the native device pointer + /// + /// + public void Set(IntPtr nativeDevicePointer) + { + OclInvoke.oclDeviceSet(_ptr, nativeDevicePointer); + } + + /// + /// Get the string representation of this oclDevice + /// + /// A string representation of this oclDevice + public override string ToString() + { + return String.Format("{0} {1}.{2} ({3}):Version - {4}; Global memory - {5}; Local memory - {6}; Max image size - {7}x{8}; DoubleFpConfig: {9}", Name, DeviceVersionMajor, DeviceVersionMinor, Type, Version, GlobalMemSize, LocalMemSize, Image2DMaxWidth, Image2DMaxHeight, DoubleFPConfig); + } + } + + + /// + /// Ocl Device Type + /// + public enum DeviceType + { + /// + /// Default + /// + Default = (1 << 0), + /// + /// Cpu + /// + Cpu = (1 << 1), + /// + /// Gpu + /// + Gpu = (1 << 2), + /// + /// Accerlerator + /// + Accelerator = (1 << 3), + /// + /// DGpu + /// + DGpu = Gpu | (1 << 16), + /// + /// IGpu + /// + IGpu = Gpu | (1 << 17), + /// + /// All + /// + All = -1 //0xFFFFFFFF + } + + /// + /// Floating point configuration + /// + [Flags] + public enum FpConfig + { + /// + /// Denorm + /// + Denorm = (1 << 0), + /// + /// inf, nan + /// + InfNan = (1 << 1), + /// + /// round to nearest + /// + RoundToNearest = (1 << 2), + /// + /// round to zero + /// + RoundToZero = (1 << 3), + /// + /// round to infinite + /// + RoundToInf = (1 << 4), + /// + /// FMA + /// + Fma = (1 << 5), + /// + /// soft float + /// + SoftFloat = (1 << 6), + /// + /// Correctly rounded divide sqrt + /// + CorrectlyRoundedDivideSqrt = (1 << 7) + } + + /// + /// Class that contains ocl functions + /// + public static partial class OclInvoke + { + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern IntPtr oclDeviceCreate(); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern void oclDeviceSet(IntPtr device, IntPtr p); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern IntPtr oclDeviceGetDefault(); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern void oclDeviceRelease(ref IntPtr oclDevice); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern IntPtr oclDeviceGetPtr(IntPtr device); + } } diff --git a/Emgu.CV/Ocl/Program.cs b/Emgu.CV/Ocl/Program.cs new file mode 100644 index 000000000..3ea22cf62 --- /dev/null +++ b/Emgu.CV/Ocl/Program.cs @@ -0,0 +1,79 @@ +//---------------------------------------------------------------------------- +// Copyright (C) 2004-2020 by EMGU Corporation. All rights reserved. +//---------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Text; +using Emgu.CV; +using Emgu.Util; +using System.Runtime.InteropServices; +using Emgu.CV.Util; + +namespace Emgu.CV.Ocl +{ + /// + /// This class contains ocl Program information + /// + public partial class Program : UnmanagedObject + { + /// + /// Create a empty OclProgram object + /// + public Program() + : this(OclInvoke.oclProgramCreate()) + { + } + + internal Program(IntPtr ptr) + { + _ptr = ptr; + } + + + /// + /// Get the program binary + /// + public byte[] Binary + { + get + { + if (_ptr == IntPtr.Zero) + return null; + + using (VectorOfByte vb = new VectorOfByte()) + { + OclInvoke.oclProgramGetBinary(_ptr, vb); + return vb.ToArray(); + } + } + } + + /// + /// Release all the unmanaged memory associated with this OclProgram + /// + protected override void DisposeObject() + { + if (_ptr != IntPtr.Zero) + { + OclInvoke.oclProgramRelease(ref _ptr); + } + } + + } + + /// + /// Class that contains ocl functions + /// + public static partial class OclInvoke + { + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern IntPtr oclProgramCreate(); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern void oclProgramRelease(ref IntPtr oclProgram); + + [DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)] + internal static extern void oclProgramGetBinary(IntPtr program, IntPtr binary); + } +}