source: trunk/CrypPlugins/Libs/OpenCLNet/Program.cs @ 2040

Last change on this file since 2040 was 2040, checked in by Sven Rech, 11 years ago
  • added OpenCL.Net project
  • added OpenCL settings in KeySearcher
  • changed rereservation status message behavior
File size: 12.4 KB
Line 
1/*
2 * Copyright (c) 2009 Olav Kalgraf(olav.kalgraf@gmail.com)
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26using System;
27using System.Collections.Generic;
28using System.ComponentModel;
29using System.Runtime.InteropServices;
30using System.Runtime.InteropServices.ComTypes;
31using System.Text;
32
33namespace OpenCLNet
34{
35    /// <summary>
36    /// Wrapper for an OpenCL Program
37    /// </summary>
38    unsafe public class Program : IDisposable, InteropTools.IPropertyContainer
39    {
40        // Track whether Dispose has been called.
41        private bool disposed = false;
42
43        #region Properties
44
45        public Context Context { get; protected set; }
46        public IntPtr ProgramID { get; protected set; }
47        public string Source { get { return InteropTools.ReadString( this, (uint)ProgramInfo.SOURCE ); } }
48        public uint ReferenceCount { get { return InteropTools.ReadUInt( this, (uint)ProgramInfo.REFERENCE_COUNT ); } }
49        public uint NumDevices { get { return InteropTools.ReadUInt( this, (uint)ProgramInfo.NUM_DEVICES ); } }
50       
51        public Device[] Devices
52        {
53            get
54            {
55                uint numDevices = NumDevices;
56                if( numDevices==0 )
57                    return null;
58
59                byte[] data = InteropTools.ReadBytes( this, (uint)ProgramInfo.DEVICES );
60                IntPtr[] deviceIDs = new IntPtr[numDevices];
61                fixed( byte* pData = data )
62                {
63                    void** pBS = (void**)pData;
64                    for( int i=0; i<numDevices; i++ )
65                        deviceIDs[i] = new IntPtr( pBS[i] );
66                }
67                return InteropTools.ConvertDeviceIDsToDevices( Context.Platform, deviceIDs );
68            }
69        }
70       
71       
72        public IntPtr[] BinarySizes
73        {
74            get
75            {
76                uint numDevices = NumDevices;
77                if( numDevices==0 )
78                    return null;
79
80                byte[] data = InteropTools.ReadBytes( this, (uint)ProgramInfo.BINARY_SIZES );
81                IntPtr[] binarySizes = new IntPtr[numDevices];
82                fixed( byte* pData = data )
83                {
84                    void** pBS = (void**)pData;
85                    for( int i=0; i<numDevices; i++ )
86                        binarySizes[i] = new IntPtr(pBS[i]);
87                }
88                return binarySizes;
89            }
90        }
91       
92        public byte[][] Binaries
93        {
94            get
95            {
96                uint numDevices = NumDevices;
97                if( numDevices==0 )
98                    return null;
99
100                IntPtr[] binarySizes = BinarySizes;
101                byte[][] binaries = new byte[numDevices][];
102                for( int i=0; i<numDevices; i++ )
103                    binaries[i] = new byte[binarySizes[i].ToInt64()];
104
105                InteropTools.ReadPreAllocatedBytePtrArray(this, (uint)ProgramInfo.BINARIES, binaries);
106                return binaries;
107            }
108        }
109
110        #endregion
111
112        internal Program( Context context, IntPtr programID )
113        {
114            Context = context;
115            ProgramID = programID;
116        }
117
118        ~Program()
119        {
120            Dispose( false );
121        }
122
123        #region IDisposable Members
124
125        // Implement IDisposable.
126        // Do not make this method virtual.
127        // A derived class should not be able to override this method.
128        public void Dispose()
129        {
130            Dispose( true );
131            // This object will be cleaned up by the Dispose method.
132            // Therefore, you should call GC.SupressFinalize to
133            // take this object off the finalization queue
134            // and prevent finalization code for this object
135            // from executing a second time.
136            GC.SuppressFinalize( this );
137        }
138
139        // Dispose(bool disposing) executes in two distinct scenarios.
140        // If disposing equals true, the method has been called directly
141        // or indirectly by a user's code. Managed and unmanaged resources
142        // can be disposed.
143        // If disposing equals false, the method has been called by the
144        // runtime from inside the finalizer and you should not reference
145        // other objects. Only unmanaged resources can be disposed.
146        private void Dispose( bool disposing )
147        {
148            // Check to see if Dispose has already been called.
149            if( !this.disposed )
150            {
151                // If disposing equals true, dispose all managed
152                // and unmanaged resources.
153                if( disposing )
154                {
155                    // Dispose managed resources.
156                }
157
158                // Call the appropriate methods to clean up
159                // unmanaged resources here.
160                // If disposing is false,
161                // only the following code is executed.
162                ErrorCode result = (ErrorCode)OpenCL.ReleaseProgram( ProgramID );
163                if( result!=ErrorCode.SUCCESS )
164                    throw new OpenCLException( "ReleaseProgram failed: "+result, result);
165
166                // Note disposing has been done.
167                disposed = true;
168            }
169        }
170
171
172        #endregion
173
174        public void Build()
175        {
176            Build( null, null, IntPtr.Zero );
177        }
178
179        public void Build(Device[] devices, ProgramNotify notify, IntPtr userData)
180        {
181            Build(devices, null, notify, userData);
182        }
183
184        public void Build(Device[] devices, string options, ProgramNotify notify, IntPtr userData)
185        {
186            ErrorCode result;
187            IntPtr[] deviceIDs;
188            int deviceLength = 0;
189
190            if (devices != null)
191                deviceLength = devices.Length;
192
193            deviceIDs = InteropTools.ConvertDevicesToDeviceIDs(devices);
194            result = (ErrorCode)OpenCL.BuildProgram(ProgramID,
195                (uint)deviceLength,
196                deviceIDs,
197                options,
198                notify,
199                userData);
200            if (result != ErrorCode.SUCCESS)
201                throw new OpenCLBuildException(this, result);
202        }
203
204        public Kernel CreateKernel( string kernelName )
205        {
206            IntPtr kernelID;
207            ErrorCode result;
208
209            kernelID = (IntPtr)OpenCL.CreateKernel( ProgramID, kernelName, out result );
210            if( result!=ErrorCode.SUCCESS )
211                throw new OpenCLException( "CreateKernel failed with error code "+result, result);
212            return new Kernel( Context, this, kernelID );
213        }
214
215        /// <summary>
216        /// Create all kernels in the program and return them as an array
217        /// </summary>
218        /// <returns></returns>
219        public Kernel[] CreateKernels()
220        {
221            uint numKernels;
222            ErrorCode result;
223
224            result = (ErrorCode)OpenCL.CreateKernelsInProgram( ProgramID, 0, null, out numKernels );
225            if( result!=ErrorCode.SUCCESS )
226                throw new OpenCLException( "CreateKernels failed with error code "+result, result);
227
228            IntPtr[] kernelIDs = new IntPtr[numKernels];
229            result = (ErrorCode)OpenCL.CreateKernelsInProgram( ProgramID, numKernels, kernelIDs, out numKernels );
230            if( result!=ErrorCode.SUCCESS )
231                throw new OpenCLException( "CreateKernels failed with error code "+result, result);
232
233            Kernel[] kernels = new Kernel[numKernels];
234            for( int i=0; i<kernels.Length; i++ )
235                kernels[i] = new Kernel( Context, this, kernelIDs[i] );
236            return kernels;
237        }
238
239        /// <summary>
240        /// Create all kernels in the program and return them as a Dictionary.
241        /// Its keys are the kernel names, its values are the kernels themselves.
242        /// </summary>
243        /// <returns></returns>
244        public Dictionary<string, Kernel> CreateKernelDictionary()
245        {
246            Kernel[] kernels = CreateKernels();
247            Dictionary<string, Kernel> kernelDictionary = new Dictionary<string, Kernel>();
248
249            foreach (Kernel k in kernels)
250                kernelDictionary[k.FunctionName] = k;
251           
252            return kernelDictionary;
253        }
254
255        public static implicit operator IntPtr( Program p )
256        {
257            return p.ProgramID;
258        }
259
260        public string GetBuildOptions( Device device )
261        {
262            BuildInfo buildInfo;
263
264            buildInfo = new BuildInfo( this, device );
265            return InteropTools.ReadString( buildInfo, (uint)ProgramBuildInfo.OPTIONS );
266        }
267
268        public string GetBuildLog( Device device )
269        {
270            BuildInfo buildInfo;
271
272            buildInfo = new BuildInfo( this, device );
273            return InteropTools.ReadString( buildInfo, (uint)ProgramBuildInfo.LOG );
274        }
275
276        public BuildStatus GetBuildStatus( Device device )
277        {
278            BuildInfo buildInfo;
279
280            buildInfo = new BuildInfo( this, device );
281            return (BuildStatus)InteropTools.ReadInt( buildInfo, (uint)ProgramBuildInfo.STATUS );
282        }
283
284        class BuildInfo : InteropTools.IPropertyContainer
285        {
286            Program Program;
287            Device Device;
288
289            public BuildInfo( Program p, Device d )
290            {
291                Program = p;
292                Device = d;
293            }
294
295            #region IPropertyContainer Members
296
297            public IntPtr GetPropertySize( uint key )
298            {
299                ErrorCode result;
300                IntPtr size;
301
302                result = (ErrorCode)OpenCL.GetProgramBuildInfo( Program.ProgramID, Device.DeviceID, key, IntPtr.Zero, null, out size );
303                if( result!=ErrorCode.SUCCESS )
304                    throw new OpenCLException( "clGetProgramBuildInfo failed with error code "+result, result);
305
306                return size;
307            }
308
309            public void ReadProperty( uint key, IntPtr keyLength, void* pBuffer )
310            {
311                ErrorCode result;
312                IntPtr size;
313
314                result = (ErrorCode)OpenCL.GetProgramBuildInfo( Program.ProgramID, Device.DeviceID, key, keyLength, pBuffer, out size );
315                if( result!=ErrorCode.SUCCESS )
316                    throw new OpenCLException( "clGetProgramBuildInfo failed with error code "+result, result);
317            }
318
319            #endregion
320        }
321
322        #region IPropertyContainer Members
323
324        public IntPtr GetPropertySize( uint key )
325        {
326            ErrorCode result;
327            IntPtr size;
328
329            result = (ErrorCode)OpenCL.GetProgramInfo( ProgramID, key, IntPtr.Zero, null, out size );
330            if( result!=ErrorCode.SUCCESS )
331                throw new OpenCLException( "clGetProgramInfo failed with error code "+result, result);
332
333            return size;
334        }
335
336        public void ReadProperty( uint key, IntPtr keyLength, void* pBuffer )
337        {
338            ErrorCode result;
339            IntPtr size;
340
341            result = (ErrorCode)OpenCL.GetProgramInfo( ProgramID, key, keyLength, pBuffer, out size );
342            if( result!=ErrorCode.SUCCESS )
343                throw new OpenCLException( "clGetProgramInfo failed with error code "+result, result);
344        }
345
346        #endregion
347    }
348}
Note: See TracBrowser for help on using the repository browser.