blob: 4b9bf4c2146408a283153ca40c10ef0036bdcc11 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "xhtml1-transitional.dtd">
<!-- saved from url=(0013)about:internet -->
<?xml-stylesheet type="text/xsl" href="mathml.xsl"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:pref="http://www.w3.org/2002/Math/preference" xmlns:xlink="http://www.w3.org/1999/xlink" pref:renderer="mathplayer-dl">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style xmlns="" type="text/css">
/* This style sets a margin around the entire page */
html, body {
margin: 10px;
}
p {
font: normal 16px verdana, sans-serif;
margin: 0;
padding-bottom:12px;
}
h1 {
font: bold 25px verdana, sans-serif;
margin-top: 0;
margin-bottom: 3px;
padding-top: 0;
padding-bottom: 0;
}
h2 {
font: bold 19px verdana, sans-serif;
margin-top: 28px;
margin-bottom: 3px;
padding-top: 0;
padding-bottom: 0;
}
h3 {
font: bold 19px verdana, sans-serif !important;
margin-top: 28px;
margin-bottom: 3px;
padding-top: 0;
padding-bottom: 0;
}
li {
font: normal 16px verdana, sans-serif;
margin-top: 0;
margin-bottom: 18px;
padding-top: 0;
padding-bottom: 0;
}
.pdparam {
font: italic 16px verdana, sans-serif;
}
.term {
font: italic 16px verdana, sans-serif;
font-weight: normal;
}
.type {
font: normal 16px verdana, sans-serif !important;
}
.parameter {
font-style: italic;
}
a:link, a:visited {
color: blue;
text-decoration: none;
font: normal 16px;
}
a:hover {
background-color: #FFFF99;
font: normal 16px;
}
div.funcsynopsis {
text-align: left;
background-color: #e6e6e6;
font: normal 16px verdana, sans-serif;
padding-top: 10px;
padding-bottom: 10px;
}
div.funcsynopsis table {
border-collapse: separate;
font: normal 16px verdana, sans-serif;
}
div.funcsynopsis td {
background-color: #e6e6e6;
border: 0 solid #000;
padding: 1px;
font: normal 16px verdana, sans-serif;
}
div.refsect1 {
font-family: verdana, sans-serif;
font-size: 16px;
}
code.constant {
font: normal 16px courier new, monospace !important;
}
span.errorname {
font: normal 16px verdana, sans-serif !important;
}
code.function {
font: bold 16px verdana, sans-serif !important;
}
b.fsfunc {
font: bold 16px verdana, sans-serif !important;
}
code.varname {
font: italic 16px verdana, sans-serif;
}
code.replaceable {
font: italic 16px courier new, monospace;
}
code.funcdef {
font: normal 16px verdana, sans-serif !important;
}
.citerefentry {
font: normal 16px verdana, sans-serif !important;
}
.parameter {
font-style: italic;
}
code.fsfunc {
font: normal 16px verdana, sans-serif !important;
}
/* PARAMETER: This style controls spacing between the terms in Parameter section */
dt {
margin-top: 15px;
}
/* TABLES: These styles apply to all tables OTHER than the Synopsis and Example tables */
div.refsect1 table {
width: 100%;
margin-top: 10px;
background-color: #FFF;
border-collapse: collapse;
border-color: #000;
border-width: 1px;
font: normal 16px verdana, sans-serif;
}
div.refsect1 th {
border-collapse: collapse;
border-color: #000;
border-width: 1px;
font: bold 16px verdana, sans-serif;
}
div.refsect1 td {
background-color: #FFF;
padding: 5px;
vertical-align: text-top;
border-collapse: collapse;
border-color: #000;
border-width: 1px;
font: normal 16px verdana, sans-serif;
}
div.refsect1 p{
font: normal 16px verdana, sans-serif;
margin-top: 8px;
margin-bottom: 8px;
padding-top: 0;
padding-bottom: 0;
}
/* EXAMPLE: These styles apply only to the Example section */
div.refsect2 {
font: normal 16px courier new, monospace !important;
}
div.refsect2 table {
margin-top: 0;
background-color: #e6e6e6;
width: 100%;
border: 0 solid #000;
padding: 2px;
font: normal 16px courier new, monospace !important;
}
div.refsect2 td {
background-color: #e6e6e6;
font: normal 16px courier new, monospace !important;
white-space:pre;
}
/* COPYRIGHT: This style formats the text of the copyright statement at the bottom of the page */
div.refsect3 {
font: normal 11px verdana, sans-serif;
margin-top: 50px;
margin-bottom: 20px;
padding-top: 0;
padding-bottom: 0;
}
</style>
<title>Blocks</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1" />
<meta name="keywords" content="Blocks" />
</head>
<body>
<div class="refentry">
<a id="id-1"></a>
<div class="titlepage"></div>
<div xmlns="" class="refnamediv">
<a xmlns="http://www.w3.org/1999/xhtml" id="Blocks"></a>
<h1>Blocks</h1>
<p>
OpenCL C 2.0 adds support for the clang block syntax.
</p>
</div>
<div class="refsect2">
<a id="synopsis"></a>
<h3>
</h3>
<div class="informaltable">
<table class="informaltable" border="0">
<colgroup>
<col align="left" class="col1" />
</colgroup>
<tbody>
<tr>
<td align="left">
Example:
int multiplier = 7;
int (^myBlock)(int) = ^(int num) { return num * multiplier; };
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="refsect1">
<a id="description"></a>
<h2>Description</h2>
<p>
OpenCL C 2.0 adds support for the clang block syntax.
Like function types, the Block type is a
pair consisting of a result value type and a list of
parameter types very similar to a function type.
Blocks are intended to be used much like functions
with the key distinction being that in addition
to executable code they also contain various
variable bindings to automatic (stack) or global
memory.
</p>
<p>
This syntax is already part of the clang source tree
on which most vendors have based their OpenCL
implementations. Additionally, blocks based closures
are supported by the clang open source C compiler as well as
Mac OS X’s C and Objective C compilers. Specifically,
Mac OS X’s Grand Central Dispatch allows applications to
queue tasks as a block.
</p>
<h4><a id="id-1.5.4"></a>Declaring and Using a Block</h4>
<p>
You use the ^ operator to declare a Block
variable and to indicate the beginning of a Block
literal. The body of the Block itself is contained
within {}, as shown in the example (as usual
with C, ; indicates the end of the statement).
</p>
<p>
The Block is able to make use of variables from
the same scope in which it was defined.
</p>
<p>
If you declare a Block as a variable, you can
then use it just as you would a function:
</p>
<p>
<code class="code"><div class="literallayout"><p><br />
    int multiplier = 7;<br />
    int (^myBlock)(int) = ^(int num) {<br />
        return num * multiplier;<br />
    };<br />
<br />
    printf(“%d\n”, myBlock(3));<br />
    // prints 21<br />
</p></div></code>
</p>
<h4><a id="id-1.5.9"></a>Declaring a Block Reference</h4>
<p>
Block variables hold references to Blocks. You
declare them using syntax similar to that you use
to declare a pointer to a function, except that
you use ^ instead of *. The Block type fully
interoperates with the rest of the C type system.
The following are valid Block variable
declarations:
</p>
<div class="literallayout">
<p>
<code class="code"><br />
    void (^blockReturningVoidWithVoidArgument)(void);<br />
    int (^blockReturningIntWithIntAndCharArguments)(int, char);<br />
</code>
</p>
</div>
<p>
A Block that takes no arguments must specify void
in the argument list. A Block reference may
not be dereferenced via the pointer dereference
operation *, and thus a Block’s size may not be
computed at compile time.
</p>
<p>
Blocks are designed to be fully type safe by giving
the compiler a full set of metadata to use to
validate use of Blocks, parameters passed to blocks,
and assignment of the return value.
</p>
<p>
You can also create types for Blocks—doing so
is generally considered to be best practice when
you use a block with a given signature in multiple places:
</p>
<div class="literallayout">
<p>
<code class="code"><br />
    typedef float (^MyBlockType)(float, float);<br />
<br />
    MyBlockType myFirstBlock = // …;<br />
    MyBlockType mySecondBlock = // …;<br />
</code>
</p>
</div>
<h4><a id="id-1.5.16"></a>Block Literal Expressions</h4>
<p>
A Block literal expression produces a reference
to a Block. It is introduced by the use of the ^
token as a unary operator.
</p>
<div class="literallayout">
<p>
<code class="code"><br />
    Block_literal_expression ::= ^ block_decl compound_statement_body<br />
    block_decl ::=<br />
    block_decl ::= parameter_list<br />
    block_decl ::= type_expression<br />
</code>
</p>
</div>
<p>
where type expression is extended to allow ^ as
a Block reference where * is allowed as a
function reference.
</p>
<p>
The following Block literal:
</p>
<div class="literallayout">
<p>
<code class="code"><br />
    ^ void (void) { printf("hello world\n"); }<br />
</code>
</p>
</div>
<p>
produces a reference to a Block with no arguments with no return value.
</p>
<p>
The return type is optional and is inferred from
the return statements. If the return statements
return a value, they all must return a value of
the same type. If there is no value returned the
inferred type of the Block is void; otherwise it
is the type of the return statement value. If the
return type is omitted and the argument list is
( <span class="type">void</span> ),
the ( <span class="type">void</span> ) argument list may also be
omitted.
</p>
<p>
So:
</p>
<div class="literallayout">
<p>
<code class="code"><br />
    ^ ( void ) { printf("hello world\n"); }<br />
</code>
</p>
</div>
<p>
and:
</p>
<div class="literallayout">
<p>
<code class="code"><br />
    ^ { printf("hello world\n"); }<br />
</code>
</p>
</div>
<p>
are exactly equivalent constructs for the same expression.
</p>
<p>
The compound statement body establishes a new
lexical scope within that of its parent. Variables
used within the scope of the compound statement
are bound to the Block in the normal manner
with the exception of those in automatic (stack)
storage. Thus one may access functions and
global variables as one would expect, as well as
static local variables.
</p>
<p>
Local automatic (stack) variables referenced within
the compound statement of a Block are
imported and captured by the Block as const copies.
The capture (binding) is performed at the
time of the Block literal expression evaluation.
</p>
<p>
The compiler is not required to capture a variable if
it can prove that no references to the variable
will actually be evaluated.
</p>
<p>
The lifetime of variables declared in a Block is that of a function.
</p>
<p>
Block literal expressions may occur within Block
literal expressions (nested) and all variables
captured by any nested blocks are implicitly also
captured in the scopes of their enclosing
Blocks.
</p>
<p>
A Block literal expression may be used as the initialization
value for Block variables at global or
local static scope.
</p>
<p>
You can also declare a Block as a global literal in program scope.
</p>
<div class="literallayout">
<p>
<code class="code"><br />
    int GlobalInt = 0;<br />
<br />
    int (^getGlobalInt)(void) = ^{ return GlobalInt; };<br />
</code>
</p>
</div>
<p>
</p>
<h4><a id="id-1.5.37.1"></a>Control Flow</h4>
<p>
</p>
<p>
The compound statement of a Block is treated much
like a function body with respect to control
flow in that continue, break and goto do not escape the Block.
</p>
<h4><a id="id-1.5.39"></a>Restrictions</h4>
<p>
The following Blocks features are currently not supported in OpenCL C.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>The __block storage type.</p>
</li>
<li class="listitem">
<p>The Block_copy() and Block_release() functions that copy and release Blocks.</p>
</li>
<li class="listitem">
<p>Blocks with variadic arguments.</p>
</li>
<li class="listitem">
<p>Arrays of Blocks.</p>
</li>
<li class="listitem">
<p>Blocks as structures and union members.</p>
</li>
</ul>
</div>
<p>
Block literals are assumed to allocate memory at the point of
definition and to be destroyed at the
end of the same scope. To support these behaviors,
additional restrictions in addition to the
above feature restrictions are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>
Block variables must be defined and used in a way that
allows them to be statically
determinable at build or "link to executable" time. In particular:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">Block variables assigned in one scope must be
used only with the same or any
nested scope.</li>
<li class="listitem">The "extern" storage-class specified cannot be
used with program scope block
variables.</li>
<li class="listitem">Block variable declarations must be qualified with
const. Therefore all block
variables must be initialized at declaration time and
may not be reassigned.</li>
<li class="listitem">A block cannot be the return value of a function.</li>
</ul>
</div>
</li>
<li class="listitem">
<p>The unary operators (* and &amp;) cannot be used with a Block.</p>
</li>
<li class="listitem">
<p>Blocks cannot be used as expressions of the ternary selection operator (?:).</p>
</li>
<li class="listitem">
<p>A Block cannot reference another Block.</p>
</li>
</ul>
</div>
<p>
OpenCL C does not allow function pointers (see section 6.9) primarily because it is difficult or
expensive to implement generic indirections to executable code in many hardware architectures
that OpenCL targets. OpenCL C’s design of Blocks is intended to respect that same condition,
yielding the restrictions listed here. As such, Blocks allow a form of dynamically enqueued
function scheduling without providing a form of runtime synchronous dynamic dispatch
analogous to function pointers.
</p>
</div>
<div class="refsect2"><a id="example1"></a><h3>
Examples
</h3>
Example 1:
<div class="literallayout"><p><code class="code"><br />
void foo(int *x, int (^bar)(int, int))<br />
{<br />
    *x = bar(*x, *x);<br />
}<br />
<br />
kernel<br />
void k(global int *x, global int *z)<br />
{<br />
    if (some expression)<br />
        *x = foo(x,<br />
                ^int(int x, int y){return x+y+*z;}); // legal<br />
    else<br />
        *x = foo(x,<br />
                ^int(int x, int y){return (x*y)-*z;}); // legal<br />
}<br />
</code></p></div>
Example 2:
<div class="literallayout"><p><code class="code"><br />
kernel<br />
void k(global int *x, global int *z)<br />
{<br />
    int ^(tmp)(int, int);<br />
    if (some expression)<br />
    {<br />
        tmp = ^int(int x, int y){return x+y+*z;}); // illegal<br />
    }<br />
    *x = foo(x, tmp);<br />
}<br />
</code></p></div>
Example 3:
<div class="literallayout"><p><code class="code"><br />
int GlobalInt = 0;<br />
int (^getGlobalInt)(void) = ^{ return GlobalInt; }; // legal<br />
int (^getAnotherGlobalInt)(void);                   // illegal<br />
extern int (^getExternGlobalInt)(void);             // illegal<br />
<br />
void foo()<br />
{<br />
    ...<br />
    getGlobalInt = ^{ return 0; }; // illegal – cannot assign to<br />
                                   // a global block variable<br />
    ...<br />
}<br />
</code></p></div></div>
<div class="refsect1">
<a id="specification"></a>
<h2>Specification</h2>
<p>
<img src="pdficon_small1.gif" />
<a href="https://www.khronos.org/registry/cl/specs/opencl-2.1-openclc.pdf#page=64" target="OpenCL Spec">OpenCL Specification</a>
</p>
</div>
<div xmlns="" class="refsect3" lang="en" xml:lang="en"><a xmlns="http://www.w3.org/1999/xhtml" id="Copyright"></a><h4 xmlns="http://www.w3.org/1999/xhtml"></h4><img xmlns="http://www.w3.org/1999/xhtml" src="KhronosLogo.jpg" /><p xmlns="http://www.w3.org/1999/xhtml"></p>Copyright © 2007-2015 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
"Materials"), to deal in the Materials without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Materials, and to
permit persons to whom the Materials are furnished to do so, subject to
the condition that this copyright notice and permission notice shall be included
in all copies or substantial portions of the Materials.
</div>
</div>
</body>
</html>