PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/implementation/cl-programs.adb

http://github.com/flyx86/OpenCLAda
Ada | 294 lines | 236 code | 36 blank | 22 comment | 11 complexity | a96ec7f289aeb007dc266300bf1e4311 MD5 | raw file
Possible License(s): 0BSD
  1. --------------------------------------------------------------------------------
  2. -- Copyright (c) 2013, Felix Krause <contact@flyx.org>
  3. --
  4. -- Permission to use, copy, modify, and/or distribute this software for any
  5. -- purpose with or without fee is hereby granted, provided that the above
  6. -- copyright notice and this permission notice appear in all copies.
  7. --
  8. -- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. -- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. -- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. -- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. -- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. -- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. -- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. --------------------------------------------------------------------------------
  16. with Ada.Text_IO;
  17. with Interfaces.C.Strings;
  18. with CL.API;
  19. with CL.Enumerations;
  20. with CL.Helpers;
  21. package body CL.Programs is
  22. -----------------------------------------------------------------------------
  23. -- Helpers
  24. -----------------------------------------------------------------------------
  25. procedure Build_Callback_Dispatcher (Subject : System.Address;
  26. Callback : Build_Callback);
  27. pragma Convention (C, Build_Callback_Dispatcher);
  28. procedure Build_Callback_Dispatcher (Subject : System.Address;
  29. Callback : Build_Callback) is
  30. begin
  31. Callback (Program'(Ada.Finalization.Controlled with Location => Subject));
  32. end Build_Callback_Dispatcher;
  33. function String_Info is
  34. new Helpers.Get_Parameters (Return_Element_T => Character,
  35. Return_T => String,
  36. Parameter_T => Enumerations.Program_Info,
  37. C_Getter => API.Get_Program_Info);
  38. function String_Build_Info is
  39. new Helpers.Get_Parameters2 (Return_Element_T => Character,
  40. Return_T => String,
  41. Parameter_T => Enumerations.Program_Build_Info,
  42. C_Getter => API.Get_Program_Build_Info);
  43. -----------------------------------------------------------------------------
  44. -- Implementations
  45. -----------------------------------------------------------------------------
  46. package body Constructors is
  47. function Create_From_Source (Context : Contexts.Context'Class;
  48. Source : String) return Program is
  49. C_String : aliased IFC.Strings.chars_ptr
  50. := IFC.Strings.New_String (Source);
  51. String_Size : aliased Size := Source'Length;
  52. Ret_Program : System.Address;
  53. Error : aliased Enumerations.Error_Code;
  54. begin
  55. Ret_Program
  56. := API.Create_Program_With_Source (CL_Object (Context).Location,
  57. 1, C_String'Access,
  58. String_Size'Access,
  59. Error'Unchecked_Access);
  60. IFC.Strings.Free (C_String);
  61. Helpers.Error_Handler (Error);
  62. return Program'(Ada.Finalization.Controlled with Location => Ret_Program);
  63. end Create_From_Source;
  64. function Create_From_Source (Context : Contexts.Context'Class;
  65. Sources : String_List)
  66. return Program is
  67. C_Strings : array (Sources.First_Index .. Sources.Last_Index)
  68. of aliased IFC.Strings.chars_ptr;
  69. Size_List : array (C_Strings'Range) of aliased Size;
  70. Ret_Program : System.Address;
  71. Error : aliased Enumerations.Error_Code;
  72. begin
  73. for Index in C_Strings'Range loop
  74. C_Strings (Index) := IFC.Strings.New_String (Sources.Element (Index));
  75. Size_List (Index) := Size (IFC.Strings.Strlen (C_Strings (Index)));
  76. end loop;
  77. Ret_Program
  78. := API.Create_Program_With_Source (CL_Object (Context).Location,
  79. UInt (Size_List'Length),
  80. C_Strings (C_Strings'First)'Access,
  81. Size_List (Size_List'First)'Access,
  82. Error'Unchecked_Access);
  83. for Index in C_Strings'Range loop
  84. IFC.Strings.Free (C_Strings (Index));
  85. end loop;
  86. Helpers.Error_Handler (Error);
  87. return Program'(Ada.Finalization.Controlled with Location => Ret_Program);
  88. end Create_From_Source;
  89. function Create_From_Files (Context : Contexts.Context'Class;
  90. Sources : String_List)
  91. return Program is
  92. C_Strings : array (Sources.First_Index .. Sources.Last_Index)
  93. of aliased IFC.Strings.chars_ptr;
  94. Size_List : array (C_Strings'Range) of aliased Size;
  95. Ret_Program : System.Address;
  96. Error : aliased Enumerations.Error_Code;
  97. begin
  98. for Index in C_Strings'Range loop
  99. declare
  100. File : Ada.Text_IO.File_Type;
  101. begin
  102. Ada.Text_IO.Open (File, Ada.Text_IO.In_File, Sources.Element (Index));
  103. C_Strings (Index) := IFC.Strings.New_String
  104. (Helpers.Read_File (File));
  105. Ada.Text_IO.Close (File);
  106. end;
  107. Size_List (Index) := Size (IFC.Strings.Strlen (C_Strings (Index)));
  108. end loop;
  109. Ret_Program
  110. := API.Create_Program_With_Source (CL_Object (Context).Location,
  111. UInt (Size_List'Length),
  112. C_Strings (C_Strings'First)'Access,
  113. Size_List (Size_List'First)'Access,
  114. Error'Unchecked_Access);
  115. for Index in C_Strings'Range loop
  116. IFC.Strings.Free (C_Strings (Index));
  117. end loop;
  118. Helpers.Error_Handler (Error);
  119. return Program'(Ada.Finalization.Controlled with Location => Ret_Program);
  120. end Create_From_Files;
  121. function Create_From_Binary (Context : Contexts.Context'Class;
  122. Devices : Platforms.Device_List;
  123. Binaries : Binary_List;
  124. Success : access Bool_List)
  125. return Program is
  126. Binary_Pointers : array (Binaries'Range) of aliased System.Address;
  127. Size_List : array (Binaries'Range) of aliased Size;
  128. Status : array (Binaries'Range) of aliased Int;
  129. Ret_Program : System.Address;
  130. Error : aliased Enumerations.Error_Code;
  131. begin
  132. for Index in Binaries'Range loop
  133. Binary_Pointers (Index) := Binaries (Index) (Binaries (Index)'First)'Address;
  134. Size_List (Index) := Binaries (Index)'Length;
  135. end loop;
  136. Ret_Program
  137. := API.Create_Program_With_Binary (CL_Object (Context).Location,
  138. UInt (Devices'Length),
  139. Devices (Devices'First)'Address,
  140. Size_List (Size_List'First)'Unchecked_Access,
  141. Binary_Pointers (Binary_Pointers'First)'Access,
  142. Status (Status'First)'Access,
  143. Error'Unchecked_Access);
  144. if Success /= null then
  145. for Index in Success.all'Range loop
  146. Success.all (Index) := (Status (Index) = 1);
  147. end loop;
  148. else
  149. Helpers.Error_Handler (Error);
  150. end if;
  151. return Program'(Ada.Finalization.Controlled with Location => Ret_Program);
  152. end Create_From_Binary;
  153. end Constructors;
  154. overriding procedure Adjust (Object : in out Program) is
  155. use type System.Address;
  156. begin
  157. if Object.Location /= System.Null_Address then
  158. Helpers.Error_Handler (API.Retain_Program (Object.Location));
  159. end if;
  160. end Adjust;
  161. overriding procedure Finalize (Object : in out Program) is
  162. use type System.Address;
  163. begin
  164. if Object.Location /= System.Null_Address then
  165. Helpers.Error_Handler (API.Release_Program (Object.Location));
  166. end if;
  167. end Finalize;
  168. procedure Build (Source : Program;
  169. Devices : Platforms.Device_List;
  170. Options : String;
  171. Callback : Build_Callback) is
  172. function Raw_Device_List is
  173. new Helpers.Raw_List (Platforms.Device, Platforms.Device_List);
  174. Error : Enumerations.Error_Code;
  175. Raw_List : Address_List := Raw_Device_List (Devices);
  176. begin
  177. if Callback /= null then
  178. Error := API.Build_Program (Source.Location, UInt (Raw_List'Length),
  179. Raw_List (1)'Address,
  180. IFC.Strings.New_String (Options),
  181. Build_Callback_Dispatcher'Access,
  182. Callback);
  183. else
  184. Error := API.Build_Program (Source.Location, UInt (Raw_List'Length),
  185. Raw_List (1)'Address,
  186. IFC.Strings.New_String (Options),
  187. null, null);
  188. end if;
  189. Helpers.Error_Handler (Error);
  190. end Build;
  191. function Reference_Count (Source : Program) return UInt is
  192. function Getter is
  193. new Helpers.Get_Parameter (Return_T => UInt,
  194. Parameter_T => Enumerations.Program_Info,
  195. C_Getter => API.Get_Program_Info);
  196. begin
  197. return Getter (Source, Enumerations.Reference_Count);
  198. end Reference_Count;
  199. function Context (Source : Program) return Contexts.Context is
  200. function Getter is
  201. new Helpers.Get_Parameter (Return_T => System.Address,
  202. Parameter_T => Enumerations.Program_Info,
  203. C_Getter => API.Get_Program_Info);
  204. function New_Context_Reference is
  205. new Helpers.New_Reference (Object_T => Contexts.Context);
  206. begin
  207. return New_Context_Reference (Getter (Source, Enumerations.Context));
  208. end Context;
  209. function Devices (Source : Program) return Platforms.Device_List is
  210. function Getter is
  211. new Helpers.Get_Parameters (Return_Element_T => System.Address,
  212. Return_T => Address_List,
  213. Parameter_T => Enumerations.Program_Info,
  214. C_Getter => API.Get_Program_Info);
  215. Raw_List : constant Address_List := Getter (Source, Enumerations.Devices);
  216. Ret_List : Platforms.Device_List (Raw_List'Range);
  217. begin
  218. for Index in Raw_List'Range loop
  219. Ret_List (Index) := Platforms.Device'(Ada.Finalization.Controlled with
  220. Location => Raw_List (Index));
  221. end loop;
  222. return Ret_List;
  223. end Devices;
  224. function Source (Source : Program) return String is
  225. begin
  226. return String_Info (Source, Enumerations.Source_String);
  227. end Source;
  228. function Binaries (Source : Program) return Binary_List is
  229. Empty_List : Binary_List (1..0);
  230. begin
  231. -- not implemented, chrhrhr
  232. raise CL.Invalid_Operation;
  233. return Empty_List;
  234. end Binaries;
  235. function Status (Source : Program;
  236. Device : Platforms.Device) return Build_Status is
  237. function Getter is
  238. new Helpers.Get_Parameter2 (Return_T => Build_Status,
  239. Parameter_T => Enumerations.Program_Build_Info,
  240. C_Getter => API.Get_Program_Build_Info);
  241. begin
  242. return Getter (Source, Device, Enumerations.Status);
  243. end Status;
  244. function Build_Options (Source : Program;
  245. Device : Platforms.Device) return String is
  246. begin
  247. return String_Build_Info (Source, Device, Enumerations.Options);
  248. end Build_Options;
  249. function Build_Log (Source : Program;
  250. Device : Platforms.Device) return String is
  251. begin
  252. return String_Build_Info (Source, Device, Enumerations.Log);
  253. end Build_Log;
  254. procedure Unload_Compiler is
  255. begin
  256. Helpers.Error_Handler (API.Unload_Compiler);
  257. end Unload_Compiler;
  258. end CL.Programs;