+
+
+Please support my work on Patreon by adopting a pet Neanderthal function in your name! I'll intive you to a dedicated Discord discussion server. Can't afford to donate? Ask for a free invite.
diff --git a/_includes/scripts.html b/_includes/scripts.html
new file mode 100644
index 0000000..28c11a1
--- /dev/null
+++ b/_includes/scripts.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/_layouts/article.html b/_layouts/article.html
new file mode 100644
index 0000000..7b1d51e
--- /dev/null
+++ b/_layouts/article.html
@@ -0,0 +1,34 @@
+
+
+
+ {% include head.html %}
+
+
+
+ {% include header.html %}
+
+
Please take some time to tell us about your experience with the library and this site. Let us know what we should be explaining or is not clear enough. If you are willing to contribute improvements, even better!
+
+
+
+
+
+
+
+ {% include footer.html %}
+
+
+ {% include scripts.html %}
+
+
diff --git a/_layouts/default.html b/_layouts/default.html
new file mode 100644
index 0000000..1160107
--- /dev/null
+++ b/_layouts/default.html
@@ -0,0 +1,22 @@
+
+
+
+ {% include head.html %}
+
+
+
+ {% include header.html %}
+
+
+
+ {% include footer.html %}
+
+
+
+ {% include scripts.html %}
+
diff --git a/_plugins/sitemap_generator.rb b/_plugins/sitemap_generator.rb
new file mode 100644
index 0000000..51da8d3
--- /dev/null
+++ b/_plugins/sitemap_generator.rb
@@ -0,0 +1,308 @@
+# Sitemap.xml Generator is a Jekyll plugin that generates a sitemap.xml file by
+# traversing all of the available posts and pages.
+#
+# How To Use:
+# 1.) Copy source file into your _plugins folder within your Jekyll project.
+# 2.) Change MY_URL to reflect your domain name.
+# 3.) Change SITEMAP_FILE_NAME if you want your sitemap to be called something
+# other than sitemap.xml.
+# 4.) Change the PAGES_INCLUDE_POSTS list to include any pages that are looping
+# through your posts (e.g. "index.html", "archive.html", etc.). This will
+# ensure that right after you make a new post, the last modified date will
+# be updated to reflect the new post.
+# 5.) Run Jekyll: jekyll --server to re-generate your site.
+# 6.) A sitemap.xml should be included in your _site folder.
+#
+# Customizations:
+# 1.) If there are any files you don't want included in the sitemap, add them
+# to the EXCLUDED_FILES list. The name should match the name of the source
+# file.
+# 2.) If you want to include the optional changefreq and priority attributes,
+# simply include custom variables in the YAML Front Matter of that file.
+# The names of these custom variables are defined below in the
+# CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME and PRIORITY_CUSTOM_VARIABLE_NAME
+# constants.
+#
+# Notes:
+# 1.) The last modified date is determined by the latest from the following:
+# system modified date of the page or post, system modified date of
+# included layout, system modified date of included layout within that
+# layout, ...
+#
+# Author: Michael Levin
+# Site: http://www.kinnetica.com
+# Distributed Under A Creative Commons License
+# - http://creativecommons.org/licenses/by/3.0/
+
+require 'rexml/document'
+
+module Jekyll
+
+ # Change MY_URL to reflect the site you are using
+ MY_URL = "http://PROJECT.clojurewerkz.org"
+
+ # Change SITEMAP_FILE_NAME if you would like your sitemap file
+ # to be called something else
+ SITEMAP_FILE_NAME = "sitemap.xml"
+
+ # Any files to exclude from being included in the sitemap.xml
+ EXCLUDED_FILES = ["atom.xml", "deploy.sh"]
+
+ # Any files that include posts, so that when a new post is added, the last
+ # modified date of these pages should take that into account
+ PAGES_INCLUDE_POSTS = ["index.html"]
+
+ # Custom variable names for changefreq and priority elements
+ # These names are used within the YAML Front Matter of pages or posts
+ # for which you want to include these properties
+ CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME = "change_frequency"
+ PRIORITY_CUSTOM_VARIABLE_NAME = "priority"
+
+ class Post
+ attr_accessor :name
+
+ def full_path_to_source
+ File.join(@base, @name)
+ end
+
+ def location_on_server
+ "#{MY_URL}#{url}"
+ end
+ end
+
+ class Page
+ attr_accessor :name
+
+ def full_path_to_source
+ File.join(@base, @dir, @name)
+ end
+
+ def location_on_server
+ location = "#{MY_URL}#{@dir}#{url}"
+ location.gsub(/index.html$/, "")
+ end
+ end
+
+ class Layout
+ def full_path_to_source
+ File.join(@base, @name)
+ end
+ end
+
+ # Recover from strange exception when starting server without --auto
+ class SitemapFile < StaticFile
+ def write(dest)
+ begin
+ super(dest)
+ rescue
+ end
+
+ true
+ end
+ end
+
+ class SitemapGenerator < Generator
+
+ # Valid values allowed by sitemap.xml spec for change frequencies
+ VALID_CHANGE_FREQUENCY_VALUES = ["always", "hourly", "daily", "weekly",
+ "monthly", "yearly", "never"]
+
+ # Goes through pages and posts and generates sitemap.xml file
+ #
+ # Returns nothing
+ def generate(site)
+ sitemap = REXML::Document.new << REXML::XMLDecl.new("1.0", "UTF-8")
+
+ urlset = REXML::Element.new "urlset"
+ urlset.add_attribute("xmlns",
+ "http://www.sitemaps.org/schemas/sitemap/0.9")
+
+ @last_modified_post_date = fill_posts(site, urlset)
+ fill_pages(site, urlset)
+
+ sitemap.add_element(urlset)
+
+ # File I/O: create sitemap.xml file and write out pretty-printed XML
+ file = File.new(File.join(site.dest, SITEMAP_FILE_NAME), "w")
+ formatter = REXML::Formatters::Pretty.new(4)
+ formatter.compact = true
+ formatter.write(sitemap, file)
+ file.close
+
+ # Keep the sitemap.xml file from being cleaned by Jekyll
+ site.static_files << Jekyll::SitemapFile.new(site, site.dest, "/", SITEMAP_FILE_NAME)
+ end
+
+ # Create url elements for all the posts and find the date of the latest one
+ #
+ # Returns last_modified_date of latest post
+ def fill_posts(site, urlset)
+ last_modified_date = nil
+ site.posts.each do |post|
+ if !excluded?(post.name)
+ url = fill_url(site, post)
+ urlset.add_element(url)
+ end
+
+ path = post.full_path_to_source
+ date = File.mtime(path)
+ last_modified_date = date if last_modified_date == nil or date > last_modified_date
+ end
+
+ last_modified_date
+ end
+
+ # Create url elements for all the normal pages and find the date of the
+ # index to use with the pagination pages
+ #
+ # Returns last_modified_date of index page
+ def fill_pages(site, urlset)
+ site.pages.each do |page|
+ if !excluded?(page.name)
+ path = page.full_path_to_source
+ if File.exists?(path)
+ url = fill_url(site, page)
+ urlset.add_element(url)
+ end
+ end
+ end
+ end
+
+ # Fill data of each URL element: location, last modified,
+ # change frequency (optional), and priority.
+ #
+ # Returns url REXML::Element
+ def fill_url(site, page_or_post)
+ url = REXML::Element.new "url"
+
+ loc = fill_location(page_or_post)
+ url.add_element(loc)
+
+ lastmod = fill_last_modified(site, page_or_post)
+ url.add_element(lastmod) if lastmod
+
+ if (page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME])
+ change_frequency =
+ page_or_post.data[CHANGE_FREQUENCY_CUSTOM_VARIABLE_NAME].downcase
+
+ if (valid_change_frequency?(change_frequency))
+ changefreq = REXML::Element.new "changefreq"
+ changefreq.text = change_frequency
+ url.add_element(changefreq)
+ else
+ puts "ERROR: Invalid Change Frequency In #{page_or_post.name}"
+ end
+ end
+
+ if (page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME])
+ priority_value = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME]
+ if valid_priority?(priority_value)
+ priority = REXML::Element.new "priority"
+ priority.text = page_or_post.data[PRIORITY_CUSTOM_VARIABLE_NAME]
+ url.add_element(priority)
+ else
+ puts "ERROR: Invalid Priority In #{page_or_post.name}"
+ end
+ end
+
+ url
+ end
+
+ # Get URL location of page or post
+ #
+ # Returns the location of the page or post
+ def fill_location(page_or_post)
+ loc = REXML::Element.new "loc"
+ loc.text = page_or_post.location_on_server
+
+ loc
+ end
+
+ # Fill lastmod XML element with the last modified date for the page or post.
+ #
+ # Returns lastmod REXML::Element or nil
+ def fill_last_modified(site, page_or_post)
+ path = page_or_post.full_path_to_source
+
+ lastmod = REXML::Element.new "lastmod"
+ date = File.mtime(path)
+ latest_date = find_latest_date(date, site, page_or_post)
+
+ if @last_modified_post_date == nil
+ # This is a post
+ lastmod.text = latest_date.iso8601
+ else
+ # This is a page
+ if posts_included?(page_or_post.name)
+ # We want to take into account the last post date
+ final_date = greater_date(latest_date, @last_modified_post_date)
+ lastmod.text = final_date.iso8601
+ else
+ lastmod.text = latest_date.iso8601
+ end
+ end
+ lastmod
+ end
+
+ # Go through the page/post and any implemented layouts and get the latest
+ # modified date
+ #
+ # Returns formatted output of latest date of page/post and any used layouts
+ def find_latest_date(latest_date, site, page_or_post)
+ layouts = site.layouts
+ layout = layouts[page_or_post.data["layout"]]
+ while layout
+ path = layout.full_path_to_source
+ date = File.mtime(path)
+
+ latest_date = date if (date > latest_date)
+
+ layout = layouts[layout.data["layout"]]
+ end
+
+ latest_date
+ end
+
+ # Which of the two dates is later
+ #
+ # Returns latest of two dates
+ def greater_date(date1, date2)
+ if (date1 >= date2)
+ date1
+ else
+ date2
+ end
+ end
+
+ # Is the page or post listed as something we want to exclude?
+ #
+ # Returns boolean
+ def excluded?(name)
+ EXCLUDED_FILES.include? name
+ end
+
+ def posts_included?(name)
+ PAGES_INCLUDE_POSTS.include? name
+ end
+
+ # Is the change frequency value provided valid according to the spec
+ #
+ # Returns boolean
+ def valid_change_frequency?(change_frequency)
+ VALID_CHANGE_FREQUENCY_VALUES.include? change_frequency
+ end
+
+ # Is the priority value provided valid according to the spec
+ #
+ # Returns boolean
+ def valid_priority?(priority)
+ begin
+ priority_val = Float(priority)
+ return true if priority_val >= 0.0 and priority_val <= 1.0
+ rescue ArgumentError
+ end
+
+ false
+ end
+ end
+end
diff --git a/articles/community.md b/articles/community.md
new file mode 100644
index 0000000..6455390
--- /dev/null
+++ b/articles/community.md
@@ -0,0 +1,53 @@
+---
+title: "ClojureCL: Community"
+layout: article
+---
+
+## Where to contact me
+
+~~[I hang around at Slack Clojurians Uncomplicate](https://clojurians.slack.com/messages/uncomplicate/details/)~~
+
Core ClojureCL functions for OpenCL **host** programming. The kernels should
+be provided as strings (that may be stored in files), written in OpenCL C.
Utility functions used as helpers in other ClojureCL namespaces.
+The user of the ClojureCL library would probably not need to use
+any of the functions defined here.
Various helpers that are not needed by ClojureCL itself,
+but may be very helpful in applications. See Neanderthal and Bayadera libraries
+for the examples of how to use them.
Defines constants and mappings from/to OpenCL constants.
+
OpenCL API defines and uses numerous int/long C-style constants as arguments in functions calls, mostly for configuring various options. Clojure uses keywords as an user friendly alternative. ClojureCL’s core namespace contains primitive functions suffixed with *, which still accept the low level constants defined in org.jocl.CL Java class, but the preferred, easier, and natural way is to use keywords. Another benefit of that method is that you can easily view available options by printing an appropriate hash-map from this namespace.
+
Most mappings are two-way. Hashmaps that convert keywords to number codes are named cl-something-clish, while functions that convert numbers to keywords are named dec-something-clish. You can see which keywords are available for a certain property by evaluate appropriate cl-something-clish hashmap. All hashmaps and functions contain brief doc and a web link to appropriate online OpenCL documentation with detailed explanations
Decodes OpenCL error code to a meaningful string. If called with a number that is not recognized as an existing OpenCL error, returns "UNKNOWN OpenCL ERROR!"
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.core.html b/codox/uncomplicate.clojurecl.core.html
new file mode 100644
index 0000000..a6fdec7
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.core.html
@@ -0,0 +1,778 @@
+
+uncomplicate.clojurecl.core documentation
Core ClojureCL functions for OpenCL **host** programming. The kernels should
+be provided as strings (that may be stored in files), written in OpenCL C.
+
+The OpenCL standard defines several datastructures (platform, device, etc.)
+that support the concepts defined in four OpenCL models (Platform Model,
+Memory Model, Execution Model, and Programming Model). ClojureCL uses
+a low-level JNI-based library [JOCL](http://www.jocl.org) for calling
+native OpenCL drivers - the datastructures are therefore defined in JOCL.
+They can be found in [`org.jocl`]
+(http://www.jocl.org/doc/org/jocl/package-tree.html) package.
+
+Some functions are available in two versions:
+
+* High-level, which works with clojure-friendly arguments - vectors,
+sequences, keywords, etc. These are preferred to low-level alternatives.
+* Low-level, suffexed by `*`, which work with primitive arguments
+and give primitive results. These functions are useful when you
+already have primitive data and want to avoid unnecessary conversions.
+You can find them in the [[uncomplicate.clojurecl.internal.impl]] namespace.
+
+The documentation given here is only a quick reminder; it is necessary
+to grasp OpenCL and parallel computing concepts to be able to use the
+library. Also, each function's doc entry have a link to much more detailed
+documentation available in OpenCL and JOCL reference - be sure to
+browse one of these documents wherever you are not sure about
+some of many important details.
+
+### Cheat Sheet
+
+* resource management: [[with-release]], [[with-platform]], [[with-context]], [[with-queue]],
+[[with-default]].
+
+* [`cl_platform_id`](http://www.jocl.org/doc/org/jocl/cl_platform_id.html):
+[[num-platforms]], [[platforms]], [[platform-info]], [[with-platform]].
+
+* [`cl_device_id`](http://www.jocl.org/doc/org/jocl/cl_device_id.html):
+[[devices]], [[num-devices]].
+
+* [`cl_context`](http://www.jocl.org/doc/org/jocl/cl_context.html):
+[[context]], [[context-info]], [[with-context]], [[context-properties]].
+
+* [`cl_mem`](http://www.jocl.org/doc/org/jocl/cl_mem.html):
+[[cl-buffer]], [[cl-sub-buffer]], [[cl-buffer*]], [[Mem]], [[CLMem]].
+
+* [`cl_event`](http://www.jocl.org/doc/org/jocl/cl_event.html):
+[[event]], [[host-event]], [[events]], [[register]], [[event-callback]], [[set-status!]].
+
+* [`cl_program`](http://www.jocl.org/doc/org/jocl/cl_program.html):
+[[program-with-source]], [[build-program!]].
+
+* [`cl_kernel`](http://www.jocl.org/doc/org/jocl/cl_kernel.html):
+[[num-kernels]], [[kernel]], [[set-arg!]], [[set-args!]], [[set-arg]].
+
+* [`cl_command_queue`](http://www.jocl.org/doc/org/jocl/cl_kernel.html):
+[[command-queue]], [[work-size]], [[enq-kernel!]],
+[[enq-read!]], [[enq-write!]], [[enq-copy!]], [[enq-fill!]], [[enq-map-buffer!]], [[enq-unmap!]],
+[[enq-svm-map!]], [[enq-svm-unmap!]], [[enq-marker!]], [[enq-wait!]], [[enq-barrier!]],
+[[finish!]], [[flush!]] [[with-queue]].
+
*command-queue*
dynamic
Dynamic var for binding the default command queue.
+
*context*
dynamic
Dynamic var for binding the default context.
+
*platform*
dynamic
Dynamic var for binding the default platform.
+
build-program!
(build-program! program devices options ch user-data)(build-program! program devices options ch)(build-program! program options ch)(build-program! program ch)(build-program! program)
Builds (compiles and links) a program executable; returns the program
+changed with side effects on `program` argument.
+
+Accepts the following arguments (nil is allowed for all optional arguments):
+
+* `program`: previously loaded [[internal/CLProgram]] that contains the program
+source or binary;
+* `devices` (optional): an optional sequence of [[internal/CLDevice]] associated with
+the program (if not supplied, all devices are used);
+* `options` (optional): an optional string of compiler options
+(such as "-Dname=value");
+* `ch` (optional): core.async channel for notifications. If supplied,
+the build will be asynchronous;
+* `user-data` (optional): passed as part of notification data.
+
+In case of OpenCL errors during the program build, throws
+`Exceptioninfo`.
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clBuildProgram.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clBuildProgram-org.jocl.cl_program-int-org.jocl.cl_device_id:A-java.lang.String-org.jocl.BuildProgramFunction-java.lang.Object-
+
+Examples:
+
+ (build-program! program) ; synchronous
+ (build-program! program ch) ; asynchronous
+ (build-program! program "-cl-std=CL2.0" ch) ; asynchronous
+ (build-program! program [dev] "-cl-std=CL2.0" ch) ; async
+ (build-program! program [dev] "-cl-std=CL2.0" ch :my-data) ; async
+
cl-buffer
(cl-buffer ctx size flag & flags)(cl-buffer size flag)(cl-buffer size)
Creates a cl buffer object ([[CLBuffer]]) in `ctx`, given `size` in bytes
+and one or more memory allocation usage keyword flags: `:read-write`,
+`:read-only`, `:write-only`, `:use-host-ptr`, `:alloc-host-ptr`,
+`:copy-host-ptr`, `:host-write-only`, `:host-read-only`, `:host-no-access`.
+
+If called with two arguments, uses the default `*context*`
+(see [[with-context]]).
+
+**Needs to be released after use.**
+
+If `ctx` is nil or the buffer size is invalid, throws `ExceptionInfo`.
+If some of the flags is invalid, throws `IllegalArgumentexception`.
+
+See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateBuffer.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clCreateBuffer-org.jocl.cl_context-long-long-org.jocl.Pointer-int:A-
+
+Examples:
+
+(cl-buffer 32 :read-only)
+(cl-buffer ctx 24 :write-only)
+
cl-buffer?
(cl-buffer? x)
Checks whether an object is a CL buffer.
+
cl-sub-buffer
(cl-sub-buffer buffer origin size flag & flags)(cl-sub-buffer buffer origin size)
(command-queue ctx device x & properties)(command-queue ctx device)(command-queue device)(command-queue)
Creates a host or device command queue on a specific device.
+
+** If you need to support OpenCL 1.2 platforms, you MUST use the alternative
+[[command-queue-1*]] function. Otherwise, you will get an
+UnsupportedOperationException erorr. What is important is the version of the
+platform, not the devices. This function is for platforms (regardless of the
+devices) supporting OpenCL 2.0 and higher. **
+
+Arguments are:
+
+* `ctx` - the `cl_context` for the queue;
+* `device` - the `cl_device_id` for the queue;
+* `x` - if integer, the size of the (on device) queue, otherwise treated
+as property;
+* `properties` - additional optional keyword properties: `:profiling`,
+`:queue-on-device`, `:out-of-order-exec-mode`, and `queue-on-device-default`;
+
+**Needs to be released after use.**
+
+See also [[command-queue*]].
+
+If called with invalid context or device, throws `ExceptionInfo`.
+If called with any invalid property, throws NullPointerexception.
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateCommandQueueWithProperties.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clCreateCommandQueueWithProperties-org.jocl.cl_context-org.jocl.cl_device_id-org.jocl.cl_queue_properties-int:A-
+
+Examples:
+
+ (command-queue ctx)
+ (command-queue ctx dev)
+ (command-queue ctx dev :profiling :queue-on-device :out-of-order-execution-mode)
+ (command-queue ctx dev 524288 :queue-on-device)
+
command-queue-1
(command-queue-1 ctx device x & properties)(command-queue-1 ctx device)(command-queue-1 device)(command-queue-1)
Info of the default context ([[*context*]]). If [[*context*]] is unbound,
+throws `Illegalargumentexception`
+
+See also: [[with-context]]
+
+Example:
+
+ (with-context (context devices)
+ (context-info))
+
context-properties
(context-properties props)
Creates `cl_context_properties` from a map of properties.
+Currently, this is not very useful, it is only here to
+support the full compatibility of [[context*]] function with
+the JOCL API.
Queries `platform` for the devices of one or a combination of
+several `device-type`s:
+`:gpu`, `:cpu`, `:all`, `:accelerator`, `:custom`, `:default`,
+and returns them in a vector containing [[internal/CLDevice]] objects.
+
+When called with only one argument `x`:
+
+* if `x` is a keyword, returns the devices of type `x` in `*platform*`;
+* otherwise returns all devices on the platform `x`.
+
+When called with no arguments, returns all devices in `*platform*`.
+
+Root level devices do not need to be explicitly released.
+
+When called with an invalid platform, throws [ExceptionInfo]
+(http://clojuredocs.org/clojure.core/ex-info). When called with an unknown
+device type, throws `NullPointerException`
+
+See also [[internal/devices*]].
+
+Examples:
+
+ (devices)
+ (devices (first (platforms)))
+ (devices :gpu)
+ (devices (first (platforms)) :gpu :cpu :accelerator)
+
(enq-fill! queue this pattern offset multiplier wait-events ev)(enq-fill! queue this pattern wait-events ev)(enq-fill! queue this pattern)(enq-fill! this pattern)
Enqueues a command to asynchronously execute a kernel on a device.
+Returns the queue.
+
+Arguments:
+
+* `queue` (optional): the `cl_command_queue` that executes the kernel.
+If omitted, [[*command-queue*]] will be used.
+* `kernel`: the `cl_kernel` that is going to be executed.
+* `work-size`: [[WorkSize]] containing the settings of execution
+(global work size, local work size, global work offset).
+* `wait-events` (optional): [[events]] array specifying the events (if any)
+that need to complete before this command can be executed.
+* `event` (optional): if specified, the `cl_event` object tied to
+the execution of this command.
+
+If an OpenCL error occurs during the call, throws `ExceptionInfo`.
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueNDRangeKernel.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueNDRangeKernel-org.jocl.cl_command_queue-org.jocl.cl_kernel-int-long:A-long:A-long:A-int-org.jocl.cl_event:A-org.jocl.cl_event-
+
+Examples:
+
+ (enq-kernel! my-kernel (work-size [8]))
+ (enq-kernel! my-queue my-kernel (work-size [8]))
+ (enq-kernel! my-queue my-kernel (work-size [8] (events event1 event2) my-event))
+
Enqueues a command to map a region of the cl buffer into the host
+address space. Returns the mapped `java.nio.ByteBuffer`. The result
+must be unmapped by calling [[enq-unmap!]] for the effects of working
+with the mapping byte buffer to be transfered back to the device memory.
+
+Arguments:
+
+* `queue` (optional): the `cl_command_queue` that maps the object.
+If omitted, [[*command-queue*]] will be used.
+* `cl`: the [[CLMem]] that is going to be mapped to.
+* `blocking`: whether the operation is blocking or non-blocking.
+* `offset`: integer value of the memory offset in bytes.
+* `req-size`: integer value of the requested size in bytes (if larger than
+ the available data, it will be shrinked).
+* flags: one keyword or a sequence of keywords that indicates memory mapping
+settings: `:read`, `:write`, and/or `:write-invalidate-settings`.
+* `wait-events` (optional): [[events]] array specifying the events (if any)
+that need to complete before this operation.
+* `event` (optional): if specified, the `cl_event` object tied to
+the execution of this operation.
+
+If event is specified, the operation is asynchronous, otherwise it blocks the
+current thread until the data transfer completes. See also [[register]].
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueMapBuffer.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueMapBuffer-org.jocl.cl_command_queue-org.jocl.cl_mem-boolean-long-long-long-int-org.jocl.cl_event:A-org.jocl.cl_event-int:A-
+
+Examples:
+
+ (enq-map-buffer! queue cl-data :write (events ev-nd) ev-map)
+ (enq-map-buffer! queue cl-data [:write :read])
+ (enq-map-buffer! cl-data :write)
+
Enqueues a command to read from a cl object to host memory.
+Returns the queue.
+
+* `queue` (optional): the `cl_command_queue` that reads the object.
+If omitted, [[*command-queue*]] will be used.
+* `cl`: the [[CLMem]] that is going to be read from.
+* `host`: [[Mem]] object on the host that the data is to be transferred to.
+Must be a direct buffer is the reading is asynchronous.
+* `blocking`: boolean indicator of synchronization.
+* `offset`: the offset in bytes in the buffer object to read from.
+* `wait-events` (optional): [[events]] array specifying the events (if any)
+that need to complete before this operation.
+* `event` (optional): if specified, the `cl_event` object tied to
+the execution of this operation.
+
+If event is specified, the operation is asynchronous, otherwise it blocks the
+current thread until the data transfer completes, unless explicitly specifiend
+with `blocking`. See also [[register]].
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueReadBuffer.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueReadBuffer-org.jocl.cl_command_queue-org.jocl.cl_mem-boolean-long-long-org.jocl.Pointer-int-org.jocl.cl_event:A-org.jocl.cl_event-
+
+Examples:
+
+ (let [host-data (direct-buffer 32)
+ ev (event)
+ notifications (chan)
+ follow (register notifications)]
+ (enq-read! my-queue cl-data host-data ev) ;; asynchronous
+ (follow ev)
+ (<!! notifications))
+
+ (enq-read! my-queu cl-data host-data) ;; blocking
+
Enqueues a command that will allow the host to update a region of a SVM buffer.
+. Returns the mapped `java.nio.ByteBuffer` (which is the same byte buffer that is
+ already accessible through `(byte-buffer svm)`). Together with [[enq-svm-unmap!]],
+ works as a synchronization point.
+
+ Arguments:
+
+ * `queue` (optional): the `cl_command_queue` that maps the object.
+ If omitted, [[*command-queue*]] will be used.
+ * `svm`: the [[SVMMem]] that is going to be mapped to.
+ * `offset` (optional): integer value of the memory offset in bytes.
+ * `flags` (optional): a bitfield that indicates whether the memory is mapped for reading
+ :read, :write, and/or :write-invalidate-region.
+ * `wait-events` (optional): [[events]] array specifying the events (if any)
+ that need to complete before this operation.
+ * `event` (optional): if specified, the `cl_event` object tied to
+ the execution of this operation.
+
+ If event is specified, the operation is asynchronous, otherwise it blocks the
+ current thread until the data transfer completes. See also [[register]].
+
+ See also [[enq-svm-map*]].
+
+ See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueSVMMap.html,
+ http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueSVMMap-org.jocl.cl_command_queue-boolean-long-org.jocl.Pointer-long-int-org.jocl.cl_event:A-org.jocl.cl_event-
+
+ Examples:
+
+ (enq-svm-map queue svm-data 0 [:write :read] (events ev-nd) ev-map)
+ (enq-svm-map queue svm-data [:write :read] (events ev-nd) ev-map)
+ (enq-svm-map queue svm-data :write ev-map)
+ (enq-svm-map queue svm-data :read)
+ (enq-svm-map svm-data :write-invalidate-region)
+
Enqueues a command to indicate that the host has completed updating the region
+given by svm [[SVMMem]] and which was specified in a previous call to
+[[enq-svm-map!]].
+
+Arguments:
+
+* `queue` (optional): the `cl_command_queue` that unmaps the object.
+If omitted, [[*command-queue*]] will be used.
+* `svm`: the [[SVMMem]] that is going to be unmapped.
+* `wait-events` (optional): [[events]] array specifying the events (if any)
+that need to complete before this operation.
+* `event` (optional): if specified, the `cl_event` object tied to
+the execution of this operation.
+
+If event is specified, the operation is asynchronous, otherwise it blocks the
+current thread until the data transfer completes. See also [[register]].
+
+See also [[enq-svm-map!]].
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueSVMUnmap,
+http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueSVMUnmap-org.jocl.cl_command_queue-org.jocl.Pointer-int-org.jocl.cl_event:A-org.jocl.cl_event-
+
+Examples:
+
+ (enq-svm-unmap! queue svm-data byte-buff (events ev-nd) ev-map)
+ (enq-svm-unmap! queue svm-data byte-buff ev-map)
+ (enq-svm-unmap! queue svm-data byte-buff)
+ (enq-svm-unmap! svm-data byte-buff)
Enqueues a command to unmap a previously mapped memory region.
+Returns the queue.
+
+Arguments:
+
+* `queue` (optional): the `cl_command_queue` that unmaps the object.
+If omitted, [[*command-queue*]] will be used.
+* `cl`: the [[CLMem]] that is going to be unmapped.
+* `host`: the host byte buffer that is going to be unmapped.
+* `wait-events` (optional): [[events]] array specifying the events (if any)
+that need to complete before this operation.
+* `event` (optional): if specified, the `cl_event` object tied to
+the execution of this operation.
+
+If event is specified, the operation is asynchronous, otherwise it blocks the
+current thread until the data transfer completes. See also [[register]].
+
+See also [[enq-map-buffer!]].
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueUnmapMemObject,
+http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueUnmapMemObject-org.jocl.cl_command_queue-org.jocl.cl_mem-java.nio.ByteBuffer-int-org.jocl.cl_event:A-org.jocl.cl_event-
+
+Examples:
+
+ (enq-unmap! queue cl-data byte-buff (events ev-nd) ev-map)
+ (enq-unmap! queue cl-data byte-buff ev-map)
+ (enq-unmap! queue cl-data byte-buff)
+ (enq-unmap! cl-data byte-buff)
+
Enqueues a command to write to a cl object from host memory.
+Returns the queue.
+
+Arguments:
+
+* `queue` (optional): the `cl_command_queue` that writes the object.
+If omitted, [[*command-queue*]] will be used.
+* `cl`: the [[CLMem]] that is going to be written to.
+* `host`: [[Mem]] object on the host that the data is to be transferred from.
+Must be a direct buffer is the writing is asynchronous.
+* `blocking`: boolean indicator of synchronization.
+* `offset`: the offset in bytes in the buffer object to write to.
+* `wait-events` (optional): [[events]] array specifying the events (if any)
+that need to complete before this operation.
+* `event` (optional): if specified, the `cl_event` object tied to
+the execution of this operation.
+
+If event is specified, the operation is asynchronous, otherwise it blocks the
+current thread until the data transfer completes, unless explicitly specifiend
+with `blocking`. See also [[register]].
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueWriteBuffer.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueWriteBuffer-org.jocl.cl_command_queue-org.jocl.cl_mem-boolean-long-long-org.jocl.Pointer-int-org.jocl.cl_event:A-org.jocl.cl_event-
+
+Examples:
+
+ (let [host-data (direct-buffer 32)
+ ev (event)
+ notifications (chan)
+ follow (register notifications)]
+ (enq-write! my-queue cl-data host-data ev) ;; asynchronous
+ (follow ev)
+ (<!! notifications))
+
+ (enq-write! my-queu cl-data host-data) ;; blocking
+
Queries `platform` for the number of devices of one or a combination of
+several `device-type`s:
+`:gpu`, `:cpu`, `:all`, `:accelerator`, `:custom`, `:default`.
+
+When called with only one argument `x`:
+
+* if `x` is a keyword, returns the number of devices of type `x` in `*platform*`;
+* otherwise returns the number of all devices on the platform `x`.
+
+When called with no arguments, returns the number of all devices in `*platform*`.
+
+When called with an invalid platform, throws [ExceptionInfo]
+(http://clojuredocs.org/clojure.core/ex-info). When called with an unknown
+device type, throws `NullPointerException`
+
+See also [[num-devices*]].
+
+Examples:
+
+ (num-devices)
+ (num-devices (first (platforms)))
+ (num-devices :gpu)
+ (num-devices (first (platforms)) :gpu :cpu :accelerator)
+
num-kernels
(num-kernels program)
Returns the number of kernels in `program` (`cl_program`).
+
Creates a convenience function that registers callbacks for events.
+It is a high-level alternative to [[set-event-callback*]]. MUST be called
+AFTER the event is used in the enqueue operation.
+
+* `channel` is a channel for communicating asynchronous notifications
+* `callback-type` is an optional keyword that specifies the command execution
+status that will be the default for the resulting function: `:complete`,
+`:submitted`, or `running`.
+
+Returns a function with the following arguments:
+
+* `e` - user event that is being followed
+* `callback-type` - optional command execution status; if ommited, the default
+is used
+* `data` - optional notification data
+
+When called, the created function returns `channel` with registered callback.
+
+See [[event-callback]], [[set-event-callback*]], [[event]].
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSetEventCallback.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clSetEventCallback-org.jocl.cl_event-int-org.jocl.EventCallbackFunction-java.lang.Object-
+
+Example:
+
+ (def notifications (chan))
+ (def follow (register notifications))
+ (def e (event))
+ (enq-read! comm-queue cl-object host-object e
+ (follow e)
+ (:event (<!! notifications))
+
release-context!
(release-context!)
Release global platform, context, and command queue (if any exists).
+
set-arg!
(set-arg! kernel n value)
Sets the argument value for a specific positional argument of a kernel.
+Returns the changed `cl_kernel` object. `value` should implement [[Argument]]
+protocol.
+
+The arguement can be a [[Mem]] ([[CLBuffer]], [[CLImage]], Java primitive arrays),
+or a number.
+In the case of [[Mem]] objects, the memory object will be set as an argument.
+In the case the argument is a number, its long value will be used as a size
+of the local memory to be allocated on the device.
+
+In case of OpenCL errors during the program build, throws
+`Exceptioninfo`. if `value` is of the type that is not supported,
+throws `IllegalArgumentexception`.
+
+See [[kernel]], [[program]], [[Argument]], [[cl-buffer]].
+
+See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSetKernelArg.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clSetKernelArg-org.jocl.cl_kernel-int-long-org.jocl.Pointer-
+
+Examples:
+
+ (set-arg! my-kernel 0 cl-buffer0)
+ (set-arg! my-kernel 1 cl-buffer1)
+ (set-arg! my-kernel 2 (int-array 8))
+ (set-arg! my-kernel 3 42)
+
set-args!
(set-args! kernel x & values)
Sets all provided arguments of `kernel`, starting from optional index `x`,
+and returns the changed `cl_kernel` object.
+Equivalent to calling [[set-arg!]] for each provided argument.
+
+Examples:n
+
+ (set-args! my-kernel cl-buffer-0)
+ (set-args! my-kernel cl-buffer-0 cl-buffer-1 (int-array 8) 42)
+ (set-args! my-kernel 2 cl-buffer-2 cl-buffer-3 (int-array 8) 42)
+
set-context!
(set-context! ctx)(set-context!)
Sets the var root binding of [[*context*]] to the context `ctx` or the default context.
+
set-default!
(set-default!)
Sets the root bindings to the default platform, context and command queue.
+
set-default-1!
(set-default-1!)
Sets the root bindings to the default platform, context and command queue.
+
set-platform!
(set-platform! p)(set-platform!)
Sets the var root binding of [[*platform*]] to the platform `p` or the default platform.
+
set-queue!
(set-queue! q)(set-queue!)
Sets the var root binding of [[*command-queue*]] to the queue `q` or the default command queue on
+the default device in the default context.
Sorts a given sequence of devices by the OpenCL version they support.
+The devices with hihger versions come first. If some devices support the same
+version their order is not changed.
Creates a svm buffer object ([[SVMBuffer]]) in `ctx`, given `size` and `alignment`
+in bytes and one or more memory allocation usage keyword flags: `:read-write`,
+`:read-only`, `:write-only`, :fine-grain-buffer, and/or :atomics
+
+If called with two arguments, uses the default alignment (platform dependent)
+and default `*context*` (see [[with-context]]). If called with one argument,
+use the default context, and alignment,and :read-write flag.
+
+**Needs to be released after use.** If you rely on the [[release]] method,
+be sure that all enqueued processing that uses this buffer finishes prior
+to that (watch out for non-blocking enqueues!).
+
+If `ctx` is nil or the buffer size is invalid, throws `IllegalArgumentException`.
+If some of the flags is invalid, throws `NullPointerException`.
+
+See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSVMAlloc.html,
+http://www.jocl.org/doc/org/jocl/CL.html#clSVMAlloc-org.jocl.cl_context-long-long-int-
+
+Examples:
+
+ (svm-buffer 32 :read-only)
+ (svm-buffer ctx 24 0 :fine-grain-buffer :atomics)
+
svm-buffer?
(svm-buffer? x)
Checks whether an object is an SVM buffer.
+
with-context
macro
(with-context context & body)
Dynamically binds `context` to the default context [[*context*]].
+and evaluates the body with that binding. Releases the context
+in the `finally` block. Take care *not* to release that context in
+some other place; JVM might crash.
+
+Example:
+
+ (with-context (context devices)
+ (context-info))
+
with-default
macro
(with-default & body)
Dynamically binds [[*platform*]], [[*context*]] and [[*command-queue*]]
+to the first of the available platforms, the context containing the first
+device of that platform that supports the highest OpenCL version, and the queue on
+the device in that context. Requires OpenCL 2.0 support in the platform.
+If you're using OpenCL 1.2 or lower, use [[with-default-1]]
with-default-1
macro
(with-default-1 & body)
Dynamically binds [[*platform*]], [[*context*]] and [[*command-queue]]
+to the first of the available platforms, the context containing the first
+device of that platform, and the queue on the device in that context.
+Supports pre-2.0 platforms.
with-platform
macro
(with-platform platform & body)
Dynamically binds `platform` to the default platform [[*platform*]] and
+evaluates the body with that binding.
with-queue
macro
(with-queue queue & body)
Dynamically binds `queue` to the default queue [[*command-queue*]].
+and evaluates the body with that binding. Releases the queue
+in the `finally` block. Take care *not* to release that queue in
+some other place; JVM might crash.
+
+Example:
+
+ (with-queue (command-queue dev)
+ (enq-read cl-data data))
+
work-size
(work-size global local offset)(work-size global local)(work-size global)(work-size)
Creates a [[WorkSize]] record, that sets global, local and offset
+parameters in enqueuing ND kernels. All arguments are sequences,
+holding as many arguments, as there are dimensions in the appropriate
+ND kernel. In OpenCL 2.0, it is usually 1, 2, or 3, depending on the device.
+
+See [[enq-kernel!]]
+Examples:
+
+ (work-size [102400 25600] [1024 128] [4 8])
+ (work-size [1024 256] [16 16])
+ (work-size [256])
+ (work-size) ; same as (work-size [1])
+
work-size-1d
(work-size-1d global local offset)(work-size-1d global local)(work-size-1d global)(work-size-1d)
Creates a 1-dimensional [[WorkSize]] from the long numbers it receives.
+See also [[work-size]].
+
+Examples:
+(work-size-1d 1024)
+(work-size-1d 1024 256)
+(work-size-1d 1024 256 1)
Creates a 3-dimensional [[WorkSize]] from the long numbers it receives.
+See also [[work-size]].
+
+Examples:
+(work-size-3d 1024 2048 512)
+(work-size-3d 1024 2048 256 16 16)
+(work-size-3d 1024 2048 128 16 4 4 16 0 2 512)
+
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.info.html b/codox/uncomplicate.clojurecl.info.html
new file mode 100644
index 0000000..e1cb941
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.info.html
@@ -0,0 +1,132 @@
+
+uncomplicate.clojurecl.info documentation
Info functions for all OpenCL objects (platforms, devices, etc...).
+
+The OpenCL standard defines info functions for all cl structures. Typically
+in OpenCL C, you would have a reference to an object representing, for example,
+platform, and then call a dedicated info function, in this case
+[`clGetPlatformInfo`](http://www.jocl.org/doc/org/jocl/CL.html#clGetPlatformInfo-org.jocl.cl_platform_id-int-long-org.jocl.Pointer-long:A-)
+with a parameter param_name that specifies which of the several available
+informations you want about that object. If you need all information, then you
+need to call this function as many times as different kinds of information there is.
+
+ClojureCL provides many conveniences for obtaining information about cl objects:
+
+1. **There is a universal, high-level, [[info]] function** that works for all kinds
+ of cl objects (platform, context, device, memory, etc.) and displays all available
+ information. This function also accepts a keyword argument for returning
+ only a specific kind of information, not all information. The information
+ will be converted from low-level C enums to a Clojre-friendly format that
+ uses keywords, sequences, sets, etc. It will release all additional cl objects
+ that it has to use to obtain information. If there is an OpenCL error in obtaining
+ the information, which may happen if the driver does not support that kind of
+ information, the [ExceptionInfo](http://clojuredocs.org/clojure.core/ex-info)
+ will be returned as a result for that particular information, instead of
+ raising an exception. This function is useful in when the information
+ is going to be displayed to the user.
+
+2. For each information kind, there is a dedicated, low-level, function that
+ returns the raw, unconverted information. If the result is a cl object that
+ needs to be released after use, it is the responsibility of the caller to
+ call the [[core/release]] function. If the information is not supported,
+ the exception is raised. These functions are convenient in the parts
+ of the program where the returned info is used by other parts of the program,
+ for example to calculate some parameters for an algorithm.
+
+3. Some information is not only about the objects, for example program, but
+ about the specific use of that object, for example a program build. In that
+ case, aditional X-info function is provided, for example [[build-info]].
+
+Most keywords in the [[info]] function are exactly the same as the corresponding
+low-level function name, except in a few cases where that would produce a clash
+with some other functionality. You can check the available keywords in
+the documentation of appropriate positional methods:
+[[->PlatformInfo]], [[->DeviceInfo]], [[->CommandQueueInfo]], [[->ContextInfo]],
+[[->KernelInfo]], [[->KernelArgInfo]], [[->ProgramInfo]], [[->ProgramBuildinfo]],
+[[->EventInfo]], [[->Profilinginfo]], [[->MemObjectInfo]], etc...
+
+###Cheat Sheet
+
+#### Low-level info functions grouped by resource type:
+
+* [`cl_platform_id`](http://www.jocl.org/doc/org/jocl/cl_platform_id.html) info:
+[[version]], [[icd-suffix-khr]], [[profile]], [[name-info]], [[vendor]],
+[[extensions]]
+
+* [`cl_device_id`] (http://www.jocl.org/doc/org/jocl/cl_device_id.html) info:
+[[address-bits]], [[available]], [[built-in-kernels]], [[compiler-available]],
+[[double-fp-config]], [[endian-little]], [[error-correction-support]],
+[[execution-capabilities]], [[global-mem-cache-size]], [[global-=mem-cache-type]],
+[[global-mem-cacheline-size]], [[global-mem-size]],
+[[global-variable-preferred-total-size]], [[image2d-max-height]],
+[[image2d-max-width]], [[image3d-max-depth]], [[image3d-max-height]],
+[[image3d-max-width]], [[image-base-address-alignment]], [[image-max-array-size]],
+[[image-max-array-size]], [[image-max-buffer-size]], [[image-pitch-alignment]],
+[[image-support]], [[linker-available]], [[local-mem-size]], [[local-mem-type]],
+[[max-clock-frequency]], [[max-compute-units]], [[max-constant-args]],
+[[max-constant-buffer-size]], [[max-global-variable-size]], [[max-mem-aloc-size]],
+[[max-on-device-events]], [[max-on-device-queues]], [[max-parameter-size]],
+[[max-pipe-args]], [[max-read-image-args]], [[max-read-write-image-args]],
+[[max-samplers]], [[max-work-group-size]], [[max-work-item-dimensions]],
+[[max-work-item-sizes]], [[max-write-image-args]], [[mem-base-addr-align]],
+[[native-vector-width-char]], [[native-vector-width-short]],
+[[native-vector-width-int]], [[native-vector-width-long]],
+[[native-vector-width-float]], [[native-vector-width-double]],
+[[native-vector-width-half]], [[opencl-c-version]], [[parent-device]],
+[[partition-affinity-domain]], [[partition-max-sub-devices]],
+[[partition-properties]], [[partition-type]],[[pipe-max-active-reservations]],
+[[pipe-max-packet-size]], [[platform]], [[preferred-global-atomic-alignment]],
+[[preferred-interop-user-sync]], [[preferred-local-atomic-alignment]],
+[[preferred-platform-atomic-alignment]], [[preferred-vector-width-char]],
+[[preferred-vector-width-short]], [[preferred-vector-width-int]],
+[[preferred-vector-width-long]], [[preferred-vector-width-float]],
+[[preferred-vector-width-double]], [[preferred-vector-width-half]],
+[[printf-buffer-size]], [[profiling-timer-resolution]], [[queue-on-device-max-size]],
+[[queue-on-device-properties]], [[queue-on-host-properties]],
+[[single-fp-config]], [[spir-versions]], [[svm-capabilities]],
+[[device-type]], [[vendor-id]], [[device-version]],
+[[driver-version]], [[extensions]], [[name-info]], [[profile]], [[vendor]],
+[[reference-count]]
+
+* [`cl_context`] (http://www.jocl.org/doc/org/jocl/cl_context.html) info:
+[[num-devices-in-context]], [[devices-in-context]], [[properties]],
+[[reference-count]]
+
+* [`cl_command_queue`] (http://www.jocl.org/doc/org/jocl/cl_command_queue.html) info:
+[[queue-context]], [[queue-device]], [[queue-size]], [[properties]],
+[[reference-count]]
+
+* [`cl_event`] (http://www.jocl.org/doc/org/jocl/cl_event.html) info:
+[[event-command-queue]], [[event-context]], [[command-type]], [[execution-status]],
+[[reference-count]]
+
+* profiling event info: **[[profiling-info]]**,
+[[queued]], [[submit]], [[start]], [[end]]
+
+* [`cl_kernel`] (http://www.jocl.org/doc/org/jocl/cl_kernel.html) info:
+[[function-name]], [[num-args]], [[kernel-context]], [[kernel-program]],
+[[attributes]], [[reference-count]]
+
+* kernel argument info: **[[arg-info]]**
+[[arg-address-qualifier]], [[arg-access-qualifier]], [[arg-type-name]],
+[[arg-type-qualifier]], [[arg-name]]
+
+* [`cl_mem`] (http://www.jocl.org/doc/org/jocl/cl_mem.html) info:
+[[mem-type]], [[flags]], [[mem-size]], [[map-count]], [[mem-context]],
+[[associated-memobject]], [[offset]], [[uses-svm-pointer]], [[reference-count]]
+
+* [`cl_program`] (http://www.jocl.org/doc/org/jocl/cl_program.html) info:
+[[program-context]], [[program-num-devices]], [[program-devices]],
+[[program-source]], [[binary-sizes]], [[binaries]], [[program-num-kernels]],
+[[kernel-names]], [[reference-count]]
+
+* program build info: **[[build-info]]**,
+[[build-status]], [[build-options]], [[build-log]], [[binary-type]],
+[[global-variable-total-size]]
+
+#### Hihg-level info and keywords (in a few cases different than low-level function names)
+
+[[->PlatformInfo]], [[->DeviceInfo]], [[->CommandQueueInfo]], [[->ContextInfo]],
+[[->KernelInfo]], [[->KernelArgInfo]], [[->ProgramInfo]], [[->ProgramBuildinfo]],
+[[->EventInfo]], [[->Profilinginfo]], [[->MemObjectInfo]],
+
(build-info program device info-type)(build-info program device)
build-log
(build-log program device)
build-options
(build-options program device)
build-status
(build-status program device)
built-in-kernels
(built-in-kernels device)
command-type
(command-type event)
compiler-available
(compiler-available device)
device-type
(device-type device)
device-version
(device-version device)
devices-in-context
(devices-in-context context)
double-fp-config
(double-fp-config device)
driver-version
(driver-version device)
durations
(durations pi)
end
(end event)
endian-little
(endian-little device)
error-correction-support
(error-correction-support device)
event-command-queue
(event-command-queue event)
event-context
(event-context event)
execution-capabilities
(execution-capabilities device)
execution-status
(execution-status event)
flags
(flags mo)
function-name
(function-name kernel)
global-mem-cache-size
(global-mem-cache-size device)
global-mem-cache-type
(global-mem-cache-type device)
global-mem-cacheline-size
(global-mem-cacheline-size device)
global-mem-size
(global-mem-size device)
global-variable-preferred-total-size
(global-variable-preferred-total-size device)
global-variable-total-size
(global-variable-total-size program device)
icd-suffix-khr
(icd-suffix-khr platform)
image-base-address-alignment
(image-base-address-alignment device)
image-max-array-size
(image-max-array-size device)
image-max-buffer-size
(image-max-buffer-size device)
image-pitch-alignment
(image-pitch-alignment device)
image-support
(image-support device)
image2d-max-height
(image2d-max-height device)
image2d-max-width
(image2d-max-width device)
image3d-max-depth
(image3d-max-depth device)
image3d-max-height
(image3d-max-height device)
image3d-max-width
(image3d-max-width device)
InfoExtensions
protocol
members
extensions
(extensions this)
InfoName
protocol
members
name-info
(name-info this)
InfoProfile
protocol
members
profile
(profile this)
InfoProperties
protocol
members
properties
(properties this)
InfoReferenceCount
protocol
members
reference-count
(reference-count this)
InfoVendor
protocol
members
vendor
(vendor this)
kernel-context
(kernel-context kernel)
kernel-names
(kernel-names p)
kernel-program
(kernel-program kernel)
linker-available
(linker-available device)
local-mem-size
(local-mem-size device)
local-mem-type
(local-mem-type device)
map-count
(map-count mo)
max-clock-frequency
(max-clock-frequency device)
max-compute-units
(max-compute-units device)
max-constant-args
(max-constant-args device)
max-constant-buffer-size
(max-constant-buffer-size device)
max-global-variable-size
(max-global-variable-size device)
max-mem-aloc-size
(max-mem-aloc-size device)
max-on-device-events
(max-on-device-events device)
max-on-device-queues
(max-on-device-queues device)
max-parameter-size
(max-parameter-size device)
max-pipe-args
(max-pipe-args device)
max-read-image-args
(max-read-image-args device)
max-read-write-image-args
(max-read-write-image-args device)
max-samplers
(max-samplers device)
max-work-group-size
(max-work-group-size device)
max-work-item-dimensions
(max-work-item-dimensions device)
max-work-item-sizes
(max-work-item-sizes device)
max-write-image-args
(max-write-image-args device)
mem-base-addr-align
(mem-base-addr-align device)
mem-context
(mem-context mo)
mem-size
(mem-size mo)
mem-type
(mem-type mo)
native-vector-width-char
(native-vector-width-char device)
native-vector-width-double
(native-vector-width-double device)
native-vector-width-float
(native-vector-width-float device)
native-vector-width-half
(native-vector-width-half device)
native-vector-width-int
(native-vector-width-int device)
native-vector-width-long
(native-vector-width-long device)
native-vector-width-short
(native-vector-width-short device)
num-args
(num-args kernel)
num-devices-in-context
(num-devices-in-context context)
offset
(offset mo)
opencl-c-version
(opencl-c-version device)
parent-device
(parent-device device)
partition-affinity-domain
(partition-affinity-domain device)
partition-max-sub-devices
(partition-max-sub-devices device)
partition-properties
(partition-properties device)
partition-type
(partition-type device)
pipe-max-active-reservations
(pipe-max-active-reservations device)
pipe-max-packet-size
(pipe-max-packet-size device)
platform
(platform device)
preferred-global-atomic-alignment
(preferred-global-atomic-alignment device)
preferred-interop-user-sync
(preferred-interop-user-sync device)
preferred-local-atomic-alignment
(preferred-local-atomic-alignment device)
preferred-platform-atomic-alignment
(preferred-platform-atomic-alignment device)
preferred-vector-width-char
(preferred-vector-width-char device)
preferred-vector-width-double
(preferred-vector-width-double device)
preferred-vector-width-float
(preferred-vector-width-float device)
preferred-vector-width-half
(preferred-vector-width-half device)
preferred-vector-width-int
(preferred-vector-width-int device)
preferred-vector-width-long
(preferred-vector-width-long device)
preferred-vector-width-short
(preferred-vector-width-short device)
printf-buffer-size
(printf-buffer-size device)
profiling-info
(profiling-info event info)(profiling-info event)
profiling-timer-resolution
(profiling-timer-resolution device)
program-context
(program-context p)
program-devices
(program-devices p)
program-num-devices
(program-num-devices p)
program-num-kernels
(program-num-kernels p)
program-source
(program-source p)
queue-context
(queue-context queue)
queue-device
(queue-device queue)
queue-on-device-max-size
(queue-on-device-max-size device)
queue-on-device-preferred-size
(queue-on-device-preferred-size device)
queue-on-device-properties
(queue-on-device-properties device)
queue-on-host-properties
(queue-on-host-properties device)
queue-size
(queue-size queue)
queued
(queued event)
single-fp-config
(single-fp-config device)
spir-versions
(spir-versions device)
start
(start event)
submit
(submit event)
svm-capabilities
(svm-capabilities device)
uses-svm-pointer
(uses-svm-pointer mo)
vendor-id
(vendor-id device)
version
(version platform)
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.internal.constants.html b/codox/uncomplicate.clojurecl.internal.constants.html
new file mode 100644
index 0000000..c959bbc
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.internal.constants.html
@@ -0,0 +1,49 @@
+
+uncomplicate.clojurecl.internal.constants documentation
Defines constants and mappings from/to OpenCL constants.
+
+ OpenCL API defines and uses numerous int/long C-style constants as arguments
+in functions calls, mostly for configuring various options. Clojure uses keywords
+as an user friendly alternative. ClojureCL's `core` namespace contains primitive
+functions suffixed with `*`, which still accept the low level constants
+defined in `org.jocl.CL` Java class, but the preferred, easier, and natural way
+is to use keywords. Another benefit of that method is that you can easily view
+available options by printing an appropriate hash-map from this namespace.
+
+ Most mappings are two-way. Hashmaps that convert keywords to number codes
+ are named `cl-something-clish`, while functions that convert numbers to keywords
+ are named `dec-something-clish`. You can see which keywords are available for
+ a certain property by evaluate appropriate `cl-something-clish` hashmap.
+ All hashmaps and functions contain brief doc and a web link to appropriate
+ online OpenCL documentation with detailed explanations
+
+ Also see the summary at
+ http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/enums.html
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.internal.protocols.html b/codox/uncomplicate.clojurecl.internal.protocols.html
new file mode 100644
index 0000000..89a47cb
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.internal.protocols.html
@@ -0,0 +1,18 @@
+
+uncomplicate.clojurecl.internal.protocols documentation
Object that can be argument in OpenCL kernels. Built-in implementations:
+[[CLBuffer]], java numbers, primitive arrays and `ByteBuffer`s.
members
set-arg
(set-arg arg kernel n)
Specific implementation of setting the kernel arguments.
+
CLMem
protocol
A wrapper for `cl_mem` objects, that also holds a `Pointer` to the cl mem
+object, context that created it, and size in bytes. It is useful in many
+functions that need that (redundant in Java) data because of the C background
+of OpenCL functions.
members
enq-copy*
(enq-copy* this queue dst src-offset dst-offset cb wait-events ev)
A specific implementation for copying this `cl-mem` object to another cl mem.
+
enq-fill*
(enq-fill* this queue pattern offset multiplier wait-events ev)
A specific implementation for filling this `cl-mem` object.
+
Mem
protocol
An object that represents memory that participates in OpenCL operations.
+It can be on the device ([[CLMem]]), or on the host. Built-in implementations:
+cl buffer, Java primitive arrays and `ByteBuffer`s.
members
ptr
(ptr this)
JOCL `Pointer` to this object.
+
size
(size this)
Memory size of this cl or host object in bytes.
+
SVMMem
protocol
A wrapper for SVM Buffer objects, that also holds a context that created it,
+`Pointer`, size in bytes, and can create a `ByteBuffer`. It is useful in many
+functions that need that (redundant in Java) data because of the C background
+of OpenCL functions.
members
byte-buffer
(byte-buffer this)(byte-buffer this offset size)
Creates a Java `ByteBuffer` for this SVM memory.
+
enq-svm-copy
(enq-svm-copy this)
Wrappable
protocol
members
wrap
(wrap this)
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.internal.utils.html b/codox/uncomplicate.clojurecl.internal.utils.html
new file mode 100644
index 0000000..d5e72ce
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.internal.utils.html
@@ -0,0 +1,45 @@
+
+uncomplicate.clojurecl.internal.utils documentation
Utility functions used as helpers in other ClojureCL namespaces.
+The user of the ClojureCL library would probably not need to use
+any of the functions defined here.
error
(error err-code details)(error err-code)
Converts an OpenCL error code to an [ExceptionInfo]
+(http://clojuredocs.org/clojure.core/ex-info)
+with richer, user-friendly information.
+
+Accepts a long `err-code` that should be one of the codes defined in
+OpenCL standard, and an optional `details` argument that could be
+anything that you think is informative.
+
+See the available codes in the source of [[constants/dec-error]].
+Also see the discussion about
+[OpenCL error codes](http://streamcomputing.eu/blog/2013-04-28/opencl-1-2-error-codes/).
+
+Examples:
+
+ (error 0) => an ExceptionInfo instance
+ (error -5 {:comment "Why here?""}) => an ExceptionInfo instance
+
maybe
macro
(maybe form)
Evaluates form in try/catch block; if an OpenCL-related exception is caught,
+substitutes the result with the [ExceptionInfo](http://clojuredocs.org/clojure.core/ex-info)
+object.
+Non-OpenCL exceptions are rethrown. Useful when we do not want to let a minor
+OpenCL error due to a driver incompatibility with the standard
+or an unimplemented feature in the actual driver crash the application.
+An [ExceptionInfo](http://clojuredocs.org/clojure.core/ex-info) object will be
+put in the place of the expected result.
with-check
macro
(with-check status form)(with-check status details form)
Evaluates `form` if `status` is not zero (`CL_SUCCESS`), otherwise throws
+an appropriate `ExceptionInfo` with decoded informative details.
+It helps fith JOCL methods that return error codes directly, while
+returning computation results through side-effects in arguments.
+
+Example:
+
+ (with-check (some-jocl-call-that-returns-error-code) result)
+
with-check-arr
macro
(with-check-arr status form)(with-check-arr status details form)
Evaluates `form` if the integer in the `status` primitive int array is `0`,
+Otherwise throws an exception corresponding to the error code.
+Similar to [[with-check]], but with the error code being held in an array instead
+of being a primitive number. It helps with JOCL methods that return results
+directly, and signal errors through side-effects in a primitive array argument.
+
+ (let [err (int-array 1)
+ res (some-jocl-call err)]
+ (with-checl-arr err res))
+
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.legacy.html b/codox/uncomplicate.clojurecl.legacy.html
new file mode 100644
index 0000000..ea38dbb
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.legacy.html
@@ -0,0 +1,33 @@
+
+uncomplicate.clojurecl.legacy documentation
Legacy alternatives for the functions from the core namespaces. If you need to use functions that were removed from the latest standard look for them here. Usually, they will be the same or similar to core functions, but will be suffixed by the largest version number that they support. Notable example is the command-queue-1 function that is required if your platform does not support at least OpenCL 2.0.
command-queue-1
(command-queue-1 ctx device x & properties)(command-queue-1 ctx device)(command-queue-1 device)
Creates a host or device command queue on a specific device.
+
** If you need to support legacy OpenCL 1.2 or earlier platforms, you MUST use this function instead of [command-queue], which is for OpenCL 2.0 and higher. What is important is the version of the platform, not the devices.**
+
Arguments are:
+
+
ctx - the cl_context for the queue;
+
device - the cl_device_id for the queue;
+
x - if integer, the size of the (on device) queue, otherwise treated as property;
Creates a host or device command queue on a specific device.
+
** If you need to support legacy OpenCL 1.2 or earlier platforms, you MUST use this function instead of [command-queue*], which is for OpenCL 2.0 and higher. What is important is the version of the platform, not the devices.**
+
Arguments are:
+
+
ctx - the cl_context for the queue;
+
device - the cl_device_id for the queue;
+
size - the size of the (on device) queue;
+
properties - long bitmask containing properties, defined by the OpenCL standard are available as constants in the org.jocl.CL class.
Examples: (command-queue-1* ctx dev 524288 (bit-or CL/CL_QUEUE_PROFILING_ENABLED CL/CL_QUEUE_ON_DEVICE)) (command-queue-1* ctx dev CL/CL_QUEUE_PROFILING_ENABLED)
with-default-1
macro
(with-default-1 & body)
Dynamically binds *platform*, *context* and *command-queue to the first of the available platforms, the context containing the first device of that platform, and the queue on the device in that context. Supports pre-2.0 platforms.
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.toolbox.html b/codox/uncomplicate.clojurecl.toolbox.html
new file mode 100644
index 0000000..ce534f8
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.toolbox.html
@@ -0,0 +1,5 @@
+
+uncomplicate.clojurecl.toolbox documentation
Various helpers that are not needed by ClojureCL itself,
+but may be very helpful in applications. See Neanderthal and Bayadera libraries
+for the examples of how to use them.
(enq-reduce! queue main-kernel reduction-kernel n local-n)(enq-reduce! queue main-kernel reduction-kernel m n local-m local-n)
\ No newline at end of file
diff --git a/codox/uncomplicate.clojurecl.utils.html b/codox/uncomplicate.clojurecl.utils.html
new file mode 100644
index 0000000..8c9bc2b
--- /dev/null
+++ b/codox/uncomplicate.clojurecl.utils.html
@@ -0,0 +1,16 @@
+
+uncomplicate.clojurecl.utils documentation
Utility functions used as helpers in other ClojureCL namespaces. The user of the ClojureCL library would probably not need to use any of the functions defined here.
error
(error err-code details)(error err-code)
Converts an OpenCL error code to an ExceptionInfo with richer, user-friendly information.
+
Accepts a long err-code that should be one of the codes defined in OpenCL standard, and an optional details argument that could be anything that you think is informative.
(error 0) => an ExceptionInfo instance
+(error -5 {:comment "Why here?""}) => an ExceptionInfo instance
+
maybe
macro
(maybe form)
Evaluates form in try/catch block; if an OpenCL-related exception is caught, substitutes the result with the ExceptionInfo object. Non-OpenCL exceptions are rethrown. Useful when we do not want to let a minor OpenCL error due to a driver incompatibility with the standard or an unimplemented feature in the actual driver crash the application. An ExceptionInfo object will be put in the place of the expected result.
with-check
macro
(with-check status form)(with-check status details form)
Evaluates form if status is not zero (CL_SUCCESS), otherwise throws an appropriate ExceptionInfo with decoded informative details. It helps fith JOCL methods that return error codes directly, while returning computation results through side-effects in arguments.
(with-check-arr status form)(with-check-arr status details form)
Evaluates form if the integer in the status primitive int array is 0, Otherwise throws an exception corresponding to the error code. Similar to with-check, but with the error code being held in an array instead of being a primitive number. It helps with JOCL methods that return results directly, and signal errors through side-effects in a primitive array argument.
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..b02b2b0
--- /dev/null
+++ b/index.html
@@ -0,0 +1,67 @@
+---
+title: ClojureCL - a Clojure library for parallel computations with OpenCL 2.0 (GPGPU).
+layout: default
+---
+
+
+
ClojureCL
+
+
+
+ Parallel computations with OpenCL 2.0 in Clojure
+
+
High Performance Computing and GPGPU in Clojure: access the supercomputer on your desktop
+
OpenCL gives you access to many hardware optimizations.
+
It supports GPUs, CPUs, and other accelerators. On the GPU, it can be thousand times faster than pure Java. On the CPU, dozens of times faster than pure Java and several times faster than native C code.
+
+
+
Optimized for Clojure
+
Built with Clojure in mind. Sane interface and functions that fit into functional style
+ while still respecting the reality of number crunching with
+ OpenCL.
Check out the Neanderthal native matrix library. It is written in Clojure and uses ClojureCL in its GPU engine that runs matrix computations at amazing speeds.
diff --git a/project.clj b/project.clj
deleted file mode 100644
index f913410..0000000
--- a/project.clj
+++ /dev/null
@@ -1,49 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(defproject uncomplicate/clojurecl "0.16.1"
- :description "ClojureCL is a Clojure library for parallel computations with OpenCL."
- :url "https://github.com/uncomplicate/clojurecl"
- :scm {:name "git"
- :url "https://github.com/uncomplicate/clojurecl"}
- :license {:name "Eclipse Public License"
- :url "http://www.eclipse.org/legal/epl-v10.html"}
- :dependencies [[org.clojure/clojure "1.12.1"]
- [org.jocl/jocl "2.0.5"]
- [org.clojure/core.async "1.8.741"]
- [uncomplicate/commons "0.17.1"]
- [uncomplicate/fluokitten "0.10.0"]]
-
- :codox {:metadata {:doc/formt a:markdown}
- :src-dir-uri "http://github.com/uncomplicate/clojurecl/blob/master/"
- :src-linenum-anchor-prefix "L"
- :output-path "docs/codox"
- :namespaces [uncomplicate.clojurecl.core
- uncomplicate.clojurecl.info
- uncomplicate.clojurecl.toolbox
- uncomplicate.clojurecl.internal.protocols
- uncomplicate.clojurecl.internal.constants
- uncomplicate.clojurecl.internal.utils]}
-
- :profiles {:dev {:plugins [[lein-midje "3.2.1"]
- [lein-codox "0.10.8"]]
- :global-vars {*warn-on-reflection* true
- *assert* true
- *unchecked-math* :warn-on-boxed
- *print-length* 128}
- :dependencies [[midje "1.10.10"]]
- :jvm-opts ^:replace ["-Dclojure.compiler.direct-linking=true"
- "--enable-native-access=ALL-UNNAMED"
- "--add-opens=java.base/jdk.internal.ref=ALL-UNNAMED"
- "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"]}}
-
- :javac-options ["-target" "1.8" "-source" "1.8" "-Xlint:-options"]
-
- :source-paths ["src/clojure" "src/opencl"]
- :test-paths ["test/clojure" "test/opencl"]
- :java-source-paths ["src/java"])
diff --git a/src/clojure/uncomplicate/clojurecl/core.clj b/src/clojure/uncomplicate/clojurecl/core.clj
deleted file mode 100644
index d8c7c87..0000000
--- a/src/clojure/uncomplicate/clojurecl/core.clj
+++ /dev/null
@@ -1,1473 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns ^{:author "Dragan Djuric"}
- uncomplicate.clojurecl.core
- "Core ClojureCL functions for OpenCL **host** programming. The kernels should
- be provided as strings (that may be stored in files), written in OpenCL C.
-
- The OpenCL standard defines several datastructures (platform, device, etc.)
- that support the concepts defined in four OpenCL models (Platform Model,
- Memory Model, Execution Model, and Programming Model). ClojureCL uses
- a low-level JNI-based library [JOCL](http://www.jocl.org) for calling
- native OpenCL drivers - the datastructures are therefore defined in JOCL.
- They can be found in [`org.jocl`]
- (http://www.jocl.org/doc/org/jocl/package-tree.html) package.
-
- Some functions are available in two versions:
-
- * High-level, which works with clojure-friendly arguments - vectors,
- sequences, keywords, etc. These are preferred to low-level alternatives.
- * Low-level, suffexed by `*`, which work with primitive arguments
- and give primitive results. These functions are useful when you
- already have primitive data and want to avoid unnecessary conversions.
- You can find them in the [[uncomplicate.clojurecl.internal.impl]] namespace.
-
- The documentation given here is only a quick reminder; it is necessary
- to grasp OpenCL and parallel computing concepts to be able to use the
- library. Also, each function's doc entry have a link to much more detailed
- documentation available in OpenCL and JOCL reference - be sure to
- browse one of these documents wherever you are not sure about
- some of many important details.
-
- ### Cheat Sheet
-
- * resource management: [[with-release]], [[with-platform]], [[with-context]], [[with-queue]],
- [[with-default]].
-
- * [`cl_platform_id`](http://www.jocl.org/doc/org/jocl/cl_platform_id.html):
- [[num-platforms]], [[platforms]], [[platform-info]], [[with-platform]].
-
- * [`cl_device_id`](http://www.jocl.org/doc/org/jocl/cl_device_id.html):
- [[devices]], [[num-devices]].
-
- * [`cl_context`](http://www.jocl.org/doc/org/jocl/cl_context.html):
- [[context]], [[context-info]], [[with-context]], [[context-properties]].
-
- * [`cl_mem`](http://www.jocl.org/doc/org/jocl/cl_mem.html):
- [[cl-buffer]], [[cl-sub-buffer]], [[cl-buffer*]], [[Mem]], [[CLMem]].
-
- * [`cl_event`](http://www.jocl.org/doc/org/jocl/cl_event.html):
- [[event]], [[host-event]], [[events]], [[register]], [[event-callback]], [[set-status!]].
-
- * [`cl_program`](http://www.jocl.org/doc/org/jocl/cl_program.html):
- [[program-with-source]], [[build-program!]].
-
- * [`cl_kernel`](http://www.jocl.org/doc/org/jocl/cl_kernel.html):
- [[num-kernels]], [[kernel]], [[set-arg!]], [[set-args!]], [[set-arg]].
-
- * [`cl_command_queue`](http://www.jocl.org/doc/org/jocl/cl_kernel.html):
- [[command-queue]], [[work-size]], [[enq-kernel!]],
- [[enq-read!]], [[enq-write!]], [[enq-copy!]], [[enq-fill!]], [[enq-map-buffer!]], [[enq-unmap!]],
- [[enq-svm-map!]], [[enq-svm-unmap!]], [[enq-marker!]], [[enq-wait!]], [[enq-barrier!]],
- [[finish!]], [[flush!]] [[with-queue]].
- "
- (:require [uncomplicate.commons
- [core :refer [release with-release info]]
- [utils :refer [mask]]]
- [uncomplicate.fluokitten.core :refer [fmap extract]]
- [uncomplicate.clojurecl.info
- :refer [build-info program-devices opencl-c-version version devices-in-context]]
- [uncomplicate.clojurecl.internal
- [protocols :refer :all]
- [constants :refer :all]
- [impl :refer :all]
- [utils :refer [with-check with-check-arr error]]]
- [clojure.string :as str])
- (:import java.nio.ByteBuffer
- [org.jocl CL cl_platform_id cl_context_properties cl_device_id
- cl_context cl_command_queue cl_mem cl_program cl_kernel cl_sampler
- cl_event cl_buffer_region cl_queue_properties]
- [uncomplicate.clojurecl.internal.impl CLBuffer SVMBuffer]))
-
-(def ^{:dynamic true
- :doc "Dynamic var for binding the default platform."}
- *platform*)
-
-(def ^{:dynamic true
- :doc "Dynamic var for binding the default context."}
- *context*)
-
-(def ^{:dynamic true
- :doc "Dynamic var for binding the default command queue."}
- *command-queue*)
-
-;; =============== Platform =========================================
-
-(defn num-platforms
- "The number of available OpenCL platforms.
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetPlatformIDs.html
- and http://www.jocl.org/doc/org/jocl/CL.html#clGetPlatformIDs-int-org.jocl.cl_platform_id:A-int:A-
- "
- ^long []
- (let [res (int-array 1)
- err (CL/clGetPlatformIDs 0 nil res)]
- (with-check err (aget res 0))))
-
-(defn platforms
- "Returns a vector of all available OpenCL platforms (`cl_platform_id`s).
- `cl_platform_id` objects do not need to be released explicitly.
-
- Platforms are represented by the [`org.jocl.platform_id`]
- (http://www.jocl.org/doc/org/jocl/cl_platform_id.html) datastructure.
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetPlatformIDs.html
- and http://www.jocl.org/doc/org/jocl/CL.html#clGetPlatformIDs-int-org.jocl.cl_platform_id:A-int:A-
- "
- []
- (let [num-platforms (num-platforms)
- res (make-array cl_platform_id num-platforms)
- err (CL/clGetPlatformIDs num-platforms res nil)]
- (with-check err (vec res))))
-
-(defn platform-info
- "Gets the [[info/info]] of the default platform [[*platform*]] (if it is bound).
- If [[*platform*]] is unbound, throws `Illegalargumentexception`."
- []
- (info *platform*))
-
-(defn set-platform!
- "Sets the var root binding of [[*platform*]] to the platform `p` or the default platform."
- ([p]
- (release *platform*)
- (alter-var-root (var *platform*) (constantly p)))
- ([]
- (set-platform! (first (platforms)))))
-
-(defmacro with-platform
- "Dynamically binds `platform` to the default platform [[*platform*]] and
- evaluates the body with that binding."
- [platform & body]
- `(binding [*platform* ~platform]
- ~@body))
-
-(defn legacy?
- "Checks whether the platform is 'legacy', less than OpenCL 2.0, or any
- future version that is necessary for building ClojureCL."
- [platform]
- (str/includes? (version platform) "OpenCL 1."))
-
-;; =============== Device ==========================================
-
-(defn num-devices
- "Queries `platform` for the number of devices of one or a combination of
- several `device-type`s:
- `:gpu`, `:cpu`, `:all`, `:accelerator`, `:custom`, `:default`.
-
- When called with only one argument `x`:
-
- * if `x` is a keyword, returns the number of devices of type `x` in `*platform*`;
- * otherwise returns the number of all devices on the platform `x`.
-
- When called with no arguments, returns the number of all devices in `*platform*`.
-
- When called with an invalid platform, throws [ExceptionInfo]
- (http://clojuredocs.org/clojure.core/ex-info). When called with an unknown
- device type, throws `NullPointerException`
-
- See also [[num-devices*]].
-
- Examples:
-
- (num-devices)
- (num-devices (first (platforms)))
- (num-devices :gpu)
- (num-devices (first (platforms)) :gpu :cpu :accelerator)
- "
- ([platform device-type & device-types]
- (num-devices* platform (mask cl-device-type device-type device-types)))
- (^long [platform device-type]
- (num-devices* platform (cl-device-type device-type)))
- (^long [x]
- (if (keyword? x)
- (num-devices *platform* x)
- (num-devices* x CL/CL_DEVICE_TYPE_ALL)))
- (^long []
- (num-devices* *platform* CL/CL_DEVICE_TYPE_ALL)))
-
-(defn devices
- "Queries `platform` for the devices of one or a combination of
- several `device-type`s:
- `:gpu`, `:cpu`, `:all`, `:accelerator`, `:custom`, `:default`,
- and returns them in a vector containing [[internal/CLDevice]] objects.
-
- When called with only one argument `x`:
-
- * if `x` is a keyword, returns the devices of type `x` in `*platform*`;
- * otherwise returns all devices on the platform `x`.
-
- When called with no arguments, returns all devices in `*platform*`.
-
- Root level devices do not need to be explicitly released.
-
- When called with an invalid platform, throws [ExceptionInfo]
- (http://clojuredocs.org/clojure.core/ex-info). When called with an unknown
- device type, throws `NullPointerException`
-
- See also [[internal/devices*]].
-
- Examples:
-
- (devices)
- (devices (first (platforms)))
- (devices :gpu)
- (devices (first (platforms)) :gpu :cpu :accelerator)
- "
- ([platform device-type & device-types]
- (fmap wrap (vec (devices* platform (mask cl-device-type device-type device-types)))))
- ([x]
- (if (keyword? x)
- (devices *platform* x)
- (fmap wrap (vec (devices* x CL/CL_DEVICE_TYPE_ALL)))))
- ([]
- (fmap wrap (vec (devices* *platform* CL/CL_DEVICE_TYPE_ALL)))))
-
-;; ========================= Context ===========================================
-
-(defn context-properties
- "Creates `cl_context_properties` from a map of properties.
- Currently, this is not very useful, it is only here to
- support the full compatibility of [[context*]] function with
- the JOCL API."
- [props]
- (reduce (fn [^cl_context_properties cp [p v]]
- (.addProperty cp (cl-context-properties p) v)
- cp)
- (cl_context_properties.)
- props))
-
-(defn context
- "Create [[internal/CLContext]] for a vector of `device`s, with optional
- hashmap of `properties`, error reporting core.async channel `ch`
- and user data that should accompany the error report. If called with
- no arguments, creates a context using all devices of the default
- platform (`*platform`).
-
- If `devices` is empty, throws `ExceptionInfo`.
-
- **Needs to be released after use.** (see [[with-context]]).
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateContext.html
- , http://www.jocl.org/doc/org/jocl/CL.html#clCreateContext-org.jocl.cl_context_properties-int-org.jocl.cl_device_id:A-org.jocl.CreateContextFunction-java.lang.Object-int:A-
-
- Examples:
-
- (context)
- (context (devices (first (platforms))))
- (context (devices (first (platforms))) {:platform p} (chan) :my-data)
- "
- ([devices properties ch user-data]
- (wrap (context* (into-array cl_device_id (fmap extract devices))
- (and (seq properties) (context-properties properties))
- ch user-data)))
- ([devices]
- (context devices nil nil nil))
- ([]
- (with-release [devs (devices)]
- (context devs))))
-
-(defn context-info
- "Info of the default context ([[*context*]]). If [[*context*]] is unbound,
- throws `Illegalargumentexception`
-
- See also: [[with-context]]
-
- Example:
-
- (with-context (context devices)
- (context-info))
- "
- []
- (info *context*))
-
-(defn set-context!
- "Sets the var root binding of [[*context*]] to the context `ctx` or the default context."
- ([ctx]
- (release *context*)
- (alter-var-root (var *context*) (constantly ctx)))
- ([]
- (set-context! (context))))
-
-(defmacro with-context
- "Dynamically binds `context` to the default context [[*context*]].
- and evaluates the body with that binding. Releases the context
- in the `finally` block. Take care *not* to release that context in
- some other place; JVM might crash.
-
- Example:
-
- (with-context (context devices)
- (context-info))
- "
- [context & body]
- `(binding [*context* ~context]
- (try ~@body
- (finally (release *context*)))))
-
-;; =========================== Memory =========================================
-
-(defn cl-buffer?
- "Checks whether an object is a CL buffer."
- [x]
- (instance? CLBuffer x))
-
-(defn svm-buffer?
- "Checks whether an object is an SVM buffer."
- [x]
- (instance? SVMBuffer x))
-
-(defn cl-buffer
- "Creates a cl buffer object ([[CLBuffer]]) in `ctx`, given `size` in bytes
- and one or more memory allocation usage keyword flags: `:read-write`,
- `:read-only`, `:write-only`, `:use-host-ptr`, `:alloc-host-ptr`,
- `:copy-host-ptr`, `:host-write-only`, `:host-read-only`, `:host-no-access`.
-
- If called with two arguments, uses the default `*context*`
- (see [[with-context]]).
-
- **Needs to be released after use.**
-
- If `ctx` is nil or the buffer size is invalid, throws `ExceptionInfo`.
- If some of the flags is invalid, throws `IllegalArgumentexception`.
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateBuffer.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateBuffer-org.jocl.cl_context-long-long-org.jocl.Pointer-int:A-
-
- Examples:
-
- (cl-buffer 32 :read-only)
- (cl-buffer ctx 24 :write-only)
- "
- ([ctx size flag & flags]
- (cl-buffer* (extract ctx) size (mask cl-mem-flags flag flags)))
- ([^long size flag]
- (cl-buffer* (extract *context*) size (cl-mem-flags flag)))
- ([^long size]
- (cl-buffer* (extract *context*) size 0)))
-
-(defn cl-sub-buffer
- "Creates a cl buffer object ([[CLBuffer]]) that shares data with an existing
- buffer object.
-
- * `buffer` has to be a valid [[CLBuffer]] object.
- * `origin` and `size` are numbers that denote offset and size of the
- region in the origin buffer.
- * `flag` and `flags` are memory allocation usage keywords same as in
- [[cl-buffer]]
-
- **Needs to be released after use.**
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateSubBuffer.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateSubBuffer-org.jocl.cl_mem-long-int-org.jocl.cl_buffer_region-int:A-
-
- Examples:
-
- (def cl-buff (cl-buffer ctx 32 :write-only))
- (cl-sub-buffer cl-buff 8 16 :write-only)
- (cl-sub-buffer cl-buff 8 16)
- "
- ([buffer origin size flag & flags]
- (cl-sub-buffer* (extract buffer) (mask cl-mem-flags flag flags) (cl_buffer_region. origin size)))
- ([buffer origin size]
- (cl-sub-buffer* (extract buffer) 0 (cl_buffer_region. origin size))))
-
-(defn svm-buffer
- "Creates a svm buffer object ([[SVMBuffer]]) in `ctx`, given `size` and `alignment`
- in bytes and one or more memory allocation usage keyword flags: `:read-write`,
- `:read-only`, `:write-only`, :fine-grain-buffer, and/or :atomics
-
- If called with two arguments, uses the default alignment (platform dependent)
- and default `*context*` (see [[with-context]]). If called with one argument,
- use the default context, and alignment,and :read-write flag.
-
- **Needs to be released after use.** If you rely on the [[release]] method,
- be sure that all enqueued processing that uses this buffer finishes prior
- to that (watch out for non-blocking enqueues!).
-
- If `ctx` is nil or the buffer size is invalid, throws `IllegalArgumentException`.
- If some of the flags is invalid, throws `NullPointerException`.
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSVMAlloc.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clSVMAlloc-org.jocl.cl_context-long-long-int-
-
- Examples:
-
- (svm-buffer 32 :read-only)
- (svm-buffer ctx 24 0 :fine-grain-buffer :atomics)
- "
- ([ctx size alignment & flags]
- (svm-buffer* (extract ctx) size (mask cl-svm-mem-flags flags) alignment))
- ([^long size flag]
- (svm-buffer* (extract *context*) size (cl-svm-mem-flags flag) 0))
- ([^long size]
- (svm-buffer* (extract *context*) size 0 0)))
-
-;; ============== Events ==========================================
-
-(defn event
- "creates new [[internal/CLEvent]].
-
- see http://www.jocl.org/doc/org/jocl/cl_event.html.
- "
- []
- (wrap (cl_event.)))
-
-(defn host-event
- "Creates new [[internal/CLEvent]] on the host (in OpenCL terminology,
- known as \"user\" event.
-
- If called without `ctx` argument, uses [[*context*]].
-
- If `ctx` is `nil`, throws ExceptionInfo
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateUserEvent.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateUserEvent-org.jocl.cl_context-int:A-
- "
- ([]
- (host-event *context*))
- ([ctx]
- (let [err (int-array 1)
- res (CL/clCreateUserEvent (extract ctx) err)]
- (with-check-arr err {:ctx (info ctx)} (wrap res)))))
-
-(defn events
- "Creates an array of `cl_event`s. Arrays of events are
- used in enqueuing commands, not vectors or sequences."
- (^objects []
- (make-array cl_event 0))
- (^objects [e]
- (doto ^objects (make-array cl_event 1)
- (aset 0 (extract e))))
- (^objects [e0 e1]
- (doto ^objects (make-array cl_event 2)
- (aset 0 (extract e0))
- (aset 1 (extract e1))))
- (^objects [e0 e1 e2]
- (doto ^objects (make-array cl_event 3)
- (aset 0 (extract e0))
- (aset 1 (extract e1))
- (aset 2 (extract e2))))
- (^objects [e0 e1 e2 e3]
- (doto ^objects (make-array cl_event 4)
- (aset 0 (extract e0))
- (aset 1 (extract e1))
- (aset 2 (extract e2))
- (aset 3 (extract e3))))
- (^objects [e0 e1 e2 e3 e4]
- (doto ^objects (make-array cl_event 5)
- (aset 0 (extract e0))
- (aset 1 (extract e1))
- (aset 2 (extract e2))
- (aset 3 (extract e3))
- (aset 4 (extract e4))))
- (^objects [e0 e1 e2 e3 e4 & es]
- (let [len (+ 5 (count es))
- res (doto ^objects (make-array cl_event len)
- (aset 0 (extract e0))
- (aset 1 (extract e1))
- (aset 2 (extract e2))
- (aset 3 (extract e3))
- (aset 4 (extract e4)))]
- (loop [i 5 es es]
- (if (< i len)
- (do (aset res i (extract (first es)))
- (recur (inc i) (next es)))
- res)))))
-
-(defn register
- "Creates a convenience function that registers callbacks for events.
- It is a high-level alternative to [[set-event-callback*]]. MUST be called
- AFTER the event is used in the enqueue operation.
-
- * `channel` is a channel for communicating asynchronous notifications
- * `callback-type` is an optional keyword that specifies the command execution
- status that will be the default for the resulting function: `:complete`,
- `:submitted`, or `running`.
-
- Returns a function with the following arguments:
-
- * `e` - user event that is being followed
- * `callback-type` - optional command execution status; if ommited, the default
- is used
- * `data` - optional notification data
-
- When called, the created function returns `channel` with registered callback.
-
- See [[event-callback]], [[set-event-callback*]], [[event]].
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSetEventCallback.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clSetEventCallback-org.jocl.cl_event-int-org.jocl.EventCallbackFunction-java.lang.Object-
-
- Example:
-
- (def notifications (chan))
- (def follow (register notifications))
- (def e (event))
- (enq-read! comm-queue cl-object host-object e
- (follow e)
- (:event (EventCallback channel)
- callb-type (get cl-command-execution-status callback-type CL/CL_COMPLETE)]
- (fn
- ([e callback-type data]
- (set-event-callback* (extract e) callback (cl-command-execution-status callback-type) data))
- ([e data]
- (set-event-callback* (extract e) callback callb-type data))
- ([e]
- (set-event-callback* (extract e) callback callb-type e)))))
- ([channel]
- (register channel nil)))
-
-(defn set-status!
- "Sets the status of a host event to indicate whether it is complete
- or there is an error (a negative value). It can be called only once to change
- the status. If called with only the first argument, sets the status to
- `CL/CL_COMPLETE`. Returns the event.
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSetUsereventstatus.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clSetUserEventStatus-org.jocl.cl_event-int-
-
- Examples:
-
- (set-status! ev) ;; event's status will be CL_COMPLETE
- (set-status! ev -12) ;; indicates and error code -12
- "
- ([ev ^long status]
- (let [err (CL/clSetUserEventStatus (extract ev) (if (< status 0) status CL/CL_COMPLETE))]
- (with-check err ev)))
- ([ev]
- (set-status! ev CL/CL_COMPLETE)))
-
-;; ============= Program ==========================================
-
-(defn program-with-source
- "Creates a [[internal/CLProgram]] for the context and loads the source code
- specified by the text strings given in the `source` sequence.
- When called with one argument, uses [[*context*]].
-
- In case of OpenCL errors during the program creation, throws
- `Exceptioninfo`.
-
- **Needs to be released after use.**
-
- See also [[build-program!]]
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateProgramWithSource.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateProgramWithSource-org.jocl.cl_context-int-java.lang.String:A-long:A-int:A-
-
- Example:
-
- (def source (slurp \"path-to-kernels/my_kernel.cl\"))
- (program-with-source ctx [source])
- "
- ([ctx source]
- (let [err (int-array 1)
- n (count source)
- res (CL/clCreateProgramWithSource (extract ctx) n (into-array String source) nil err)]
- (with-check-arr err {:ctx (info ctx) :source source} (wrap res))))
- ([source]
- (program-with-source *context* source)))
-
-(defn build-program!
- "Builds (compiles and links) a program executable; returns the program
- changed with side effects on `program` argument.
-
- Accepts the following arguments (nil is allowed for all optional arguments):
-
- * `program`: previously loaded [[internal/CLProgram]] that contains the program
- source or binary;
- * `devices` (optional): an optional sequence of [[internal/CLDevice]] associated with
- the program (if not supplied, all devices are used);
- * `options` (optional): an optional string of compiler options
- (such as \"-Dname=value\");
- * `ch` (optional): core.async channel for notifications. If supplied,
- the build will be asynchronous;
- * `user-data` (optional): passed as part of notification data.
-
- In case of OpenCL errors during the program build, throws
- `Exceptioninfo`.
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clBuildProgram.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clBuildProgram-org.jocl.cl_program-int-org.jocl.cl_device_id:A-java.lang.String-org.jocl.BuildProgramFunction-java.lang.Object-
-
- Examples:
-
- (build-program! program) ; synchronous
- (build-program! program ch) ; asynchronous
- (build-program! program \"-cl-std=CL2.0\" ch) ; asynchronous
- (build-program! program [dev] \"-cl-std=CL2.0\" ch) ; async
- (build-program! program [dev] \"-cl-std=CL2.0\" ch :my-data) ; async
- "
- ([program devices options ch user-data]
- (let [err (CL/clBuildProgram (extract program) (count devices)
- (if devices (into-array cl_device_id (fmap extract devices)) nil)
- options
- (if ch (->BuildCallback ch) nil)
- user-data)]
- (if (= CL/CL_SUCCESS err)
- program
- (throw (error err (map (partial build-info program)
- (if devices devices (program-devices program))))))))
- ([program devices options ch]
- (build-program! program devices options ch nil))
- ([program options ch]
- (build-program! program nil options ch nil))
- ([program ch]
- (build-program! program nil nil ch nil))
- ([program]
- (build-program! program nil nil nil nil)))
-
-;; ============== Kernel =========================================
-
-(defn num-kernels
- "Returns the number of kernels in `program` (`cl_program`).
- "
- ^long [program]
- (let [res (int-array 1)
- err (CL/clCreateKernelsInProgram (extract program) 0 nil res)]
- (with-check err (aget res 0))))
-
-(defn kernel
- "Creates `cl_kernel` objects for the kernel function specified by `name`,
- or, if the name is not specified, all kernel functions in a `program`.
-
- **Needs to be released after use.**
-
- In case of OpenCL errors during the program build, throws
- `Exceptioninfo`.
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateKernel.html,
- https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateKernelsInProgram.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateKernel-org.jocl.cl_program-java.lang.String-int:A-
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateKernelsInProgram-org.jocl.cl_program-int-org.jocl.cl_kernel:A-int:A-
- Examples:
-
- (kernel program \"dumb_kernel\") ; `cl_kernel` object
- (kernel program) ; all kernels in a vector
- "
- ([program name]
- (let [err (int-array 1)
- res (CL/clCreateKernel (extract program) name err)]
- (with-check-arr err {:name name} (wrap res))))
- ([program]
- (let [nk (num-kernels program)
- res (make-array cl_kernel nk)
- err (CL/clCreateKernelsInProgram (extract program) nk res nil)]
- (with-check err (fmap wrap (vec res))))))
-
-(defn set-arg!
- "Sets the argument value for a specific positional argument of a kernel.
- Returns the changed `cl_kernel` object. `value` should implement [[Argument]]
- protocol.
-
- The arguement can be a [[Mem]] ([[CLBuffer]], [[CLImage]], Java primitive arrays),
- or a number.
- In the case of [[Mem]] objects, the memory object will be set as an argument.
- In the case the argument is a number, its long value will be used as a size
- of the local memory to be allocated on the device.
-
- In case of OpenCL errors during the program build, throws
- `Exceptioninfo`. if `value` is of the type that is not supported,
- throws `IllegalArgumentexception`.
-
- See [[kernel]], [[program]], [[Argument]], [[cl-buffer]].
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSetKernelArg.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clSetKernelArg-org.jocl.cl_kernel-int-long-org.jocl.Pointer-
-
- Examples:
-
- (set-arg! my-kernel 0 cl-buffer0)
- (set-arg! my-kernel 1 cl-buffer1)
- (set-arg! my-kernel 2 (int-array 8))
- (set-arg! my-kernel 3 42)
- "
- [kernel n value]
- (set-arg value (extract kernel) n)
- kernel)
-
-(defn set-args!
- "Sets all provided arguments of `kernel`, starting from optional index `x`,
- and returns the changed `cl_kernel` object.
- Equivalent to calling [[set-arg!]] for each provided argument.
-
- Examples:n
-
- (set-args! my-kernel cl-buffer-0)
- (set-args! my-kernel cl-buffer-0 cl-buffer-1 (int-array 8) 42)
- (set-args! my-kernel 2 cl-buffer-2 cl-buffer-3 (int-array 8) 42)
- "
- ([kernel x & values]
- (if (integer? x)
- (loop [i (long x) values values]
- (if-let [val (first values)]
- (do (set-arg! kernel i val)
- (recur (inc i) (next values)))
- kernel))
- (apply set-args! kernel 0 (cons x values)))))
-
-;; ============== Work Size ==================================
-
-(defrecord WorkSize [^long workdim ^longs global ^longs local ^longs offset])
-
-(defn work-size
- "Creates a [[WorkSize]] record, that sets global, local and offset
- parameters in enqueuing ND kernels. All arguments are sequences,
- holding as many arguments, as there are dimensions in the appropriate
- ND kernel. In OpenCL 2.0, it is usually 1, 2, or 3, depending on the device.
-
- See [[enq-kernel!]]
- Examples:
-
- (work-size [102400 25600] [1024 128] [4 8])
- (work-size [1024 256] [16 16])
- (work-size [256])
- (work-size) ; same as (work-size [1])
- "
- ([global local offset]
- (let [global-array (long-array global)
- local-array (long-array local)
- offset-array (long-array offset)
- dim (alength global-array)]
- (if (= dim (alength local-array) (alength offset-array))
- (->WorkSize dim global-array local-array offset-array)
- (throw (IllegalArgumentException. "All work-sizes must have the same work-dimension.")))))
- ([global local]
- (let [global-array (long-array global)
- local-array (long-array local)
- dim (alength global-array)]
- (if (= dim (alength local-array))
- (->WorkSize dim global-array local-array nil)
- (throw (IllegalArgumentException. "All work-sizes must have the same work-dimension.")))))
- ([global]
- (let [global-array (long-array global)]
- (->WorkSize (alength global-array) global-array nil nil)))
- ([]
- (let [global-array (doto (long-array 0) (aset 0 1))]
- (->WorkSize 1 global-array nil nil))))
-
-(defn work-size-1d
- "Creates a 1-dimensional [[WorkSize]] from the long numbers it receives.
- See also [[work-size]].
-
- Examples:
- (work-size-1d 1024)
- (work-size-1d 1024 256)
- (work-size-1d 1024 256 1)"
- ([^long global ^long local ^long offset]
- (->WorkSize 1
- (doto (long-array 1) (aset 0 global))
- (doto (long-array 1) (aset 0 local))
- (doto (long-array 1) (aset 0 offset))))
- ([^long global ^long local]
- (->WorkSize 1
- (doto (long-array 1) (aset 0 global))
- (doto (long-array 1) (aset 0 local))
- nil))
- ([^long global]
- (->WorkSize 1 (doto (long-array 1) (aset 0 global)) nil nil))
- ([]
- (->WorkSize 1 (doto (long-array 1) (aset 0 1)) nil nil)))
-
-(defn work-size-2d
- "Creates a 2-dimensional [[WorkSize]] from the long numbers it receives.
- See also [[work-size]].
-
- Examples:
- (work-size-2d 1024 2048)
- (work-size-2d 1024 2048 16 16)
- (work-size-2d 1024 2048 16 16 8 0 2)
- "
- ([global0 global1 local0 local1 offset0 offset1]
- (->WorkSize 2
- (doto (long-array 2) (aset 0 (long global0)) (aset 1 (long global1)))
- (doto (long-array 2) (aset 0 (long local0)) (aset 1 (long local1)))
- (doto (long-array 2) (aset 0 (long offset0)) (aset 1 (long offset1)))))
- ([^long global0 ^long global1 ^long local0 ^long local1]
- (->WorkSize 2
- (doto (long-array 2) (aset 0 global0) (aset 1 global1))
- (doto (long-array 2) (aset 0 local0) (aset 1 local1))
- nil))
- ([^long global0 ^long global1]
- (->WorkSize 2 (doto (long-array 2) (aset 0 global0) (aset 1 global1)) nil nil))
- ([]
- (->WorkSize 2 (doto (long-array 2) (aset 0 1) (aset 1 1)) nil nil)))
-
-(defn work-size-3d
- "Creates a 3-dimensional [[WorkSize]] from the long numbers it receives.
- See also [[work-size]].
-
- Examples:
- (work-size-3d 1024 2048 512)
- (work-size-3d 1024 2048 256 16 16)
- (work-size-3d 1024 2048 128 16 4 4 16 0 2 512)
- "
- ([global0 global1 global2 local0 local1 local2 offset0 offset1 offset2]
- (->WorkSize 3
- (doto (long-array 3) (aset 0 (long global0))
- (aset 1 (long global1)) (aset 2 (long global2)))
- (doto (long-array 3) (aset 0 (long local0))
- (aset 1 (long local1)) (aset 2 (long local2)))
- (doto (long-array 3) (aset 0 (long offset0))
- (aset 1 (long offset1)) (aset 2 (long offset2)))))
- ([global0 global1 global2 local0 local1 local2]
- (->WorkSize 3
- (doto (long-array 3) (aset 0 (long global0))
- (aset 1 (long global1)) (aset 2 (long global2)))
- (doto (long-array 3) (aset 0 (long local0))
- (aset 1 (long local1)) (aset 2 (long local2)))
- nil))
- ([^long global0 ^long global1 ^long global2]
- (->WorkSize 3
- (doto (long-array 3) (aset 0 global0)
- (aset 1 global1) (aset 2 global2))
- nil nil))
- ([]
- (->WorkSize 3 (doto (long-array 3) (aset 0 1) (aset 1 1) (aset 2 1)) nil nil)))
-
-;; ============== Command Queue ===============================
-
-(defn command-queue
- "Creates a host or device command queue on a specific device.
-
- ** If you need to support OpenCL 1.2 platforms, you MUST use the alternative
- [[command-queue-1*]] function. Otherwise, you will get an
- UnsupportedOperationException erorr. What is important is the version of the
- platform, not the devices. This function is for platforms (regardless of the
- devices) supporting OpenCL 2.0 and higher. **
-
- Arguments are:
-
- * `ctx` - the `cl_context` for the queue;
- * `device` - the `cl_device_id` for the queue;
- * `x` - if integer, the size of the (on device) queue, otherwise treated
- as property;
- * `properties` - additional optional keyword properties: `:profiling`,
- `:queue-on-device`, `:out-of-order-exec-mode`, and `queue-on-device-default`;
-
- **Needs to be released after use.**
-
- See also [[command-queue*]].
-
- If called with invalid context or device, throws `ExceptionInfo`.
- If called with any invalid property, throws NullPointerexception.
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateCommandQueueWithProperties.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateCommandQueueWithProperties-org.jocl.cl_context-org.jocl.cl_device_id-org.jocl.cl_queue_properties-int:A-
-
- Examples:
-
- (command-queue ctx)
- (command-queue ctx dev)
- (command-queue ctx dev :profiling :queue-on-device :out-of-order-execution-mode)
- (command-queue ctx dev 524288 :queue-on-device)
- "
- ([ctx device x & properties]
- (if (integer? x)
- (wrap (command-queue* (extract ctx) (extract device) x
- (mask cl-command-queue-properties properties)))
- (wrap (command-queue* (extract ctx) (extract device) 0
- (mask cl-command-queue-properties x properties)))))
- ([ctx device]
- (wrap (command-queue* (extract ctx) (extract device) 0 0)))
- ([device]
- (command-queue *context* device))
- ([]
- (command-queue *context* ((devices-in-context *context*) 0))))
-
-(defn command-queue-1
- "Creates a host or device command queue on a specific device.
-
- ** If you need to support legacy OpenCL 1.2 or earlier platforms,
- you MUST use this function instead of [command-queue], which is for
- OpenCL 2.0 and higher. What is important is the version of the platform,
- not the devices.**
-
- Arguments are:
-
- * `ctx` - the `cl_context` for the queue;
- * `device` - the `cl_device_id` for the queue;
- * `x` - if integer, the size of the (on device) queue, otherwise treated
- as property;
- * `properties` - additional optional keyword properties: `:profiling`,
- `:queue-on-device`, `:out-of-order-exec-mode`, and `queue-on-device-default`;
-
- **Needs to be released after use.**
-
- See also [[command-queue-1*]].
-
- If called with invalid context or device, throws `ExceptionInfo`.
- If called with any invalid property, throws NullPointerexception.
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateCommandQueueWithProperties.html,
- https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateCommandQueue.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateCommandQueueWithProperties-org.jocl.cl_context-org.jocl.cl_device_id-org.jocl.cl_queue_properties-int:A-
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateCommandQueue-org.jocl.cl_context-org.jocl.cl_device_id-long-int:A-
-
- Examples:
-
- (command-queue-1 ctx)
- (command-queue-1 ctx dev)
- (command-queue-1 ctx dev :profiling)
- (command-queue-1 ctx dev 524288 :queue-on-device)
- "
- ([ctx device x & properties]
- (if (integer? x)
- (wrap (command-queue-1* (extract ctx) (extract device) x
- (mask cl-command-queue-properties properties)))
- (wrap (command-queue-1* (extract ctx) (extract device) 0
- (mask cl-command-queue-properties x properties)))))
- ([ctx device]
- (wrap (command-queue-1* (extract ctx) (extract device) 0 0)))
- ([device]
- (command-queue-1 *context* device))
- ([]
- (command-queue-1 *context* ((devices-in-context *context*) 0))))
-
-(defn enq-kernel!
- "Enqueues a command to asynchronously execute a kernel on a device.
- Returns the queue.
-
- Arguments:
-
- * `queue` (optional): the `cl_command_queue` that executes the kernel.
- If omitted, [[*command-queue*]] will be used.
- * `kernel`: the `cl_kernel` that is going to be executed.
- * `work-size`: [[WorkSize]] containing the settings of execution
- (global work size, local work size, global work offset).
- * `wait-events` (optional): [[events]] array specifying the events (if any)
- that need to complete before this command can be executed.
- * `event` (optional): if specified, the `cl_event` object tied to
- the execution of this command.
-
- If an OpenCL error occurs during the call, throws `ExceptionInfo`.
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueNDRangeKernel.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueNDRangeKernel-org.jocl.cl_command_queue-org.jocl.cl_kernel-int-long:A-long:A-long:A-int-org.jocl.cl_event:A-org.jocl.cl_event-
-
- Examples:
-
- (enq-kernel! my-kernel (work-size [8]))
- (enq-kernel! my-queue my-kernel (work-size [8]))
- (enq-kernel! my-queue my-kernel (work-size [8] (events event1 event2) my-event))
- "
- ([queue kernel ^WorkSize work-size ^objects wait-events event]
- (with-check
- (CL/clEnqueueNDRangeKernel (extract queue) (extract kernel) (.workdim work-size) (.offset work-size)
- (.global work-size) (.local work-size)
- (if wait-events (alength wait-events) 0)
- wait-events (extract event))
- {:kernel (info kernel)}
- queue))
- ([queue kernel work-size event]
- (enq-kernel! queue kernel work-size nil event))
- ([queue kernel work-size]
- (enq-kernel! queue kernel work-size nil nil))
- ([kernel work-size]
- (enq-kernel! *command-queue* kernel work-size nil nil)))
-
-(defn enq-read!
- "Enqueues a command to read from a cl object to host memory.
- Returns the queue.
-
- * `queue` (optional): the `cl_command_queue` that reads the object.
- If omitted, [[*command-queue*]] will be used.
- * `cl`: the [[CLMem]] that is going to be read from.
- * `host`: [[Mem]] object on the host that the data is to be transferred to.
- Must be a direct buffer is the reading is asynchronous.
- * `blocking`: boolean indicator of synchronization.
- * `offset`: the offset in bytes in the buffer object to read from.
- * `wait-events` (optional): [[events]] array specifying the events (if any)
- that need to complete before this operation.
- * `event` (optional): if specified, the `cl_event` object tied to
- the execution of this operation.
-
- If event is specified, the operation is asynchronous, otherwise it blocks the
- current thread until the data transfer completes, unless explicitly specifiend
- with `blocking`. See also [[register]].
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueReadBuffer.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueReadBuffer-org.jocl.cl_command_queue-org.jocl.cl_mem-boolean-long-long-org.jocl.Pointer-int-org.jocl.cl_event:A-org.jocl.cl_event-
-
- Examples:
-
- (let [host-data (direct-buffer 32)
- ev (event)
- notifications (chan)
- follow (register notifications)]
- (enq-read! my-queue cl-data host-data ev) ;; asynchronous
- (follow ev)
- (PlatformInfo]], [[->DeviceInfo]], [[->CommandQueueInfo]], [[->ContextInfo]],
- [[->KernelInfo]], [[->KernelArgInfo]], [[->ProgramInfo]], [[->ProgramBuildinfo]],
- [[->EventInfo]], [[->Profilinginfo]], [[->MemObjectInfo]], etc...
-
- ###Cheat Sheet
-
- #### Low-level info functions grouped by resource type:
-
- * [`cl_platform_id`](http://www.jocl.org/doc/org/jocl/cl_platform_id.html) info:
- [[version]], [[icd-suffix-khr]], [[profile]], [[name-info]], [[vendor]],
- [[extensions]]
-
- * [`cl_device_id`] (http://www.jocl.org/doc/org/jocl/cl_device_id.html) info:
- [[address-bits]], [[available]], [[built-in-kernels]], [[compiler-available]],
- [[double-fp-config]], [[endian-little]], [[error-correction-support]],
- [[execution-capabilities]], [[global-mem-cache-size]], [[global-=mem-cache-type]],
- [[global-mem-cacheline-size]], [[global-mem-size]],
- [[global-variable-preferred-total-size]], [[image2d-max-height]],
- [[image2d-max-width]], [[image3d-max-depth]], [[image3d-max-height]],
- [[image3d-max-width]], [[image-base-address-alignment]], [[image-max-array-size]],
- [[image-max-array-size]], [[image-max-buffer-size]], [[image-pitch-alignment]],
- [[image-support]], [[linker-available]], [[local-mem-size]], [[local-mem-type]],
- [[max-clock-frequency]], [[max-compute-units]], [[max-constant-args]],
- [[max-constant-buffer-size]], [[max-global-variable-size]], [[max-mem-aloc-size]],
- [[max-on-device-events]], [[max-on-device-queues]], [[max-parameter-size]],
- [[max-pipe-args]], [[max-read-image-args]], [[max-read-write-image-args]],
- [[max-samplers]], [[max-work-group-size]], [[max-work-item-dimensions]],
- [[max-work-item-sizes]], [[max-write-image-args]], [[mem-base-addr-align]],
- [[native-vector-width-char]], [[native-vector-width-short]],
- [[native-vector-width-int]], [[native-vector-width-long]],
- [[native-vector-width-float]], [[native-vector-width-double]],
- [[native-vector-width-half]], [[opencl-c-version]], [[parent-device]],
- [[partition-affinity-domain]], [[partition-max-sub-devices]],
- [[partition-properties]], [[partition-type]],[[pipe-max-active-reservations]],
- [[pipe-max-packet-size]], [[platform]], [[preferred-global-atomic-alignment]],
- [[preferred-interop-user-sync]], [[preferred-local-atomic-alignment]],
- [[preferred-platform-atomic-alignment]], [[preferred-vector-width-char]],
- [[preferred-vector-width-short]], [[preferred-vector-width-int]],
- [[preferred-vector-width-long]], [[preferred-vector-width-float]],
- [[preferred-vector-width-double]], [[preferred-vector-width-half]],
- [[printf-buffer-size]], [[profiling-timer-resolution]], [[queue-on-device-max-size]],
- [[queue-on-device-properties]], [[queue-on-host-properties]],
- [[single-fp-config]], [[spir-versions]], [[svm-capabilities]],
- [[device-type]], [[vendor-id]], [[device-version]],
- [[driver-version]], [[extensions]], [[name-info]], [[profile]], [[vendor]],
- [[reference-count]]
-
- * [`cl_context`] (http://www.jocl.org/doc/org/jocl/cl_context.html) info:
- [[num-devices-in-context]], [[devices-in-context]], [[properties]],
- [[reference-count]]
-
- * [`cl_command_queue`] (http://www.jocl.org/doc/org/jocl/cl_command_queue.html) info:
- [[queue-context]], [[queue-device]], [[queue-size]], [[properties]],
- [[reference-count]]
-
- * [`cl_event`] (http://www.jocl.org/doc/org/jocl/cl_event.html) info:
- [[event-command-queue]], [[event-context]], [[command-type]], [[execution-status]],
- [[reference-count]]
-
- * profiling event info: **[[profiling-info]]**,
- [[queued]], [[submit]], [[start]], [[end]]
-
- * [`cl_kernel`] (http://www.jocl.org/doc/org/jocl/cl_kernel.html) info:
- [[function-name]], [[num-args]], [[kernel-context]], [[kernel-program]],
- [[attributes]], [[reference-count]]
-
- * kernel argument info: **[[arg-info]]**
- [[arg-address-qualifier]], [[arg-access-qualifier]], [[arg-type-name]],
- [[arg-type-qualifier]], [[arg-name]]
-
- * [`cl_mem`] (http://www.jocl.org/doc/org/jocl/cl_mem.html) info:
- [[mem-type]], [[flags]], [[mem-size]], [[map-count]], [[mem-context]],
- [[associated-memobject]], [[offset]], [[uses-svm-pointer]], [[reference-count]]
-
- * [`cl_program`] (http://www.jocl.org/doc/org/jocl/cl_program.html) info:
- [[program-context]], [[program-num-devices]], [[program-devices]],
- [[program-source]], [[binary-sizes]], [[binaries]], [[program-num-kernels]],
- [[kernel-names]], [[reference-count]]
-
- * program build info: **[[build-info]]**,
- [[build-status]], [[build-options]], [[build-log]], [[binary-type]],
- [[global-variable-total-size]]
-
- #### Hihg-level info and keywords (in a few cases different than low-level function names)
-
- [[->PlatformInfo]], [[->DeviceInfo]], [[->CommandQueueInfo]], [[->ContextInfo]],
- [[->KernelInfo]], [[->KernelArgInfo]], [[->ProgramInfo]], [[->ProgramBuildinfo]],
- [[->EventInfo]], [[->Profilinginfo]], [[->MemObjectInfo]],
- "
- (:require [clojure.string :as str]
- [uncomplicate.commons
- [core :refer [Info info]]
- [utils :refer [unmask unmask1 direct-buffer]]]
- [uncomplicate.fluokitten.core :refer [fmap extract]]
- [uncomplicate.clojurecl.internal
- [constants :refer :all]
- [protocols :refer [wrap]]
- [utils :refer :all]
- [impl :refer :all]])
- (:import [java.nio ByteBuffer IntBuffer LongBuffer]
- [org.jocl CL cl_platform_id cl_device_id cl_context cl_command_queue
- cl_program cl_kernel cl_sampler cl_event cl_device_partition_property
- cl_mem Sizeof Pointer]
- [uncomplicate.clojurecl.internal.impl CLDevice CLContext CLCommandQueue CLProgram
- CLKernel CLEvent CLBuffer]))
-
-(defn ^:private get-array [^ByteBuffer buf]
- (if (= Sizeof/size_t 8)
- (let [b (.asLongBuffer buf)
- res (long-array (.capacity b))]
- (.get b res)
- res)
- (let [b (.asIntBuffer buf)
- res (int-array (.capacity b))]
- (.get b res)
- res)))
-
-;; =================== Info* utility macros ===============================
-
-(defmacro ^:private info-count*
- ([method clobject info sizeof]
- `(/ (info-count* ~method ~clobject ~info) ~sizeof))
- ([method clobject info]
- `(long (let [res# (long-array 1)
- err# (~method ~clobject ~info 0 nil res#)]
- (with-check err# (aget res# 0))))))
-
-(defmacro ^:private info-string* [method clobject info]
- `(let [size# (info-count* ~method ~clobject ~info)
- res# (byte-array size#)
- err# (~method ~clobject ~info (alength res#) (Pointer/to res#) nil)]
- (with-check err# (String. res# 0 (max 0 (dec size#))))))
-
-(defn ^:private to-set [s]
- (if (str/blank? s)
- #{}
- (apply hash-set (str/split s #" "))))
-
-(defn ^:private to-native-pointer [^"[Lorg.jocl.NativePointerObject;" np]
- (Pointer/to np))
-
-(defmacro ^:private info-native* [method clobject info type size]
- `(let [bytesize# (info-count* ~method ~clobject ~info)
- res# (make-array ~type (/ bytesize# ~size))
- err# (~method ~clobject ~info bytesize# (~to-native-pointer res#) nil)]
- (with-check err# res#)))
-
-(defn ^:private pointer-to-buffer [^ByteBuffer b]
- (Pointer/toBuffer b))
-
-(defmacro ^:private info-size*
- ([method clobject info num]
- `(let [res# (direct-buffer (* Sizeof/size_t (long ~num)))
- err# (~method ~clobject ~info (* Sizeof/size_t (long ~num)) (~pointer-to-buffer res#) nil)]
- (with-check err#
- (vec (get-array res#)))))
- ([method clobject info]
- `(first (info-size* ~method ~clobject ~info 1))))
-
-(defmacro ^:private info-long*
- ([method clobject info num]
- `(let [res# (long-array ~num)
- err# (~method ~clobject ~info (* Sizeof/cl_long (long ~num)) (Pointer/to res#) nil)]
- (with-check err# res#)))
- ([method clobject info]
- `(aget (longs (info-long* ~method ~clobject ~info 1)) 0)))
-
-(defmacro ^:private info-int*
- ([method clobject info num]
- `(let [res# (int-array ~num)
- err# (~method ~clobject ~info (* Sizeof/cl_int (long ~num)) (Pointer/to res#) nil)]
- (with-check err# res#)))
- ([method clobject info]
- `(aget (ints (info-int* ~method ~clobject ~info 1)) 0)))
-
-(defmacro ^:private info-bool* [method clobject info]
- `(not= 0 (info-int* ~method ~clobject ~info)))
-
-;; =================== Protocols ==================================
-
-(defprotocol InfoExtensions
- (extensions [this]))
-
-(defprotocol InfoName
- (name-info [this]))
-
-(defprotocol InfoProfile
- (profile [this]))
-
-(defprotocol InfoVendor
- (vendor [this]))
-
-(defprotocol InfoReferenceCount
- (reference-count [this]))
-
-(defprotocol InfoProperties
- (properties [this]))
-
-;; =================== Platform ===================================
-
-(defn version [platform]
- (info-string* CL/clGetPlatformInfo platform CL/CL_PLATFORM_VERSION))
-
-(defn icd-suffix-khr [platform]
- (info-string* CL/clGetPlatformInfo platform CL/CL_PLATFORM_ICD_SUFFIX_KHR))
-
-(defrecord PlatformInfo [profile version name vendor extensions icd-suffix-khr])
-
-(extend-type cl_platform_id
- Info
- (info
- ([p info-type]
- (maybe
- (case info-type
- :profile (profile p)
- :version (version p)
- :name (name-info p)
- :vendor (vendor p)
- :extensions (extensions p)
- :icd-suffix-khr (icd-suffix-khr p)
- nil)))
- ([p]
- (->PlatformInfo (maybe (profile p))
- (maybe (version p))
- (maybe (name-info p))
- (maybe (vendor p))
- (maybe (extensions p))
- (maybe (icd-suffix-khr p)))))
- InfoExtensions
- (extensions [p]
- (to-set (info-string* CL/clGetPlatformInfo p CL/CL_PLATFORM_EXTENSIONS)))
- InfoName
- (name-info [p]
- (info-string* CL/clGetPlatformInfo p CL/CL_PLATFORM_NAME))
- InfoProfile
- (profile [p]
- (info-string* CL/clGetPlatformInfo p CL/CL_PLATFORM_PROFILE))
- InfoVendor
- (vendor [p]
- (info-string* CL/clGetPlatformInfo p CL/CL_PLATFORM_VENDOR)))
-
-;; =================== Device ==============================================
-
-(defn address-bits ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_ADDRESS_BITS))
-
-(defn available [device]
- (info-bool* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_AVAILABLE))
-
-(defn built-in-kernels [device]
- (to-set (info-string* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_BUILT_IN_KERNELS)))
-
-(defn compiler-available [device]
- (info-bool* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_COMPILER_AVAILABLE))
-
-(defn double-fp-config ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_DOUBLE_FP_CONFIG))
-
-(defn endian-little [device]
- (info-bool* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_ENDIAN_LITTLE))
-
-(defn error-correction-support [device]
- (info-bool* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_ERROR_CORRECTION_SUPPORT))
-
-(defn execution-capabilities ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_EXECUTION_CAPABILITIES))
-
-(defn global-mem-cache-size ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_GLOBAL_MEM_CACHE_SIZE))
-
-(defn global-mem-cache-type ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_GLOBAL_MEM_CACHE_TYPE))
-
-(defn global-mem-cacheline-size ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE))
-
-(defn global-mem-size ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_GLOBAL_MEM_SIZE))
-
-(defn global-variable-preferred-total-size ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE))
-
-(defn image2d-max-height ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE2D_MAX_HEIGHT))
-
-(defn image2d-max-width ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE2D_MAX_WIDTH))
-
-(defn image3d-max-depth ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE3D_MAX_DEPTH))
-
-(defn image3d-max-height ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE3D_MAX_HEIGHT))
-
-(defn image3d-max-width ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE3D_MAX_WIDTH))
-
-(defn image-base-address-alignment ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT))
-
-(defn image-max-array-size ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE_MAX_ARRAY_SIZE))
-
-(defn image-max-buffer-size ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE_MAX_BUFFER_SIZE))
-
-(defn image-pitch-alignment ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE_PITCH_ALIGNMENT))
-
-(defn image-support [device]
- (info-bool* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_IMAGE_SUPPORT))
-
-(defn linker-available [device]
- (info-bool* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_LINKER_AVAILABLE))
-
-(defn local-mem-size ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_LOCAL_MEM_SIZE))
-
-(defn local-mem-type ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_LOCAL_MEM_TYPE))
-
-(defn max-clock-frequency ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_CLOCK_FREQUENCY))
-
-(defn max-compute-units ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_COMPUTE_UNITS))
-
-(defn max-constant-args ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_CONSTANT_ARGS))
-
-(defn max-constant-buffer-size ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE))
-
-(defn max-global-variable-size ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE))
-
-(defn max-mem-aloc-size ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_MEM_ALLOC_SIZE))
-
-(defn max-on-device-events ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_ON_DEVICE_EVENTS))
-
-(defn max-on-device-queues ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_ON_DEVICE_QUEUES))
-
-(defn max-parameter-size ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_PARAMETER_SIZE))
-
-(defn max-pipe-args ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_PIPE_ARGS))
-
-(defn max-read-image-args ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_READ_IMAGE_ARGS))
-
-(defn max-read-write-image-args ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS))
-
-(defn max-samplers ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_SAMPLERS))
-
-(defn max-work-group-size ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_WORK_GROUP_SIZE))
-
-(defn max-work-item-dimensions ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS))
-
-(defn max-work-item-sizes [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_WORK_ITEM_SIZES
- (max-work-item-dimensions device)))
-
-(defn max-write-image-args ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MAX_WRITE_IMAGE_ARGS))
-
-(defn mem-base-addr-align ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_MEM_BASE_ADDR_ALIGN))
-
-(defn native-vector-width-char ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR))
-
-(defn native-vector-width-short ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT))
-
-(defn native-vector-width-int ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_NATIVE_VECTOR_WIDTH_INT))
-
-(defn native-vector-width-long ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG))
-
-(defn native-vector-width-float ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT))
-
-(defn native-vector-width-double ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE))
-
-(defn native-vector-width-half ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF))
-
-(defn opencl-c-version [device]
- (let [info (str/split (info-string* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_OPENCL_C_VERSION)
- #" ")]
- {:version (Double/parseDouble (get info 2 0))
- :vendor-specific-info (get info 3)}))
-
-(defn parent-device [device]
- (let [device (extract device)
- id (info-long* CL/clGetDeviceInfo device CL/CL_DEVICE_PARENT_DEVICE)]
- (if (= 0 id)
- nil
- (let [parent (cl_device_id.)
- err (CL/clGetDeviceInfo device CL/CL_DEVICE_PARENT_DEVICE Sizeof/cl_device_id
- (Pointer/to parent) nil)]
- (with-check err (wrap parent))))))
-
-(defn partition-affinity-domain ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device)
- CL/CL_DEVICE_PARTITION_AFFINITY_DOMAIN))
-
-(defn partition-max-sub-devices ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PARTITION_MAX_SUB_DEVICES))
-
-(defn partition-properties [device]
- (let [device (extract device)]
- (info-long* CL/clGetDeviceInfo device CL/CL_DEVICE_PARTITION_PROPERTIES
- (info-count* CL/clGetDeviceInfo device CL/CL_DEVICE_PARTITION_PROPERTIES
- Sizeof/cl_long))))
-
-;;TODO
-(defn partition-type [device]
- (let [device (extract device)]
- (info-long* CL/clGetDeviceInfo device CL/CL_DEVICE_PARTITION_TYPE
- (info-count* CL/clGetDeviceInfo device CL/CL_DEVICE_PARTITION_TYPE Sizeof/cl_long))) )
-
-(defn pipe-max-active-reservations ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS))
-
-(defn pipe-max-packet-size ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PIPE_MAX_PACKET_SIZE))
-
-(defn platform [device]
- (let [p (cl_platform_id.)
- err (CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PLATFORM Sizeof/cl_platform_id
- (Pointer/to p) nil)]
- (with-check err p)))
-
-(defn preferred-global-atomic-alignment ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT))
-
-(defn preferred-interop-user-sync [device]
- (info-bool* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_INTEROP_USER_SYNC))
-
-(defn preferred-local-atomic-alignment ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT))
-
-(defn preferred-platform-atomic-alignment ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT))
-
-(defn preferred-vector-width-char ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR))
-
-(defn preferred-vector-width-short ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT))
-
-(defn preferred-vector-width-int ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT))
-
-(defn preferred-vector-width-long ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG))
-
-(defn preferred-vector-width-float ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT))
-
-(defn preferred-vector-width-double ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE))
-
-(defn preferred-vector-width-half ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF))
-
-(defn printf-buffer-size ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PRINTF_BUFFER_SIZE))
-
-(defn profiling-timer-resolution ^long [device]
- (info-size* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_PROFILING_TIMER_RESOLUTION))
-
-(defn queue-on-device-max-size ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE))
-
-(defn queue-on-device-preferred-size ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE))
-
-(defn queue-on-device-properties ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES))
-
-(defn queue-on-host-properties ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_QUEUE_ON_HOST_PROPERTIES))
-
-(defn single-fp-config ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_SINGLE_FP_CONFIG))
-
-(defn spir-versions [device]
- (apply hash-set
- (map #(if (clojure.string/blank? %) 0 (Double/parseDouble %))
- (str/split (info-string* CL/clGetDeviceInfo (extract device) CL_DEVICE_SPIR_VERSIONS)
- #" "))))
-
-(defn svm-capabilities ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_SVM_CAPABILITIES))
-
-(defn device-type ^long [device]
- (info-long* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_TYPE))
-
-(defn vendor-id ^long [device]
- (info-int* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_VENDOR_ID))
-
-(defn device-version [device]
- (info-string* CL/clGetDeviceInfo (extract device) CL/CL_DEVICE_VERSION))
-
-(defn driver-version [device]
- (info-string* CL/clGetDeviceInfo (extract device) CL/CL_DRIVER_VERSION))
-
-(defrecord DeviceInfo [address-bits
- available
- built-in-kernels
- compiler-available
- double-fp-config
- endian-little
- error-correction-support
- execution-capabilities
- extensions
- global-mem-cache-size
- global-mem-cache-type
- global-mem-cacheline-size
- global-mem-size
- global-variable-preferred-total-size
- image2d-max-height
- image2d-max-width
- image3d-max-depth
- image3d-max-height
- image3d-max-width
- image-base-address-alignment
- image-max-array-size
- image-max-buffer-size
- image-pitch-alignment
- image-support
- linker-available
- local-mem-size
- local-mem-type
- max-clock-frequency
- max-compute-units
- max-constant-args
- max-constant-buffer-size
- max-global-variable-size
- max-mem-aloc-size
- max-on-device-events
- max-on-device-queues
- max-parameter-size
- max-pipe-args
- max-read-image-args
- max-read-write-image-args
- max-samplers
- max-work-group-size
- max-work-item-dimensions
- max-work-item-sizes
- max-write-image-args
- mem-base-addr-align
- name
- native-vector-width-char
- native-vector-width-short
- native-vector-width-int
- native-vector-width-long
- native-vector-width-double
- native-vector-width-float
- native-vector-width-half
- opencl-c-version
- parent-device
- partition-affinity-domain
- partition-max-sub-devices
- partition-properties
- partition-type
- pipe-max-active-reservations
- pipe-max-packet-size
- platform
- preferred-global-atomic-alignment
- preferred-interop-user-sync
- preferred-local-atomic-alignment
- preferred-platform-atomic-alignment
- preferred-vector-width-char
- preferred-vector-width-short
- preferred-vector-width-int
- preferred-vector-width-long
- preferred-vector-width-double
- preferred-vector-width-float
- preferred-vector-width-half
- printf-buffer-size
- profile
- profiling-timer-resolution
- queue-on-device-max-size
- queue-on-device-preferred-size
- queue-on-device-properties
- queue-on-host-properties
- reference-count
- single-fp-config
- spir-versions
- svm-capabilities
- device-type
- vendor
- vendor-id
- device-version
- driver-version])
-
-(extend-type CLDevice
- Info
- (info
- ([d info-type]
- (maybe
- (case info-type
- :address-bits (address-bits d)
- :available (available d)
- :built-in-kernels (built-in-kernels d)
- :compiler-available (compiler-available d)
- :double-fp-config (set (unmask cl-device-fp-config (double-fp-config d)))
- :endian-little (endian-little d)
- :error-correction-support (error-correction-support d)
- :execution-capabilities (set (unmask cl-device-exec-capabilities (execution-capabilities d)))
- :extensions (extensions d)
- :global-mem-cache-size (global-mem-cache-size d)
- :global-mem-cache-type (unmask1 cl-device-mem-cache-type (global-mem-cache-type d))
- :global-mem-cacheline-size (global-mem-cacheline-size d)
- :global-mem-size (global-mem-size d)
- :global-variable-preferred-total-size (global-variable-preferred-total-size d)
- :image2d-max-height (image2d-max-height d)
- :image2d-max-width (image2d-max-width d)
- :image3d-max-depth (image3d-max-depth d)
- :image3d-max-height (image3d-max-height d)
- :image3d-max-width (image3d-max-width d)
- :image-base-address-alignment (image-base-address-alignment d)
- :image-max-array-size (image-max-array-size d)
- :image-max-buffer-size (image-max-buffer-size d)
- :image-pitch-alignment (image-pitch-alignment d)
- :image-support (image-support d)
- :linker-available (linker-available d)
- :local-mem-size (local-mem-size d)
- :local-mem-type (unmask1 cl-local-mem-type (local-mem-type d))
- :max-clock-frequency (max-clock-frequency d)
- :max-compute-units (max-compute-units d)
- :max-constant-args (max-constant-args d)
- :max-constant-buffer-size (max-constant-buffer-size d)
- :max-global-variable-size (max-global-variable-size d)
- :max-mem-alloc-size (max-mem-aloc-size d)
- :max-on-device-events (max-on-device-events d)
- :max-parameter-queues (max-on-device-queues d)
- :max-parameter-size (max-parameter-size d)
- :max-pipe-args (max-pipe-args d)
- :max-read-image-args (max-read-image-args d)
- :max-read-write-image-args (max-read-write-image-args d)
- :max-samplers (max-samplers d)
- :max-work-group-size (max-work-group-size d)
- :max-work-item-dimensions (max-work-item-dimensions d)
- :max-work-item-sizes (max-work-item-sizes d)
- :max-write-image-args (max-write-image-args d)
- :mem-base-addr-align (mem-base-addr-align d)
- :name (name-info d)
- :native-vector-width-char (native-vector-width-char d)
- :native-vector-width-short (native-vector-width-short d)
- :native-vector-width-int (native-vector-width-int d)
- :native-vector-width-long (native-vector-width-long d)
- :native-vector-width-double (native-vector-width-double d)
- :native-vector-width-float (native-vector-width-float d)
- :native-vector-width-half (native-vector-width-half d)
- :opencl-c-version (opencl-c-version d)
- :parent-device (if-let [pd (parent-device d)] (name-info pd) nil)
- :partition-affinity-domain (set (unmask cl-device-affinity-domain (partition-affinity-domain d)))
- :partition-max-sub-devices (partition-max-sub-devices d)
- :partition-properties (map dec-device-partition-property (partition-properties d))
- :partition-type (map dec-device-partition-property (partition-type d))
- :pipe-max-active-reservations (pipe-max-active-reservations d)
- :pipe-max-packet-size (pipe-max-packet-size d)
- :platform (platform d)
- :preferred-global-atomic-alignment (preferred-global-atomic-alignment d)
- :preferred-interop-user-sync (preferred-interop-user-sync d)
- :preferred-local-atomic-alignment (preferred-local-atomic-alignment d)
- :preferred-platform-atomic-alignment (preferred-platform-atomic-alignment d)
- :preferred-vector-width-char (preferred-vector-width-char d)
- :preferred-vector-width-short (preferred-vector-width-short d)
- :preferred-vector-width-int (preferred-vector-width-int d)
- :preferred-vector-width-long (preferred-vector-width-long d)
- :preferred-vector-width-double (preferred-vector-width-double d)
- :preferred-vector-width-float (preferred-vector-width-float d)
- :preferred-vector-width-half (preferred-vector-width-half d)
- :printf-buffer-size (printf-buffer-size d)
- :profile (profile d)
- :profiling-timer-resolution (profiling-timer-resolution d)
- :queue-on-device-max-size (queue-on-device-max-size d)
- :queue-on-device-preferred-size (queue-on-device-preferred-size d)
- :queue-on-device-properties (set (unmask cl-command-queue-properties (queue-on-device-properties d)))
- :queue-on-host-properties (set (unmask cl-command-queue-properties (queue-on-host-properties d)))
- :reference-count (reference-count d)
- :single-fp-config (set (unmask cl-device-fp-config (single-fp-config d)))
- :spir-versions (spir-versions d)
- :svm-capabilities (set (unmask cl-device-svm-capabilities (svm-capabilities d)))
- :device-type (unmask1 cl-device-type (device-type d))
- :vendor (vendor d)
- :vendor-id (vendor-id d)
- :device-version (device-version d)
- :driver-version (driver-version d)
- nil)))
- ([d]
- (->DeviceInfo
- (maybe (address-bits d))
- (maybe (available d))
- (maybe (built-in-kernels d))
- (maybe (compiler-available d))
- (maybe (set (unmask cl-device-fp-config (double-fp-config d))))
- (maybe (endian-little d))
- (maybe (error-correction-support d))
- (maybe (set (unmask cl-device-exec-capabilities (execution-capabilities d))))
- (maybe (extensions d))
- (maybe (global-mem-cache-size d))
- (maybe (unmask1 cl-device-mem-cache-type (global-mem-cache-type d)))
- (maybe (global-mem-cacheline-size d))
- (maybe (global-mem-size d))
- (maybe (global-variable-preferred-total-size d))
- (maybe (image2d-max-height d))
- (maybe (image2d-max-width d))
- (maybe (image3d-max-depth d))
- (maybe (image3d-max-height d))
- (maybe (image3d-max-width d))
- (maybe (image-base-address-alignment d))
- (maybe (image-max-array-size d))
- (maybe (image-max-buffer-size d))
- (maybe (image-pitch-alignment d))
- (maybe (image-support d))
- (maybe (linker-available d))
- (maybe (local-mem-size d))
- (maybe (unmask1 cl-local-mem-type (local-mem-type d)))
- (maybe (max-clock-frequency d))
- (maybe (max-compute-units d))
- (maybe (max-constant-args d))
- (maybe (max-constant-buffer-size d))
- (maybe (max-global-variable-size d))
- (maybe (max-mem-aloc-size d))
- (maybe (max-on-device-events d))
- (maybe (max-on-device-queues d))
- (maybe (max-parameter-size d))
- (maybe (max-pipe-args d))
- (maybe (max-read-image-args d))
- (maybe (max-read-write-image-args d))
- (maybe (max-samplers d))
- (maybe (max-work-group-size d))
- (maybe (max-work-item-dimensions d))
- (maybe (max-work-item-sizes d))
- (maybe (max-write-image-args d))
- (maybe (mem-base-addr-align d))
- (maybe (name-info d))
- (maybe (native-vector-width-char d))
- (maybe (native-vector-width-short d))
- (maybe (native-vector-width-int d))
- (maybe (native-vector-width-long d))
- (maybe (native-vector-width-double d))
- (maybe (native-vector-width-float d))
- (maybe (native-vector-width-half d))
- (maybe (opencl-c-version d))
- (maybe (if-let [pd (parent-device d)] (name-info pd) nil))
- (maybe (set (unmask cl-device-affinity-domain (partition-affinity-domain d))))
- (maybe (partition-max-sub-devices d))
- (maybe (map dec-device-partition-property (partition-properties d)))
- (maybe (map dec-device-partition-property (partition-type d)))
- (maybe (pipe-max-active-reservations d))
- (maybe (pipe-max-packet-size d))
- (maybe (platform d))
- (maybe (preferred-global-atomic-alignment d))
- (maybe (preferred-interop-user-sync d))
- (maybe (preferred-local-atomic-alignment d))
- (maybe (preferred-platform-atomic-alignment d))
- (maybe (preferred-vector-width-char d))
- (maybe (preferred-vector-width-short d))
- (maybe (preferred-vector-width-int d))
- (maybe (preferred-vector-width-long d))
- (maybe (preferred-vector-width-double d))
- (maybe (preferred-vector-width-float d))
- (maybe (preferred-vector-width-half d))
- (maybe (printf-buffer-size d))
- (maybe (profile d))
- (maybe (profiling-timer-resolution d))
- (maybe (queue-on-device-max-size d))
- (maybe (queue-on-device-preferred-size d))
- (maybe (set (unmask cl-command-queue-properties (queue-on-device-properties d))))
- (maybe (set (unmask cl-command-queue-properties (queue-on-host-properties d))))
- (maybe (reference-count d))
- (maybe (set (unmask cl-device-fp-config (single-fp-config d))))
- (maybe (spir-versions d))
- (maybe (set (unmask cl-device-svm-capabilities (svm-capabilities d))))
- (maybe (unmask1 cl-device-type (device-type d)))
- (maybe (vendor d))
- (maybe (vendor-id d))
- (maybe (device-version d))
- (maybe (driver-version d)))))
- InfoExtensions
- (extensions [d]
- (to-set (info-string* CL/clGetDeviceInfo (extract d) CL/CL_DEVICE_EXTENSIONS)))
- InfoName
- (name-info [d]
- (info-string* CL/clGetDeviceInfo (extract d) CL/CL_DEVICE_NAME))
- InfoProfile
- (profile [d]
- (info-string* CL/clGetDeviceInfo (extract d) CL/CL_DEVICE_PROFILE))
- InfoVendor
- (vendor [d]
- (info-string* CL/clGetDeviceInfo (extract d) CL/CL_DEVICE_VENDOR))
- InfoReferenceCount
- (reference-count [d]
- (info-int* CL/clGetDeviceInfo (extract d) CL/CL_DEVICE_REFERENCE_COUNT)))
-
-;; =================== Context =============================================
-
-(defn num-devices-in-context ^long [context]
- (info-int* CL/clGetContextInfo (extract context) CL/CL_CONTEXT_NUM_DEVICES))
-
-(defn devices-in-context [context]
- (fmap wrap (vec (info-native* CL/clGetContextInfo (extract context) CL/CL_CONTEXT_DEVICES
- cl_device_id Sizeof/cl_device_id))))
-
-(defrecord ContextInfo [num-devices reference-count devices properties])
-
-(extend-type CLContext
- Info
- (info
- ([c info-type]
- (maybe
- (case info-type
- :num-devices (num-devices-in-context c)
- :reference-count (reference-count c)
- :devices (fmap name-info (devices-in-context c))
- :properties (map dec-context-properties (remove zero? (properties c)))
- nil)))
- ([c]
- (->ContextInfo (maybe (num-devices-in-context c))
- (maybe (reference-count c))
- (maybe (fmap name-info (devices-in-context c)))
- (maybe (map dec-context-properties (remove zero? (properties c)))))))
- InfoProperties
- (properties [c]
- (info-long* CL/clGetContextInfo (extract c) CL/CL_CONTEXT_PROPERTIES
- (info-count* CL/clGetContextInfo (extract c) CL/CL_CONTEXT_PROPERTIES Sizeof/cl_long)))
- InfoReferenceCount
- (reference-count [c]
- (info-int* CL/clGetContextInfo (extract c) CL/CL_CONTEXT_REFERENCE_COUNT)))
-
-;; =================== Command Queue =======================================
-
-(defn queue-context [queue]
- (let [c (cl_context.)
- err (CL/clGetCommandQueueInfo (extract queue) CL/CL_QUEUE_CONTEXT Sizeof/cl_context
- (Pointer/to c) nil)]
- (with-check err (wrap c))))
-
-(defn queue-device [queue]
- (let [d (cl_device_id.)
- err (CL/clGetCommandQueueInfo (extract queue) CL/CL_QUEUE_DEVICE Sizeof/cl_device_id
- (Pointer/to d) nil)]
- (with-check err (wrap d))))
-
-(defn queue-size ^long [queue]
- (info-int* CL/clGetCommandQueueInfo (extract queue) CL/CL_QUEUE_SIZE))
-
-(defrecord CommandQueueInfo [context device reference-count properties size])
-
-(extend-type CLCommandQueue
- Info
- (info
- ([cq info-type]
- (maybe
- (case info-type
- :context (str (queue-context cq))
- :device (name-info (queue-device cq))
- :reference-count (reference-count cq)
- :properties (set (unmask cl-command-queue-properties (properties cq)))
- :size (queue-size cq)
- nil)))
- ([cq]
- (->CommandQueueInfo (maybe (str (queue-context cq)))
- (maybe (name-info (queue-device cq)))
- (maybe (reference-count cq))
- (maybe (set (unmask cl-command-queue-properties (properties cq))))
- (maybe (queue-size cq)))))
- InfoReferenceCount
- (reference-count [cq]
- (info-int* CL/clGetCommandQueueInfo (extract cq) CL/CL_QUEUE_REFERENCE_COUNT))
- InfoProperties
- (properties [cq]
- (info-long* CL/clGetCommandQueueInfo (extract cq) CL/CL_QUEUE_PROPERTIES)))
-
-;; =================== Event ===============================================
-
-(defn event-command-queue [event]
- (let [cq (cl_command_queue.)
- err (CL/clGetEventInfo (extract event) CL/CL_EVENT_COMMAND_QUEUE Sizeof/cl_command_queue
- (Pointer/to cq) nil)]
- (with-check err (wrap cq))))
-
-(defn event-context [event]
- (let [c (cl_context.)
- err (CL/clGetEventInfo (extract event) CL/CL_EVENT_CONTEXT Sizeof/cl_context (Pointer/to c) nil)]
- (with-check err (wrap c))))
-
-(defn command-type [event]
- (info-int* CL/clGetEventInfo (extract event) CL/CL_EVENT_COMMAND_TYPE))
-
-(defn execution-status [event]
- (info-int* CL/clGetEventInfo (extract event) CL/CL_EVENT_COMMAND_EXECUTION_STATUS))
-
-(defrecord EventInfo [command-queue context command-type execution-status reference-count])
-
-(extend-type CLEvent
- Info
- (info
- ([e info-type]
- (maybe
- (case info-type
- :command-queue (str (event-command-queue e))
- :context (str (event-context e))
- :command-type (dec-command-type (command-type e))
- :execution-status (dec-command-execution-status (execution-status e))
- :reference-count (reference-count e)
- nil)))
- ([e]
- (->EventInfo (maybe (str (event-command-queue e)))
- (maybe (str (event-context e)))
- (maybe (dec-command-type (command-type e)))
- (maybe (dec-command-execution-status (execution-status e)))
- (maybe (reference-count e)))))
- InfoReferenceCount
- (reference-count [e]
- (info-int* CL/clGetEventInfo (extract e) CL/CL_EVENT_REFERENCE_COUNT)))
-
-;; =================== Event Profiling =====================================
-
-(defn queued ^long [event]
- (info-long* CL/clGetEventProfilingInfo (extract event) CL/CL_PROFILING_COMMAND_QUEUED))
-
-(defn submit ^long [event]
- (info-long* CL/clGetEventProfilingInfo (extract event) CL/CL_PROFILING_COMMAND_SUBMIT))
-
-(defn start ^long [event]
- (info-long* CL/clGetEventProfilingInfo (extract event) CL/CL_PROFILING_COMMAND_START))
-
-(defn end ^long [event]
- (info-long* CL/clGetEventProfilingInfo (extract event) CL/CL_PROFILING_COMMAND_END))
-
-(defrecord ProfilingInfo [^long queued ^long submit ^long start ^long end])
-
-(defn profiling-info
- (^long [event info]
- (case info
- :queued (queued event)
- :submit (submit event)
- :start (start event)
- :end (end event)
- nil))
-
- ([event]
- (->ProfilingInfo (queued event) (submit event) (start event) (end event))))
-
-(defn durations [^ProfilingInfo pi]
- (->ProfilingInfo 0
- (- (.submit pi) (.queued pi))
- (- (.start pi) (.submit pi))
- (- (.end pi) (.start pi))))
-
-;; ===================== Image ================================================
-
-;; TODO
-
-;; ===================== Kernel ===============================================
-
-(defn function-name [kernel]
- (info-string* CL/clGetKernelInfo (extract kernel) CL/CL_KERNEL_FUNCTION_NAME))
-
-(defn num-args ^long [kernel]
- (info-int* CL/clGetKernelInfo (extract kernel) CL/CL_KERNEL_NUM_ARGS))
-
-(defn kernel-context [kernel]
- (let [c (cl_context.)
- err (CL/clGetKernelInfo (extract kernel) CL/CL_KERNEL_CONTEXT Sizeof/cl_context (Pointer/to c) nil)]
- (with-check err (wrap c))))
-
-(defn kernel-program [kernel]
- (let [p (cl_program.)
- err (CL/clGetKernelInfo (extract kernel) CL/CL_KERNEL_PROGRAM Sizeof/cl_program (Pointer/to p) nil)]
- (with-check err (wrap p))))
-
-(defn attributes [kernel]
- (to-set (info-string* CL/clGetKernelInfo (extract kernel) CL/CL_KERNEL_ATTRIBUTES)))
-
-(defrecord KernelInfo [function-name num-args reference-count context program attributes])
-
-(extend-type CLKernel
- Info
- (info
- ([k info-type]
- (maybe
- (case info-type
- :function-name (function-name k)
- :num-args (num-args k)
- :reference-count (reference-count k)
- :context (str (kernel-context k))
- :program (str (kernel-program k))
- :attributes (attributes k)
- nil)))
- ([k]
- (->KernelInfo (maybe (function-name k))
- (maybe (num-args k))
- (maybe (reference-count k))
- (maybe (str (kernel-context k)))
- (maybe (str (kernel-program k)))
- (maybe (attributes k)))))
- InfoReferenceCount
- (reference-count [k]
- (info-int* CL/clGetKernelInfo (extract k) CL/CL_KERNEL_REFERENCE_COUNT)))
-
-;; ===================== Kernel Arg ===========================================
-
-;; -- Kernel Arg Info has special utility functions with one more parameter. --
-
-(defmacro ^:private arg-info-string* [kernel arg info]
- `(let [cnt# (long-array 1)
- kernel# (extract ~kernel)
- err# (CL/clGetKernelArgInfo kernel# ~arg ~info 0 nil cnt#)]
- (with-check err#
- (let [res# (byte-array (aget cnt# 0))
- err# (CL/clGetKernelArgInfo kernel# ~arg ~info (alength res#) (Pointer/to res#) nil)]
- (with-check err#
- (String. res# 0 (max 0 (dec (alength res#)))))))))
-
-(defmacro ^:private arg-info-long* [kernel arg info]
- `(let [res# (long-array 1)
- err# (CL/clGetKernelArgInfo (extract ~kernel) ~arg ~info Sizeof/cl_long (Pointer/to res#) nil)]
- (with-check err# (aget res# 0))))
-
-;; ----------- Kernel Arg Info functions -------------------------------------
-
-(defn arg-address-qualifier ^long [kernel arg]
- (arg-info-long* kernel arg CL/CL_KERNEL_ARG_ADDRESS_QUALIFIER))
-
-(defn arg-access-qualifier ^long [kernel arg]
- (arg-info-long* kernel arg CL/CL_KERNEL_ARG_ACCESS_QUALIFIER))
-
-(defn arg-type-name ^long [kernel arg]
- (arg-info-string* kernel arg CL/CL_KERNEL_ARG_TYPE_NAME))
-
-(defn arg-type-qualifier ^long [kernel arg]
- (arg-info-long* kernel arg CL/CL_KERNEL_ARG_TYPE_QUALIFIER))
-
-(defn arg-name [kernel arg]
- (arg-info-string* kernel arg CL/CL_KERNEL_ARG_NAME))
-
-(defrecord KernelArgInfo [address-qualifier access-qualifier type-name type-qualifier name])
-
-(defn arg-info
- ([kernel arg info-type]
- (maybe
- (case info-type
- :address-qualifier (dec-kernel-arg-address-qualifier (arg-address-qualifier kernel arg))
- :access-qualifier (dec-kernel-arg-access-qualifier (arg-access-qualifier kernel arg))
- :type-name (arg-type-name kernel arg)
- :type-qualifier (set (unmask cl-kernel-arg-type-qualifier (arg-type-qualifier kernel arg)))
- :name (arg-name kernel arg)
- nil)))
- ([kernel arg]
- (->KernelArgInfo (maybe (dec-kernel-arg-address-qualifier (arg-address-qualifier kernel arg)))
- (maybe (dec-kernel-arg-access-qualifier (arg-access-qualifier kernel arg)))
- (maybe (arg-type-name kernel arg))
- (maybe (set (unmask cl-kernel-arg-type-qualifier (arg-type-qualifier kernel arg))))
- (maybe (arg-name kernel arg))))
- ([kernel]
- (map (partial arg-info kernel) (range (num-args kernel)) )))
-
-;; ===================== Kernel Sub Group =====================================
-
-;; TODO
-
-;; ===================== Kernel Work Group ====================================
-
-;; TODO
-
-;; ===================== Mem Object ===========================================
-
-(defn mem-type ^long [mo]
- (info-int* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_TYPE))
-
-(defn flags ^long [mo]
- (info-long* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_FLAGS))
-
-(defn mem-size ^long [mo]
- (info-size* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_SIZE))
-
-;;TODO see what to do with these voids, and whether they make sense with Java.
-;;(defn mem-host-ptr [mo]
-;; (info-long* CL/clGetMemObjectInfo mo CL/CL_MEM_HOST_PTR))
-
-(defn map-count ^long [mo]
- (info-int* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_MAP_COUNT))
-
-(defn ^:private aget-first-np [^objects npa]
- (aget npa 0))
-
-(defn mem-context [mo]
- (wrap (aget-first-np (info-native* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_CONTEXT
- cl_context Sizeof/cl_context))))
-
-(defn associated-memobject [mo]
- (aget-first-np (info-native* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_ASSOCIATED_MEMOBJECT
- cl_mem Sizeof/cl_mem)))
-
-(defn offset ^long [mo]
- (info-size* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_OFFSET))
-
-(defn uses-svm-pointer [mo]
- (info-bool* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_USES_SVM_POINTER))
-
-(defrecord MemObjectInfo [type flags size map-count reference-count context associated-memobject
- offset uses-svm-pointer])
-
-(extend-type CLBuffer
- Info
- (info
- ([mo info-type]
- (maybe
- (case info-type
- :type (dec-mem-object-type (mem-type mo))
- :flags (set (unmask cl-mem-flags (flags mo)))
- :size (mem-size mo)
- :map-count (map-count mo)
- :reference-count (reference-count mo)
- :context (str (mem-context mo))
- :associated-memobject (if-let [mo (associated-memobject mo)] (str mo) nil)
- :offset (offset mo)
- :uses-svm-pointer (uses-svm-pointer mo)
- nil)))
- ([mo]
- (->MemObjectInfo (maybe (dec-mem-object-type (mem-type mo)))
- (maybe (set (unmask cl-mem-flags (flags mo))))
- (maybe (mem-size mo))
- (maybe (map-count mo))
- (maybe (reference-count mo))
- (maybe (str (mem-context mo)))
- (maybe (if-let [mo (associated-memobject mo)] (str mo) nil))
- (maybe (offset mo))
- (maybe (uses-svm-pointer mo)))))
- InfoReferenceCount
- (reference-count [mo]
- (info-int* CL/clGetMemObjectInfo (extract mo) CL/CL_MEM_REFERENCE_COUNT)))
-
-;; ===================== Pipe =================================================
-
-;; TODO
-
-;; ===================== Program Build ========================================
-
-;; -- Program Build Info has special utility functions with one more param ----
-
-(defmacro ^:private pb-info-string* [program device info]
- `(let [cnt# (long-array 1)
- program# (extract ~program)
- err# (CL/clGetProgramBuildInfo program# (extract ~device) ~info 0 nil cnt#)]
- (with-check err#
- (let [res# (byte-array (aget cnt# 0))
- err# (CL/clGetProgramBuildInfo program# (extract ~device) ~info
- (alength res#) (Pointer/to res#) nil)]
- (with-check err#
- (String. res# 0 (max 0 (dec (alength res#)))))))))
-
-(defmacro ^:private pb-info-int* [program device info]
- `(let [res# (int-array 1)
- err# (CL/clGetProgramBuildInfo (extract ~program) (extract ~device)
- ~info Sizeof/cl_int (Pointer/to res#) nil)]
- (with-check err# (aget res# 0))))
-
-(let [pointer-to-buffer (fn [^ByteBuffer b] (Pointer/to b))]
- (defmacro ^:private pb-info-size* [program device info]
- `(let [res# (direct-buffer Sizeof/size_t)
- err# (CL/clGetProgramBuildInfo (extract ~program) (extract ~device) ~info Sizeof/size_t
- (~pointer-to-buffer res#) nil)]
- (with-check err#
- (first (seq (get-array res#)))))))
-
-;; -- Program Build Info functions --------------------------------------------
-
-(defn build-status ^long [program device]
- (pb-info-int* program device CL/CL_PROGRAM_BUILD_STATUS))
-
-(defn build-options [program device]
- (pb-info-string* program device CL/CL_PROGRAM_BUILD_OPTIONS))
-
-(defn build-log [program device]
- (pb-info-string* program device CL/CL_PROGRAM_BUILD_LOG))
-
-(defn binary-type ^long [program device]
- (pb-info-int* program device CL/CL_PROGRAM_BINARY_TYPE))
-
-(defn global-variable-total-size ^long [program device]
- (pb-info-size* program device CL/CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE))
-
-(defrecord ProgramBuildInfo [build-status build-options build-log binary-type global-variable-total-size])
-
-(defn build-info
- ([program device info-type]
- (maybe
- (case info-type
- :status (dec-build-status (build-status program device))
- :options (build-options program device)
- :log (build-log program device)
- :binary-type (dec-program-binary-type (binary-type program device))
- :global-variable-total-size (global-variable-total-size program device))))
- ([program device]
- (->ProgramBuildInfo (maybe (dec-build-status (build-status program device)))
- (maybe (build-options program device))
- (maybe (build-log program device))
- (maybe (dec-program-binary-type (binary-type program device)))
- (maybe (global-variable-total-size program device)))))
-
-;; ===================== Program ==============================================
-
-(defn program-context [p]
- (wrap (aget-first-np (info-native* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_CONTEXT
- cl_context Sizeof/cl_context))))
-
-(defn program-num-devices ^long [p]
- (info-int* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_NUM_DEVICES))
-
-(defn program-devices [p]
- (fmap wrap (vec (info-native* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_DEVICES
- cl_device_id Sizeof/cl_device_id))))
-
-(defn program-source [p]
- (info-string* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_SOURCE))
-
-(defn binary-sizes [p]
- (info-size* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_BINARY_SIZES (program-num-devices p)))
-
-(defn binaries [p]
- (let [result-buffers (map direct-buffer (binary-sizes p))
- pointer (to-native-pointer (into-array Pointer (map pointer-to-buffer result-buffers)))
- err (CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_BINARIES
- (* (count result-buffers) Sizeof/POINTER) pointer nil)]
- (with-check err result-buffers)))
-
-(defn program-num-kernels ^long [p]
- (if (some pos? (binary-sizes p))
- (info-size* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_NUM_KERNELS)
- 0))
-
-(defn kernel-names [p]
- (if (some pos? (binary-sizes p))
- (to-set (info-string* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_KERNEL_NAMES))
- #{}))
-
-(defrecord ProgramInfo [reference-count context num-devices devices source
- binary-sizes binaries num-kernels kernel-names])
-
-(extend-type CLProgram
- Info
- (info
- ([p info-type]
- (maybe
- (case info-type
- :reference-count (reference-count p)
- :context (str (program-context p))
- :num-devices (program-num-devices p)
- :devices (fmap name-info (program-devices p))
- :source (program-source p)
- :binary-sizes (binary-sizes p)
- :binaries (program-num-devices p)
- :num-kernels (program-num-kernels p)
- :kernel-names (kernel-names p)
- nil)))
- ([p]
- (->ProgramInfo (maybe (reference-count p))
- (maybe (str (program-context p)))
- (maybe (program-num-devices p))
- (maybe (fmap name-info (program-devices p)))
- (maybe (program-source p))
- (maybe (binary-sizes p))
- (maybe (program-num-devices p))
- (maybe (program-num-kernels p))
- (maybe (kernel-names p)))))
- InfoReferenceCount
- (reference-count [p]
- (info-int* CL/clGetProgramInfo (extract p) CL/CL_PROGRAM_REFERENCE_COUNT)))
-
-;; ===================== Sampler ==============================================
-
-;; TODO
-
-;; ===================== GL Context ===========================================
-
-;; TODO
-;; ===================== GL Object ============================================
-
-;; TODO
-
-;; ===================== GL Texture ===========================================
-
-;; TODO
-
-;; ============================================================================
diff --git a/src/clojure/uncomplicate/clojurecl/internal/constants.clj b/src/clojure/uncomplicate/clojurecl/internal/constants.clj
deleted file mode 100644
index 4cf3aac..0000000
--- a/src/clojure/uncomplicate/clojurecl/internal/constants.clj
+++ /dev/null
@@ -1,385 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns ^{:author "Dragan Djuric"}
- uncomplicate.clojurecl.internal.constants
- "Defines constants and mappings from/to OpenCL constants.
-
- OpenCL API defines and uses numerous int/long C-style constants as arguments
-in functions calls, mostly for configuring various options. Clojure uses keywords
-as an user friendly alternative. ClojureCL's `core` namespace contains primitive
-functions suffixed with `*`, which still accept the low level constants
-defined in `org.jocl.CL` Java class, but the preferred, easier, and natural way
-is to use keywords. Another benefit of that method is that you can easily view
-available options by printing an appropriate hash-map from this namespace.
-
- Most mappings are two-way. Hashmaps that convert keywords to number codes
- are named `cl-something-clish`, while functions that convert numbers to keywords
- are named `dec-something-clish`. You can see which keywords are available for
- a certain property by evaluate appropriate `cl-something-clish` hashmap.
- All hashmaps and functions contain brief doc and a web link to appropriate
- online OpenCL documentation with detailed explanations
-
- Also see the summary at
- http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/enums.html"
- (:import org.jocl.CL))
-
-;; ===== OpenCL defines this, but JOCL 0.2.0 still misses it.
-(def ^{:no-doc true :const true}
- CL_DEVICE_SPIR_VERSIONS 0x40E0)
-
-(def ^{:no-doc true :const true}
- CL_TERMINATE_CAPABILITY_KHR 0x200F)
-
-;; ============= Error Codes ===================================================
-
-(defn dec-error
- "Decodes OpenCL error code to a meaningful string.
- If called with a number that is not recognized as an existing OpenCL error,
- returns `\"UNKNOWN OpenCL ERROR!\"`
-
- Also see the discussion at
- http://streamcomputing.eu/blog/2013-04-28/opencl-1-2-error-codes/"
- [^long code]
- (case code
- 0 "CL_SUCCESS"
- -1 "CL_DEVICE_NOT_FOUND"
- -2 "CL_DEVICE_NOT_AVAILABLE"
- -3 "CL_COMPILER_NOT_AVAILABLE"
- -4 "CL_MEM_OBJECT_ALLOCATION_FAILURE"
- -5 "CL_OUT_OF_RESOURCES"
- -6 "CL_OUT_OF_HOST_MEMORY"
- -7 "CL_PROFILING_INFO_NOT_AVAILABLE"
- -8 "CL_MEM_COPY_OVERLAP"
- -9 "CL_IMAGE_FORMAT_MISMATCH"
- -10 "CL_IMAGE_FORMAT_NOT_SUPPORTED"
- -11 "CL_BUILD_PROGRAM_FAILURE"
- -12 "CL_MAP_FAILURE"
- -13 "CL_MISALIGNED_SUB_BUFFER_OFFSET"
- -14 "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST"
- -15 "CL_COMPILE_PROGRAM_FAILURE"
- -16 "CL_LINKER_NOT_AVAILABLE"
- -17 "CL_LINK_PROGRAM_FAILURE"
- -18 "CL_DEVICE_PARTITION_FAILED"
- -19 "CL_KERNEL_ARG_INFO_NOT_AVAILABLE"
- -30 "CL_INVALID_VALUE"
- -31 "CL_INVALID_DEVICE_TYPE"
- -32 "CL_INVALID_PLATFORM"
- -33 "CL_INVALID_DEVICE"
- -34 "CL_INVALID_CONTEXT"
- -35 "CL_INVALID_QUEUE_PROPERTIES"
- -36 "CL_INVALID_COMMAND_QUEUE"
- -37 "CL_INVALID_HOST_PTR"
- -38 "CL_INVALID_MEM_OBJECT"
- -39 "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"
- -40 "CL_INVALID_IMAGE_SIZE"
- -41 "CL_INVALID_SAMPLER"
- -42 "CL_INVALID_BINARY"
- -43 "CL_INVALID_BUILD_OPTIONS"
- -44 "CL_INVALID_PROGRAM"
- -45 "CL_INVALID_PROGRAM_EXECUTABLE"
- -46 "CL_INVALID_KERNEL_NAME"
- -47 "CL_INVALID_KERNEL_DEFINITION"
- -48 "CL_INVALID_KERNEL"
- -49 "CL_INVALID_ARG_INDEX"
- -50 "CL_INVALID_ARG_VALUE"
- -51 "CL_INVALID_ARG_SIZE"
- -52 "CL_INVALID_KERNEL_ARGS"
- -53 "CL_INVALID_WORK_DIMENSION"
- -54 "CL_INVALID_WORK_GROUP_SIZE"
- -55 "CL_INVALID_WORK_ITEM_SIZE"
- -56 "CL_INVALID_GLOBAL_OFFSET"
- -57 "CL_INVALID_EVENT_WAIT_LIST"
- -58 "CL_INVALID_EVENT"
- -59 "CL_INVALID_OPERATION"
- -60 "CL_INVALID_GL_OBJECT"
- -61 "CL_INVALID_BUFFER_SIZE"
- -62 "CL_INVALID_MIP_LEVEL"
- -63 "CL_INVALID_GLOBAL_WORK_SIZE"
- -64 "CL_INVALID_PROPERTY"
- -65 "CL_INVALID_IMAGE_DESCRIPTOR"
- -66 "CL_INVALID_COMPILER_OPTIONS"
- -67 "CL_INVALID_LINKER_OPTIONS"
- -68 "CL_INVALID_DEVICE_PARTITION_COUNT"
- -69 "CL_INVALID_PIPE_SIZE"
- -70 "CL_INVALID_DEVICE_QUEUE"
- -16384 "CL_JOCL_INTERNAL_ERROR"
- -1000 "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR"
- -1001 "CL_PLATFORM_NOT_FOUND_KHR"
- "UNKNOWN OpenCL ERROR!"))
-
-;; ==================== Keyword mapping ======================================
-
-(def ^{:doc "Types of OpenCL devices defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceIDs.html"
- :const true}
- cl-device-type
- {:gpu CL/CL_DEVICE_TYPE_GPU
- :cpu CL/CL_DEVICE_TYPE_CPU
- :default CL/CL_DEVICE_TYPE_DEFAULT
- :accelerator CL/CL_DEVICE_TYPE_ACCELERATOR
- :custom CL/CL_DEVICE_TYPE_CUSTOM
- :all CL/CL_DEVICE_TYPE_ALL})
-
-(def ^{:doc "Floating point capabilities of the device defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- :const true}
- cl-device-fp-config
- {:denorm CL/CL_FP_DENORM
- :inf-nan CL/CL_FP_INF_NAN
- :round-to-nearest CL/CL_FP_ROUND_TO_NEAREST
- :round-to-zero CL/CL_FP_ROUND_TO_ZERO
- :round-to-inf CL/CL_FP_ROUND_TO_INF
- :fma CL/CL_FP_FMA
- :correctly-rounded-divide-sqrt CL/CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT
- :soft-float CL/CL_FP_SOFT_FLOAT})
-
-(def
- ^{:doc "Types of global memory cache defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"}
- cl-device-mem-cache-type
- {:none CL/CL_NONE
- :read-only CL/CL_READ_ONLY_CACHE
- :read-write CL/CL_READ_WRITE_CACHE})
-
-(def ^{:doc "Types of local memory defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- :const true}
- cl-local-mem-type
- {:local CL/CL_LOCAL
- :global CL/CL_GLOBAL
- :none CL/CL_NONE})
-
-(def ^{:doc "The execution capabilities of the device defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- :const true}
- cl-device-exec-capabilities
- {:kernel CL/CL_EXEC_KERNEL
- :native-kernel CL/CL_EXEC_NATIVE_KERNEL})
-
-(def ^{:doc "On device command-queue properties defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- :const true}
- cl-command-queue-properties
- {:out-of-order-exec-mode CL/CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
- :profiling CL/CL_QUEUE_PROFILING_ENABLE
- :queue-on-device CL/CL_QUEUE_ON_DEVICE
- :queue-on-device-default CL/CL_QUEUE_ON_DEVICE_DEFAULT})
-
-(def ^{:doc "Context properties defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- :const true}
- cl-context-properties
- {:platform CL/CL_CONTEXT_PLATFORM
- :interop-user-sync CL/CL_CONTEXT_INTEROP_USER_SYNC
- :gl-context-khr CL/CL_GL_CONTEXT_KHR
- :cgl-sharegroup-khr CL/CL_CGL_SHAREGROUP_KHR
- :egl-display-khr CL/CL_EGL_DISPLAY_KHR
- :glx-display-khr CL/CL_GLX_DISPLAY_KHR
- :wgl-hdc-khr CL/CL_WGL_HDC_KHR})
-
-(defn dec-context-properties
- "Converts `cl_context_properties` code from number to keyword.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- [^long code]
- (case code
- 0x1004 :platform
- 0x1005 :interop-user-sync
- code))
-
-(defn dec-device-partition-property
- "Converts `cl_device_partition_property` code from number to keyword.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- [^long code]
- (case code
- 0x1086 :equally
- 0x1087 :by-counts
- 0x0 :by-counts-list-end
- 0x1088 :by-affinity-domain
- code))
-
-(def ^{:doc "Affinity domains for partitioning the device defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- :const true}
- cl-device-affinity-domain
- {:numa CL/CL_DEVICE_AFFINITY_DOMAIN_NUMA
- :l1-cache CL/CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE
- :l2-cache CL/CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE
- :l3-cache CL/CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE
- :l4-cache CL/CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE
- :next-partitionable CL/CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE})
-
-(def ^{:doc "Context properties defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceInfo.html"
- :const true}
- cl-device-svm-capabilities
- {:coarse-grain-buffer CL/CL_DEVICE_SVM_COARSE_GRAIN_BUFFER
- :fine-grain-buffer CL/CL_DEVICE_SVM_FINE_GRAIN_BUFFER
- :fine-grain-system CL/CL_DEVICE_SVM_FINE_GRAIN_SYSTEM
- :atomics CL/CL_DEVICE_SVM_ATOMICS})
-
-(def ^{:doc "Memory allocation and usage information defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateBuffer.html"
- :const true}
- cl-mem-flags
- {:read-write CL/CL_MEM_READ_WRITE
- :write-only CL/CL_MEM_WRITE_ONLY
- :read-only CL/CL_MEM_READ_ONLY
- :use-host-ptr CL/CL_MEM_USE_HOST_PTR
- :alloc-host-ptr CL/CL_MEM_ALLOC_HOST_PTR
- :copy-host-ptr CL/CL_MEM_COPY_HOST_PTR
- :host-write-only CL/CL_MEM_HOST_WRITE_ONLY
- :host-read-only CL/CL_MEM_HOST_READ_ONLY
- :host-no-access CL/CL_MEM_HOST_NO_ACCESS})
-
-(def ^{:doc "Memory allocation and usage information defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSVMAlloc.html"
- :const true}
- cl-svm-mem-flags
- {:read-write CL/CL_MEM_READ_WRITE
- :write-only CL/CL_MEM_WRITE_ONLY
- :read-only CL/CL_MEM_READ_ONLY
- :fine-grain-buffer CL/CL_MEM_SVM_FINE_GRAIN_BUFFER
- :atomics CL/CL_MEM_SVM_ATOMICS})
-
-(defn dec-mem-object-type
- "Converts `cl_mem_object_type` code from number to keyword.
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetMemObjectInfo.html"
- [^long code]
- (case code
- 0x10F0 :buffer
- 0x10F1 :image2d
- 0x10F2 :image3d
- 0x10F3 :image2d-array
- 0x10F4 :image1d
- 0x10F5 :image1d-array
- 0x10F6 :image1d-buffer
- 0x10F7 :pipe
- code))
-
-(def ^{:doc "Map flags used in enqueuing buffer mapping defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueMapBuffer.html"
- :const true}
- cl-map-flags
- {:read CL/CL_MAP_READ
- :write CL/CL_MAP_WRITE
- :write-invalidate-region CL/CL_MAP_WRITE_INVALIDATE_REGION})
-
-(defn dec-program-binary-type
- "Converts `cl_program_binary_type` code from number to keyword.
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetProgramBuildInfo.html"
- [^long code]
- (case code
- 0x0 :none
- 0x1 :compiled-object
- 0x2 :library
- 0x4 :executable
- 0x40E1 :intermediate
- code))
-
-(defn dec-build-status
- "Converts `cl_program_build_status` code from number to keyword.
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetProgramBuildInfo.html"
- [^long code]
- (case code
- 0 :success
- -1 :none
- -2 :error
- -3 :in-progress
- code))
-
-(defn
- dec-kernel-arg-address-qualifier
- "Converts `cl_kernel_arg_address_qualifier` code from number to keyword.
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetKernelArgInfo.html"
- [^long code]
- (case code
- 0x119B :global
- 0x119C :local
- 0x119D :constant
- 0x119E :private
- code))
-
-(defn dec-kernel-arg-access-qualifier
- "Converts `cl_kernel_arg_access_qualifier` code from number to keyword.
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetKernelArgInfo.html"
- [^long code]
- (case code
- 0x11A0 :read-only
- 0x11A1 :write-only
- 0x11A2 :read-write
- 0x11A3 :none
- code))
-
-(def ^{:doc "Type quilifiers specified for the argument, defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetKernelArgInfo.html"
- :const true}
- cl-kernel-arg-type-qualifier
- {:const CL/CL_KERNEL_ARG_TYPE_CONST
- :restrict CL/CL_KERNEL_ARG_TYPE_RESTRICT
- :volatile CL/CL_KERNEL_ARG_TYPE_VOLATILE
- :pipe CL/CL_KERNEL_ARG_TYPE_PIPE
- :none CL/CL_KERNEL_ARG_TYPE_NONE})
-
-(defn dec-command-type
- "Converts `cl_event_command_type` code from number to keyword.
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetEventInfo.html"
- [^long code]
- (case code
- 0x11F0 :ndrange-kernel
- 0x11F1 :task
- 0x11F2 :native-kernel
- 0x11F3 :read-buffer
- 0x11F4 :write-buffer
- 0x11F5 :copy-buffer
- 0x11F6 :read-image
- 0x11F7 :write-image
- 0x11F8 :copy-image
- 0x11F9 :copy-image-to-buffer
- 0x11FA :copy-buffer-to-image
- 0x11FB :map-buffer
- 0x11FC :map-image
- 0x11FD :unmap-mem-object
- 0x11FE :marker
- 0x11FF :acquire-gl-objects
- 0x1200 :release-gl-objects
- 0x1201 :read-buffer-rect
- 0x1202 :write-buffer-rect
- 0x1203 :copy-buffer-rect
- 0x1204 :user
- 0x1205 :barrier
- 0x1206 :migrate-mem-objects
- 0x1207 :fill-buffer
- 0x1208 :fill-image
- 0x1209 :svm-free
- 0x120A :svm-memcpy
- 0x120B :svm-memfill
- 0x120C :svm-map
- 0x120D :svm-unmap
- 0x200D :gl-fence-sync-object-khr
- code))
-
-(defn dec-command-execution-status
- "Converts `cl_event_command_execution_status` code from number to keyword.
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetEventInfo.html"
- [^long code]
- (case code
- 0x0 :complete
- 0x1 :running
- 0x2 :submitted
- 0x3 :queued
- code))
-
-(def
- ^{:doc "Execution statuses of commands, defined in OpenCL standard.
-See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetEventInfo.html"}
- cl-command-execution-status
- {:complete CL/CL_COMPLETE
- :running CL/CL_RUNNING
- :submitted CL/CL_SUBMITTED
- :queued CL/CL_QUEUED})
diff --git a/src/clojure/uncomplicate/clojurecl/internal/impl.clj b/src/clojure/uncomplicate/clojurecl/internal/impl.clj
deleted file mode 100644
index 454f823..0000000
--- a/src/clojure/uncomplicate/clojurecl/internal/impl.clj
+++ /dev/null
@@ -1,627 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns ^{:author "Dragan Djuric"}
- uncomplicate.clojurecl.internal.impl
- (:require [uncomplicate.commons
- [core :refer [Releaseable release Info info]]
- [utils :refer [dragan-says-ex]]]
- [uncomplicate.fluokitten.protocols :refer [Comonad extract]]
- [uncomplicate.clojurecl.internal
- [protocols :refer :all]
- [constants :refer :all]
- [utils :refer [with-check with-check-arr]]]
- [clojure.core.async :refer [go >!]])
- (:import [java.nio ByteBuffer ByteOrder]
- clojure.lang.IDeref
- [org.jocl CL NativePointerObject cl_device_id cl_mem
- cl_context cl_command_queue cl_mem cl_program cl_kernel cl_sampler
- cl_event cl_buffer_region cl_queue_properties cl_platform_id
- Sizeof Pointer CreateContextFunction EventCallbackFunction
- BuildProgramFunction JOCLAccessor]))
-
-;; =============== Release CL Resources ==================================
-
-(defn native-pointer ^long [npo]
- (if npo (JOCLAccessor/getNativePointer npo) 0))
-
-(extend-type NativePointerObject
- Releaseable
- (release [this]
- (dragan-says-ex "It is not allowed to use and release raw JOCL objects. Use safe wrappers."
- {:this this})))
-
-(defmacro ^:private deftype-wrapper [name release-method]
- (let [name-str (str name)]
- `(deftype ~name [ref#]
- Object
- (hashCode [this#]
- (hash (deref ref#)))
- (equals [this# other#]
- (= (deref ref#) (extract other#)))
- (toString [this#]
- (format "#%s[0x%s]" ~name-str (Long/toHexString (native-pointer (deref ref#)))))
- Comonad
- (extract [this#]
- (deref ref#))
- Releaseable
- (release [this#]
- (locking ref#
- (when-let [d# (deref ref#)]
- (locking d#
- (with-check (~release-method d#) (vreset! ref# nil)))))
- true))))
-
-(deftype-wrapper CLDevice CL/clReleaseDevice)
-(deftype-wrapper CLContext CL/clReleaseContext)
-(deftype-wrapper CLCommandQueue CL/clReleaseCommandQueue)
-(deftype-wrapper CLEvent CL/clReleaseEvent)
-(deftype-wrapper CLKernel CL/clReleaseKernel)
-(deftype-wrapper CLProgram CL/clReleaseProgram)
-(deftype-wrapper CLSampler CL/clReleaseSampler)
-
-(extend-type cl_platform_id
- Releaseable
- (release [_]
- true)
- Wrappable
- (wrap [this]
- this)
- Comonad
- (extract [this]
- this))
-
-(extend-type cl_command_queue
- Info
- (info [this]
- (info (wrap this)))
- Wrappable
- (wrap [queue]
- (->CLCommandQueue (volatile! queue))))
-
-(extend-type cl_context
- Info
- (info [this]
- (info (wrap this)))
- Wrappable
- (wrap [ctx]
- (->CLContext (volatile! ctx))))
-
-(extend-type cl_device_id
- Info
- (info [this]
- (info (wrap this)))
- Wrappable
- (wrap [dev]
- (->CLDevice (volatile! dev))))
-
-(extend-type cl_event
- Info
- (info [this]
- (info (wrap this)))
- Wrappable
- (wrap [event]
- (->CLEvent (volatile! event))))
-
-(extend-type cl_kernel
- Info
- (info [this]
- (info (wrap this)))
- Wrappable
- (wrap [kernel]
- (->CLKernel (volatile! kernel))))
-
-(extend-type cl_program
- Info
- (info [this]
- (info (wrap this)))
- Wrappable
- (wrap [program]
- (->CLProgram (volatile! program))))
-
-(extend-type cl_sampler
- Info
- (info [this]
- (info (wrap this)))
- Wrappable
- (wrap [sampler]
- (->CLSampler (volatile! sampler))))
-
-;; =============== Device ==========================================
-
-(defn num-devices*
- "Queries `platform` for the number of devices of `device-type`s. Device types
- are given as a bitfield, where each type is defined in the OpenCL standard.
- Available device types are accessible through `org.jocl.CL/CL_DEVICE_TYPE_X`
- constants. If there are no such devices, returns 0.
-
- NOTE: You should prefer a higher-level [[num-devices]] function, unless you
- already have a `device-type` in a long number form in your code.
-
- When called with an invalid platform, throws [ExceptionInfo]
- (http://clojuredocs.org/clojure.core/ex-info).
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceIDs.html
- and http://www.jocl.org/doc/org/jocl/CL.html#clGetDeviceIDs-int-org.jocl.cl_device_id:A-int:A-
- "
- ^long [platform ^long device-type]
- (let [res (int-array 1)
- err (CL/clGetDeviceIDs platform device-type 0 nil res)]
- (if (= CL/CL_DEVICE_NOT_FOUND err)
- 0
- (with-check err
- {:platform (info platform) :device-type device-type}
- (aget res 0)))))
-
-(defn devices*
- "Queries `platform` for the devices of `device-type`s, and returns them as an
- array of `cl_device_id`s. The types are given as a bitfield, where each type
- is a number constant defined in the OpenCL standard.
- Available device types are accessible through `org.jocl.CL/CL_DEVICE_TYPE_X`
- constants. If there are no such devices, returns a zero-length array.
-
- Root level devices do not need to be explicitly released.
-
- NOTE: You should prefer a higher-level [[devices]] function, unless you
- already have a `device-type` in a long number form in your code, and/or you
- want to get resulting devices in an array rather than in a vector.
-
- When called with an invalid platform, throws [ExceptionInfo]
- (http://clojuredocs.org/clojure.core/ex-info).
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clGetDeviceIDs.html
- and http://www.jocl.org/doc/org/jocl/CL.html#clGetDeviceIDs-int-org.jocl.cl_device_id:A-int:A-
- "
- [platform ^long device-type]
- (let [num-devices (num-devices* platform device-type)
- res (make-array cl_device_id num-devices)]
- (if (< 0 num-devices)
- (let [err (CL/clGetDeviceIDs platform device-type num-devices res nil)]
- (with-check err
- {:platform (info platform) :device-type device-type}
- res))
- res)))
-
-;; ========================= Context ===========================================
-
-(defrecord CreateContextInfo [errinfo private-info data])
-
-(deftype CreateContextCallback [ch]
- CreateContextFunction
- (function [this errinfo private-info cb data]
- (go (>! ch (->CreateContextInfo errinfo private-info data)))))
-
-(defn context*
- "Creates `CLContext` for an array of `device`s, with optional
- `cl_context_properties`, error reporting core.async channel `ch`
- and user data that should accompany the error report.
-
- If `devices` is empty, throws `ExceptionInfo`.
-
- **Needs to be released after use.**
-
- This is a low-level alternative to [[context]].
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateContext.html
- See throws `Illegalargumentexception`http://www.jocl.org/doc/org/jocl/CL.html#clCreateContext-org.jocl.cl_context_properties-int-org.jocl.cl_device_id:A-org.jocl.CreateContextFunction-java.lang.Object-int:A-
- "
- [^objects devices properties ch user-data]
- (let [err (int-array 1)
- res (CL/clCreateContext properties
- (alength devices) devices
- (if ch (->CreateContextCallback ch) nil)
- user-data err)]
- (with-check-arr err
- {:devices (map info devices)}
- res)))
-
-;; =========================== Memory =========================================
-
-(deftype CLBuffer [cl ^Pointer cl* ^long s]
- Object
- (hashCode [this]
- (hash @cl))
- (equals [this other]
- (= @cl (extract other)))
- (toString [this]
- (format "#CLBuffer[0x%s]" (Long/toHexString (native-pointer @cl))))
- Comonad
- (extract [_]
- @cl)
- Releaseable
- (release [this]
- (locking cl
- (when-let [c @cl]
- (locking c
- (with-check (CL/clReleaseMemObject c)
- (do
- (vreset! cl nil)
- (vreset! cl* nil))))))
- true)
- Mem
- (ptr [_]
- @cl*)
- (size [_]
- s)
- CLMem
- (enq-copy* [this queue dst src-offset dst-offset size wait-events ev]
- (with-check
- (CL/clEnqueueCopyBuffer queue @cl (extract dst) src-offset dst-offset size
- (if wait-events (alength ^objects wait-events) 0)
- wait-events ev)
- queue))
- (enq-fill* [this queue pattern offset multiplier wait-events ev]
- (with-check
- (CL/clEnqueueFillBuffer queue @cl (ptr pattern) (size pattern)
- offset (* ^long (size pattern) ^long multiplier)
- (if wait-events (alength ^objects wait-events) 0)
- wait-events ev)
- queue))
- Argument
- (set-arg [this kernel n]
- (with-check (CL/clSetKernelArg kernel n Sizeof/cl_mem @cl*)
- {:kernel (info kernel) :n n :arg (info this)}
- kernel)))
-
-(deftype SVMBuffer [ctx svm* ^long s]
- Object
- (hashCode [this]
- (hash @svm*))
- (equals [this other]
- (= @svm* (extract other)))
- (toString [this]
- (str @svm*))
- Comonad
- (extract [_]
- @svm*)
- Releaseable
- (release [this]
- (locking svm*
- (when-let [ss @svm*]
- (locking ss
- (CL/clSVMFree ctx ss)
- (vreset! svm* nil))))
- true)
- Mem
- (ptr [_]
- @svm*)
- (size [_]
- s)
- SVMMem
- (byte-buffer [this]
- (byte-buffer this 0 s))
- (byte-buffer [_ offset size]
- (.order (.getByteBuffer ^Pointer @svm* offset size) (ByteOrder/nativeOrder)))
- Argument
- (set-arg [this kernel n]
- (with-check (CL/clSetKernelArgSVMPointer kernel n @svm*)
- {:kernel (info kernel) :n n :arg (info this)}
- kernel)))
-
-(defn cl-buffer*
- "Creates a cl buffer object in `ctx`, given `size` in bytes and a bitfield
- `flags` describing memory allocation usage.
-
- Flags defined by the OpenCL standard are available as constants in the
- [org.jocl.CL](http://www.jocl.org/doc/org/jocl/CL.html) class.
-
- **Needs to be released after use.**
-
- This is a low-level alternative to [[cl-buffer]]
- If `ctx` is nil or the buffer size is invalid, throws `ExceptionInfo`.
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateBuffer.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateBuffer-org.jocl.cl_context-long-long-org.jocl.Pointer-int:A-
-
- Example:
-
- (cl-buffer* ctx 24 CL/CL_MEM_READ_ONLY)
- "
- ([^cl_context ctx ^long size ^long flags]
- (let [err (int-array 1)
- res (CL/clCreateBuffer ctx flags size nil err)]
- (with-check-arr err
- {:ctx (info ctx) :size size}
- (->CLBuffer (volatile! res) (volatile! (Pointer/to ^cl_mem res)) size)))))
-
-(defn cl-sub-buffer*
- "Creates a cl buffer object ([[CLBuffer]]) that shares data with an existing
- buffer object.
-
- * `buffer` has to be a valid `cl_mem` buffer object.
- * `flags` is a bitfield that specifies allocation usage (see [[cl-buffer*]]).
- * `create-type` is a type of buffer object to be created (in OpenCL 2.0, only
- `CL/CL_BUFFER_CREATE_TYPE_REGION` is supported).
- * `region` is a `cl_buffer_region` that specifies offset and size
- of the subbuffer.
-
- **Needs to be released after use.**
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateBuffer.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateBuffer-org.jocl.cl_context-long-long-org.jocl.Pointer-int:A-
-
- Examples:
-
- (def cl-buff (cl-buffer ctx 32 :write-only))
- (def region (cl_buffer_region. 8 16))
- (cl-sub-buffer* cl-buff CL/CL_MEM_READ_WRITE CL/CL_BUFFER_CREATE_TYPE_REGION region)
- (cl-sub-buffer* cl-buff CL/CL_MEM_READ_ONLY region)
- "
- ([^cl_mem buffer ^long flags ^long create-type ^cl_buffer_region region]
- (let [err (int-array 1)
- res (CL/clCreateSubBuffer buffer flags (int create-type) region err)]
- (with-check-arr err (->CLBuffer (volatile! res) (volatile! (Pointer/to ^cl_mem res))
- (.size region)))))
- ([^cl_mem buffer ^long flags region]
- (cl-sub-buffer* buffer flags CL/CL_BUFFER_CREATE_TYPE_REGION region)))
-
-(defn svm-buffer*
- "Creates a svm buffer object in `ctx`, given `size` in bytes, bitfield
- `flags` describing memory allocation usage, and alignment size.
-
- Flags defined by the OpenCL standard are available as constants in the
- [org.jocl.CL](http://www.jocl.org/doc/org/jocl/CL.html) class.
-
- **Needs to be released after use.**
-
- This is a low-level alternative to [[svm-buffer!]]
- If `ctx` is nil or the buffer size is invalid, throws `IllegalArgumentException`.
-
- See http://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSVMAlloc.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clSVMAlloc-org.jocl.cl_context-long-long-int-
-
- Example:
-
- (svm-buffer* ctx 24 (bit-or CL/CL_MEM_SVM_FINE_GRAIN_BUFFER CL/CL_MEM_SVM_ATOMICS) 0)
- "
- [^cl_context ctx ^long size ^long flags ^long alignment]
- (if (and ctx (< 0 size))
- (let [err (int-array 1)
- res (CL/clSVMAlloc ctx flags size alignment)]
- (with-check-arr err (->SVMBuffer ctx (volatile! res) size)))
- (dragan-says-ex "To create a svm buffer, you must provide a context and a positive size.")))
-
-(defmacro ^:private extend-number [type]
- `(extend-type ~type
- Argument
- (set-arg [this# kernel# n#]
- (with-check (CL/clSetKernelArg kernel# n# this# nil)
- {:kernel (info kernel#) :n n# :arg (info this#)}
- kernel#))))
-
-(extend-number Double)
-(extend-number Float)
-(extend-number Long)
-(extend-number Integer)
-(extend-number Byte)
-(extend-number Short)
-(extend-number Character)
-
-(defmacro ^:private extend-mem-array [type atype bytes]
- `(extend-type ~type
- Mem
- (ptr [this#]
- (Pointer/to (~atype this#)))
- (size [this#]
- (* ~bytes (alength (~atype this#))))
- Argument
- (set-arg [this# kernel# n#]
- (with-check
- (CL/clSetKernelArg kernel# n# (* ~bytes (alength (~atype this#))) (Pointer/to (~atype this#)))
- {:kernel (info kernel#) :n n# :arg (info this#)}
- kernel#))))
-
-(extend-mem-array (Class/forName "[F") floats Float/BYTES)
-(extend-mem-array (Class/forName "[D") doubles Double/BYTES)
-(extend-mem-array (Class/forName "[I") ints Integer/BYTES)
-(extend-mem-array (Class/forName "[J") longs Long/BYTES)
-(extend-mem-array (Class/forName "[B") bytes Byte/BYTES)
-(extend-mem-array (Class/forName "[S") shorts Short/BYTES)
-(extend-mem-array (Class/forName "[C") chars Character/BYTES)
-
-(extend-type ByteBuffer
- Mem
- (ptr [this]
- (Pointer/toBuffer this))
- (size [this]
- (.capacity ^ByteBuffer this)))
-
-;; ============== Events ==========================================
-
-(defrecord EventCallbackInfo [status data])
-
-(deftype EventCallback [ch]
- EventCallbackFunction
- (function [this ev status data]
- (go (>! ch (->EventCallbackInfo (dec-command-execution-status status) data)))))
-
-(defn set-event-callback*
- "Registers a callback function for an event and a specific command
- execution status. Returns the channel. MUST be called AFTER the event is
- used in the enqueue operation.
-
- If called without `callback-type` and `data`, registers [`CL/CL_COMPLETE`]
- (http://www.jocl.org/doc/org/jocl/CL.html#CL_COMPLETE) status.
-
- See [[event-callback]], [[register]], [[event]].
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clSetEventCallback.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clSetEventCallback-org.jocl.cl_event-int-org.jocl.EventCallbackFunction-java.lang.Object-
-
- Example:
-
- (set-event-callback* (user-event) (event-callback) CL/CL_COMPLETE :my-data)
- (set-event-callback* (user-event) (event-callback))
- "
- ([^cl_event e ^EventCallback callback ^long callback-type data]
- (with-check (CL/clSetEventCallback e callback-type callback data) (.ch callback)))
- ([^cl_event e ^EventCallback callback]
- (set-event-callback* e callback CL/CL_COMPLETE nil)))
-
-;; ============= Program ==========================================
-
-(deftype BuildCallback [ch]
- BuildProgramFunction
- (function [this program data]
- (go (>! ch (if data data :no-user-data)))))
-
-;; ============== Command Queue ===============================
-
-(defn command-queue*
- "Creates a host or device command queue on a specific device.
-
- ** If you need to support OpenCL 1.2 platforms, you MUST use the alternative
- [[command-queue-1*]] function. Otherwise, you will get an
- UnsupportedOperationException erorr. What is important is the version of the
- platform, not the devices. This function is for platforms (regardless of the
- devices) supporting OpenCL 2.0 and higher. **
-
- Arguments are:
-
- * `ctx` - the `cl_context` for the queue;
- * `device` - the `cl_device_id` for the queue;
- * `size` - the size of the (on device) queue;
- * `properties` - long bitmask containing properties, defined by the OpenCL
- standard are available as constants in the org.jocl.CL class.
-
- This is a low-level version of [[command-queue]].
-
- If called with invalid context or device, throws `ExceptionInfo`.
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clCreateCommandQueueWithProperties.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateCommandQueueWithProperties-org.jocl.cl_context-org.jocl.cl_device_id-org.jocl.cl_queue_properties-int:A-
-
- Examples:
- (command-queue* ctx dev 524288 (bit-or CL/CL_QUEUE_PROFILING_ENABLED
- CL/CL_QUEUE_ON_DEVICE))
- (command-queue* ctx dev CL/CL_QUEUE_PROFILING_ENABLED)
- "
- ([^cl_context ctx ^cl_device_id device ^long properties]
- (command-queue* ctx device 0 properties))
- ([^cl_context ctx ^cl_device_id device ^long size ^long properties]
- (let [err (int-array 1)
- props (let [clqp (cl_queue_properties.)]
- (when (< 0 properties) (.addProperty clqp CL/CL_QUEUE_PROPERTIES properties))
- (when (< 0 size) (.addProperty clqp CL/CL_QUEUE_SIZE size))
- clqp)
- res (CL/clCreateCommandQueueWithProperties ctx device props err)]
- (with-check-arr err {:device (info device)} res))))
-
-(defn command-queue-1*
- "Creates a host or device command queue on a specific device.
-
- ** If you need to support legacy OpenCL 1.2 or earlier platforms,
- you MUST use this function instead of [command-queue*], which is for
- OpenCL 2.0 and higher. What is important is the version of the platform,
- not the devices.**
-
- Arguments are:
-
- * `ctx` - the `cl_context` for the queue;
- * `device` - the `cl_device_id` for the queue;
- * `size` - the size of the (on device) queue;
- * `properties` - long bitmask containing properties, defined by the OpenCL
- standard are available as constants in the org.jocl.CL class.
-
- This is a low-level version of [[command-queue-1]].
-
- If called with invalid context or device, throws `ExceptionInfo`.
-
- See https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateCommandQueue.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clCreateCommandQueue-org.jocl.cl_context-org.jocl.cl_device_id-long-int:A-
-
- Examples:
- (command-queue-1* ctx dev 524288 (bit-or CL/CL_QUEUE_PROFILING_ENABLED
- CL/CL_QUEUE_ON_DEVICE))
- (command-queue-1* ctx dev CL/CL_QUEUE_PROFILING_ENABLED)
- "
- ([ctx device ^long properties]
- (command-queue-1* ctx device 0 properties))
- ([ctx device ^long size ^long properties]
- (let [err (int-array 1)
- res (CL/clCreateCommandQueue ctx device properties err)]
- (with-check-arr err res))))
-
-(defn enq-map-buffer*
- "Enqueues a command to map a region of the cl buffer into the host
- address space. Returns the mapped `java.nio.ByteBuffer`. The result
- must be unmapped by calling [[enq-unmap!]] for the effects of working
- with the mapping byte buffer to be transfered back to the device memory.
-
- Arguments:
-
- * `queue` (optional): the `cl_command_queue` that maps the object.
- If omitted, [[*command-queue*]] will be used.
- * `cl`: the [[CLMem]] that is going to be mapped to.
- * `blocking`: whether the operation is blocking (CL/CL_TRUE) or non-blocking
- (CL/CL_FALSE).
- * `offset`: integer value of the memory offset in bytes.
- * `req-size`: integer value of the requested size in bytes (if larger than
- the available data, it will be shrinked.).
- * `flags`: a bitfield that indicates whether the memory is mapped for reading
- (`CL/CL_MAP_READ`), writing (`CL/CL_MAP_WRITE`) or both
- `(bit-or CL/CL_MAP_READ CL/CL_MAP_WRITE)`.
- * `wait-events` (optional): [[events]] array specifying the events (if any)
- that need to complete before this operation.
- * `event` (optional): if specified, the `cl_event` object tied to
- the execution of this operation.
-
- This is a low-level version of [[enq-map-buffer!]].
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueMapBuffer.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueMapBuffer-org.jocl.cl_command_queue-org.jocl.cl_mem-boolean-long-long-long-int-org.jocl.cl_event:A-org.jocl.cl_event-int:A-
-
- Examples:
-
- (enq-map-buffer* queue cl-data true 0 CL/CL_WRITE (events ev-nd) ev-map)
- "
- ^ByteBuffer [queue cl blocking offset req-size flags ^objects wait-events event]
- (if (< 0 ^long req-size)
- (let [err (int-array 1)
- res (CL/clEnqueueMapBuffer queue (extract cl) blocking flags offset
- (min ^long req-size (- ^long (size cl) ^long offset))
- (if wait-events (alength wait-events) 0)
- wait-events event err)]
- (with-check-arr err (.order res (ByteOrder/nativeOrder))))
- (ByteBuffer/allocateDirect 0)))
-
-(defn enq-svm-map*
- "Enqueues a command that will allow the host to update a region of a SVM buffer.
-. Returns the mapped `java.nio.ByteBuffer` (which is the same byte buffer that is
- already accessible through `(byte-buffer svm)`). Together with [[enq-svm-unmap!]],
- works as a synchronization point.
-
- Arguments:
-
- * `queue` (optional): the `cl_command_queue` that maps the object.
- If omitted, [[*command-queue*]] will be used.
- * `svm`: the [[SVMMem]] that is going to be mapped to.
- * `blocking`: whether the operation is blocking (CL/CL_TRUE) or non-blocking
- (CL/CL_FALSE).
- * `flags`: a bitfield that indicates whether the memory is mapped for reading
- (`CL/CL_MAP_READ`), writing (`CL/CL_MAP_WRITE`), both
- `(bit-or CL/CL_MAP_READ CL/CL_MAP_WRITE)` or `CL_MAP_WRITE_INVALIDATE_REGION`.
- * `wait-events` (optional): [[events]] array specifying the events (if any)
- that need to complete before this operation.
- * `event` (optional): if specified, the `cl_event` object tied to
- the execution of this operation.
-
- This is a low-level version of [[enq-svm-map!]].
-
- See https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/clEnqueueSVMMap.html,
- http://www.jocl.org/doc/org/jocl/CL.html#clEnqueueSVMMap-org.jocl.cl_command_queue-boolean-long-org.jocl.Pointer-long-int-org.jocl.cl_event:A-org.jocl.cl_event-
-
- Examples:
-
- (enq-svm-map* queue svm-data false 0 CL/CL_WRITE (events ev-nd) ev-map)
- "
- [queue svm blocking flags ^objects wait-events event]
- (with-check
- (CL/clEnqueueSVMMap queue blocking flags (ptr svm) (size svm)
- (if wait-events (alength wait-events) 0)
- wait-events event)
- (byte-buffer svm)))
diff --git a/src/clojure/uncomplicate/clojurecl/internal/protocols.clj b/src/clojure/uncomplicate/clojurecl/internal/protocols.clj
deleted file mode 100644
index 459ecb6..0000000
--- a/src/clojure/uncomplicate/clojurecl/internal/protocols.clj
+++ /dev/null
@@ -1,47 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns ^{:author "Dragan Djuric"}
- uncomplicate.clojurecl.internal.protocols)
-
-(defprotocol Wrappable
- (wrap [this]))
-
-(defprotocol Mem
- "An object that represents memory that participates in OpenCL operations.
- It can be on the device ([[CLMem]]), or on the host. Built-in implementations:
- cl buffer, Java primitive arrays and `ByteBuffer`s."
- (ptr [this]
- "JOCL `Pointer` to this object.")
- (size [this]
- "Memory size of this cl or host object in bytes."))
-
-(defprotocol CLMem
- "A wrapper for `cl_mem` objects, that also holds a `Pointer` to the cl mem
- object, context that created it, and size in bytes. It is useful in many
- functions that need that (redundant in Java) data because of the C background
- of OpenCL functions."
- (enq-copy* [this queue dst src-offset dst-offset cb wait-events ev]
- "A specific implementation for copying this `cl-mem` object to another cl mem.")
- (enq-fill* [this queue pattern offset multiplier wait-events ev]
- "A specific implementation for filling this `cl-mem` object."))
-
-(defprotocol SVMMem
- "A wrapper for SVM Buffer objects, that also holds a context that created it,
- `Pointer`, size in bytes, and can create a `ByteBuffer`. It is useful in many
- functions that need that (redundant in Java) data because of the C background
- of OpenCL functions."
- (byte-buffer [this] [this offset size]
- "Creates a Java `ByteBuffer` for this SVM memory.")
- (enq-svm-copy [this]));;TODO
-
-(defprotocol Argument
- "Object that can be argument in OpenCL kernels. Built-in implementations:
- [[CLBuffer]], java numbers, primitive arrays and `ByteBuffer`s."
- (set-arg [arg kernel n]
- "Specific implementation of setting the kernel arguments."))
diff --git a/src/clojure/uncomplicate/clojurecl/internal/utils.clj b/src/clojure/uncomplicate/clojurecl/internal/utils.clj
deleted file mode 100644
index f3a31c2..0000000
--- a/src/clojure/uncomplicate/clojurecl/internal/utils.clj
+++ /dev/null
@@ -1,94 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns ^{:author "Dragan Djuric"}
- uncomplicate.clojurecl.internal.utils
- "Utility functions used as helpers in other ClojureCL namespaces.
- The user of the ClojureCL library would probably not need to use
- any of the functions defined here."
- (:require [uncomplicate.commons.utils :as cu]
- [uncomplicate.clojurecl.internal.constants :refer [dec-error]])
- (:import clojure.lang.ExceptionInfo))
-
-
-;; ========== Error handling ======================================
-
-(defn error
- "Converts an OpenCL error code to an [ExceptionInfo]
- (http://clojuredocs.org/clojure.core/ex-info)
- with richer, user-friendly information.
-
- Accepts a long `err-code` that should be one of the codes defined in
- OpenCL standard, and an optional `details` argument that could be
- anything that you think is informative.
-
- See the available codes in the source of [[constants/dec-error]].
- Also see the discussion about
- [OpenCL error codes](http://streamcomputing.eu/blog/2013-04-28/opencl-1-2-error-codes/).
-
- Examples:
-
- (error 0) => an ExceptionInfo instance
- (error -5 {:comment \"Why here?\"\"}) => an ExceptionInfo instance
- "
- ([^long err-code details]
- (let [err (dec-error err-code)]
- (ex-info (format "OpenCL error: %s." err)
- {:name err :code err-code :type :opencl-error :details details})))
- ([err-code]
- (error err-code nil)))
-
-(defmacro with-check
- "Evaluates `form` if `status` is not zero (`CL_SUCCESS`), otherwise throws
- an appropriate `ExceptionInfo` with decoded informative details.
- It helps fith JOCL methods that return error codes directly, while
- returning computation results through side-effects in arguments.
-
- Example:
-
- (with-check (some-jocl-call-that-returns-error-code) result)
- "
- ([status form]
- `(cu/with-check error ~status ~form))
- ([status details form]
- `(let [status# ~status]
- (if (= 0 status#)
- ~form
- (throw (error status# ~details))))))
-
-(defmacro with-check-arr
- "Evaluates `form` if the integer in the `status` primitive int array is `0`,
- Otherwise throws an exception corresponding to the error code.
- Similar to [[with-check]], but with the error code being held in an array instead
- of being a primitive number. It helps with JOCL methods that return results
- directly, and signal errors through side-effects in a primitive array argument.
-
- (let [err (int-array 1)
- res (some-jocl-call err)]
- (with-checl-arr err res))
- "
- ([status form]
- `(with-check (aget (ints ~status) 0) ~form))
- ([status details form]
- `(with-check (aget (ints ~status) 0) ~details ~form)))
-
-(defmacro maybe
- "Evaluates form in try/catch block; if an OpenCL-related exception is caught,
- substitutes the result with the [ExceptionInfo](http://clojuredocs.org/clojure.core/ex-info)
- object.
- Non-OpenCL exceptions are rethrown. Useful when we do not want to let a minor
- OpenCL error due to a driver incompatibility with the standard
- or an unimplemented feature in the actual driver crash the application.
- An [ExceptionInfo](http://clojuredocs.org/clojure.core/ex-info) object will be
- put in the place of the expected result."
- [form]
- `(try ~form
- (catch ExceptionInfo ex-info#
- (if (= :opencl-error (:type (ex-data ex-info#)))
- (:name (ex-data ex-info#))
- (throw ex-info#)))))
diff --git a/src/clojure/uncomplicate/clojurecl/toolbox.clj b/src/clojure/uncomplicate/clojurecl/toolbox.clj
deleted file mode 100644
index 9cdd2c5..0000000
--- a/src/clojure/uncomplicate/clojurecl/toolbox.clj
+++ /dev/null
@@ -1,62 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns ^{:author "Dragan Djuric"}
- uncomplicate.clojurecl.toolbox
- "Various helpers that are not needed by ClojureCL itself,
- but may be very helpful in applications. See Neanderthal and Bayadera libraries
- for the examples of how to use them."
- (:require [uncomplicate.commons
- [core :refer [wrap-int]]
- [utils :refer [count-groups]]]
- [uncomplicate.clojurecl.core :refer :all]))
-
-(defn enq-reduce!
- ([queue main-kernel reduction-kernel n local-n]
- (loop [queue (enq-kernel! queue main-kernel (work-size-1d n local-n))
- global-size (count-groups local-n n)]
- (if (= 1 global-size)
- queue
- (recur (enq-kernel! queue reduction-kernel (work-size-1d global-size local-n))
- (count-groups local-n global-size)))))
- ([queue main-kernel reduction-kernel m n local-m local-n]
- (if (or (< 1 (long local-n)) (<= (long local-n) (long n)))
- (loop [queue (enq-kernel! queue main-kernel (work-size-2d m n local-m local-n))
- global-size (count-groups local-n n)]
- (if (= 1 global-size)
- queue
- (recur (enq-kernel! queue reduction-kernel (work-size-2d m global-size local-m local-n))
- (count-groups local-n global-size))))
- (throw (IllegalArgumentException.
- (format "local-n %d would cause infinite recursion for n:%d." local-n n))))))
-
-(defn enq-read-int ^long [queue cl-buf]
- (let [res (int-array 1)]
- (enq-read! queue cl-buf res)
- (aget res 0)))
-
-(defn enq-read-long ^long [queue cl-buf]
- (let [res (long-array 1)]
- (enq-read! queue cl-buf res)
- (aget res 0)))
-
-(defn enq-read-double ^double [queue cl-buf]
- (let [res (double-array 1)]
- (enq-read! queue cl-buf res)
- (aget res 0)))
-
-(defn enq-read-float ^double [queue cl-buf]
- (let [res (float-array 1)]
- (enq-read! queue cl-buf res)
- (aget res 0)))
-
-(defn decent-platform
- ([platforms]
- (decent-platform platforms :gpu))
- ([platforms device-type]
- (first (filter #(< 0 (num-devices % device-type)) (remove legacy? platforms)))))
diff --git a/src/java/org/jocl/JOCLAccessor.java b/src/java/org/jocl/JOCLAccessor.java
deleted file mode 100644
index 76f1409..0000000
--- a/src/java/org/jocl/JOCLAccessor.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) Dragan Djuric. All rights reserved.
-// The use and distribution terms for this software are covered by the
-// Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-// which can be found in the file LICENSE at the root of this distribution.
-// By using this software in any fashion, you are agreeing to be bound by
-// the terms of this license.
-// You must not remove this notice, or any other, from this software.
-
-package org.jocl;
-
-public class JOCLAccessor {
-
- public static long getNativePointer (NativePointerObject npo) {
- return npo.getNativePointer();
- };
-}
diff --git a/src/opencl/uncomplicate/clojurecl/kernels/reduction.cl b/src/opencl/uncomplicate/clojurecl/kernels/reduction.cl
deleted file mode 100644
index f317d2d..0000000
--- a/src/opencl/uncomplicate/clojurecl/kernels/reduction.cl
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef REAL
-#define REAL float
-#endif
-
-#ifndef ACCUMULATOR
-#define ACCUMULATOR float
-#endif
-
-#ifndef WGS
-#define WGS 256
-#endif
-
-// ================= Sum reduction =============================================
-
-inline ACCUMULATOR work_group_reduction_sum (ACCUMULATOR* lacc, const ACCUMULATOR value) {
-
- const uint local_id = get_local_id(0);
-
- //__local ACCUMULATOR lacc[WGS];
- lacc[local_id] = value;
-
- work_group_barrier(CLK_LOCAL_MEM_FENCE);
-
- ACCUMULATOR pacc = value;
- uint i = get_local_size(0);
- while (i > 0) {
- const bool include_odd = (i > ((i >> 1) << 1)) && (local_id == ((i >> 1) - 1));
- i >>= 1;
- if (include_odd) {
- pacc += lacc[local_id + i + 1];
- }
- if (local_id < i) {
- pacc += lacc[local_id + i];
- lacc[local_id] = pacc;
- }
- work_group_barrier(CLK_LOCAL_MEM_FENCE);
- }
-
- return lacc[0];
-}
-
-inline ACCUMULATOR work_group_reduction_sum_2 (ACCUMULATOR* lacc, const REAL value) {
-
- const uint local_row = get_local_id(0);
- const uint local_col = get_local_id(1);
- const uint local_m = get_local_size(0);
-
- //__local ACCUMULATOR lacc[WGS];
- lacc[local_row + local_col * local_m] = value;
-
- work_group_barrier(CLK_LOCAL_MEM_FENCE);
-
- ACCUMULATOR pacc = value;
- uint i = get_local_size(1);
- while (i > 0) {
- const bool include_odd = (i > ((i >> 1) << 1)) && (local_col == ((i >> 1) - 1));
- i >>= 1;
- if (include_odd) {
- pacc += lacc[local_row + (local_col + i + 1) * local_m];
- }
- if (local_col < i) {
- pacc += lacc[local_row + (local_col + i) * local_m];
- lacc[local_row + local_col * local_m] = pacc;
- }
- work_group_barrier(CLK_LOCAL_MEM_FENCE);
- }
-
- return lacc[local_row];
-
-}
-
-__kernel void sum_reduction (__global ACCUMULATOR* acc) {
- const ACCUMULATOR sum = work_group_reduce_add(acc[get_global_id(0)]);
- if (get_local_id(0) == 0) {
- acc[get_group_id(0)] = sum;
- }
-}
-
-__kernel void sum_reduce (__global ACCUMULATOR* acc, __global const REAL* x) {
- const ACCUMULATOR sum = work_group_reduce_add(x[get_global_id(0)]);
- if (get_local_id(0) == 0) {
- acc[get_group_id(0)] = sum;
- }
-}
-
-
-__kernel void sum_reduction_horizontal (__global ACCUMULATOR* acc) {
- const uint i = get_global_size(0) * get_global_id(1) + get_global_id(0);
- const uint iacc = get_global_size(0) * get_group_id(1) + get_global_id(0);
- __local ACCUMULATOR lacc[WGS];
- const ACCUMULATOR sum = work_group_reduction_sum_2(lacc, acc[i]);
- if (get_local_id(1) == 0) {
- acc[iacc] = sum;
- }
-}
-
-__kernel void sum_reduction_vertical (__global ACCUMULATOR* acc) {
- const uint i = get_global_size(1) * get_global_id(0) + get_global_id(1);
- const uint iacc = get_global_size(0) * get_group_id(1) + get_global_id(0);
- __local ACCUMULATOR lacc[WGS];
- const ACCUMULATOR sum = work_group_reduction_sum_2(lacc, acc[i]);
- if (get_local_id(1) == 0) {
- acc[iacc] = sum;
- }
-}
diff --git a/test/clojure/uncomplicate/clojurecl/core_test.clj b/test/clojure/uncomplicate/clojurecl/core_test.clj
deleted file mode 100644
index 4c535b9..0000000
--- a/test/clojure/uncomplicate/clojurecl/core_test.clj
+++ /dev/null
@@ -1,385 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.core-test
- (:require [midje.sweet :refer :all]
- [uncomplicate.commons
- [core :refer [release with-release info]]
- [utils :refer [direct-buffer put-float! get-float]]]
- [uncomplicate.fluokitten.core :refer [fmap extract]]
- [uncomplicate.clojurecl
- [core :refer :all]
- [info :refer [reference-count mem-base-addr-align opencl-c-version queue-context]]
- [toolbox :refer [decent-platform]]]
- [uncomplicate.clojurecl.internal
- [protocols :refer [size ptr byte-buffer wrap]]
- [impl :refer :all]]
- [clojure.core.async :refer [go >! true
-
- (count (platforms)) => (num-platforms)
-
- (let [p (first (platforms))]
- (with-platform p (platform-info)) => (info p)))
-
-;; ================== Device tests ========================
-(facts
- "num-devices tests."
-
- (let [p (decent-platform (platforms))]
- (num-devices* p CL/CL_DEVICE_TYPE_ALL) => (num-devices p :all)
-
- (< 0 (num-devices p :all)) => true
- ;;(< 0 (num-devices p :cpu)) => true
- (< 0 (num-devices p :gpu)) => true
-
- (num-devices p :cpu :gpu :accelerator :custom) => (num-devices p :all)
-
- (+ (num-devices p :cpu) (num-devices p :gpu)
- (num-devices p :accelerator) #_(num-devices p :custom));;Default Nvidia no longer supports :custom
- => (num-devices p :all)
-
- (num-devices p) => (num-devices p :all)
- (with-platform p
- (num-devices :all) => (num-devices p :all)
- (num-devices) => (num-devices p :all))
-
- ;;(num-devices nil :all) => (throws ExceptionInfo) ;;Some platforms just use first p
- (num-devices p :unknown-device) => (throws NullPointerException)))
-
-(facts
- "devices tests"
-
- (let [p (decent-platform (platforms))]
- ;;(vec (devices* p CL/CL_DEVICE_TYPE_ALL)) => (devices p :all)
-
- (count (devices p :all)) => (num-devices p :all)
-
- (devices p :gpu :cpu) => (concat (devices p :gpu) (devices p :cpu))
-;; (devices p :custom) => []
-
-;; (type (first (devices p :cpu))) => uncomplicate.clojurecl.internal.impl.CLDevice
-
- (with-platform p
- (devices :all) => (devices p :all)
- (devices :gpu) => (devices p :gpu)
- (devices) => (devices p :all))
-
- ;;(devices nil :all) => (throws ExceptionInfo);;Some platforms just use first p
- (devices p :unknown-device) => (throws NullPointerException)))
-
-(facts
- "Root level devices resource management."
-
- (let [p (decent-platform (platforms))
- da (first (devices p))
- db (first (devices p))]
- (reference-count da) => 1
- (reference-count db) => 1))
-
-;; ================== Context tests ========================
-
-(set! *warn-on-reflection* false)
-(facts
- "CreateContextCallback tests"
- (let [ch (chan)]
- (->CreateContextCallback ch) =not=> nil
- (do (.function (->CreateContextCallback ch) "Some error"
- (Pointer/to (int-array 1)) Integer/BYTES :some-data)
- (:errinfo ( "Some error")))
-(set! *warn-on-reflection* true)
-
-(let [p (decent-platform (platforms))]
- (with-platform p
- (with-release [devs (devices p)
- dev (first (filter #(<= 2.0 (double (:version (opencl-c-version %)))) devs))]
-
- (facts
- "context-properties tests"
- (context-properties {:platform p}) =not=> nil)
-
- (facts
- "context tests"
-
- (let [adevs (devices* p CL/CL_DEVICE_TYPE_ALL)
- props (context-properties {:platform p})]
-
- (let [ctx (wrap (context* adevs nil nil nil))]
- (reference-count ctx) => 1
- (release ctx) => true)
-
- (let [ctx (wrap (context* adevs props nil nil))]
- (reference-count ctx) => 1
- (release ctx) => true)
-
- ;; TODO I am not sure how this CreateContextFunction mechanism work.
- ;; It is implemented, but I do not know how to raise an error that
- ;; shoud then reported through the channel. Test it later.)
-
- (let [ch (chan)
- ctx (wrap (context* adevs props ch :some-data))]
- (reference-count ctx) => 1
- (command-queue ctx nil) => (throws ExceptionInfo))
-
- (context* nil nil nil nil) => (throws NullPointerException)
- (context* (make-array cl_device_id 0) nil nil nil) => (throws ExceptionInfo)
-
- (let [ctx (context)]
- (reference-count ctx) => 1
- (release ctx) => true)
-
- (context nil) => (throws ExceptionInfo)
-
- (let [ctx (context [dev])]
- (reference-count ctx) => 1
- (release ctx) => true)
-
- (release (context devs)) => true
- (release (context devs {:platform p} (chan) :some-data)) => true))
-
- (facts
- "queue tests"
- (with-release [ctx (context devs)
- cl-data (cl-buffer ctx Float/BYTES :read-write)]
- (let [queue (command-queue ctx dev)]
- (reference-count queue) => 1
- (queue-context queue) => ctx
- (info queue :properties) => #{}
- (release queue) => true)
-
- (let [queue (wrap (command-queue* (extract ctx) (extract dev) 0))]
- (reference-count queue) => 1
- (queue-context queue) => ctx
- (info queue :properties) => #{}
- (type (info queue :size)) => String
- (release queue) => true)
-
- (let [queue (wrap (command-queue* (extract ctx) (extract dev) 0 5))]
- (reference-count queue) => 1
- (queue-context queue) => ctx
- (info queue :properties) => #{:queue-on-device :out-of-order-exec-mode}
- (info queue :size) => (info dev :queue-on-device-preferred-size)
- (release queue) => true)
-
- (with-context (context devs)
- (let [queue (command-queue dev)]
- (reference-count queue) => 1
- (queue-context queue) => *context*
- (info queue :properties) => #{}
- (release queue) => true))
-
- (let [queue (command-queue ctx dev :queue-on-device :out-of-order-exec-mode :profiling)]
- (reference-count queue) => 1
- (queue-context queue) => ctx
- (info queue :properties) => #{:profiling :out-of-order-exec-mode
- :queue-on-device}
- (release queue) => true)
-
- (let [queue (command-queue ctx dev 524288 :queue-on-device :out-of-order-exec-mode :profiling)]
- (reference-count queue) => 1
- (queue-context queue) => ctx
- (info queue :properties) => #{:profiling :out-of-order-exec-mode :queue-on-device}
- (info queue :size) => 524288
- (release queue) => true)
-
- (command-queue ctx nil) => (throws ExceptionInfo)
- (command-queue nil dev) => (throws ExceptionInfo)
- (command-queue ctx dev :my-prop) => (throws NullPointerException))))))
-
-(with-default
-
- (facts
- "cl-buffer and cl-sub-buffer reading/writing tests."
- (let [alignment (mem-base-addr-align
- (first (filter #(<= 2.0 (double (:version (opencl-c-version %))))
- (devices (decent-platform (platforms))))))]
- (with-release [cl-buf (cl-buffer (* 4 alignment Float/BYTES))
- cl-subbuf (cl-sub-buffer cl-buf (* alignment Float/BYTES) (* alignment Float/BYTES))]
- (cl-buffer? cl-subbuf) => true
- (let [data-arr (float-array (range (* 4 alignment)))
- buf-arr (float-array (* 4 alignment))
- subbuf-arr (float-array alignment)]
- (enq-write! cl-buf data-arr)
- (enq-read! cl-buf buf-arr)
- (enq-read! cl-subbuf subbuf-arr)
- (vec buf-arr) => (vec data-arr)
- (vec subbuf-arr) => (map float (range alignment (* 2 alignment)))))))
-
- (facts
- "Event tests."
- (event) =not=> nil
- (host-event nil) => (throws ExceptionInfo)
- (host-event) =not=> nil
-
- (alength (events (host-event) (host-event))) => 2
- (alength ^objects (apply events (for [n (range 10)] (host-event)))) => 10)
-
- (facts
- "EventCallback tests"
- (let [ch (chan)
- ev (host-event)
- call-event-fun (fn [^EventCallbackFunction f] (.function f (extract ev) CL/CL_QUEUED ev))]
- (->EventCallback ch) =not=> nil
- (do (call-event-fun (->EventCallback ch))
- (:data ( ev))
-
- (with-release [cl-buf (cl-buffer Float/BYTES)
- cpu-buf (put-float! (direct-buffer Float/BYTES) 0 1.0)]
- (let [ev (event)
- notifications (chan)
- follow (register notifications)]
- (enq-write! *command-queue* cl-buf cpu-buf ev)
- (follow ev)
- (:data ( ev)))
-
- (let [src (slurp "test/opencl/core_test.cl")
- cnt 8
- data (float cnt)
- notifications (chan)
- follow (register notifications)]
-
- (facts
- "Program tests"
- (with-release [program (build-program! (program-with-source [src]))]
- program =not=> nil
- (info program :source) => src))
-
- (with-release [program (build-program! (program-with-source [src]) nil "-cl-std=CL2.0"
- notifications :my-data)]
- (facts
- "Program build tests."
- program =not=> nil
- (info program :source) => src
- ( :my-data)
-
- ;; TODO Some procedures might crash JVM if called on
- ;; unprepared objects (kernels of unbuilt program).
- ;; Solve and test such cases systematically in info.clj
- ;; in a similar way as kernels check for program binaries first.
-
- (facts
- (info (program-with-source [src])) =not=> nil)
-
- (with-release [dumb-kernel (kernel program "dumb_kernel")
- all-kernels (kernel program)
- cl-data (cl-buffer (* cnt Float/BYTES))
- cl-copy-data (cl-buffer (size cl-data))]
- (facts
- "Kernel tests"
- (num-kernels program) => 1
-
- (info dumb-kernel :name) => (info (first all-kernels) :name)
- (kernel nil) => (throws ExceptionInfo)
-
- (set-arg! dumb-kernel 0 nil) => (throws IllegalArgumentException)
-
- (set-arg! dumb-kernel 0 cl-data) => dumb-kernel
- (set-arg! dumb-kernel 1 Integer/BYTES) => dumb-kernel
- (set-arg! dumb-kernel 2 (int-array [42])) => dumb-kernel
-
- (set-args! dumb-kernel cl-data Integer/BYTES) => dumb-kernel)
-
- (let [wsize (work-size [cnt])
- data (float-array (range cnt))
- copy-data (float-array cnt)]
- (facts
- "enq-kernel!, enq-read!, enq-write!, enq-copy! enq-fill tests"
- (enq-write! cl-data data) => *command-queue*
- (enq-kernel! dumb-kernel wsize) => *command-queue*
- (enq-read! cl-data data) => *command-queue*
- (vec data) => [84.0 86.0 88.0 90.0 92.0 94.0 96.0 98.0]
- (enq-copy! cl-data cl-copy-data) => *command-queue*
- (enq-read! cl-copy-data copy-data) => *command-queue*
- (vec copy-data) => (vec data)
- (enq-fill! cl-data (float-array [1 2 3 4])) => *command-queue*
- (enq-read! cl-data data) => *command-queue*
- (vec data) => [1.0 2.0 3.0 4.0 1.0 2.0 3.0 4.0]))))))
-
-(let [cnt 8
- src (slurp "test/opencl/core_test.cl")
- data (let [d (direct-buffer (* 8 Float/BYTES))]
- (dotimes [n cnt]
- (put-float! d n n))
- d)
- notifications (chan)
- follow (register notifications)
- ev-nd1 (event)
- ev-nd2 (event)
- ev-read (event)
- ev-write (event)
- wsize (work-size [8])]
-
- (with-release [devs (devices (decent-platform (platforms)))
- ctx (context devs)
- queue1 (command-queue ctx (first devs))
- queue2 (command-queue ctx (first devs))
- cl-data (cl-buffer ctx (* cnt Float/BYTES) :read-write)
- program (build-program! (program-with-source ctx [src]))
- dumb-kernel (kernel program "dumb_kernel")]
-
- (facts
- "wait-events tests"
- (set-args! dumb-kernel cl-data Integer/BYTES (int-array [42]))
- (enq-write! queue1 cl-data data ev-write)
- (enq-kernel! queue1 dumb-kernel wsize (events ev-write) ev-nd1)
- (enq-kernel! queue2 dumb-kernel wsize (events ev-write ev-nd1) ev-nd2)
- (enq-read! queue1 cl-data data (events ev-nd2) ev-read)
- (follow ev-read)
-
- (:data ( ev-read
-
- (vec (let [res (float-array cnt)] (.get (.asFloatBuffer ^ByteBuffer data) res) res))
- => [168.0 171.0 174.0 177.0 180.0 183.0 186.0 189.0]
-
- (let [mapped-read (enq-map-buffer! queue1 cl-data :read)
- mapped-write (enq-map-buffer! queue1 cl-data :write)]
- (get-float mapped-read 1) => 171.0
- (get-float mapped-write 1) => 171.0
- (do (put-float! mapped-write 1 100.0) (get-float mapped-write 1)) => 100.0
- (get-float ^ByteBuffer mapped-read 1) => 100.0
- (do (put-float! mapped-read 1 100.0) (get-float mapped-read 1)) => 100.0
- (enq-unmap! queue1 cl-data mapped-read) => queue1
- (enq-unmap! queue1 cl-data mapped-write) => queue1)))
-
- (with-release [dev (first (filter #(= 2.0 (:version (opencl-c-version %)))
- (devices (decent-platform (platforms)) :gpu)))
- ctx (context [dev])
- queue (command-queue ctx dev)
- svm (svm-buffer ctx (* cnt Float/BYTES) 0)
- program (build-program! (program-with-source ctx [src]) "-cl-std=CL2.0" nil)
- dumb-kernel (kernel program "dumb_kernel")]
- (facts
- "SVM tests" ;; ONLY BASIC TESTS, since i do not have an APU, and
- ;; my current platform (AMD) only supports OpenCL 1.2 for the CPU.
- (ptr svm) =not=> nil
- (set-args! dumb-kernel svm Integer/BYTES (int-array [42])) => dumb-kernel
- (enq-svm-map! queue svm :write)
- (put-float! (byte-buffer svm) 1 42.0)
- (get-float (byte-buffer svm) 1) => 42.0
- (enq-svm-unmap! queue svm) => queue
- (enq-kernel! queue dumb-kernel wsize) => queue
- (enq-svm-map! queue svm :read)
- (get-float (byte-buffer svm) 1) => 127.0
- (enq-svm-unmap! queue svm) => queue
-
- (svm-buffer* nil 4 0) => (throws IllegalArgumentException)
- (svm-buffer* (extract ctx) 0 0) => (throws IllegalArgumentException)
- (svm-buffer ctx 4 0 :invalid-flag) => (throws NullPointerException))))
-
-(with-default-1
- (facts "Legacy bindings"
- *context* => truthy
- *command-queue* => truthy))
diff --git a/test/clojure/uncomplicate/clojurecl/examples/jocl/hello_test.clj b/test/clojure/uncomplicate/clojurecl/examples/jocl/hello_test.clj
deleted file mode 100644
index fd8edd7..0000000
--- a/test/clojure/uncomplicate/clojurecl/examples/jocl/hello_test.clj
+++ /dev/null
@@ -1,73 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.examples.jocl.hello-test
- (:require [midje.sweet :refer :all]
- [uncomplicate.commons
- [core :refer [with-release]]
- [utils :refer [put-float! get-float]]]
- [uncomplicate.clojurecl.core :refer :all]
- [uncomplicate.clojurecl.toolbox :refer [decent-platform]]))
-
-(def program-source (slurp "test/opencl/examples/jocl/hello-kernel.cl"))
-
-(let [n 100
- bytesize (* (long n) Float/BYTES)
- src-array-a (float-array (range n))
- src-array-b (float-array (range n))
- dest-array (float-array n)
- work-sizes (work-size [n] [1])]
- (with-release [devs (devices (decent-platform (platforms)))
- dev (first devs)
- ctx (context devs)
- cqueue (command-queue ctx dev)
- mem-objects [(cl-buffer ctx bytesize :read-only)
- (cl-buffer ctx bytesize :read-only)
- (cl-buffer ctx bytesize :write-only)]
- prog (build-program! (program-with-source ctx [program-source]))
- sample-kernel (kernel prog "sampleKernel")]
-
- (facts
-
- (apply set-args! sample-kernel mem-objects) => sample-kernel
-
- (-> cqueue
- (enq-write! (mem-objects 0) src-array-a)
- (enq-write! (mem-objects 1) src-array-b)
- (enq-kernel! sample-kernel work-sizes)
- (enq-read! (mem-objects 2) dest-array))
- => cqueue
-
- (finish! cqueue)
- (seq dest-array) => (map float (range 0 200 2)))
-
- (with-release [mem-object-a (cl-buffer ctx bytesize :read-only)
- mem-object-b (cl-buffer ctx bytesize :read-only)
- mem-object-dest (cl-buffer ctx bytesize :read-only)]
-
- (let [src-buffer-a (enq-map-buffer! cqueue mem-object-a :write)]
- (put-float! src-buffer-a 0 46)
- (put-float! src-buffer-a 1 100)
- (enq-unmap! cqueue mem-object-a src-buffer-a))
-
- (let [src-buffer-b (enq-map-buffer! cqueue mem-object-b :write)]
- (put-float! src-buffer-b 0 56)
- (put-float! src-buffer-b 1 200)
- (enq-unmap! cqueue mem-object-b src-buffer-b))
-
- (facts
- (set-arg! sample-kernel 0 mem-object-a) => sample-kernel
- (set-arg! sample-kernel 1 mem-object-b) => sample-kernel
- (set-arg! sample-kernel 2 mem-object-dest) => sample-kernel
-
- (enq-kernel! cqueue sample-kernel work-sizes) => cqueue
-
- (let [dest-buffer (enq-map-buffer! cqueue mem-object-dest :read)]
- (get-float dest-buffer 0) => 102.0
- (get-float dest-buffer 1) => 300.0
- (enq-unmap! cqueue mem-object-dest dest-buffer) => cqueue)))))
diff --git a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch04.clj b/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch04.clj
deleted file mode 100644
index b487847..0000000
--- a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch04.clj
+++ /dev/null
@@ -1,106 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.examples.openclinaction.ch04
- (:require [midje.sweet :refer :all]
- [clojure.java.io :as io]
- [clojure.core.async :refer [chan hello-kernel
- (enq-kernel! cqueue hello-kernel work-sizes) => cqueue
- (enq-read! cqueue cl-msg host-msg read-complete) => cqueue
- (follow read-complete host-msg) => notifications
- (let [data ^java.nio.ByteBuffer (:data ( "Hello kernel!!!\0")))
-
- (facts
- "Section 4.2, Page 72."
- (let [host-a (float-array [10])
- host-b (float-array [2])
- host-out (float-array 1)
- work-sizes (work-size [1])
- program-source
- (slurp (io/resource "examples/openclinaction/ch04/double-test.cl"))]
- (with-release [cl-a (cl-buffer ctx (* 2 Float/BYTES) :read-only)
- cl-b (cl-buffer ctx (* 2 Float/BYTES) :read-only)
- cl-out (cl-buffer ctx (* 2 Float/BYTES) :write-only)
- prog (build-program! (program-with-source ctx [program-source])
- (if (contains? (info dev :extensions)
- "cl_khr_fp64")
- "-DFP_64"
- "")
- notifications)
- double-test (kernel prog "double_test")]
-
- (set-args! double-test cl-a cl-b cl-out) => double-test
- (enq-write! cqueue cl-a host-a) => cqueue
- (enq-write! cqueue cl-b host-b) => cqueue
- (enq-kernel! cqueue double-test work-sizes) => cqueue
- (enq-read! cqueue cl-out host-out) => cqueue
- (seq host-out) => (map / host-a host-b))))
-
- (facts
- "Section 4.3, Page 77."
- (println "Single FP Config: " (info dev :single-fp-config)))
-
- (facts
- "Section 4.4.1, Page 79."
- (println "Preferred vector widths: "
- (select-keys (info dev) [:preferred-vector-width-char
- :preferred-vector-width-short
- :preferred-vector-width-int
- :preferred-vector-width-long
- :preferred-vector-width-float
- :preferred-vector-width-double
- :preferred-vector-width-long])))
-
- (facts
- "Section 4.4.4, Page 85."
- (let [host-data (byte-array 16)
- work-sizes (work-size [1])
- program-source
- (slurp (io/resource "examples/openclinaction/ch04/vector-bytes.cl"))]
- (with-release [cl-data (cl-buffer ctx 16 :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- vector-bytes (kernel prog "vector_bytes")]
-
- (set-args! vector-bytes cl-data) => vector-bytes
- (enq-write! cqueue cl-data host-data) => cqueue
- (enq-kernel! cqueue vector-bytes work-sizes) => cqueue
- (enq-read! cqueue cl-data host-data) => cqueue
- (seq host-data) => (if (endian-little dev)
- [3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12]
- (range 16)))))))
diff --git a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch05.clj b/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch05.clj
deleted file mode 100644
index 462c934..0000000
--- a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch05.clj
+++ /dev/null
@@ -1,151 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.examples.openclinaction.ch05
- (:require [midje.sweet :refer :all]
- [clojure.java.io :as io]
- [uncomplicate.commons.core :refer [with-release info]]
- [uncomplicate.clojurecl
- [core :refer :all]
- [toolbox :refer [decent-platform]]]))
-
-(with-release [dev (first (devices (decent-platform (platforms))))
- ctx (context [dev])
- cqueue (command-queue ctx dev)]
-
- (facts
- "Listing 5.1, Page 96."
- (let [host-output (int-array 4)
- work-sizes (work-size [1])
- program-source
- (slurp (io/resource "examples/openclinaction/ch05/op-test.cl"))]
- (with-release [cl-output (cl-buffer ctx (* 4 Integer/BYTES) :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- op-test-kernel (kernel prog "op_test")]
-
- (set-args! op-test-kernel cl-output) => op-test-kernel
- (enq-kernel! cqueue op-test-kernel work-sizes) => cqueue
- (enq-read! cqueue cl-output host-output) => cqueue
- (vec host-output) => [-1 0 0 4])))
-
- (facts
- "Listing 5.2, Page 100."
- (let [host-output (float-array 24)
- work-sizes (work-size [6 4] [3 2] [3 5])
- program-source
- (slurp (io/resource "examples/openclinaction/ch05/id-check.cl"))]
- (with-release [cl-output (cl-buffer ctx (* 24 Float/BYTES) :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- id-check-kernel (kernel prog "id_check")]
-
- (set-args! id-check-kernel cl-output) => id-check-kernel
- (enq-kernel! cqueue id-check-kernel work-sizes) => cqueue
- (enq-read! cqueue cl-output host-output) => cqueue
- (seq host-output)
- => (just (roughly 35.0) (roughly 45.1) (roughly 55.2)
- (roughly 65.0) (roughly 75.1) (roughly 85.2)
- (roughly 36.01) (roughly 46.109997) (roughly 56.21)
- (roughly 66.01) (roughly 76.11) (roughly 86.21)
- (roughly 37.0) (roughly 47.1) (roughly 57.2)
- (roughly 67.0) (roughly 77.1) (roughly 87.2)
- (roughly 38.01) (roughly 48.109997) (roughly 58.21)
- (roughly 68.01) (roughly 78.11) (roughly 88.21)))))
-
- (facts
- "Listing 5.3, Page 104."
- (let [host-mod-input (float-array [317 23])
- host-mod-output (float-array 2)
- host-round-input (float-array [6.5 -3.5 3.5 6.5])
- host-round-output (float-array 20)
- work-sizes (work-size [1])
- program-source
- (slurp (io/resource "examples/openclinaction/ch05/mod-round.cl"))]
- (with-release [cl-mod-input (cl-buffer ctx (* 2 Float/BYTES) :read-only)
- cl-mod-output (cl-buffer ctx (* 2 Float/BYTES) :write-only)
- cl-round-input (cl-buffer ctx (* 20 Float/BYTES) :read-only)
- cl-round-output (cl-buffer ctx (* 20 Float/BYTES) :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- mod-round-kernel (kernel prog "mod_round")]
-
- (set-args! mod-round-kernel cl-mod-input cl-mod-output
- cl-round-input cl-round-output)
- => mod-round-kernel
- (enq-write! cqueue cl-mod-input host-mod-input) => cqueue
- (enq-write! cqueue cl-round-input host-round-input) => cqueue
- (enq-kernel! cqueue mod-round-kernel work-sizes) => cqueue
- (enq-read! cqueue cl-mod-output host-mod-output) => cqueue
- (enq-read! cqueue cl-round-output host-round-output) => cqueue
- (seq host-mod-output) => '(18.0 -5.0)
- (vec host-round-output) => [6.0 -4.0 4.0 6.0
- 7.0 -4.0 4.0 7.0
- 7.0 -3.0 4.0 7.0
- 6.0 -4.0 3.0 6.0
- 6.0 -3.0 3.0 6.0])))
-
- (facts
- "Listing 5.4, Page 108."
- (let [rvals (float-array [2 1 3 4])
- angles (float-array [(* (double 3/8) Math/PI) (* (double 3/4) Math/PI)
- (* (double 4/3) Math/PI) (* (double 11/6) Math/PI)])
- xcoords (float-array 4)
- ycoords (float-array 4)
- work-sizes (work-size [1])
- program-source
- (slurp (io/resource "examples/openclinaction/ch05/polar-rect.cl"))]
- (with-release [cl-rvals (cl-buffer ctx (* 4 Float/BYTES) :read-only)
- cl-angles (cl-buffer ctx (* 4 Float/BYTES) :read-only)
- cl-xcoords (cl-buffer ctx (* 4 Float/BYTES) :write-only)
- cl-ycoords (cl-buffer ctx (* 4 Float/BYTES) :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- polar-rect-kernel (kernel prog "polar_rect")]
-
- (set-args! polar-rect-kernel cl-rvals cl-angles cl-xcoords cl-ycoords)
- => polar-rect-kernel
- (enq-write! cqueue cl-rvals rvals) => cqueue
- (enq-write! cqueue cl-angles angles) => cqueue
- (enq-kernel! cqueue polar-rect-kernel work-sizes) => cqueue
- (enq-read! cqueue cl-xcoords xcoords) => cqueue
- (enq-read! cqueue cl-ycoords ycoords) => cqueue
- (seq xcoords) => (just (roughly 0.76536685) (roughly -0.70710677)
- (roughly -1.4999998) (roughly 3.4641013))
- (seq ycoords) => (just (roughly 1.847759) (roughly 0.70710677)
- (roughly -2.5980763) (roughly -2.0000007)))))
-
- (facts
- "Listing 5.5, Page 112."
- (let [output (int-array 2)
- work-sizes (work-size [1])
- program-source
- (slurp (io/resource "examples/openclinaction/ch05/mad-test.cl"))]
- (with-release [cl-output (cl-buffer ctx (* 2 Integer/BYTES) :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- mad-test-kernel (kernel prog "mad_test")]
-
- (set-args! mad-test-kernel cl-output) => mad-test-kernel
- (enq-kernel! cqueue mad-test-kernel work-sizes) => cqueue
- (enq-read! cqueue cl-output output) => cqueue
- (vec output) => [-396694989 1118792])))
-
- (facts
- "Listing 5.6, Page 116."
- (let [s1 (float-array 4)
- s2 (byte-array 2)
- work-sizes (work-size [1])
- program-source
- (slurp (io/resource "examples/openclinaction/ch05/select-test.cl"))]
- (with-release [cl-s1 (cl-buffer ctx (* 4 Float/BYTES) :write-only)
- cl-s2 (cl-buffer ctx 8 :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- select-test-kernel (kernel prog "select_test")]
-
- (set-args! select-test-kernel cl-s1 cl-s2) => select-test-kernel
- (enq-kernel! cqueue select-test-kernel work-sizes) => cqueue
- (enq-read! cqueue cl-s1 s1) => cqueue
- (enq-read! cqueue cl-s2 s2) => cqueue
- (vec s1) => [1.25 0.5 1.75 1.0]
- (vec s2) => [2r00100111 2r00011011]))))
diff --git a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch07.clj b/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch07.clj
deleted file mode 100644
index e7f63f8..0000000
--- a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch07.clj
+++ /dev/null
@@ -1,95 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.examples.openclinaction.ch07
- (:require [midje.sweet :refer :all]
- [clojure.java.io :as io]
- [clojure.core.async :refer [ user-event-kernel
- (enq-kernel! cqueue user-event-kernel work-sizes (events user-event) kernel-event)
- => cqueue
- (enq-read! cqueue cl-v v (events kernel-event) read-event) => cqueue
- (follow read-event) => notifications
- (set-status! user-event) => user-event
- (:data ( read-event))))
-
- (facts
- "Listing 7.6. Page 155."
- (let [program-source
- (slurp (io/resource "examples/openclinaction/ch07/profile-read.cl"))
- bytesize (Math/pow 2 20)
- notifications (chan)
- follow (register notifications)
- data (direct-buffer bytesize)
- num (int-array [(/ (long bytesize) 16)])
- work-sizes (work-size [1])]
- (with-release [cl-data (cl-buffer ctx bytesize :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- profile-read (kernel prog "profile_read")
- profile-event (event)]
- (facts
- (set-args! profile-read cl-data num) => profile-read
-
- (enq-kernel! cqueue profile-read work-sizes)
- (enq-read! cqueue cl-data data profile-event)
- (follow profile-event)
-
- (< 10000
- (-> ( true))))
-
- (facts
- "Listing 7.7. Page 157."
- (let [program-source
- (slurp (io/resource "examples/openclinaction/ch07/profile-items.cl"))
- num-ints 65536
- data (int-array (range num-ints))
- notifications (chan)
- follow (register notifications)
- work-sizes (work-size [512] [1])]
- (with-release [cl-x (cl-buffer ctx (* num-ints Integer/BYTES 4) :write-only)
- prog (build-program! (program-with-source ctx [program-source]))
- profile-items (kernel prog "profile_items")
- profile-event (event)]
- (facts
- (set-args! profile-items cl-x (int-array [num-ints])) => profile-items
- (enq-kernel! cqueue profile-items work-sizes nil profile-event)
- (follow profile-event)
-
- (< 10000
- (-> ( true)))))
diff --git a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch10.clj b/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch10.clj
deleted file mode 100644
index fe4f296..0000000
--- a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch10.clj
+++ /dev/null
@@ -1,96 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.examples.openclinaction.ch10
- (:require [midje.sweet :refer :all]
- [clojure.java.io :as io]
- [clojure.core.async :refer [chan naive-reduction
- (enq-write! cqueue cl-data data) => cqueue
- (enq-kernel! cqueue naive-reduction (work-size [1]) nil profile-event)
- => cqueue
- (follow profile-event) => notifications
- (enq-read! cqueue cl-output output) => cqueue
- (finish! cqueue) => cqueue
- (println "Naive reduction time:"
- (-> ( num-items
- ;; ============= Scalar reduction ====================================
- (set-args! reduction-scalar cl-data cl-partial-sums cl-partial-output)
- => reduction-scalar
- (enq-kernel! cqueue reduction-scalar
- (work-size [num-items] [workgroup-size])
- nil profile-event)
- (follow profile-event)
- (enq-read! cqueue cl-partial-output partial-output)
- (finish! cqueue)
- (println "Scalar reduction time:"
- (-> ( workgroup-size
- ;; =============== Vector reduction ==================================
- (set-args! reduction-vector cl-data cl-partial-sums cl-partial-output)
- => reduction-vector
- (enq-kernel! cqueue reduction-vector
- (work-size [(/ num-items 4)] [workgroup-size])
- nil profile-event1)
- (follow profile-event1)
- (set-args! reduction-vector cl-partial-output cl-partial-sums cl-partial-output)
- => reduction-vector
- (enq-kernel! cqueue reduction-vector
- (work-size [(/ num-items 4 workgroup-size 4)] [workgroup-size])
- nil profile-event2)
- (follow profile-event2)
- (enq-read! cqueue cl-partial-output partial-output)
- (finish! cqueue)
- (println "Vector reduction time:"
- (-> ( ( num-items)))))
diff --git a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch11.clj b/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch11.clj
deleted file mode 100644
index 571a427..0000000
--- a/test/clojure/uncomplicate/clojurecl/examples/openclinaction/ch11.clj
+++ /dev/null
@@ -1,55 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.examples.openclinaction.ch11
- (:require [midje.sweet :refer :all]
- [clojure.java.io :as io]
- [clojure.core.async :refer [chan string-search
- (enq-write! cqueue cl-text kafka) => cqueue
- (enq-write! cqueue cl-result result) => cqueue
- (enq-kernel! cqueue string-search work-size) => cqueue
- (enq-read! cqueue cl-result result) => cqueue
- (finish! cqueue) => cqueue
- (vec result) => [330 237 110 116])))))
diff --git a/test/clojure/uncomplicate/clojurecl/toolbox_test.clj b/test/clojure/uncomplicate/clojurecl/toolbox_test.clj
deleted file mode 100644
index fd60b4a..0000000
--- a/test/clojure/uncomplicate/clojurecl/toolbox_test.clj
+++ /dev/null
@@ -1,81 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.toolbox-test
- (:require [midje.sweet :refer :all]
- [uncomplicate.commons
- [core :refer [release with-release]]
- [utils :refer [direct-buffer count-groups]]]
- [uncomplicate.clojurecl
- [core :refer :all]
- [info :refer :all]
- [toolbox :refer :all]])
- (:import java.nio.ByteBuffer))
-
-(let [cnt-m 311
- cnt-n 9011
- cnt (* cnt-m cnt-n)
- program-source [(slurp "src/opencl/uncomplicate/clojurecl/kernels/reduction.cl")
- (slurp "test/opencl/toolbox_test.cl")]]
-
- (with-release [dev (first (devices (decent-platform (platforms))))
- ctx (context [dev])
- queue (command-queue ctx dev)
- wgs (max-work-group-size dev)
- program (build-program! (program-with-source ctx program-source)
- (format "-cl-std=CL2.0 -DREAL=float -DACCUMULATOR=double -DWGS=%d" wgs)
- nil)
- data (let [d (direct-buffer (* cnt Float/BYTES))]
- (dotimes [n cnt]
- (.putFloat ^ByteBuffer d (* n Float/BYTES) (float n)))
- d)
- cl-data (cl-buffer ctx (* cnt Float/BYTES) :read-only)]
-
- (enq-write! queue cl-data data)
-
- (let [acc-size (* Double/BYTES (max 1 (count-groups (max-work-group-size dev) cnt)))]
- (with-release [sum-reduction-kernel (kernel program "sum_reduction")
- sum-reduce-kernel (kernel program "sum_reduce")
- cl-acc (cl-buffer ctx acc-size :read-write)]
-
- (facts
- "Test 1D reduction."
- (set-arg! sum-reduction-kernel 0 cl-acc)
- (set-args! sum-reduce-kernel cl-acc cl-data)
- (enq-reduce! queue sum-reduce-kernel sum-reduction-kernel cnt wgs)
- (enq-read-double queue cl-acc) => 3926780329408.0)))
-
- (let [wgs-m 4
- wgs-n 32
- acc-size (* Double/BYTES (max 1 (* cnt-m (count-groups wgs-n cnt-n))))
- res (double-array cnt-m)]
- (with-release [sum-reduction-horizontal (kernel program "sum_reduction_horizontal")
- sum-reduce-horizontal (kernel program "sum_reduce_horizontal")
- cl-acc (cl-buffer ctx acc-size :read-write)]
-
- (facts
- (set-arg! sum-reduction-horizontal 0 cl-acc)
- (set-args! sum-reduce-horizontal cl-acc cl-data)
- (enq-reduce! queue sum-reduce-horizontal sum-reduction-horizontal cnt-m cnt-n wgs-m wgs-n)
- (enq-read! queue cl-acc res)
- (apply + (seq res)) => (roughly 3.92678032941E12))))
-
- (let [wgs-m 32
- wgs-n 4
- acc-size (* Double/BYTES (max 1 (* cnt-n (count-groups wgs-m cnt-m))))
- res (double-array cnt-n)]
- (with-release [sum-reduction-vertical (kernel program "sum_reduction_vertical")
- sum-reduce-vertical (kernel program "sum_reduce_vertical")
- cl-acc (cl-buffer ctx acc-size :read-write)]
-
- (facts
- (set-arg! sum-reduction-vertical 0 cl-acc)
- (set-args! sum-reduce-vertical cl-acc cl-data)
- (enq-reduce! queue sum-reduce-vertical sum-reduction-vertical cnt-n cnt-m wgs-n wgs-m)
- (enq-read! queue cl-acc res)
- (apply + (seq res)) => (roughly 3.92678032941E12))))))
diff --git a/test/clojure/uncomplicate/clojurecl/utils_test.clj b/test/clojure/uncomplicate/clojurecl/utils_test.clj
deleted file mode 100644
index f4a4f1e..0000000
--- a/test/clojure/uncomplicate/clojurecl/utils_test.clj
+++ /dev/null
@@ -1,45 +0,0 @@
-;; Copyright (c) Dragan Djuric. All rights reserved.
-;; The use and distribution terms for this software are covered by the
-;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) or later
-;; which can be found in the file LICENSE at the root of this distribution.
-;; By using this software in any fashion, you are agreeing to be bound by
-;; the terms of this license.
-;; You must not remove this notice, or any other, from this software.
-
-(ns uncomplicate.clojurecl.utils-test
- (:require [midje.sweet :refer :all]
- [uncomplicate.clojurecl.internal.utils :refer :all]))
-
-(facts
- "error tests"
-
- (ex-data (error 0))
- => {:code 0, :details nil, :name "CL_SUCCESS", :type :opencl-error}
-
- (ex-data (error 43))
- => {:code 43, :details nil, :name "UNKNOWN OpenCL ERROR!", :type :opencl-error}
-
- (ex-data (error 0 "Additional details"))
- => {:code 0, :details "Additional details", :name "CL_SUCCESS", :type :opencl-error})
-
-(facts
- "with-check tests"
- (let [f (fn [x] (if x 0 -1))]
- (with-check (f 1) :success) => :success
- (with-check (f false) :success) => (throws clojure.lang.ExceptionInfo)))
-
-(facts
- "with-check-arr tests"
- (let [f (fn [x ^ints err]
- (do (aset err 0 (if x 0 -1))
- x))
- err (int-array 1)]
- (let [res (f :success err)] (with-check-arr err res) => :success)
- (let [res (f false err)] (with-check-arr err res))) => (throws clojure.lang.ExceptionInfo))
-
-(facts
- "maybe tests"
- (ex-data (maybe (throw (ex-info "Test Exception" {:data :test}))))
- => (throws clojure.lang.ExceptionInfo)
-
- (:type (ex-data (error -1 nil))) => :opencl-error)
diff --git a/test/opencl/core_test.cl b/test/opencl/core_test.cl
deleted file mode 100644
index 89d4719..0000000
--- a/test/opencl/core_test.cl
+++ /dev/null
@@ -1,4 +0,0 @@
-__kernel void dumb_kernel(__global float *data, __local int* n, int m) {
- int gid = get_global_id(0);
- data[gid] = data [gid] + (float)gid + 2.0f * m;
-}
diff --git a/test/opencl/examples/jocl/hello-kernel.cl b/test/opencl/examples/jocl/hello-kernel.cl
deleted file mode 100644
index aeda43f..0000000
--- a/test/opencl/examples/jocl/hello-kernel.cl
+++ /dev/null
@@ -1,6 +0,0 @@
-__kernel void sampleKernel(__global const float *a,
- __global const float *b,
- __global float *c) {
- int gid = get_global_id(0);
- c[gid] = a[gid] + b[gid];
-}
diff --git a/test/opencl/examples/openclinaction/ch04/double-test.cl b/test/opencl/examples/openclinaction/ch04/double-test.cl
deleted file mode 100644
index e73910c..0000000
--- a/test/opencl/examples/openclinaction/ch04/double-test.cl
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifdef FP_64
-#pragma OPENCL EXTENSION cl_khr_fp64: enable
-#endif
-
-__kernel void double_test(__global float* a,
- __global float* b,
- __global float* out) {
-#ifdef FP_64
- double c = (double)(*a / *b);
- *out = (float)c;
-#else
- *out = *a * *b;
-#endif
-}
diff --git a/test/opencl/examples/openclinaction/ch04/hello-kernel.cl b/test/opencl/examples/openclinaction/ch04/hello-kernel.cl
deleted file mode 100644
index a9999eb..0000000
--- a/test/opencl/examples/openclinaction/ch04/hello-kernel.cl
+++ /dev/null
@@ -1,4 +0,0 @@
-__kernel void hello_kernel(__global char16 *msg) {
- *msg = (char16)('H', 'e', 'l', 'l', 'o', ' ',
- 'k', 'e', 'r', 'n', 'e', 'l', '!', '!', '!', '\0');
-}
diff --git a/test/opencl/examples/openclinaction/ch04/vector-bytes.cl b/test/opencl/examples/openclinaction/ch04/vector-bytes.cl
deleted file mode 100644
index accc347..0000000
--- a/test/opencl/examples/openclinaction/ch04/vector-bytes.cl
+++ /dev/null
@@ -1,8 +0,0 @@
-__kernel void vector_bytes(__global uchar16 *test) {
-
- uint4 vec = (uint4) (0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F);
- uchar *p = (uchar*)&vec;
- *test = (uchar16)(*p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6),
- *(p+7), *(p+8), *(p+9), *(p+10), *(p+11), *(p+12),
- *(p+13), *(p+14), *(p+15));
-}
diff --git a/test/opencl/examples/openclinaction/ch05/id-check.cl b/test/opencl/examples/openclinaction/ch05/id-check.cl
deleted file mode 100644
index 7ec0de9..0000000
--- a/test/opencl/examples/openclinaction/ch05/id-check.cl
+++ /dev/null
@@ -1,16 +0,0 @@
-__kernel void id_check (__global float *output) {
-
- size_t gid0 = get_global_id(0);
- size_t gid1 = get_global_id(1);
- size_t gsize0 = get_global_size(0);
- size_t offset0 = get_global_offset(0);
- size_t offset1 = get_global_offset(1);
- size_t lid0 = get_local_id(0);
- size_t lid1 = get_local_id(1);
-
- int index0 = gid0 - offset0;
- int index1 = gid1 - offset1;
- int index = index1 * gsize0 + index0;
-
- output[index] = gid0 * 10.0f + gid1 * 1.0f + lid0 * 0.1f + lid1 * 0.01f;
-}
diff --git a/test/opencl/examples/openclinaction/ch05/mad-test.cl b/test/opencl/examples/openclinaction/ch05/mad-test.cl
deleted file mode 100644
index 645a6af..0000000
--- a/test/opencl/examples/openclinaction/ch05/mad-test.cl
+++ /dev/null
@@ -1,7 +0,0 @@
-__kernel void mad_test (__global uint *result) {
- uint a = 0x123456;
- uint b = 0x112233;
- uint c = 0x111111;
- result[0] = mad24(a, b, c);
- result[1] = mad_hi(a, b, c);
-}
diff --git a/test/opencl/examples/openclinaction/ch05/mod-round.cl b/test/opencl/examples/openclinaction/ch05/mod-round.cl
deleted file mode 100644
index 275153e..0000000
--- a/test/opencl/examples/openclinaction/ch05/mod-round.cl
+++ /dev/null
@@ -1,13 +0,0 @@
-__kernel void mod_round (__global float *mod_input,
- __global float *mod_output,
- __global float4 *round_input,
- __global float4 *round_output) {
- mod_output[0] = fmod(mod_input[0], mod_input[1]);
- mod_output[1] = remainder(mod_input[0], mod_input[1]);
-
- round_output[0] = rint(*round_input);
- round_output[1] = round(*round_input);
- round_output[2] = ceil(*round_input);
- round_output[3] = floor(*round_input);
- round_output[4] = trunc(*round_input);
-}
diff --git a/test/opencl/examples/openclinaction/ch05/op-test.cl b/test/opencl/examples/openclinaction/ch05/op-test.cl
deleted file mode 100644
index 6220e96..0000000
--- a/test/opencl/examples/openclinaction/ch05/op-test.cl
+++ /dev/null
@@ -1,12 +0,0 @@
-__kernel void op_test(__global int4 *output) {
-
- int4 vec = (int4) (1, 2, 3, 4);
- vec += 4;
- if (vec.s2 == 7)
- vec &= (int4)(-1, -1, 0, -1);
- vec.s01 = vec.s23 < 7;
- while (vec.s3 > 7 && (vec.s0 < 16 || vec.s1 < 16))
- vec.s3 >>= 1;
-
- *output = vec;
-}
diff --git a/test/opencl/examples/openclinaction/ch05/polar-rect.cl b/test/opencl/examples/openclinaction/ch05/polar-rect.cl
deleted file mode 100644
index 063309b..0000000
--- a/test/opencl/examples/openclinaction/ch05/polar-rect.cl
+++ /dev/null
@@ -1,8 +0,0 @@
-__kernel void polar_rect (__global float4 *rvals,
- __global float4 *angles,
- __global float4 *xcoords,
- __global float4 *ycoords) {
- *ycoords = sincos(*angles, xcoords);
- *xcoords *= *rvals;
- *ycoords *= *rvals;
-}
diff --git a/test/opencl/examples/openclinaction/ch05/select-test.cl b/test/opencl/examples/openclinaction/ch05/select-test.cl
deleted file mode 100644
index 74ad33b..0000000
--- a/test/opencl/examples/openclinaction/ch05/select-test.cl
+++ /dev/null
@@ -1,12 +0,0 @@
-__kernel void select_test (__global float4 *s1,
- __global uchar2 *s2) {
- int4 mask1 = (int4)(-1, 0, -1, 0);
- float4 input1 = (float4)(0.25f, 0.5f, 0.75f, 1.0f);
- float4 input2 = (float4)(1.25f, 1.5f, 1.75f, 2.0f);
- *s1 = select(input1, input2, mask1);
-
- uchar2 mask2 = (uchar2)(0xAA, 0x55);
- uchar2 input3 = (uchar2)(0x0F, 0x0F);
- uchar2 input4 = (uchar2)(0x33, 0x33);
- *s2 = bitselect(input3, input4, mask2);
-}
diff --git a/test/opencl/examples/openclinaction/ch05/shuffle-test.cl b/test/opencl/examples/openclinaction/ch05/shuffle-test.cl
deleted file mode 100644
index 593c9fb..0000000
--- a/test/opencl/examples/openclinaction/ch05/shuffle-test.cl
+++ /dev/null
@@ -1,14 +0,0 @@
-__kernel void shuffle_test (__global float8 *s1,
- __global char16 *s2) {
-
- uint8 mask1 = (uint8) (1, 2, 0, 1, 3, 1, 2, 3);
- float4 input = (float4) (0.25f, 0.5f, 0.75f, 1.0f);
- *s1 = shuffle(input, mask1);
-
- uchar16 mask2 = (uchar16) (6, 10, 5, 2, 8, 0, 9, 14,
- 7, 5, 12, 3, 11, 15, 1, 13);
- char8 input1 = (char8)('l', 'o', 'f', 'c', 'a', 'u', 's', 'f');
- char8 input2 = (char8)('f', 'e', 'h', 't', 'n', 'n', '2', 'i');
- *s2 = shuffle2(input1, input2, mask2);
-
-}
diff --git a/test/opencl/examples/openclinaction/ch07/profile-items.cl b/test/opencl/examples/openclinaction/ch07/profile-items.cl
deleted file mode 100644
index 84b7bf2..0000000
--- a/test/opencl/examples/openclinaction/ch07/profile-items.cl
+++ /dev/null
@@ -1,10 +0,0 @@
-__kernel void profile_items (__global int4 *x, int num_ints) {
-
- int num_vectors = num_ints/(4 * get_global_size(0));
- x += get_global_id(0) * num_vectors;
- for (int i = 0; i < num_vectors; i++){
- x[i] += 1;
- x[i] *= 2;
- x[i] /= 3;
- }
-}
diff --git a/test/opencl/examples/openclinaction/ch07/profile-read.cl b/test/opencl/examples/openclinaction/ch07/profile-read.cl
deleted file mode 100644
index 8787331..0000000
--- a/test/opencl/examples/openclinaction/ch07/profile-read.cl
+++ /dev/null
@@ -1,8 +0,0 @@
-__kernel void profile_read (__global char16 *c,
- int num) {
-
- for (int i=0; i < num; i++) {
- c[i] = (char16)(5);
- }
-
-}
diff --git a/test/opencl/examples/openclinaction/ch07/user-event.cl b/test/opencl/examples/openclinaction/ch07/user-event.cl
deleted file mode 100644
index f24e620..0000000
--- a/test/opencl/examples/openclinaction/ch07/user-event.cl
+++ /dev/null
@@ -1,4 +0,0 @@
-__kernel void user_event(__global float4 *v) {
-
- *v *= -1.0f;
-}
diff --git a/test/opencl/examples/openclinaction/ch10/reduction.cl b/test/opencl/examples/openclinaction/ch10/reduction.cl
deleted file mode 100644
index a8d9b34..0000000
--- a/test/opencl/examples/openclinaction/ch10/reduction.cl
+++ /dev/null
@@ -1,54 +0,0 @@
-__kernel void naive_reduction(__global float* data, __global float* output) {
- float sum = 0.0;
- if (get_global_id(0) == 0) {
- for (int i = 0; i < 1048576; i++) {
- sum += data[i];
- }
- }
- *output = sum;
-}
-
-__kernel void reduction_scalar(__global float* data,
- __local float* partial_sums,
- __global float* output) {
-
-
- int lid = get_local_id(0);
- int gsize = get_local_size(0);
-
- partial_sums[lid] = data[get_global_id(0)];
- barrier(CLK_LOCAL_MEM_FENCE);
-
- for (int i = gsize/2; i > 0; i >>= 1) {
- if (lid < i) {
- partial_sums[lid] += partial_sums[lid + i];
- }
- barrier(CLK_LOCAL_MEM_FENCE);
- }
-
- if(lid == 0) {
- output[get_group_id(0)] = partial_sums[0];
- }
-}
-
-__kernel void reduction_vector(__global float4* data,
- __local float4* partial_sums,
- __global float* output) {
-
- int lid = get_local_id(0);
- int group_size = get_local_size(0);
-
- partial_sums[lid] = data[get_global_id(0)];
- barrier(CLK_LOCAL_MEM_FENCE);
-
- for(int i = group_size/2; i>0; i >>= 1) {
- if(lid < i) {
- partial_sums[lid] += partial_sums[lid + i];
- }
- barrier(CLK_LOCAL_MEM_FENCE);
- }
-
- if(lid == 0) {
- output[get_group_id(0)] = dot (partial_sums[0], (float4)(1.0f));
- }
-}
diff --git a/test/opencl/examples/openclinaction/ch11/kafka.txt b/test/opencl/examples/openclinaction/ch11/kafka.txt
deleted file mode 100644
index d0e2cc4..0000000
--- a/test/opencl/examples/openclinaction/ch11/kafka.txt
+++ /dev/null
@@ -1,1946 +0,0 @@
-One morning, when Gregor Samsa woke from troubled dreams, he found
-himself transformed in his bed into a horrible vermin. He lay on
-his armour-like back, and if he lifted his head a little he could
-see his brown belly, slightly domed and divided by arches into stiff
-sections. The bedding was hardly able to cover it and seemed ready
-to slide off any moment. His many legs, pitifully thin compared
-with the size of the rest of him, waved about helplessly as he
-looked.
-
-"What's happened to me?" he thought. It wasn't a dream. His room,
-a proper human room although a little too small, lay peacefully
-between its four familiar walls. A collection of textile samples
-lay spread out on the table - Samsa was a travelling salesman - and
-above it there hung a picture that he had recently cut out of an
-illustrated magazine and housed in a nice, gilded frame. It showed
-a lady fitted out with a fur hat and fur boa who sat upright,
-raising a heavy fur muff that covered the whole of her lower arm
-towards the viewer.
-
-Gregor then turned to look out the window at the dull weather.
-Drops of rain could be heard hitting the pane, which made him feel
-quite sad. "How about if I sleep a little bit longer and forget all
-this nonsense", he thought, but that was something he was unable to
-do because he was used to sleeping on his right, and in his present
-state couldn't get into that position. However hard he threw
-himself onto his right, he always rolled back to where he was. He
-must have tried it a hundred times, shut his eyes so that he
-wouldn't have to look at the floundering legs, and only stopped when
-he began to feel a mild, dull pain there that he had never felt
-before.
-
-"Oh, God", he thought, "what a strenuous career it is that I've
-chosen! Travelling day in and day out. Doing business like this
-takes much more effort than doing your own business at home, and on
-top of that there's the curse of travelling, worries about making
-train connections, bad and irregular food, contact with different
-people all the time so that you can never get to know anyone or
-become friendly with them. It can all go to Hell!" He felt a
-slight itch up on his belly; pushed himself slowly up on his back
-towards the headboard so that he could lift his head better; found
-where the itch was, and saw that it was covered with lots of little
-white spots which he didn't know what to make of; and when he tried
-to feel the place with one of his legs he drew it quickly back
-because as soon as he touched it he was overcome by a cold shudder.
-
-He slid back into his former position. "Getting up early all the
-time", he thought, "it makes you stupid. You've got to get enough
-sleep. Other travelling salesmen live a life of luxury. For
-instance, whenever I go back to the guest house during the morning
-to copy out the contract, these gentlemen are always still sitting
-there eating their breakfasts. I ought to just try that with my
-boss; I'd get kicked out on the spot. But who knows, maybe that
-would be the best thing for me. If I didn't have my parents to
-think about I'd have given in my notice a long time ago, I'd have
-gone up to the boss and told him just what I think, tell him
-everything I would, let him know just what I feel. He'd fall right
-off his desk! And it's a funny sort of business to be sitting up
-there at your desk, talking down at your subordinates from up there,
-especially when you have to go right up close because the boss is
-hard of hearing. Well, there's still some hope; once I've got the
-money together to pay off my parents' debt to him - another five or
-six years I suppose - that's definitely what I'll do. That's when
-I'll make the big change. First of all though, I've got to get up,
-my train leaves at five."
-
-And he looked over at the alarm clock, ticking on the chest of
-drawers. "God in Heaven!" he thought. It was half past six and the
-hands were quietly moving forwards, it was even later than half
-past, more like quarter to seven. Had the alarm clock not rung? He
-could see from the bed that it had been set for four o'clock as it
-should have been; it certainly must have rung. Yes, but was it
-possible to quietly sleep through that furniture-rattling noise?
-True, he had not slept peacefully, but probably all the more deeply
-because of that. What should he do now? The next train went at
-seven; if he were to catch that he would have to rush like mad and
-the collection of samples was still not packed, and he did not at
-all feel particularly fresh and lively. And even if he did catch
-the train he would not avoid his boss's anger as the office
-assistant would have been there to see the five o'clock train go, he
-would have put in his report about Gregor's not being there a long
-time ago. The office assistant was the boss's man, spineless, and
-with no understanding. What about if he reported sick? But that
-would be extremely strained and suspicious as in fifteen years of
-service Gregor had never once yet been ill. His boss would
-certainly come round with the doctor from the medical insurance
-company, accuse his parents of having a lazy son, and accept the
-doctor's recommendation not to make any claim as the doctor believed
-that no-one was ever ill but that many were workshy. And what's
-more, would he have been entirely wrong in this case? Gregor did in
-fact, apart from excessive sleepiness after sleeping for so long,
-feel completely well and even felt much hungrier than usual.
-
-He was still hurriedly thinking all this through, unable to decide
-to get out of the bed, when the clock struck quarter to seven.
-There was a cautious knock at the door near his head. "Gregor",
-somebody called - it was his mother - "it's quarter to seven.
-Didn't you want to go somewhere?" That gentle voice! Gregor was
-shocked when he heard his own voice answering, it could hardly be
-recognised as the voice he had had before. As if from deep inside
-him, there was a painful and uncontrollable squeaking mixed in with
-it, the words could be made out at first but then there was a sort
-of echo which made them unclear, leaving the hearer unsure whether
-he had heard properly or not. Gregor had wanted to give a full
-answer and explain everything, but in the circumstances contented
-himself with saying: "Yes, mother, yes, thank-you, I'm getting up
-now." The change in Gregor's voice probably could not be noticed
-outside through the wooden door, as his mother was satisfied with
-this explanation and shuffled away. But this short conversation
-made the other members of the family aware that Gregor, against
-their expectations was still at home, and soon his father came
-knocking at one of the side doors, gently, but with his fist.
-"Gregor, Gregor", he called, "what's wrong?" And after a short
-while he called again with a warning deepness in his voice: "Gregor!
-Gregor!" At the other side door his sister came plaintively:
-"Gregor? Aren't you well? Do you need anything?" Gregor answered to
-both sides: "I'm ready, now", making an effort to remove all the
-strangeness from his voice by enunciating very carefully and putting
-long pauses between each, individual word. His father went back to
-his breakfast, but his sister whispered: "Gregor, open the door, I
-beg of you." Gregor, however, had no thought of opening the door,
-and instead congratulated himself for his cautious habit, acquired
-from his travelling, of locking all doors at night even when he was
-at home.
-
-The first thing he wanted to do was to get up in peace without being
-disturbed, to get dressed, and most of all to have his breakfast.
-Only then would he consider what to do next, as he was well aware
-that he would not bring his thoughts to any sensible conclusions by
-lying in bed. He remembered that he had often felt a slight pain in
-bed, perhaps caused by lying awkwardly, but that had always turned
-out to be pure imagination and he wondered how his imaginings would
-slowly resolve themselves today. He did not have the slightest
-doubt that the change in his voice was nothing more than the first
-sign of a serious cold, which was an occupational hazard for
-travelling salesmen.
-
-It was a simple matter to throw off the covers; he only had to blow
-himself up a little and they fell off by themselves. But it became
-difficult after that, especially as he was so exceptionally broad.
-He would have used his arms and his hands to push himself up; but
-instead of them he only had all those little legs continuously
-moving in different directions, and which he was moreover unable to
-control. If he wanted to bend one of them, then that was the first
-one that would stretch itself out; and if he finally managed to do
-what he wanted with that leg, all the others seemed to be set free
-and would move about painfully. "This is something that can't be
-done in bed", Gregor said to himself, "so don't keep trying to do
-it".
-
-The first thing he wanted to do was get the lower part of his body
-out of the bed, but he had never seen this lower part, and could not
-imagine what it looked like; it turned out to be too hard to move;
-it went so slowly; and finally, almost in a frenzy, when he
-carelessly shoved himself forwards with all the force he could
-gather, he chose the wrong direction, hit hard against the lower
-bedpost, and learned from the burning pain he felt that the lower
-part of his body might well, at present, be the most sensitive.
-
-So then he tried to get the top part of his body out of the bed
-first, carefully turning his head to the side. This he managed
-quite easily, and despite its breadth and its weight, the bulk of
-his body eventually followed slowly in the direction of the head.
-But when he had at last got his head out of the bed and into the
-fresh air it occurred to him that if he let himself fall it would be
-a miracle if his head were not injured, so he became afraid to carry
-on pushing himself forward the same way. And he could not knock
-himself out now at any price; better to stay in bed than lose
-consciousness.
-
-It took just as much effort to get back to where he had been
-earlier, but when he lay there sighing, and was once more watching
-his legs as they struggled against each other even harder than
-before, if that was possible, he could think of no way of bringing
-peace and order to this chaos. He told himself once more that it
-was not possible for him to stay in bed and that the most sensible
-thing to do would be to get free of it in whatever way he could at
-whatever sacrifice. At the same time, though, he did not forget to
-remind himself that calm consideration was much better than rushing
-to desperate conclusions. At times like this he would direct his
-eyes to the window and look out as clearly as he could, but
-unfortunately, even the other side of the narrow street was
-enveloped in morning fog and the view had little confidence or cheer
-to offer him. "Seven o'clock, already", he said to himself when the
-clock struck again, "seven o'clock, and there's still a fog like
-this." And he lay there quietly a while longer, breathing lightly
-as if he perhaps expected the total stillness to bring things back
-to their real and natural state.
-
-But then he said to himself: "Before it strikes quarter past seven
-I'll definitely have to have got properly out of bed. And by then
-somebody will have come round from work to ask what's happened to me
-as well, as they open up at work before seven o'clock." And so he
-set himself to the task of swinging the entire length of his body
-out of the bed all at the same time. If he succeeded in falling out
-of bed in this way and kept his head raised as he did so he could
-probably avoid injuring it. His back seemed to be quite hard, and
-probably nothing would happen to it falling onto the carpet. His
-main concern was for the loud noise he was bound to make, and which
-even through all the doors would probably raise concern if not
-alarm. But it was something that had to be risked.
-
-When Gregor was already sticking half way out of the bed - the new
-method was more of a game than an effort, all he had to do was rock
-back and forth - it occurred to him how simple everything would be
-if somebody came to help him. Two strong people - he had his father
-and the maid in mind - would have been more than enough; they would
-only have to push their arms under the dome of his back, peel him
-away from the bed, bend down with the load and then be patient and
-careful as he swang over onto the floor, where, hopefully, the
-little legs would find a use. Should he really call for help
-though, even apart from the fact that all the doors were locked?
-Despite all the difficulty he was in, he could not suppress a smile
-at this thought.
-
-After a while he had already moved so far across that it would have
-been hard for him to keep his balance if he rocked too hard. The
-time was now ten past seven and he would have to make a final
-decision very soon. Then there was a ring at the door of the flat.
-"That'll be someone from work", he said to himself, and froze very
-still, although his little legs only became all the more lively as
-they danced around. For a moment everything remained quiet.
-"They're not opening the door", Gregor said to himself, caught in
-some nonsensical hope. But then of course, the maid's firm steps
-went to the door as ever and opened it. Gregor only needed to hear
-the visitor's first words of greeting and he knew who it was - the
-chief clerk himself. Why did Gregor have to be the only one
-condemned to work for a company where they immediately became highly
-suspicious at the slightest shortcoming? Were all employees, every
-one of them, louts, was there not one of them who was faithful and
-devoted who would go so mad with pangs of conscience that he
-couldn't get out of bed if he didn't spend at least a couple of
-hours in the morning on company business? Was it really not enough
-to let one of the trainees make enquiries - assuming enquiries were
-even necessary - did the chief clerk have to come himself, and did
-they have to show the whole, innocent family that this was so
-suspicious that only the chief clerk could be trusted to have the
-wisdom to investigate it? And more because these thoughts had made
-him upset than through any proper decision, he swang himself with
-all his force out of the bed. There was a loud thump, but it wasn't
-really a loud noise. His fall was softened a little by the carpet,
-and Gregor's back was also more elastic than he had thought, which
-made the sound muffled and not too noticeable. He had not held his
-head carefully enough, though, and hit it as he fell; annoyed and in
-pain, he turned it and rubbed it against the carpet.
-
-"Something's fallen down in there", said the chief clerk in the room
-on the left. Gregor tried to imagine whether something of the sort
-that had happened to him today could ever happen to the chief clerk
-too; you had to concede that it was possible. But as if in gruff
-reply to this question, the chief clerk's firm footsteps in his
-highly polished boots could now be heard in the adjoining room.
-From the room on his right, Gregor's sister whispered to him to let
-him know: "Gregor, the chief clerk is here." "Yes, I know", said
-Gregor to himself; but without daring to raise his voice loud enough
-for his sister to hear him.
-
-"Gregor", said his father now from the room to his left, "the chief
-clerk has come round and wants to know why you didn't leave on the
-early train. We don't know what to say to him. And anyway, he
-wants to speak to you personally. So please open up this door. I'm
-sure he'll be good enough to forgive the untidiness of your room."
-Then the chief clerk called "Good morning, Mr. Samsa". "He isn't
-well", said his mother to the chief clerk, while his father
-continued to speak through the door. "He isn't well, please believe
-me. Why else would Gregor have missed a train! The lad only ever
-thinks about the business. It nearly makes me cross the way he
-never goes out in the evenings; he's been in town for a week now but
-stayed home every evening. He sits with us in the kitchen and just
-reads the paper or studies train timetables. His idea of relaxation
-is working with his fretsaw. He's made a little frame, for
-instance, it only took him two or three evenings, you'll be amazed
-how nice it is; it's hanging up in his room; you'll see it as soon
-as Gregor opens the door. Anyway, I'm glad you're here; we wouldn't
-have been able to get Gregor to open the door by ourselves; he's so
-stubborn; and I'm sure he isn't well, he said this morning that he
-is, but he isn't." "I'll be there in a moment", said Gregor slowly
-and thoughtfully, but without moving so that he would not miss any
-word of the conversation. "Well I can't think of any other way of
-explaining it, Mrs. Samsa", said the chief clerk, "I hope it's
-nothing serious. But on the other hand, I must say that if we
-people in commerce ever become slightly unwell then, fortunately or
-unfortunately as you like, we simply have to overcome it because of
-business considerations." "Can the chief clerk come in to see you
-now then?", asked his father impatiently, knocking at the door
-again. "No", said Gregor. In the room on his right there followed
-a painful silence; in the room on his left his sister began to cry.
-
-So why did his sister not go and join the others? She had probably
-only just got up and had not even begun to get dressed. And why was
-she crying? Was it because he had not got up, and had not let the
-chief clerk in, because he was in danger of losing his job and if
-that happened his boss would once more pursue their parents with the
-same demands as before? There was no need to worry about things like
-that yet. Gregor was still there and had not the slightest
-intention of abandoning his family. For the time being he just lay
-there on the carpet, and no-one who knew the condition he was in
-would seriously have expected him to let the chief clerk in. It was
-only a minor discourtesy, and a suitable excuse could easily be
-found for it later on, it was not something for which Gregor could
-be sacked on the spot. And it seemed to Gregor much more sensible
-to leave him now in peace instead of disturbing him with talking at
-him and crying. But the others didn't know what was happening, they
-were worried, that would excuse their behaviour.
-
-The chief clerk now raised his voice, "Mr. Samsa", he called to him,
-"what is wrong? You barricade yourself in your room, give us no more
-than yes or no for an answer, you are causing serious and
-unnecessary concern to your parents and you fail - and I mention
-this just by the way - you fail to carry out your business duties in
-a way that is quite unheard of. I'm speaking here on behalf of your
-parents and of your employer, and really must request a clear and
-immediate explanation. I am astonished, quite astonished. I
-thought I knew you as a calm and sensible person, and now you
-suddenly seem to be showing off with peculiar whims. This morning,
-your employer did suggest a possible reason for your failure to
-appear, it's true - it had to do with the money that was recently
-entrusted to you - but I came near to giving him my word of honour
-that that could not be the right explanation. But now that I see
-your incomprehensible stubbornness I no longer feel any wish
-whatsoever to intercede on your behalf. And nor is your position
-all that secure. I had originally intended to say all this to you
-in private, but since you cause me to waste my time here for no good
-reason I don't see why your parents should not also learn of it.
-Your turnover has been very unsatisfactory of late; I grant you that
-it's not the time of year to do especially good business, we
-recognise that; but there simply is no time of year to do no
-business at all, Mr. Samsa, we cannot allow there to be."
-
-"But Sir", called Gregor, beside himself and forgetting all else in
-the excitement, "I'll open up immediately, just a moment. I'm
-slightly unwell, an attack of dizziness, I haven't been able to get
-up. I'm still in bed now. I'm quite fresh again now, though. I'm
-just getting out of bed. Just a moment. Be patient! It's not quite
-as easy as I'd thought. I'm quite alright now, though. It's
-shocking, what can suddenly happen to a person! I was quite alright
-last night, my parents know about it, perhaps better than me, I had
-a small symptom of it last night already. They must have noticed
-it. I don't know why I didn't let you know at work! But you always
-think you can get over an illness without staying at home. Please,
-don't make my parents suffer! There's no basis for any of the
-accusations you're making; nobody's ever said a word to me about any
-of these things. Maybe you haven't read the latest contracts I sent
-in. I'll set off with the eight o'clock train, as well, these few
-hours of rest have given me strength. You don't need to wait, sir;
-I'll be in the office soon after you, and please be so good as to
-tell that to the boss and recommend me to him!"
-
-And while Gregor gushed out these words, hardly knowing what he was
-saying, he made his way over to the chest of drawers - this was
-easily done, probably because of the practise he had already had in
-bed - where he now tried to get himself upright. He really did want
-to open the door, really did want to let them see him and to speak
-with the chief clerk; the others were being so insistent, and he was
-curious to learn what they would say when they caught sight of him.
-If they were shocked then it would no longer be Gregor's
-responsibility and he could rest. If, however, they took everything
-calmly he would still have no reason to be upset, and if he hurried
-he really could be at the station for eight o'clock. The first few
-times he tried to climb up on the smooth chest of drawers he just
-slid down again, but he finally gave himself one last swing and
-stood there upright; the lower part of his body was in serious pain
-but he no longer gave any attention to it. Now he let himself fall
-against the back of a nearby chair and held tightly to the edges of
-it with his little legs. By now he had also calmed down, and kept
-quiet so that he could listen to what the chief clerk was saying.
-
-"Did you understand a word of all that?" the chief clerk asked his
-parents, "surely he's not trying to make fools of us". "Oh, God!"
-called his mother, who was already in tears, "he could be seriously
-ill and we're making him suffer. Grete! Grete!" she then cried.
-"Mother?" his sister called from the other side. They communicated
-across Gregor's room. "You'll have to go for the doctor straight
-away. Gregor is ill. Quick, get the doctor. Did you hear the way
-Gregor spoke just now?" "That was the voice of an animal", said the
-chief clerk, with a calmness that was in contrast with his mother's
-screams. "Anna! Anna!" his father called into the kitchen through
-the entrance hall, clapping his hands, "get a locksmith here, now!"
-And the two girls, their skirts swishing, immediately ran out
-through the hall, wrenching open the front door of the flat as they
-went. How had his sister managed to get dressed so quickly? There
-was no sound of the door banging shut again; they must have left it
-open; people often do in homes where something awful has happened.
-
-Gregor, in contrast, had become much calmer. So they couldn't
-understand his words any more, although they seemed clear enough to
-him, clearer than before - perhaps his ears had become used to the
-sound. They had realised, though, that there was something wrong
-with him, and were ready to help. The first response to his
-situation had been confident and wise, and that made him feel
-better. He felt that he had been drawn back in among people, and
-from the doctor and the locksmith he expected great and surprising
-achievements - although he did not really distinguish one from the
-other. Whatever was said next would be crucial, so, in order to
-make his voice as clear as possible, he coughed a little, but taking
-care to do this not too loudly as even this might well sound
-different from the way that a human coughs and he was no longer sure
-he could judge this for himself. Meanwhile, it had become very
-quiet in the next room. Perhaps his parents were sat at the table
-whispering with the chief clerk, or perhaps they were all pressed
-against the door and listening.
-
-Gregor slowly pushed his way over to the door with the chair. Once
-there he let go of it and threw himself onto the door, holding
-himself upright against it using the adhesive on the tips of his
-legs. He rested there a little while to recover from the effort
-involved and then set himself to the task of turning the key in the
-lock with his mouth. He seemed, unfortunately, to have no proper
-teeth - how was he, then, to grasp the key? - but the lack of teeth
-was, of course, made up for with a very strong jaw; using the jaw,
-he really was able to start the key turning, ignoring the fact that
-he must have been causing some kind of damage as a brown fluid came
-from his mouth, flowed over the key and dripped onto the floor.
-"Listen", said the chief clerk in the next room, "he's turning the
-key." Gregor was greatly encouraged by this; but they all should
-have been calling to him, his father and his mother too: "Well done,
-Gregor", they should have cried, "keep at it, keep hold of the
-lock!" And with the idea that they were all excitedly following his
-efforts, he bit on the key with all his strength, paying no
-attention to the pain he was causing himself. As the key turned
-round he turned around the lock with it, only holding himself
-upright with his mouth, and hung onto the key or pushed it down
-again with the whole weight of his body as needed. The clear sound
-of the lock as it snapped back was Gregor's sign that he could break
-his concentration, and as he regained his breath he said to himself:
-"So, I didn't need the locksmith after all". Then he lay his head on
-the handle of the door to open it completely.
-
-Because he had to open the door in this way, it was already wide
-open before he could be seen. He had first to slowly turn himself
-around one of the double doors, and he had to do it very carefully
-if he did not want to fall flat on his back before entering the
-room. He was still occupied with this difficult movement, unable to
-pay attention to anything else, when he heard the chief clerk
-exclaim a loud "Oh!", which sounded like the soughing of the wind.
-Now he also saw him - he was the nearest to the door - his hand
-pressed against his open mouth and slowly retreating as if driven by
-a steady and invisible force. Gregor's mother, her hair still
-dishevelled from bed despite the chief clerk's being there, looked
-at his father. Then she unfolded her arms, took two steps forward
-towards Gregor and sank down onto the floor into her skirts that
-spread themselves out around her as her head disappeared down onto
-her breast. His father looked hostile, and clenched his fists as if
-wanting to knock Gregor back into his room. Then he looked
-uncertainly round the living room, covered his eyes with his hands
-and wept so that his powerful chest shook.
-
-So Gregor did not go into the room, but leant against the inside of
-the other door which was still held bolted in place. In this way
-only half of his body could be seen, along with his head above it
-which he leant over to one side as he peered out at the others.
-Meanwhile the day had become much lighter; part of the endless,
-grey-black building on the other side of the street - which was a
-hospital - could be seen quite clearly with the austere and regular
-line of windows piercing its facade; the rain was still
-falling, now throwing down large, individual droplets which hit the
-ground one at a time. The washing up from breakfast lay on the
-table; there was so much of it because, for Gregor's father,
-breakfast was the most important meal of the day and he would
-stretch it out for several hours as he sat reading a number of
-different newspapers. On the wall exactly opposite there was
-photograph of Gregor when he was a lieutenant in the army, his sword
-in his hand and a carefree smile on his face as he called forth
-respect for his uniform and bearing. The door to the entrance hall
-was open and as the front door of the flat was also open he could
-see onto the landing and the stairs where they began their way down
-below.
-
-"Now, then", said Gregor, well aware that he was the only one to
-have kept calm, "I'll get dressed straight away now, pack up my
-samples and set off. Will you please just let me leave? You can
-see", he said to the chief clerk, "that I'm not stubborn and like I
-like to do my job; being a commercial traveller is arduous but
-without travelling I couldn't earn my living. So where are you
-going, in to the office? Yes? Will you report everything accurately,
-then? It's quite possible for someone to be temporarily unable to
-work, but that's just the right time to remember what's been
-achieved in the past and consider that later on, once the difficulty
-has been removed, he will certainly work with all the more diligence
-and concentration. You're well aware that I'm seriously in debt to
-our employer as well as having to look after my parents and my
-sister, so that I'm trapped in a difficult situation, but I will
-work my way out of it again. Please don't make things any harder
-for me than they are already, and don't take sides against me at the
-office. I know that nobody likes the travellers. They think we
-earn an enormous wage as well as having a soft time of it. That's
-just prejudice but they have no particular reason to think better
-it. But you, sir, you have a better overview than the rest of the
-staff, in fact, if I can say this in confidence, a better overview
-than the boss himself - it's very easy for a businessman like him to
-make mistakes about his employees and judge them more harshly than
-he should. And you're also well aware that we travellers spend
-almost the whole year away from the office, so that we can very
-easily fall victim to gossip and chance and groundless complaints,
-and it's almost impossible to defend yourself from that sort of
-thing, we don't usually even hear about them, or if at all it's when
-we arrive back home exhausted from a trip, and that's when we feel
-the harmful effects of what's been going on without even knowing
-what caused them. Please, don't go away, at least first say
-something to show that you grant that I'm at least partly right!"
-
-But the chief clerk had turned away as soon as Gregor had started to
-speak, and, with protruding lips, only stared back at him over his
-trembling shoulders as he left. He did not keep still for a moment
-while Gregor was speaking, but moved steadily towards the door
-without taking his eyes off him. He moved very gradually, as if
-there had been some secret prohibition on leaving the room. It was
-only when he had reached the entrance hall that he made a sudden
-movement, drew his foot from the living room, and rushed forward in
-a panic. In the hall, he stretched his right hand far out towards
-the stairway as if out there, there were some supernatural force
-waiting to save him.
-
-Gregor realised that it was out of the question to let the chief
-clerk go away in this mood if his position in the firm was not to be
-put into extreme danger. That was something his parents did not
-understand very well; over the years, they had become convinced that
-this job would provide for Gregor for his entire life, and besides,
-they had so much to worry about at present that they had lost sight
-of any thought for the future. Gregor, though, did think about the
-future. The chief clerk had to be held back, calmed down, convinced
-and finally won over; the future of Gregor and his family depended
-on it! If only his sister were here! She was clever; she was already
-in tears while Gregor was still lying peacefully on his back. And
-the chief clerk was a lover of women, surely she could persuade him;
-she would close the front door in the entrance hall and talk him out
-of his shocked state. But his sister was not there, Gregor would
-have to do the job himself. And without considering that he still
-was not familiar with how well he could move about in his present
-state, or that his speech still might not - or probably would not -
-be understood, he let go of the door; pushed himself through the
-opening; tried to reach the chief clerk on the landing who,
-ridiculously, was holding on to the banister with both hands; but
-Gregor fell immediately over and, with a little scream as he sought
-something to hold onto, landed on his numerous little legs. Hardly
-had that happened than, for the first time that day, he began to
-feel alright with his body; the little legs had the solid ground
-under them; to his pleasure, they did exactly as he told them; they
-were even making the effort to carry him where he wanted to go; and
-he was soon believing that all his sorrows would soon be finally at
-an end. He held back the urge to move but swayed from side to side
-as he crouched there on the floor. His mother was not far away in
-front of him and seemed, at first, quite engrossed in herself, but
-then she suddenly jumped up with her arms outstretched and her
-fingers spread shouting: "Help, for pity's sake, Help!" The way she
-held her head suggested she wanted to see Gregor better, but the
-unthinking way she was hurrying backwards showed that she did not;
-she had forgotten that the table was behind her with all the
-breakfast things on it; when she reached the table she sat quickly
-down on it without knowing what she was doing; without even seeming
-to notice that the coffee pot had been knocked over and a gush of
-coffee was pouring down onto the carpet.
-
-"Mother, mother", said Gregor gently, looking up at her. He had
-completely forgotten the chief clerk for the moment, but could not
-help himself snapping in the air with his jaws at the sight of the
-flow of coffee. That set his mother screaming anew, she fled from
-the table and into the arms of his father as he rushed towards her.
-Gregor, though, had no time to spare for his parents now; the chief
-clerk had already reached the stairs; with his chin on the banister,
-he looked back for the last time. Gregor made a run for him; he
-wanted to be sure of reaching him; the chief clerk must have
-expected something, as he leapt down several steps at once and
-disappeared; his shouts resounding all around the staircase. The
-flight of the chief clerk seemed, unfortunately, to put Gregor's
-father into a panic as well. Until then he had been relatively self
-controlled, but now, instead of running after the chief clerk
-himself, or at least not impeding Gregor as he ran after him,
-Gregor's father seized the chief clerk's stick in his right hand
-(the chief clerk had left it behind on a chair, along with his hat
-and overcoat), picked up a large newspaper from the table with his
-left, and used them to drive Gregor back into his room, stamping his
-foot at him as he went. Gregor's appeals to his father were of no
-help, his appeals were simply not understood, however much he humbly
-turned his head his father merely stamped his foot all the harder.
-Across the room, despite the chilly weather, Gregor's mother had
-pulled open a window, leant far out of it and pressed her hands to
-her face. A strong draught of air flew in from the street towards
-the stairway, the curtains flew up, the newspapers on the table
-fluttered and some of them were blown onto the floor. Nothing would
-stop Gregor's father as he drove him back, making hissing noises at
-him like a wild man. Gregor had never had any practice in moving
-backwards and was only able to go very slowly. If Gregor had only
-been allowed to turn round he would have been back in his room
-straight away, but he was afraid that if he took the time to do that
-his father would become impatient, and there was the threat of a
-lethal blow to his back or head from the stick in his father's hand
-any moment. Eventually, though, Gregor realised that he had no
-choice as he saw, to his disgust, that he was quite incapable of
-going backwards in a straight line; so he began, as quickly as
-possible and with frequent anxious glances at his father, to turn
-himself round. It went very slowly, but perhaps his father was able
-to see his good intentions as he did nothing to hinder him, in fact
-now and then he used the tip of his stick to give directions from a
-distance as to which way to turn. If only his father would stop
-that unbearable hissing! It was making Gregor quite confused. When
-he had nearly finished turning round, still listening to that
-hissing, he made a mistake and turned himself back a little the way
-he had just come. He was pleased when he finally had his head in
-front of the doorway, but then saw that it was too narrow, and his
-body was too broad to get through it without further difficulty. In
-his present mood, it obviously did not occur to his father to open
-the other of the double doors so that Gregor would have enough space
-to get through. He was merely fixed on the idea that Gregor should
-be got back into his room as quickly as possible. Nor would he ever
-have allowed Gregor the time to get himself upright as preparation
-for getting through the doorway. What he did, making more noise
-than ever, was to drive Gregor forwards all the harder as if there
-had been nothing in the way; it sounded to Gregor as if there was
-now more than one father behind him; it was not a pleasant
-experience, and Gregor pushed himself into the doorway without
-regard for what might happen. One side of his body lifted itself,
-he lay at an angle in the doorway, one flank scraped on the white
-door and was painfully injured, leaving vile brown flecks on it,
-soon he was stuck fast and would not have been able to move at all
-by himself, the little legs along one side hung quivering in the air
-while those on the other side were pressed painfully against the
-ground. Then his father gave him a hefty shove from behind which
-released him from where he was held and sent him flying, and heavily
-bleeding, deep into his room. The door was slammed shut with the
-stick, then, finally, all was quiet.
-
-
-
-II
-
-
-It was not until it was getting dark that evening that Gregor awoke
-from his deep and coma-like sleep. He would have woken soon
-afterwards anyway even if he hadn't been disturbed, as he had had
-enough sleep and felt fully rested. But he had the impression that
-some hurried steps and the sound of the door leading into the front
-room being carefully shut had woken him. The light from the
-electric street lamps shone palely here and there onto the ceiling
-and tops of the furniture, but down below, where Gregor was, it was
-dark. He pushed himself over to the door, feeling his way clumsily
-with his antennae - of which he was now beginning to learn the value
-- in order to see what had been happening there. The whole of his
-left side seemed like one, painfully stretched scar, and he limped
-badly on his two rows of legs. One of the legs had been badly
-injured in the events of that morning - it was nearly a miracle that
-only one of them had been - and dragged along lifelessly.
-
-It was only when he had reached the door that he realised what it
-actually was that had drawn him over to it; it was the smell of
-something to eat. By the door there was a dish filled with
-sweetened milk with little pieces of white bread floating in it. He
-was so pleased he almost laughed, as he was even hungrier than he
-had been that morning, and immediately dipped his head into the
-milk, nearly covering his eyes with it. But he soon drew his head
-back again in disappointment; not only did the pain in his tender
-left side make it difficult to eat the food - he was only able to
-eat if his whole body worked together as a snuffling whole - but the
-milk did not taste at all nice. Milk like this was normally his
-favourite drink, and his sister had certainly left it there for him
-because of that, but he turned, almost against his own will, away
-from the dish and crawled back into the centre of the room.
-
-Through the crack in the door, Gregor could see that the gas had
-been lit in the living room. His father at this time would normally
-be sat with his evening paper, reading it out in a loud voice to
-Gregor's mother, and sometimes to his sister, but there was now not
-a sound to be heard. Gregor's sister would often write and tell him
-about this reading, but maybe his father had lost the habit in
-recent times. It was so quiet all around too, even though there
-must have been somebody in the flat. "What a quiet life it is the
-family lead", said Gregor to himself, and, gazing into the darkness,
-felt a great pride that he was able to provide a life like that in
-such a nice home for his sister and parents. But what now, if all
-this peace and wealth and comfort should come to a horrible and
-frightening end? That was something that Gregor did not want to
-think about too much, so he started to move about, crawling up and
-down the room.
-
-Once during that long evening, the door on one side of the room was
-opened very slightly and hurriedly closed again; later on the door
-on the other side did the same; it seemed that someone needed to
-enter the room but thought better of it. Gregor went and waited
-immediately by the door, resolved either to bring the timorous
-visitor into the room in some way or at least to find out who it
-was; but the door was opened no more that night and Gregor waited in
-vain. The previous morning while the doors were locked everyone had
-wanted to get in there to him, but now, now that he had opened up
-one of the doors and the other had clearly been unlocked some time
-during the day, no-one came, and the keys were in the other sides.
-
-It was not until late at night that the gaslight in the living room
-was put out, and now it was easy to see that parents and sister had
-stayed awake all that time, as they all could be distinctly heard as
-they went away together on tip-toe. It was clear that no-one would
-come into Gregor's room any more until morning; that gave him plenty
-of time to think undisturbed about how he would have to re-arrange
-his life. For some reason, the tall, empty room where he was forced
-to remain made him feel uneasy as he lay there flat on the floor,
-even though he had been living in it for five years. Hardly aware
-of what he was doing other than a slight feeling of shame, he
-hurried under the couch. It pressed down on his back a little, and
-he was no longer able to lift his head, but he nonetheless felt
-immediately at ease and his only regret was that his body was too
-broad to get it all underneath.
-
-He spent the whole night there. Some of the time he passed in a
-light sleep, although he frequently woke from it in alarm because of
-his hunger, and some of the time was spent in worries and vague
-hopes which, however, always led to the same conclusion: for the
-time being he must remain calm, he must show patience and the
-greatest consideration so that his family could bear the
-unpleasantness that he, in his present condition, was forced to
-impose on them.
-
-Gregor soon had the opportunity to test the strength of his
-decisions, as early the next morning, almost before the night had
-ended, his sister, nearly fully dressed, opened the door from the
-front room and looked anxiously in. She did not see him straight
-away, but when she did notice him under the couch - he had to be
-somewhere, for God's sake, he couldn't have flown away - she was so
-shocked that she lost control of herself and slammed the door shut
-again from outside. But she seemed to regret her behaviour, as she
-opened the door again straight away and came in on tip-toe as if
-entering the room of someone seriously ill or even of a stranger.
-Gregor had pushed his head forward, right to the edge of the couch,
-and watched her. Would she notice that he had left the milk as it
-was, realise that it was not from any lack of hunger and bring him
-in some other food that was more suitable? If she didn't do it
-herself he would rather go hungry than draw her attention to it,
-although he did feel a terrible urge to rush forward from under the
-couch, throw himself at his sister's feet and beg her for something
-good to eat. However, his sister noticed the full dish immediately
-and looked at it and the few drops of milk splashed around it with
-some surprise. She immediately picked it up - using a rag,
-not her bare hands - and carried it out. Gregor was extremely
-curious as to what she would bring in its place, imagining the
-wildest possibilities, but he never could have guessed what his
-sister, in her goodness, actually did bring. In order to test his
-taste, she brought him a whole selection of things, all spread out
-on an old newspaper. There were old, half-rotten vegetables; bones
-from the evening meal, covered in white sauce that had gone hard; a
-few raisins and almonds; some cheese that Gregor had declared
-inedible two days before; a dry roll and some bread spread with
-butter and salt. As well as all that she had poured some water into
-the dish, which had probably been permanently set aside for Gregor's
-use, and placed it beside them. Then, out of consideration for
-Gregor's feelings, as she knew that he would not eat in front of
-her, she hurried out again and even turned the key in the lock so
-that Gregor would know he could make things as comfortable for
-himself as he liked. Gregor's little legs whirred, at last he could
-eat. What's more, his injuries must already have completely healed
-as he found no difficulty in moving. This amazed him, as more than
-a month earlier he had cut his finger slightly with a knife, he
-thought of how his finger had still hurt the day before yesterday.
-"Am I less sensitive than I used to be, then?", he thought, and was
-already sucking greedily at the cheese which had immediately, almost
-compellingly, attracted him much more than the other foods on the
-newspaper. Quickly one after another, his eyes watering with
-pleasure, he consumed the cheese, the vegetables and the sauce; the
-fresh foods, on the other hand, he didn't like at all, and even
-dragged the things he did want to eat a little way away from them
-because he couldn't stand the smell. Long after he had finished
-eating and lay lethargic in the same place, his sister slowly turned
-the key in the lock as a sign to him that he should withdraw. He
-was immediately startled, although he had been half asleep, and he
-hurried back under the couch. But he needed great self-control to
-stay there even for the short time that his sister was in the room,
-as eating so much food had rounded out his body a little and he
-could hardly breathe in that narrow space. Half suffocating, he
-watched with bulging eyes as his sister unselfconsciously took a
-broom and swept up the left-overs, mixing them in with the food he
-had not even touched at all as if it could not be used any more.
-She quickly dropped it all into a bin, closed it with its wooden
-lid, and carried everything out. She had hardly turned her back
-before Gregor came out again from under the couch and stretched
-himself.
-
-This was how Gregor received his food each day now, once in the
-morning while his parents and the maid were still asleep, and the
-second time after everyone had eaten their meal at midday as his
-parents would sleep for a little while then as well, and Gregor's
-sister would send the maid away on some errand. Gregor's father and
-mother certainly did not want him to starve either, but perhaps it
-would have been more than they could stand to have any more
-experience of his feeding than being told about it, and perhaps his
-sister wanted to spare them what distress she could as they were
-indeed suffering enough.
-
-It was impossible for Gregor to find out what they had told the
-doctor and the locksmith that first morning to get them out of the
-flat. As nobody could understand him, nobody, not even his sister,
-thought that he could understand them, so he had to be content to
-hear his sister's sighs and appeals to the saints as she moved about
-his room. It was only later, when she had become a little more used
-to everything - there was, of course, no question of her ever
-becoming fully used to the situation - that Gregor would sometimes
-catch a friendly comment, or at least a comment that could be
-construed as friendly. "He's enjoyed his dinner today", she might
-say when he had diligently cleared away all the food left for him,
-or if he left most of it, which slowly became more and more
-frequent, she would often say, sadly, "now everything's just been
-left there again".
-
-Although Gregor wasn't able to hear any news directly he did listen
-to much of what was said in the next rooms, and whenever he heard
-anyone speaking he would scurry straight to the appropriate door and
-press his whole body against it. There was seldom any conversation,
-especially at first, that was not about him in some way, even if
-only in secret. For two whole days, all the talk at every mealtime
-was about what they should do now; but even between meals they spoke
-about the same subject as there were always at least two members of
-the family at home - nobody wanted to be at home by themselves and
-it was out of the question to leave the flat entirely empty. And on
-the very first day the maid had fallen to her knees and begged
-Gregor's mother to let her go without delay. It was not very clear
-how much she knew of what had happened but she left within a quarter
-of an hour, tearfully thanking Gregor's mother for her dismissal as
-if she had done her an enormous service. She even swore
-emphatically not to tell anyone the slightest about what had
-happened, even though no-one had asked that of her.
-
-Now Gregor's sister also had to help his mother with the cooking;
-although that was not so much bother as no-one ate very much.
-Gregor often heard how one of them would unsuccessfully urge another
-to eat, and receive no more answer than "no thanks, I've had enough"
-or something similar. No-one drank very much either. His sister
-would sometimes ask his father whether he would like a beer, hoping
-for the chance to go and fetch it herself. When his father then
-said nothing she would add, so that he would not feel selfish, that
-she could send the housekeeper for it, but then his father would
-close the matter with a big, loud "No", and no more would be said.
-
-Even before the first day had come to an end, his father had
-explained to Gregor's mother and sister what their finances and
-prospects were. Now and then he stood up from the table and took
-some receipt or document from the little cash box he had saved from
-his business when it had collapsed five years earlier. Gregor heard
-how he opened the complicated lock and then closed it again after he
-had taken the item he wanted. What he heard his father say was some
-of the first good news that Gregor heard since he had first been
-incarcerated in his room. He had thought that nothing at all
-remained from his father's business, at least he had never told him
-anything different, and Gregor had never asked him about it anyway.
-Their business misfortune had reduced the family to a state of total
-despair, and Gregor's only concern at that time had been to arrange
-things so that they could all forget about it as quickly as
-possible. So then he started working especially hard, with a fiery
-vigour that raised him from a junior salesman to a travelling
-representative almost overnight, bringing with it the chance to earn
-money in quite different ways. Gregor converted his success at work
-straight into cash that he could lay on the table at home for the
-benefit of his astonished and delighted family. They had been good
-times and they had never come again, at least not with the same
-splendour, even though Gregor had later earned so much that he was
-in a position to bear the costs of the whole family, and did bear
-them. They had even got used to it, both Gregor and the family,
-they took the money with gratitude and he was glad to provide it,
-although there was no longer much warm affection given in return.
-Gregor only remained close to his sister now. Unlike him, she was
-very fond of music and a gifted and expressive violinist, it was his
-secret plan to send her to the conservatory next year even though it
-would cause great expense that would have to be made up for in some
-other way. During Gregor's short periods in town, conversation with
-his sister would often turn to the conservatory but it was only ever
-mentioned as a lovely dream that could never be realised. Their
-parents did not like to hear this innocent talk, but Gregor thought
-about it quite hard and decided he would let them know what he
-planned with a grand announcement of it on Christmas day.
-
-That was the sort of totally pointless thing that went through his
-mind in his present state, pressed upright against the door and
-listening. There were times when he simply became too tired to
-continue listening, when his head would fall wearily against the
-door and he would pull it up again with a start, as even the
-slightest noise he caused would be heard next door and they would
-all go silent. "What's that he's doing now", his father would say
-after a while, clearly having gone over to the door, and only then
-would the interrupted conversation slowly be taken up again.
-
-When explaining things, his father repeated himself several times,
-partly because it was a long time since he had been occupied with
-these matters himself and partly because Gregor's mother did not
-understand everything first time. From these repeated explanations
-Gregor learned, to his pleasure, that despite all their misfortunes
-there was still some money available from the old days. It was not
-a lot, but it had not been touched in the meantime and some interest
-had accumulated. Besides that, they had not been using up all the
-money that Gregor had been bringing home every month, keeping only a
-little for himself, so that that, too, had been accumulating.
-Behind the door, Gregor nodded with enthusiasm in his pleasure at
-this unexpected thrift and caution. He could actually have used
-this surplus money to reduce his father's debt to his boss, and the
-day when he could have freed himself from that job would have come
-much closer, but now it was certainly better the way his father had
-done things.
-
-This money, however, was certainly not enough to enable the family
-to live off the interest; it was enough to maintain them for,
-perhaps, one or two years, no more. That's to say, it was money
-that should not really be touched but set aside for emergencies;
-money to live on had to be earned. His father was healthy but old,
-and lacking in self confidence. During the five years that he had
-not been working - the first holiday in a life that had been full of
-strain and no success - he had put on a lot of weight and become
-very slow and clumsy. Would Gregor's elderly mother now have to go
-and earn money? She suffered from asthma and it was a strain for her
-just to move about the home, every other day would be spent
-struggling for breath on the sofa by the open window. Would his
-sister have to go and earn money? She was still a child of
-seventeen, her life up till then had been very enviable, consisting
-of wearing nice clothes, sleeping late, helping out in the business,
-joining in with a few modest pleasures and most of all playing the
-violin. Whenever they began to talk of the need to earn money,
-Gregor would always first let go of the door and then throw himself
-onto the cool, leather sofa next to it, as he became quite hot with
-shame and regret.
-
-He would often lie there the whole night through, not sleeping a
-wink but scratching at the leather for hours on end. Or he might go
-to all the effort of pushing a chair to the window, climbing up onto
-the sill and, propped up in the chair, leaning on the window to
-stare out of it. He had used to feel a great sense of freedom from
-doing this, but doing it now was obviously something more remembered
-than experienced, as what he actually saw in this way was becoming
-less distinct every day, even things that were quite near; he had
-used to curse the ever-present view of the hospital across the
-street, but now he could not see it at all, and if he had not known
-that he lived in Charlottenstrasse, which was a quiet street despite
-being in the middle of the city, he could have thought that he was
-looking out the window at a barren waste where the grey sky and the
-grey earth mingled inseparably. His observant sister only needed to
-notice the chair twice before she would always push it back to its
-exact position by the window after she had tidied up the room, and
-even left the inner pane of the window open from then on.
-
-If Gregor had only been able to speak to his sister and thank her
-for all that she had to do for him it would have been easier for him
-to bear it; but as it was it caused him pain. His sister,
-naturally, tried as far as possible to pretend there was nothing
-burdensome about it, and the longer it went on, of course, the
-better she was able to do so, but as time went by Gregor was also
-able to see through it all so much better. It had even become very
-unpleasant for him, now, whenever she entered the room. No sooner
-had she come in than she would quickly close the door as a
-precaution so that no-one would have to suffer the view into
-Gregor's room, then she would go straight to the window and pull it
-hurriedly open almost as if she were suffocating. Even if it was
-cold, she would stay at the window breathing deeply for a little
-while. She would alarm Gregor twice a day with this running about
-and noise making; he would stay under the couch shivering the whole
-while, knowing full well that she would certainly have liked to
-spare him this ordeal, but it was impossible for her to be in the
-same room with him with the windows closed.
-
-One day, about a month after Gregor's transformation when his sister
-no longer had any particular reason to be shocked at his appearance,
-she came into the room a little earlier than usual and found him
-still staring out the window, motionless, and just where he would be
-most horrible. In itself, his sister's not coming into the room
-would have been no surprise for Gregor as it would have been
-difficult for her to immediately open the window while he was still
-there, but not only did she not come in, she went straight back and
-closed the door behind her, a stranger would have thought he had
-threatened her and tried to bite her. Gregor went straight to hide
-himself under the couch, of course, but he had to wait until midday
-before his sister came back and she seemed much more uneasy than
-usual. It made him realise that she still found his appearance
-unbearable and would continue to do so, she probably even had to
-overcome the urge to flee when she saw the little bit of him that
-protruded from under the couch. One day, in order to spare her even
-this sight, he spent four hours carrying the bedsheet over to the
-couch on his back and arranged it so that he was completely covered
-and his sister would not be able to see him even if she bent down.
-If she did not think this sheet was necessary then all she had to do
-was take it off again, as it was clear enough that it was no
-pleasure for Gregor to cut himself off so completely. She left the
-sheet where it was. Gregor even thought he glimpsed a look of
-gratitude one time when he carefully looked out from under the sheet
-to see how his sister liked the new arrangement.
-
-For the first fourteen days, Gregor's parents could not bring
-themselves to come into the room to see him. He would often hear
-them say how they appreciated all the new work his sister was doing
-even though, before, they had seen her as a girl who was somewhat
-useless and frequently been annoyed with her. But now the two of
-them, father and mother, would often both wait outside the door of
-Gregor's room while his sister tidied up in there, and as soon as
-she went out again she would have to tell them exactly how
-everything looked, what Gregor had eaten, how he had behaved this
-time and whether, perhaps, any slight improvement could be seen.
-His mother also wanted to go in and visit Gregor relatively soon but
-his father and sister at first persuaded her against it. Gregor
-listened very closely to all this, and approved fully. Later,
-though, she had to be held back by force, which made her call out:
-"Let me go and see Gregor, he is my unfortunate son! Can't you
-understand I have to see him?", and Gregor would think to himself
-that maybe it would be better if his mother came in, not every day
-of course, but one day a week, perhaps; she could understand
-everything much better than his sister who, for all her courage, was
-still just a child after all, and really might not have had an
-adult's appreciation of the burdensome job she had taken on.
-
-Gregor's wish to see his mother was soon realised. Out of
-consideration for his parents, Gregor wanted to avoid being seen at
-the window during the day, the few square meters of the floor did
-not give him much room to crawl about, it was hard to just lie
-quietly through the night, his food soon stopped giving him any
-pleasure at all, and so, to entertain himself, he got into the habit
-of crawling up and down the walls and ceiling. He was especially
-fond of hanging from the ceiling; it was quite different from lying
-on the floor; he could breathe more freely; his body had a light
-swing to it; and up there, relaxed and almost happy, it might happen
-that he would surprise even himself by letting go of the ceiling and
-landing on the floor with a crash. But now, of course, he had far
-better control of his body than before and, even with a fall as
-great as that, caused himself no damage. Very soon his sister
-noticed Gregor's new way of entertaining himself - he had, after
-all, left traces of the adhesive from his feet as he crawled about -
-and got it into her head to make it as easy as possible for him by
-removing the furniture that got in his way, especially the chest of
-drawers and the desk. Now, this was not something that she would be
-able to do by herself; she did not dare to ask for help from her
-father; the sixteen year old maid had carried on bravely since the
-cook had left but she certainly would not have helped in this, she
-had even asked to be allowed to keep the kitchen locked at all times
-and never to have to open the door unless it was especially
-important; so his sister had no choice but to choose some time when
-Gregor's father was not there and fetch his mother to help her. As
-she approached the room, Gregor could hear his mother express her
-joy, but once at the door she went silent. First, of course, his
-sister came in and looked round to see that everything in the room
-was alright; and only then did she let her mother enter. Gregor had
-hurriedly pulled the sheet down lower over the couch and put more
-folds into it so that everything really looked as if it had just
-been thrown down by chance. Gregor also refrained, this time, from
-spying out from under the sheet; he gave up the chance to see his
-mother until later and was simply glad that she had come. "You can
-come in, he can't be seen", said his sister, obviously leading her
-in by the hand. The old chest of drawers was too heavy for a pair
-of feeble women to be heaving about, but Gregor listened as they
-pushed it from its place, his sister always taking on the heaviest
-part of the work for herself and ignoring her mother's warnings that
-she would strain herself. This lasted a very long time. After
-labouring at it for fifteen minutes or more his mother said it would
-be better to leave the chest where it was, for one thing it was too
-heavy for them to get the job finished before Gregor's father got
-home and leaving it in the middle of the room it would be in his way
-even more, and for another thing it wasn't even sure that taking the
-furniture away would really be any help to him. She thought just
-the opposite; the sight of the bare walls saddened her right to her
-heart; and why wouldn't Gregor feel the same way about it, he'd been
-used to this furniture in his room for a long time and it would make
-him feel abandoned to be in an empty room like that. Then, quietly,
-almost whispering as if wanting Gregor (whose whereabouts she did
-not know) to hear not even the tone of her voice, as she was
-convinced that he did not understand her words, she added "and by
-taking the furniture away, won't it seem like we're showing that
-we've given up all hope of improvement and we're abandoning him to
-cope for himself? I think it'd be best to leave the room exactly the
-way it was before so that when Gregor comes back to us again he'll
-find everything unchanged and he'll be able to forget the time in
-between all the easier".
-
-Hearing these words from his mother made Gregor realise that the
-lack of any direct human communication, along with the monotonous
-life led by the family during these two months, must have made him
-confused - he could think of no other way of explaining to himself
-why he had seriously wanted his room emptied out. Had he really
-wanted to transform his room into a cave, a warm room fitted out
-with the nice furniture he had inherited? That would have let him
-crawl around unimpeded in any direction, but it would also have let
-him quickly forget his past when he had still been human. He had
-come very close to forgetting, and it had only been the voice of his
-mother, unheard for so long, that had shaken him out of it. Nothing
-should be removed; everything had to stay; he could not do without
-the good influence the furniture had on his condition; and if the
-furniture made it difficult for him to crawl about mindlessly that
-was not a loss but a great advantage.
-
-His sister, unfortunately, did not agree; she had become used to the
-idea, not without reason, that she was Gregor's spokesman to his
-parents about the things that concerned him. This meant that his
-mother's advice now was sufficient reason for her to insist on
-removing not only the chest of drawers and the desk, as she had
-thought at first, but all the furniture apart from the all-important
-couch. It was more than childish perversity, of course, or the
-unexpected confidence she had recently acquired, that made her
-insist; she had indeed noticed that Gregor needed a lot of room to
-crawl about in, whereas the furniture, as far as anyone could see,
-was of no use to him at all. Girls of that age, though, do become
-enthusiastic about things and feel they must get their way whenever
-they can. Perhaps this was what tempted Grete to make Gregor's
-situation seem even more shocking than it was so that she could do
-even more for him. Grete would probably be the only one who would
-dare enter a room dominated by Gregor crawling about the bare walls
-by himself.
-
-So she refused to let her mother dissuade her. Gregor's mother
-already looked uneasy in his room, she soon stopped speaking and
-helped Gregor's sister to get the chest of drawers out with what
-strength she had. The chest of drawers was something that Gregor
-could do without if he had to, but the writing desk had to stay.
-Hardly had the two women pushed the chest of drawers, groaning, out
-of the room than Gregor poked his head out from under the couch to
-see what he could do about it. He meant to be as careful and
-considerate as he could, but, unfortunately, it was his mother who
-came back first while Grete in the next room had her arms round the
-chest, pushing and pulling at it from side to side by herself
-without, of course, moving it an inch. His mother was not used to
-the sight of Gregor, he might have made her ill, so Gregor hurried
-backwards to the far end of the couch. In his startlement, though,
-he was not able to prevent the sheet at its front from moving a
-little. It was enough to attract his mother's attention. She stood
-very still, remained there a moment, and then went back out to
-Grete.
-
-Gregor kept trying to assure himself that nothing unusual was
-happening, it was just a few pieces of furniture being moved after
-all, but he soon had to admit that the women going to and fro, their
-little calls to each other, the scraping of the furniture on the
-floor, all these things made him feel as if he were being assailed
-from all sides. With his head and legs pulled in against him and
-his body pressed to the floor, he was forced to admit to himself
-that he could not stand all of this much longer. They were emptying
-his room out; taking away everything that was dear to him; they had
-already taken out the chest containing his fretsaw and other tools;
-now they threatened to remove the writing desk with its place
-clearly worn into the floor, the desk where he had done his homework
-as a business trainee, at high school, even while he had been at
-infant school - he really could not wait any longer to see whether
-the two women's intentions were good. He had nearly forgotten they
-were there anyway, as they were now too tired to say anything while
-they worked and he could only hear their feet as they stepped
-heavily on the floor.
-
-So, while the women were leant against the desk in the other room
-catching their breath, he sallied out, changed direction four times
-not knowing what he should save first before his attention was
-suddenly caught by the picture on the wall - which was already
-denuded of everything else that had been on it - of the lady dressed
-in copious fur. He hurried up onto the picture and pressed himself
-against its glass, it held him firmly and felt good on his hot
-belly. This picture at least, now totally covered by Gregor, would
-certainly be taken away by no-one. He turned his head to face the
-door into the living room so that he could watch the women when they
-came back.
-
-They had not allowed themselves a long rest and came back quite
-soon; Grete had put her arm around her mother and was nearly
-carrying her. "What shall we take now, then?", said Grete and
-looked around. Her eyes met those of Gregor on the wall. Perhaps
-only because her mother was there, she remained calm, bent her face
-to her so that she would not look round and said, albeit hurriedly
-and with a tremor in her voice: "Come on, let's go back in the
-living room for a while?" Gregor could see what Grete had in mind,
-she wanted to take her mother somewhere safe and then chase him down
-from the wall. Well, she could certainly try it! He sat unyielding
-on his picture. He would rather jump at Grete's face.
-
-But Grete's words had made her mother quite worried, she stepped to
-one side, saw the enormous brown patch against the flowers of the
-wallpaper, and before she even realised it was Gregor that she saw
-screamed: "Oh God, oh God!" Arms outstretched, she fell onto the
-couch as if she had given up everything and stayed there immobile.
-"Gregor!" shouted his sister, glowering at him and shaking her fist.
- That was the first word she had spoken to him directly since his
-transformation. She ran into the other room to fetch some kind of
-smelling salts to bring her mother out of her faint; Gregor wanted
-to help too - he could save his picture later, although he stuck
-fast to the glass and had to pull himself off by force; then he,
-too, ran into the next room as if he could advise his sister like in
-the old days; but he had to just stand behind her doing nothing; she
-was looking into various bottles, he startled her when she turned
-round; a bottle fell to the ground and broke; a splinter cut
-Gregor's face, some kind of caustic medicine splashed all over him;
-now, without delaying any longer, Grete took hold of all the bottles
-she could and ran with them in to her mother; she slammed the door
-shut with her foot. So now Gregor was shut out from his mother,
-who, because of him, might be near to death; he could not open the
-door if he did not want to chase his sister away, and she had to
-stay with his mother; there was nothing for him to do but wait; and,
-oppressed with anxiety and self-reproach, he began to crawl about,
-he crawled over everything, walls, furniture, ceiling, and finally
-in his confusion as the whole room began to spin around him he fell
-down into the middle of the dinner table.
-
-He lay there for a while, numb and immobile, all around him it was
-quiet, maybe that was a good sign. Then there was someone at the
-door. The maid, of course, had locked herself in her kitchen so
-that Grete would have to go and answer it. His father had arrived
-home. "What's happened?" were his first words; Grete's appearance
-must have made everything clear to him. She answered him with
-subdued voice, and openly pressed her face into his chest: "Mother's
-fainted, but she's better now. Gregor got out." "Just as I
-expected", said his father, "just as I always said, but you women
-wouldn't listen, would you." It was clear to Gregor that Grete had
-not said enough and that his father took it to mean that something
-bad had happened, that he was responsible for some act of violence.
-That meant Gregor would now have to try to calm his father, as he
-did not have the time to explain things to him even if that had been
-possible. So he fled to the door of his room and pressed himself
-against it so that his father, when he came in from the hall, could
-see straight away that Gregor had the best intentions and would go
-back into his room without delay, that it would not be necessary to
-drive him back but that they had only to open the door and he would
-disappear.
-
-His father, though, was not in the mood to notice subtleties like
-that; "Ah!", he shouted as he came in, sounding as if he were both
-angry and glad at the same time. Gregor drew his head back from the
-door and lifted it towards his father. He really had not imagined
-his father the way he stood there now; of late, with his new habit
-of crawling about, he had neglected to pay attention to what was
-going on the rest of the flat the way he had done before. He really
-ought to have expected things to have changed, but still, still, was
-that really his father? The same tired man as used to be laying
-there entombed in his bed when Gregor came back from his business
-trips, who would receive him sitting in the armchair in his
-nightgown when he came back in the evenings; who was hardly even
-able to stand up but, as a sign of his pleasure, would just raise
-his arms and who, on the couple of times a year when they went for a
-walk together on a Sunday or public holiday wrapped up tightly in
-his overcoat between Gregor and his mother, would always labour his
-way forward a little more slowly than them, who were already walking
-slowly for his sake; who would place his stick down carefully and,
-if he wanted to say something would invariably stop and gather his
-companions around him. He was standing up straight enough now;
-dressed in a smart blue uniform with gold buttons, the sort worn by
-the employees at the banking institute; above the high, stiff collar
-of the coat his strong double-chin emerged; under the bushy
-eyebrows, his piercing, dark eyes looked out fresh and alert; his
-normally unkempt white hair was combed down painfully close to his
-scalp. He took his cap, with its gold monogram from, probably, some
-bank, and threw it in an arc right across the room onto the sofa,
-put his hands in his trouser pockets, pushing back the bottom of his
-long uniform coat, and, with look of determination, walked towards
-Gregor. He probably did not even know himself what he had in mind,
-but nonetheless lifted his feet unusually high. Gregor was amazed
-at the enormous size of the soles of his boots, but wasted no time
-with that - he knew full well, right from the first day of his new
-life, that his father thought it necessary to always be extremely
-strict with him. And so he ran up to his father, stopped when his
-father stopped, scurried forwards again when he moved, even
-slightly. In this way they went round the room several times
-without anything decisive happening, without even giving the
-impression of a chase as everything went so slowly. Gregor remained
-all this time on the floor, largely because he feared his father
-might see it as especially provoking if he fled onto the wall or
-ceiling. Whatever he did, Gregor had to admit that he certainly
-would not be able to keep up this running about for long, as for
-each step his father took he had to carry out countless movements.
-He became noticeably short of breath, even in his earlier life his
-lungs had not been very reliable. Now, as he lurched about in his
-efforts to muster all the strength he could for running he could
-hardly keep his eyes open; his thoughts became too slow for him to
-think of any other way of saving himself than running; he almost
-forgot that the walls were there for him to use although, here, they
-were concealed behind carefully carved furniture full of notches and
-protrusions - then, right beside him, lightly tossed, something flew
-down and rolled in front of him. It was an apple; then another one
-immediately flew at him; Gregor froze in shock; there was no longer
-any point in running as his father had decided to bombard him. He
-had filled his pockets with fruit from the bowl on the sideboard and
-now, without even taking the time for careful aim, threw one apple
-after another. These little, red apples rolled about on the floor,
-knocking into each other as if they had electric motors. An apple
-thrown without much force glanced against Gregor's back and slid off
-without doing any harm. Another one however, immediately following
-it, hit squarely and lodged in his back; Gregor wanted to drag
-himself away, as if he could remove the surprising, the incredible
-pain by changing his position; but he felt as if nailed to the spot
-and spread himself out, all his senses in confusion. The last thing
-he saw was the door of his room being pulled open, his sister was
-screaming, his mother ran out in front of her in her blouse (as his
-sister had taken off some of her clothes after she had fainted to
-make it easier for her to breathe), she ran to his father, her
-skirts unfastened and sliding one after another to the ground,
-stumbling over the skirts she pushed herself to his father, her arms
-around him, uniting herself with him totally - now Gregor lost his
-ability to see anything - her hands behind his father's head begging
-him to spare Gregor's life.
-
-
-
-III
-
-
-No-one dared to remove the apple lodged in Gregor's flesh, so it
-remained there as a visible reminder of his injury. He had suffered
-it there for more than a month, and his condition seemed serious
-enough to remind even his father that Gregor, despite his current
-sad and revolting form, was a family member who could not be treated
-as an enemy. On the contrary, as a family there was a duty to
-swallow any revulsion for him and to be patient, just to be patient.
-
-Because of his injuries, Gregor had lost much of his mobility -
-probably permanently. He had been reduced to the condition of an
-ancient invalid and it took him long, long minutes to crawl across
-his room - crawling over the ceiling was out of the question - but
-this deterioration in his condition was fully (in his opinion) made
-up for by the door to the living room being left open every evening.
- He got into the habit of closely watching it for one or two hours
-before it was opened and then, lying in the darkness of his room
-where he could not be seen from the living room, he could watch the
-family in the light of the dinner table and listen to their
-conversation - with everyone's permission, in a way, and thus quite
-differently from before.
-
-They no longer held the lively conversations of earlier times, of
-course, the ones that Gregor always thought about with longing when
-he was tired and getting into the damp bed in some small hotel room.
- All of them were usually very quiet nowadays. Soon after dinner,
-his father would go to sleep in his chair; his mother and sister
-would urge each other to be quiet; his mother, bent deeply under the
-lamp, would sew fancy underwear for a fashion shop; his sister, who
-had taken a sales job, learned shorthand and French in the evenings
-so that she might be able to get a better position later on.
-Sometimes his father would wake up and say to Gregor's mother
-"you're doing so much sewing again today!", as if he did not know
-that he had been dozing - and then he would go back to sleep again
-while mother and sister would exchange a tired grin.
-
-With a kind of stubbornness, Gregor's father refused to take his
-uniform off even at home; while his nightgown hung unused on its peg
-Gregor's father would slumber where he was, fully dressed, as if
-always ready to serve and expecting to hear the voice of his
-superior even here. The uniform had not been new to start with, but
-as a result of this it slowly became even shabbier despite the
-efforts of Gregor's mother and sister to look after it. Gregor
-would often spend the whole evening looking at all the stains on
-this coat, with its gold buttons always kept polished and shiny,
-while the old man in it would sleep, highly uncomfortable but
-peaceful.
-
-As soon as it struck ten, Gregor's mother would speak gently to his
-father to wake him and try to persuade him to go to bed, as he
-couldn't sleep properly where he was and he really had to get his
-sleep if he was to be up at six to get to work. But since he had
-been in work he had become more obstinate and would always insist on
-staying longer at the table, even though he regularly fell asleep
-and it was then harder than ever to persuade him to exchange the
-chair for his bed. Then, however much mother and sister would
-importune him with little reproaches and warnings he would keep
-slowly shaking his head for a quarter of an hour with his eyes
-closed and refusing to get up. Gregor's mother would tug at his
-sleeve, whisper endearments into his ear, Gregor's sister would
-leave her work to help her mother, but nothing would have any effect
-on him. He would just sink deeper into his chair. Only when the
-two women took him under the arms he would abruptly open his eyes,
-look at them one after the other and say: "What a life! This is what
-peace I get in my old age!" And supported by the two women he would
-lift himself up carefully as if he were carrying the greatest load
-himself, let the women take him to the door, send them off and carry
-on by himself while Gregor's mother would throw down her needle and
-his sister her pen so that they could run after his father and
-continue being of help to him.
-
-Who, in this tired and overworked family, would have had time to
-give more attention to Gregor than was absolutely necessary? The
-household budget became even smaller; so now the maid was dismissed;
-an enormous, thick-boned charwoman with white hair that flapped
-around her head came every morning and evening to do the heaviest
-work; everything else was looked after by Gregor's mother on top of
-the large amount of sewing work she did. Gregor even learned,
-listening to the evening conversation about what price they had
-hoped for, that several items of jewellery belonging to the family
-had been sold, even though both mother and sister had been very fond
-of wearing them at functions and celebrations. But the loudest
-complaint was that although the flat was much too big for their
-present circumstances, they could not move out of it, there was no
-imaginable way of transferring Gregor to the new address. He could
-see quite well, though, that there were more reasons than
-consideration for him that made it difficult for them to move, it
-would have been quite easy to transport him in any suitable crate
-with a few air holes in it; the main thing holding the family back
-from their decision to move was much more to do with their total
-despair, and the thought that they had been struck with a misfortune
-unlike anything experienced by anyone else they knew or were related
-to. They carried out absolutely everything that the world expects
-from poor people, Gregor's father brought bank employees their
-breakfast, his mother sacrificed herself by washing clothes for
-strangers, his sister ran back and forth behind her desk at the
-behest of the customers, but they just did not have the strength to
-do any more. And the injury in Gregor's back began to hurt as much
-as when it was new. After they had come back from taking his father
-to bed Gregor's mother and sister would now leave their work where
-it was and sit close together, cheek to cheek; his mother would
-point to Gregor's room and say "Close that door, Grete", and then,
-when he was in the dark again, they would sit in the next room and
-their tears would mingle, or they would simply sit there staring
-dry-eyed at the table.
-
-Gregor hardly slept at all, either night or day. Sometimes he would
-think of taking over the family's affairs, just like before, the
-next time the door was opened; he had long forgotten about his boss
-and the chief clerk, but they would appear again in his thoughts,
-the salesmen and the apprentices, that stupid teaboy, two or three
-friends from other businesses, one of the chambermaids from a
-provincial hotel, a tender memory that appeared and disappeared
-again, a cashier from a hat shop for whom his attention had been
-serious but too slow, - all of them appeared to him, mixed together
-with strangers and others he had forgotten, but instead of helping
-him and his family they were all of them inaccessible, and he was
-glad when they disappeared. Other times he was not at all in the
-mood to look after his family, he was filled with simple rage about
-the lack of attention he was shown, and although he could think of
-nothing he would have wanted, he made plans of how he could get into
-the pantry where he could take all the things he was entitled to,
-even if he was not hungry. Gregor's sister no longer thought about
-how she could please him but would hurriedly push some food or other
-into his room with her foot before she rushed out to work in the
-morning and at midday, and in the evening she would sweep it away
-again with the broom, indifferent as to whether it had been eaten or
-- more often than not - had been left totally untouched. She still
-cleared up the room in the evening, but now she could not have been
-any quicker about it. Smears of dirt were left on the walls, here
-and there were little balls of dust and filth. At first, Gregor
-went into one of the worst of these places when his sister arrived
-as a reproach to her, but he could have stayed there for weeks
-without his sister doing anything about it; she could see the dirt
-as well as he could but she had simply decided to leave him to it.
-At the same time she became touchy in a way that was quite new for
-her and which everyone in the family understood - cleaning up
-Gregor's room was for her and her alone. Gregor's mother did once
-thoroughly clean his room, and needed to use several bucketfuls of
-water to do it - although that much dampness also made Gregor ill
-and he lay flat on the couch, bitter and immobile. But his mother
-was to be punished still more for what she had done, as hardly had
-his sister arrived home in the evening than she noticed the change
-in Gregor's room and, highly aggrieved, ran back into the living
-room where, despite her mothers raised and imploring hands, she
-broke into convulsive tears. Her father, of course, was startled
-out of his chair and the two parents looked on astonished and
-helpless; then they, too, became agitated; Gregor's father, standing
-to the right of his mother, accused her of not leaving the cleaning
-of Gregor's room to his sister; from her left, Gregor's sister
-screamed at her that she was never to clean Gregor's room again;
-while his mother tried to draw his father, who was beside himself
-with anger, into the bedroom; his sister, quaking with tears,
-thumped on the table with her small fists; and Gregor hissed in
-anger that no-one had even thought of closing the door to save him
-the sight of this and all its noise.
-
-Gregor's sister was exhausted from going out to work, and looking
-after Gregor as she had done before was even more work for her, but
-even so his mother ought certainly not to have taken her place.
-Gregor, on the other hand, ought not to be neglected. Now, though,
-the charwoman was here. This elderly widow, with a robust bone
-structure that made her able to withstand the hardest of things in
-her long life, wasn't really repelled by Gregor. Just by chance one
-day, rather than any real curiosity, she opened the door to Gregor's
-room and found herself face to face with him. He was taken totally
-by surprise, no-one was chasing him but he began to rush to and fro
-while she just stood there in amazement with her hands crossed in
-front of her. From then on she never failed to open the door
-slightly every evening and morning and look briefly in on him. At
-first she would call to him as she did so with words that she
-probably considered friendly, such as "come on then, you old
-dung-beetle!", or "look at the old dung-beetle there!" Gregor never
-responded to being spoken to in that way, but just remained where he
-was without moving as if the door had never even been opened. If
-only they had told this charwoman to clean up his room every day
-instead of letting her disturb him for no reason whenever she felt
-like it! One day, early in the morning while a heavy rain struck the
-windowpanes, perhaps indicating that spring was coming, she began to
-speak to him in that way once again. Gregor was so resentful of it
-that he started to move toward her, he was slow and infirm, but it
-was like a kind of attack. Instead of being afraid, the charwoman
-just lifted up one of the chairs from near the door and stood there
-with her mouth open, clearly intending not to close her mouth until
-the chair in her hand had been slammed down into Gregor's back.
-"Aren't you coming any closer, then?", she asked when Gregor turned
-round again, and she calmly put the chair back in the corner.
-
-Gregor had almost entirely stopped eating. Only if he happened to
-find himself next to the food that had been prepared for him he
-might take some of it into his mouth to play with it, leave it there
-a few hours and then, more often than not, spit it out again. At
-first he thought it was distress at the state of his room that
-stopped him eating, but he had soon got used to the changes made
-there. They had got into the habit of putting things into this room
-that they had no room for anywhere else, and there were now many
-such things as one of the rooms in the flat had been rented out to
-three gentlemen. These earnest gentlemen - all three of them had
-full beards, as Gregor learned peering through the crack in the door
-one day - were painfully insistent on things' being tidy. This
-meant not only in their own room but, since they had taken a room in
-this establishment, in the entire flat and especially in the
-kitchen. Unnecessary clutter was something they could not tolerate,
-especially if it was dirty. They had moreover brought most of their
-own furnishings and equipment with them. For this reason, many
-things had become superfluous which, although they could not be
-sold, the family did not wish to discard. All these things found
-their way into Gregor's room. The dustbins from the kitchen found
-their way in there too. The charwoman was always in a hurry, and
-anything she couldn't use for the time being she would just chuck in
-there. He, fortunately, would usually see no more than the object
-and the hand that held it. The woman most likely meant to fetch the
-things back out again when she had time and the opportunity, or to
-throw everything out in one go, but what actually happened was that
-they were left where they landed when they had first been thrown
-unless Gregor made his way through the junk and moved it somewhere
-else. At first he moved it because, with no other room free where
-he could crawl about, he was forced to, but later on he came to
-enjoy it although moving about in the way left him sad and tired to
-death and he would remain immobile for hours afterwards.
-
-The gentlemen who rented the room would sometimes take their evening
-meal at home in the living room that was used by everyone, and so
-the door to this room was often kept closed in the evening. But
-Gregor found it easy to give up having the door open, he had, after
-all, often failed to make use of it when it was open and, without
-the family having noticed it, lain in his room in its darkest
-corner. One time, though, the charwoman left the door to the living
-room slightly open, and it remained open when the gentlemen who
-rented the room came in in the evening and the light was put on.
-They sat up at the table where, formerly, Gregor had taken his meals
-with his father and mother, they unfolded the serviettes and picked
-up their knives and forks. Gregor's mother immediately appeared in
-the doorway with a dish of meat and soon behind her came his sister
-with a dish piled high with potatoes. The food was steaming, and
-filled the room with its smell. The gentlemen bent over the dishes
-set in front of them as if they wanted to test the food before
-eating it, and the gentleman in the middle, who seemed to count as
-an authority for the other two, did indeed cut off a piece of meat
-while it was still in its dish, clearly wishing to establish whether
-it was sufficiently cooked or whether it should be sent back to the
-kitchen. It was to his satisfaction, and Gregor's mother and
-sister, who had been looking on anxiously, began to breathe again
-and smiled.
-
-The family themselves ate in the kitchen. Nonetheless, Gregor's
-father came into the living room before he went into the kitchen,
-bowed once with his cap in his hand and did his round of the table.
-The gentlemen stood as one, and mumbled something into their beards.
- Then, once they were alone, they ate in near perfect silence. It
-seemed remarkable to Gregor that above all the various noises of
-eating their chewing teeth could still be heard, as if they had
-wanted to Show Gregor that you need teeth in order to eat and it was
-not possible to perform anything with jaws that are toothless
-however nice they might be. "I'd like to eat something", said
-Gregor anxiously, "but not anything like they're eating. They do
-feed themselves. And here I am, dying!"
-
-Throughout all this time, Gregor could not remember having heard the
-violin being played, but this evening it began to be heard from the
-kitchen. The three gentlemen had already finished their meal, the
-one in the middle had produced a newspaper, given a page to each of
-the others, and now they leant back in their chairs reading them and
-smoking. When the violin began playing they became attentive, stood
-up and went on tip-toe over to the door of the hallway where they
-stood pressed against each other. Someone must have heard them in
-the kitchen, as Gregor's father called out: "Is the playing perhaps
-unpleasant for the gentlemen? We can stop it straight away." "On
-the contrary", said the middle gentleman, "would the young lady not
-like to come in and play for us here in the room, where it is, after
-all, much more cosy and comfortable?" "Oh yes, we'd love to",
-called back Gregor's father as if he had been the violin player
-himself. The gentlemen stepped back into the room and waited.
-Gregor's father soon appeared with the music stand, his mother with
-the music and his sister with the violin. She calmly prepared
-everything for her to begin playing; his parents, who had never
-rented a room out before and therefore showed an exaggerated
-courtesy towards the three gentlemen, did not even dare to sit on
-their own chairs; his father leant against the door with his right
-hand pushed in between two buttons on his uniform coat; his mother,
-though, was offered a seat by one of the gentlemen and sat - leaving
-the chair where the gentleman happened to have placed it - out of
-the way in a corner.
-
-His sister began to play; father and mother paid close attention,
-one on each side, to the movements of her hands. Drawn in by the
-playing, Gregor had dared to come forward a little and already had
-his head in the living room. Before, he had taken great pride in
-how considerate he was but now it hardly occurred to him that he had
-become so thoughtless about the others. What's more, there was now
-all the more reason to keep himself hidden as he was covered in the
-dust that lay everywhere in his room and flew up at the slightest
-movement; he carried threads, hairs, and remains of food about on
-his back and sides; he was much too indifferent to everything now to
-lay on his back and wipe himself on the carpet like he had used to
-do several times a day. And despite this condition, he was not too
-shy to move forward a little onto the immaculate floor of the living
-room.
-
-No-one noticed him, though. The family was totally preoccupied with
-the violin playing; at first, the three gentlemen had put their
-hands in their pockets and come up far too close behind the music
-stand to look at all the notes being played, and they must have
-disturbed Gregor's sister, but soon, in contrast with the family,
-they withdrew back to the window with their heads sunk and talking
-to each other at half volume, and they stayed by the window while
-Gregor's father observed them anxiously. It really now seemed very
-obvious that they had expected to hear some beautiful or
-entertaining violin playing but had been disappointed, that they had
-had enough of the whole performance and it was only now out of
-politeness that they allowed their peace to be disturbed. It was
-especially unnerving, the way they all blew the smoke from their
-cigarettes upwards from their mouth and noses. Yet Gregor's sister
-was playing so beautifully. Her face was leant to one side,
-following the lines of music with a careful and melancholy
-expression. Gregor crawled a little further forward, keeping his
-head close to the ground so that he could meet her eyes if the
-chance came. Was he an animal if music could captivate him so? It
-seemed to him that he was being shown the way to the unknown
-nourishment he had been yearning for. He was determined to make his
-way forward to his sister and tug at her skirt to show her she might
-come into his room with her violin, as no-one appreciated her
-playing here as much as he would. He never wanted to let her out of
-his room, not while he lived, anyway; his shocking appearance
-should, for once, be of some use to him; he wanted to be at every
-door of his room at once to hiss and spit at the attackers; his
-sister should not be forced to stay with him, though, but stay of
-her own free will; she would sit beside him on the couch with her
-ear bent down to him while he told her how he had always intended to
-send her to the conservatory, how he would have told everyone about
-it last Christmas - had Christmas really come and gone already? - if
-this misfortune hadn't got in the way, and refuse to let anyone
-dissuade him from it. On hearing all this, his sister would break
-out in tears of emotion, and Gregor would climb up to her shoulder
-and kiss her neck, which, since she had been going out to work, she
-had kept free without any necklace or collar.
-
-"Mr. Samsa!", shouted the middle gentleman to Gregor's father,
-pointing, without wasting any more words, with his forefinger at
-Gregor as he slowly moved forward. The violin went silent, the
-middle of the three gentlemen first smiled at his two friends,
-shaking his head, and then looked back at Gregor. His father seemed
-to think it more important to calm the three gentlemen before
-driving Gregor out, even though they were not at all upset and
-seemed to think Gregor was more entertaining that the violin playing
-had been. He rushed up to them with his arms spread out and
-attempted to drive them back into their room at the same time as
-trying to block their view of Gregor with his body. Now they did
-become a little annoyed, and it was not clear whether it was his
-father's behaviour that annoyed them or the dawning realisation that
-they had had a neighbour like Gregor in the next room without
-knowing it. They asked Gregor's father for explanations, raised
-their arms like he had, tugged excitedly at their beards and moved
-back towards their room only very slowly. Meanwhile Gregor's sister
-had overcome the despair she had fallen into when her playing was
-suddenly interrupted. She had let her hands drop and let violin and
-bow hang limply for a while but continued to look at the music as if
-still playing, but then she suddenly pulled herself together, lay
-the instrument on her mother's lap who still sat laboriously
-struggling for breath where she was, and ran into the next room
-which, under pressure from her father, the three gentlemen were more
-quickly moving toward. Under his sister's experienced hand, the
-pillows and covers on the beds flew up and were put into order and
-she had already finished making the beds and slipped out again
-before the three gentlemen had reached the room. Gregor's father
-seemed so obsessed with what he was doing that he forgot all the
-respect he owed to his tenants. He urged them and pressed them
-until, when he was already at the door of the room, the middle of
-the three gentlemen shouted like thunder and stamped his foot and
-thereby brought Gregor's father to a halt. "I declare here and
-now", he said, raising his hand and glancing at Gregor's mother and
-sister to gain their attention too, "that with regard to the
-repugnant conditions that prevail in this flat and with this family"
-- here he looked briefly but decisively at the floor - "I give
-immediate notice on my room. For the days that I have been living
-here I will, of course, pay nothing at all, on the contrary I will
-consider whether to proceed with some kind of action for damages
-from you, and believe me it would be very easy to set out the
-grounds for such an action." He was silent and looked straight
-ahead as if waiting for something. And indeed, his two friends
-joined in with the words: "And we also give immediate notice." With
-that, he took hold of the door handle and slammed the door.
-
-Gregor's father staggered back to his seat, feeling his way with his
-hands, and fell into it; it looked as if he was stretching himself
-out for his usual evening nap but from the uncontrolled way his head
-kept nodding it could be seen that he was not sleeping at all.
-Throughout all this, Gregor had lain still where the three gentlemen
-had first seen him. His disappointment at the failure of his plan,
-and perhaps also because he was weak from hunger, made it impossible
-for him to move. He was sure that everyone would turn on him any
-moment, and he waited. He was not even startled out of this state
-when the violin on his mother's lap fell from her trembling fingers
-and landed loudly on the floor.
-
-"Father, Mother", said his sister, hitting the table with her hand
-as introduction, "we can't carry on like this. Maybe you can't see
-it, but I can. I don't want to call this monster my brother, all I
-can say is: we have to try and get rid of it. We've done all that's
-humanly possible to look after it and be patient, I don't think
-anyone could accuse us of doing anything wrong."
-
-"She's absolutely right", said Gregor's father to himself. His
-mother, who still had not had time to catch her breath, began to
-cough dully, her hand held out in front of her and a deranged
-expression in her eyes.
-
-Gregor's sister rushed to his mother and put her hand on her
-forehead. Her words seemed to give Gregor's father some more
-definite ideas. He sat upright, played with his uniform cap between
-the plates left by the three gentlemen after their meal, and
-occasionally looked down at Gregor as he lay there immobile.
-
-"We have to try and get rid of it", said Gregor's sister, now
-speaking only to her father, as her mother was too occupied with
-coughing to listen, "it'll be the death of both of you, I can see it
-coming. We can't all work as hard as we have to and then come home
-to be tortured like this, we can't endure it. I can't endure it any
-more." And she broke out so heavily in tears that they flowed down
-the face of her mother, and she wiped them away with mechanical hand
-movements.
-
-"My child", said her father with sympathy and obvious understanding,
-"what are we to do?"
-
-His sister just shrugged her shoulders as a sign of the helplessness
-and tears that had taken hold of her, displacing her earlier
-certainty.
-
-"If he could just understand us", said his father almost as a
-question; his sister shook her hand vigorously through her tears as
-a sign that of that there was no question.
-
-"If he could just understand us", repeated Gregor's father, closing
-his eyes in acceptance of his sister's certainty that that was quite
-impossible, "then perhaps we could come to some kind of arrangement
-with him. But as it is ..."
-
-"It's got to go", shouted his sister, "that's the only way, Father.
-You've got to get rid of the idea that that's Gregor. We've only
-harmed ourselves by believing it for so long. How can that be
-Gregor? If it were Gregor he would have seen long ago that it's not
-possible for human beings to live with an animal like that and he
-would have gone of his own free will. We wouldn't have a brother
-any more, then, but we could carry on with our lives and remember
-him with respect. As it is this animal is persecuting us, it's
-driven out our tenants, it obviously wants to take over the whole
-flat and force us to sleep on the streets. Father, look, just
-look", she suddenly screamed, "he's starting again!" In her alarm,
-which was totally beyond Gregor's comprehension, his sister even
-abandoned his mother as she pushed herself vigorously out of her
-chair as if more willing to sacrifice her own mother than stay
-anywhere near Gregor. She rushed over to behind her father, who had
-become excited merely because she was and stood up half raising his
-hands in front of Gregor's sister as if to protect her.
-
-But Gregor had had no intention of frightening anyone, least of all
-his sister. All he had done was begin to turn round so that he
-could go back into his room, although that was in itself quite
-startling as his pain-wracked condition meant that turning round
-required a great deal of effort and he was using his head to help
-himself do it, repeatedly raising it and striking it against the
-floor. He stopped and looked round. They seemed to have realised
-his good intention and had only been alarmed briefly. Now they all
-looked at him in unhappy silence. His mother lay in her chair with
-her legs stretched out and pressed against each other, her eyes
-nearly closed with exhaustion; his sister sat next to his father
-with her arms around his neck.
-
-"Maybe now they'll let me turn round", thought Gregor and went back
-to work. He could not help panting loudly with the effort and had
-sometimes to stop and take a rest. No-one was making him rush any
-more, everything was left up to him. As soon as he had finally
-finished turning round he began to move straight ahead. He was
-amazed at the great distance that separated him from his room, and
-could not understand how he had covered that distance in his weak
-state a little while before and almost without noticing it. He
-concentrated on crawling as fast as he could and hardly noticed that
-there was not a word, not any cry, from his family to distract him.
-He did not turn his head until he had reached the doorway. He did
-not turn it all the way round as he felt his neck becoming stiff,
-but it was nonetheless enough to see that nothing behind him had
-changed, only his sister had stood up. With his last glance he saw
-that his mother had now fallen completely asleep.
-
-He was hardly inside his room before the door was hurriedly shut,
-bolted and locked. The sudden noise behind Gregor so startled him
-that his little legs collapsed under him. It was his sister who had
-been in so much of a rush. She had been standing there waiting and
-sprung forward lightly, Gregor had not heard her coming at all, and
-as she turned the key in the lock she said loudly to her parents "At
-last!".
-
-"What now, then?", Gregor asked himself as he looked round in the
-darkness. He soon made the discovery that he could no longer move
-at all. This was no surprise to him, it seemed rather that being
-able to actually move around on those spindly little legs until then
-was unnatural. He also felt relatively comfortable. It is true
-that his entire body was aching, but the pain seemed to be slowly
-getting weaker and weaker and would finally disappear altogether.
-He could already hardly feel the decayed apple in his back or the
-inflamed area around it, which was entirely covered in white dust.
-He thought back of his family with emotion and love. If it was
-possible, he felt that he must go away even more strongly than his
-sister. He remained in this state of empty and peaceful rumination
-until he heard the clock tower strike three in the morning. He
-watched as it slowly began to get light everywhere outside the
-window too. Then, without his willing it, his head sank down
-completely, and his last breath flowed weakly from his nostrils.
-
-When the cleaner came in early in the morning - they'd often asked
-her not to keep slamming the doors but with her strength and in her
-hurry she still did, so that everyone in the flat knew when she'd
-arrived and from then on it was impossible to sleep in peace - she
-made her usual brief look in on Gregor and at first found nothing
-special. She thought he was laying there so still on purpose,
-playing the martyr; she attributed all possible understanding to
-him. She happened to be holding the long broom in her hand, so she
-tried to tickle Gregor with it from the doorway. When she had no
-success with that she tried to make a nuisance of herself and poked
-at him a little, and only when she found she could shove him across
-the floor with no resistance at all did she start to pay attention.
-She soon realised what had really happened, opened her eyes wide,
-whistled to herself, but did not waste time to yank open the bedroom
-doors and shout loudly into the darkness of the bedrooms: "Come and
-'ave a look at this, it's dead, just lying there, stone dead!"
-
-Mr. and Mrs. Samsa sat upright there in their marriage bed and had
-to make an effort to get over the shock caused by the cleaner before
-they could grasp what she was saying. But then, each from his own
-side, they hurried out of bed. Mr. Samsa threw the blanket over his
-shoulders, Mrs. Samsa just came out in her nightdress; and that is
-how they went into Gregor's room. On the way they opened the door
-to the living room where Grete had been sleeping since the three
-gentlemen had moved in; she was fully dressed as if she had never
-been asleep, and the paleness of her face seemed to confirm this.
-"Dead?", asked Mrs. Samsa, looking at the charwoman enquiringly,
-even though she could have checked for herself and could have known
-it even without checking. "That's what I said", replied the
-cleaner, and to prove it she gave Gregor's body another shove with
-the broom, sending it sideways across the floor. Mrs. Samsa made a
-movement as if she wanted to hold back the broom, but did not
-complete it. "Now then", said Mr. Samsa, "let's give thanks to God
-for that". He crossed himself, and the three women followed his
-example. Grete, who had not taken her eyes from the corpse, said:
-"Just look how thin he was. He didn't eat anything for so long.
-The food came out again just the same as when it went in". Gregor's
-body was indeed completely dried up and flat, they had not seen it
-until then, but now he was not lifted up on his little legs, nor did
-he do anything to make them look away.
-
-"Grete, come with us in here for a little while", said Mrs. Samsa
-with a pained smile, and Grete followed her parents into the bedroom
-but not without looking back at the body. The cleaner shut the door
-and opened the window wide. Although it was still early in the
-morning the fresh air had something of warmth mixed in with it. It
-was already the end of March, after all.
-
-The three gentlemen stepped out of their room and looked round in
-amazement for their breakfasts; they had been forgotten about.
-"Where is our breakfast?", the middle gentleman asked the cleaner
-irritably. She just put her finger on her lips and made a quick and
-silent sign to the men that they might like to come into Gregor's
-room. They did so, and stood around Gregor's corpse with their
-hands in the pockets of their well-worn coats. It was now quite
-light in the room.
-
-Then the door of the bedroom opened and Mr. Samsa appeared in his
-uniform with his wife on one arm and his daughter on the other. All
-of them had been crying a little; Grete now and then pressed her
-face against her father's arm.
-
-"Leave my home. Now!", said Mr. Samsa, indicating the door and
-without letting the women from him. "What do you mean?", asked the
-middle of the three gentlemen somewhat disconcerted, and he smiled
-sweetly. The other two held their hands behind their backs and
-continually rubbed them together in gleeful anticipation of a loud
-quarrel which could only end in their favour. "I mean just what I
-said", answered Mr. Samsa, and, with his two companions, went in a
-straight line towards the man. At first, he stood there still,
-looking at the ground as if the contents of his head were
-rearranging themselves into new positions. "Alright, we'll go
-then", he said, and looked up at Mr. Samsa as if he had been
-suddenly overcome with humility and wanted permission again from
-Mr. Samsa for his decision. Mr. Samsa merely opened his eyes wide
-and briefly nodded to him several times. At that, and without
-delay, the man actually did take long strides into the front
-hallway; his two friends had stopped rubbing their hands some time
-before and had been listening to what was being said. Now they
-jumped off after their friend as if taken with a sudden fear that
-Mr. Samsa might go into the hallway in front of them and break the
-connection with their leader. Once there, all three took their hats
-from the stand, took their sticks from the holder, bowed without a
-word and left the premises. Mr. Samsa and the two women followed
-them out onto the landing; but they had had no reason to mistrust
-the men' intentions and as they leaned over the landing they saw how
-the three gentlemen made slow but steady progress down the many
-steps. As they turned the corner on each floor they disappeared and
-would reappear a few moments later; the further down they went, the
-more that the Samsa family lost interest in them; when a butcher's
-boy, proud of posture with his tray on his head, passed them on his
-way up and came nearer than they were, Mr. Samsa and the women came
-away from the landing and went, as if relieved, back into the flat.
-
-They decided the best way to make use of that day was for relaxation
-and to go for a walk; not only had they earned a break from work but
-they were in serious need of it. So they sat at the table and wrote
-three letters of excusal, Mr. Samsa to his employers, Mrs. Samsa
-to her contractor and Grete to her principal. The cleaner came in
-while they were writing to tell them she was going, she'd finished
-her work for that morning. The three of them at first just nodded
-without looking up from what they were writing, and it was only when
-the cleaner still did not seem to want to leave that they looked up
-in irritation. "Well?", asked Mr. Samsa. The charwoman stood in
-the doorway with a smile on her face as if she had some tremendous
-good news to report, but would only do it if she was clearly asked
-to. The almost vertical little ostrich feather on her hat, which
-had been source of irritation to Mr. Samsa all the time she had
-been working for them, swayed gently in all directions. "What is it
-you want then?", asked Mrs. Samsa, whom the cleaner had the most
-respect for. "Yes", she answered, and broke into a friendly laugh
-that made her unable to speak straight away, "well then, that thing
-in there, you needn't worry about how you're going to get rid of it.
- That's all been sorted out." Mrs. Samsa and Grete bent down over
-their letters as if intent on continuing with what they were
-writing; Mr. Samsa saw that the cleaner wanted to start describing
-everything in detail but, with outstretched hand, he made it quite
-clear that she was not to. So, as she was prevented from telling
-them all about it, she suddenly remembered what a hurry she was in
-and, clearly peeved, called out "Cheerio then, everyone", turned
-round sharply and left, slamming the door terribly as she went.
-
-"Tonight she gets sacked", said Mr. Samsa, but he received no reply
-from either his wife or his daughter as the charwoman seemed to have
-destroyed the peace they had only just gained. They got up and went
-over to the window where they remained with their arms around each
-other. Mr. Samsa twisted round in his chair to look at them and sat
-there watching for a while. Then he called out: "Come here, then.
-Let's forget about all that old stuff, shall we. Come and give me a
-bit of attention". The two women immediately did as he said,
-hurrying over to him where they kissed him and hugged him and then
-they quickly finished their letters.
-
-After that, the three of them left the flat together, which was
-something they had not done for months, and took the tram out to the
-open country outside the town. They had the tram, filled with warm
-sunshine, all to themselves. Leant back comfortably on their seats,
-they discussed their prospects and found that on closer examination
-they were not at all bad - until then they had never asked each
-other about their work but all three had jobs which were very good
-and held particularly good promise for the future. The greatest
-improvement for the time being, of course, would be achieved quite
-easily by moving house; what they needed now was a flat that was
-smaller and cheaper than the current one which had been chosen by
-Gregor, one that was in a better location and, most of all, more
-practical. All the time, Grete was becoming livelier. With all the
-worry they had been having of late her cheeks had become pale, but,
-while they were talking, Mr. and Mrs. Samsa were struck, almost
-simultaneously, with the thought of how their daughter was
-blossoming into a well built and beautiful young lady. They became
-quieter. Just from each other's glance and almost without knowing
-it they agreed that it would soon be time to find a good man for
-her. And, as if in confirmation of their new dreams and good
-intentions, as soon as they reached their destination Grete was the
-first to get up and stretch out her young body.
diff --git a/test/opencl/examples/openclinaction/ch11/string-search.cl b/test/opencl/examples/openclinaction/ch11/string-search.cl
deleted file mode 100644
index 1c40093..0000000
--- a/test/opencl/examples/openclinaction/ch11/string-search.cl
+++ /dev/null
@@ -1,40 +0,0 @@
-__kernel void string_search (char16 pattern, __global char* text,
- int chars_per_item, __local int* local_result,
- __global int* global_result) {
-
- char16 text_vector, check_vector;
-
- local_result[0] = 0;
- local_result[1] = 0;
- local_result[2] = 0;
- local_result[3] = 0;
-
- work_group_barrier(CLK_LOCAL_MEM_FENCE);
-
- int item_offset = get_global_id(0) * chars_per_item;
-
- for (int i = item_offset; i < item_offset + chars_per_item; i++) {
- text_vector = vload16(0, text + i);
-
- check_vector = text_vector == pattern;
-
- if (all(check_vector.s0123))
- atomic_inc(local_result);
- if (all(check_vector.s4567))
- atomic_inc(local_result + 1);
- if (all(check_vector.s89AB))
- atomic_inc(local_result + 2);
- if (all(check_vector.sCDEF))
- atomic_inc(local_result + 3);
-
- }
-
- work_group_barrier(CLK_GLOBAL_MEM_FENCE);
-
- if(get_local_id(0) == 0) {
- atomic_add(global_result, local_result[0]);
- atomic_add(global_result + 1, local_result[1]);
- atomic_add(global_result + 2, local_result[2]);
- atomic_add(global_result + 3, local_result[3]);
- }
-}
diff --git a/test/opencl/toolbox_test.cl b/test/opencl/toolbox_test.cl
deleted file mode 100644
index 39e0e79..0000000
--- a/test/opencl/toolbox_test.cl
+++ /dev/null
@@ -1,19 +0,0 @@
-__kernel void sum_reduce_horizontal (__global ACCUMULATOR* acc, __global REAL* data) {
- const uint i = get_global_size(0) * get_global_id(1) + get_global_id(0);
- const uint iacc = get_global_size(0) * get_group_id(1) + get_global_id(0);
- __local ACCUMULATOR lacc[WGS];
- const ACCUMULATOR sum = work_group_reduction_sum_2(lacc, data[i]);
- if (get_local_id(1) == 0) {
- acc[iacc] = sum;
- }
-}
-
-__kernel void sum_reduce_vertical (__global ACCUMULATOR* acc, __global REAL* data) {
- const uint i = get_global_size(1) * get_global_id(0) + get_global_id(1);
- const uint iacc = get_global_size(0) * get_group_id(1) + get_global_id(0);
- __local ACCUMULATOR lacc[WGS];
- const ACCUMULATOR sum = work_group_reduction_sum_2(lacc, data[i]);
- if (get_local_id(1) == 0) {
- acc[iacc] = sum;
- }
-}