OpenCL (empty) → 1.0.1.3
raw patch · 11 files changed
+3919/−0 lines, 11 filesdep +basedep +bytestringdep +mtlsetup-changed
Dependencies added: base, bytestring, mtl
Files
- LICENSE +661/−0
- OpenCL.cabal +43/−0
- Setup.hs +2/−0
- src/System/GPU/OpenCL.hs +39/−0
- src/System/GPU/OpenCL/CommandQueue.chs +553/−0
- src/System/GPU/OpenCL/Context.chs +150/−0
- src/System/GPU/OpenCL/Event.chs +158/−0
- src/System/GPU/OpenCL/Memory.chs +286/−0
- src/System/GPU/OpenCL/Program.chs +745/−0
- src/System/GPU/OpenCL/Query.chs +590/−0
- src/System/GPU/OpenCL/Types.chs +692/−0
+ LICENSE view
@@ -0,0 +1,661 @@+ GNU AFFERO GENERAL PUBLIC LICENSE+ Version 3, 19 November 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The GNU Affero General Public License is a free, copyleft license for+software and other kinds of works, specifically designed to ensure+cooperation with the community in the case of network server software.++ The licenses for most software and other practical works are designed+to take away your freedom to share and change the works. By contrast,+our General Public Licenses are intended to guarantee your freedom to+share and change all versions of a program--to make sure it remains free+software for all its users.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+them if you wish), that you receive source code or can get it if you+want it, that you can change the software or use pieces of it in new+free programs, and that you know you can do these things.++ Developers that use our General Public Licenses protect your rights+with two steps: (1) assert copyright on the software, and (2) offer+you this License which gives you legal permission to copy, distribute+and/or modify the software.++ A secondary benefit of defending all users' freedom is that+improvements made in alternate versions of the program, if they+receive widespread use, become available for other developers to+incorporate. Many developers of free software are heartened and+encouraged by the resulting cooperation. However, in the case of+software used on network servers, this result may fail to come about.+The GNU General Public License permits making a modified version and+letting the public access it on a server without ever releasing its+source code to the public.++ The GNU Affero General Public License is designed specifically to+ensure that, in such cases, the modified source code becomes available+to the community. It requires the operator of a network server to+provide the source code of the modified version running there to the+users of that server. Therefore, public use of a modified version, on+a publicly accessible server, gives the public access to the source+code of the modified version.++ An older license, called the Affero General Public License and+published by Affero, was designed to accomplish similar goals. This is+a different license, not a version of the Affero GPL, but Affero has+released a new version of the Affero GPL which permits relicensing under+this license.++ The precise terms and conditions for copying, distribution and+modification follow.++ TERMS AND CONDITIONS++ 0. Definitions.++ "This License" refers to version 3 of the GNU Affero General Public License.++ "Copyright" also means copyright-like laws that apply to other kinds of+works, such as semiconductor masks.++ "The Program" refers to any copyrightable work licensed under this+License. Each licensee is addressed as "you". "Licensees" and+"recipients" may be individuals or organizations.++ To "modify" a work means to copy from or adapt all or part of the work+in a fashion requiring copyright permission, other than the making of an+exact copy. The resulting work is called a "modified version" of the+earlier work or a work "based on" the earlier work.++ A "covered work" means either the unmodified Program or a work based+on the Program.++ To "propagate" a work means to do anything with it that, without+permission, would make you directly or secondarily liable for+infringement under applicable copyright law, except executing it on a+computer or modifying a private copy. Propagation includes copying,+distribution (with or without modification), making available to the+public, and in some countries other activities as well.++ To "convey" a work means any kind of propagation that enables other+parties to make or receive copies. Mere interaction with a user through+a computer network, with no transfer of a copy, is not conveying.++ An interactive user interface displays "Appropriate Legal Notices"+to the extent that it includes a convenient and prominently visible+feature that (1) displays an appropriate copyright notice, and (2)+tells the user that there is no warranty for the work (except to the+extent that warranties are provided), that licensees may convey the+work under this License, and how to view a copy of this License. If+the interface presents a list of user commands or options, such as a+menu, a prominent item in the list meets this criterion.++ 1. Source Code.++ The "source code" for a work means the preferred form of the work+for making modifications to it. "Object code" means any non-source+form of a work.++ A "Standard Interface" means an interface that either is an official+standard defined by a recognized standards body, or, in the case of+interfaces specified for a particular programming language, one that+is widely used among developers working in that language.++ The "System Libraries" of an executable work include anything, other+than the work as a whole, that (a) is included in the normal form of+packaging a Major Component, but which is not part of that Major+Component, and (b) serves only to enable use of the work with that+Major Component, or to implement a Standard Interface for which an+implementation is available to the public in source code form. A+"Major Component", in this context, means a major essential component+(kernel, window system, and so on) of the specific operating system+(if any) on which the executable work runs, or a compiler used to+produce the work, or an object code interpreter used to run it.++ The "Corresponding Source" for a work in object code form means all+the source code needed to generate, install, and (for an executable+work) run the object code and to modify the work, including scripts to+control those activities. However, it does not include the work's+System Libraries, or general-purpose tools or generally available free+programs which are used unmodified in performing those activities but+which are not part of the work. For example, Corresponding Source+includes interface definition files associated with source files for+the work, and the source code for shared libraries and dynamically+linked subprograms that the work is specifically designed to require,+such as by intimate data communication or control flow between those+subprograms and other parts of the work.++ The Corresponding Source need not include anything that users+can regenerate automatically from other parts of the Corresponding+Source.++ The Corresponding Source for a work in source code form is that+same work.++ 2. Basic Permissions.++ All rights granted under this License are granted for the term of+copyright on the Program, and are irrevocable provided the stated+conditions are met. This License explicitly affirms your unlimited+permission to run the unmodified Program. The output from running a+covered work is covered by this License only if the output, given its+content, constitutes a covered work. This License acknowledges your+rights of fair use or other equivalent, as provided by copyright law.++ You may make, run and propagate covered works that you do not+convey, without conditions so long as your license otherwise remains+in force. You may convey covered works to others for the sole purpose+of having them make modifications exclusively for you, or provide you+with facilities for running those works, provided that you comply with+the terms of this License in conveying all material for which you do+not control copyright. Those thus making or running the covered works+for you must do so exclusively on your behalf, under your direction+and control, on terms that prohibit them from making any copies of+your copyrighted material outside their relationship with you.++ Conveying under any other circumstances is permitted solely under+the conditions stated below. Sublicensing is not allowed; section 10+makes it unnecessary.++ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.++ No covered work shall be deemed part of an effective technological+measure under any applicable law fulfilling obligations under article+11 of the WIPO copyright treaty adopted on 20 December 1996, or+similar laws prohibiting or restricting circumvention of such+measures.++ When you convey a covered work, you waive any legal power to forbid+circumvention of technological measures to the extent such circumvention+is effected by exercising rights under this License with respect to+the covered work, and you disclaim any intention to limit operation or+modification of the work as a means of enforcing, against the work's+users, your or third parties' legal rights to forbid circumvention of+technological measures.++ 4. Conveying Verbatim Copies.++ You may convey verbatim copies of the Program's source code as you+receive it, in any medium, provided that you conspicuously and+appropriately publish on each copy an appropriate copyright notice;+keep intact all notices stating that this License and any+non-permissive terms added in accord with section 7 apply to the code;+keep intact all notices of the absence of any warranty; and give all+recipients a copy of this License along with the Program.++ You may charge any price or no price for each copy that you convey,+and you may offer support or warranty protection for a fee.++ 5. Conveying Modified Source Versions.++ You may convey a work based on the Program, or the modifications to+produce it from the Program, in the form of source code under the+terms of section 4, provided that you also meet all of these conditions:++ a) The work must carry prominent notices stating that you modified+ it, and giving a relevant date.++ b) The work must carry prominent notices stating that it is+ released under this License and any conditions added under section+ 7. This requirement modifies the requirement in section 4 to+ "keep intact all notices".++ c) You must license the entire work, as a whole, under this+ License to anyone who comes into possession of a copy. This+ License will therefore apply, along with any applicable section 7+ additional terms, to the whole of the work, and all its parts,+ regardless of how they are packaged. This License gives no+ permission to license the work in any other way, but it does not+ invalidate such permission if you have separately received it.++ d) If the work has interactive user interfaces, each must display+ Appropriate Legal Notices; however, if the Program has interactive+ interfaces that do not display Appropriate Legal Notices, your+ work need not make them do so.++ A compilation of a covered work with other separate and independent+works, which are not by their nature extensions of the covered work,+and which are not combined with it such as to form a larger program,+in or on a volume of a storage or distribution medium, is called an+"aggregate" if the compilation and its resulting copyright are not+used to limit the access or legal rights of the compilation's users+beyond what the individual works permit. Inclusion of a covered work+in an aggregate does not cause this License to apply to the other+parts of the aggregate.++ 6. Conveying Non-Source Forms.++ You may convey a covered work in object code form under the terms+of sections 4 and 5, provided that you also convey the+machine-readable Corresponding Source under the terms of this License,+in one of these ways:++ a) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by the+ Corresponding Source fixed on a durable physical medium+ customarily used for software interchange.++ b) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by a+ written offer, valid for at least three years and valid for as+ long as you offer spare parts or customer support for that product+ model, to give anyone who possesses the object code either (1) a+ copy of the Corresponding Source for all the software in the+ product that is covered by this License, on a durable physical+ medium customarily used for software interchange, for a price no+ more than your reasonable cost of physically performing this+ conveying of source, or (2) access to copy the+ Corresponding Source from a network server at no charge.++ c) Convey individual copies of the object code with a copy of the+ written offer to provide the Corresponding Source. This+ alternative is allowed only occasionally and noncommercially, and+ only if you received the object code with such an offer, in accord+ with subsection 6b.++ d) Convey the object code by offering access from a designated+ place (gratis or for a charge), and offer equivalent access to the+ Corresponding Source in the same way through the same place at no+ further charge. You need not require recipients to copy the+ Corresponding Source along with the object code. If the place to+ copy the object code is a network server, the Corresponding Source+ may be on a different server (operated by you or a third party)+ that supports equivalent copying facilities, provided you maintain+ clear directions next to the object code saying where to find the+ Corresponding Source. Regardless of what server hosts the+ Corresponding Source, you remain obligated to ensure that it is+ available for as long as needed to satisfy these requirements.++ e) Convey the object code using peer-to-peer transmission, provided+ you inform other peers where the object code and Corresponding+ Source of the work are being offered to the general public at no+ charge under subsection 6d.++ A separable portion of the object code, whose source code is excluded+from the Corresponding Source as a System Library, need not be+included in conveying the object code work.++ A "User Product" is either (1) a "consumer product", which means any+tangible personal property which is normally used for personal, family,+or household purposes, or (2) anything designed or sold for incorporation+into a dwelling. In determining whether a product is a consumer product,+doubtful cases shall be resolved in favor of coverage. For a particular+product received by a particular user, "normally used" refers to a+typical or common use of that class of product, regardless of the status+of the particular user or of the way in which the particular user+actually uses, or expects or is expected to use, the product. A product+is a consumer product regardless of whether the product has substantial+commercial, industrial or non-consumer uses, unless such uses represent+the only significant mode of use of the product.++ "Installation Information" for a User Product means any methods,+procedures, authorization keys, or other information required to install+and execute modified versions of a covered work in that User Product from+a modified version of its Corresponding Source. The information must+suffice to ensure that the continued functioning of the modified object+code is in no case prevented or interfered with solely because+modification has been made.++ If you convey an object code work under this section in, or with, or+specifically for use in, a User Product, and the conveying occurs as+part of a transaction in which the right of possession and use of the+User Product is transferred to the recipient in perpetuity or for a+fixed term (regardless of how the transaction is characterized), the+Corresponding Source conveyed under this section must be accompanied+by the Installation Information. But this requirement does not apply+if neither you nor any third party retains the ability to install+modified object code on the User Product (for example, the work has+been installed in ROM).++ The requirement to provide Installation Information does not include a+requirement to continue to provide support service, warranty, or updates+for a work that has been modified or installed by the recipient, or for+the User Product in which it has been modified or installed. Access to a+network may be denied when the modification itself materially and+adversely affects the operation of the network or violates the rules and+protocols for communication across the network.++ Corresponding Source conveyed, and Installation Information provided,+in accord with this section must be in a format that is publicly+documented (and with an implementation available to the public in+source code form), and must require no special password or key for+unpacking, reading or copying.++ 7. Additional Terms.++ "Additional permissions" are terms that supplement the terms of this+License by making exceptions from one or more of its conditions.+Additional permissions that are applicable to the entire Program shall+be treated as though they were included in this License, to the extent+that they are valid under applicable law. If additional permissions+apply only to part of the Program, that part may be used separately+under those permissions, but the entire Program remains governed by+this License without regard to the additional permissions.++ When you convey a copy of a covered work, you may at your option+remove any additional permissions from that copy, or from any part of+it. (Additional permissions may be written to require their own+removal in certain cases when you modify the work.) You may place+additional permissions on material, added by you to a covered work,+for which you have or can give appropriate copyright permission.++ Notwithstanding any other provision of this License, for material you+add to a covered work, you may (if authorized by the copyright holders of+that material) supplement the terms of this License with terms:++ a) Disclaiming warranty or limiting liability differently from the+ terms of sections 15 and 16 of this License; or++ b) Requiring preservation of specified reasonable legal notices or+ author attributions in that material or in the Appropriate Legal+ Notices displayed by works containing it; or++ c) Prohibiting misrepresentation of the origin of that material, or+ requiring that modified versions of such material be marked in+ reasonable ways as different from the original version; or++ d) Limiting the use for publicity purposes of names of licensors or+ authors of the material; or++ e) Declining to grant rights under trademark law for use of some+ trade names, trademarks, or service marks; or++ f) Requiring indemnification of licensors and authors of that+ material by anyone who conveys the material (or modified versions of+ it) with contractual assumptions of liability to the recipient, for+ any liability that these contractual assumptions directly impose on+ those licensors and authors.++ All other non-permissive additional terms are considered "further+restrictions" within the meaning of section 10. If the Program as you+received it, or any part of it, contains a notice stating that it is+governed by this License along with a term that is a further+restriction, you may remove that term. If a license document contains+a further restriction but permits relicensing or conveying under this+License, you may add to a covered work material governed by the terms+of that license document, provided that the further restriction does+not survive such relicensing or conveying.++ If you add terms to a covered work in accord with this section, you+must place, in the relevant source files, a statement of the+additional terms that apply to those files, or a notice indicating+where to find the applicable terms.++ Additional terms, permissive or non-permissive, may be stated in the+form of a separately written license, or stated as exceptions;+the above requirements apply either way.++ 8. Termination.++ You may not propagate or modify a covered work except as expressly+provided under this License. Any attempt otherwise to propagate or+modify it is void, and will automatically terminate your rights under+this License (including any patent licenses granted under the third+paragraph of section 11).++ However, if you cease all violation of this License, then your+license from a particular copyright holder is reinstated (a)+provisionally, unless and until the copyright holder explicitly and+finally terminates your license, and (b) permanently, if the copyright+holder fails to notify you of the violation by some reasonable means+prior to 60 days after the cessation.++ Moreover, your license from a particular copyright holder is+reinstated permanently if the copyright holder notifies you of the+violation by some reasonable means, this is the first time you have+received notice of violation of this License (for any work) from that+copyright holder, and you cure the violation prior to 30 days after+your receipt of the notice.++ Termination of your rights under this section does not terminate the+licenses of parties who have received copies or rights from you under+this License. If your rights have been terminated and not permanently+reinstated, you do not qualify to receive new licenses for the same+material under section 10.++ 9. Acceptance Not Required for Having Copies.++ You are not required to accept this License in order to receive or+run a copy of the Program. Ancillary propagation of a covered work+occurring solely as a consequence of using peer-to-peer transmission+to receive a copy likewise does not require acceptance. However,+nothing other than this License grants you permission to propagate or+modify any covered work. These actions infringe copyright if you do+not accept this License. Therefore, by modifying or propagating a+covered work, you indicate your acceptance of this License to do so.++ 10. Automatic Licensing of Downstream Recipients.++ Each time you convey a covered work, the recipient automatically+receives a license from the original licensors, to run, modify and+propagate that work, subject to this License. You are not responsible+for enforcing compliance by third parties with this License.++ An "entity transaction" is a transaction transferring control of an+organization, or substantially all assets of one, or subdividing an+organization, or merging organizations. If propagation of a covered+work results from an entity transaction, each party to that+transaction who receives a copy of the work also receives whatever+licenses to the work the party's predecessor in interest had or could+give under the previous paragraph, plus a right to possession of the+Corresponding Source of the work from the predecessor in interest, if+the predecessor has it or can get it with reasonable efforts.++ You may not impose any further restrictions on the exercise of the+rights granted or affirmed under this License. For example, you may+not impose a license fee, royalty, or other charge for exercise of+rights granted under this License, and you may not initiate litigation+(including a cross-claim or counterclaim in a lawsuit) alleging that+any patent claim is infringed by making, using, selling, offering for+sale, or importing the Program or any portion of it.++ 11. Patents.++ A "contributor" is a copyright holder who authorizes use under this+License of the Program or a work on which the Program is based. The+work thus licensed is called the contributor's "contributor version".++ A contributor's "essential patent claims" are all patent claims+owned or controlled by the contributor, whether already acquired or+hereafter acquired, that would be infringed by some manner, permitted+by this License, of making, using, or selling its contributor version,+but do not include claims that would be infringed only as a+consequence of further modification of the contributor version. For+purposes of this definition, "control" includes the right to grant+patent sublicenses in a manner consistent with the requirements of+this License.++ Each contributor grants you a non-exclusive, worldwide, royalty-free+patent license under the contributor's essential patent claims, to+make, use, sell, offer for sale, import and otherwise run, modify and+propagate the contents of its contributor version.++ In the following three paragraphs, a "patent license" is any express+agreement or commitment, however denominated, not to enforce a patent+(such as an express permission to practice a patent or covenant not to+sue for patent infringement). To "grant" such a patent license to a+party means to make such an agreement or commitment not to enforce a+patent against the party.++ If you convey a covered work, knowingly relying on a patent license,+and the Corresponding Source of the work is not available for anyone+to copy, free of charge and under the terms of this License, through a+publicly available network server or other readily accessible means,+then you must either (1) cause the Corresponding Source to be so+available, or (2) arrange to deprive yourself of the benefit of the+patent license for this particular work, or (3) arrange, in a manner+consistent with the requirements of this License, to extend the patent+license to downstream recipients. "Knowingly relying" means you have+actual knowledge that, but for the patent license, your conveying the+covered work in a country, or your recipient's use of the covered work+in a country, would infringe one or more identifiable patents in that+country that you have reason to believe are valid.++ If, pursuant to or in connection with a single transaction or+arrangement, you convey, or propagate by procuring conveyance of, a+covered work, and grant a patent license to some of the parties+receiving the covered work authorizing them to use, propagate, modify+or convey a specific copy of the covered work, then the patent license+you grant is automatically extended to all recipients of the covered+work and works based on it.++ A patent license is "discriminatory" if it does not include within+the scope of its coverage, prohibits the exercise of, or is+conditioned on the non-exercise of one or more of the rights that are+specifically granted under this License. You may not convey a covered+work if you are a party to an arrangement with a third party that is+in the business of distributing software, under which you make payment+to the third party based on the extent of your activity of conveying+the work, and under which the third party grants, to any of the+parties who would receive the covered work from you, a discriminatory+patent license (a) in connection with copies of the covered work+conveyed by you (or copies made from those copies), or (b) primarily+for and in connection with specific products or compilations that+contain the covered work, unless you entered into that arrangement,+or that patent license was granted, prior to 28 March 2007.++ Nothing in this License shall be construed as excluding or limiting+any implied license or other defenses to infringement that may+otherwise be available to you under applicable patent law.++ 12. No Surrender of Others' Freedom.++ If conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot convey a+covered work so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you may+not convey it at all. For example, if you agree to terms that obligate you+to collect a royalty for further conveying from those to whom you convey+the Program, the only way you could satisfy both those terms and this+License would be to refrain entirely from conveying the Program.++ 13. Remote Network Interaction; Use with the GNU General Public License.++ Notwithstanding any other provision of this License, if you modify the+Program, your modified version must prominently offer all users+interacting with it remotely through a computer network (if your version+supports such interaction) an opportunity to receive the Corresponding+Source of your version by providing access to the Corresponding Source+from a network server at no charge, through some standard or customary+means of facilitating copying of software. This Corresponding Source+shall include the Corresponding Source for any work covered by version 3+of the GNU General Public License that is incorporated pursuant to the+following paragraph.++ Notwithstanding any other provision of this License, you have+permission to link or combine any covered work with a work licensed+under version 3 of the GNU General Public License into a single+combined work, and to convey the resulting work. The terms of this+License will continue to apply to the part which is the covered work,+but the work with which it is combined will remain governed by version+3 of the GNU General Public License.++ 14. Revised Versions of this License.++ The Free Software Foundation may publish revised and/or new versions of+the GNU Affero General Public License from time to time. Such new versions+will be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++ Each version is given a distinguishing version number. If the+Program specifies that a certain numbered version of the GNU Affero General+Public License "or any later version" applies to it, you have the+option of following the terms and conditions either of that numbered+version or of any later version published by the Free Software+Foundation. If the Program does not specify a version number of the+GNU Affero General Public License, you may choose any version ever published+by the Free Software Foundation.++ If the Program specifies that a proxy can decide which future+versions of the GNU Affero General Public License can be used, that proxy's+public statement of acceptance of a version permanently authorizes you+to choose that version for the Program.++ Later license versions may give you additional or different+permissions. However, no additional obligations are imposed on any+author or copyright holder as a result of your choosing to follow a+later version.++ 15. Disclaimer of Warranty.++ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.++ 16. Limitation of Liability.++ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF+SUCH DAMAGES.++ 17. Interpretation of Sections 15 and 16.++ If the disclaimer of warranty and limitation of liability provided+above cannot be given local legal effect according to their terms,+reviewing courts shall apply local law that most closely approximates+an absolute waiver of all civil liability in connection with the+Program, unless a warranty or assumption of liability accompanies a+copy of the Program in return for a fee.++ END OF TERMS AND CONDITIONS++ How to Apply These Terms to Your New Programs++ If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++ To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+state the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ <one line to give the program's name and a brief idea of what it does.>+ Copyright (C) <year> <name of author>++ This program is free software: you can redistribute it and/or modify+ it under the terms of the GNU Affero General Public License as published by+ the Free Software Foundation, either version 3 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU Affero General Public License for more details.++ You should have received a copy of the GNU Affero General Public License+ along with this program. If not, see <http://www.gnu.org/licenses/>.++Also add information on how to contact you by electronic and paper mail.++ If your software can interact with users remotely through a computer+network, you should also make sure that it provides a way for users to+get its source. For example, if your program is a web application, its+interface could display a "Source" link that leads users to an archive+of the code. There are many ways you could offer source, and different+solutions will be better for different programs; see section 13 for the+specific requirements.++ You should also get your employer (if you work as a programmer) or school,+if any, to sign a "copyright disclaimer" for the program, if necessary.+For more information on this, and how to apply and follow the GNU AGPL, see+<http://www.gnu.org/licenses/>.
+ OpenCL.cabal view
@@ -0,0 +1,43 @@+Name: OpenCL+Version: 1.0.1.3+License: GPL+License-File: LICENSE+Author: Luis Cabellos+Copyright: (c) 2011 Luis Cabellos+Category: GPU, FFI, Graphics+Build-Type: Simple+Stability: Experimental+Maintainer: Luis Cabellos+Homepage: https://github.com/zhensydow/opencl+Synopsis: Haskell high-level wrapper for OpenCL+Description: Haskell FFI binding to OpenCL library. It includes high-level wrappers to help development. Based on OpenCLRaw package.+bug-reports: https://github.com/zhensydow/opencl/issues+Cabal-Version: >=1.8+Tested-With: GHC++source-repository this+ type: git+ location: https://zhensydow@github.com/zhensydow/opencl.git+ tag: 1.0.1.3+ branch: master++source-repository head+ type: git+ location: https://zhensydow@github.com/zhensydow/opencl.git+ branch: develop++Library+ Build-tools: c2hs+ hs-Source-Dirs: src+ ghc-options: -Wall+ Build-Depends: base >=4.0 && < 5, bytestring -any, mtl==2.0.*+ Exposed-Modules: + System.GPU.OpenCL+ System.GPU.OpenCL.Query+ System.GPU.OpenCL.Context+ System.GPU.OpenCL.CommandQueue+ System.GPU.OpenCL.Memory+ System.GPU.OpenCL.Event+ System.GPU.OpenCL.Program+ Other-Modules: + System.GPU.OpenCL.Types
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/System/GPU/OpenCL.hs view
@@ -0,0 +1,39 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+module System.GPU.OpenCL( + -- * Basic Types+ CLError(..), CLint, CLuint, CLulong,+ -- * Modules+ module System.GPU.OpenCL.Query,+ module System.GPU.OpenCL.Context,+ module System.GPU.OpenCL.CommandQueue, + module System.GPU.OpenCL.Memory,+ module System.GPU.OpenCL.Event,+ module System.GPU.OpenCL.Program )+ where++-- -----------------------------------------------------------------------------+import System.GPU.OpenCL.Query+import System.GPU.OpenCL.Context+import System.GPU.OpenCL.CommandQueue+import System.GPU.OpenCL.Memory+import System.GPU.OpenCL.Event+import System.GPU.OpenCL.Program+import System.GPU.OpenCL.Types( + CLError(..), CLint, CLuint, CLulong )++-- -----------------------------------------------------------------------------
+ src/System/GPU/OpenCL/CommandQueue.chs view
@@ -0,0 +1,553 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+module System.GPU.OpenCL.CommandQueue(+ -- * Types+ CLCommandQueue, CLCommandQueueProperty(..), + -- * Command Queue Functions+ clCreateCommandQueue, clRetainCommandQueue, clReleaseCommandQueue,+ clGetCommandQueueContext, clGetCommandQueueDevice, + clGetCommandQueueReferenceCount, clGetCommandQueueProperties,+ clSetCommandQueueProperty,+ -- * Memory Commands+ clEnqueueReadBuffer, clEnqueueWriteBuffer,+ -- * Executing Kernels+ clEnqueueNDRangeKernel, clEnqueueTask, clEnqueueMarker, + clEnqueueWaitForEvents, clEnqueueBarrier,+ -- * Flush and Finish+ clFlush, clFinish+ ) where++-- -----------------------------------------------------------------------------+import Foreign+import Foreign.C.Types+import System.GPU.OpenCL.Types( + CLint, CLbool, CLuint, CLCommandQueueProperty_, CLCommandQueueInfo_, + CLError(..), CLCommandQueue, CLDeviceID, CLContext, CLCommandQueueProperty(..), + CLEvent, CLMem, CLKernel,+ wrapCheckSuccess, wrapPError, wrapGetInfo, getCLValue, getEnumCL,+ bitmaskToCommandQueueProperties, bitmaskFromFlags )++#include <CL/cl.h>++-- -----------------------------------------------------------------------------+foreign import ccall "clCreateCommandQueue" raw_clCreateCommandQueue :: + CLContext -> CLDeviceID -> CLCommandQueueProperty_ -> Ptr CLint -> IO CLCommandQueue+foreign import ccall "clRetainCommandQueue" raw_clRetainCommandQueue :: + CLCommandQueue -> IO CLint+foreign import ccall "clReleaseCommandQueue" raw_clReleaseCommandQueue :: + CLCommandQueue -> IO CLint+foreign import ccall "clGetCommandQueueInfo" raw_clGetCommandQueueInfo :: + CLCommandQueue -> CLCommandQueueInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint+foreign import ccall "clSetCommandQueueProperty" raw_clSetCommandQueueProperty :: + CLCommandQueue -> CLCommandQueueProperty_ -> CLbool -> Ptr CLCommandQueueProperty_ -> IO CLint+foreign import ccall "clEnqueueReadBuffer" raw_clEnqueueReadBuffer ::+ CLCommandQueue -> CLMem -> CLbool -> CSize -> CSize -> Ptr () -> CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint+foreign import ccall "clEnqueueWriteBuffer" raw_clEnqueueWriteBuffer ::+ CLCommandQueue -> CLMem -> CLbool -> CSize -> CSize -> Ptr () -> CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint+foreign import ccall "clEnqueueNDRangeKernel" raw_clEnqueueNDRangeKernel :: + CLCommandQueue -> CLKernel -> CLuint -> Ptr CSize -> Ptr CSize -> Ptr CSize -> CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint+foreign import ccall "clEnqueueTask" raw_clEnqueueTask :: + CLCommandQueue -> CLKernel -> CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint+foreign import ccall "clEnqueueMarker" raw_clEnqueueMarker :: + CLCommandQueue -> Ptr CLEvent -> IO CLint +foreign import ccall "clEnqueueWaitForEvents" raw_clEnqueueWaitForEvents :: + CLCommandQueue -> CLuint -> Ptr CLEvent -> IO CLint+foreign import ccall "clEnqueueBarrier" raw_clEnqueueBarrier :: + CLCommandQueue -> IO CLint +foreign import ccall "clFlush" raw_clFlush ::+ CLCommandQueue -> IO CLint+foreign import ccall "clFinish" raw_clFinish ::+ CLCommandQueue -> IO CLint++-- -----------------------------------------------------------------------------+{-| Create a command-queue on a specific device.++The OpenCL functions that are submitted to a command-queue are enqueued in the +order the calls are made but can be configured to execute in-order or +out-of-order. The properties argument in clCreateCommandQueue can be used to +specify the execution order.++If the 'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' property of a command-queue is +not set, the commands enqueued to a command-queue execute in order. For example, +if an application calls 'clEnqueueNDRangeKernel' to execute kernel A followed by +a 'clEnqueueNDRangeKernel' to execute kernel B, the application can assume that +kernel A finishes first and then kernel B is executed. If the memory objects +output by kernel A are inputs to kernel B then kernel B will see the correct +data in memory objects produced by execution of kernel A. If the +'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' property of a commandqueue is set, then +there is no guarantee that kernel A will finish before kernel B starts execution.++Applications can configure the commands enqueued to a command-queue to execute +out-of-order by setting the 'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' property of +the command-queue. This can be specified when the command-queue is created or +can be changed dynamically using 'clCreateCommandQueue'. In out-of-order +execution mode there is no guarantee that the enqueued commands will finish +execution in the order they were queued. As there is no guarantee that kernels +will be executed in order, i.e. based on when the 'clEnqueueNDRangeKernel' calls +are made within a command-queue, it is therefore possible that an earlier +'clEnqueueNDRangeKernel' call to execute kernel A identified by event A may +execute and/or finish later than a 'clEnqueueNDRangeKernel' call to execute +kernel B which was called by the application at a later point in time. To +guarantee a specific order of execution of kernels, a wait on a particular event +(in this case event A) can be used. The wait for event A can be specified in the +event_wait_list argument to 'clEnqueueNDRangeKernel' for kernel B.++In addition, a wait for events or a barrier command can be enqueued to the +command-queue. The wait for events command ensures that previously enqueued +commands identified by the list of events to wait for have finished before the +next batch of commands is executed. The barrier command ensures that all +previously enqueued commands in a command-queue have finished execution before +the next batch of commands is executed.++Similarly, commands to read, write, copy or map memory objects that are enqueued +after 'clEnqueueNDRangeKernel', 'clEnqueueTask' or 'clEnqueueNativeKernel' +commands are not guaranteed to wait for kernels scheduled for execution to have +completed (if the 'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' property is set). To +ensure correct ordering of commands, the event object returned by +'clEnqueueNDRangeKernel', 'clEnqueueTask' or 'clEnqueueNativeKernel' can be +used to enqueue a wait for event or a barrier command can be enqueued that must +complete before reads or writes to the memory object(s) occur.+-}+clCreateCommandQueue :: CLContext -> CLDeviceID -> [CLCommandQueueProperty] + -> IO (Either CLError CLCommandQueue)+clCreateCommandQueue ctx did xs = wrapPError $ \perr -> do+ raw_clCreateCommandQueue ctx did props perr+ where+ props = bitmaskFromFlags xs++{-| Increments the command_queue reference count. 'clCreateCommandQueue'+performs an implicit retain. This is very helpful for 3rd party libraries, which+typically get a command-queue passed to them by the application. However, it is+possible that the application may delete the command-queue without informing the+library. Allowing functions to attach to (i.e. retain) and release a+command-queue solves the problem of a command-queue being used by a library no+longer being valid. Returns 'True' if the function is executed successfully. It+returns 'False' if command_queue is not a valid command-queue. +-}+clRetainCommandQueue :: CLCommandQueue -> IO Bool+clRetainCommandQueue = wrapCheckSuccess . raw_clRetainCommandQueue++-- | Decrements the command_queue reference count.+-- After the command_queue reference count becomes zero and all commands queued +-- to command_queue have finished (e.g., kernel executions, memory object +-- updates, etc.), the command-queue is deleted.+-- Returns 'True' if the function is executed successfully. It returns 'False'+-- if command_queue is not a valid command-queue.+clReleaseCommandQueue :: CLCommandQueue -> IO Bool+clReleaseCommandQueue = wrapCheckSuccess . raw_clReleaseCommandQueue++#c+enum CLCommandQueueInfo {+ cL_QUEUE_CONTEXT=CL_QUEUE_CONTEXT,+ cL_QUEUE_DEVICE=CL_QUEUE_DEVICE,+ cL_QUEUE_REFERENCE_COUNT=CL_QUEUE_REFERENCE_COUNT,+ cL_QUEUE_PROPERTIES=CL_QUEUE_PROPERTIES,+ };+#endc+{#enum CLCommandQueueInfo {upcaseFirstLetter} #}++-- | Return the context specified when the command-queue is created.+clGetCommandQueueContext :: CLCommandQueue -> IO (Either CLError CLContext)+clGetCommandQueueContext cq = wrapGetInfo (\(dat :: Ptr CLContext) + -> raw_clGetCommandQueueInfo cq infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_QUEUE_CONTEXT+ size = fromIntegral $ sizeOf (nullPtr::CLContext)++-- | Return the device specified when the command-queue is created.+clGetCommandQueueDevice :: CLCommandQueue -> IO (Either CLError CLDeviceID)+clGetCommandQueueDevice cq = wrapGetInfo (\(dat :: Ptr CLDeviceID) + -> raw_clGetCommandQueueInfo cq infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_QUEUE_DEVICE+ size = fromIntegral $ sizeOf (nullPtr::CLDeviceID)++-- | Return the command-queue reference count.+-- The reference count returned should be considered immediately stale. It is +-- unsuitable for general use in applications. This feature is provided for +-- identifying memory leaks.+clGetCommandQueueReferenceCount :: CLCommandQueue -> IO (Either CLError CLuint)+clGetCommandQueueReferenceCount cq = wrapGetInfo (\(dat :: Ptr CLuint) + -> raw_clGetCommandQueueInfo cq infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_QUEUE_REFERENCE_COUNT+ size = fromIntegral $ sizeOf (0::CLuint)+++-- | Return the currently specified properties for the command-queue. These +-- properties are specified by the properties argument in 'clCreateCommandQueue'+-- , and can be changed by 'clSetCommandQueueProperty'.+clGetCommandQueueProperties :: CLCommandQueue -> IO (Either CLError [CLCommandQueueProperty])+clGetCommandQueueProperties cq = wrapGetInfo (\(dat :: Ptr CLCommandQueueProperty_) + -> raw_clGetCommandQueueInfo cq infoid size (castPtr dat)) bitmaskToCommandQueueProperties+ where + infoid = getCLValue CL_QUEUE_PROPERTIES+ size = fromIntegral $ sizeOf (0::CLCommandQueueProperty_)++{-| Enable or disable the properties of a command-queue. Returns the+command-queue properties before they were changed by+'clSetCommandQueueProperty'. As specified for 'clCreateCommandQueue', the+'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' command-queue property determines+whether the commands in a command-queue are executed in-order or+out-of-order. Changing this command-queue property will cause the OpenCL+implementation to block until all previously queued commands in command_queue+have completed. This can be an expensive operation and therefore changes to the+'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' property should be only done when+absolutely necessary.++ It is possible that a device(s) becomes unavailable after a context and+command-queues that use this device(s) have been created and commands have been+queued to command-queues. In this case the behavior of OpenCL API calls that use+this context (and command-queues) are considered to be+implementation-defined. The user callback function, if specified when the+context is created, can be used to record appropriate information when the+device becomes unavailable.+-}+clSetCommandQueueProperty :: CLCommandQueue -> [CLCommandQueueProperty] -> Bool + -> IO (Either CLError [CLCommandQueueProperty])+clSetCommandQueueProperty cq xs val = alloca $ \(dat :: Ptr CLCommandQueueProperty_) -> do+ errcode <- raw_clSetCommandQueueProperty cq props (fromBool val) dat+ if errcode == getCLValue CL_SUCCESS+ then fmap (Right . bitmaskToCommandQueueProperties) $ peek dat+ else return . Left . getEnumCL $ errcode+ where+ props = bitmaskFromFlags xs++-- -----------------------------------------------------------------------------+clEnqueue :: (CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint) -> [CLEvent] + -> IO (Either CLError CLEvent)+clEnqueue f [] = alloca $ \event -> do+ errcode <- f 0 nullPtr event+ if errcode == getCLValue CL_SUCCESS+ then fmap Right $ peek event+ else return . Left . getEnumCL $ errcode+clEnqueue f events = allocaArray nevents $ \pevents -> do+ pokeArray pevents events+ alloca $ \event -> do+ errcode <- f cnevents pevents event+ if errcode == getCLValue CL_SUCCESS+ then fmap Right $ peek event+ else return . Left . getEnumCL $ errcode+ where+ nevents = length events+ cnevents = fromIntegral nevents++-- -----------------------------------------------------------------------------+{-| Enqueue commands to read from a buffer object to host memory. Calling+clEnqueueReadBuffer to read a region of the buffer object with the ptr argument+value set to host_ptr + offset, where host_ptr is a pointer to the memory region+specified when the buffer object being read is created with+'CL_MEM_USE_HOST_PTR', must meet the following requirements in order to avoid+undefined behavior:++ * All commands that use this buffer object have finished execution before the+read command begins execution++ * The buffer object is not mapped++ * The buffer object is not used by any command-queue until the read command has+finished execution Errors++'clEnqueueReadBuffer' returns the event if the function is executed+successfully. Otherwise, it returns one of the following errors:++ * 'CL_INVALID_COMMAND_QUEUE' if command_queue is not a valid command-queue.++ * 'CL_INVALID_CONTEXT' if the context associated with command_queue and buffer+are not the same or if the context associated with command_queue and events in+event_wait_list are not the same.++ * 'CL_INVALID_MEM_OBJECT' if buffer is not a valid buffer object.++ * 'CL_INVALID_VALUE' if the region being read specified by (offset, cb) is out+of bounds or if ptr is a NULL value.++ * 'CL_INVALID_EVENT_WAIT_LIST' if event_wait_list is NULL and+num_events_in_wait_list greater than 0, or event_wait_list is not NULL and+num_events_in_wait_list is 0, or if event objects in event_wait_list are not+valid events.++ * 'CL_MEM_OBJECT_ALLOCATION_FAILURE' if there is a failure to allocate memory+for data store associated with buffer.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host.+-}+clEnqueueReadBuffer :: Integral a => CLCommandQueue -> CLMem -> Bool -> a -> a+ -> Ptr () -> [CLEvent] -> IO (Either CLError CLEvent)+clEnqueueReadBuffer cq mem check off size dat = clEnqueue (raw_clEnqueueReadBuffer cq mem (fromBool check) (fromIntegral off) (fromIntegral size) dat)++{-| Enqueue commands to write to a buffer object from host memory.Calling+clEnqueueWriteBuffer to update the latest bits in a region of the buffer object+with the ptr argument value set to host_ptr + offset, where host_ptr is a+pointer to the memory region specified when the buffer object being written is+created with 'CL_MEM_USE_HOST_PTR', must meet the following requirements in+order to avoid undefined behavior:++ * The host memory region given by (host_ptr + offset, cb) contains the latest+bits when the enqueued write command begins execution.++ * The buffer object is not mapped.++ * The buffer object is not used by any command-queue until the write command+has finished execution.++'clEnqueueWriteBuffer' returns the Event if the function is executed+successfully. Otherwise, it returns one of the following errors:++ * 'CL_INVALID_COMMAND_QUEUE' if command_queue is not a valid command-queue.++ * 'CL_INVALID_CONTEXT' if the context associated with command_queue and buffer+are not the same or if the context associated with command_queue and events in+event_wait_list are not the same.++ * 'CL_INVALID_MEM_OBJECT' if buffer is not a valid buffer object.++ * 'CL_INVALID_VALUE' if the region being written specified by (offset, cb) is+out of bounds or if ptr is a NULL value.++ * 'CL_INVALID_EVENT_WAIT_LIST' if event_wait_list is NULL and+num_events_in_wait_list greater than 0, or event_wait_list is not NULL and+num_events_in_wait_list is 0, or if event objects in event_wait_list are not+valid events.++ * 'CL_MEM_OBJECT_ALLOCATION_FAILURE' if there is a failure to allocate memory+for data store associated with buffer.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host.+-}+clEnqueueWriteBuffer :: Integral a => CLCommandQueue -> CLMem -> Bool -> a -> a+ -> Ptr () -> [CLEvent] -> IO (Either CLError CLEvent)+clEnqueueWriteBuffer cq mem check off size dat = clEnqueue (raw_clEnqueueWriteBuffer cq mem (fromBool check) (fromIntegral off) (fromIntegral size) dat)++-- -----------------------------------------------------------------------------+{-| Enqueues a command to execute a kernel on a device. Each work-item is+uniquely identified by a global identifier. The global ID, which can be read+inside the kernel, is computed using the value given by global_work_size and+global_work_offset. In OpenCL 1.0, the starting global ID is always (0, 0,+... 0). In addition, a work-item is also identified within a work-group by a+unique local ID. The local ID, which can also be read by the kernel, is computed+using the value given by local_work_size. The starting local ID is always (0, 0,+... 0).++Returns the event if the kernel execution was successfully queued. Otherwise, it+returns one of the following errors:++ * 'CL_INVALID_PROGRAM_EXECUTABLE' if there is no successfully built program+executable available for device associated with command_queue.++ * 'CL_INVALID_COMMAND_QUEUE' if command_queue is not a valid command-queue.++ * 'CL_INVALID_KERNEL' if kernel is not a valid kernel object.++ * 'CL_INVALID_CONTEXT' if context associated with command_queue and kernel is+not the same or if the context associated with command_queue and events in+event_wait_list are not the same.++ * 'CL_INVALID_KERNEL_ARGS' if the kernel argument values have not been+specified.++ * 'CL_INVALID_WORK_DIMENSION' if work_dim is not a valid value (i.e. a value+between 1 and 3).++ * 'CL_INVALID_WORK_GROUP_SIZE' if local_work_size is specified and number of+work-items specified by global_work_size is not evenly divisable by size of+work-group given by local_work_size or does not match the work-group size+specified for kernel using the __attribute__((reqd_work_group_size(X, Y, Z)))+qualifier in program source.++ * 'CL_INVALID_WORK_GROUP_SIZE' if local_work_size is specified and the total+number of work-items in the work-group computed as local_work_size[0]+*... local_work_size[work_dim - 1] is greater than the value specified by+'CL_DEVICE_MAX_WORK_GROUP_SIZE' in the table of OpenCL Device Queries for+clGetDeviceInfo.++ * 'CL_INVALID_WORK_GROUP_SIZE' if local_work_size is NULL and the+__attribute__((reqd_work_group_size(X, Y, Z))) qualifier is used to declare the+work-group size for kernel in the program source.++ * 'CL_INVALID_WORK_ITEM_SIZE' if the number of work-items specified in any of+local_work_size[0], ... local_work_size[work_dim - 1] is greater than the+corresponding values specified by 'CL_DEVICE_MAX_WORK_ITEM_SIZES'[0],+.... 'CL_DEVICE_MAX_WORK_ITEM_SIZES'[work_dim - 1].++ * 'CL_OUT_OF_RESOURCES' if there is a failure to queue the execution instance+of kernel on the command-queue because of insufficient resources needed to+execute the kernel. For example, the explicitly specified local_work_size causes+a failure to execute the kernel because of insufficient resources such as+registers or local memory. Another example would be the number of read-only+image args used in kernel exceed the 'CL_DEVICE_MAX_READ_IMAGE_ARGS' value for+device or the number of write-only image args used in kernel exceed the+'CL_DEVICE_MAX_WRITE_IMAGE_ARGS' value for device or the number of samplers used+in kernel exceed 'CL_DEVICE_MAX_SAMPLERS' for device.++ * 'CL_MEM_OBJECT_ALLOCATION_FAILURE' if there is a failure to allocate memory for data store associated with image or buffer objects specified as arguments to kernel.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required by+the OpenCL implementation on the host.+-}+clEnqueueNDRangeKernel :: Integral a => CLCommandQueue -> CLKernel -> [a] -> [a] -> [CLEvent] -> IO (Either CLError CLEvent)+clEnqueueNDRangeKernel cq krn gws lws events = withArray (map fromIntegral gws) $ \pgws -> withArray (map fromIntegral lws) $ \plws -> do+ clEnqueue (raw_clEnqueueNDRangeKernel cq krn num nullPtr pgws plws) events+ where+ num = fromIntegral $ length gws+ +{-| Enqueues a command to execute a kernel on a device. The kernel is executed+using a single work-item.++'clEnqueueTask' is equivalent to calling 'clEnqueueNDRangeKernel' with work_dim+= 1, global_work_offset = [], global_work_size[0] set to 1, and+local_work_size[0] set to 1.++Returns the evens if the kernel execution was successfully queued, or one of the+errors below:++ * 'CL_INVALID_PROGRAM_EXECUTABLE' if there is no successfully built program+executable available for device associated with command_queue.++ * 'CL_INVALID_COMMAND_QUEUE if' command_queue is not a valid command-queue.++ * 'CL_INVALID_KERNEL' if kernel is not a valid kernel object.++ * 'CL_INVALID_CONTEXT' if context associated with command_queue and kernel is+not the same or if the context associated with command_queue and events in+event_wait_list are not the same.++ * 'CL_INVALID_KERNEL_ARGS' if the kernel argument values have not been specified.++ * 'CL_INVALID_WORK_GROUP_SIZE' if a work-group size is specified for kernel+using the __attribute__((reqd_work_group_size(X, Y, Z))) qualifier in program+source and is not (1, 1, 1).++ * 'CL_OUT_OF_RESOURCES' if there is a failure to queue the execution instance+of kernel on the command-queue because of insufficient resources needed to+execute the kernel.++ * 'CL_MEM_OBJECT_ALLOCATION_FAILURE' if there is a failure to allocate memory+for data store associated with image or buffer objects specified as arguments to+kernel.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host.+-}+clEnqueueTask :: CLCommandQueue -> CLKernel -> [CLEvent] + -> IO (Either CLError CLEvent)+clEnqueueTask cq krn = clEnqueue (raw_clEnqueueTask cq krn)+ +-- -----------------------------------------------------------------------------+-- | Enqueues a marker command to command_queue. The marker command returns an+-- event which can be used to queue a wait on this marker event i.e. wait for+-- all commands queued before the marker command to complete. Returns the event+-- if the function is successfully executed. It returns+-- 'CL_INVALID_COMMAND_QUEUE' if command_queue is not a valid command-queue and+-- returns 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources+-- required by the OpenCL implementation on the host.+clEnqueueMarker :: CLCommandQueue -> IO (Either CLError CLEvent)+clEnqueueMarker cq = alloca $ \event -> do+ errcode <- raw_clEnqueueMarker cq event+ if errcode == getCLValue CL_SUCCESS+ then fmap Right $ peek event+ else return . Left . getEnumCL $ errcode+ +{-| Enqueues a wait for a specific event or a list of events to complete before+any future commands queued in the command-queue are executed. The context+associated with events in event_list and command_queue must be the same.++Returns one of the errors below when fails:++ * 'CL_INVALID_COMMAND_QUEUE' if command_queue is not a valid command-queue.++ * 'CL_INVALID_CONTEXT' if the context associated with command_queue and events+in event_list are not the same.++ * 'CL_INVALID_VALUE' if num_events is zero.++ * 'CL_INVALID_EVENT' if event objects specified in event_list are not valid+events.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host.+-}+clEnqueueWaitForEvents :: CLCommandQueue -> [CLEvent] -> IO (Either CLError ())+clEnqueueWaitForEvents cq [] = do+ errcode <- raw_clEnqueueWaitForEvents cq 0 nullPtr+ if errcode == getCLValue CL_SUCCESS+ then return $ Right ()+ else return . Left . getEnumCL $ errcode+clEnqueueWaitForEvents cq events = allocaArray nevents $ \pevents -> do+ pokeArray pevents events+ errcode <- raw_clEnqueueWaitForEvents cq cnevents pevents+ if errcode == getCLValue CL_SUCCESS+ then return $ Right ()+ else return . Left . getEnumCL $ errcode+ where+ nevents = length events+ cnevents = fromIntegral nevents++-- | 'clEnqueueBarrier' is a synchronization point that ensures that all queued+-- commands in command_queue have finished execution before the next batch of+-- commands can begin execution. It returns 'CL_INVALID_COMMAND_QUEUE' if+-- command_queue is not a valid command-queue and returns+-- 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+-- by the OpenCL implementation on the host.+clEnqueueBarrier :: CLCommandQueue -> IO (Either CLError ())+clEnqueueBarrier cq = do+ errcode <- raw_clEnqueueBarrier cq+ if errcode == getCLValue CL_SUCCESS+ then return $ Right ()+ else return . Left . getEnumCL $ errcode+ +-- -----------------------------------------------------------------------------+{-| Issues all previously queued OpenCL commands in a command-queue to the+device associated with the command-queue. 'clFlush' only guarantees that all+queued commands to command_queue get issued to the appropriate device. There is+no guarantee that they will be complete after 'clFlush' returns.++ 'clFlush' returns 'True' if the function call was executed successfully. It+returns 'False' if command_queue is not a valid command-queue or if there is a+failure to allocate resources required by the OpenCL implementation on the host.++ Any blocking commands queued in a command-queue such as 'clEnqueueReadImage' or+'clEnqueueReadBuffer' with blocking_read set to 'True', 'clEnqueueWriteImage' or+'clEnqueueWriteBuffer' with blocking_write set to 'True', 'clEnqueueMapImage' or+'clEnqueueMapBuffer' with blocking_map set to 'True' or 'clWaitForEvents'+perform an implicit flush of the command-queue.++ To use event objects that refer to commands enqueued in a command-queue as+event objects to wait on by commands enqueued in a different command-queue, the+application must call a 'clFlush' or any blocking commands that perform an+implicit flush of the command-queue where the commands that refer to these event+objects are enqueued.+-}+clFlush :: CLCommandQueue -> IO Bool+clFlush = wrapCheckSuccess . raw_clFlush+ +-- | Blocks until all previously queued OpenCL commands in a command-queue are +-- issued to the associated device and have completed.+-- 'clFinish' does not return until all queued commands in command_queue have +-- been processed and completed. 'clFinish' is also a synchronization point.+--+-- 'clFinish' returns 'True' if the function call was executed successfully. It +-- returns 'False' if command_queue is not a valid command-queue or if there is +-- a failure to allocate resources required by the OpenCL implementation on the +-- host.+clFinish :: CLCommandQueue -> IO Bool+clFinish = wrapCheckSuccess . raw_clFinish+ +-- -----------------------------------------------------------------------------
+ src/System/GPU/OpenCL/Context.chs view
@@ -0,0 +1,150 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+module System.GPU.OpenCL.Context(+ -- * Types+ CLContext,+ -- * Context Functions+ clCreateContext, clCreateContextFromType, clRetainContext, clReleaseContext,+ clGetContextReferenceCount, clGetContextDevices )+ where++-- -----------------------------------------------------------------------------+import Foreign( + Ptr, FunPtr, nullPtr, castPtr, alloca, allocaArray, peek, peekArray, + pokeArray )+import Foreign.C.Types( CSize )+import Foreign.C.String( CString, peekCString )+import Foreign.Storable( sizeOf )+import System.GPU.OpenCL.Types( + CLuint, CLint, CLDeviceType_, CLContextInfo_, CLContextProperty_, CLDeviceID, + CLContext, CLDeviceType, CLError(..), bitmaskFromFlags, getCLValue, getEnumCL, + wrapCheckSuccess, wrapPError, wrapGetInfo )++#include <CL/cl.h>++-- -----------------------------------------------------------------------------+type ContextCallback = CString -> Ptr () -> CSize -> Ptr () -> IO ()+foreign import ccall "wrapper" wrapContextCallback :: + ContextCallback -> IO (FunPtr ContextCallback)+foreign import ccall "clCreateContext" raw_clCreateContext ::+ Ptr CLContextProperty_ -> CLuint -> Ptr CLDeviceID -> FunPtr ContextCallback -> + Ptr () -> Ptr CLint -> IO CLContext+foreign import ccall "clCreateContextFromType" raw_clCreateContextFromType :: + Ptr CLContextProperty_ -> CLDeviceType_ -> FunPtr ContextCallback -> + Ptr () -> Ptr CLint -> IO CLContext+foreign import ccall "clRetainContext" raw_clRetainContext :: + CLContext -> IO CLint+foreign import ccall "clReleaseContext" raw_clReleaseContext :: + CLContext -> IO CLint+foreign import ccall "clGetContextInfo" raw_clGetContextInfo :: + CLContext -> CLContextInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint++-- -----------------------------------------------------------------------------+mkContextCallback :: (String -> IO ()) -> ContextCallback+mkContextCallback f msg _ _ _ = peekCString msg >>= f++-- | Creates an OpenCL context.+-- An OpenCL context is created with one or more devices. Contexts are used by +-- the OpenCL runtime for managing objects such as command-queues, memory, +-- program and kernel objects and for executing kernels on one or more devices +-- specified in the context.+clCreateContext :: [CLDeviceID] -> (String -> IO ()) + -> IO (Either CLError CLContext)+clCreateContext devs f = allocaArray ndevs $ \pdevs -> do+ pokeArray pdevs devs+ wrapPError $ \perr -> do+ fptr <- wrapContextCallback $ mkContextCallback f+ raw_clCreateContext nullPtr cndevs pdevs fptr nullPtr perr+ where+ ndevs = length devs+ cndevs = fromIntegral ndevs++-- | Create an OpenCL context from a device type that identifies the specific +-- device(s) to use.+clCreateContextFromType :: [CLDeviceType] -> (String -> IO ()) + -> IO (Either CLError CLContext)+clCreateContextFromType xs f = wrapPError $ \perr -> do+ fptr <- wrapContextCallback $ mkContextCallback f+ raw_clCreateContextFromType nullPtr types fptr nullPtr perr+ where+ types = bitmaskFromFlags xs++-- | Increment the context reference count.+-- 'clCreateContext' and 'clCreateContextFromType' perform an implicit retain. +-- This is very helpful for 3rd party libraries, which typically get a context +-- passed to them by the application. However, it is possible that the +-- application may delete the context without informing the library. Allowing +-- functions to attach to (i.e. retain) and release a context solves the +-- problem of a context being used by a library no longer being valid.+-- Returns 'True' if the function is executed successfully, or 'False' if +-- context is not a valid OpenCL context.+clRetainContext :: CLContext -> IO Bool+clRetainContext ctx = wrapCheckSuccess $ raw_clRetainContext ctx ++-- | Decrement the context reference count.+-- After the context reference count becomes zero and all the objects attached +-- to context (such as memory objects, command-queues) are released, the +-- context is deleted.+-- Returns 'True' if the function is executed successfully, or 'False' if +-- context is not a valid OpenCL context.+clReleaseContext :: CLContext -> IO Bool+clReleaseContext ctx = wrapCheckSuccess $ raw_clReleaseContext ctx ++getContextInfoSize :: CLContext -> CLContextInfo_ -> IO (Either CLError CSize)+getContextInfoSize ctx infoid = alloca $ \(value_size :: Ptr CSize) -> do+ errcode <- raw_clGetContextInfo ctx infoid 0 nullPtr value_size+ if errcode == getCLValue CL_SUCCESS+ then fmap Right $ peek value_size+ else return . Left . getEnumCL $ errcode++#c+enum CLContextInfo {+ cL_CONTEXT_REFERENCE_COUNT=CL_CONTEXT_REFERENCE_COUNT,+ cL_CONTEXT_DEVICES=CL_CONTEXT_DEVICES,+ cL_CONTEXT_PROPERTIES=CL_CONTEXT_PROPERTIES+ };+#endc+{#enum CLContextInfo {upcaseFirstLetter} #}++-- | Return the context reference count. The reference count returned should be +-- considered immediately stale. It is unsuitable for general use in +-- applications. This feature is provided for identifying memory leaks.+clGetContextReferenceCount :: CLContext -> IO (Either CLError CLuint)+clGetContextReferenceCount ctx = wrapGetInfo (\(dat :: Ptr CLuint) + -> raw_clGetContextInfo ctx infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_CONTEXT_REFERENCE_COUNT+ size = fromIntegral $ sizeOf (0::CLuint)++-- | Return the list of devices in context.+clGetContextDevices :: CLContext -> IO (Either CLError [CLDeviceID])+clGetContextDevices ctx = do+ val <- getContextInfoSize ctx infoid+ case val of+ Left err -> return . Left $ err+ Right size -> let n = (fromIntegral size) `div` elemSize+ in allocaArray n $ \(buff :: Ptr CLDeviceID) -> do+ errcode <- raw_clGetContextInfo ctx infoid size (castPtr buff) nullPtr+ if errcode == getCLValue CL_SUCCESS+ then fmap Right $ peekArray n buff+ else return . Left . getEnumCL $ errcode+ where+ infoid = getCLValue CL_CONTEXT_DEVICES+ elemSize = sizeOf (nullPtr :: CLDeviceID)++-- -----------------------------------------------------------------------------
+ src/System/GPU/OpenCL/Event.chs view
@@ -0,0 +1,158 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+module System.GPU.OpenCL.Event( + -- * Types+ CLEvent, CLCommandType(..), CLProfilingInfo(..), CLCommandExecutionStatus(..),+ -- * Functions+ clWaitForEvents, clRetainEvent, clReleaseEvent, clGetEventCommandQueue, + clGetEventCommandType, clGetEventReferenceCount, + clGetEventCommandExecutionStatus, clGetEventProfilingInfo+ ) where++-- -----------------------------------------------------------------------------+import Foreign+import Foreign.C.Types+import System.GPU.OpenCL.Types( + CLEvent, CLint, CLuint, CLulong, CLEventInfo_, CLProfilingInfo_, CLError(..),+ CLCommandQueue, CLCommandType(..), CLCommandType_, + CLCommandExecutionStatus(..), CLProfilingInfo(..), getCommandExecutionStatus, + getCLValue, getEnumCL, wrapCheckSuccess, wrapGetInfo )++#include <CL/cl.h>++-- -----------------------------------------------------------------------------+foreign import ccall "clWaitForEvents" raw_clWaitForEvents :: + CLuint -> Ptr CLEvent -> IO CLint+foreign import ccall "clGetEventInfo" raw_clGetEventInfo :: + CLEvent -> CLEventInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint+foreign import ccall "clRetainEvent" raw_clRetainEvent :: + CLEvent -> IO CLint +foreign import ccall "clReleaseEvent" raw_clReleaseEvent :: + CLEvent -> IO CLint +foreign import ccall "clGetEventProfilingInfo" raw_clGetEventProfilingInfo :: + CLEvent -> CLProfilingInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint++-- -----------------------------------------------------------------------------+-- | Waits on the host thread for commands identified by event objects in +-- event_list to complete. A command is considered complete if its execution +-- status is 'CL_COMPLETE' or a negative value.+-- Returns 'True' if the function was executed successfully. It returns 'False'+-- if the list of events is empty, or if events specified in event_list do not +-- belong to the same context, or if event objects specified in event_list are +-- not valid event objects.+clWaitForEvents :: [CLEvent] -> IO Bool+clWaitForEvents [] = return False+clWaitForEvents xs = allocaArray nevents $ \pevents -> do+ pokeArray pevents xs+ wrapCheckSuccess $ raw_clWaitForEvents (fromIntegral nevents) pevents+ where+ nevents = length xs+ +-- | Increments the event reference count.+-- The OpenCL commands that return an event perform an implicit retain.+-- Returns 'True' if the function is executed successfully. It returns 'False' +-- if event is not a valid event object.+clRetainEvent :: CLEvent -> IO Bool+clRetainEvent ev = wrapCheckSuccess $ raw_clRetainEvent ev++-- | Decrements the event reference count.+-- Decrements the event reference count. The event object is deleted once the +-- reference count becomes zero, the specific command identified by this event +-- has completed (or terminated) and there are no commands in the command-queues +-- of a context that require a wait for this event to complete.+-- Returns 'True' if the function is executed successfully. It returns 'False' +-- if event is not a valid event object.+clReleaseEvent :: CLEvent -> IO Bool+clReleaseEvent ev = wrapCheckSuccess $ raw_clReleaseEvent ev++#c+enum CLEventInfo {+ cL_EVENT_COMMAND_QUEUE=CL_EVENT_COMMAND_QUEUE,+ cL_EVENT_COMMAND_TYPE=CL_EVENT_COMMAND_TYPE,+ cL_EVENT_COMMAND_EXECUTION_STATUS=CL_EVENT_COMMAND_EXECUTION_STATUS,+ cL_EVENT_REFERENCE_COUNT=CL_EVENT_REFERENCE_COUNT+ };+#endc+{#enum CLEventInfo {upcaseFirstLetter} #}+++-- | Return the command-queue associated with event.+clGetEventCommandQueue :: CLEvent -> IO (Either CLError CLCommandQueue)+clGetEventCommandQueue ev = wrapGetInfo (\(dat :: Ptr CLCommandQueue) + -> raw_clGetEventInfo ev infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_EVENT_COMMAND_QUEUE+ size = fromIntegral $ sizeOf (nullPtr::CLCommandQueue)+ +-- | Return the command associated with event.+clGetEventCommandType :: CLEvent -> IO (Either CLError CLCommandType)+clGetEventCommandType ev = wrapGetInfo (\(dat :: Ptr CLCommandType_) + -> raw_clGetEventInfo ev infoid size (castPtr dat)) getEnumCL+ where + infoid = getCLValue CL_EVENT_COMMAND_TYPE+ size = fromIntegral $ sizeOf (0::CLCommandType_)+ +-- | Return the event reference count. The reference count returned should be +-- considered immediately stale. It is unsuitable for general use in applications. +-- This feature is provided for identifying memory leaks.+clGetEventReferenceCount :: CLEvent -> IO (Either CLError CLint)+clGetEventReferenceCount ev = wrapGetInfo (\(dat :: Ptr CLint) + -> raw_clGetEventInfo ev infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_EVENT_REFERENCE_COUNT+ size = fromIntegral $ sizeOf (0::CLint)++-- | Return the execution status of the command identified by event.+clGetEventCommandExecutionStatus :: CLEvent -> IO (Either CLError CLCommandExecutionStatus)+clGetEventCommandExecutionStatus ev = wrapGetInfo (\(dat :: Ptr CLint) + -> raw_clGetEventInfo ev infoid size (castPtr dat)) getCommandExecutionStatus+ where + infoid = getCLValue CL_EVENT_COMMAND_EXECUTION_STATUS+ size = fromIntegral $ sizeOf (0::CLint)+ +{-| Returns profiling information for the command associated with event if +profiling is enabled. The unsigned 64-bit values returned can be used to measure +the time in nano-seconds consumed by OpenCL commands.++OpenCL devices are required to correctly track time across changes in device +frequency and power states. The 'CL_DEVICE_PROFILING_TIMER_RESOLUTION' specifies +the resolution of the timer i.e. the number of nanoseconds elapsed before the +timer is incremented.++Event objects can be used to capture profiling information that measure +execution time of a command. Profiling of OpenCL commands can be enabled either +by using a command-queue created with 'CL_QUEUE_PROFILING_ENABLE' flag set in +properties argument to clCreateCommandQueue or by setting the +'CL_QUEUE_PROFILING_ENABLE' flag in properties argument to +'clSetCommandQueueProperty'.++'clGetEventProfilingInfo' returns the valueif the function is executed +successfully and the profiling information has been recorded, and returns +'Nothing' if the 'CL_QUEUE_PROFILING_ENABLE' flag is not set for the +command-queue and if the profiling information is currently not available +(because the command identified by event has not completed), or if event is a +not a valid event object.+-} +clGetEventProfilingInfo :: CLEvent -> CLProfilingInfo -> IO (Either CLError CLulong)+clGetEventProfilingInfo ev prof = wrapGetInfo (\(dat :: Ptr CLulong) + -> raw_clGetEventProfilingInfo ev infoid size (castPtr dat)) id+ where + infoid = getCLValue prof+ size = fromIntegral $ sizeOf (0::CLulong)++-- -----------------------------------------------------------------------------
+ src/System/GPU/OpenCL/Memory.chs view
@@ -0,0 +1,286 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+module System.GPU.OpenCL.Memory(+ -- * Types+ CLMem, CLSampler, CLMemFlag(..), CLMemObjectType(..), CLAddressingMode(..), + CLFilterMode(..),+ -- * Memory Functions+ clCreateBuffer, clRetainMemObject, clReleaseMemObject, clGetMemType, + clGetMemFlags, clGetMemSize, clGetMemHostPtr, clGetMemMapCount, + clGetMemReferenceCount, clGetMemContext,+ -- * Sampler Functions+ clCreateSampler, clRetainSampler, clReleaseSampler, clGetSamplerReferenceCount, + clGetSamplerContext, clGetSamplerAddressingMode, clGetSamplerFilterMode, + clGetSamplerNormalizedCoords+ ) where++-- -----------------------------------------------------------------------------+import Foreign+import Foreign.C.Types+import System.GPU.OpenCL.Types( + CLMem, CLContext, CLSampler, CLint, CLuint, CLbool, CLMemFlags_, CLError(..), + CLMemInfo_, CLAddressingMode_, CLFilterMode_, CLSamplerInfo_, + CLAddressingMode(..), CLFilterMode(..), CLMemFlag(..), CLMemObjectType_, + CLMemObjectType(..), + wrapPError, wrapCheckSuccess, wrapGetInfo, getEnumCL, bitmaskFromFlags, + bitmaskToMemFlags, getCLValue )++#include <CL/cl.h>++-- -----------------------------------------------------------------------------+foreign import ccall "clCreateBuffer" raw_clCreateBuffer :: + CLContext -> CLMemFlags_ -> CSize -> Ptr () -> Ptr CLint -> IO CLMem+--foreign import ccall "clCreateImage2D" raw_clCreateImage2D :: +-- CLContext -> CLMemFlags_ -> CLImageFormat_p -> CSize -> CSize -> CSize +-- -> Ptr () -> Ptr CLint -> IO CLMem+--foreign import ccall "clCreateImage3D" raw_clCreateImage3D :: +-- CLContext -> CLMemFlags_-> CLImageFormat_p -> CSize -> CSize -> CSize -> CSize +-- -> CSize -> Ptr () -> Ptr CLint -> IO CLMem+foreign import ccall "clRetainMemObject" raw_clRetainMemObject :: + CLMem -> IO CLint+foreign import ccall "clReleaseMemObject" raw_clReleaseMemObject :: + CLMem -> IO CLint+--foreign import ccall "clGetSupportedImageFormats" raw_clGetSupportedImageFormats :: +-- CLContext -> CLMemFlags_ -> CLMemObjectType_ -> CLuint -> CLImageFormat_p +-- -> Ptr CLuint -> IO CLint+foreign import ccall "clGetMemObjectInfo" raw_clGetMemObjectInfo :: + CLMem -> CLMemInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint+--foreign import ccall "clGetImageInfo" raw_clGetImageInfo :: +-- CLMem -> CLImageInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint+foreign import ccall "clCreateSampler" raw_clCreateSampler :: + CLContext -> CLbool -> CLAddressingMode_ -> CLFilterMode_ -> Ptr CLint -> IO CLSampler+foreign import ccall "clRetainSampler" raw_clRetainSampler :: + CLSampler -> IO CLint+foreign import ccall "clReleaseSampler" raw_clReleaseSampler :: + CLSampler -> IO CLint+foreign import ccall "clGetSamplerInfo" raw_clGetSamplerInfo :: + CLSampler -> CLSamplerInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint++-- -----------------------------------------------------------------------------+{-| Creates a buffer object. Returns a valid non-zero buffer object if the+buffer object is created successfully. Otherwise, it returns: ++ * 'CL_INVALID_CONTEXT' if context is not a valid context.++ * 'CL_INVALID_VALUE' if values specified in flags are not valid.++ * 'CL_INVALID_BUFFER_SIZE' if size is 0 or is greater than+'clDeviceMaxMemAllocSize' value for all devices in context.++ * 'CL_INVALID_HOST_PTR' if host_ptr is NULL and 'CL_MEM_USE_HOST_PTR' or+'CL_MEM_COPY_HOST_PTR' are set in flags or if host_ptr is not NULL but+'CL_MEM_COPY_HOST_PTR' or 'CL_MEM_USE_HOST_PTR' are not set in flags.++ * 'CL_MEM_OBJECT_ALLOCATION_FAILURE' if there is a failure to allocate memory+for buffer object.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host.+-}+clCreateBuffer :: Integral a => CLContext -> [CLMemFlag] -> (a, Ptr ()) -> IO (Either CLError CLMem)+clCreateBuffer ctx xs (sbuff,buff) = wrapPError $ \perr -> do+ raw_clCreateBuffer ctx flags (fromIntegral sbuff) buff perr+ where+ flags = bitmaskFromFlags xs+ +-- | Increments the memory object reference count. returns 'True' if the+-- function is executed successfully. After the memobj reference count becomes+-- zero and commands queued for execution on a command-queue(s) that use memobj+-- have finished, the memory object is deleted. It returns 'False' if memobj is+-- not a valid memory object.+clRetainMemObject :: CLMem -> IO Bool+clRetainMemObject mem = wrapCheckSuccess $ raw_clRetainMemObject mem++-- | Decrements the memory object reference count. After the memobj reference+-- count becomes zero and commands queued for execution on a command-queue(s)+-- that use memobj have finished, the memory object is deleted. Returns 'True'+-- if the function is executed successfully. It returns 'False' if memobj is not+-- a valid memory object.+clReleaseMemObject :: CLMem -> IO Bool+clReleaseMemObject mem = wrapCheckSuccess $ raw_clReleaseMemObject mem++#c+enum CLMemInfo {+ cL_MEM_TYPE=CL_MEM_TYPE,+ cL_MEM_FLAGS=CL_MEM_FLAGS,+ cL_MEM_SIZE=CL_MEM_SIZE,+ cL_MEM_HOST_PTR=CL_MEM_HOST_PTR,+ cL_MEM_MAP_COUNT=CL_MEM_MAP_COUNT,+ cL_MEM_REFERENCE_COUNT=CL_MEM_REFERENCE_COUNT,+ cL_MEM_CONTEXT=CL_MEM_CONTEXT,+ };+#endc+{#enum CLMemInfo {upcaseFirstLetter} #}++-- | Returns the mem object type.+clGetMemType :: CLMem -> IO (Either CLError CLMemObjectType)+clGetMemType mem = wrapGetInfo (\(dat :: Ptr CLMemObjectType_) + -> raw_clGetMemObjectInfo mem infoid size (castPtr dat)) getEnumCL+ where + infoid = getCLValue CL_MEM_TYPE+ size = fromIntegral $ sizeOf (0::CLMemObjectType_)++-- | Return the flags argument value specified when memobj was created.+clGetMemFlags :: CLMem -> IO (Either CLError [CLMemFlag])+clGetMemFlags mem = wrapGetInfo (\(dat :: Ptr CLMemFlags_)+ -> raw_clGetMemObjectInfo mem infoid size (castPtr dat)) bitmaskToMemFlags+ where + infoid = getCLValue CL_MEM_FLAGS+ size = fromIntegral $ sizeOf (0::CLMemFlags_)++-- | Return actual size of memobj in bytes.+clGetMemSize :: CLMem -> IO (Either CLError CSize)+clGetMemSize mem = wrapGetInfo (\(dat :: Ptr CSize)+ -> raw_clGetMemObjectInfo mem infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_MEM_SIZE+ size = fromIntegral $ sizeOf (0::CSize)++-- | Return the host_ptr argument value specified when memobj is created.+clGetMemHostPtr :: CLMem -> IO (Either CLError (Ptr ()))+clGetMemHostPtr mem = wrapGetInfo (\(dat :: Ptr (Ptr ()))+ -> raw_clGetMemObjectInfo mem infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_MEM_HOST_PTR+ size = fromIntegral $ sizeOf (nullPtr::Ptr ())++-- | Map count. The map count returned should be considered immediately+-- stale. It is unsuitable for general use in applications. This feature is+-- provided for debugging.+clGetMemMapCount :: CLMem -> IO (Either CLError CLuint)+clGetMemMapCount mem = wrapGetInfo (\(dat :: Ptr CLuint)+ -> raw_clGetMemObjectInfo mem infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_MEM_MAP_COUNT+ size = fromIntegral $ sizeOf (0 :: CLuint)++-- | Return memobj reference count. The reference count returned should be+-- considered immediately stale. It is unsuitable for general use in+-- applications. This feature is provided for identifying memory leaks.+clGetMemReferenceCount :: CLMem -> IO (Either CLError CLuint)+clGetMemReferenceCount mem = wrapGetInfo (\(dat :: Ptr CLuint)+ -> raw_clGetMemObjectInfo mem infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_MEM_REFERENCE_COUNT+ size = fromIntegral $ sizeOf (0 :: CLuint)++-- | Return context specified when memory object is created.+clGetMemContext :: CLMem -> IO (Either CLError CLContext)+clGetMemContext mem = wrapGetInfo (\(dat :: Ptr CLContext)+ -> raw_clGetMemObjectInfo mem infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_MEM_CONTEXT+ size = fromIntegral $ sizeOf (0 :: CLuint)++-- -----------------------------------------------------------------------------+{-| Creates a sampler object. A sampler object describes how to sample an image+when the image is read in the kernel. The built-in functions to read from an+image in a kernel take a sampler as an argument. The sampler arguments to the+image read function can be sampler objects created using OpenCL functions and+passed as argument values to the kernel or can be samplers declared inside a+kernel. In this section we discuss how sampler objects are created using OpenCL+functions.++Returns a valid non-zero sampler object if the sampler object is created+successfully. Otherwise, it returns one of the following error values:++ * 'CL_INVALID_CONTEXT' if context is not a valid context.++ * 'CL_INVALID_VALUE' if addressing_mode, filter_mode, or normalized_coords or a+combination of these argument values are not valid.++ * 'CL_INVALID_OPERATION' if images are not supported by any device associated+with context (i.e. 'CL_DEVICE_IMAGE_SUPPORT' specified in the table of OpenCL+Device Queries for clGetDeviceInfo is 'False').++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host.+-}+clCreateSampler :: CLContext -> Bool -> CLAddressingMode -> CLFilterMode -> IO (Either CLError CLSampler)+clCreateSampler ctx norm am fm = wrapPError $ \perr -> do+ raw_clCreateSampler ctx (fromBool norm) (getCLValue am) (getCLValue fm) perr++-- | Increments the sampler reference count. 'clCreateSampler' does an implicit+-- retain. Returns 'True' if the function is executed successfully. It returns+-- 'False' if sampler is not a valid sampler object.+clRetainSampler :: CLSampler -> IO Bool+clRetainSampler mem = wrapCheckSuccess $ raw_clRetainSampler mem++-- | Decrements the sampler reference count. The sampler object is deleted after+-- the reference count becomes zero and commands queued for execution on a+-- command-queue(s) that use sampler have finished. 'clReleaseSampler' returns+-- 'True' if the function is executed successfully. It returns 'False' if+-- sampler is not a valid sampler object.+clReleaseSampler :: CLSampler -> IO Bool+clReleaseSampler mem = wrapCheckSuccess $ raw_clReleaseSampler mem++#c+enum CLSamplerInfo {+ cL_SAMPLER_REFERENCE_COUNT=CL_SAMPLER_REFERENCE_COUNT,+ cL_SAMPLER_CONTEXT=CL_SAMPLER_CONTEXT,+ cL_SAMPLER_ADDRESSING_MODE=CL_SAMPLER_ADDRESSING_MODE,+ cL_SAMPLER_FILTER_MODE=CL_SAMPLER_FILTER_MODE,+ cL_SAMPLER_NORMALIZED_COORDS=CL_SAMPLER_NORMALIZED_COORDS+ };+#endc+{#enum CLSamplerInfo {upcaseFirstLetter} #}++-- | Return the sampler reference count. The reference count returned should be+-- considered immediately stale. It is unsuitable for general use in+-- applications. This feature is provided for identifying memory leaks.+clGetSamplerReferenceCount :: CLSampler -> IO (Either CLError CLuint)+clGetSamplerReferenceCount sam = wrapGetInfo (\(dat :: Ptr CLuint)+ -> raw_clGetSamplerInfo sam infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_SAMPLER_REFERENCE_COUNT+ size = fromIntegral $ sizeOf (0 :: CLuint)++-- | Return the context specified when the sampler is created.+clGetSamplerContext :: CLSampler -> IO (Either CLError CLContext)+clGetSamplerContext sam = wrapGetInfo (\(dat :: Ptr CLContext)+ -> raw_clGetSamplerInfo sam infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_SAMPLER_CONTEXT+ size = fromIntegral $ sizeOf (nullPtr :: CLContext)++-- | Return the value specified by addressing_mode argument to clCreateSampler.+clGetSamplerAddressingMode :: CLSampler -> IO (Either CLError CLAddressingMode)+clGetSamplerAddressingMode sam = wrapGetInfo (\(dat :: Ptr CLAddressingMode_)+ -> raw_clGetSamplerInfo sam infoid size (castPtr dat)) getEnumCL+ where + infoid = getCLValue CL_SAMPLER_ADDRESSING_MODE+ size = fromIntegral $ sizeOf (0 :: CLAddressingMode_)++-- | Return the value specified by filter_mode argument to clCreateSampler.+clGetSamplerFilterMode :: CLSampler -> IO (Either CLError CLFilterMode)+clGetSamplerFilterMode sam = wrapGetInfo (\(dat :: Ptr CLFilterMode_)+ -> raw_clGetSamplerInfo sam infoid size (castPtr dat)) getEnumCL+ where + infoid = getCLValue CL_SAMPLER_FILTER_MODE+ size = fromIntegral $ sizeOf (0 :: CLFilterMode_)++-- | Return the value specified by normalized_coords argument to+-- clCreateSampler.+clGetSamplerNormalizedCoords :: CLSampler -> IO (Either CLError Bool)+clGetSamplerNormalizedCoords sam = wrapGetInfo (\(dat :: Ptr CLbool)+ -> raw_clGetSamplerInfo sam infoid size (castPtr dat)) (/=0)+ where + infoid = getCLValue CL_SAMPLER_NORMALIZED_COORDS+ size = fromIntegral $ sizeOf (0 :: CLbool)++-- -----------------------------------------------------------------------------
+ src/System/GPU/OpenCL/Program.chs view
@@ -0,0 +1,745 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+module System.GPU.OpenCL.Program( + -- * Types+ CLProgram, CLBuildStatus(..), CLKernel,+ -- * Program Functions+ clCreateProgramWithSource, clRetainProgram, clReleaseProgram, + clUnloadCompiler, clBuildProgram, clGetProgramReferenceCount, + clGetProgramContext, clGetProgramNumDevices, clGetProgramDevices,+ clGetProgramSource, clGetProgramBinarySizes, clGetProgramBinaries, + clGetProgramBuildStatus, clGetProgramBuildOptions, clGetProgramBuildLog,+ -- * Kernel Functions+ clCreateKernel, clCreateKernelsInProgram, clRetainKernel, clReleaseKernel, + clSetKernelArg, clGetKernelFunctionName, clGetKernelNumArgs, + clGetKernelReferenceCount, clGetKernelContext, clGetKernelProgram, + clGetKernelWorkGroupSize, clGetKernelCompileWorkGroupSize, + clGetKernelLocalMemSize+ ) where++-- -----------------------------------------------------------------------------+import Control.Monad( zipWithM )+import Foreign+import Foreign.C.Types+import Foreign.C.String( CString, withCString, newCString, peekCString )+import System.GPU.OpenCL.Types( + CLint, CLuint, CLulong, CLProgram, CLContext, CLKernel, CLDeviceID, + CLError(..), CLProgramInfo_, CLBuildStatus(..), CLBuildStatus_, + CLProgramBuildInfo_, CLKernelInfo_, CLKernelWorkGroupInfo_, wrapCheckSuccess, + wrapPError, wrapGetInfo, getCLValue, getEnumCL )++#include <CL/cl.h>++-- -----------------------------------------------------------------------------+type BuildCallback = CLProgram -> Ptr () -> IO ()+foreign import ccall "clCreateProgramWithSource" raw_clCreateProgramWithSource :: + CLContext -> CLuint -> Ptr CString -> Ptr CSize -> Ptr CLint -> IO CLProgram+--foreign import ccall "clCreateProgramWithBinary" raw_clCreateProgramWithBinary :: +-- CLContext -> CLuint -> Ptr CLDeviceID -> Ptr CSize -> Ptr (Ptr Word8) -> Ptr CLint -> Ptr CLint -> IO CLProgram+foreign import ccall "clRetainProgram" raw_clRetainProgram :: + CLProgram -> IO CLint+foreign import ccall "clReleaseProgram" raw_clReleaseProgram :: + CLProgram -> IO CLint+foreign import ccall "clBuildProgram" raw_clBuildProgram :: + CLProgram -> CLuint -> Ptr CLDeviceID -> CString -> FunPtr BuildCallback -> Ptr () -> IO CLint+foreign import ccall "clUnloadCompiler" raw_clUnloadCompiler :: + IO CLint+foreign import ccall "clGetProgramInfo" raw_clGetProgramInfo :: + CLProgram -> CLProgramInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint+foreign import ccall "clGetProgramBuildInfo" raw_clGetProgramBuildInfo :: + CLProgram -> CLDeviceID -> CLProgramBuildInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint+foreign import ccall "clCreateKernel" raw_clCreateKernel :: + CLProgram -> CString -> Ptr CLint -> IO CLKernel +foreign import ccall "clCreateKernelsInProgram" raw_clCreateKernelsInProgram :: + CLProgram -> CLuint -> Ptr CLKernel -> Ptr CLuint -> IO CLint +foreign import ccall "clRetainKernel" raw_clRetainKernel :: + CLKernel -> IO CLint +foreign import ccall "clReleaseKernel" raw_clReleaseKernel :: + CLKernel -> IO CLint +foreign import ccall "clSetKernelArg" raw_clSetKernelArg :: + CLKernel -> CLuint -> CSize -> Ptr () -> IO CLint+foreign import ccall "clGetKernelInfo" raw_clGetKernelInfo :: + CLKernel -> CLKernelInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint+foreign import ccall "clGetKernelWorkGroupInfo" raw_clGetKernelWorkGroupInfo :: + CLKernel -> CLDeviceID -> CLKernelWorkGroupInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint++-- -----------------------------------------------------------------------------+{-| Creates a program object for a context, and loads the source code specified+by the text strings in the strings array into the program object. The devices+associated with the program object are the devices associated with context.++OpenCL allows applications to create a program object using the program source+or binary and build appropriate program executables. This allows applications to+determine whether they want to use the pre-built offline binary or load and+compile the program source and use the executable compiled/linked online as the+program executable. This can be very useful as it allows applications to load+and build program executables online on its first instance for appropriate+OpenCL devices in the system. These executables can now be queried and cached by+the application. Future instances of the application launching will no longer+need to compile and build the program executables. The cached executables can be+read and loaded by the application, which can help significantly reduce the+application initialization time.++An OpenCL program consists of a set of kernels that are identified as functions+declared with the __kernel qualifier in the program source. OpenCL programs may+also contain auxiliary functions and constant data that can be used by __kernel+functions. The program executable can be generated online or offline by the+OpenCL compiler for the appropriate target device(s).++'clCreateProgramWithSource' returns a valid non-zero program object if the+program object is created successfully. Otherwise, it returns one of the+following error values:++ * 'CL_INVALID_CONTEXT' if context is not a valid context.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host. +-}+clCreateProgramWithSource :: CLContext -> String -> IO (Either CLError CLProgram)+clCreateProgramWithSource ctx source = wrapPError $ \perr -> do+ let strings = lines source+ count = fromIntegral $ length strings+ cstrings <- mapM newCString strings+ prog <- withArray cstrings $ \srcArray -> do+ raw_clCreateProgramWithSource ctx count srcArray nullPtr perr+ mapM_ free cstrings+ return prog+ +-- | Increments the program reference count. 'clRetainProgram' returns 'True' if +-- the function is executed successfully. It returns 'False' if program is not a +-- valid program object.+clRetainProgram :: CLProgram -> IO Bool+clRetainProgram prg = wrapCheckSuccess $ raw_clRetainProgram prg++-- | Decrements the program reference count. The program object is deleted after +-- all kernel objects associated with program have been deleted and the program +-- reference count becomes zero. 'clReleseProgram' returns 'True' if +-- the function is executed successfully. It returns 'False' if program is not a +-- valid program object.+clReleaseProgram :: CLProgram -> IO Bool+clReleaseProgram prg = wrapCheckSuccess $ raw_clReleaseProgram prg++-- | Allows the implementation to release the resources allocated by the OpenCL+-- compiler. This is a hint from the application and does not guarantee that the+-- compiler will not be used in the future or that the compiler will actually be+-- unloaded by the implementation. Calls to 'clBuildProgram' after+-- 'clUnloadCompiler' will reload the compiler, if necessary, to build the+-- appropriate program executable.+clUnloadCompiler :: IO ()+clUnloadCompiler = raw_clUnloadCompiler >> return ()++{-| Builds (compiles and links) a program executable from the program source or+binary. OpenCL allows program executables to be built using the source or the+binary. The build options are categorized as pre-processor options, options for+math intrinsics, options that control optimization and miscellaneous+options. This specification defines a standard set of options that must be+supported by an OpenCL compiler when building program executables online or+offline. These may be extended by a set of vendor- or platform-specific options.++ * Preprocessor Options++These options control the OpenCL preprocessor which is run on each program+source before actual compilation. -D options are processed in the order they are+given in the options argument to clBuildProgram.++ [-D name] Predefine name as a macro, with definition 1.++ [-D name=definition] The contents of definition are tokenized and processed as+if they appeared during translation phase three in a `#define' directive. In+particular, the definition will be truncated by embedded newline characters.++ [-I dir] Add the directory dir to the list of directories to be searched for+header files.++ * Math Intrinsics Options++These options control compiler behavior regarding floating-point+arithmetic. These options trade off between speed and correctness.++ [-cl-single-precision-constant] Treat double precision floating-point constant+as single precision constant.++ [-cl-denorms-are-zero] This option controls how single precision and double+precision denormalized numbers are handled. If specified as a build option, the+single precision denormalized numbers may be flushed to zero and if the optional+extension for double precision is supported, double precision denormalized+numbers may also be flushed to zero. This is intended to be a performance hint+and the OpenCL compiler can choose not to flush denorms to zero if the device+supports single precision (or double precision) denormalized numbers.++This option is ignored for single precision numbers if the device does not+support single precision denormalized numbers i.e. 'CL_FP_DENORM' bit is not set+in 'clGetDeviceSingleFPConfig'.++This option is ignored for double precision numbers if the device does not+support double precision or if it does support double precison but+'CL_FP_DENORM' bit is not set in 'clGetDeviceDoubleFPConfig'.++This flag only applies for scalar and vector single precision floating-point+variables and computations on these floating-point variables inside a+program. It does not apply to reading from or writing to image objects.++ * Optimization Options++These options control various sorts of optimizations. Turning on optimization+flags makes the compiler attempt to improve the performance and/or code size at+the expense of compilation time and possibly the ability to debug the program.++ [-cl-opt-disable] This option disables all optimizations. The default is+optimizations are enabled.++ [-cl-strict-aliasing] This option allows the compiler to assume the strictest+aliasing rules.++The following options control compiler behavior regarding floating-point+arithmetic. These options trade off between performance and correctness and must+be specifically enabled. These options are not turned on by default since it can+result in incorrect output for programs which depend on an exact implementation+of IEEE 754 rules/specifications for math functions.++ [-cl-mad-enable] Allow a * b + c to be replaced by a mad. The mad computes a *+b + c with reduced accuracy. For example, some OpenCL devices implement mad as+truncate the result of a * b before adding it to c.++ [-cl-no-signed-zeros] Allow optimizations for floating-point arithmetic that+ignore the signedness of zero. IEEE 754 arithmetic specifies the behavior of+distinct +0.0 and -0.0 values, which then prohibits simplification of+expressions such as x+0.0 or 0.0*x (even with -clfinite-math only). This option+implies that the sign of a zero result isn't significant.++ [-cl-unsafe-math-optimizations] Allow optimizations for floating-point+arithmetic that (a) assume that arguments and results are valid, (b) may violate+IEEE 754 standard and (c) may violate the OpenCL numerical compliance+requirements as defined in section 7.4 for single-precision floating-point,+section 9.3.9 for double-precision floating-point, and edge case behavior in+section 7.5. This option includes the -cl-no-signed-zeros and -cl-mad-enable+options.++ [-cl-finite-math-only] Allow optimizations for floating-point arithmetic that+assume that arguments and results are not NaNs or ±∞. This option may violate+the OpenCL numerical compliance requirements defined in in section 7.4 for+single-precision floating-point, section 9.3.9 for double-precision+floating-point, and edge case behavior in section 7.5.++ [-cl-fast-relaxed-math] Sets the optimization options -cl-finite-math-only and+-cl-unsafe-math-optimizations. This allows optimizations for floating-point+arithmetic that may violate the IEEE 754 standard and the OpenCL numerical+compliance requirements defined in the specification in section 7.4 for+single-precision floating-point, section 9.3.9 for double-precision+floating-point, and edge case behavior in section 7.5. This option causes the+preprocessor macro __FAST_RELAXED_MATH__ to be defined in the OpenCL program.++ * Options to Request or Suppress Warnings++Warnings are diagnostic messages that report constructions which are not+inherently erroneous but which are risky or suggest there may have been an+error. The following languageindependent options do not enable specific warnings+but control the kinds of diagnostics produced by the OpenCL compiler.++ [-w] Inhibit all warning messages.+ + [-Werror] Make all warnings into errors.++clBuildProgram returns the following errors when fails:++ * 'CL_INVALID_PROGRAM' if program is not a valid program object.++ * 'CL_INVALID_DEVICE' if OpenCL devices listed in device_list are not in the+list of devices associated with program.++ * 'CL_INVALID_BINARY' if program is created with+'clCreateWithProgramWithBinary' and devices listed in device_list do not have a+valid program binary loaded.++ * 'CL_INVALID_BUILD_OPTIONS' if the build options specified by options are+invalid.++ * 'CL_INVALID_OPERATION' if the build of a program executable for any of the+devices listed in device_list by a previous call to 'clBuildProgram' for program+has not completed.++ * 'CL_COMPILER_NOT_AVAILABLE' if program is created with+'clCreateProgramWithSource' and a compiler is not available+i.e. 'clGetDeviceCompilerAvailable' is set to 'False'.++ * 'CL_BUILD_PROGRAM_FAILURE' if there is a failure to build the program+executable. This error will be returned if 'clBuildProgram' does not return+until the build has completed.++ * 'CL_INVALID_OPERATION' if there are kernel objects attached to program.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host. +-}+clBuildProgram :: CLProgram -> [CLDeviceID] -> String -> IO (Either CLError ())+clBuildProgram prg devs opts = allocaArray ndevs $ \pdevs -> do+ pokeArray pdevs devs+ withCString opts $ \copts -> do+ errcode <- raw_clBuildProgram prg cndevs pdevs copts nullFunPtr nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then return $ Right ()+ else return . Left . toEnum . fromIntegral $ errcode+ where+ ndevs = length devs+ cndevs = fromIntegral ndevs++#c+enum CLProgramInfo {+ cL_PROGRAM_REFERENCE_COUNT=CL_PROGRAM_REFERENCE_COUNT,+ cL_PROGRAM_CONTEXT=CL_PROGRAM_CONTEXT,+ cL_PROGRAM_NUM_DEVICES=CL_PROGRAM_NUM_DEVICES,+ cL_PROGRAM_DEVICES=CL_PROGRAM_DEVICES,+ cL_PROGRAM_SOURCE=CL_PROGRAM_SOURCE,+ cL_PROGRAM_BINARY_SIZES=CL_PROGRAM_BINARY_SIZES,+ cL_PROGRAM_BINARIES=CL_PROGRAM_BINARIES,+ };+#endc+{#enum CLProgramInfo {upcaseFirstLetter} #}++getProgramInfoSize :: CLProgram -> CLProgramInfo_ -> IO (Either CLError CSize)+getProgramInfoSize prg infoid = alloca $ \(value_size :: Ptr CSize) -> do+ errcode <- raw_clGetProgramInfo prg infoid 0 nullPtr value_size+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peek value_size+ else return . Left . toEnum . fromIntegral $ errcode+ +-- | Return the program reference count. The reference count returned should be+-- considered immediately stale. It is unsuitable for general use in+-- applications. This feature is provided for identifying memory leaks.+clGetProgramReferenceCount :: CLProgram -> IO (Either CLError CLuint)+clGetProgramReferenceCount prg = wrapGetInfo (\(dat :: Ptr CLuint) + -> raw_clGetProgramInfo prg infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_PROGRAM_REFERENCE_COUNT+ size = fromIntegral $ sizeOf (0::CLuint)++-- | Return the context specified when the program object is created.+clGetProgramContext :: CLProgram -> IO (Either CLError CLContext)+clGetProgramContext prg = wrapGetInfo (\(dat :: Ptr CLContext) + -> raw_clGetProgramInfo prg infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_PROGRAM_CONTEXT+ size = fromIntegral $ sizeOf (nullPtr::CLContext)++-- | Return the number of devices associated with program.+clGetProgramNumDevices :: CLProgram -> IO (Either CLError CLuint)+clGetProgramNumDevices prg = wrapGetInfo (\(dat :: Ptr CLuint) + -> raw_clGetProgramInfo prg infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_PROGRAM_NUM_DEVICES+ size = fromIntegral $ sizeOf (0::CLuint)++-- | Return the list of devices associated with the program object. This can be+-- the devices associated with context on which the program object has been+-- created or can be a subset of devices that are specified when a progam object+-- is created using 'clCreateProgramWithBinary'.+clGetProgramDevices :: CLProgram -> IO (Either CLError [CLDeviceID])+clGetProgramDevices prg = do+ sval <- getProgramInfoSize prg infoid+ case sval of+ Left err -> return . Left $ err+ Right size -> allocaArray (numElems size) $ \(buff :: Ptr CLDeviceID) -> do+ errcode <- raw_clGetProgramInfo prg infoid size (castPtr buff) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peekArray (numElems size) buff+ else return . Left . toEnum . fromIntegral $ errcode+ where + infoid = getCLValue CL_PROGRAM_DEVICES+ numElems s = (fromIntegral s) `div` elemSize+ elemSize = sizeOf (nullPtr::CLDeviceID)++-- | Return the program source code specified by+-- 'clCreateProgramWithSource'. The source string returned is a concatenation of+-- all source strings specified to 'clCreateProgramWithSource' with a null+-- terminator. The concatenation strips any nulls in the original source+-- strings. The actual number of characters that represents the program source+-- code including the null terminator is returned in param_value_size_ret.+clGetProgramSource :: CLProgram -> IO (Either CLError String)+clGetProgramSource prg = do+ sval <- getProgramInfoSize prg infoid+ case sval of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(buff :: CString) -> do+ errcode <- raw_clGetProgramInfo prg infoid n (castPtr buff) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peekCString buff+ else return . Left . toEnum . fromIntegral $ errcode+ where + infoid = getCLValue CL_PROGRAM_SOURCE+ +-- | Returns an array that contains the size in bytes of the program binary for+-- each device associated with program. The size of the array is the number of+-- devices associated with program. If a binary is not available for a+-- device(s), a size of zero is returned.+clGetProgramBinarySizes :: CLProgram -> IO (Either CLError [CSize])+clGetProgramBinarySizes prg = do+ sval <- getProgramInfoSize prg infoid+ case sval of+ Left err -> return . Left $ err+ Right size -> allocaArray (numElems size) $ \(buff :: Ptr CSize) -> do+ errcode <- raw_clGetProgramInfo prg infoid size (castPtr buff) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peekArray (numElems size) buff+ else return . Left . toEnum . fromIntegral $ errcode+ where + infoid = getCLValue CL_PROGRAM_BINARY_SIZES+ numElems s = (fromIntegral s) `div` elemSize+ elemSize = sizeOf (0::CSize)++{-| Return the program binaries for all devices associated with program. For+each device in program, the binary returned can be the binary specified for the+device when program is created with 'clCreateProgramWithBinary' or it can be the+executable binary generated by 'clBuildProgram'. If program is created with+'clCreateProgramWithSource', the binary returned is the binary generated by+'clBuildProgram'. The bits returned can be an implementation-specific+intermediate representation (a.k.a. IR) or device specific executable bits or+both. The decision on which information is returned in the binary is up to the+OpenCL implementation.++To find out which device the program binary in the array refers to, use the+'clGetProgramDevices' query to get the list of devices. There is a one-to-one+correspondence between the array of data returned by 'clGetProgramBinaries' and+array of devices returned by 'clGetProgramDevices'. +-}+clGetProgramBinaries :: CLProgram -> IO (Either CLError [[Word8]])+clGetProgramBinaries prg = do+ sval <- clGetProgramBinarySizes prg+ case sval of+ Left err -> return . Left $ err+ Right sizes -> do+ let numElems = length sizes+ size = fromIntegral $ numElems * elemSize+ buffers <- (mapM (mallocArray.fromIntegral) sizes) :: IO [Ptr Word8]+ ret <- withArray buffers $ \(parray :: Ptr (Ptr Word8)) -> do+ errcode <- raw_clGetProgramInfo prg infoid size (castPtr parray) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then do+ vals <- zipWithM peekArray (map fromIntegral sizes) buffers+ return . Right $ vals+ else return . Left . toEnum . fromIntegral $ errcode+ mapM_ free buffers+ return ret+ where + infoid = getCLValue CL_PROGRAM_BINARIES+ elemSize = sizeOf (nullPtr::Ptr Word8)++-- -----------------------------------------------------------------------------+#c+enum CLProgramBuildInfo {+ cL_PROGRAM_BUILD_STATUS=CL_PROGRAM_BUILD_STATUS,+ cL_PROGRAM_BUILD_OPTIONS=CL_PROGRAM_BUILD_OPTIONS,+ cL_PROGRAM_BUILD_LOG=CL_PROGRAM_BUILD_LOG,+ };+#endc+{#enum CLProgramBuildInfo {upcaseFirstLetter} #}++getProgramBuildInfoSize :: CLProgram -> CLDeviceID -> CLProgramInfo_ -> IO (Either CLError CSize)+getProgramBuildInfoSize prg device infoid = alloca $ \(value_size :: Ptr CSize) -> do+ errcode <- raw_clGetProgramBuildInfo prg device infoid 0 nullPtr value_size+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peek value_size+ else return . Left . toEnum . fromIntegral $ errcode+ +-- | Returns the build status of program for a specific device as given by+-- device.+clGetProgramBuildStatus :: CLProgram -> CLDeviceID -> IO (Either CLError CLBuildStatus)+clGetProgramBuildStatus prg device = wrapGetInfo (\(dat :: Ptr CLBuildStatus_) + -> raw_clGetProgramBuildInfo prg device infoid size (castPtr dat)) getEnumCL+ where + infoid = getCLValue CL_PROGRAM_BUILD_STATUS+ size = fromIntegral $ sizeOf (0::CLBuildStatus_)++-- | Return the build options specified by the options argument in+-- clBuildProgram for device. If build status of program for device is+-- 'CL_BUILD_NONE', an empty string is returned.+clGetProgramBuildOptions :: CLProgram -> CLDeviceID -> IO (Either CLError String)+clGetProgramBuildOptions prg device = do+ sval <- getProgramBuildInfoSize prg device infoid+ case sval of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(buff :: CString) -> do+ errcode <- raw_clGetProgramBuildInfo prg device infoid n (castPtr buff) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peekCString buff+ else return . Left . toEnum . fromIntegral $ errcode+ where + infoid = getCLValue CL_PROGRAM_BUILD_OPTIONS+ +-- | Return the build log when 'clBuildProgram' was called for device. If build+-- status of program for device is 'CL_BUILD_NONE', an empty string is returned.+clGetProgramBuildLog :: CLProgram -> CLDeviceID -> IO (Either CLError String)+clGetProgramBuildLog prg device = do+ sval <- getProgramBuildInfoSize prg device infoid+ case sval of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(buff :: CString) -> do+ errcode <- raw_clGetProgramBuildInfo prg device infoid n (castPtr buff) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peekCString buff+ else return . Left . toEnum . fromIntegral $ errcode+ where + infoid = getCLValue CL_PROGRAM_BUILD_LOG+ +-- -----------------------------------------------------------------------------+{-| Creates a kernal object. A kernel is a function declared in a program. A+kernel is identified by the __kernel qualifier applied to any function in a+program. A kernel object encapsulates the specific __kernel function declared in+a program and the argument values to be used when executing this __kernel+function.++'clCreateKernel' returns a valid non-zero kernel object if the kernel object is+created successfully. Otherwise, it returns one of the following error values:++ * 'CL_INVALID_PROGRAM' if program is not a valid program object.++ * 'CL_INVALID_PROGRAM_EXECUTABLE' if there is no successfully built executable+ for program.++ * 'CL_INVALID_KERNEL_NAME' if kernel_name is not found in program.++ * 'CL_INVALID_KERNEL_DEFINITION' if the function definition for __kernel+function given by kernel_name such as the number of arguments, the argument+types are not the same for all devices for which the program executable has been+built.++ * 'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required+by the OpenCL implementation on the host. +-}+clCreateKernel :: CLProgram -> String -> IO (Either CLError CLKernel)+clCreateKernel prg name = withCString name $ \cname -> wrapPError $ \perr -> do+ raw_clCreateKernel prg cname perr++{-| Creates kernel objects for all kernel functions in a program object. Kernel+objects are not created for any __kernel functions in program that do not have+the same function definition across all devices for which a program executable+has been successfully built.++Kernel objects can only be created once you have a program object with a valid+program source or binary loaded into the program object and the program+executable has been successfully built for one or more devices associated with+program. No changes to the program executable are allowed while there are kernel+objects associated with a program object. This means that calls to+'clBuildProgram' return 'CL_INVALID_OPERATION' if there are kernel objects+attached to a program object. The OpenCL context associated with program will be+the context associated with kernel. The list of devices associated with program+are the devices associated with kernel. Devices associated with a program object+for which a valid program executable has been built can be used to execute+kernels declared in the program object.++'clCreateKernelsInProgram' will return the kernel objects if the kernel objects+were successfully allocated, returns 'CL_INVALID_PROGRAM' if program is not a+valid program object, returns 'CL_INVALID_PROGRAM_EXECUTABLE' if there is no+successfully built executable for any device in program and returns+'CL_OUT_OF_HOST_MEMORY' if there is a failure to allocate resources required by+the OpenCL implementation on the host.+-}+clCreateKernelsInProgram :: CLProgram -> IO (Either CLError [CLKernel])+clCreateKernelsInProgram prg = do+ nks <- alloca $ \pn -> do+ errcode <- raw_clCreateKernelsInProgram prg 0 nullPtr pn+ if errcode == (getCLValue CL_SUCCESS)+ then peek pn >>= (return . Right)+ else return $ Left errcode+ + case nks of+ Left err -> return . Left . getEnumCL $ err+ Right n -> allocaArray (fromIntegral n) $ \pks -> do+ errcode <- raw_clCreateKernelsInProgram prg n pks nullPtr+ if errcode == (getCLValue CL_SUCCESS)+ then peekArray (fromIntegral n) pks >>= (return . Right)+ else return . Left .getEnumCL $ errcode++-- | Increments the program program reference count. 'clRetainKernel' returns+-- 'True' if the function is executed successfully. 'clCreateKernel' or+-- 'clCreateKernelsInProgram' do an implicit retain.+clRetainKernel :: CLKernel -> IO Bool+clRetainKernel krn = wrapCheckSuccess $ raw_clRetainKernel krn++-- | Decrements the kernel reference count. The kernel object is deleted once+-- the number of instances that are retained to kernel become zero and the+-- kernel object is no longer needed by any enqueued commands that use+-- kernel. 'clReleaseKernel' returns 'True' if the function is executed+-- successfully.+clReleaseKernel :: CLKernel -> IO Bool+clReleaseKernel krn = wrapCheckSuccess $ raw_clReleaseKernel krn++{-| Used to set the argument value for a specific argument of a kernel.++A kernel object does not update the reference count for objects such as memory,+sampler objects specified as argument values by 'clSetKernelArg', Users may not+rely on a kernel object to retain objects specified as argument values to the+kernel.++Implementations shall not allow 'CLKernel' objects to hold reference counts to+'CLKernel' arguments, because no mechanism is provided for the user to tell the+kernel to release that ownership right. If the kernel holds ownership rights on+kernel args, that would make it impossible for the user to tell with certainty+when he may safely release user allocated resources associated with OpenCL+objects such as the CLMem backing store used with 'CL_MEM_USE_HOST_PTR'.++'clSetKernelArg' returns returns one of the following errors when fails:++ * 'CL_INVALID_KERNEL' if kernel is not a valid kernel object.+ + * 'CL_INVALID_ARG_INDEX' if arg_index is not a valid argument index.++ * 'CL_INVALID_ARG_VALUE' if arg_value specified is NULL for an argument that is+not declared with the __local qualifier or vice-versa.++ * 'CL_INVALID_MEM_OBJECT' for an argument declared to be a memory object when+the specified arg_value is not a valid memory object.++ * 'CL_INVALID_SAMPLER' for an argument declared to be of type sampler_t when+the specified arg_value is not a valid sampler object.++ * 'CL_INVALID_ARG_SIZE' if arg_size does not match the size of the data type+for an argument that is not a memory object or if the argument is a memory+object and arg_size != sizeof(cl_mem) or if arg_size is zero and the argument is+declared with the __local qualifier or if the argument is a sampler and arg_size+!= sizeof(cl_sampler). +-}+clSetKernelArg :: Storable a => CLKernel -> CLuint -> a -> IO (Either CLError ())+clSetKernelArg krn idx val = with val $ \pval -> do+ errcode <- raw_clSetKernelArg krn idx (fromIntegral . sizeOf $ val) (castPtr pval)+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then return $ Right ()+ else return . Left . toEnum . fromIntegral $ errcode++#c+enum CLKernelInfo {+ cL_KERNEL_FUNCTION_NAME=CL_KERNEL_FUNCTION_NAME,+ cL_KERNEL_NUM_ARGS=CL_KERNEL_NUM_ARGS,+ cL_KERNEL_REFERENCE_COUNT=CL_KERNEL_REFERENCE_COUNT,+ cL_KERNEL_CONTEXT=CL_KERNEL_CONTEXT,+ cL_KERNEL_PROGRAM=CL_KERNEL_PROGRAM+ };+#endc+{#enum CLKernelInfo {upcaseFirstLetter} #}++getKernelInfoSize :: CLKernel -> CLKernelInfo_ -> IO (Either CLError CSize)+getKernelInfoSize krn infoid = alloca $ \(value_size :: Ptr CSize) -> do+ errcode <- raw_clGetKernelInfo krn infoid 0 nullPtr value_size+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peek value_size+ else return . Left . toEnum . fromIntegral $ errcode+ +-- | Return the kernel function name.+clGetKernelFunctionName :: CLKernel -> IO (Either CLError String)+clGetKernelFunctionName krn = do+ sval <- getKernelInfoSize krn infoid+ case sval of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(buff :: CString) -> do+ errcode <- raw_clGetKernelInfo krn infoid n (castPtr buff) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peekCString buff+ else return . Left . toEnum . fromIntegral $ errcode+ where + infoid = getCLValue CL_KERNEL_FUNCTION_NAME++-- | Return the number of arguments to kernel.+clGetKernelNumArgs :: CLKernel -> IO (Either CLError CLuint)+clGetKernelNumArgs krn = wrapGetInfo (\(dat :: Ptr CLuint) + -> raw_clGetKernelInfo krn infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_KERNEL_NUM_ARGS+ size = fromIntegral $ sizeOf (0::CLuint)++-- | Return the kernel reference count. The reference count returned should be+-- considered immediately stale. It is unsuitable for general use in+-- applications. This feature is provided for identifying memory leaks.+clGetKernelReferenceCount :: CLKernel -> IO (Either CLError CLuint)+clGetKernelReferenceCount krn = wrapGetInfo (\(dat :: Ptr CLuint) + -> raw_clGetKernelInfo krn infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_KERNEL_REFERENCE_COUNT+ size = fromIntegral $ sizeOf (0::CLuint)++-- | Return the context associated with kernel.+clGetKernelContext :: CLKernel -> IO (Either CLError CLContext)+clGetKernelContext krn = wrapGetInfo (\(dat :: Ptr CLContext) + -> raw_clGetKernelInfo krn infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_KERNEL_CONTEXT+ size = fromIntegral $ sizeOf (nullPtr::CLContext)++-- | Return the program object associated with kernel.+clGetKernelProgram :: CLKernel -> IO (Either CLError CLProgram)+clGetKernelProgram krn = wrapGetInfo (\(dat :: Ptr CLProgram) + -> raw_clGetKernelInfo krn infoid size (castPtr dat)) id+ where + infoid = getCLValue CL_KERNEL_PROGRAM+ size = fromIntegral $ sizeOf (nullPtr::CLProgram)+++#c+enum CLKernelGroupInfo {+ cL_KERNEL_WORK_GROUP_SIZE=CL_KERNEL_WORK_GROUP_SIZE,+ cL_KERNEL_COMPILE_WORK_GROUP_SIZE=CL_KERNEL_COMPILE_WORK_GROUP_SIZE,+ cL_KERNEL_LOCAL_MEM_SIZE=CL_KERNEL_LOCAL_MEM_SIZE,+ };+#endc+{#enum CLKernelGroupInfo {upcaseFirstLetter} #}++-- | This provides a mechanism for the application to query the work-group size+-- that can be used to execute a kernel on a specific device given by+-- device. The OpenCL implementation uses the resource requirements of the+-- kernel (register usage etc.) to determine what this work-group size should+-- be.+clGetKernelWorkGroupSize :: CLKernel -> CLDeviceID -> IO (Either CLError CSize)+clGetKernelWorkGroupSize krn device = wrapGetInfo (\(dat :: Ptr CSize)+ -> raw_clGetKernelWorkGroupInfo krn device infoid size (castPtr dat)) id+ where+ infoid = getCLValue CL_KERNEL_WORK_GROUP_SIZE+ size = fromIntegral $ sizeOf (0::CSize)++-- | Returns the work-group size specified by the __attribute__((reqd_work_gr+-- oup_size(X, Y, Z))) qualifier. See Function Qualifiers. If the work-group+-- size is not specified using the above attribute qualifier (0, 0, 0) is+-- returned.+clGetKernelCompileWorkGroupSize :: CLKernel -> CLDeviceID -> IO (Either CLError [CSize])+clGetKernelCompileWorkGroupSize krn device = do+ allocaArray num $ \(buff :: Ptr CSize) -> do+ errcode <- raw_clGetKernelWorkGroupInfo krn device infoid size (castPtr buff) nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS)+ then fmap Right $ peekArray num buff+ else return . Left . toEnum . fromIntegral $ errcode+ where + infoid = getCLValue CL_KERNEL_COMPILE_WORK_GROUP_SIZE+ num = 3+ elemSize = fromIntegral $ sizeOf (0::CSize)+ size = fromIntegral $ num * elemSize+++-- | Returns the amount of local memory in bytes being used by a kernel. This+-- includes local memory that may be needed by an implementation to execute the+-- kernel, variables declared inside the kernel with the __local address+-- qualifier and local memory to be allocated for arguments to the kernel+-- declared as pointers with the __local address qualifier and whose size is+-- specified with 'clSetKernelArg'.+--+-- If the local memory size, for any pointer argument to the kernel declared+-- with the __local address qualifier, is not specified, its size is assumed to+-- be 0.+clGetKernelLocalMemSize :: CLKernel -> CLDeviceID -> IO (Either CLError CLulong)+clGetKernelLocalMemSize krn device = wrapGetInfo (\(dat :: Ptr CLulong)+ -> raw_clGetKernelWorkGroupInfo krn device infoid size (castPtr dat)) id+ where+ infoid = getCLValue CL_KERNEL_LOCAL_MEM_SIZE+ size = fromIntegral $ sizeOf (0::CLulong)+-- -----------------------------------------------------------------------------
+ src/System/GPU/OpenCL/Query.chs view
@@ -0,0 +1,590 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+module System.GPU.OpenCL.Query( + -- * Types+ CLPlatformInfo(..), CLPlatformID, CLDeviceID, CLDeviceType(..),+ CLDeviceFPConfig(..), CLDeviceExecCapability(..), CLDeviceLocalMemType(..),+ CLDeviceMemCacheType(..),+ -- * Platform Query Functions+ clGetPlatformIDs, clGetPlatformInfo, + -- * Device Query Functions+ clGetDeviceIDs, clGetDeviceExecutionCapabilities,+ clGetDeviceAddressBits, clGetDeviceAvailable, clGetDeviceCompilerAvailable, + clGetDeviceEndianLittle, clGetDeviceErrorCorrectionSupport, + clGetDeviceExtensions, clGetDeviceGlobalMemCacheSize, + clGetDeviceGlobalMemCachelineSize, clGetDeviceGlobalMemSize, + clGetDeviceImageSupport, clGetDeviceImage2DMaxHeight, + clGetDeviceImage2DMaxWidth, clGetDeviceImage3DMaxDepth, + clGetDeviceImage3DMaxHeight, clGetDeviceImage3DMaxWidth, + clGetDeviceLocalMemSize, clGetDeviceMaxClockFrequency, + clGetDeviceMaxComputeUnits, clGetDeviceMaxConstantArgs, + clGetDeviceMaxConstantBufferSize, clGetDeviceMaxMemAllocSize, + clGetDeviceMaxParameterSize, clGetDeviceMaxReadImageArgs, + clGetDeviceMaxSamplers, clGetDeviceMaxWorkGroupSize, + clGetDeviceMaxWorkItemDimensions, clGetDeviceMaxWorkItemSizes, + clGetDeviceMaxWriteImageArgs, clGetDeviceMemBaseAddrAlign, + clGetDeviceMinDataTypeAlignSize, clGetDeviceName, clGetDevicePlatform, + clGetDevicePreferredVectorWidthChar, clGetDevicePreferredVectorWidthShort, + clGetDevicePreferredVectorWidthInt, clGetDevicePreferredVectorWidthLong, + clGetDevicePreferredVectorWidthFloat, clGetDevicePreferredVectorWidthDouble, + clGetDeviceProfile, clGetDeviceProfilingTimerResolution, clGetDeviceVendor, + clGetDeviceVendorID, clGetDeviceVersion, clGetDeviceDriverVersion, + clGetDeviceSingleFPConfig, clGetDeviceDoubleFPConfig, + clGetDeviceHalfFPConfig, clGetDeviceLocalMemType, + clGetDeviceGlobalMemCacheType, clGetDeviceQueueProperties, clGetDeviceType )+ where++-- -----------------------------------------------------------------------------+import Foreign( Ptr, nullPtr, castPtr, alloca, allocaArray, peek, peekArray )+import Foreign.C.String( CString, peekCString )+import Foreign.C.Types( CSize )+import Foreign.Storable( sizeOf )+import System.GPU.OpenCL.Types( + CLbool, CLint, CLuint, CLulong, CLPlatformInfo_, CLDeviceType_, CLError(..),+ CLDeviceInfo_, CLDeviceFPConfig(..), CLDeviceExecCapability(..),+ CLDeviceLocalMemType(..), CLDeviceMemCacheType(..), CLPlatformInfo(..),+ CLPlatformID, CLDeviceID, CLDeviceType(..), CLCommandQueueProperty, + getCLValue, getEnumCL, bitmaskToDeviceTypes, bitmaskToCommandQueueProperties, + whenSuccess, bitmaskToFPConfig, bitmaskToExecCapability )++-- -----------------------------------------------------------------------------+foreign import ccall "clGetPlatformIDs" raw_clGetPlatformIDs :: + CLuint -> Ptr CLPlatformID -> Ptr CLuint -> IO CLint+foreign import ccall "clGetPlatformInfo" raw_clGetPlatformInfo :: + CLPlatformID -> CLPlatformInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint +foreign import ccall "clGetDeviceIDs" raw_clGetDeviceIDs :: + CLPlatformID -> CLDeviceType_ -> CLuint -> Ptr CLDeviceID -> Ptr CLuint -> IO CLint+foreign import ccall "clGetDeviceInfo" raw_clGetDeviceInfo :: + CLDeviceID -> CLDeviceInfo_ -> CSize -> Ptr () -> Ptr CSize -> IO CLint++#include <CL/cl.h>++-- -----------------------------------------------------------------------------+getNumPlatforms :: IO (Either CLError CLuint)+getNumPlatforms = alloca $ \(num_platforms :: Ptr CLuint) -> do + whenSuccess (raw_clGetPlatformIDs 0 nullPtr num_platforms) + $ peek num_platforms++-- | Obtain the list of platforms available. Returns the list if the function +-- is executed successfully. Otherwise it returns the empty list.+clGetPlatformIDs :: IO (Either CLError [CLPlatformID])+clGetPlatformIDs = do+ nplats <- getNumPlatforms+ case nplats of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(plats :: Ptr CLPlatformID) -> do+ whenSuccess (raw_clGetPlatformIDs n plats nullPtr) + $ peekArray (fromIntegral n) plats+ +getPlatformInfoSize :: CLPlatformID -> CLuint -> IO (Either CLError CSize)+getPlatformInfoSize platform infoid = alloca $ \(value_size :: Ptr CSize) -> do+ whenSuccess (raw_clGetPlatformInfo platform infoid 0 nullPtr value_size) + $ peek value_size+ +-- | Get specific information about the OpenCL platform. It returns Nothing if+-- platform is not a valid platform.+clGetPlatformInfo :: CLPlatformID -> CLPlatformInfo -> IO (Either CLError String)+clGetPlatformInfo platform infoid = do+ sval <- getPlatformInfoSize platform infocl+ case sval of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(buff :: CString) -> do+ whenSuccess (raw_clGetPlatformInfo platform infocl n (castPtr buff) nullPtr)+ $ peekCString buff+ where+ infocl = getCLValue infoid++-- -----------------------------------------------------------------------------+getNumDevices :: CLPlatformID -> CLDeviceType_ -> IO (Either CLError CLuint)+getNumDevices platform dtype = alloca $ \(num_devices :: Ptr CLuint) -> do+ whenSuccess (raw_clGetDeviceIDs platform dtype 0 nullPtr num_devices)+ $ peek num_devices++-- | Obtain the list of devices available on a platform. Returns the list if +-- the function is executed successfully. Otherwise it returns the empty list +-- if platform is not a valid platform or no OpenCL devices that matched +-- device_type were found.+clGetDeviceIDs :: CLPlatformID -> CLDeviceType -> IO (Either CLError [CLDeviceID])+clGetDeviceIDs platform dtype = do+ ndevs <- getNumDevices platform dval+ case ndevs of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(devs :: Ptr CLDeviceID) -> do+ whenSuccess (raw_clGetDeviceIDs platform dval n devs nullPtr)+ $ peekArray (fromIntegral n) devs+ where+ dval = getCLValue dtype++getDeviceInfoSize :: CLDeviceID -> CLDeviceInfo_ -> IO (Either CLError CSize)+getDeviceInfoSize device infoid = alloca $ \(value_size :: Ptr CSize) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid 0 nullPtr value_size)+ $ peek value_size+ +getDeviceInfoString :: CLDeviceInfo_ -> CLDeviceID -> IO (Either CLError String)+getDeviceInfoString infoid device = do+ sval <- getDeviceInfoSize device infoid+ case sval of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(buff :: CString) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid n (castPtr buff) nullPtr)+ $ peekCString buff+ +getDeviceInfoUint :: CLDeviceInfo_ -> CLDeviceID -> IO (Either CLError CLuint)+getDeviceInfoUint infoid device = alloca $ \(dat :: Ptr CLuint) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid size (castPtr dat) nullPtr)+ $ peek dat+ where + size = fromIntegral $ sizeOf (0::CLuint)++getDeviceInfoUlong :: CLDeviceInfo_ -> CLDeviceID -> IO (Either CLError CLulong)+getDeviceInfoUlong infoid device = alloca $ \(dat :: Ptr CLulong) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid size (castPtr dat) nullPtr)+ $ peek dat+ where + size = fromIntegral $ sizeOf (0::CLulong)++getDeviceInfoSizet :: CLDeviceInfo_ -> CLDeviceID -> IO (Either CLError CSize)+getDeviceInfoSizet infoid device = alloca $ \(dat :: Ptr CSize) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid size (castPtr dat) nullPtr)+ $ peek dat+ where + size = fromIntegral $ sizeOf (0::CSize)+ +getDeviceInfoBool :: CLDeviceInfo_ -> CLDeviceID -> IO (Either CLError Bool)+getDeviceInfoBool infoid device = alloca $ \(dat :: Ptr CLbool) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid size (castPtr dat) nullPtr)+ $ peek dat >>= return . (/=0)+ where + size = fromIntegral $ sizeOf (0::CLbool)+ +getDeviceInfoFP :: CLDeviceInfo_ -> CLDeviceID -> IO (Either CLError [CLDeviceFPConfig])+getDeviceInfoFP infoid device = do+ val <- getDeviceInfoUlong infoid device+ case val of+ Left err -> return . Left $ err+ Right flags -> return . Right . bitmaskToFPConfig $ flags++#c+enum CLDeviceInfo {+ cL_DEVICE_ADDRESS_BITS=CL_DEVICE_ADDRESS_BITS,+ cL_DEVICE_AVAILABLE=CL_DEVICE_AVAILABLE,+ cL_DEVICE_COMPILER_AVAILABLE=CL_DEVICE_COMPILER_AVAILABLE,+#ifdef CL_DEVICE_DOUBLE_FP_CONFIG + cL_DEVICE_DOUBLE_FP_CONFIG=CL_DEVICE_DOUBLE_FP_CONFIG,+#else+ cL_DEVICE_DOUBLE_FP_CONFIG=0x1032,+#endif+ cL_DEVICE_ENDIAN_LITTLE=CL_DEVICE_ENDIAN_LITTLE,+ cL_DEVICE_ERROR_CORRECTION_SUPPORT=CL_DEVICE_ERROR_CORRECTION_SUPPORT,+ cL_DEVICE_EXECUTION_CAPABILITIES=CL_DEVICE_EXECUTION_CAPABILITIES,+ cL_DEVICE_EXTENSIONS=CL_DEVICE_EXTENSIONS,+ cL_DEVICE_GLOBAL_MEM_CACHE_SIZE=CL_DEVICE_GLOBAL_MEM_CACHE_SIZE,+ cL_DEVICE_GLOBAL_MEM_CACHE_TYPE=CL_DEVICE_GLOBAL_MEM_CACHE_TYPE,+ cL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE=CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE,+ cL_DEVICE_GLOBAL_MEM_SIZE=CL_DEVICE_GLOBAL_MEM_SIZE,+#ifdef CL_DEVICE_HALF_FP_CONFIG+ cL_DEVICE_HALF_FP_CONFIG=CL_DEVICE_HALF_FP_CONFIG,+#else+ cL_DEVICE_HALF_FP_CONFIG=0x1033,+#endif+ cL_DEVICE_IMAGE_SUPPORT=CL_DEVICE_IMAGE_SUPPORT,+ cL_DEVICE_IMAGE2D_MAX_HEIGHT=CL_DEVICE_IMAGE2D_MAX_HEIGHT,+ cL_DEVICE_IMAGE2D_MAX_WIDTH=CL_DEVICE_IMAGE2D_MAX_WIDTH,+ cL_DEVICE_IMAGE3D_MAX_DEPTH=CL_DEVICE_IMAGE3D_MAX_DEPTH,+ cL_DEVICE_IMAGE3D_MAX_HEIGHT=CL_DEVICE_IMAGE3D_MAX_HEIGHT,+ cL_DEVICE_IMAGE3D_MAX_WIDTH=CL_DEVICE_IMAGE3D_MAX_WIDTH,+ cL_DEVICE_LOCAL_MEM_SIZE=CL_DEVICE_LOCAL_MEM_SIZE,+ cL_DEVICE_LOCAL_MEM_TYPE=CL_DEVICE_LOCAL_MEM_TYPE,+ cL_DEVICE_MAX_CLOCK_FREQUENCY=CL_DEVICE_MAX_CLOCK_FREQUENCY,+ cL_DEVICE_MAX_COMPUTE_UNITS=CL_DEVICE_MAX_COMPUTE_UNITS,+ cL_DEVICE_MAX_CONSTANT_ARGS=CL_DEVICE_MAX_CONSTANT_ARGS,+ cL_DEVICE_MAX_CONSTANT_BUFFER_SIZE=CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,+ cL_DEVICE_MAX_MEM_ALLOC_SIZE=CL_DEVICE_MAX_MEM_ALLOC_SIZE,+ cL_DEVICE_MAX_PARAMETER_SIZE=CL_DEVICE_MAX_PARAMETER_SIZE,+ cL_DEVICE_MAX_READ_IMAGE_ARGS=CL_DEVICE_MAX_READ_IMAGE_ARGS,+ cL_DEVICE_MAX_SAMPLERS=CL_DEVICE_MAX_SAMPLERS,+ cL_DEVICE_MAX_WORK_GROUP_SIZE=CL_DEVICE_MAX_WORK_GROUP_SIZE,+ cL_DEVICE_MAX_WORK_ITEM_DIMENSIONS=CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,+ cL_DEVICE_MAX_WORK_ITEM_SIZES=CL_DEVICE_MAX_WORK_ITEM_SIZES,+ cL_DEVICE_MAX_WRITE_IMAGE_ARGS=CL_DEVICE_MAX_WRITE_IMAGE_ARGS,+ cL_DEVICE_MEM_BASE_ADDR_ALIGN=CL_DEVICE_MEM_BASE_ADDR_ALIGN,+ cL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE=CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE,+ cL_DEVICE_NAME=CL_DEVICE_NAME,+ cL_DEVICE_PLATFORM=CL_DEVICE_PLATFORM,+ cL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR=CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR,+ cL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT=CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT,+ cL_DEVICE_PREFERRED_VECTOR_WIDTH_INT=CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT,+ cL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG=CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG,+ cL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT=CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT,+ cL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE=CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE,+ cL_DEVICE_PROFILE=CL_DEVICE_PROFILE,+ cL_DEVICE_PROFILING_TIMER_RESOLUTION=CL_DEVICE_PROFILING_TIMER_RESOLUTION,+ cL_DEVICE_QUEUE_PROPERTIES=CL_DEVICE_QUEUE_PROPERTIES,+ cL_DEVICE_SINGLE_FP_CONFIG=CL_DEVICE_SINGLE_FP_CONFIG,+ cL_DEVICE_TYPE=CL_DEVICE_TYPE,+ cL_DEVICE_VENDOR=CL_DEVICE_VENDOR,+ cL_DEVICE_VENDOR_ID=CL_DEVICE_VENDOR_ID,+ cL_DEVICE_VERSION=CL_DEVICE_VERSION,+ cL_DRIVER_VERSION=CL_DRIVER_VERSION,+ };+#endc+{#enum CLDeviceInfo {upcaseFirstLetter} #}++-- | The default compute device address space size specified as an unsigned +-- integer value in bits. Currently supported values are 32 or 64 bits.+clGetDeviceAddressBits :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceAddressBits = getDeviceInfoUint . getCLValue $ CL_DEVICE_ADDRESS_BITS++-- | Is 'True' if the device is available and 'False' if the device is not +-- available.+clGetDeviceAvailable :: CLDeviceID -> IO (Either CLError Bool)+clGetDeviceAvailable = getDeviceInfoBool . getCLValue $ CL_DEVICE_AVAILABLE++-- | Is 'False' if the implementation does not have a compiler available to +-- compile the program source. Is 'True' if the compiler is available. This can +-- be 'False' for the embededed platform profile only.+clGetDeviceCompilerAvailable :: CLDeviceID -> IO (Either CLError Bool)+clGetDeviceCompilerAvailable = getDeviceInfoBool . getCLValue $ CL_DEVICE_COMPILER_AVAILABLE++-- | Describes the OPTIONAL double precision floating-point capability of the +-- OpenCL device. This is a bit-field that describes one or more of the +-- 'CLDeviceFPConfig' values.+-- The mandated minimum double precision floating-point capability is +-- 'CL_FP_FMA' | 'CL_FP_ROUND_TO_NEAREST' | 'CL_FP_ROUND_TO_ZERO' | +-- 'CL_FP_ROUND_TO_INF' | 'CL_FP_INF_NAN' | 'CL_FP_DENORM'.+clGetDeviceDoubleFPConfig :: CLDeviceID -> IO (Either CLError [CLDeviceFPConfig])+clGetDeviceDoubleFPConfig = getDeviceInfoFP . getCLValue $ CL_DEVICE_DOUBLE_FP_CONFIG++-- | Is 'True' if the OpenCL device is a little endian device and 'False' +-- otherwise.+clGetDeviceEndianLittle :: CLDeviceID -> IO (Either CLError Bool)+clGetDeviceEndianLittle = getDeviceInfoBool . getCLValue $ CL_DEVICE_ENDIAN_LITTLE++-- | Is 'True' if the device implements error correction for the memories, +-- caches, registers etc. in the device. Is 'False' if the device does not +-- implement error correction. This can be a requirement for certain clients of +-- OpenCL.+clGetDeviceErrorCorrectionSupport :: CLDeviceID -> IO (Either CLError Bool)+clGetDeviceErrorCorrectionSupport = getDeviceInfoBool . getCLValue $ CL_DEVICE_ERROR_CORRECTION_SUPPORT++-- | Describes the execution capabilities of the device. This is a list that +-- describes one or more of the 'CLDeviceExecCapability' values.+-- The mandated minimum capability is 'CL_EXEC_KERNEL'.+clGetDeviceExecutionCapabilities :: CLDeviceID -> IO (Either CLError [CLDeviceExecCapability])+clGetDeviceExecutionCapabilities device = do+ val <- getDeviceInfoUlong (getCLValue CL_DEVICE_EXECUTION_CAPABILITIES) device+ case val of+ Left err -> return . Left $ err+ Right flags -> return . Right . bitmaskToExecCapability $ flags++-- | Returns a space separated list of extension names (the extension names +-- themselves do not contain any spaces). The list of extension names returned +-- currently can include one or more of the following approved extension names:+--+-- * cl_khr_fp64+--+-- * cl_khr_select_fprounding_mode+--+-- * cl_khr_global_int32_base_atomics+--+-- * cl_khr_global_int32_extended_atomics+--+-- * cl_khr_local_int32_base_atomics+--+-- * cl_khr_local_int32_extended_atomics+--+-- * cl_khr_int64_base_atomics+--+-- * cl_khr_int64_extended_atomics+--+-- * cl_khr_3d_image_writes+--+-- * cl_khr_byte_addressable_store+--+-- * cl_khr_fp16+clGetDeviceExtensions :: CLDeviceID -> IO (Either CLError String)+clGetDeviceExtensions = getDeviceInfoString . getCLValue $ CL_DEVICE_EXTENSIONS++-- | Size of global memory cache in bytes.+clGetDeviceGlobalMemCacheSize :: CLDeviceID -> IO (Either CLError CLulong)+clGetDeviceGlobalMemCacheSize = getDeviceInfoUlong . getCLValue $ CL_DEVICE_GLOBAL_MEM_CACHE_SIZE++-- | Type of global memory cache supported. Valid values are: 'CL_NONE', +-- 'CL_READ_ONLY_CACHE', and 'CL_READ_WRITE_CACHE'.+clGetDeviceGlobalMemCacheType :: CLDeviceID -> IO (Either CLError CLDeviceMemCacheType)+clGetDeviceGlobalMemCacheType device = do+ val <- getDeviceInfoUint (getCLValue CL_DEVICE_GLOBAL_MEM_CACHE_TYPE) device + case val of+ Left err -> return . Left $ err+ Right typ -> return . Right . getEnumCL $ typ++-- | Size of global memory cache line in bytes.+clGetDeviceGlobalMemCachelineSize :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceGlobalMemCachelineSize = getDeviceInfoUint . getCLValue $ CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE++-- | Size of global device memory in bytes.+clGetDeviceGlobalMemSize :: CLDeviceID -> IO (Either CLError CLulong)+clGetDeviceGlobalMemSize = getDeviceInfoUlong . getCLValue $ CL_DEVICE_GLOBAL_MEM_SIZE++-- | Describes the OPTIONAL half precision floating-point capability of the +-- OpenCL device. This is a bit-field that describes one or more of the +-- 'CLDeviceFPConfig' values.+-- The required minimum half precision floating-point capability as implemented +-- by this extension is 'CL_FP_ROUND_TO_ZERO' | 'CL_FP_ROUND_TO_INF' | +-- 'CL_FP_INF_NAN'.+clGetDeviceHalfFPConfig :: CLDeviceID -> IO (Either CLError [CLDeviceFPConfig])+clGetDeviceHalfFPConfig = getDeviceInfoFP . getCLValue $ CL_DEVICE_HALF_FP_CONFIG++-- | Is 'True' if images are supported by the OpenCL device and 'False' otherwise.+clGetDeviceImageSupport :: CLDeviceID -> IO (Either CLError Bool)+clGetDeviceImageSupport = getDeviceInfoBool . getCLValue $ CL_DEVICE_IMAGE_SUPPORT++-- | Max height of 2D image in pixels. The minimum value is 8192 if+-- 'clGetDeviceImageSupport' is 'True'.+clGetDeviceImage2DMaxHeight :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceImage2DMaxHeight = getDeviceInfoSizet . getCLValue $ CL_DEVICE_IMAGE2D_MAX_HEIGHT++-- | Max width of 2D image in pixels. The minimum value is 8192 if+-- 'clGetDeviceImageSupport' is 'True'.+clGetDeviceImage2DMaxWidth :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceImage2DMaxWidth = getDeviceInfoSizet . getCLValue $ CL_DEVICE_IMAGE2D_MAX_WIDTH++-- | Max depth of 3D image in pixels. The minimum value is 2048 if +-- 'clGetDeviceImageSupport' is 'True'.+clGetDeviceImage3DMaxDepth :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceImage3DMaxDepth = getDeviceInfoSizet . getCLValue $ CL_DEVICE_IMAGE3D_MAX_DEPTH++-- | Max height of 3D image in pixels. The minimum value is 2048 if +-- 'clGetDeviceImageSupport' is 'True'.+clGetDeviceImage3DMaxHeight :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceImage3DMaxHeight = getDeviceInfoSizet . getCLValue $ CL_DEVICE_IMAGE3D_MAX_HEIGHT++-- | Max width of 3D image in pixels. The minimum value is 2048 if +-- 'clGetDeviceImageSupport' is 'True'.+clGetDeviceImage3DMaxWidth :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceImage3DMaxWidth = getDeviceInfoSizet . getCLValue $ CL_DEVICE_IMAGE3D_MAX_WIDTH++-- | Size of local memory arena in bytes. The minimum value is 16 KB.+clGetDeviceLocalMemSize :: CLDeviceID -> IO (Either CLError CLulong)+clGetDeviceLocalMemSize = getDeviceInfoUlong . getCLValue $ CL_DEVICE_LOCAL_MEM_SIZE++-- | Type of local memory supported. This can be set to 'CL_LOCAL' implying +-- dedicated local memory storage such as SRAM, or 'CL_GLOBAL'.+clGetDeviceLocalMemType :: CLDeviceID -> IO (Either CLError CLDeviceLocalMemType)+clGetDeviceLocalMemType device = do+ val <- getDeviceInfoUint (getCLValue CL_DEVICE_LOCAL_MEM_TYPE) device + case val of+ Left err -> return . Left $ err+ Right typ -> return . Right . getEnumCL $ typ++-- | Maximum configured clock frequency of the device in MHz.+clGetDeviceMaxClockFrequency :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMaxClockFrequency = getDeviceInfoUint . getCLValue $ CL_DEVICE_MAX_CLOCK_FREQUENCY++-- | The number of parallel compute cores on the OpenCL device. The minimum +-- value is 1.+clGetDeviceMaxComputeUnits :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMaxComputeUnits = getDeviceInfoUint . getCLValue $ CL_DEVICE_MAX_COMPUTE_UNITS++-- | Max number of arguments declared with the __constant qualifier in a kernel. +-- The minimum value is 8.+clGetDeviceMaxConstantArgs :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMaxConstantArgs = getDeviceInfoUint . getCLValue $ CL_DEVICE_MAX_CONSTANT_ARGS++-- | Max size in bytes of a constant buffer allocation. The minimum value is +-- 64 KB.+clGetDeviceMaxConstantBufferSize :: CLDeviceID -> IO (Either CLError CLulong)+clGetDeviceMaxConstantBufferSize = getDeviceInfoUlong . getCLValue $ CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE++-- | Max size of memory object allocation in bytes. The minimum value is max +-- (1/4th of 'clGetDeviceGlobalMemSize', 128*1024*1024)+clGetDeviceMaxMemAllocSize :: CLDeviceID -> IO (Either CLError CLulong)+clGetDeviceMaxMemAllocSize = getDeviceInfoUlong . getCLValue $ CL_DEVICE_MAX_MEM_ALLOC_SIZE++-- | Max size in bytes of the arguments that can be passed to a kernel. The +-- minimum value is 256.+clGetDeviceMaxParameterSize :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceMaxParameterSize = getDeviceInfoSizet . getCLValue $ CL_DEVICE_MAX_PARAMETER_SIZE++-- | Max number of simultaneous image objects that can be read by a kernel. The +-- minimum value is 128 if 'clGetDeviceImageSupport' is 'True'.+clGetDeviceMaxReadImageArgs :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMaxReadImageArgs = getDeviceInfoUint . getCLValue $ CL_DEVICE_MAX_READ_IMAGE_ARGS++-- | Maximum number of samplers that can be used in a kernel. The minimum value +-- is 16 if 'clGetDeviceImageSupport' is 'True'. (Also see sampler type.)+clGetDeviceMaxSamplers :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMaxSamplers = getDeviceInfoUint . getCLValue $ CL_DEVICE_MAX_SAMPLERS++-- | Maximum number of work-items in a work-group executing a kernel using the +-- data parallel execution model. (Refer to 'clEnqueueNDRangeKernel'). The +-- minimum value is 1.+clGetDeviceMaxWorkGroupSize :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceMaxWorkGroupSize = getDeviceInfoSizet . getCLValue $ CL_DEVICE_MAX_WORK_GROUP_SIZE++-- | Maximum dimensions that specify the global and local work-item IDs used by +-- the data parallel execution model. (Refer to 'clEnqueueNDRangeKernel'). +-- The minimum value is 3.+clGetDeviceMaxWorkItemDimensions :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMaxWorkItemDimensions = getDeviceInfoUint . getCLValue $ CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS++-- | Maximum number of work-items that can be specified in each dimension of the +-- work-group to 'clEnqueueNDRangeKernel'.+-- Returns n entries, where n is the value returned by the query for +-- clDeviceMaxWorkItemDimensions. The minimum value is (1, 1, 1).+clGetDeviceMaxWorkItemSizes :: CLDeviceID -> IO (Either CLError [CSize])+clGetDeviceMaxWorkItemSizes device = do+ val <- clGetDeviceMaxWorkItemDimensions device+ case val of+ Left err -> return . Left $ err+ Right n -> allocaArray (fromIntegral n) $ \(buff :: Ptr CSize) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid (size n) (castPtr buff) nullPtr)+ $ peekArray (fromIntegral n) buff+ where+ infoid = getCLValue CL_DEVICE_MAX_WORK_ITEM_SIZES+ size n = fromIntegral $ (fromIntegral n) * (sizeOf (0::CSize))++-- | Max number of simultaneous image objects that can be written to by a +-- kernel. The minimum value is 8 if 'clGetDeviceImageSupport' is 'True'.+clGetDeviceMaxWriteImageArgs :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMaxWriteImageArgs = getDeviceInfoUint . getCLValue $ CL_DEVICE_MAX_WRITE_IMAGE_ARGS++-- | Describes the alignment in bits of the base address of any allocated +-- memory object.+clGetDeviceMemBaseAddrAlign :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMemBaseAddrAlign = getDeviceInfoUint . getCLValue $ CL_DEVICE_MEM_BASE_ADDR_ALIGN++-- | The smallest alignment in bytes which can be used for any data type.+clGetDeviceMinDataTypeAlignSize :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceMinDataTypeAlignSize = getDeviceInfoUint . getCLValue $ CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE++-- | Device name string.+clGetDeviceName :: CLDeviceID -> IO (Either CLError String)+clGetDeviceName = getDeviceInfoString . getCLValue $ CL_DEVICE_NAME++-- | The platform associated with this device.+clGetDevicePlatform :: CLDeviceID -> IO (Either CLError CLPlatformID)+clGetDevicePlatform device = alloca $ \(dat :: Ptr CLPlatformID) -> do+ whenSuccess (raw_clGetDeviceInfo device infoid size (castPtr dat) nullPtr)+ $ peek dat+ where + infoid = getCLValue CL_DEVICE_PLATFORM+ size = fromIntegral $ sizeOf (nullPtr :: CLPlatformID)++-- | Preferred native vector width size for built-in char types that can be put +-- into vectors. The vector width is defined as the number of scalar elements +-- that can be stored in the vector.+clGetDevicePreferredVectorWidthChar :: CLDeviceID -> IO (Either CLError CLuint)+clGetDevicePreferredVectorWidthChar = getDeviceInfoUint . getCLValue $ CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR++-- | Preferred native vector width size for built-in short types that can be put +-- into vectors. The vector width is defined as the number of scalar elements +-- that can be stored in the vector.+clGetDevicePreferredVectorWidthShort :: CLDeviceID -> IO (Either CLError CLuint)+clGetDevicePreferredVectorWidthShort = getDeviceInfoUint . getCLValue $ CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT++-- | Preferred native vector width size for built-in int types that can be put +-- into vectors. The vector width is defined as the number of scalar elements +-- that can be stored in the vector.+clGetDevicePreferredVectorWidthInt :: CLDeviceID -> IO (Either CLError CLuint)+clGetDevicePreferredVectorWidthInt = getDeviceInfoUint . getCLValue $ CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT++-- | Preferred native vector width size for built-in long types that can be put +-- into vectors. The vector width is defined as the number of scalar elements +-- that can be stored in the vector.+clGetDevicePreferredVectorWidthLong :: CLDeviceID -> IO (Either CLError CLuint)+clGetDevicePreferredVectorWidthLong = getDeviceInfoUint . getCLValue $ CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG++-- | Preferred native vector width size for built-in float types that can be put +-- into vectors. The vector width is defined as the number of scalar elements +-- that can be stored in the vector.+clGetDevicePreferredVectorWidthFloat :: CLDeviceID -> IO (Either CLError CLuint)+clGetDevicePreferredVectorWidthFloat = getDeviceInfoUint . getCLValue $ CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT++-- | Preferred native vector width size for built-in double types that can be put +-- into vectors. The vector width is defined as the number of scalar elements +-- that can be stored in the vector.+-- | If the cl_khr_fp64 extension is not supported, +-- 'clGetDevicePreferredVectorWidthDouble' must return 0.+clGetDevicePreferredVectorWidthDouble :: CLDeviceID -> IO (Either CLError CLuint)+clGetDevicePreferredVectorWidthDouble = getDeviceInfoUint . getCLValue $ CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE++-- | OpenCL profile string. Returns the profile name supported by the device +-- (see note). The profile name returned can be one of the following strings:+-- +-- * FULL_PROFILE - if the device supports the OpenCL specification +-- (functionality defined as part of the core specification and does not require +-- any extensions to be supported).+-- +-- * EMBEDDED_PROFILE - if the device supports the OpenCL embedded profile.+clGetDeviceProfile :: CLDeviceID -> IO (Either CLError String)+clGetDeviceProfile = getDeviceInfoString . getCLValue $ CL_DEVICE_PROFILE++-- | Describes the resolution of device timer. This is measured in nanoseconds.+clGetDeviceProfilingTimerResolution :: CLDeviceID -> IO (Either CLError CSize)+clGetDeviceProfilingTimerResolution = getDeviceInfoSizet . getCLValue $ CL_DEVICE_PROFILING_TIMER_RESOLUTION++-- | Describes the command-queue properties supported by the device. This is a +-- list that describes one or more of the CLCommandQueueProperty values.+-- These properties are described in the table for 'clCreateCommandQueue'. +-- The mandated minimum capability is 'CL_QUEUE_PROFILING_ENABLE'.+clGetDeviceQueueProperties :: CLDeviceID -> IO (Either CLError [CLCommandQueueProperty])+clGetDeviceQueueProperties device = do+ val <- getDeviceInfoUlong (getCLValue CL_DEVICE_QUEUE_PROPERTIES) device+ case val of+ Left err -> return . Left $ err+ Right flags -> return . Right . bitmaskToCommandQueueProperties $ flags+ +-- | Describes single precision floating-point capability of the device. This is +-- a bit-field that describes one or more of the 'CLDeviceFPConfig' values.+-- The mandated minimum floating-point capability is 'CL_FP_ROUND_TO_NEAREST' | +-- 'CL_FP_INF_NAN'.+clGetDeviceSingleFPConfig :: CLDeviceID -> IO (Either CLError [CLDeviceFPConfig])+clGetDeviceSingleFPConfig = getDeviceInfoFP . getCLValue $ CL_DEVICE_SINGLE_FP_CONFIG++-- | The OpenCL device type. Currently supported values are one of or a +-- combination of: 'CL_DEVICE_TYPE_CPU', 'CL_DEVICE_TYPE_GPU', +-- 'CL_DEVICE_TYPE_ACCELERATOR', or 'CL_DEVICE_TYPE_DEFAULT'.+clGetDeviceType :: CLDeviceID -> IO (Either CLError [CLDeviceType])+clGetDeviceType device = do+ val <- getDeviceInfoUlong (getCLValue CL_DEVICE_TYPE) device+ case val of+ Left err -> return . Left $ err+ Right flags -> return . Right . bitmaskToDeviceTypes $ flags++-- | Vendor name string.+clGetDeviceVendor :: CLDeviceID -> IO (Either CLError String)+clGetDeviceVendor = getDeviceInfoString . getCLValue $ CL_DEVICE_VENDOR++-- | A unique device vendor identifier. An example of a unique device identifier +-- could be the PCIe ID.+clGetDeviceVendorID :: CLDeviceID -> IO (Either CLError CLuint)+clGetDeviceVendorID = getDeviceInfoUint . getCLValue $ CL_DEVICE_VENDOR_ID++-- | OpenCL version string. Returns the OpenCL version supported by the device. +-- This version string has the following format:+-- /OpenCL major_version.minor_version vendor-specific information/+-- The major_version.minor_version value returned will be 1.0.+clGetDeviceVersion :: CLDeviceID -> IO (Either CLError String)+clGetDeviceVersion = getDeviceInfoString . getCLValue $ CL_DEVICE_VERSION++-- | OpenCL software driver version string in the form major_number.minor_number.+clGetDeviceDriverVersion :: CLDeviceID -> IO (Either CLError String)+clGetDeviceDriverVersion = getDeviceInfoString . getCLValue $ CL_DRIVER_VERSION++-- -----------------------------------------------------------------------------
+ src/System/GPU/OpenCL/Types.chs view
@@ -0,0 +1,692 @@+-- -----------------------------------------------------------------------------+-- This file is part of Haskell-Opencl.++-- Haskell-Opencl is free software: you can redistribute it and/or modify+-- it under the terms of the GNU General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.++-- Haskell-Opencl is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+-- GNU General Public License for more details.++-- You should have received a copy of the GNU General Public License+-- along with Haskell-Opencl. If not, see <http://www.gnu.org/licenses/>.+-- -----------------------------------------------------------------------------+module System.GPU.OpenCL.Types( + -- * Symple CL Types+ CLbool, CLint, CLuint, CLulong, CLProgram, CLEvent, CLMem, CLPlatformID, + CLDeviceID, CLContext, CLCommandQueue, CLPlatformInfo_, CLDeviceType_, + CLDeviceInfo_, CLContextInfo_, CLContextProperty_, CLCommandQueueInfo_, + CLEventInfo_, CLProfilingInfo_, CLCommandType_, CLCommandQueueProperty_, + CLMemFlags_, CLImageFormat_p, CLMemObjectType_, CLMemInfo_, CLImageInfo_,+ CLProgramInfo_, CLBuildStatus_,CLKernel, CLProgramBuildInfo_, CLKernelInfo_,+ CLKernelWorkGroupInfo_, CLDeviceLocalMemType_, CLDeviceMemCacheType_,+ CLSampler, CLFilterMode_, CLSamplerInfo_, CLAddressingMode_,+ -- * High Level Types+ CLError(..), CLDeviceFPConfig(..), CLDeviceMemCacheType(..), + CLDeviceExecCapability(..), CLDeviceLocalMemType(..), CLDeviceType(..), + CLCommandQueueProperty(..), CLCommandType(..), CLCommandExecutionStatus(..), + CLProfilingInfo(..), CLPlatformInfo(..), CLMemFlag(..), CLMemObjectType(..),+ CLBuildStatus(..), CLAddressingMode(..), CLFilterMode(..),+ -- * Functions+ wrapPError, wrapCheckSuccess, wrapGetInfo, whenSuccess, getCLValue, + getEnumCL, bitmaskToFlags, getCommandExecutionStatus, bitmaskToDeviceTypes, + bitmaskFromFlags, bitmaskToCommandQueueProperties, bitmaskToFPConfig, + bitmaskToExecCapability, bitmaskToMemFlags )+ where++-- -----------------------------------------------------------------------------+import Foreign+import Foreign.C.Types+import Data.List( foldl' )++#include <CL/cl.h>++-- -----------------------------------------------------------------------------++type CLPlatformID = {#type cl_platform_id#}+type CLDeviceID = {#type cl_device_id#}+type CLContext = {#type cl_context#}+type CLCommandQueue = {#type cl_command_queue#}+type CLMem = {#type cl_mem#}+type CLEvent = {#type cl_event#}+type CLProgram = {#type cl_program#}+type CLKernel = {#type cl_kernel#}+type CLSampler = {#type cl_sampler#}++type CLint = {#type cl_int#}+type CLuint = {#type cl_uint#}+type CLulong = {#type cl_ulong#}+type CLbool = {#type cl_bool#}++type CLPlatformInfo_ = {#type cl_platform_info#}+type CLDeviceType_ = {#type cl_device_type#}+type CLDeviceInfo_ = {#type cl_device_info#}+type CLDeviceFPConfig_ = {#type cl_device_fp_config#}+type CLDeviceMemCacheType_ = {#type cl_device_mem_cache_type#}+type CLDeviceLocalMemType_ = {#type cl_device_local_mem_type#}+type CLDeviceExecCapability_ = {#type cl_device_exec_capabilities#}+type CLContextInfo_ = {#type cl_context_info#}+type CLContextProperty_ = {#type cl_context_properties#}+type CLCommandQueueInfo_ = {#type cl_command_queue_info#}+type CLCommandQueueProperty_ = {#type cl_command_queue_properties#}+type CLEventInfo_ = {#type cl_event_info#}+type CLProfilingInfo_ = {#type cl_profiling_info#}+type CLCommandType_ = {#type cl_command_type#}+type CLMemFlags_ = {#type cl_mem_flags#}+type CLMemObjectType_ = {#type cl_mem_object_type#}+type CLMemInfo_ = {#type cl_mem_info#}+type CLImageInfo_ = {#type cl_image_info#}+type CLProgramInfo_ = {#type cl_program_info#}+type CLProgramBuildInfo_ = {#type cl_program_build_info#}+type CLBuildStatus_ = {#type cl_build_status#}+type CLKernelInfo_ = {#type cl_kernel_info#}+type CLKernelWorkGroupInfo_ = {#type cl_kernel_work_group_info#}+type CLFilterMode_ = {#type cl_filter_mode#}+type CLSamplerInfo_ = {#type cl_sampler_info#}+type CLAddressingMode_ = {#type cl_addressing_mode#}++{#pointer *cl_image_format as CLImageFormat_p#}++--type CLImageChannelOrder_ = {#type cl_channel_order#}+--type CLImageChannelDataType_ = {#type cl_channel_type#}++-- -----------------------------------------------------------------------------+#c+enum CLError {+ cL_BUILD_PROGRAM_FAILURE=CL_BUILD_PROGRAM_FAILURE,+ cL_COMPILER_NOT_AVAILABLE=CL_COMPILER_NOT_AVAILABLE,+ cL_DEVICE_NOT_AVAILABLE=CL_DEVICE_NOT_AVAILABLE,+ cL_DEVICE_NOT_FOUND=CL_DEVICE_NOT_FOUND,+ cL_IMAGE_FORMAT_MISMATCH=CL_IMAGE_FORMAT_MISMATCH,+ cL_IMAGE_FORMAT_NOT_SUPPORTED=CL_IMAGE_FORMAT_NOT_SUPPORTED,+ cL_INVALID_ARG_INDEX=CL_INVALID_ARG_INDEX,+ cL_INVALID_ARG_SIZE=CL_INVALID_ARG_SIZE,+ cL_INVALID_ARG_VALUE=CL_INVALID_ARG_VALUE,+ cL_INVALID_BINARY=CL_INVALID_BINARY,+ cL_INVALID_BUFFER_SIZE=CL_INVALID_BUFFER_SIZE,+ cL_INVALID_BUILD_OPTIONS=CL_INVALID_BUILD_OPTIONS,+ cL_INVALID_COMMAND_QUEUE=CL_INVALID_COMMAND_QUEUE,+ cL_INVALID_CONTEXT=CL_INVALID_CONTEXT,+ cL_INVALID_DEVICE=CL_INVALID_DEVICE,+ cL_INVALID_DEVICE_TYPE=CL_INVALID_DEVICE_TYPE,+ cL_INVALID_EVENT=CL_INVALID_EVENT,+ cL_INVALID_EVENT_WAIT_LIST=CL_INVALID_EVENT_WAIT_LIST,+ cL_INVALID_GL_OBJECT=CL_INVALID_GL_OBJECT,+ cL_INVALID_GLOBAL_OFFSET=CL_INVALID_GLOBAL_OFFSET,+ cL_INVALID_HOST_PTR=CL_INVALID_HOST_PTR,+ cL_INVALID_IMAGE_FORMAT_DESCRIPTOR=CL_INVALID_IMAGE_FORMAT_DESCRIPTOR,+ cL_INVALID_IMAGE_SIZE=CL_INVALID_IMAGE_SIZE,+ cL_INVALID_KERNEL_NAME=CL_INVALID_KERNEL_NAME,+ cL_INVALID_KERNEL=CL_INVALID_KERNEL,+ cL_INVALID_KERNEL_ARGS=CL_INVALID_KERNEL_ARGS,+ cL_INVALID_KERNEL_DEFINITION=CL_INVALID_KERNEL_DEFINITION,+ cL_INVALID_MEM_OBJECT=CL_INVALID_MEM_OBJECT,+ cL_INVALID_OPERATION=CL_INVALID_OPERATION,+ cL_INVALID_PLATFORM=CL_INVALID_PLATFORM,+ cL_INVALID_PROGRAM=CL_INVALID_PROGRAM,+ cL_INVALID_PROGRAM_EXECUTABLE=CL_INVALID_PROGRAM_EXECUTABLE,+ cL_INVALID_QUEUE_PROPERTIES=CL_INVALID_QUEUE_PROPERTIES,+ cL_INVALID_SAMPLER=CL_INVALID_SAMPLER,+ cL_INVALID_VALUE=CL_INVALID_VALUE,+ cL_INVALID_WORK_DIMENSION=CL_INVALID_WORK_DIMENSION,+ cL_INVALID_WORK_GROUP_SIZE=CL_INVALID_WORK_GROUP_SIZE,+ cL_INVALID_WORK_ITEM_SIZE=CL_INVALID_WORK_ITEM_SIZE,+ cL_MAP_FAILURE=CL_MAP_FAILURE,+ cL_MEM_OBJECT_ALLOCATION_FAILURE=CL_MEM_OBJECT_ALLOCATION_FAILURE,+ cL_MEM_COPY_OVERLAP=CL_MEM_COPY_OVERLAP,+ cL_OUT_OF_HOST_MEMORY=CL_OUT_OF_HOST_MEMORY,+ cL_OUT_OF_RESOURCES=CL_OUT_OF_RESOURCES,+ cL_PROFILING_INFO_NOT_AVAILABLE=CL_PROFILING_INFO_NOT_AVAILABLE,+ cL_SUCCESS=CL_SUCCESS+ };+#endc++{-| + * 'CL_BUILD_PROGRAM_FAILURE', Returned if there is a failure to build the+program executable.++ * 'CL_COMPILER_NOT_AVAILABLE', Returned if the parameter program is created with+'clCreateProgramWithSource' and a compiler is not available. For example+'clDeviceCompilerAvalaible' is set to 'False'.++ * 'CL_DEVICE_NOT_AVAILABLE', Returned if the specified device is not currently+available.++ * 'CL_DEVICE_NOT_FOUND', Returned if no OpenCL devices that match the specified+devices were found.++ * 'CL_IMAGE_FORMAT_MISMATCH', Returned if the specified source and destination+images are not valid image objects.++ * 'CL_IMAGE_FORMAT_NOT_SUPPORTED', Returned if the specified image format is not+supported.++ * 'CL_INVALID_ARG_INDEX', Returned if an invalid argument index is specified.++ * 'CL_INVALID_ARG_SIZE', Returned if argument size specified (arg_size) does not+match the size of the data type for an argument that is not a memory object, or+if the argument is a memory object and arg_size != sizeof(cl_mem) or if arg_size+is zero and the argument is declared with the __local qualifier or if the+argument is a sampler and arg_size != sizeof(cl_sampler).++ * 'CL_INVALID_ARG_VALUE', Returned if the argument value specified is NULL for+an argument that is not declared with the __local qualifier or vice-versa.++ * 'CL_INVALID_BINARY', Returned if the program binary is not a valid binary for+the specified device.++ * 'CL_INVALID_BUFFER_SIZE', Returned if the value of the parameter size is 0 or+is greater than 'clDeviceMaxMemAllocSize' for all devices specified in the+parameter context.++ * 'CL_INVALID_BUILD_OPTIONS', Returned if the specified build options are+invalid.++ * 'CL_INVALID_COMMAND_QUEUE', Returned if the specified command-queue is not a+valid command-queue.++ * 'CL_INVALID_CONTEXT', Returned if the specified context is not a valid OpenCL+context, or the context associated with certain parameters are not the same.++ * 'CL_INVALID_DEVICE', Returned if the device or devices specified are not+valid.++ * 'CL_INVALID_DEVICE_TYPE', Returned if device type specified is not valid.++ * 'CL_INVALID_EVENT', Returned if the event objects specified are not valid.++ * 'CL_INVALID_EVENT_WAIT_LIST', Returned if event_wait_list is NULL and+num_events_in_wait_list > 0, or event_wait_list_list is not NULL and+num_events_in_wait_list is 0, or specified event objects are not valid events.++ * 'CL_INVALID_GL_OBJECT', Returned if obj is not a vaild GL object or is a GL+object but does not have an existing data store.++ * 'CL_INVALID_GLOBAL_OFFSET', Returned if global_work_offset is not NULL.++ * 'CL_INVALID_HOST_PTR', Returned if host_ptr is NULL and 'CL_MEM_USE_HOST_PTR'+or 'CL_MEM_COPY_HOST_PTR' are set in flags or if host_ptr is not NULL but+'CL_MEM_COPY_HOST_PTR' or 'CL_MEM_USE_HOST_PTR' are not set in flags.++ * 'CL_INVALID_IMAGE_FORMAT_DESCRIPTOR', Returned if the image format specified+is not valid or is NULL or does not map to a supported OpenCL image format.++ * 'CL_INVALID_IMAGE_SIZE', Returned if the specified image width or height are+invalid or if the image row pitch and image slice pitch do not follow the rules.++ * 'CL_INVALID_KERNEL_NAME', Returned if the specified kernel name is not found+in program.++ * 'CL_INVALID_KERNEL', Returned if the specified kernel is not a valid kernel+object.++ * 'CL_INVALID_KERNEL_ARGS', Returned if the kernel argument values have not been+specified.++ * 'CL_INVALID_KERNEL_DEFINITION', Returned if the function definition for+__kernel function given by kernel_name such as the number of arguments, the+argument types are not the same for all devices for which the program executable+has been built.++ * 'CL_INVALID_MEM_OBJECT', Returned if a parameter is not a valid memory, image,+or buffer object.++ * 'CL_INVALID_OPERATION', Returned if there are no devices in context that+support images. Returned if the build of a program executable for any of the+devices specified by a previous call to 'clBuildProgram' for program has not+completed, or if there are kernel objects attached to program. Returned by+'clEnqueueNativeKernel' if the specified device cannot execute the native+kernel.++ * 'CL_INVALID_PLATFORM', Returned if the specified platform is not a valid+platform, or no platform could be selected, or if platform value specified in+properties is not a valid platform.++ * 'CL_INVALID_PROGRAM', Returned if the specified program is not a valid program+object.++ * 'CL_INVALID_PROGRAM_EXECUTABLE', Returned if there is no successfully built+executable for program, or if there is no device in program. Returned if there+is no successfully built program executable available for device associated with+command_queue.++ * 'CL_INVALID_QUEUE_PROPERTIES', Returned if specified properties are valid but+are not supported by the device.++ * 'CL_INVALID_SAMPLER', Returned if the specified sampler is not a valid sampler+object, or for an argument declared to be of type sampler_t when the specified+arg_value is not a valid sampler object.++ * 'CL_INVALID_VALUE', Returned if a parameter is not an expected value.++ * 'CL_INVALID_WORK_DIMENSION', Returned if work_dim is not a valid value.++ * 'CL_INVALID_WORK_GROUP_SIZE', Returned if local_work_size is specified and+number of workitems specified by global_work_size is not evenly divisible by+size of work-group given by local_work_size or does not match the work-group+size specified for kernel using the __attribute__((reqd_work_group_size(X, Y,+Z))) qualifier in program source.++ * 'CL_INVALID_WORK_ITEM_SIZE', Returned if the number of work-items specified in+any of local_work_size... [0]... local_work_size[work_dim - 1] is greater than+the corresponding values specified by 'clDeviceMaxWorkItemSizes'.++ * 'CL_MAP_FAILURE', Returned by if there is a failure to map the requested+region into the host address space. This error cannot occur for buffer objects+created with 'CLMEM_USE_HOST_PTR' or 'CLMEM_ALLOC_HOST_PTR'.++ * 'CL_MEM_OBJECT_ALLOCATION_FAILURE', Returned if there is a failure to allocate+memory for data store associated with image or buffer objects specified as+arguments to kernel.++ * 'CL_MEM_COPY_OVERLAP', Returned if the source and destination images are the+same image (or the source and destination buffers are the same buffer), and the+source and destination regions overlap.++ * 'CL_OUT_OF_HOST_MEMORY', Returned in the event of a failure to allocate+resources required by the OpenCL implementation on the host.++ * 'CL_OUT_OF_RESOURCES', Returned in the event of a failure to queue the+execution instance of kernel on the command-queue because of insufficient+resources needed to execute the kernel.++ * 'CL_PROFILING_INFO_NOT_AVAILABLE', Returned if the 'CL_QUEUE_PROFILING_ENABLE'+flag is not set for the command-queue and the profiling information is currently+not available (because the command identified by event has not completed).++ * 'CL_SUCCESS', Indicates that the function executed successfully.+-}+{#enum CLError {upcaseFirstLetter} deriving( Show, Eq ) #}++wrapPError :: (Ptr CLint -> IO a) -> IO (Either CLError a)+wrapPError f = alloca $ \perr -> do+ v <- f perr+ errcode <- peek perr >>= return . toEnum . fromIntegral+ if errcode == CL_SUCCESS+ then return $ Right v+ else return $ Left errcode+ +wrapCheckSuccess :: IO CLint -> IO Bool+wrapCheckSuccess f = f >>= return . (==CL_SUCCESS) . toEnum . fromIntegral++wrapGetInfo :: Storable a => (Ptr a -> Ptr CSize -> IO CLint) -> (a -> b) + -> IO (Either CLError b)+wrapGetInfo fget fconvert= alloca $ \dat -> do+ errcode <- fget dat nullPtr+ if errcode == (fromIntegral . fromEnum $ CL_SUCCESS )+ then fmap (Right . fconvert) $ peek dat+ else return . Left . toEnum . fromIntegral $ errcode++whenSuccess :: IO CLint -> IO a -> IO (Either CLError a)+whenSuccess fcheck fval = do+ errcode <- fcheck+ if errcode == getCLValue CL_SUCCESS+ then fval >>= return . Right+ else return . Left . getEnumCL $ errcode+ +-- -----------------------------------------------------------------------------+#c+enum CLPlatformInfo {+ cL_PLATFORM_PROFILE=CL_PLATFORM_PROFILE,+ cL_PLATFORM_VERSION=CL_PLATFORM_VERSION,+ cL_PLATFORM_NAME=CL_PLATFORM_NAME,+ cL_PLATFORM_VENDOR=CL_PLATFORM_VENDOR,+ cL_PLATFORM_EXTENSIONS=CL_PLATFORM_EXTENSIONS+ };+#endc++{-|+ * 'CL_PLATFORM_PROFILE', OpenCL profile string. Returns the profile name +supported by the implementation. The profile name returned can be one of the +following strings:++ [@FULL_PROFILE@] If the implementation supports the OpenCL specification+(functionality defined as part of the core specification and does not require+any extensions to be supported).++ [@EMBEDDED_PROFILE@] If the implementation supports the OpenCL embedded +profile. The embedded profile is defined to be a subset for each version of +OpenCL.++ * 'CL_PLATFORM_VERSION', OpenCL version string. Returns the OpenCL version +supported by the implementation. This version string has the following format: +/OpenCL major_version.minor_version platform-specific information/ The +/major_version.minor_version/ value returned will be 1.0.+ + * 'CL_PLATFORM_NAME', Platform name string.+ + * 'CL_PLATFORM_VENDOR', Platform vendor string.+ + * 'CL_PLATFORM_EXTENSIONS', Returns a space-separated list of extension names +(the extension names themselves do not contain any spaces) supported by the +platform. Extensions defined here must be supported by all devices associated +with this platform.+-}+{#enum CLPlatformInfo {upcaseFirstLetter} deriving( Show ) #}++-- -----------------------------------------------------------------------------+#c+enum CLDeviceType {+ cL_DEVICE_TYPE_CPU=CL_DEVICE_TYPE_CPU,+ cL_DEVICE_TYPE_GPU=CL_DEVICE_TYPE_GPU,+ cL_DEVICE_TYPE_ACCELERATOR=CL_DEVICE_TYPE_ACCELERATOR,+ cL_DEVICE_TYPE_DEFAULT=CL_DEVICE_TYPE_DEFAULT,+ cL_DEVICE_TYPE_ALL=CL_DEVICE_TYPE_ALL+ };+#endc++{-|+ * 'CL_DEVICE_TYPE_CPU', An OpenCL device that is the host processor. The host +processor runs the OpenCL implementations and is a single or multi-core CPU.+ + * 'CL_DEVICE_TYPE_GPU', An OpenCL device that is a GPU. By this we mean that the +device can also be used to accelerate a 3D API such as OpenGL or DirectX.+ + * 'CL_DEVICE_TYPE_ACCELERATOR', Dedicated OpenCL accelerators (for example the +IBM CELL Blade). These devices communicate with the host processor using a +peripheral interconnect such as PCIe.+ + * 'CL_DEVICE_TYPE_DEFAULT', The default OpenCL device in the system.+ + * 'CL_DEVICE_TYPE_ALL', All OpenCL devices available in the system.+-}+{#enum CLDeviceType {upcaseFirstLetter} deriving( Show ) #}++#c+enum CLCommandQueueProperty { + cL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE=CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,+ cL_QUEUE_PROFILING_ENABLE=CL_QUEUE_PROFILING_ENABLE+ };+#endc++{-|+ * 'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE', Determines whether the commands +queued in the command-queue are executed in-order or out-of-order. If set, the +commands in the command-queue are executed out-of-order. Otherwise, commands are +executed in-order.+ + * 'CL_QUEUE_PROFILING_ENABLE', Enable or disable profiling of commands in the +command-queue. If set, the profiling of commands is enabled. Otherwise profiling +of commands is disabled. See 'clGetEventProfilingInfo' for more information.+-}+{#enum CLCommandQueueProperty {upcaseFirstLetter} deriving( Show, Bounded, Eq, Ord ) #}++#c+enum CLDeviceFPConfig {+ cL_FP_DENORM=CL_FP_DENORM, cL_FP_INF_NAN=CL_FP_INF_NAN,+ cL_FP_ROUND_TO_NEAREST=CL_FP_ROUND_TO_NEAREST,+ cL_FP_ROUND_TO_ZERO=CL_FP_ROUND_TO_ZERO,+ cL_FP_ROUND_TO_INF=CL_FP_ROUND_TO_INF, cL_FP_FMA=CL_FP_FMA,+ };+#endc++{-|+ * 'CL_FP_DENORM', denorms are supported.+ + * 'CL_FP_INF_NAN', INF and NaNs are supported.+ + * 'CL_FP_ROUND_TO_NEAREST', round to nearest even rounding mode supported.+ + * 'CL_FP_ROUND_TO_ZERO', round to zero rounding mode supported.+ + * 'CL_FP_ROUND_TO_INF', round to +ve and -ve infinity rounding modes supported.+ + * 'CL_FP_FMA', IEEE754-2008 fused multiply-add is supported.+-}+{#enum CLDeviceFPConfig {upcaseFirstLetter} deriving( Show, Bounded, Eq, Ord ) #}++#c+enum CLDeviceExecCapability {+ cL_EXEC_KERNEL=CL_EXEC_KERNEL,+ cL_EXEC_NATIVE_KERNEL=CL_EXEC_NATIVE_KERNEL+ };+#endc++{-|+ * 'CL_EXEC_KERNEL', The OpenCL device can execute OpenCL kernels.+ + * 'CL_EXEC_NATIVE_KERNEL', The OpenCL device can execute native kernels.+-}+{#enum CLDeviceExecCapability {upcaseFirstLetter} deriving( Show, Bounded, Eq, Ord ) #}++#c+enum CLDeviceMemCacheType {+ cL_NONE=CL_NONE, cL_READ_ONLY_CACHE=CL_READ_ONLY_CACHE,+ cL_READ_WRITE_CACHE=CL_READ_WRITE_CACHE+ };+#endc++{#enum CLDeviceMemCacheType {upcaseFirstLetter} deriving( Show ) #}++#c+enum CLDeviceLocalMemType {+ cL_LOCAL=CL_LOCAL, cL_GLOBAL=CL_GLOBAL+ };+#endc++{#enum CLDeviceLocalMemType {upcaseFirstLetter} deriving( Show ) #}++-- -----------------------------------------------------------------------------+#c+enum CLCommandType {+ cL_COMMAND_NDRANGE_KERNEL=CL_COMMAND_NDRANGE_KERNEL,+ cL_COMMAND_TASK=CL_COMMAND_TASK ,+ cL_COMMAND_NATIVE_KERNEL=CL_COMMAND_NATIVE_KERNEL,+ cL_COMMAND_READ_BUFFER=CL_COMMAND_READ_BUFFER,+ cL_COMMAND_WRITE_BUFFER=CL_COMMAND_WRITE_BUFFER,+ cL_COMMAND_COPY_BUFFER=CL_COMMAND_COPY_BUFFER,+ cL_COMMAND_READ_IMAGE=CL_COMMAND_READ_IMAGE,+ cL_COMMAND_WRITE_IMAGE=CL_COMMAND_WRITE_IMAGE,+ cL_COMMAND_COPY_IMAGE=CL_COMMAND_COPY_IMAGE,+ cL_COMMAND_COPY_BUFFER_TO_IMAGE=CL_COMMAND_COPY_BUFFER_TO_IMAGE,+ cL_COMMAND_COPY_IMAGE_TO_BUFFER=CL_COMMAND_COPY_IMAGE_TO_BUFFER,+ cL_COMMAND_MAP_BUFFER=CL_COMMAND_MAP_BUFFER,+ cL_COMMAND_MAP_IMAGE=CL_COMMAND_MAP_IMAGE,+ cL_COMMAND_UNMAP_MEM_OBJECT=CL_COMMAND_UNMAP_MEM_OBJECT,+ cL_COMMAND_MARKER=CL_COMMAND_MARKER,+ cL_COMMAND_ACQUIRE_GL_OBJECTS=CL_COMMAND_ACQUIRE_GL_OBJECTS,+ cL_COMMAND_RELEASE_GL_OBJECTS=CL_COMMAND_RELEASE_GL_OBJECTS+ };+#endc++-- | Command associated with an event.+{#enum CLCommandType {upcaseFirstLetter} deriving( Show ) #}++#c+enum CLCommandExecutionStatus {+ cL_QUEUED=CL_QUEUED, cL_SUBMITTED=CL_SUBMITTED, cL_RUNNING=CL_RUNNING,+ cL_COMPLETE=CL_COMPLETE, cL_EXEC_ERROR= -1+ };+#endc++{-|+ * 'CL_QUEUED', command has been enqueued in the command-queue.++ * 'CL_SUBMITTED', enqueued command has been submitted by the host to the +device associated with the command-queue.++ * 'CL_RUNNING', device is currently executing this command.+ + * 'CL_COMPLETE', the command has completed.+ + * 'CL_EXEC_ERROR', command was abnormally terminated.+-}+{#enum CLCommandExecutionStatus {upcaseFirstLetter} deriving( Show ) #}++#c+enum CLProfilingInfo {+ cL_PROFILING_COMMAND_QUEUED=CL_PROFILING_COMMAND_QUEUED,+ cL_PROFILING_COMMAND_SUBMIT=CL_PROFILING_COMMAND_SUBMIT,+ cL_PROFILING_COMMAND_START=CL_PROFILING_COMMAND_START,+ cL_PROFILING_COMMAND_END=CL_PROFILING_COMMAND_END+ };+#endc++{-| Specifies the profiling data.++ * 'CL_PROFILING_COMMAND_QUEUED', A 64-bit value that describes the current +device time counter in nanoseconds when the command identified by event is +enqueued in a command-queue by the host.+ + * 'CL_PROFILING_COMMAND_SUBMIT', A 64-bit value that describes the current +device time counter in nanoseconds when the command identified by event that has +been enqueued is submitted by the host to the device associated with the +commandqueue.+ + * 'CL_PROFILING_COMMAND_START', A 64-bit value that describes the current +device time counter in nanoseconds when the command identified by event starts +execution on the device.+ + * 'CL_PROFILING_COMMAND_END', A 64-bit value that describes the current device +time counter in nanoseconds when the command identified by event has finished +execution on the device.+-}+{#enum CLProfilingInfo {upcaseFirstLetter} deriving( Show ) #}++-- -----------------------------------------------------------------------------+#c+enum CLMemFlag {+ cL_MEM_READ_WRITE=CL_MEM_READ_WRITE,+ cL_MEM_WRITE_ONLY=CL_MEM_WRITE_ONLY,+ cL_MEM_READ_ONLY=CL_MEM_READ_ONLY,+ cL_MEM_USE_HOST_PTR=CL_MEM_USE_HOST_PTR,+ cL_MEM_ALLOC_HOST_PTR=CL_MEM_ALLOC_HOST_PTR,+ cL_MEM_COPY_HOST_PTR=CL_MEM_COPY_HOST_PTR+ };+#endc+{-| + * 'CL_MEM_READ_WRITE', This flag specifies that the memory object will be+read and written by a kernel. This is the default.++ * 'CL_MEM_WRITE_ONLY', This flags specifies that the memory object will be+written but not read by a kernel. Reading from a buffer or image object created+with 'CLMEM_WRITE_ONLY' inside a kernel is undefined.++ * 'CL_MEM_READ_ONLY', This flag specifies that the memory object is a read-only+memory object when used inside a kernel. Writing to a buffer or image object+created with 'CLMEM_READ_ONLY' inside a kernel is undefined.++ * 'CL_MEM_USE_HOST_PTR', This flag is valid only if host_ptr is not NULL. If+specified, it indicates that the application wants the OpenCL implementation to+use memory referenced by host_ptr as the storage bits for the memory+object. OpenCL implementations are allowed to cache the buffer contents pointed+to by host_ptr in device memory. This cached copy can be used when kernels are+executed on a device. The result of OpenCL commands that operate on multiple+buffer objects created with the same host_ptr or overlapping host regions is+considered to be undefined.++ * 'CL_MEM_ALLOC_HOST_PTR', This flag specifies that the application wants the+OpenCL implementation to allocate memory from host accessible+memory. 'CL_MEM_ALLOC_HOST_PTR' and 'CL_MEM_USE_HOST_PTR' are mutually exclusive.++ * 'CL_MEM_COPY_HOST_PTR', This flag is valid only if host_ptr is not NULL. If+specified, it indicates that the application wants the OpenCL implementation to+allocate memory for the memory object and copy the data from memory referenced+by host_ptr. 'CL_MEM_COPY_HOST_PTR' and 'CL_MEM_USE_HOST_PTR' are mutually+exclusive. 'CL_MEM_COPY_HOST_PTR' can be used with 'CL_MEM_ALLOC_HOST_PTR' to+initialize the contents of the cl_mem object allocated using host-accessible+(e.g. PCIe) memory. +-} +{#enum CLMemFlag {upcaseFirstLetter} deriving( Show, Bounded, Eq, Ord ) #}++#c+enum CLMemObjectType {+ cL_MEM_OBJECT_BUFFER=CL_MEM_OBJECT_BUFFER,+ cL_MEM_OBJECT_IMAGE2D=CL_MEM_OBJECT_IMAGE2D,+ cL_MEM_OBJECT_IMAGE3D=CL_MEM_OBJECT_IMAGE3D+ };+#endc++{-| * 'CL_MEM_OBJECT_BUFFER' if memobj is created with 'clCreateBuffer'. + + * 'CL_MEM_OBJECT_IMAGE2D' if memobj is created with 'clCreateImage2D' ++ * 'CL_MEM_OBJECT_IMAGE3D' if memobj is created with 'clCreateImage3D'.+-}+{#enum CLMemObjectType {upcaseFirstLetter} deriving( Show ) #}++#c+enum CLBuildStatus {+ cL_BUILD_NONE=CL_BUILD_NONE,+ cL_BUILD_ERROR=CL_BUILD_ERROR,+ cL_BUILD_SUCCESS=CL_BUILD_SUCCESS,+ cL_BUILD_IN_PROGRESS=CL_BUILD_IN_PROGRESS,+ };+#endc++{-| * 'CL_BUILD_NONE'. The build status returned if no build has been performed+on the specified program object for device.++ * 'CL_BUILD_ERROR'. The build status returned if the last call to+'clBuildProgram' on the specified program object for device generated an error.++ * 'CL_BUILD_SUCCESS'. The build status retrned if the last call to+'clBuildProgram' on the specified program object for device was successful.++ * 'CL_BUILD_IN_PROGRESS'. The build status returned if the last call to +'clBuildProgram' on the specified program object for device has not finished.+-}+{#enum CLBuildStatus {upcaseFirstLetter} deriving( Show ) #}++#c+enum CLAddressingMode {+ cL_ADDRESS_REPEAT=CL_ADDRESS_REPEAT,+ cL_ADDRESS_CLAMP_TO_EDGE =CL_ADDRESS_CLAMP_TO_EDGE ,+ cL_ADDRESS_CLAMP=CL_ADDRESS_CLAMP,+ cL_ADDRESS_NONE=CL_ADDRESS_NONE+ };+#endc+{#enum CLAddressingMode {upcaseFirstLetter} deriving( Show ) #}++#c+enum CLFilterMode {+ cL_FILTER_NEAREST=CL_FILTER_NEAREST,+ cL_FILTER_LINEAR=CL_FILTER_LINEAR,+ };+#endc+{#enum CLFilterMode {upcaseFirstLetter} deriving( Show ) #}++-- -----------------------------------------------------------------------------+getCLValue :: (Enum a, Integral b) => a -> b+getCLValue = fromIntegral . fromEnum++getEnumCL :: (Integral a, Enum b) => a -> b+getEnumCL = toEnum . fromIntegral ++getCommandExecutionStatus :: CLint -> CLCommandExecutionStatus+getCommandExecutionStatus n + | n < 0 = CL_EXEC_ERROR+ | otherwise = getEnumCL $ n+ +-- -----------------------------------------------------------------------------+binaryFlags :: (Ord b, Enum b, Bounded b) => b -> [b]+binaryFlags m = map toEnum . takeWhile (<= (fromEnum m)) $ [1 `shiftL` n | n <- [0..]]+ +testMask :: Bits b => b -> b -> Bool+testMask mask v = (v .&. mask) == v++bitmaskFromFlags :: (Enum a, Bits b) => [a] -> b+bitmaskFromFlags = foldl' (.|.) 0 . map (fromIntegral . fromEnum)++bitmaskToFlags :: (Enum a, Bits b) => [a] -> b -> [a]+bitmaskToFlags xs mask = filter (testMask mask . fromIntegral . fromEnum) xs++bitmaskToDeviceTypes :: CLDeviceType_ -> [CLDeviceType]+bitmaskToDeviceTypes = bitmaskToFlags [CL_DEVICE_TYPE_CPU,CL_DEVICE_TYPE_GPU,CL_DEVICE_TYPE_ACCELERATOR,CL_DEVICE_TYPE_DEFAULT,CL_DEVICE_TYPE_ALL]++bitmaskToCommandQueueProperties :: CLCommandQueueProperty_ -> [CLCommandQueueProperty]+bitmaskToCommandQueueProperties = bitmaskToFlags (binaryFlags maxBound)+ +bitmaskToFPConfig :: CLDeviceFPConfig_ -> [CLDeviceFPConfig]+bitmaskToFPConfig = bitmaskToFlags (binaryFlags maxBound)++bitmaskToExecCapability :: CLDeviceExecCapability_ -> [CLDeviceExecCapability]+bitmaskToExecCapability = bitmaskToFlags (binaryFlags maxBound)++bitmaskToMemFlags :: CLMemFlags_ -> [CLMemFlag]+bitmaskToMemFlags = bitmaskToFlags (binaryFlags maxBound)++-- -----------------------------------------------------------------------------