packages feed

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 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)++-- -----------------------------------------------------------------------------