blob: 171fd590a28bfeacb0a013cd228766a481859b1a [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.5">
<meta name="author" content="Khronos OpenCL Working Group">
<title>The OpenCL&#8482; C++ 1.0 Specification</title>
<style>
/*! normalize.css v2.1.2 | MIT License | git.io/normalize */
/* ========================================================================== HTML5 display definitions ========================================================================== */
/** Correct `block` display not defined in IE 8/9. */
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
/** Correct `inline-block` display not defined in IE 8/9. */
audio, canvas, video { display: inline-block; }
/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
audio:not([controls]) { display: none; height: 0; }
/** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */
[hidden], template { display: none; }
script { display: none !important; }
/* ========================================================================== Base ========================================================================== */
/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ }
/** Remove default margin. */
body { margin: 0; }
/* ========================================================================== Links ========================================================================== */
/** Remove the gray background color from active links in IE 10. */
a { background: transparent; }
/** Address `outline` inconsistency between Chrome and other browsers. */
a:focus { outline: thin dotted; }
/** Improve readability when focused and also mouse hovered in all browsers. */
a:active, a:hover { outline: 0; }
/* ========================================================================== Typography ========================================================================== */
/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */
h1 { font-size: 2em; margin: 0.67em 0; }
/** Address styling not present in IE 8/9, Safari 5, and Chrome. */
abbr[title] { border-bottom: 1px dotted; }
/** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */
b, strong { font-weight: bold; }
/** Address styling not present in Safari 5 and Chrome. */
dfn { font-style: italic; }
/** Address differences between Firefox and other browsers. */
hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
/** Address styling not present in IE 8/9. */
mark { background: #ff0; color: #000; }
/** Correct font family set oddly in Safari 5 and Chrome. */
code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; }
/** Improve readability of pre-formatted text in all browsers. */
pre { white-space: pre-wrap; }
/** Set consistent quote types. */
q { quotes: "\201C" "\201D" "\2018" "\2019"; }
/** Address inconsistent and variable font size in all browsers. */
small { font-size: 80%; }
/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
/* ========================================================================== Embedded content ========================================================================== */
/** Remove border when inside `a` element in IE 8/9. */
img { border: 0; }
/** Correct overflow displayed oddly in IE 9. */
svg:not(:root) { overflow: hidden; }
/* ========================================================================== Figures ========================================================================== */
/** Address margin not present in IE 8/9 and Safari 5. */
figure { margin: 0; }
/* ========================================================================== Forms ========================================================================== */
/** Define consistent border, margin, and padding. */
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
/** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */
legend { border: 0; /* 1 */ padding: 0; /* 2 */ }
/** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */
button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ }
/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
button, input { line-height: normal; }
/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */
button, select { text-transform: none; }
/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */
button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }
/** Re-set default cursor for disabled elements. */
button[disabled], html input[disabled] { cursor: default; }
/** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }
/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; }
/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
/** Remove inner padding and border in Firefox 4+. */
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
/** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */
textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ }
/* ========================================================================== Tables ========================================================================== */
/** Remove most spacing between table cells. */
table { border-collapse: collapse; border-spacing: 0; }
meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; }
meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; }
meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; }
*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
html, body { font-size: 100%; }
body { background: white; color: #222222; padding: 0; margin: 0; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; }
a:hover { cursor: pointer; }
img, object, embed { max-width: 100%; height: auto; }
object, embed { height: 100%; }
img { -ms-interpolation-mode: bicubic; }
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
.left { float: left !important; }
.right { float: right !important; }
.text-left { text-align: left !important; }
.text-right { text-align: right !important; }
.text-center { text-align: center !important; }
.text-justify { text-align: justify !important; }
.hide { display: none; }
.antialiased { -webkit-font-smoothing: antialiased; }
img { display: inline-block; vertical-align: middle; }
textarea { height: auto; min-height: 50px; }
select { width: 100%; }
object, svg { display: inline-block; vertical-align: middle; }
.center { margin-left: auto; margin-right: auto; }
.spread { width: 100%; }
p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; }
.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: black; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
/* Typography resets */
div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; }
/* Default Link Styles */
a { color: #0068b0; text-decoration: none; line-height: inherit; }
a:hover, a:focus { color: #333333; }
a img { border: none; }
/* Default paragraph styles */
p { font-family: Noto, sans-serif; font-weight: normal; font-size: 1em; line-height: 1.6; margin-bottom: 0.75em; text-rendering: optimizeLegibility; }
p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; }
/* Default header styles */
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: Noto, sans-serif; font-weight: normal; font-style: normal; color: black; text-rendering: optimizeLegibility; margin-top: 0.5em; margin-bottom: 0.5em; line-height: 1.2125em; }
h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #4d4d4d; line-height: 0; }
h1 { font-size: 2.125em; }
h2 { font-size: 1.6875em; }
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; }
h4 { font-size: 1.125em; }
h5 { font-size: 1.125em; }
h6 { font-size: 1em; }
hr { border: solid #dddddd; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; }
/* Helpful Typography Defaults */
em, i { font-style: italic; line-height: inherit; }
strong, b { font-weight: bold; line-height: inherit; }
small { font-size: 60%; line-height: inherit; }
code { font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; color: #264357; }
/* Lists */
ul, ol, dl { font-size: 1em; line-height: 1.6; margin-bottom: 0.75em; list-style-position: outside; font-family: Noto, sans-serif; }
ul, ol { margin-left: 1.5em; }
ul.no-bullet, ol.no-bullet { margin-left: 1.5em; }
/* Unordered Lists */
ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ }
ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; }
ul.square { list-style-type: square; }
ul.circle { list-style-type: circle; }
ul.disc { list-style-type: disc; }
ul.no-bullet { list-style: none; }
/* Ordered Lists */
ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; }
/* Definition Lists */
dl dt { margin-bottom: 0.3em; font-weight: bold; }
dl dd { margin-bottom: 0.75em; }
/* Abbreviations */
abbr, acronym { text-transform: uppercase; font-size: 90%; color: black; border-bottom: 1px dotted #dddddd; cursor: help; }
abbr { text-transform: none; }
/* Blockquotes */
blockquote { margin: 0 0 0.75em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; }
blockquote cite { display: block; font-size: 0.8125em; color: #5e93b8; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited { color: #5e93b8; }
blockquote, blockquote p { line-height: 1.6; color: #333333; }
/* Microformats */
.vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; }
.vcard li { margin: 0; display: block; }
.vcard .fn { font-weight: bold; font-size: 0.9375em; }
.vevent .summary { font-weight: bold; }
.vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; }
@media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; }
h1 { font-size: 2.75em; }
h2 { font-size: 2.3125em; }
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
h4 { font-size: 1.4375em; } }
/* Tables */
table { background: white; margin-bottom: 1.25em; border: solid 1px #d8d8ce; }
table thead, table tfoot { background: -webkit-linear-gradient(top, #add386, #90b66a); font-weight: bold; }
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: white; text-align: left; }
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #6d6e71; }
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #edf2f2; }
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.4; }
body { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; tab-size: 4; }
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; }
a:hover, a:focus { text-decoration: underline; }
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
.clearfix:after, .float-group:after { clear: both; }
*:not(pre) > code { font-size: inherit; font-style: normal !important; letter-spacing: 0; padding: 0; background-color: white; -webkit-border-radius: 0; border-radius: 0; line-height: inherit; word-wrap: break-word; }
*:not(pre) > code.nobreak { word-wrap: normal; }
*:not(pre) > code.nowrap { white-space: nowrap; }
pre, pre > code { line-height: 1.6; color: #264357; font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; }
em em { font-style: normal; }
strong strong { font-weight: normal; }
.keyseq { color: #333333; }
kbd { font-family: Consolas, "Liberation Mono", Courier, monospace; display: inline-block; color: black; font-size: 0.65em; line-height: 1.45; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: 0 0.15em; padding: 0.2em 0.5em; vertical-align: middle; position: relative; top: -0.1em; white-space: nowrap; }
.keyseq kbd:first-child { margin-left: 0; }
.keyseq kbd:last-child { margin-right: 0; }
.menuseq, .menuref { color: #000; }
.menuseq b:not(.caret), .menuref { font-weight: inherit; }
.menuseq { word-spacing: -0.02em; }
.menuseq b.caret { font-size: 1.25em; line-height: 0.8; }
.menuseq i.caret { font-weight: bold; text-align: center; width: 0.45em; }
b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
b.button:before { content: "["; padding: 0 3px 0 2px; }
b.button:after { content: "]"; padding: 0 2px 0 3px; }
#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 1.5em; padding-right: 1.5em; }
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
#content { margin-top: 1.25em; }
#content:before { content: none; }
#header > h1:first-child { color: black; margin-top: 2.25rem; margin-bottom: 0; }
#header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid #dddddd; }
#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid #dddddd; padding-bottom: 8px; }
#header .details { border-bottom: 1px solid #dddddd; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #5e93b8; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; }
#header .details span:first-child { margin-left: -0.125em; }
#header .details span.email a { color: #333333; }
#header .details br { display: none; }
#header .details br + span:before { content: "\00a0\2013\00a0"; }
#header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #333333; }
#header .details br + span#revremark:before { content: "\00a0|\00a0"; }
#header #revnumber { text-transform: capitalize; }
#header #revnumber:after { content: "\00a0"; }
#content > h1:first-child:not([class]) { color: black; border-bottom: 1px solid #dddddd; padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; }
#toc { border-bottom: 0 solid #dddddd; padding-bottom: 0.5em; }
#toc > ul { margin-left: 0.125em; }
#toc ul.sectlevel0 > li > a { font-style: italic; }
#toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; }
#toc ul { font-family: Noto, sans-serif; list-style-type: none; }
#toc li { line-height: 1.3334; margin-top: 0.3334em; }
#toc a { text-decoration: none; }
#toc a:active { text-decoration: underline; }
#toctitle { color: black; font-size: 1.2em; }
@media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; }
body.toc2 { padding-left: 15em; padding-right: 0; }
#toc.toc2 { margin-top: 0 !important; background-color: white; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #dddddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }
#toc.toc2 #toctitle { margin-top: 0; margin-bottom: 0.8rem; font-size: 1.2em; }
#toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; }
#toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
body.toc2.toc-right { padding-left: 0; padding-right: 15em; }
body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #dddddd; left: auto; right: 0; } }
@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
#toc.toc2 { width: 20em; }
#toc.toc2 #toctitle { font-size: 1.375em; }
#toc.toc2 > ul { font-size: 0.95em; }
#toc.toc2 ul ul { padding-left: 1.25em; }
body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
#content #toc { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; }
#content #toc > :first-child { margin-top: 0; }
#content #toc > :last-child { margin-bottom: 0; }
#footer { max-width: 100%; background-color: none; padding: 1.25em; }
#footer-text { color: black; line-height: 1.44; }
#content { margin-bottom: 0.625em; }
.sect1 { padding-bottom: 0.625em; }
@media only screen and (min-width: 768px) { #content { margin-bottom: 1.25em; }
.sect1 { padding-bottom: 1.25em; } }
.sect1:last-child { padding-bottom: 0; }
.sect1 + .sect1 { border-top: 0 solid #dddddd; }
#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; }
#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\00A7"; font-size: 0.85em; display: block; padding-top: 0.1em; }
#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; }
#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: black; text-decoration: none; }
#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: black; }
.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; }
.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; }
table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; }
.paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: black; }
table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
.admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; }
.admonitionblock > table td.icon { text-align: center; width: 80px; }
.admonitionblock > table td.icon img { max-width: initial; }
.admonitionblock > table td.icon .title { font-weight: bold; font-family: Noto, sans-serif; text-transform: uppercase; }
.admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #dddddd; color: #5e93b8; }
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; }
.exampleblock > .content > :first-child { margin-top: 0; }
.exampleblock > .content > :last-child { margin-bottom: 0; }
.sidebarblock { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; }
.sidebarblock > :first-child { margin-top: 0; }
.sidebarblock > :last-child { margin-bottom: 0; }
.sidebarblock > .content > .title { color: black; margin-top: 0; }
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
.literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: #eeeeee; }
.sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; }
.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px hidden #666666; -webkit-border-radius: 0; border-radius: 0; word-wrap: break-word; padding: 1.25em 1.5625em 1.125em 1.5625em; font-size: 0.8125em; }
.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
@media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } }
@media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } }
.literalblock.output pre { color: #eeeeee; background-color: #264357; }
.listingblock pre.highlightjs { padding: 0; }
.listingblock pre.highlightjs > code { padding: 1.25em 1.5625em 1.125em 1.5625em; -webkit-border-radius: 0; border-radius: 0; }
.listingblock > .content { position: relative; }
.listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; }
.listingblock:hover code[data-lang]:before { display: block; }
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
.listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; }
table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; }
table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; line-height: 1.6; }
table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #dddddd; }
pre.pygments .lineno { display: inline-block; margin-right: .25em; }
table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; }
.quoteblock { margin: 0 1em 0.75em 1.5em; display: table; }
.quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; }
.quoteblock blockquote, .quoteblock blockquote p { color: #333333; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; }
.quoteblock blockquote { margin: 0; padding: 0; border: 0; }
.quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: black; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); }
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
.quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; }
.quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #5e93b8; }
.quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; }
.quoteblock .quoteblock blockquote:before { display: none; }
.verseblock { margin: 0 1em 0.75em 1em; }
.verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #333333; font-weight: 300; text-rendering: optimizeLegibility; }
.verseblock pre strong { font-weight: 400; }
.verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; }
.quoteblock .attribution, .verseblock .attribution { font-size: 0.8125em; line-height: 1.45; font-style: italic; }
.quoteblock .attribution br, .verseblock .attribution br { display: none; }
.quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.025em; color: #5e93b8; }
.quoteblock.abstract { margin: 0 0 0.75em 0; display: block; }
.quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; }
.quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; }
table.tableblock { max-width: 100%; border-collapse: separate; }
table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; }
table.tableblock, th.tableblock, td.tableblock { border: 0 solid #d8d8ce; }
table.grid-all > thead > tr > .tableblock, table.grid-all > tbody > tr > .tableblock { border-width: 0 1px 1px 0; }
table.grid-all > tfoot > tr > .tableblock { border-width: 1px 1px 0 0; }
table.grid-cols > * > tr > .tableblock { border-width: 0 1px 0 0; }
table.grid-rows > thead > tr > .tableblock, table.grid-rows > tbody > tr > .tableblock { border-width: 0 0 1px 0; }
table.grid-rows > tfoot > tr > .tableblock { border-width: 1px 0 0 0; }
table.grid-all > * > tr > .tableblock:last-child, table.grid-cols > * > tr > .tableblock:last-child { border-right-width: 0; }
table.grid-all > tbody > tr:last-child > .tableblock, table.grid-all > thead:last-child > tr > .tableblock, table.grid-rows > tbody > tr:last-child > .tableblock, table.grid-rows > thead:last-child > tr > .tableblock { border-bottom-width: 0; }
table.frame-all { border-width: 1px; }
table.frame-sides { border-width: 0 1px; }
table.frame-topbot { border-width: 1px 0; }
th.halign-left, td.halign-left { text-align: left; }
th.halign-right, td.halign-right { text-align: right; }
th.halign-center, td.halign-center { text-align: center; }
th.valign-top, td.valign-top { vertical-align: top; }
th.valign-bottom, td.valign-bottom { vertical-align: bottom; }
th.valign-middle, td.valign-middle { vertical-align: middle; }
table thead th, table tfoot th { font-weight: bold; }
tbody tr th { display: table-cell; line-height: 1.4; background: -webkit-linear-gradient(top, #add386, #90b66a); }
tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: white; font-weight: bold; }
p.tableblock > code:only-child { background: none; padding: 0; }
p.tableblock { font-size: 1em; }
td > div.verse { white-space: pre; }
ol { margin-left: 1.75em; }
ul li ol { margin-left: 1.5em; }
dl dd { margin-left: 1.125em; }
dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; }
ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.375em; }
ul.checklist, ul.none, ol.none, ul.no-bullet, ol.no-bullet, ol.unnumbered, ul.unstyled, ol.unstyled { list-style-type: none; }
ul.no-bullet, ol.no-bullet, ol.unnumbered { margin-left: 0.625em; }
ul.unstyled, ol.unstyled { margin-left: 0; }
ul.checklist { margin-left: 0.625em; }
ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1.25em; font-size: 0.8em; position: relative; bottom: 0.125em; }
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { margin-right: 0.25em; }
ul.inline { display: -ms-flexbox; display: -webkit-box; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; list-style: none; margin: 0 0 0.375em -0.75em; }
ul.inline > li { margin-left: 0.75em; }
.unstyled dl dt { font-weight: normal; font-style: normal; }
ol.arabic { list-style-type: decimal; }
ol.decimal { list-style-type: decimal-leading-zero; }
ol.loweralpha { list-style-type: lower-alpha; }
ol.upperalpha { list-style-type: upper-alpha; }
ol.lowerroman { list-style-type: lower-roman; }
ol.upperroman { list-style-type: upper-roman; }
ol.lowergreek { list-style-type: lower-greek; }
.hdlist > table, .colist > table { border: 0; background: none; }
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
td.hdlist1, td.hdlist2 { vertical-align: top; padding: 0 0.625em; }
td.hdlist1 { font-weight: bold; padding-bottom: 0.75em; }
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
.colist > table tr > td:first-of-type { padding: 0.4em 0.75em 0 0.75em; line-height: 1; vertical-align: top; }
.colist > table tr > td:first-of-type img { max-width: initial; }
.colist > table tr > td:last-of-type { padding: 0.25em 0; }
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
.imageblock > .title { margin-bottom: 0; }
.imageblock.thumb, .imageblock.th { border-width: 6px; }
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
.image.left { margin-right: 0.625em; }
.image.right { margin-left: 0.625em; }
a.image { text-decoration: none; display: inline-block; }
a.image object { pointer-events: none; }
sup.footnote, sup.footnoteref { font-size: 0.875em; position: static; vertical-align: super; }
sup.footnote a, sup.footnoteref a { text-decoration: none; }
sup.footnote a:active, sup.footnoteref a:active { text-decoration: underline; }
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
#footnotes hr { width: 20%; min-width: 6.25em; margin: -0.25em 0 0.75em 0; border-width: 1px 0 0 0; }
#footnotes .footnote { padding: 0 0.375em 0 0.225em; line-height: 1.3334; font-size: 0.875em; margin-left: 1.2em; margin-bottom: 0.2em; }
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; margin-left: -1.05em; }
#footnotes .footnote:last-of-type { margin-bottom: 0; }
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
.gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; }
.gist .file-data > table td.line-data { width: 99%; }
div.unbreakable { page-break-inside: avoid; }
.big { font-size: larger; }
.small { font-size: smaller; }
.underline { text-decoration: underline; }
.overline { text-decoration: overline; }
.line-through { text-decoration: line-through; }
.aqua { color: #00bfbf; }
.aqua-background { background-color: #00fafa; }
.black { color: black; }
.black-background { background-color: black; }
.blue { color: #0000bf; }
.blue-background { background-color: #0000fa; }
.fuchsia { color: #bf00bf; }
.fuchsia-background { background-color: #fa00fa; }
.gray { color: #606060; }
.gray-background { background-color: #7d7d7d; }
.green { color: #006000; }
.green-background { background-color: #007d00; }
.lime { color: #00bf00; }
.lime-background { background-color: #00fa00; }
.maroon { color: #600000; }
.maroon-background { background-color: #7d0000; }
.navy { color: #000060; }
.navy-background { background-color: #00007d; }
.olive { color: #606000; }
.olive-background { background-color: #7d7d00; }
.purple { color: #600060; }
.purple-background { background-color: #7d007d; }
.red { color: #bf0000; }
.red-background { background-color: #fa0000; }
.silver { color: #909090; }
.silver-background { background-color: #bcbcbc; }
.teal { color: #006060; }
.teal-background { background-color: #007d7d; }
.white { color: #bfbfbf; }
.white-background { background-color: #fafafa; }
.yellow { color: #bfbf00; }
.yellow-background { background-color: #fafa00; }
span.icon > .fa { cursor: default; }
a span.icon > .fa { cursor: inherit; }
.admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; }
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #29475c; }
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; }
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; }
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; }
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; }
.conum[data-value] { display: inline-block; color: #fff !important; background-color: black; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; }
.conum[data-value] * { color: #fff !important; }
.conum[data-value] + b { display: none; }
.conum[data-value]:after { content: attr(data-value); }
pre .conum[data-value] { position: relative; top: -0.125em; }
b.conum * { color: inherit !important; }
.conum:not([data-value]):empty { display: none; }
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { border-bottom: 1px solid #dddddd; }
.sect1 { padding-bottom: 0; }
#toctitle { color: #00406F; font-weight: normal; margin-top: 1.5em; }
.sidebarblock { border-color: #aaa; }
code { -webkit-border-radius: 4px; border-radius: 4px; }
p.tableblock.header { color: #6d6e71; }
.literalblock pre, .listingblock pre { background: #eeeeee; }
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<style>
/* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
/*pre.CodeRay {background-color:#f7f7f8;}*/
.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
.CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
table.CodeRay td{vertical-align: top;line-height:1.45}
table.CodeRay td.line-numbers{text-align:right}
table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
table.CodeRay td.code{padding:0 0 0 .5em}
table.CodeRay td.code>pre{padding:0}
.CodeRay .debug{color:#fff !important;background:#000080 !important}
.CodeRay .annotation{color:#007}
.CodeRay .attribute-name{color:#000080}
.CodeRay .attribute-value{color:#700}
.CodeRay .binary{color:#509}
.CodeRay .comment{color:#998;font-style:italic}
.CodeRay .char{color:#04d}
.CodeRay .char .content{color:#04d}
.CodeRay .char .delimiter{color:#039}
.CodeRay .class{color:#458;font-weight:bold}
.CodeRay .complex{color:#a08}
.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
.CodeRay .color{color:#099}
.CodeRay .class-variable{color:#369}
.CodeRay .decorator{color:#b0b}
.CodeRay .definition{color:#099}
.CodeRay .delimiter{color:#000}
.CodeRay .doc{color:#970}
.CodeRay .doctype{color:#34b}
.CodeRay .doc-string{color:#d42}
.CodeRay .escape{color:#666}
.CodeRay .entity{color:#800}
.CodeRay .error{color:#808}
.CodeRay .exception{color:inherit}
.CodeRay .filename{color:#099}
.CodeRay .function{color:#900;font-weight:bold}
.CodeRay .global-variable{color:#008080}
.CodeRay .hex{color:#058}
.CodeRay .integer,.CodeRay .float{color:#099}
.CodeRay .include{color:#555}
.CodeRay .inline{color:#000}
.CodeRay .inline .inline{background:#ccc}
.CodeRay .inline .inline .inline{background:#bbb}
.CodeRay .inline .inline-delimiter{color:#d14}
.CodeRay .inline-delimiter{color:#d14}
.CodeRay .important{color:#555;font-weight:bold}
.CodeRay .interpreted{color:#b2b}
.CodeRay .instance-variable{color:#008080}
.CodeRay .label{color:#970}
.CodeRay .local-variable{color:#963}
.CodeRay .octal{color:#40e}
.CodeRay .predefined{color:#369}
.CodeRay .preprocessor{color:#579}
.CodeRay .pseudo-class{color:#555}
.CodeRay .directive{font-weight:bold}
.CodeRay .type{font-weight:bold}
.CodeRay .predefined-type{color:inherit}
.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
.CodeRay .key{color:#808}
.CodeRay .key .delimiter{color:#606}
.CodeRay .key .char{color:#80f}
.CodeRay .value{color:#088}
.CodeRay .regexp .delimiter{color:#808}
.CodeRay .regexp .content{color:#808}
.CodeRay .regexp .modifier{color:#808}
.CodeRay .regexp .char{color:#d14}
.CodeRay .regexp .function{color:#404;font-weight:bold}
.CodeRay .string{color:#d20}
.CodeRay .string .string .string{background:#ffd0d0}
.CodeRay .string .content{color:#d14}
.CodeRay .string .char{color:#d14}
.CodeRay .string .delimiter{color:#d14}
.CodeRay .shell{color:#d14}
.CodeRay .shell .delimiter{color:#d14}
.CodeRay .symbol{color:#990073}
.CodeRay .symbol .content{color:#a60}
.CodeRay .symbol .delimiter{color:#630}
.CodeRay .tag{color:#008080}
.CodeRay .tag-special{color:#d70}
.CodeRay .variable{color:#036}
.CodeRay .insert{background:#afa}
.CodeRay .delete{background:#faa}
.CodeRay .change{color:#aaf;background:#007}
.CodeRay .head{color:#f8f;background:#505}
.CodeRay .insert .insert{color:#080}
.CodeRay .delete .delete{color:#800}
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
</style>
<link rel="stylesheet" href="../katex/katex.min.css">
<script src="../katex/katex.min.js"></script>
<script src="../katex/contrib/auto-render.min.js"></script>
<!-- Use KaTeX to render math once document is loaded, see
https://github.com/Khan/KaTeX/tree/master/contrib/auto-render -->
<script>
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(
document.body,
{
delimiters: [
{ left: "$$", right: "$$", display: true},
{ left: "\\[", right: "\\]", display: true},
{ left: "$", right: "$", display: false},
{ left: "\\(", right: "\\)", display: false}
]
}
);
});
</script></head>
<body class="book toc2 toc-left" style="max-width: 100;">
<div id="header">
<h1>The OpenCL<sup>&#8482;</sup> C++ 1.0 Specification</h1>
<div class="details">
<span id="author" class="author">Khronos OpenCL Working Group</span><br>
<span id="revnumber">version 2.2-8,</span>
<span id="revdate">Mon, 08 Oct 2018 16:50:47 +0000</span>
<br><span id="revremark">from git branch: master commit: b3cab22fcff5d8c17869907c983e259ddd7ce788</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#generic-type-name-notation">1. Generic Type Name Notation</a></li>
<li><a href="#openclcpp-programming-language">2. OpenCL C++ Programming Language</a>
<ul class="sectlevel2">
<li><a href="#supported-builtin-data-types">2.1. Supported Built-in Data Types</a></li>
<li><a href="#keywords">2.2. Keywords</a></li>
<li><a href="#implicit-type-conversions">2.3. Implicit Type Conversions</a></li>
<li><a href="#expressions">2.4. Expressions</a></li>
<li><a href="#address-spaces">2.5. Address Spaces</a></li>
<li><a href="#kernel-functions">2.6. Kernel Functions</a></li>
<li><a href="#preprocessor-directives-and-macros">2.7. Preprocessor Directives and Macros</a></li>
<li><a href="#attribute-qualifiers">2.8. Attribute Qualifiers</a></li>
<li><a href="#opencl_cxx_restrictions">2.9. Restrictions</a></li>
</ul>
</li>
<li><a href="#opencl-c-standard-library">3. OpenCL C++ Standard Library</a>
<ul class="sectlevel2">
<li><a href="#opencl-definitions">3.1. OpenCL Definitions</a></li>
<li><a href="#conversions-library">3.2. Conversions Library</a></li>
<li><a href="#reinterpreting-data-library">3.3. Reinterpreting Data Library</a></li>
<li><a href="#address-spaces-library">3.4. Address Spaces Library</a></li>
<li><a href="#specialization-constants-library">3.5. Specialization Constants Library</a></li>
<li><a href="#half-wrapper-library">3.6. Half Wrapper Library</a></li>
<li><a href="#vector-wrapper-library">3.7. Vector Wrapper Library</a></li>
<li><a href="#range-library">3.8. Range Library</a></li>
<li><a href="#vector-utilities-library">3.9. Vector Utilities Library</a></li>
<li><a href="#marker-types">3.10. Marker Types</a></li>
<li><a href="#images-and-samplers-library">3.11. Images and Samplers Library</a></li>
<li><a href="#pipes-library">3.12. Pipes Library</a></li>
<li><a href="#device-enqueue-library">3.13. Device Enqueue Library</a></li>
<li><a href="#work-item-functions">3.14. Work-Item Functions</a></li>
<li><a href="#work-group-functions">3.15. Work-group Functions</a></li>
<li><a href="#synchronization-functions">3.16. Synchronization Functions</a></li>
<li><a href="#common-functions">3.17. Common Functions</a></li>
<li><a href="#geometric-functions">3.18. Geometric Functions</a></li>
<li><a href="#math-functions">3.19. Math Functions</a></li>
<li><a href="#integer-functions">3.20. Integer Functions</a></li>
<li><a href="#relational-functions">3.21. Relational Functions</a></li>
<li><a href="#vector-data-load-and-store-functions">3.22. Vector Data Load and Store Functions</a></li>
<li><a href="#printf">3.23. printf</a></li>
<li><a href="#atomic-operations-library">3.24. Atomic Operations Library</a></li>
<li><a href="#array-library">3.25. Array Library</a></li>
<li><a href="#limits-library">3.26. Limits Library</a></li>
<li><a href="#math-constants-library">3.27. Math Constants Library</a></li>
<li><a href="#tuple-library">3.28. Tuple Library</a></li>
<li><a href="#type-traits-library">3.29. Type Traits Library</a></li>
<li><a href="#iterator-library">3.30. Iterator Library</a></li>
<li><a href="#general-utilities-library">3.31. General Utilities Library</a></li>
</ul>
</li>
<li><a href="#opencl-numerical-compliance">4. OpenCL Numerical Compliance</a>
<ul class="sectlevel2">
<li><a href="#rounding-modes-1">4.1. Rounding Modes</a></li>
<li><a href="#inf-nan-and-denormalized-numbers">4.2. INF, NaN and Denormalized Numbers</a></li>
<li><a href="#floating-point-exceptions">4.3. Floating-Point Exceptions</a></li>
<li><a href="#relative-error-as-ulps">4.4. Relative Error as ULPs</a></li>
<li><a href="#edge-case-behavior">4.5. Edge Case Behavior</a></li>
</ul>
</li>
<li><a href="#image-addressing-and-filtering">5. Image Addressing and Filtering</a>
<ul class="sectlevel2">
<li><a href="#image-coordinates">5.1. Image Coordinates</a></li>
<li><a href="#addressing-and-filter-modes">5.2. Addressing and Filter Modes</a></li>
<li><a href="#conversion-rules">5.3. Conversion Rules</a></li>
<li><a href="#selecting-an-image-from-an-image-array">5.4. Selecting an Image from an Image Array</a></li>
</ul>
</li>
<li><a href="#compiler_options">6. Compiler options</a>
<ul class="sectlevel2">
<li><a href="#preprocessor_options">6.1. Preprocessor options</a></li>
<li><a href="#options-controlling_the-opencl_c_version">6.2. Options Controlling the OpenCL C++ version</a></li>
<li><a href="#fp16_and_fp64_options">6.3. Double and half-precision floating-point options</a></li>
<li><a href="#other_options">6.4. Other options</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Copyright 2008-2018 The Khronos Group.</p>
</div>
<div class="paragraph">
<p>This specification is protected by copyright laws and contains material proprietary
to the Khronos Group, Inc. Except as described by these terms, it or any components
may not be reproduced, republished, distributed, transmitted, displayed, broadcast
or otherwise exploited in any manner without the express prior written permission
of Khronos Group.</p>
</div>
<div class="paragraph">
<p>Khronos Group grants a conditional copyright license to use and reproduce the
unmodified specification for any purpose, without fee or royalty, EXCEPT no licenses
to any patent, trademark or other intellectual property rights are granted under
these terms. Parties desiring to implement the specification and make use of
Khronos trademarks in relation to that implementation, and receive reciprocal patent
license protection under the Khronos IP Policy must become Adopters and confirm the
implementation as conformant under the process defined by Khronos for this
specification; see <a href="https://www.khronos.org/adopters" class="bare">https://www.khronos.org/adopters</a>.</p>
</div>
<div class="paragraph">
<p>Khronos Group makes no, and expressly disclaims any, representations or warranties,
express or implied, regarding this specification, including, without limitation:
merchantability, fitness for a particular purpose, non-infringement of any
intellectual property, correctness, accuracy, completeness, timeliness, and
reliability. Under no circumstances will the Khronos Group, or any of its Promoters,
Contributors or Members, or their respective partners, officers, directors,
employees, agents or representatives be liable for any damages, whether direct,
indirect, special or consequential damages for lost revenues, lost profits, or
otherwise, arising from or in connection with these materials.</p>
</div>
<div class="paragraph">
<p>Vulkan is a registered trademark and Khronos, OpenXR, SPIR, SPIR-V, SYCL, WebGL,
WebCL, OpenVX, OpenVG, EGL, COLLADA, glTF, NNEF, OpenKODE, OpenKCAM, StreamInput,
OpenWF, OpenSL ES, OpenMAX, OpenMAX AL, OpenMAX IL, OpenMAX DL, OpenML and DevU are
trademarks of the Khronos Group Inc. ASTC is a trademark of ARM Holdings PLC,
OpenCL is a trademark of Apple Inc. and OpenGL and OpenML are registered trademarks
and the OpenGL ES and OpenGL SC logos are trademarks of Silicon Graphics
International used under license by Khronos. All other product names, trademarks,
and/or company names are used solely for identification and belong to their
respective owners.</p>
</div>
<div style="page-break-after: always;"></div>
<h2 id="acknowledgements" class="float">Acknowledgements</h2>
<div class="paragraph">
<p>The OpenCL C++ specification is the result of the contributions of many people, representing a cross section of the desktop, hand-held, and embedded computer industry.
Following is a partial list of the contributors, including the company that they represented at the time of their contribution:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Eric Berdahl, Adobe</p>
</li>
<li>
<p>Aaftab Munshi, Apple</p>
</li>
<li>
<p>Brian Sumner, AMD</p>
</li>
<li>
<p>Andrew Richards, Codeplay</p>
</li>
<li>
<p>Maria Rovatsou, Codeplay</p>
</li>
<li>
<p>Adam Stański, Intel</p>
</li>
<li>
<p>Alexey Bader, Intel</p>
</li>
<li>
<p>Allen Hux, Intel</p>
</li>
<li>
<p>Bartosz Sochacki, Intel</p>
</li>
<li>
<p>Ben Ashbaugh, Intel</p>
</li>
<li>
<p>Kevin Stevens, Intel</p>
</li>
<li>
<p>Łukasz Dudziak, Intel</p>
</li>
<li>
<p>Łukasz Towarek, Intel</p>
</li>
<li>
<p>Marcin Walkowiak, Intel</p>
</li>
<li>
<p>Michael Kinsner, Intel</p>
</li>
<li>
<p>Raun Krisch, Intel</p>
</li>
<li>
<p>Tomasz Fiechowski, Intel</p>
</li>
<li>
<p>Kedar Patil, NVIDIA</p>
</li>
<li>
<p>Yuan Lin, NVIDIA</p>
</li>
<li>
<p>Alex Bourd, Qualcomm</p>
</li>
<li>
<p>Lee Howes, Qualcomm</p>
</li>
<li>
<p>Anton Gorenko, StreamComputing</p>
</li>
<li>
<p>Jakub Szuppe, StreamComputing</p>
</li>
<li>
<p>James Price, University of Bristol</p>
</li>
<li>
<p>Paul Preney, University of Windsor</p>
</li>
<li>
<p>Ronan Keryell, Xilinx</p>
</li>
<li>
<p>AJ Guillon, YetiWare Inc.</p>
</li>
</ul>
</div>
<div style="page-break-after: always;"></div>
</div>
</div>
<div class="sect1">
<h2 id="generic-type-name-notation">1. Generic Type Name Notation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The generic type names are used when some entity has multiple overloads which differ only by argument(s).
They can map to one or more built-in data types.
The tables below describe these mappings in details.</p>
</div>
<div class="paragraph">
<p>Assuming that <code>gentype</code> maps to built-in types: <code>float</code>, <code>int</code> and <code>uint</code>, when coming across definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype function(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>reader should understand that such function has in fact three overloads:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float function(float x);
int function(int x);
uint function(uint x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that if a function signature has multiple usages of <code>gentype</code> they all should map to the same type.
Following this rule such overloads are then invalid:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float function(int x);
uint function(float x);
// etc.</code></pre>
</div>
</div>
<div class="paragraph">
<p>If a function is meant to have such overloads, respective gentypes in its signature should be postfixed with numbers to indicate they represent different types.
Declaration like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>cl::common_type_t&lt;gentype1, gentype2&gt; greater(gentype1 x, gentype2 y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>would match following overloads:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>cl::common_type_t&lt;float, float&gt; greater(float x, float y);
cl::common_type_t&lt;float, int&gt; greater(float x, int y);
cl::common_type_t&lt;float, uint&gt; greater(float x, uint y);
cl::common_type_t&lt;int, float&gt; greater(int x, float y);
// etc.</code></pre>
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 1. generic types</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>generic type</strong></th>
<th class="tableblock halign-left valign-top"><strong>corresponding built-in types</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>typen</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>scalar and all vector types of type</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="paragraph">
<p><code>floatn</code> matches: <code>float</code>, <code>float2</code>, <code>float3</code>, <code>float4</code>, <code>float8</code> and <code>float16</code><br>
<code>floatn</code> doesn&#8217;t match: <code>half</code>, <code>int2</code></p>
</div>
</div>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gentype</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">unspecified in global context, should be defined whenever used</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sgentype</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subset of scalar types from types matched by <code>gentype</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ugentype</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subset of unsigned integer types from types matched by <code>gentype</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gentypeh</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>half</code>, <code>half2</code>, <code>half3</code>, <code>half4</code>, <code>half8</code> or <code>half16</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gentypef</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>float</code>, <code>float2</code>, <code>float3</code>, <code>float4</code>, <code>float8</code> or <code>float16</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gentyped</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>double</code>, <code>double2</code>, <code>double3</code>, <code>double4</code>, <code>double8</code> or <code>double16</code></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="openclcpp-programming-language">2. OpenCL C++ Programming Language</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This section describes the OpenCL C++ programming language used to create kernels that are executed on OpenCL device(s).
The OpenCL C++ programming language is based on the ISO/IEC JTC1 SC22 WG21 N 3690 language specification (a.k.a. C++14 specification) with specific restrictions (see the <a href="#opencl_cxx_restrictions"><em>OpenCL C++ restrictions</em></a> section).
Please refer to this specification for a detailed description of the language grammar.
This section describes restrictions to the C++14 specification supported in OpenCL C++.</p>
</div>
<div class="sect2">
<h3 id="supported-builtin-data-types">2.1. Supported Built-in Data Types</h3>
<div class="paragraph">
<p>The following data types are supported.</p>
</div>
<div class="sect3">
<h4 id="builtin-scalar-data-types">2.1.1. Built-in Scalar Data Types</h4>
<table id="device_builtin_scalar_data_types" class="tableblock frame-all grid-all spread">
<caption class="title">Table 2. Device Built-in scalar data types</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Type</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>bool</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A data type which is either <code>true</code> or <code>false</code>. (<em>See section 2.14.6 lex.bool and section 3.9.1 basic.fundamental of the C++14 Specification.</em>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>char</code>, <code>signed char</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A signed two&#8217;s complement 8-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned char</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An unsigned 8-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>short</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A signed two&#8217;s complement 16-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned short</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An unsigned 16-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>int</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A signed two&#8217;s complement 32-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned int</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An unsigned 32-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>long</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A signed two&#8217;s complement 64-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned long</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An unsigned 64-bit integer.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>float</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A 32-bit floating-point.
The float data type must conform to the IEEE 754 single precision storage format.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>double</code> <a id="ftnref2"></a> <a href="#ftn2">[2]</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A 64-bit floating-point.
The double data type must conform to the IEEE 754 double precision storage format.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>half</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A 16-bit floating-point.
The half data type must conform to the IEEE 754-2008 half precision storage format.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>void</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The <code>void</code> type comprises an empty set of values; it is an incomplete type that cannot be completed.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Most built-in scalar data types are also declared as appropriate types in the OpenCL API (and header files) that can be used by an application.
The following table describes the built-in scalar data type in the OpenCL C++ programming language and the corresponding data type available to the application:</p>
</div>
<table id="host_scalar_builtin_data_types" class="tableblock frame-all grid-all spread">
<caption class="title">Table 3. Host Scalar Built-in Data Types</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Type in OpenCL Language</strong></th>
<th class="tableblock halign-left valign-top"><strong>API type for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>bool</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">n/a, i.e., there is no corresponding <code>cl_bool</code> type.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>char</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_char</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned char</code>, <code>uchar</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_uchar</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>short</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_short</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned short</code>, <code>ushort</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_ushort</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>int</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_int</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned int</code>, <code>uint</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_uint</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>long</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_long</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unsigned long</code>, <code>ulong</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_ulong</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>float</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_float</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>double</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_double</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>half</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_half</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>void</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>void</code></p></td>
</tr>
</tbody>
</table>
<div class="sect4">
<h5 id="builtin-half-data-type">Built-in Half Data Type</h5>
<div class="paragraph">
<p>The <code>half</code> data type must be IEEE 754-2008 compliant.
<code>half</code> numbers have 1 sign bit, 5 exponent bits, and 10 mantissa bits.
The interpretation of the sign, exponent and mantissa is analogous to IEEE 754 floating-point numbers.</p>
</div>
<div class="paragraph">
<p>The exponent bias is 15.
The <code>half</code> data type must represent finite and normal numbers, denormalized numbers, infinities and NaN.
Denormalized numbers for the <code>half</code> data type which may be generated when converting a <code>float</code> to a <code>half</code> using <code>vstore_half</code> and converting a <code>half</code> to a <code>float</code> using <code>vload_half</code> cannot be flushed to zero.</p>
</div>
<div class="paragraph">
<p>Conversions from <code>float</code> to <code>half</code> correctly round the mantissa to 11 bits of precision.</p>
</div>
<div class="paragraph">
<p>Conversions from <code>half</code> to <code>float</code> are lossless; all <code>half</code> numbers are exactly representable as <code>float</code> values.</p>
</div>
<div class="paragraph">
<p>The <code>half</code> data type can only be used to declare a pointer to a buffer that contains <code>half</code> values.
All other operations are not allowed if the <strong>cl_khr_fp16</strong> extension is not supported.</p>
</div>
<div class="paragraph">
<p>A few valid examples are given below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_def&gt;
#include &lt;opencl_memory&gt;
#include &lt;opencl_vector_load_store&gt;
float bar(half *a) {
return cl::vload_half&lt; 1 &gt;(0, a);
}
kernel void foo(cl::global_ptr&lt;half&gt; pg) { //ok: a global pointer
// passed from the host
int offset = 1;
half *ptr = pg.get() + offset; //ok: half pointer arithmetic
float b = bar(ptr);
if(b &lt; *ptr) { //not allowed: it is only supported if cl_khr_fp16
// extension is enabled
//...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>half</code> scalar data type is required to be supported as a data storage format.
Vector data load and store functions (described in the <a href="#vector-data-load-and-store-functions"><em>Vector Data Load and Store Functions</em></a> section) must be supported.</p>
</div>
</div>
<div class="sect4">
<h5 id="cl_khr_fp16-extension"><strong>cl_khr_fp16</strong> extension</h5>
<div class="paragraph">
<p>This extension adds support for <code>half</code> scalar and vector types as built-in types that can be used for arithmetic operations, conversions etc.
An application that wants to use <code>half</code> and <code>halfn</code> types will need to specify the <code>-cl-fp16-enable</code> compiler option (see the <a href="#fp16_and_fp64_options"><em>Double and half-precision floating-point options</em></a> section).</p>
</div>
<div class="paragraph">
<p>The OpenCL compiler accepts an h and H suffix on floating point literals, indicating the literal is typed as a <code>half</code></p>
</div>
<div class="paragraph">
<p>A few valid examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_def&gt;
#include &lt;opencl_memory&gt;
half bar(half a) {
half b = a;
b += 10.0h; //ok: cl_khr_fp16 extension is enabled. All arithmetic
// operations on half built-in type are available
return b;
}
kernel void foo(cl::global_ptr&lt;half&gt; pg) {
int offset = 1;
half *ptr = pg.get() + offset;
half b = bar(*ptr);
if(b &lt; *ptr) { //ok: cl_khr_fp16 extension is enabled.
// All comparison operations are available
//...
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="hexadecimal-floating-point-literals">Hexadecimal floating point literals</h5>
<div class="paragraph">
<p>Hexadecimal floating point literals are supported in OpenCL C++.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float f = 0x1.fffffep127f
double d = 0x1.fffffffffffffp1023;
half h = 0x1.ffcp15h;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="builtin-vector-data-types">2.1.2. Built-in Vector Data Types</h4>
<div class="sect4">
<h5 id="supported-vector-data-types">Supported Vector Data Types</h5>
<div class="paragraph">
<p>The <code>bool</code>, <code>char</code>, <code>unsigned char</code>, <code>short</code>, <code>unsigned short</code>, <code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>, <code>half</code>, <code>float</code> and <code>double</code> vector data types are supported.
The vector data type is defined with the type name i.e. <code>bool</code>, <code>char</code>, <code>uchar</code>, <code>short</code>, <code>ushort</code>, <code>int</code>, <code>uint</code>, <code>long</code>, <code>ulong</code>, <code>half</code>, <code>float</code> or <code>double</code> followed by a literal value <em>n</em> that defines the number of elements in the vector.
Supported values of <em>n</em> are 2, 3, 4, 8, and 16 for all vector data types.</p>
</div>
<table id="device_builtin_vector_data_types" class="tableblock frame-all grid-all spread">
<caption class="title">Table 4. Device Built-in Vector Data Types</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Type</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>bool<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> boolean values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>char<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 8-bit signed two&#8217;s complement integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>uchar<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 8-bit unsigned integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>short<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">vector of <em>n</em> 16-bit signed two&#8217;s complement integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ushort<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 16-bit unsigned integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>int<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 32-bit signed two&#8217;s complement integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>uint<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 32-bit unsigned integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>long<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 64-bit signed two&#8217;s complement integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ulong<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 64-bit unsigned integer values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>half<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 16-bit floating-point values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>float<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 32-bit floating-point values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>double<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A vector of <em>n</em> 64-bit floating-point values.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The built-in vector data types are also declared as appropriate types in the OpenCL API (and header files) that can be used by an application.
The following table describes the built-in vector data type in the OpenCL C++ programming language and the corresponding data type available to the application:</p>
</div>
<table id="host_builtin_vector_data_types" class="tableblock frame-all grid-all spread">
<caption class="title">Table 5. Host Built-in Vector Data Types</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Type in OpenCL Language</strong></th>
<th class="tableblock halign-left valign-top"><strong>API type for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>bool<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">n/a, i.e., there is no corresponding <code>cl_bool<em>n</em></code> type.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>char<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_char<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>uchar<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_uchar<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>short<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_short<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ushort<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_ushort<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>int<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_int<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>uint<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_uint<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>long<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_long<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ulong<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_ulong<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>half<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_half<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>float<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_float<em>n</em></code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>double<em>n</em></code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_double<em>n</em></code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The <code>half<em>n</em></code> vector data type is required to be supported as a data storage format.
Vector data load and store functions (described in the <a href="#vector-data-load-and-store-functions"><em>Vector Data Load and Store Functions</em></a> section) must be supported.</p>
</div>
<div class="paragraph">
<p>Support for the <code>double<em>n</em></code> vector data type is optional.</p>
</div>
</div>
<div class="sect4">
<h5 id="vector-changes-to-cpp14-standard">Vector Changes to C++14 standard</h5>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Vector types are classified as fundamental (<em>[ISO/IEC 14882:2014: basic.fundamental, ch. 3.9.1]</em>) and literal types</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
A vector type behave similarly to a trivially destructible class with all data members of literal type and all of its constructors defined as constexpr constructors
</td>
</tr>
</table>
</div>
</li>
<li>
<p>Abbreviating vector type as Tn, T is called the component type of a vector.
The numerical value n specifies number of components in a vector.
<a href="#device_builtin_vector_data_types">Device built-in vector data types</a> table specifies supported vector types.</p>
<div class="paragraph">
<p>A vector type which component type is <em>integral type</em> is called <em>integral vector type</em>.
A vector type which component is <em>floating-point type</em> is called <em>floating-point vector type</em>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float8 a; // component type: float, number of components: 8
uint16 b; // component type: uint, number of components: 16</code></pre>
</div>
</div>
</li>
<li>
<p>An <em>integral vector type</em> can be used as type of value of non-type template-parameter.
The change is introduced by following changes in C++ specification:</p>
<div class="openblock">
<div class="content">
<div class="ulist">
<ul>
<li>
<p><em>[ISO/IEC 14882:2014: temp.param, ch. 14.1 (4, 4.1)]</em> Template parameters: A non-type template-parameter shall have one of the following (optionally cv-qualified) types:</p>
<div class="ulist">
<ul>
<li>
<p>integral, integral vector or enumeration type,</p>
</li>
<li>
<p>integral, integral vector or enumeration type,</p>
</li>
<li>
<p>[ &#8230;&#8203; ]</p>
</li>
</ul>
</div>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: temp.param, ch. 14.1 (7)]</em> Template parameters: A non-type <em>template-parameter</em> shall not be declared to have floating point, floating-point vector, class, or void type.</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: temp.type, ch. 14.4 (1, 1.3)]</em> Type equivalence: Two <em>template-ids</em> refer to the same class, function, or variable if</p>
<div class="ulist">
<ul>
<li>
<p>[ &#8230;&#8203; ]</p>
</li>
<li>
<p>their corresponding non-type template arguments of integral, integral vector or enumeration type have identical values and</p>
</li>
<li>
<p>[ &#8230;&#8203; ]</p>
</li>
</ul>
</div>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: temp.res, ch. 14.6 (8, 8.3, 8.3.1)]</em> Name resolution: [&#8230;&#8203;] If the interpretation of such a construct in the hypothetical instantiation is different from the interpretation of the corresponding construct</p>
<div class="ulist">
<ul>
<li>
<p>integral, integral vector or enumeration type, in any actual instantiation of the template, the program is ill-formed; no diagnostic is required.
This can happen in situations including the following:</p>
</li>
<li>
<p>[ &#8230;&#8203; ]</p>
</li>
<li>
<p>constant expression evaluation (5.20) within the template instantiation uses</p>
<div class="ulist">
<ul>
<li>
<p>the value of a const object of integral, integral vector or unscoped enumeration type or</p>
</li>
<li>
<p>[ &#8230;&#8203; ]</p>
</li>
</ul>
</div>
</li>
<li>
<p>[ &#8230;&#8203; ]</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
</li>
</ol>
</div>
</div>
<div class="sect4">
<h5 id="vector-component-access">Vector Component Access</h5>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The components of vector type can be accessed using swizzle expression.
The syntax of a swizzle expression is similar to syntax used in class member access expression <em>[ISO/IEC 14882:2014: expr.ref, ch. 5.2.5]</em>:
The swizzle expression is a postfix expression formed with a postfix expression followed by a dot <code>.</code> or an arrow <code>-&gt;</code> and then followed by an <em>vector-swizzle-selector</em>. The postfix expression before the dot or arrow is evaluated. The result of that evaluation, together with the <em>vector-swizzle-selector</em>, determines the result of the entire postfix expression.</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float4 v1 = float4(1.0f, 2.0f, 3.0f, 4.0f);
float4 *pv1 = &amp;v1;
float2 v2 = v1.xz; // v1.xz is a swizzle expression
float3 v3 = pv1-&gt;s321; // pv1-&gt;s321 is a swizzle expression
// equivalent to (*pv1).s321
(*pv1).rgb = float3(0.0f, 0.5f, 1.0f); // (*pv1).rgb is a swizzle expression
pv1-&gt;lo.hi = 0.0f; // pv1-&gt;lo and pv1-&gt;lo.hi are swizzle
// expressions</code></pre>
</div>
</div>
</li>
<li>
<p>For the first option (dot) the first expression shall have vector type or be a swizzle expression which results in vector-swizzle of vector type.
For the second option (arrow) the first expression shall have pointer to vector type.
The expression <code>E1-&gt;E2</code> is converted to the equivalent form <code>(*(E1)).E2</code>; the remainder of <a href="#vector-component-access">Vector Component Access</a> will address only the first option (dot).</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<code>(*(E1))</code> is lvalue. In either case, the <em>vector-swizzle-selector</em> shall name a vector component selection of a swizzle.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>uint8 v1 = uint8(10, 11, 12, 13, 14, 15, 16, 17);
uint4 v2 = v1.s7301; // correct
uint3 v3 = (&amp;v1)-&gt;s246; // correct
uint4 v4 = v1-&gt;s0123; // ill-formed: v1 is not a pointer to
// vector type
uint8 *pv1 = &amp;v1;
uint2 v5 = pv1-&gt;S13; // correct
uint2 v6 = (*pv1).s0745.even; // correct
uint4 v7 = pv1.odd; // ill-formed: pv1 is not vector or
// vector-swizzle</code></pre>
</div>
</div>
</li>
<li>
<p>Abbreviating <em>postfix-expression.vector-swizzle-selector</em> as <code>E1.E2</code>, <code>E1</code> is called the vector expression.
The type and value category of <code>E1.E2</code> are determined as follows.
In the remainder of <a href="#vector-component-access">Vector Component Access</a>, <em>cq</em> represents either <code>const</code> or the absence of <code>const</code> and <em>vq</em> represents either <code>volatile</code> or the absence of <code>volatile</code>.
cv represents an arbitrary set of cv-qualifiers, as defined in <em>[ISO/IEC 14882:2014: basic.type.qualifier, ch. 3.9.3]</em> .</p>
</li>
<li>
<p><em>vector-swizzle-selector</em> is subset of <em>identifier</em> with following syntax:</p>
<div class="openblock">
<div class="content">
<div class="paragraph">
<p>
<em>vector-swizzle-selector</em>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>vector-swizzle-xyzw-selector</em>:</p>
<div class="ulist">
<ul>
<li>
<p><em>vector-swizzle-xyzw-selector-value</em></p>
</li>
<li>
<p><em>vector-swizzle-xyzw-selector vector-swizzle-xyzw-selector-value</em></p>
</li>
</ul>
</div>
</li>
<li>
<p><em>vector-swizzle-rgba-selector</em>:</p>
<div class="ulist">
<ul>
<li>
<p><em>vector-swizzle-rgba-selector-value</em></p>
</li>
<li>
<p><em>vector-swizzle-rgba-selector vector-swizzle-rgba-selector-value</em></p>
</li>
</ul>
</div>
</li>
<li>
<p><em>vector-swizzle-special-selector</em>:</p>
<div class="ulist">
<ul>
<li>
<p><code>hi</code></p>
</li>
<li>
<p><code>lo</code></p>
</li>
<li>
<p><code>even</code></p>
</li>
<li>
<p><code>odd</code></p>
</li>
</ul>
</div>
</li>
<li>
<p><em>vector-swizzle-num-selector</em>:</p>
<div class="ulist">
<ul>
<li>
<p><code>s</code> <em>vector-swizzle-num-selector-values</em></p>
</li>
<li>
<p><code>S</code> <em>vector-swizzle-num-selector-values</em></p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="openblock">
<div class="content">
<div class="paragraph">
<p>
<em>vector-swizzle-num-selector-values</em>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>vector-swizzle-num-selector-value</em></p>
</li>
<li>
<p><em>vector-swizzle-num-selector-values vector-swizzle-num-selector-value</em></p>
</li>
</ul>
</div>
</div>
</div>
<div class="paragraph">
<p>
<em>vector-swizzle-xyzw-selector-value</em>: one of <code>x y z w</code></p>
</div>
<div class="paragraph">
<p>
<em>vector-swizzle-rgba-selector-value</em>: one of <code>r g b a</code></p>
</div>
<div class="paragraph">
<p>
<em>vector-swizzle-num-selector-value</em>: one of <code>0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F</code></p>
</div>
<div class="openblock">
<div class="content">
<div class="paragraph">
<p>
with following restrictions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>vector-swizzle-selector</em> in a form of <em>vector-swizzle-special-selector</em> shall only be used with vector expression with at least 2 components.</p>
</li>
<li>
<p><em>vector-swizzle-selector</em> shall not select components beyond those available in vector expression.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<a href="#selector_values_and_their_corresponding_components_in_swizzle">Selector values and their corresponding components in swizzle</a> table describes relation between selector value and components.
</td>
</tr>
</table>
</div>
</li>
<li>
<p><em>vector-swizzle-selector</em> shall have swizzle size of 1, 2, 3, 4, 8 or 16.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Result from the swizzle expression shall be either of scalar or of valid vector type.
</td>
</tr>
</table>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="paragraph">
<p>
If <em>vector-swizzle-selector</em> does not meet requirements, the swizzle expression is ill-formed.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int2 v2;
int3 v3;
int4 v4;
int8 v8;
int16 v16;
v4.xyz = int3(1, 2, 3); // correct: xyz selector
v4.baS01 = v8.lo; // ill-formed: baS01 is mix of rgba
// and numerical selectors
v3.rx = int2(20, 7); // ill-formed: mix of rgba and
// xyzw selectors
int v2c1 = v2.z; // correct: xyzw selector
int v3c1 = v3.b; // correct: rgba selector
int2 v4c1 = v4.ww; // correct: xyzw selector
int3 v8c1 = v8.xyz; // ill-formed: xyzw and rgba selectors
// are not allowed on vector expressions
// with more than 4 components
int2 v8c2 = v8.hi.xyz; // correct: xyzw selector on vector
// expression v8.hi (vector-swizzle
// of int4 type)
int2 v3c2 = v3.odd; // correct: special selector
int2 v3c2 = v3.x.even; // ill-formed: #1 vector expression
// is invalid (vector swizzle of
// scalar type)
// #2 special selector cannot be
// used with less than 2 components
v3.x = 1; // correct: xyzw selector
v3.w = 2; // ill-formed: there is no "w" component in int3
v2.gb = v4.hi; // ill-formed: there is no "b" component in int2
v8.S7890 = v4; // ill-formed: int8 allows numerical selector
// in range 0-7
auto v16c1 = v16.s012; // correct: numerical selector
auto v16c2 = v16.s467899; // ill-formed: swizzle expression
// has not allowed size
// (there is no int6 type)
int16 vv1 = int16(v16.S98aabb01, v2, v2.gr, v3.xxxx); // correct
int16 vv2 = int16(v16.S98aabb0123, v2.gr, v3.xxxx);
// ill-formed:
// although it sums up to 16
// components the
// S98aabb0123 selector has invalid
// swizzle size (there is no int10)</code></pre>
</div>
</div>
</li>
<li>
<p><em>vector-swizzle-selector</em>, in a form of <em>vector-swizzle-xyzw-selector</em>, <em>vector-swizzle-rgba-selector</em> or <em>vector-swizzle-num-selector</em> can specify multiple values.
Each value selects single component.
Values in a selector can be repeated and specified in any order.
A number of values in a selector including repeated values is called the swizzle size.</p>
<table id="selector_values_and_their_corresponding_components_in_swizzle" class="tableblock frame-all grid-all spread">
<caption class="title">Table 6. Selector values and their corresponding components in swizzle</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Selector</strong></th>
<th class="tableblock halign-left valign-top"><strong>Selector value</strong></th>
<th class="tableblock halign-left valign-top"><strong>Selected component</strong></th>
<th class="tableblock halign-left valign-top"><strong>Required number of components in vector expression</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-xyzw-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>x</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1<sup>st</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2, 3 or 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-xyzw-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>y</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2<sup>nd</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2, 3 or 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-xyzw-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>z</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3<sup>rd</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3 or 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-xyzw-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>w</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-rgba-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>r</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1<sup>st</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2, 3 or 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-rgba-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>g</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2<sup>nd</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2, 3 or 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-rgba-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>b</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3<sup>rd</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3 or 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-rgba-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>0</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1<sup>st</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2, 3, 4, 8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>1</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2<sup>nd</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2, 3, 4, 8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3<sup>rd</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3, 4, 8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>3</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4, 8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>4</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">5<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>5</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>6</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">7<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>7</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8 or 16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>8</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>9</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">10<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a</code> or <code>A</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">11<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>b</code> or <code>B</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">12<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>c</code> or <code>C</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">13<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>d</code> or <code>D</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">14<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>e</code> or <code>E</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">15<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>vector-swizzle-num-selector</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>f</code> or <code>F</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16<sup>th</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
</tbody>
</table>
</li>
<li>
<p><em>vector-swizzle-selector</em> in a form of <em>vector-swizzle-special-selector</em> shall select:</p>
<div class="openblock">
<div class="content">
<div class="ulist">
<ul>
<li>
<p>if number of components in vector expression is 3, the same components as if number of components of the vector expression was 4 and the 4-th component was undefined.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If 4-th component is read, the returned value is undefined; all writes to 4-th component shall be discarded.
</td>
</tr>
</table>
</div>
</li>
<li>
<p>otherwise, half of components of <em>vector expression</em> with</p>
<div class="ulist">
<ul>
<li>
<p><code>hi</code> - highest numerical selector values in ascending order (higher half of the vector)</p>
</li>
<li>
<p><code>lo</code> - lowest numerical selector values in ascending order (lower half of the vector)</p>
</li>
<li>
<p><code>even</code> - even numerical selector values in ascending order</p>
</li>
<li>
<p><code>odd</code> - odd numerical selector values in ascending order</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="paragraph">
<p>The following <a href="#special_selector_values">Special selector values</a> table describes special selector values and their numerical equivalents.</p>
</div>
<table id="special_selector_values" class="tableblock frame-all grid-all spread">
<caption class="title">Table 7. Special selector values</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Number of components in vector expression</strong></th>
<th class="tableblock halign-left valign-top"><strong>Selector value</strong></th>
<th class="tableblock halign-left valign-top"><strong>Equivalent numerical selector</strong></th>
<th class="tableblock halign-left valign-top"><strong>Number of components in result vector swizzle (swizzle size)</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s1</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s2?</code> <a href="#ftn3">[3]</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s23</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s4567</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s89abcdef</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>lo</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s0</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>lo</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s01</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>lo</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s01</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>lo</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s0123</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>lo</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s01234567</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>even</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s0</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>even</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s02</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>even</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s02</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>even</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s0246</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>even</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s02468ace</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>odd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s1</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>odd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s1?</code> <a href="#ftn3">[3]</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>odd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s13</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>odd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s1357</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>odd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>s13579bdf</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
</tr>
</tbody>
</table>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float8 v = float8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f);
auto vv1 = v.hi; // vv1 = float4(5, 6, 7, 8)
auto vv2 = v.lo; // vv2 = float4(1, 2, 3, 4)
auto vv3 = v.even; // equivalent of v.s0246; vv3 = float4(1, 3, 5, 7)
auto vv4 = v.odd; // equivalent of v.s1357; vv4 = float4(2, 4, 6, 8)
auto vv5 = v.odd.even; // vv5 = float2(2, 6)
int3 sv = int3(10, 20, 30);
// ? means undefined value
auto svv1 = sv.hi; // svv1 = int2(30, ?)
auto svv2 = sv.odd; // svv2 = int2(20, ?)
sv.hi = int2(-123, 456); // write to 4-th channel in sv is discarded;
// equivalent of sv.s2 = int2(-123, 456).s0</code></pre>
</div>
</div>
</li>
<li>
<p>The value of a swizzle expression <code>E1.E2</code> is <em>vector-swizzle</em>.
The expression designates group of components of the object designated by expression <code>E1</code>.
Selector <code>E2</code> specifies which components are designated, how many times and in which order.</p>
<div class="paragraph">
<p>Assuming that in the type of a vector expression <code>E1</code> is <code>cv Tn</code> where <code>T</code> denotes type of components and <code>n</code> their number in vector type, the resulting <em>vector-swizzle</em> shall have:</p>
</div>
<div class="openblock">
<div class="content">
<div class="ulist">
<ul>
<li>
<p>scalar type <code>cv T</code> if it is result of a swizzle expression with swizzle size of one or</p>
</li>
<li>
<p>vector type <code>cv Tm</code> if it is result of a swizzle expression with swizzle size of two or more.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<code>m</code> is a swizzle size.
</td>
</tr>
</table>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="paragraph">
<p>If <code>E1</code> is an lvalue, then <code>E1.E2</code> is an lvalue; if <code>E1</code> is an xvalue, then <code>E1.E2</code> is an xvalue; otherwise, it is a prvalue.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>long2 v;
const long2 pv = &amp;v;
auto vc1 = pv-&gt;x; // pv-&gt;x is lvalue vector-swizzle of
// scalar type: const long
auto vc2 = pv-&gt;rg; // pv-&gt;rg is lvalue vector-swizzle of
// vector type: const long2
auto vc3 = uchar4(1).xxy; // uchar4(1).xxy is prvalue
// vector-swizzle
// of vector type: uchar3
v.x = long2(1, 2); // ill-formed: cannot assign prvalue of long2
// to lvalue vector-swizzle of
// scalar type: long - types do not
// match</code></pre>
</div>
</div>
</li>
<li>
<p>A <em>vector-swizzle</em> with vector type <code>T</code> shall have the same number of components as number of components of <code>T</code>.
Each component of the vector-swizzle refers to component from <code>E1</code> designated by corresponding value specified in selector <code>E2</code>, assuming that <code>E1.E2</code> is swizzle expression used to create the <em>vector-swizzle</em>.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
First component refers to component from <code>E1</code> selected by first value in selector <code>E2</code>, second - by second value and so on.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>A <em>vector-swizzle</em> with scalar type <code>T</code> shall behave as value of <code>T</code> and refer to component from <code>E1</code> designated by <code>E2</code>'s value, assuming <code>E1.E2</code> is swizzle expression used to create the <em>vector-swizzle</em>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
It is similar to reference bounded to value of selected component from <code>E1</code>.
</td>
</tr>
</table>
</div>
</li>
<li>
<p>A <em>vector-swizzle</em> shall have scalar or vector type.
The address-of operator <code>&amp;</code> shall not be applied to <em>vector-swizzle</em>, so there are no pointers to <em>vector-swizzles</em>.
A non-const reference shall not be bound to <em>vector-swizzle</em>.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If the initializer for a reference of type <code>const T&amp;</code> is lvalue that refers to vector-swizzle, the reference is bound to a temporary initialized to hold the value of the vector-swizzle; the reference is not bound to the vector-swizzle directly.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>There is no declarator for <em>vector-swizzle</em>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Any variable, member or type declaration shall not involve vector-swizzle; vector-swizzle cannot be stored.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>An <em>alignment-specifier</em> shall not be applied to <em>vector-swizzle</em>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float4 v;
auto pv1 = &amp;v; // correct: pv1 points to v
auto pv2 = &amp;v.xy; // ill-formed: address-of operator &amp; is not
// allowed on vector-swizzle
const auto &amp;rv1 = v.xx; // correct: refers to temporary value of
// float2 type initialized with
// value of vector-swizzle
float2 &amp;rv2 = v.xy; // ill-formed: binding to non-const reference
// is not allowed</code></pre>
</div>
</div>
</li>
<li>
<p>A result <em>vector-swizzle</em> from swizzle expression <code>E1.E2</code> is modifiable if:</p>
<div class="openblock">
<div class="content">
<div class="ulist">
<ul>
<li>
<p>Vector expression <code>E1</code> is modifiable lvalue and</p>
</li>
<li>
<p>Each component selected by <em>vector-swizzle-selector</em> <code>E2</code> is selected at most once.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="paragraph">
<p>Expression which modifies unmodifiable <em>vector-swizzle</em> is ill-formed.</p>
</div>
<div class="paragraph">
<p>Changes applied to modifiable <em>vector-swizzle</em> are applied to components of <code>E1</code> referred by the <em>vector-swizzle</em> or by its components.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>char4 v;
const char4 cv;
v.yx = char2(33, 45); // correct
v.zzwx = cv; // ill-formed: v.zzwx is not modifiable
// (repeated components)
cv.zxy = char3(1); // ill-formed: cv.zxy is not modifiable
// (cv is const)</code></pre>
</div>
</div>
</li>
<li>
<p>A prvalue for <em>vector-swizzle</em> of <code>T</code> type can be converted to a prvalue of <code>T</code> type.</p>
<div class="paragraph">
<p>This conversion is called <em>swizzle-to-vector</em> conversion.
<em>swizzle-to-vector</em> conversion shall be applied if necessary in all contexts where lvalue-to-rvalue conversions are allowed.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
swizzle-to-vector conversion shall be applied after lvalue-to-rvalue conversions and before any arithmetic conversions.
</td>
</tr>
</table>
</div>
</li>
<li>
<p>A glvalue <em>vector-swizzle</em> of scalar or vector type <code>T</code> can be used in all expressions where glvalue of type <code>T</code> can be used except those which do not meet requirements and restrictions for <em>vector-swizzle</em>.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
For example the address-of operator <code>&amp;</code> and binding to non-const reference are one of them.
</td>
</tr>
</table>
</div>
</li>
<li>
<p>A swizzle expression <code>E1.E2</code> where <code>E2</code> selects all components of vector expression <code>E1</code> in order of their numerical selector values is called identity swizzle.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Components selected in <code>E2</code> are not repeated.
</td>
</tr>
</table>
</div>
</li>
<li>
<p>Additional changes to C++ specification:</p>
<div class="ulist">
<ul>
<li>
<p><em>[ISO/IEC 14882:2014: expr.static.cast, ch. 5.2.9 (3)]</em> static_cast: If value is not a bit-field or a <em>vector-swizzle</em>, [&#8230;&#8203;]; if value is a <em>vector-swizzle</em>, the <em>lvalue-to-rvalue</em> conversion and <em>swizzle-to-vector</em> conversion are applied to the <em>vector-swizzle</em> and the resulting prvalue is used as the expression of the <code>static_cast</code> for the remainder of this section; otherwise, [&#8230;&#8203;]</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: expr.unary.op, ch. 5.3.1 (5)]</em> Unary operators: [&#8230;&#8203;] The operand of <code>&amp;</code> shall not be a bit-field or a <em>vector-swizzle</em>.</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: expr.pre.incr, ch. 5.3.2 (1)]</em> Increment and decrement: The result is the updated operand; it is an lvalue, and it is a bit-field or a <em>vector-swizzle</em> if the operand is respectively a bit-field or a <em>vector-swizzle</em>.</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: expr.sizeof, ch. 5.3.3 (2)]</em> Sizeof: [&#8230;&#8203;] When applied to a <em>vector-swizzle</em> which has type <code>T</code>, the result is the same as result from <code>sizeof(T)</code>.</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: expr.cond, ch. 5.16 (2.1)]</em> Conditional operator: - [&#8230;&#8203;] The conditional-expression is a bit-field or a <em>vector-swizzle</em> if that operand is respectively a bit-field or a <em>vector-swizzle</em>.</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: expr.cond, ch. 5.16 (4)]</em> Conditional operator: If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.
The result is also a <em>vector-swizzle</em> if the second or the third operand is a <em>vector-swizzle</em>, or if both are <em>vector-swizzles</em>.</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
An operand is converted to vector-swizzle if required by applying identity swizzle expression to it.
</td>
</tr>
</table>
</div>
<div class="ulist">
<ul>
<li>
<p><em>[ISO/IEC 14882:2014: expr.ass, ch. 5.18 (1)]</em> Assignment and compound assignment operators: The result in all cases is a bit-field or a <em>vector-swizzle</em> if the left operand is respectively a bit-field or a <em>vector-swizzle</em>.</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: expr.comma, ch. 5.19 (1)]</em> Comma operator: The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand, and is a bit-field if its right operand is a glvalue and a bit-field, and is a <em>vector-swizzle</em> its right operand is a glvalue and a <em>vector-swizzle</em>.</p>
</li>
<li>
<p><em>[ISO/IEC 14882:2014: dcl.type.simple, ch. 7.1.6.2 (4, 4.1)]</em> Simple type specifiers: For an expression e, the type denoted by decltype(e) is defined as follows:</p>
<div class="ulist">
<ul>
<li>
<p>if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5) or unparenthesized swizzle expression, <code>decltype(e)</code> is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed.</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ol>
</div>
</div>
<div class="sect4">
<h5 id="vector-constructors">Vector Constructors</h5>
<div class="paragraph">
<p>Vector constructors are defined to initialize a vector data type from a list of scalar or vectors.
The forms of the constructors that are available is the set of possible argument lists for which all arguments have the same element type as the result vector, and the total number of elements is equal to the number of elements in the result vector.
In addition, a form with a single scalar of the same type as the element type of the vector is available.</p>
</div>
<div class="paragraph">
<p>For example, the following forms are available for <code>float4</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float4( float, float, float, float )
float4( float2, float, float )
float4( float, float2, float )
float4( float, float, float2 )
float4( float2, float2 )
float4( float3, float )
float4( float, float3 )
float4( float )
float4{ float, float, float, float }
float4{ float2, float, float }
float4{ float, float2, float }
float4{ float, float, float2 }
float4{ float2, float2 }
float4{ float3, float }
float4{ float, float3 }
float4{ float }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Operands are evaluated by standard rules for function evaluation, except that implicit scalar-to-vector conversion shall not occur.
The order in which the operands are evaluated is undefined.
The operands are assigned to their respective positions in the result vector as they appear in memory order.
That is, the first element of the first operand is assigned to result.x, the second element of the first operand (or the first element of the second operand if the first operand was a scalar) is assigned to result.y, etc.
In the case of the form that has a single scalar operand, the operand is replicated across all lanes of the vector.</p>
</div>
<div class="paragraph">
<p>Examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float4 f = float4(1.0f, 2.0f, 3.0f, 4.0f);
uint4 u = uint4(1); // u will be (1, 1, 1, 1).
float4 f = float4(float2(1.0f, 2.0f),
float2(3.0f, 4.0f));
float4 f = float4(1.0f, float2(2.0f, 3.0f), 4.0f);
float4 f = float4(1.0f, 2.0f); // error
int4 i = (int4)(1, 2, 3, 4); // warning, vector literals (from OpenCL C) are
// not part of OpenCL C++,
// this expression will be evaluated to (int4)4,
// and i will be (4, 4, 4, 4)</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="vector-types-and-usual-arithmetic-conversions">Vector Types and Usual Arithmetic Conversions</h5>
<div class="paragraph">
<p>Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way.
The purpose is to determine a common real type for the operands and result.
For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type.
For this purpose, all vector types shall be considered to have higher conversion ranks than scalars.
Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise.
This pattern is called the usual arithmetic conversions.
If the operands are of more than one vector type, then an error shall occur.
Implicit conversions between vector types are not permitted, per the <a href="#implicit-type-conversions"><em>Implicit Type Conversions</em></a> section.</p>
</div>
<div class="paragraph">
<p>Otherwise, if there is only a single vector type, and all other operands are scalar types, the scalar types are converted to the type of the vector element, then widened into a new vector containing the same number of elements as the vector, by duplication of the scalar value across the width of the new vector.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="alignment-of-types">2.1.3. Alignment of Types</h4>
<div class="paragraph">
<p>A data item declared to be a data type in memory is always aligned to the size of the data type in bytes.
For example, a <code>float4</code> variable will be aligned to a 16-byte boundary, a <code>char2</code> variable will be aligned to a 2-byte boundary.</p>
</div>
<div class="paragraph">
<p>For 3-component vector data types, the size of the data type is <code>4 * sizeof(component)</code>.
This means that a 3-component vector data type will be aligned to a <code>4 * sizeof(component)</code> boundary.
The <code>vload3</code> and <code>vstore3</code> built-in functions can be used to read and write, respectively, 3-component vector data types from an array of packed scalar data type.</p>
</div>
<div class="paragraph">
<p>A built-in data type that is not a power of two bytes in size must be aligned to the next larger power of two.
This rule applies to built-in types only, not structs or unions.</p>
</div>
<div class="paragraph">
<p>The OpenCL C++ compiler is responsible for aligning data items to the appropriate alignment as required by the data type.
For arguments to a kernel function declared to be a pointer to a data type, the OpenCL compiler can assume that the pointee is always appropriately aligned as required by the data type.
The behavior of an unaligned load or store is undefined, except for the <code>vload<em>n</em></code>, <code>vload_half<em>n</em></code>, <code>vstore<em>n</em></code>, and <code>vstore_half<em>n</em></code> functions defined in the <a href="#vector-data-load-and-store-functions"><em>Vector Data Load and Store Functions</em></a> section.
The vector load functions can read a vector from an address aligned to the element type of the vector.
The vector store functions can write a vector to an address aligned to the element type of the vector.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="keywords">2.2. Keywords</h3>
<div class="paragraph">
<p>The following names are reserved for use as keywords in OpenCL C++ and shall not be used otherwise.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Names reserved as keywords by C++14.</p>
</li>
<li>
<p>OpenCL C++ data types defined in <a href="#device_builtin_scalar_data_types">Device built-in scalar data types</a> and <a href="#device_builtin_vector_data_types">Device built-in vector data types</a> tables.</p>
</li>
<li>
<p>Function qualifiers: <code>__kernel</code> and <code>kernel</code>.</p>
</li>
<li>
<p>Access qualifiers: <code>__read_only</code>, <code>read_only</code>, <code>\__write_only</code>, <code>write_only</code>, <code>__read_write</code> and <code>read_write</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="implicit-type-conversions">2.3. Implicit Type Conversions</h3>
<div class="paragraph">
<p>Implicit conversions between scalar built-in types defined in <a href="#device_builtin_scalar_data_types">Device built-in scalar data types</a> table (except <code>void</code>) are supported.
When an implicit conversion is done, it is not just a re-interpretation of the expression&#8217;s value, but a conversion of that value to an equivalent value in the new type.
For example, the integer value 5 will be converted to the floating-point value 5.0.</p>
</div>
<div class="paragraph">
<p>Implicit conversions from a scalar type to a vector type are allowed.
In this case, the scalar may be subject to the usual arithmetic conversion to the element type used by the vector.
The scalar type is then widened to the vector.
If conversion from a scalar type to the element type used by the vector result in truncation or precision loss, the program is ill-formed, with the exception that:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>if scalar value is prvalue of literal type and the value is representable as the element type, the conversion should take place without error (warnings may be generated in this case).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Implicit conversions between built-in vector data types are disallowed.
Explicit conversions described in the <a href="#conversions-library"><em>Conversions Library</em></a> section must be used instead.</p>
</div>
<div class="paragraph">
<p>Implicit conversions for pointer types follow the rules described in the C++14 specification.</p>
</div>
</div>
<div class="sect2">
<h3 id="expressions">2.4. Expressions</h3>
<div class="paragraph">
<p>All expressions behave as described in <em>[ISO/IEC 14882:2014: expr, ch. 5]</em> with the the restrictions described in the <a href="#opencl_cxx_restrictions"><em>OpenCL C++ Restrictions</em></a> section and the following changes:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>All built-in operators have their vector counterparts.</p>
</li>
<li>
<p>All built-in vector operations, apart from conditional operator, are performed component-wise.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Conditional operator logical-or-expression cannot be of vector type.
</td>
</tr>
</table>
</div>
</li>
<li>
<p>Built in operators taking two vectors require that vectors have the same number of components, otherwise expression is ill-formed.</p>
</li>
<li>
<p>Vector swizzle operations meet extra requirements and restrictions described in the <a href="#vector-component-access"><em>Vector Component Access</em></a> section.</p>
</li>
<li>
<p>Implicit and explicit casts between vector types are not legal.
The conversion between vector types can be done only using <code>convert_cast</code> from the <a href="#conversions-library"><em>Conversions Library</em></a> section.</p>
<div class="paragraph">
<p>Examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int4 i;
uint4 u = (uint4) i; // not allowed
float4 f;
int4 i = static_cast&lt;int4&gt;(f); // not allowed
float4 f;
int8 i = (int8) f; // not allowed</code></pre>
</div>
</div>
</li>
<li>
<p>Implicit and explicit casts from scalar to vector types are supported.</p>
</li>
<li>
<p>All built-in arithmetic operators return result of the same built-in type (integer or floating-point) as the type of the operands, after operand type conversion.
After conversion, the following cases are valid:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>The two operands are scalars. In this case, the operation is applied, resulting in a scalar.</p>
</li>
<li>
<p>One operand is a scalar, and the other is a vector.
In this case, the scalar may be subject to the usual arithmetic conversion to the element type used by the vector operand.
The scalar type is then widened to a vector that has the same number of components as the vector operand.
The operation is done component-wise resulting in the same size vector.</p>
</li>
<li>
<p>The two operands are vectors of the same type.
In this case, the operation is done component-wise resulting in the same size vector.</p>
</li>
</ol>
</div>
</li>
<li>
<p>The built-in relational and equality operators equal (<code>==</code>), not equal (<code>!=</code>), greater than (<code>&gt;</code>), greater than or equal (<code>&gt;=</code>), less than (<code>&lt;</code>), and less than or equal (<code>&lt;=</code>) operate on scalar and vector types.
All relational and equality operators result in a boolean (scalar or vector) type.
After operand type conversion, the following cases are valid:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>The two operands are scalars.
In this case, the operation is applied, resulting in a boolean scalar.</p>
</li>
<li>
<p>One operand is a scalar, and the other is a vector.
In this case, the scalar may be subject to the usual arithmetic conversion to the element type used by the vector operand.
The scalar type is then widened to a vector that has the same number of components as the vector operand.
The operation is done component-wise resulting in the same size boolean vector.</p>
</li>
<li>
<p>The two operands are vectors of the same type.
In this case, the operation is done component-wise resulting in the same size boolean vector.</p>
</li>
</ol>
</div>
</li>
<li>
<p>The built-in bitwise operators and (<code>&amp;</code>), or (<code>|</code>), exclusive or (<code>^</code>), not (<code>~</code>) operate on all scalar and vector built-in types except the built-in scalar and vector float types.
For vector built-in types, the operators are applied component-wise.
If one operand is a scalar and the other is a vector, the scalar may be subject to the usual arithmetic conversion to the element type used by the vector operand.
The scalar type is then widened to a vector that has the same number of components as the vector operand.
The operation is done component-wise resulting in the same size vector.</p>
</li>
<li>
<p>The built-in logical operators and (<code>&amp;&amp;</code>), or (<code>||</code>) operate on all scalar and vector built-in types.
For scalar built-in types the logical operator and (<code>&amp;&amp;</code>) will only evaluate the right hand operand if the left hand operand compares unequal to <code>false</code>.
For scalar built-in types the logical operator or (<code>||</code>) will only evaluate the right hand operand if the left hand operand compares equal to <code>false</code>.
For built-in vector types, both operands are evaluated and the operators are applied component-wise.
If one operand is a scalar and the other is a vector, the scalar may be subject to the usual arithmetic conversion to the element type used by the vector operand.
The scalar type is then widened to a vector that has the same number of components as the vector operand.
The operation is done component-wise resulting in the same size vector.</p>
<div class="paragraph">
<p>The result is a scalar or vector boolean.</p>
</div>
</li>
<li>
<p>The built-in logical unary operator not (<code>!</code>) operates on all scalar and vector built-in types.
For built-in vector types, the operators are applied component-wise.</p>
<div class="paragraph">
<p>The result is a scalar or vector boolean.</p>
</div>
</li>
<li>
<p>The built-in conditional operator (<code>?:</code>) described in <em>[ISO/IEC 14882:2014: expr, ch. 5.2]</em> operates on three expressions (<code>exp1 ? exp2 : exp3</code>).
This operator evaluates the first expression <code>exp1</code>, which must be a scalar boolean result.
If the result is <em>true</em> it selects to evaluate the second expression, otherwise it selects to evaluate the third expression.
The second and third expressions can be any type, as long their types match, or there is a conversion in the <a href="#implicit-type-conversions"><em>Implicit Type Conversions</em></a> section that can be applied to one of the expressions to make their types match, or one is a vector and the other is a scalar and the scalar may be subject to the usual arithmetic conversion to the element type used by the vector operand and widened to the same type as the vector type.</p>
<div class="paragraph">
<p>This resulting matching type is the type of the entire expression.</p>
</div>
</li>
<li>
<p>The built-in shift operators are supported for built-in vector types except the built-in scalar and vector float types.
For built-in vector types, the operators are applied component-wise.
For the right-shift (<code>&gt;&gt;</code>), left-shift (<code>&lt;&lt;</code>) operators, the rightmost operand must be a scalar if the first operand is a scalar, and the rightmost operand can be a vector or scalar if the first operand is a vector.
The result of <code>E1 &lt;&lt; E2</code> is <code>E1</code> left-shifted by <code>log2(N)</code> least significant bits in <code>E2</code> viewed as an unsigned integer value, where <code>N</code> is the number of bits used to represent the data type of <code>E1</code> after integer promotion, if <code>E1</code> is a scalar, or the number of bits used to represent the type of <code>E1</code> elements, if <code>E1</code> is a vector.
The vacated bits are filled with zeros.
The result of <code>E1 &gt;&gt; E2</code> is <code>E1</code> right-shifted by <code>log2(N)</code> least significant bits in <code>E2</code> viewed as an unsigned integer value, where <code>N</code> is the number of bits used to represent the data type of <code>E1</code> after integer promotion, if <code>E1</code> is a scalar, or the number of bits used to represent the type of <code>E1</code> elements, if <code>E1</code> is a vector.</p>
<div class="paragraph">
<p>If <code>E1</code> has an unsigned type or if <code>E1</code> has a signed type and a nonnegative value, the vacated bits are filled with zeros.</p>
</div>
<div class="paragraph">
<p>If <code>E1</code> has a signed type and a negative value, the vacated bits are filled with ones.</p>
</div>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="address-spaces">2.5. Address Spaces</h3>
<div class="paragraph">
<p>The OpenCL C++ kernel language doesn&#8217;t introduce any explicit named address spaces, but they are implemented as part of the standard library described in the <a href="#address-spaces-library"><em>Address Spaces Library</em></a> section.
There are 4 types of memory supported by all OpenCL devices: global, local, private and constant.
The developers should be aware of them and know their limitations.</p>
</div>
<div class="sect3">
<h4 id="implicit-storage-classes">2.5.1. Implicit Storage Classes</h4>
<div class="paragraph">
<p>The OpenCL C++ compiler can deduce an address space based on the scope where an object is declared:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If a variable is declared in program scope, with <code>static</code> or <code>extern</code> specifier and the standard library storage class (see the <a href="#address-spaces-library"><em>Address Spaces Library</em></a> section) is not used, the variable is allocated in the global memory of a device.</p>
</li>
<li>
<p>If a variable is declared in function scope, without <code>static</code> specifier and the standard library storage class (see the <a href="#address-spaces-library"><em>Address Spaces Library</em></a> section) is not used, the variable is allocated in the private memory of a device.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="memory-pools">2.5.2. Memory Pools</h4>
<div class="sect4">
<h5 id="global">Global</h5>
<div class="paragraph">
<p>The variables are allocated from the global memory pool if they meet the criteria described in the <a href="#implicit-storage-classes"><em>Implicit Storage Classes</em></a> section for the implicit global storage class or they are declared using explicit global storage class from the standard library (see the <a href="#global-class"><em>global class</em></a> section).</p>
</div>
<div class="paragraph">
<p>The global memory objects can be:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Passed by pointer or reference to a kernel from the host.
In such case the host manages their visibility, lifetime and a type of allocation.</p>
</li>
<li>
<p>Declared in the program source (<code>static</code>, <code>extern</code> and program scope global variables).
In such case they are:</p>
<div class="ulist">
<ul>
<li>
<p>the coarse-grained SVM allocations that can be usable by multiple kernels on the same device safely</p>
</li>
<li>
<p>not shared across devices</p>
</li>
<li>
<p>not accessible from the host</p>
</li>
<li>
<p>their lifetime is the same as a program</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The non-trivial constructors and destructors are supported with limitations described in the <a href="#memory-initialization"><em>Memory initialization</em></a> section.</p>
</div>
<div class="paragraph">
<p>The constructors of objects in global memory are executed before the first kernel execution in the program.
The destructors executed at program release time.</p>
</div>
<div class="paragraph">
<p>The additional restrictions may apply if the explicit global storage class is used.
Please refer to the <a href="#restrictions-2"><em>Restrictions</em></a> section for more details.</p>
</div>
</div>
<div class="sect4">
<h5 id="local">Local</h5>
<div class="paragraph">
<p>The local variables can be only allocated in a program using the explicit local storage class from the standard library (see the <a href="#local-class"><em>local class</em></a> section).
This type of memory is allocated for each work-group executing the kernel and exist only for the lifetime of the work-group executing the kernel.</p>
</div>
<div class="paragraph">
<p>The non-trivial constructors and destructors are supported with limitations described in the <a href="#memory-initialization"><em>Memory initialization</em></a> section.</p>
</div>
<div class="paragraph">
<p>The constructors of objects in local memory are executed by one work-item before the kernel body execution.
The destructors are executed by one work-item after the kernel body execution.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
initialization of local variables can cause performance degradation.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The additional restrictions may apply if the explicit local storage class is used.
Please refer to the <a href="#restrictions-2"><em>Restrictions</em></a> section for more details.</p>
</div>
</div>
<div class="sect4">
<h5 id="private">Private</h5>
<div class="paragraph">
<p>The variables are allocated from the private memory pool if they meet the criteria described in <a href="#implicit-storage-classes">Implicit Storage Classes</a> for the implicit private storage class or they were declared using explicit private storage class from the standard library (see the <a href="#priv-class"><em>priv class</em></a> section).</p>
</div>
<div class="paragraph">
<p>The non-trivial constructors and destructors are supported.</p>
</div>
<div class="paragraph">
<p>The additional restrictions may apply if the explicit priv storage class is used.
Please refer to the <a href="#restrictions-2"><em>Restrictions</em></a> section for more details.</p>
</div>
</div>
<div class="sect4">
<h5 id="constant">Constant</h5>
<div class="paragraph">
<p>The constant variables can be only allocated in a program using the explicit constant storage class from the standard library (see the <a href="#constant-class"><em>constant class</em></a> section).
The variables declared using the <code>constant&lt;T&gt;</code> class refer to memory objects allocated from the global memory pool and which are accessed inside a kernel(s) as read-only variables.
These read-only variables can be accessed by all (global) work-items of the kernel during its execution.</p>
</div>
<div class="paragraph">
<p>The constant objects must be constructible at compile time, they cannot have any user defined constructors, destructors, methods and operators.
Otherwise behavior is undefined.</p>
</div>
<div class="paragraph">
<p>The additional restrictions may apply if the explicit constant storage class is used.
Please refer to the <a href="#restrictions-2"><em>Restrictions</em></a> section for more details.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="pointers-and-references">2.5.3. Pointers and references</h4>
<div class="paragraph">
<p>All C++ pointers and references point to an object in the unnamed/generic address space if the explicit address space pointer classes are not used.
The explicit address space pointer classes are implemented as a part of the standard library and they are described in the <a href="#explicit-address-space-pointer-classes"><em>Explicit address space pointer classes</em></a> section.</p>
</div>
</div>
<div class="sect3">
<h4 id="memory-initialization">2.5.4. Memory initialization</h4>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 8. Supported memory initializers</caption>
<colgroup>
<col style="width: 13%;">
<col style="width: 12%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Storage memory (address space)</strong></th>
<th class="tableblock halign-left valign-top"><strong>Scope type</strong></th>
<th class="tableblock halign-left valign-top" colspan="3"><strong>Initialization type</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">uninitialized (no constructor or trivial default constructor)
</p><p class="tableblock"> <strong>AND</strong>
</p><p class="tableblock"> trivial destructor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">initialized by constant expression
</p><p class="tableblock"> <strong>AND</strong>
</p><p class="tableblock"> trivial destructor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">custom initializer
</p><p class="tableblock"> <strong>OR</strong>
</p><p class="tableblock"> custom destructor</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top" rowspan="4"><p class="tableblock">local</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">program</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported (not zero-pre-init)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">kernel</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are not zero-pre-initialized.
</p><p class="tableblock"> Optional zero-pre-initialization possible using switch: -cl-zero-init-local-mem-vars</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are not zero-pre-initialized.
</p><p class="tableblock"> Materialize temporary expressions are not supported.
</p><p class="tableblock"> Optional zero-pre-initialization possible using switch: -cl-zero-init-local-mem-vars</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are not zero-pre-initialized.
</p><p class="tableblock"> Materialize temporary expressions are not supported.
</p><p class="tableblock"> Optional zero-pre-initialization possible using switch: -cl-zero-init-local-mem-vars</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">local (non-kernel)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">class (static data member)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are not zero-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top" rowspan="3"><p class="tableblock">global</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">program</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero or constexpr-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">kernel / local</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero or constexpr-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">class (static data member)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero or constexpr-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">constant</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(any)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported
</p><p class="tableblock"> Variables are zero or constexpr-pre-initialized.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">not supported</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">private</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(any)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">supported</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="kernel-functions">2.6. Kernel Functions</h3>
<div class="sect3">
<h4 id="function-qualifiers">2.6.1. Function Qualifiers</h4>
<div class="paragraph">
<p>The <code>kernel</code> (or <code>__kernel</code>) qualifier declares a function to be a kernel that can be executed by an application on an OpenCL device(s).
The following rules apply to functions that are declared with this qualifier:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>It can be executed on the device only.</p>
</li>
<li>
<p>It can be enqueued by the host or on the device.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>kernel</code> and <code>__kernel</code> names are reserved for use as functions qualifiers and shall not be used otherwise.</p>
</div>
</div>
<div class="sect3">
<h4 id="restrictions">2.6.2. Restrictions</h4>
<div class="sect4">
<h5 id="kernel-function-restrictions">Kernel Function Restrictions</h5>
<div class="ulist">
<ul>
<li>
<p>Kernel functions are implicitly declared as <code>extern "C"</code>.</p>
</li>
<li>
<p>Kernel functions cannot be overloaded.</p>
</li>
<li>
<p>Kernel functions cannot be template functions.</p>
</li>
<li>
<p>Kernel functions cannot be called by other kernel functions.</p>
</li>
<li>
<p>Kernel functions cannot have parameters specified with default values.</p>
</li>
<li>
<p>Kernel functions must have the return type <code>void</code>.</p>
</li>
<li>
<p>Kernel functions cannot be called <code>main</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="kernel-parameter-restrictions">Kernel Parameter Restrictions</h5>
<div class="paragraph">
<p>The OpenCL host compiler and the OpenCL C++ kernel language device compiler can have different requirements for i.e. type sizes, data packing and alignment, etc., therefore the kernel parameters must meet the following requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Types passed by pointer or reference must be standard layout types.</p>
</li>
<li>
<p>Types passed by value must be POD types.</p>
</li>
<li>
<p>Types cannot be declared with the built-in <code>bool</code> scalar type, vector type or a class that contain <code>bool</code> scalar or vector type fields.</p>
</li>
<li>
<p>Types cannot be structures or classes with bit field members.</p>
</li>
<li>
<p>Marker types must be passed by value (see the <a href="#marker-types"><em>Marker Types</em></a> section).</p>
</li>
<li>
<p><code>global</code>, <code>constant</code>, and <code>local</code> storage classes can be passed only by reference or pointer. More details in the <a href="#explicit-address-space-storage-classes"><em>Explicit address space storage classes</em></a> section.</p>
</li>
<li>
<p>Pointers and references must point to one of the following address spaces: global, local or constant.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="preprocessor-directives-and-macros">2.7. Preprocessor Directives and Macros</h3>
<div class="paragraph">
<p>The preprocessing directives defined by the C++14 specification (<em>section 16</em>) are supported.</p>
</div>
<div class="paragraph">
<p>The <code>#pragma</code> directive is described as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#pragma pp-tokensopt new-line</code></pre>
</div>
</div>
<div class="paragraph">
<p>A <code>#pragma</code> directive where the preprocessing token <code>OPENCL</code> (used instead of <code>STDC</code>) does not immediately follow pragma in the directive (prior to any macro replacement) causes the implementation to behave in an implementation-defined manner.
The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner.
Any such pragma that is not recognized by the implementation is ignored.
If the preprocessing token <code>OPENCL</code> does immediately follow pragma in the directive (prior to any macro replacement), then no macro replacement is performed on the directive, and the directive shall have one of the following forms whose meanings are described elsewhere:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#pragma OPENCL FP_CONTRACT on-off-switch // on-off-switch: one of ON OFF DEFAULT
#pragma OPENCL EXTENSION extensionname : behavior
#pragma OPENCL EXTENSION all : behavior</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following predefined macro names are available.</p>
</div>
<div class="paragraph">
<p><code>__FILE__</code> The presumed name of the current source file (a character string literal).</p>
</div>
<div class="paragraph">
<p><code>__LINE__</code> The presumed line number (within the current source file) of the current source line (an integer constant).</p>
</div>
<div class="paragraph">
<p><code>__OPENCL_CPP_VERSION__</code> substitutes an integer reflecting the OpenCL C++ version specified when compiling the OpenCL C++ program.
The version of OpenCL C++ described in this document will have <code>__OPENCL_CPP_VERSION__</code> substitute the integer <code>100</code>.</p>
</div>
<div class="paragraph">
<p>The macro names defined by the C++14 specification in <em>section 16</em> but not currently supported by OpenCL are reserved for future use.</p>
</div>
<div class="paragraph">
<p>The predefined identifier <code>__func__</code> is available.</p>
</div>
</div>
<div class="sect2">
<h3 id="attribute-qualifiers">2.8. Attribute Qualifiers</h3>
<div class="paragraph">
<p>The <code>[[ ]]</code> attribute qualifier syntax allows additional attributes to be attached to types, variables, kernel functions, kernel parameters, or loops.</p>
</div>
<div class="paragraph">
<p>Some attributes change the semantics of the program and are required for program correctness.
Other attributes are optional hints that may be ignored without affecting program correctness.
Nevertheless, frontend compilers that compile to an intermediate representation are required to faithfully pass optional attribute hints with an intermediate representation to device compilers for further processing.</p>
</div>
<div class="sect3">
<h4 id="optional-type-attributes">2.8.1. Optional Type Attributes</h4>
<div class="paragraph">
<p><code>[[ ]]</code> attribute syntax can be used to specify special attributes of enum, class and union types when you define such types.
Two attributes are currently defined for types: <code>aligned</code>, and <code>packed</code>.</p>
</div>
<div class="paragraph">
<p>You may specify type attributes in an enum, class or union type declaration or definition, or for other types in a typedef declaration.</p>
</div>
<div class="paragraph">
<p>For an enum, class or union type, you may specify attributes either between the enum, class or union tag and the name of the type, or just past the closing curly brace of the definition.
The former syntax is preferred.</p>
</div>
<div class="sect4">
<h5 id="claligned-alignment">cl::aligned (alignment)</h5>
<div class="paragraph">
<p>This attribute specifies a minimum alignment (in bytes) for variables of the specified type.
For example, the declarations:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>struct S { short f[3]; } [[cl::aligned(8)]];
typedef int more_aligned_int [[cl::aligned(8)]];</code></pre>
</div>
</div>
<div class="paragraph">
<p>force the compiler to insure (as far as it can) that each variable whose type is struct S or <code>more_aligned_int</code> will be allocated and aligned <em>at least</em> on a 8-byte boundary.</p>
</div>
<div class="paragraph">
<p>Note that the alignment of any given struct or union type is required by the C++ standard to be at least a perfect multiple of the lowest common multiple of the alignments of all of the members of the struct or union in question and must also be a power of two.
This means that you <em>can</em> effectively adjust the alignment of a class or union type by attaching an aligned attribute to any one of the members of such a type, but the notation illustrated in the example above is a more obvious, intuitive, and readable way to request the compiler to adjust the alignment of an entire class or union type.</p>
</div>
<div class="paragraph">
<p>As in the preceding example, you can explicitly specify the alignment (in bytes) that you wish the compiler to use for a given class or union type.
Alternatively, you can leave out the alignment factor and just ask the compiler to align a type to the maximum useful alignment for the target machine you are compiling for.
For example, you could write:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>struct S { short f[3]; } [[cl::aligned]];</code></pre>
</div>
</div>
<div class="paragraph">
<p>Whenever you leave out the alignment factor in an aligned attribute specification, the compiler automatically sets the alignment for the type to the largest alignment which is ever used for any data type on the target machine you are compiling for.
In the example above, the size of each short is 2 bytes, and therefore the size of the entire struct S type is 6 bytes.
The smallest power of two which is greater than or equal to that is 8, so the compiler sets the alignment for the entire struct S type to 8 bytes.</p>
</div>
<div class="paragraph">
<p>Note that the effectiveness of aligned attributes may be limited by inherent limitations of the OpenCL device and compiler.
For some devices, the OpenCL compiler may only be able to arrange for variables to be aligned up to a certain maximum alignment.
If the OpenCL compiler is only able to align variables up to a maximum of 8 byte alignment, then specifying <code>aligned(16)</code> will still only provide you with 8 byte alignment.
See your platform-specific documentation for further information.</p>
</div>
<div class="paragraph">
<p>The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well.
See below.</p>
</div>
</div>
<div class="sect4">
<h5 id="clpacked">cl::packed</h5>
<div class="paragraph">
<p>This attribute, attached to class or union type definition, specifies that each member of the structure or union is placed to minimize the memory required.
When attached to an enum definition, it indicates that the smallest integral type should be used.</p>
</div>
<div class="paragraph">
<p>Specifying this attribute for class and union types is equivalent to specifying the packed attribute on each of the structure or union members.</p>
</div>
<div class="paragraph">
<p>In the following example struct my_packed_struct&#8217;s members are packed closely together, but the internal layout of its s member is not packed.
To do that, struct <code>my_unpacked_struct</code> would need to be packed, too.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>struct my_unpacked_struct
{
char c;
int i;
};
struct [[cl::packed]] my_packed_struct
{
char c;
int i;
struct my_unpacked_struct s;
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>You may only specify this attribute on the definition of an enum, class or union, not on a typedef which does not also define the enumerated type, structure or union.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="optional-variable-attributes">2.8.2. Optional Variable Attributes</h4>
<div class="paragraph">
<p>[[ ]] syntax allows you to specify special attributes of variables or structure fields.
The following attribute qualifiers are currently defined:</p>
</div>
<div class="sect4">
<h5 id="claligned">cl::aligned</h5>
<div class="paragraph">
<p>This attribute specifies a minimum alignment for the variable or class field, measured in bytes.
For example, the declaration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int x [[cl::aligned(16)]] = 0;</code></pre>
</div>
</div>
<div class="paragraph">
<p>causes the compiler to allocate the global variable <code>x</code> on a 16-byte boundary.
The alignment value specified must be a power of two.</p>
</div>
<div class="paragraph">
<p>You can also specify the alignment of structure fields.
For example, to create double-word aligned int pair, you could write:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>struct foo { int x[2] [[cl::aligned(8)]]; };</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is an alternative to creating a union with a double member that forces the union to be double-word aligned.</p>
</div>
<div class="paragraph">
<p>As in the preceding examples, you can explicitly specify the alignment (in bytes) that you wish the compiler to use for a given variable or structure field.
Alternatively, you can leave out the alignment factor and just ask the compiler to align a variable or field to the maximum useful alignment for the target machine you are compiling for.
For example, you could write:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>short array[3] [[cl::aligned]];</code></pre>
</div>
</div>
<div class="paragraph">
<p>Whenever you leave out the alignment factor in an aligned attribute specification, the OpenCL compiler automatically sets the alignment for the declared variable or field to the largest alignment which is ever used for any data type on the target device you are compiling for.</p>
</div>
<div class="paragraph">
<p>When used on a class, or class member, the aligned attribute can only increase the alignment; in order to decrease it, the packed attribute must be specified as well.
When used as part of a typedef, the aligned attribute can both increase and decrease alignment, and specifying the packed attribute will generate a warning.</p>
</div>
<div class="paragraph">
<p>Note that the effectiveness of aligned attributes may be limited by inherent limitations of the OpenCL device and compiler.
For some devices, the OpenCL compiler may only be able to arrange for variables to be aligned up to a certain maximum alignment.
If the OpenCL
compiler is only able to align variables up to a maximum of 8 byte alignment, then specifying <code>aligned(16)</code> will still only provide you with 8 byte alignment.
See your platform-specific documentation for further information.</p>
</div>
</div>
<div class="sect4">
<h5 id="clpacked-1">cl::packed</h5>
<div class="paragraph">
<p>The <code>packed</code> attribute specifies that a variable or class field should have the smallest possible alignment - one byte for a variable, unless you specify a larger value with the aligned attribute.</p>
</div>
<div class="paragraph">
<p>Here is a structure in which the field <code>x</code> is packed, so that it immediately follows a:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>struct foo
{
char a;
int x[2] [[cl::packed]];
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>An attribute list placed at the beginning of a user-defined type applies to the variable of that type and not the type, while attributes following the type body apply to the type.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>/* a has alignment of 128 */
[[cl::aligned(128)]] struct A { int i; } a;
/* b has alignment of 16 */
[[cl::aligned(16)]] struct B { double d; } [[cl::aligned(32)]] b;
struct A a1; /* a1 has alignment of 4 */
struct B b1; /* b1 has alignment of 32 */</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="optional-kernel-function-attributes">2.8.3. Optional Kernel Function Attributes</h4>
<div class="paragraph">
<p>The kernel qualifier can be used with the <code>[[ ]]</code> attribute syntax to declare additional information about the kernel function.
The kernel function attributes must appear immediately before the kernel function to be affected.</p>
</div>
<div class="paragraph">
<p>The following attributes are supported:</p>
</div>
<div class="sect4">
<h5 id="clwork_group_size_hint">cl::work_group_size_hint</h5>
<div class="paragraph">
<p>The optional <code>[[cl::work_group_size_hint(X, Y, Z)]]</code> is a hint to the compiler and is intended to specify the work-group size that may be used i.e. value most likely to be specified by the <code>local_work_size</code> argument to <code>clEnqueueNDRangeKernel</code>.
For example the <code>[[cl::work_group_size_hint(1, 1, 1)]]</code> is a hint to the compiler that the kernel will most likely be executed with a work-group size of 1.</p>
</div>
<div class="paragraph">
<p>The specialization constants (see the <a href="#specialization-constants-library"><em>Specialization Constants</em></a> section) can be used as arguments of <code>cl::work_group_size_hint</code> attribute.</p>
</div>
</div>
<div class="sect4">
<h5 id="clrequired_work_group_size">cl::required_work_group_size</h5>
<div class="paragraph">
<p>The optional <code>[[cl::required_work_group_size(X, Y, Z)]]</code> is the work-group size that must be used as the <code>local_work_size</code> argument to <code>clEnqueueNDRangeKernel</code>.
This allows the compiler to optimize the generated code appropriately for this kernel.</p>
</div>
<div class="paragraph">
<p>If <code>Z</code> is one, the <code>work_dim</code> argument to <code>clEnqueueNDRangeKernel</code> can be 2 or 3.
If <code>Y</code> and <code>Z</code> are one, the <code>work_dim</code> argument to <code>clEnqueueNDRangeKernel</code> can be 1, 2 or 3.</p>
</div>
<div class="paragraph">
<p>The specialization constants (see the <a href="#specialization-constants-library"><em>Specialization Constants</em></a> section) can be used as arguments of <code>cl::required_work_group_size(X, Y, Z)</code> attribute.</p>
</div>
</div>
<div class="sect4">
<h5 id="clrequired_num_sub_groups">cl::required_num_sub_groups</h5>
<div class="paragraph">
<p>The optional <code>[[cl::required_num_sub_groups(X)]]</code> is the number of sub-groups that must be generated by a kernel launch.
To ensure that this number is created the queries mapping number of sub-groups to local size may be used.
This allows the compiler to optimize the kernel based on the sub-group count and in addition allows the API to enforce correctness of kernel use to the user when concurrency of sub-groups is a requirement.</p>
</div>
<div class="paragraph">
<p>The specialization constants (see the <a href="#specialization-constants-library"><em>Specialization Constants</em></a> section) can be used as argument of <code>cl::required_num_sub_groups</code> attribute.</p>
</div>
</div>
<div class="sect4">
<h5 id="clvec_type_hint">cl::vec_type_hint</h5>
<div class="paragraph">
<p>The optional <code>[[cl::vec_type_hint(&lt;type&gt;)]]</code> is a hint to the compiler and is intended to be a representation of the computational <em>width</em> of the kernel, and should serve as the basis for calculating processor bandwidth utilization when the compiler is looking to autovectorize the code.
In the <code>[[cl::vec_type_hint(&lt;type&gt;)]]</code> qualifier <code>&lt;type&gt;</code> is one of the built-in vector types listed in <a href="#device_builtin_vector_data_types">Device built-in vector data types</a> table or the constituent scalar element types.
If <code>cl::vec_type_hint(&lt;type&gt;)</code> is not specified, the kernel is assumed to have the <code>[[cl::vec_type_hint(int)]]</code> qualifier.</p>
</div>
<div class="paragraph">
<p>For example, where the developer specified a width of <code>float4</code>, the compiler should assume that the computation usually uses up to 4 lanes of a float vector, and would decide to merge work-items or possibly even separate one work-item into many threads to better match the hardware capabilities.
A conforming implementation is not required to autovectorize code, but shall support the hint.
A compiler may autovectorize, even if no hint is provided.
If an implementation merges N work-items into one thread, it is responsible for correctly handling cases where the number of global or local work-items in any dimension modulo N is not zero.</p>
</div>
<div class="paragraph">
<p>Examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>// autovectorize assuming float4 as the
// basic computation width
[[cl::vec_type_hint(float4)]] kernel
void foo(cl::global_ptr&lt;float4&gt; p) { ... }
// autovectorize assuming double as the
// basic computation width
[[cl::vec_type_hint(double)]] kernel
void foo(cl::global_ptr&lt;float4&gt; p) { ... }
// autovectorize assuming int (default)
// as the basic computation width
kernel void foo(cl::global_ptr&lt;float4&gt; p) { ... }</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="optional-kernel-parameter-attributes">2.8.4. Optional Kernel Parameter Attributes</h4>
<div class="paragraph">
<p>The kernel parameter can be used with the <code>[[ ]]</code> attribute syntax to declare additional information about an argument passed to the kernel.
The kernel parameter attributes must appear immediately before or after the kernel parameter declaration to be affected.</p>
</div>
<div class="paragraph">
<p>The following attributes are supported:</p>
</div>
<div class="sect4">
<h5 id="clmax_size">cl::max_size</h5>
<div class="paragraph">
<p>This attribute can be provided with a kernel argument of type <code>constant_ptr&lt;T&gt;</code>, <code>constant&lt;T&gt;*</code>, <code>constant&lt;T&gt;&amp;</code>, <code>local_ptr&lt;T&gt;</code>, <code>local&lt;T&gt;*</code>, <code>local&lt;T&gt;&amp;</code>.
The value of the attribute specifies the maximum size in bytes of the corresponding memory object.
This size cannot exceed the limits supported by the device:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE</code> for the kernel arguments in constant memory</p>
</li>
<li>
<p><code>CL_DEVICE_LOCAL_MEM_SIZE</code> for the kernel arguments in local memory</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The specialization constants (see the <a href="#specialization-constants-library"><em>Specialization Constants</em></a> section) can be used as argument of <code>cl::max_size</code> attribute.</p>
</div>
<div class="paragraph">
<p>Examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
kernel void foo([[cl::max_size(65536)]] cl::constant_ptr&lt;int&gt; arg) {
//...
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="optional-loop-attributes">2.8.5. Optional Loop Attributes</h4>
<div class="sect4">
<h5 id="_cl_unroll_hint">cl::unroll_hint</h5>
<div class="paragraph">
<p>The <code><a id="cl::unroll_hint"></a></code> and <code>[[cl::unroll_hint(n)]]</code> attribute qualifiers can be used to specify that a loop (<code>for</code>, <code>while</code> and <code>do</code> loops) can be unrolled.
This attribute qualifier can be used to specify full unrolling or partial unrolling by a specified amount.
This is a compiler hint and the compiler may ignore this directive.</p>
</div>
<div class="paragraph">
<p><code>n</code> is the loop unrolling factor and must be a positive integral compile time constant expression.
An unroll factor of 1 disables unrolling.
If <code>n</code> is not specified, the compiler determines the unrolling factor for the loop.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <code>[[cl::unroll_hint(n)]]</code> attribute qualifier must appear immediately before the loop to be affected.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::unroll_hint(2)]]
while (*s != 0)
*p++ = *s++;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This tells the compiler to unroll the above while loop by a factor of 2.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::unroll_hint]]
for (int i=0; i&lt;2; i++) {
//...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the example above, the compiler will determine how much to unroll the loop.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::unroll_hint(1)]]
for (int i=0; i&lt;32; i++) {
//...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above is an example where the loop should not be unrolled.</p>
</div>
<div class="paragraph">
<p>Below are some examples of invalid usage of <code>[[cl::unroll_hint(n)]]</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::unroll_hint(-1)]]
while (/* ... */) {
//...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above example is an invalid usage of the loop unroll factor as the loop unroll factor is negative.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::unroll_hint]]
if(/* ... */) {
//...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above example is invalid because the <code>unroll_hint</code> attribute qualifier is used on a non-loop construct.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>kernel void my_kernel(/* ... */) {
int x;
[[cl::unroll_hint(x)]]
for (int i=0; i&lt;x; i++) {
//...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above example is invalid because the loop unroll factor is not a compile-time constant expression.</p>
</div>
</div>
<div class="sect4">
<h5 id="clivdep">cl::ivdep</h5>
<div class="paragraph">
<p>The <code>[[cl::ivdep]]</code> (ignore vector dependencies) attribute qualifier is a hint to the compiler and may appear in loops to indicate that the compiler may assume there are no memory dependencies across loop iterations in order to autovectorize consecutive iterations of the loop.
This attribute qualifier may appear in one of the following
forms:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::ivdep]]
[[cl::ivdep(len)]]</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the parameter <code>len</code> is specified, it is used to specify the maximum number of consecutive iterations without loop-carried dependencies.
<code>len</code> is a lower bound on the distance of any loop-carried dependence, and it applies to arbitrary alignment.
For example, any 4 consecutive iterations can be vectorized with <code>cl::ivdep(4)</code>.
The <code>len</code> parameter must be a positive integer.
The final decision whether to autovectorize the complete loop may be subject to other compiler heuristics as well as flags e.g., <em>-cl-fast-relaxed-math</em> to ignore non-associated operations.</p>
</div>
<div class="paragraph">
<p>Examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::ivdep]]
for (int i=0; i&lt;N; i++) {
C[i+offset] = A[i+offset] * B[i+offset];
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the example above, assuming that <code>A</code> and <code>B</code> are not restricted pointers, it is unknown if <code>C</code> aliases <code>A</code> or <code>B</code>.
Placing the <code>[[cl::ivdep]]</code> attribute before the loop lets the compiler assume there are no memory dependencies across the loop iterations.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::ivdep(8)]]
for (int i=0; i&lt;N; i++) {
A[i+K] = A[i] * B[i];
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the example above, buffer <code>A</code> is read from and written to in the loop iterations.
In each iteration, the read and write to <code>A</code> are to different indices.
In this case it is not safe to vectorize the loop to a vector length greater than <code>K</code>, so the <code>len</code> parameter is specified with a value that is known to be not greater than any value that <code>K</code> may take during the execution of loop.
In this example we are guaranteed (by <code>len</code>) that <code>K</code> will always be greater than or equal to 8.</p>
</div>
<div class="paragraph">
<p>Below is an example of invalid usage of <code>[[cl::ivdep]]</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>[[cl::ivdep(-1)]]
for (int i=0; i&lt;N; i++) {
C[i+offset] = A[i+offset] * B[i+offset];
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above example is an invalid usage of the attribute qualifier as <code>len</code> is negative.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="extending-attribute-qualifiers">2.8.6. Extending Attribute Qualifiers</h4>
<div class="paragraph">
<p>The attribute syntax can be extended for standard language extensions and vendor specific extensions.
Any extensions should follow the naming conventions outlined in the introduction to <em>section 9</em> in the OpenCL 2.2 Extension Specification.</p>
</div>
<div class="paragraph">
<p>Attributes are intended as useful hints to the compiler.
It is our intention that a particular implementation of OpenCL be free to ignore all attributes and the resulting executable binary will produce the same result.
This does not preclude an implementation from making use of the additional information provided by attributes and performing optimizations or other transformations as it sees fit.
In this case it is the programmer&#8217;s responsibility to guarantee that the information provided is in some sense correct.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="opencl_cxx_restrictions">2.9. Restrictions</h3>
<div class="paragraph">
<p>The following C++14 features are not supported by OpenCL C++:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the <code>dynamic_cast</code> operator (<em>ISO C++ Section 5.2.7</em>)</p>
</li>
<li>
<p>type identification (<em>ISO C++ Section 5.2.8</em>)</p>
</li>
<li>
<p>recursive function calls (<em>ISO C++ Section 5.2.2, item 9</em>) unless they are a compile-time constant expression</p>
</li>
<li>
<p>non-placement <code>new</code> and <code>delete</code> operators (<em>ISO C++ Sections 5.3.4 and 5.3.5</em>)</p>
</li>
<li>
<p><code>register</code> and <code>thread_local</code> storage qualifiers (<em>ISO C++ Section 7.1.1</em>)</p>
</li>
<li>
<p>virtual function qualifier (<em>ISO C++ Section 7.1.2</em>)</p>
</li>
<li>
<p>function pointers (<em>ISO C++ Sections 8.3.5 and 8.5.3</em>) unless they are a compile-time constant expression</p>
</li>
<li>
<p>virtual functions and abstract classes (<em>ISO C++ Sections 10.3 and 10.4</em>)</p>
</li>
<li>
<p>exception handling (<em>ISO C++ Section 15</em>)</p>
</li>
<li>
<p>the C++ standard library (<em>ISO C++ Sections 17 &#8230;&#8203; 30</em>)</p>
</li>
<li>
<p>no implicit lambda to function pointer conversion (<em>ISO C++ Section 5.1.2, item 6</em>)</p>
</li>
<li>
<p>variadic functions (<em>ISO C99 Section 7.15, Variable arguments &lt;stdarg.h&gt;</em>)</p>
</li>
<li>
<p>and, like C++, OpenCL C++ does not support variable length arrays (<em>ISO C99, Section 6.7.5</em>)</p>
</li>
<li>
<p>whether irreducible control flow is legal is implementation defined.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To avoid potential confusion with the above, please note the following features <em>are</em> supported in OpenCL C++:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>All variadic templates (<em>ISO C++ Section 14.5.3</em>) including variadic function templates are supported.</p>
</li>
<li>
<p>Virtual inheritance (<em>ISO C++ Section 10.1, item 4</em>) is supported.</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This page refers to <em>ISO C99</em> instead of <em>ISO C11</em> since the <em>ISO C++14</em> document refers to <em>ISO C99</em> in <em>ISO C++ Section 1.2 and Annex C</em>.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="opencl-c-standard-library">3. OpenCL C++ Standard Library</h2>
<div class="sectionbody">
<div class="paragraph">
<p>OpenCL C++ does not support the C++14 standard library, but instead implements its own standard library.
No OpenCL types and functions are auto-included.</p>
</div>
<div class="sect2">
<h3 id="opencl-definitions">3.1. OpenCL Definitions</h3>
<div class="paragraph">
<p>Header <em>&lt;opencl_def&gt;</em> defines OpenCL scalar, vector types and macros.
<code>cl_</code>* types are guaranteed to have exactly the same size as their host counterparts defined in <em>cl_platform.h</em> file.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_def-synopsis">3.1.1. Header &lt;opencl_def&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#define __OPENCL_CPP_VERSION__ 100
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef decltype(nullptr) nullptr_t;
#define NULL nullptr
typedef __INT8_TYPE__ int8_t [[cl::aligned(1)]];
typedef __UINT8_TYPE__ uint8_t [[cl::aligned(1)]];
typedef __INT16_TYPE__ int16_t [[cl::aligned(2)]];
typedef __UINT16_TYPE__ uint16_t [[cl::aligned(2)]];
typedef __INT32_TYPE__ int32_t [[cl::aligned(4)]];
typedef __UINT32_TYPE__ uint32_t [[cl::aligned(4)]];
typedef __INT64_TYPE__ int64_t [[cl::aligned(8)]];
typedef __UINT64_TYPE__ uint64_t [[cl::aligned(8)]];
#if __INTPTR_WIDTH__ == 32
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
#elif __INTPTR_WIDTH__ == 64
typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
#endif
namespace cl
{
using ::intptr_t;
using ::uintptr_t;
using ::ptrdiff_t;
using ::nullptr_t;
using ::size_t;
}
typedef int8_t cl_char;
typedef uint8_t cl_uchar;
typedef int16_t cl_short
typedef uint16_t cl_ushort;
typedef int32_t cl_int;
typedef uint32_t cl_uint;
typedef int64_t cl_long;
typedef uint64_t cl_ulong;
#ifdef cl_khr_fp16
typedef half cl_half [[aligned(2)]];
#endif
typedef float cl_float [[aligned(4)]];
#ifdef cl_khr_fp64
typedef double cl_double [[aligned(8)]];
#endif
typedef implementation-defined bool2;
typedef implementation-defined bool3;
typedef implementation-defined bool4;
typedef implementation-defined bool8;
typedef implementation-defined bool16;
typedef implementation-defined char2;
typedef implementation-defined char3;
typedef implementation-defined char4;
typedef implementation-defined char8;
typedef implementation-defined char16;
typedef implementation-defined uchar2;
typedef implementation-defined uchar3;
typedef implementation-defined uchar4;
typedef implementation-defined uchar8;
typedef implementation-defined uchar16;
typedef implementation-defined short2;
typedef implementation-defined short3;
typedef implementation-defined short4;
typedef implementation-defined short8;
typedef implementation-defined short16;
typedef implementation-defined ushort2;
typedef implementation-defined ushort3;
typedef implementation-defined ushort4;
typedef implementation-defined ushort8;
typedef implementation-defined ushort16;
typedef implementation-defined int2;
typedef implementation-defined int3;
typedef implementation-defined int4;
typedef implementation-defined int8;
typedef implementation-defined int16;
typedef implementation-defined uint2;
typedef implementation-defined uint3;
typedef implementation-defined uint4;
typedef implementation-defined uint8;
typedef implementation-defined uint16;
typedef implementation-defined long2;
typedef implementation-defined long3;
typedef implementation-defined long4;
typedef implementation-defined long8;
typedef implementation-defined long16;
typedef implementation-defined ulong2;
typedef implementation-defined ulong3;
typedef implementation-defined ulong4;
typedef implementation-defined ulong8;
typedef implementation-defined ulong16;
typedef implementation-defined float2;
typedef implementation-defined float3;
typedef implementation-defined float4;
typedef implementation-defined float8;
typedef implementation-defined float16;
#ifdef cl_khr_fp16
typedef implementation-defined half2;
typedef implementation-defined half3;
typedef implementation-defined half4;
typedef implementation-defined half8;
typedef implementation-defined half16;
#endif
#ifdef cl_khr_fp64
typedef implementation-defined double2;
typedef implementation-defined double3;
typedef implementation-defined double4;
typedef implementation-defined double8;
typedef implementation-defined double16;
#endif
typedef bool2 cl_bool2;
typedef bool3 cl_bool3;
typedef bool4 cl_bool4;
typedef bool8 cl_bool8;
typedef bool16 cl_bool16;
typedef char2 cl_char2;
typedef char3 cl_char3;
typedef char4 cl_char4;
typedef char8 cl_char8;
typedef char16 cl_char16;
typedef uchar2 cl_uchar2;
typedef uchar3 cl_uchar3;
typedef uchar4 cl_uchar4;
typedef uchar8 cl_uchar8;
typedef uchar16 cl_uchar16;
typedef short2 cl_short2;
typedef short3 cl_short3;
typedef short4 cl_short4;
typedef short8 cl_short8;
typedef short16 cl_short16;
typedef ushort2 cl_ushort2;
typedef ushort3 cl_ushort3;
typedef ushort4 cl_ushort4;
typedef ushort8 cl_ushort8;
typedef ushort16 cl_ushort16;
typedef int2 cl_int2;
typedef int3 cl_int3;
typedef int4 cl_int4;
typedef int8 cl_int8;
typedef int16 cl_int16;
typedef uint2 cl_uint2;
typedef uint3 cl_uint3;
typedef uint4 cl_uint4;
typedef uint8 cl_uint8;
typedef uint16 cl_uint16;
typedef long2 cl_long2;
typedef long3 cl_long3;
typedef long4 cl_long4;
typedef long8 cl_long8;
typedef long16 cl_long16;
typedef ulong2 cl_ulong2;
typedef ulong3 cl_ulong3;
typedef ulong4 cl_ulong4;
typedef ulong8 cl_ulong8;
typedef ulong16 cl_ulong16;
typedef float2 cl_float2;
typedef float3 cl_float3;
typedef float4 cl_float4;
typedef float8 cl_float8;
typedef float16 cl_float16;
#ifdef cl_khr_fp16
typedef half2 cl_half2;
typedef half3 cl_half3;
typedef half4 cl_half4;
typedef half8 cl_half8;
typedef half16 cl_half16;
#endif
#ifdef cl_khr_fp64
typedef double2 cl_double2;
typedef double3 cl_double3;
typedef double4 cl_double4;
typedef double8 cl_double8;
typedef double16 cl_double16;
#endif</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="conversions-library">3.2. Conversions Library</h3>
<div class="paragraph">
<p>This section describes the explicit conversion cast functions.
These functions provide a full set of type conversions between supported scalar and vector data types (see the <a href="#builtin-scalar-data-types"><em>Built-in Scalar Data Types</em></a> and the <a href="#builtin-vector-data-types"><em>Built-in Vector Data Types</em></a> sections) except for the following types: <code>size_t</code>, <code>ptrdiff_t</code>, <code>intptr_t</code>, <code>uintptr_t</code>, and <code>void</code>.</p>
</div>
<div class="paragraph">
<p>The behavior of the conversion may be modified by one or two optional modifiers that specify saturation for out-of-range inputs and rounding behavior.</p>
</div>
<div class="paragraph">
<p>The <code>convert_cast</code> type conversion operator that specifies a rounding mode and saturation is also provided.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_convert-synopsis">3.2.1. Header &lt;opencl_convert&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class rounding_mode { rte, rtz, rtp, rtn };
enum class saturate { off, on };
template &lt;class T, class U&gt;
T convert_cast(U const&amp; arg);
template &lt;class T&gt;
T convert_cast(T const&amp; arg);
template &lt;class T, rounding_mode rmode, class U&gt;
T convert_cast(U const&amp; arg);
template &lt;class T, rounding_mode rmode&gt;
T convert_cast(T const&amp; arg);
template &lt;class T, saturate smode, class U&gt;
T convert_cast(U const&amp; arg);
template &lt;class T, saturate smode&gt;
T convert_cast(T const&amp; arg);
template &lt;class T, rounding_mode rmode, saturate smode, class U&gt;
T convert_cast(U const&amp; arg);
template &lt;class T, rounding_mode rmode, saturate smode&gt;
T convert_cast(T const&amp; arg);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="data-types">3.2.2. Data Types</h4>
<div class="paragraph">
<p>Conversions are available for the following scalar types: <code>bool</code>, <code>char</code>, <code>uchar</code>, <code>short</code>, <code>ushort</code>, <code>int</code>, <code>uint</code>, <code>long</code>, <code>ulong</code>, <code>half</code> <a id="ftnref4"></a> <a href="#ftn4">[4]</a>, <code>float</code>, <code>double</code>, and built-in vector types derived therefrom.
The operand and result type must have the same number of elements.
The operand and result type may be the same type in which case the conversion has no effect on the type or value of an expression.</p>
</div>
<div class="paragraph">
<p>Conversions between integer types follow the conversion rules specified in the C++14 specification except for out-of-range behavior and saturated conversions which are described in the <a href="#out-of-range-behavior-and-saturated-conversions"><em>Out-of-Range Behavior and Saturated Conversions</em></a> section below.</p>
</div>
</div>
<div class="sect3">
<h4 id="rounding-modes">3.2.3. Rounding Modes</h4>
<div class="paragraph">
<p>Conversions to and from floating-point type shall conform to IEEE-754 rounding rules.
Conversions may have an optional rounding mode specified as described in the table belows.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 9. Rounding Modes</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Rounding Mode</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>rte</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Round to nearest even</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>rtz</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Round toward zero</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>rtp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Round toward positive infinity</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>rtn</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Round toward negative infinity</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>If a rounding mode is not specified, conversions to integer type use the <code>rtz</code> (round toward zero) rounding mode and conversions to floating-point type <a id="ftnref5"></a> <a href="#ftn5">[5]</a> uses the <code>rte</code> rounding mode.</p>
</div>
</div>
<div class="sect3">
<h4 id="out-of-range-behavior-and-saturated-conversions">3.2.4. Out-of-Range Behavior and Saturated Conversions</h4>
<div class="paragraph">
<p>When the conversion operand is either greater than the greatest representable destination value or less than the least representable destination value, it is said to be out-of-range.
The result of out-of-range conversion is determined by the conversion rules specified by the C++14 specification in <em>chapter 4.9</em>.
When converting from a floating-point type to integer type, the behavior is implementation-defined.</p>
</div>
<div class="paragraph">
<p>Conversions to integer type may opt to convert using the optional saturation mode.
When in saturated mode, values that are outside the representable range shall clamp to the nearest representable value in the destination format.
(NaN should be converted to 0).</p>
</div>
<div class="paragraph">
<p>Conversions to floating-point type shall conform to IEEE-754 rounding rules. The <code>convert_cast</code> operator with a saturate argument may not be used for conversions to floating-point formats.</p>
</div>
</div>
<div class="sect3">
<h4 id="examples-1">3.2.5. Examples</h4>
<div class="sect4">
<h5 id="example-1-1">Example 1</h5>
<div class="paragraph">
<p>Examples of casting between two vector types with saturation.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_convert&gt;
using namespace cl;
kernel void Foo() {
short4 s;
// negative values clamped to 0
ushort4 u = convert_cast&lt;ushort4,saturate::on&gt;(s);
// values &gt; CHAR_MAX converted to CHAR_MAX
// values &lt; CHAR_MIN converted to CHAR_MIN
char4 c = convert_cast&lt;char4, saturate::on&gt;(s);
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2-1">Example 2</h5>
<div class="paragraph">
<p>Examples of casting from float to integer vector type with saturation and rounding mode specified.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_convert&gt;
using namespace cl;
kernel void Foo() {
float4 f;
// values implementation defined for
// f &gt; INT_MAX, f &lt; INT_MIN or NaN
int4 i1 = convert_cast&lt;int4&gt;(f);
// values &gt; INT_MAX clamp to INT_MAX, values &lt; INT_MIN clamp
// to INT_MIN. NaN should produce 0.
// The rtz rounding mode is used to produce the integer
// values.
int4 i2 = convert_cast&lt;int4,saturate::on&gt;(f);
// similar to convert_cast&lt;int4&gt;, except that floating-point
// values are rounded to the nearest integer instead of
// truncated
int4 i3 = convert_cast&lt;int4, rounding_mode::rte&gt;(f);
// similar to convert_cast&lt;int4, saturate::on&gt;, except that
// floating-point values are rounded to the nearest integer
// instead of truncated
int4 i4 = convert_cast&lt;int4, rounding_mode::rte,
saturate::on&gt;(f);
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-3">Example 3</h5>
<div class="paragraph">
<p>Examples of casting from integer to float vector type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_convert&gt;
using namespace cl;
kernel void Foo() {
int4 i;
// convert ints to floats using the default rounding mode.
float4 f1 = convert_cast&lt;float4&gt;(i);
// convert ints to floats. integer values that cannot
// be exactly represented as floats should round up to the
// next representable float.
float4 f2 = convert_cast&lt;float4, rounding_mode::rtp&gt;(i);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="reinterpreting-data-library">3.3. Reinterpreting Data Library</h3>
<div class="paragraph">
<p>It is frequently necessary to reinterpret bits in a data type as another data type in OpenCL C++.
This is typically required when direct access to the bits in a floating-point type is needed, for example to mask off the sign bit or make use of the result of a vector relational operator on floating-point data.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_reinterpret-synopsis">3.3.1. Header &lt;opencl_reinterpret&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class T, class U&gt;
T as_type(U const&amp; arg);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="reinterpreting-types">3.3.2. Reinterpreting Types</h4>
<div class="paragraph">
<p>All data types described in <a href="#device_builtin_scalar_data_types">Device built-in scalar data types</a> and <a href="#device_builtin_vector_data_types">Device built-in vector data types</a> tables (except <code>bool</code> and <code>void</code>) may be also reinterpreted as another data type of the same size using the <code>as_type()</code> <a id="ftnref6"></a> <a href="#ftn6">[6]</a> function for scalar and vector data types.
When the operand and result type contain the same number of elements, the bits in the operand shall be returned directly without modification as the new type.
The usual type promotion for function arguments shall not be performed.</p>
</div>
<div class="paragraph">
<p>For example, <code>as_type&lt;float&gt;(0x3f800000)</code> returns <code>1.0f</code>, which is the value that the bit pattern <code>0x3f800000</code> has if viewed as an IEEE-754 single precision value.</p>
</div>
<div class="paragraph">
<p>When the operand and result type contain a different number of elements, the result shall be implementation-defined except if the operand is a 4-component vector and the result is a 3-component vector.
In this case, the bits in the operand shall be returned directly without modification as the new type.
That is, a conforming implementation shall explicitly define a behavior, but two conforming implementations need not have the same behavior when the number of elements in the result and operand types does not match.
The implementation may define the result to contain all, some or none of the original bits in whatever order it chooses.
It is an error to use the <code>as_type&lt;T&gt;</code> operator to reinterpret data to a type of a different number of bytes.</p>
</div>
</div>
<div class="sect3">
<h4 id="examples-2">3.3.3. Examples</h4>
<div class="sect4">
<h5 id="example-1-2">Example 1</h5>
<div class="paragraph">
<p>Examples of reinterpreting data types using <code>as_type&lt;&gt;</code> function.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_reinterpret&gt;
using namespace cl;
kernel void Foo() {
float f = 1.0f;
uint u = as_type&lt;uint&gt;(f); // Legal. Contains: 0x3f800000
float4 f = float4(1.0f, 2.0f, 3.0f, 4.0f);
// Legal. Contains:
// int4(0x3f800000, 0x40000000, 0x40400000, 0x40800000)
int4 i = as_type&lt;int4&gt;(f);
int i;
// Legal. Result is implementation-defined.
short2 j = as_type&lt;short2&gt;(i);
int4 i;
// Legal. Result is implementation-defined.
short8 j = as_type&lt;short8&gt;(i);
float4 f;
// Error. Result and operand have different sizes
double4 g = as_type&lt;double4&gt;(f);
float4 f;
// Legal. g.xyz will have same values as f.xyz. g.w is
// undefined
float3 g = as_type&lt;float3&gt;(f);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="address-spaces-library">3.4. Address Spaces Library</h3>
<div class="paragraph">
<p>Unlike OpenCL C, OpenCL C++ does not require the address space qualifiers to allocate storage from global, local and constant memory pool.
The same functionality is provided using the storage and pointer classes.
These new types are designed to avoid many programming issues and it is recommended to use them for the static and program scope variables even if it is not required.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_memory-synopsis">3.4.1. Header &lt;opencl_memory&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class mem_fence
{
local,
global,
image
};
inline mem_fence operator ~(mem_fence flags);
inline mem_fence operator &amp;(mem_fence LHS, mem_fence RHS);
inline mem_fence operator |(mem_fence LHS, mem_fence RHS);
inline mem_fence operator ^(mem_fence LHS, mem_fence RHS);
// address space pointer classes
template&lt;class T&gt;
class global_ptr;
template&lt;class T&gt;
class local_ptr;
template&lt;class T&gt;
class private_ptr;
template&lt;class T&gt;
class constant_ptr;
template&lt;class T&gt;
using global = see 'global class' section;
template&lt;class T&gt;
using local = see 'local class' section;
template&lt;class T&gt;
using priv = see 'priv class' section;
template&lt;class T&gt;
using constant = see 'constant class' section;
// address space query functions
template&lt;class T&gt;
mem_fence get_mem_fence(T *ptr);
// address space cast functions
template&lt;class T&gt;
T dynamic_asptr_cast(T *ptr) noexcept;
template &lt;class T, class U&gt;
local_ptr&lt;T&gt; static_asptr_cast(local_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
global_ptr&lt;T&gt; static_asptr_cast(global_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
constant_ptr&lt;T&gt; static_asptr_cast(constant_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
private_ptr&lt;T&gt; static_asptr_cast(private_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
local_ptr&lt;T&gt; reinterpret_asptr_cast(local_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
global_ptr&lt;T&gt; reinterpret_asptr_cast(global_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
constant_ptr&lt;T&gt; reinterpret_asptr_cast(constant_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
private_ptr&lt;T&gt; reinterpret_asptr_cast(private_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T&gt;
T* addressof(T&amp; t) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="explicit-address-space-storage-classes">3.4.2. Explicit address space storage classes</h4>
<div class="paragraph">
<p>The explicit address space storage classes described in this section are designed to allocate memory in one of the named address spaces: global, local, constant or private.</p>
</div>
<div class="sect4">
<h5 id="global-class">global class</h5>
<div class="paragraph">
<p>The variables declared using <code>global&lt;T&gt;</code> class refer to memory objects allocated from the global memory pool (see the <a href="#global"><em>Global Memory Pool</em></a> section).
The global storage class can only be used to declare variables at program, function and class scope.
The variables at function and class scope must be declared with <code>static</code> specifier.</p>
</div>
<div class="paragraph">
<p>If <code>T</code> is a fundamental or an array type, the <code>global</code> class should meet the following requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>no user provide default constructor</p>
</li>
<li>
<p>default copy and move constructors</p>
</li>
<li>
<p>default copy and move assignment operators</p>
</li>
<li>
<p>address-of operators that return a generic <code>T</code> pointer (<code>T*</code>)</p>
</li>
<li>
<p>conversion operators to a generic <code>T</code> lvalue reference type (<code>T&amp;</code>)</p>
</li>
<li>
<p>assignment <code>const T&amp;</code> operator</p>
</li>
<li>
<p><code>ptr()</code> methods that return a <code>global_ptr&lt;T&gt;</code> pointer class</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If <code>T</code> is a class type, the <code>global</code> class should provide the following interface:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the same public interface as <code>T</code> type including constructors and assignment operators address-of operators that return a generic <code>T</code> pointer (<code>T*</code>)</p>
</li>
<li>
<p>conversion operators to a generic <code>T</code> lvalue reference type (<code>T&amp;</code>)</p>
</li>
<li>
<p><code>ptr()</code> methods that return a <code>global_ptr&lt;T&gt;</code> pointer class</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="local-class">local class</h5>
<div class="paragraph">
<p>The variables declared using <code>local&lt;T&gt;</code> class refer to memory objects allocated from the local memory pool (see the <a href="#local"><em>Local Memory Pool</em></a> section).
The local storage class can only be used to declare variables at program, kernel and class scope.
The variables at class scope must be declared with <code>static</code> specifier.</p>
</div>
<div class="paragraph">
<p>If <code>T</code> is a fundamental or an array type, the <code>local</code> class should meet the following requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>no user provide default constructor</p>
</li>
<li>
<p>default copy and move constructors</p>
</li>
<li>
<p>default copy and move assignment operators</p>
</li>
<li>
<p>address-of operators that return a generic <code>T</code> pointer (<code>T*</code>)</p>
</li>
<li>
<p>conversion operators to a generic <code>T</code> lvalue reference type (<code>T&amp;</code>)</p>
</li>
<li>
<p>assignment <code>const T&amp;</code> operator</p>
</li>
<li>
<p><code>ptr()</code> methods that return a <code>local_ptr&lt;T&gt;</code> pointer class</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If <code>T</code> is a class type, the <code>local</code> class should provide the following interface:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the same public interface as <code>T</code> type including constructors
and assignment operators</p>
</li>
<li>
<p>address-of operators that return a generic <code>T</code> pointer (<code>T*</code>)</p>
</li>
<li>
<p>conversion operators to a generic <code>T</code> lvalue reference type (<code>T&amp;</code>)</p>
</li>
<li>
<p><code>ptr()</code> methods that return a <code>local_ptr&lt;T&gt;</code> pointer class</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="priv-class">priv class</h5>
<div class="paragraph">
<p>The variables declared using the <code>priv&lt;T&gt;</code> class refer to memory objects allocated from the private memory pool.</p>
</div>
<div class="paragraph">
<p>The <code>priv</code> storage class cannot be used to declare variables in the program scope, with <code>static</code> specifier or <code>extern</code> specifier.</p>
</div>
<div class="paragraph">
<p>If <code>T</code> is a fundamental or an array type, the <code>priv</code> class should meet the following requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>no user provide default constructor</p>
</li>
<li>
<p>default copy and move constructors</p>
</li>
<li>
<p>default copy and move assignment operators</p>
</li>
<li>
<p>address-of operators that return a generic <code>T</code> pointer (<code>T*</code>)</p>
</li>
<li>
<p>conversion operators to a generic <code>T</code> lvalue reference type (<code>T&amp;</code>)</p>
</li>
<li>
<p>assignment const <code>T&amp;</code> operator</p>
</li>
<li>
<p><code>ptr()</code> methods that return a <code>private_ptr&lt;T&gt;</code> pointer class</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If <code>T</code> is a class type, the <code>priv</code> class should provide the following interface:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the same public interface as <code>T</code> type including constructors and assignment operators</p>
</li>
<li>
<p>address-of operators that return a generic <code>T</code> pointer (<code>T*</code>)</p>
</li>
<li>
<p>conversion operators to a generic <code>T</code> lvalue reference type (<code>T&amp;</code>)</p>
</li>
<li>
<p><code>ptr()</code> methods that return a <code>private_ptr&lt;T&gt;</code> pointer class</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="constant-class">constant class</h5>
<div class="paragraph">
<p>The variables declared using the <code>constant&lt;T&gt;</code> class refer to memory objects allocated from the global memory pool and which are accessed inside a kernel(s) as read-only variables.
The constant storage class can only be used to declare variables at program, kernel and class scope.
The variables at class scope must be declared with <code>static</code> specifier.</p>
</div>
<div class="paragraph">
<p>The <code>T</code> type must meet the following requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>T</code> must be constructible at compile time</p>
</li>
<li>
<p><code>T</code> cannot have any user defined constructors, destructors, methods and operators</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If <code>T</code> is a fundamental, array or class type, the <code>constant</code> class should meet the following requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>no user provide default constructor</p>
</li>
<li>
<p>default copy and move constructors</p>
</li>
<li>
<p>copy and move assignment operators deleted</p>
</li>
<li>
<p>address-of operators that return a <code>constant_ptr&lt;T&gt;</code> pointer class</p>
</li>
<li>
<p><code>ptr()</code> methods that return a <code>constant_ptr&lt;T&gt;</code> pointer class</p>
</li>
<li>
<p>conversion operators to a constant <code>T</code> lvalue reference type (<code>add_constant_t&lt;T&gt;&amp;</code>)</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect3">
<h4 id="explicit-address-space-pointer-classes">3.4.3. Explicit address space pointer classes</h4>
<div class="paragraph">
<p>The explicit address space pointer classes are just like pointers: they can be converted to and from pointers with compatible address spaces, qualifiers and types.
Assignment or casting between explicit pointer types of incompatible address spaces is illegal.</p>
</div>
<div class="paragraph">
<p>All named address spaces are incompatible with all other address spaces, but local, global and private pointers can be converted to standard C++ pointers.</p>
</div>
<div class="sect4">
<h5 id="global_ptr-class">global_ptr class</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class T&gt; class global_ptr
{
public:
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_global_t&lt;T&gt;&amp; reference;
typedef const add_global_t&lt;T&gt;&amp; const_reference;
typedef add_global_t&lt;T&gt;* pointer;
typedef const add_global_t&lt;T&gt;* const_pointer;
//constructors:
constexpr global_ptr() noexcept;
explicit global_ptr(pointer p) noexcept;
global_ptr(const global_ptr &amp;r) noexcept;
global_ptr(global_ptr &amp;&amp;r) noexcept;
constexpr global_ptr(nullptr_t) noexcept;
//assignment:
global_ptr &amp;operator=(const global_ptr &amp;r) noexcept;
global_ptr &amp;operator=(global_ptr &amp;&amp;r) noexcept;
global_ptr &amp;operator=(pointer r) noexcept;
global_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
add_lvalue_reference_t&lt;add_global_t&lt;T&gt;&gt; operator*() const noexcept;
pointer operator-&gt;() const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release() noexcept;
void reset(pointer p = pointer()) noexcept;
void swap(global_ptr&amp; r) noexcept;
global_ptr &amp;operator++() noexcept;
global_ptr operator++(int) noexcept;
global_ptr &amp;operator--() noexcept;
global_ptr operator--(int) noexcept;
global_ptr &amp;operator+=(difference_type r) noexcept;
global_ptr &amp;operator-=(difference_type r) noexcept;
global_ptr operator+(difference_type r) noexcept;
global_ptr operator-(difference_type r) noexcept;
};
template &lt;class T&gt; class global_ptr&lt;T[]&gt;
{
public:
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_global_t&lt;T&gt;&amp; reference;
typedef const add_global_t&lt;T&gt;&amp; const_reference;
typedef add_global_t&lt;T&gt;* pointer;
typedef const add_global_t&lt;T&gt;* const_pointer;
//constructors:
constexpr global_ptr() noexcept;
explicit global_ptr(pointer p) noexcept;
global_ptr(const global_ptr &amp;r) noexcept;
global_ptr(global_ptr &amp;&amp;r) noexcept;
constexpr global_ptr(nullptr_t) noexcept;
//assignment:
global_ptr &amp;operator=(const global_ptr &amp;r) noexcept;
global_ptr &amp;operator=(global_ptr &amp;&amp;r) noexcept;
global_ptr &amp;operator=(pointer r) noexcept;
global_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
reference operator[](size_t pos) const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release()noexcept;
void reset(pointer p) noexcept;
void reset(nullptr_t p = nullptr) noexcept;
void swap(global_ptr&amp; r) noexcept;
global_ptr &amp;operator++() noexcept;
global_ptr operator++(int) noexcept;
global_ptr &amp;operator--() noexcept;
global_ptr operator--(int) noexcept;
global_ptr &amp;operator+=(difference_type r) noexcept;
global_ptr &amp;operator-=(difference_type r) noexcept;
global_ptr operator+(difference_type r) noexcept;
global_ptr operator-(difference_type r) noexcept;
};
template&lt;class T, class U&gt;
bool operator==(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator!=(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;=(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;=(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T&gt;
bool operator==(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator==(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator!=(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
void swap(global_ptr&lt;T&gt;&amp; a, global_ptr&lt;T&gt;&amp; b) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="local_ptr-class">local_ptr class</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class T&gt; class local_ptr
{
public:
struct size_type
{
explicit constexpr size_type(size_t size);
operator size_t();
};
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_local_t&lt;T&gt;&amp; reference;
typedef const add_local_t&lt;T&gt;&amp; const_reference;
typedef add_local_t&lt;T&gt;* pointer;
typedef const add_local_t&lt;T&gt;* const_pointer;
//constructors:
constexpr local_ptr() noexcept;
explicit local_ptr(pointer p) noexcept;
local_ptr(const local_ptr &amp;r) noexcept;
local_ptr(local_ptr &amp;&amp;r) noexcept;
constexpr local_ptr(nullptr_t) noexcept;
//assignment:
local_ptr &amp;operator=(const local_ptr &amp;r) noexcept;
local_ptr &amp;operator=(local_ptr &amp;&amp;r) noexcept;
local_ptr &amp;operator=(pointer r) noexcept;
local_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
add_lvalue_reference_t&lt;add_local_t&lt;T&gt;&gt; operator*() const noexcept;
pointer operator-&gt;() const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release() noexcept;
void reset(pointer p = pointer()) noexcept;
void swap(local_ptr&amp; r) noexcept;
local_ptr &amp;operator++() noexcept;
local_ptr operator++(int) noexcept;
local_ptr &amp;operator--() noexcept;
local_ptr operator--(int) noexcept;
local_ptr &amp;operator+=(difference_type r) noexcept;
local_ptr &amp;operator-=(difference_type r) noexcept;
local_ptr operator+(difference_type r) noexcept;
local_ptr operator-(difference_type r) noexcept;
};
template &lt;class T&gt; class local_ptr&lt;T[]&gt;
{
public:
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_local_t&lt;T&gt;&amp; reference;
typedef const add_local_t&lt;T&gt;&amp; const_reference;
typedef add_local_t&lt;T&gt;* pointer;
typedef const add_local_t&lt;T&gt;* const_pointer;
//constructors:
constexpr local_ptr() noexcept;
explicit local_ptr(pointer p) noexcept;
local_ptr(const local_ptr &amp;r) noexcept;
local_ptr(local_ptr &amp;&amp;r) noexcept;
constexpr local_ptr(nullptr_t) noexcept;
//assignment:
local_ptr &amp;operator=(const local_ptr &amp;r) noexcept;
local_ptr &amp;operator=(local_ptr &amp;&amp;r) noexcept;
local_ptr &amp;operator=(pointer r) noexcept;
local_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
reference operator[](size_t pos) const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release()noexcept;
void reset(pointer p) noexcept;
void reset(nullptr_t p = nullptr) noexcept;
void swap(local_ptr&amp; r) noexcept;
local_ptr &amp;operator++() noexcept;
local_ptr operator++(int) noexcept;
local_ptr &amp;operator--() noexcept;
local_ptr operator--(int) noexcept;
local_ptr &amp;operator+=(difference_type r) noexcept;
local_ptr &amp;operator-=(difference_type r) noexcept;
local_ptr operator+(difference_type r) noexcept;
local_ptr operator-(difference_type r) noexcept;
};
template&lt;class T, class U&gt;
bool operator==(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator!=(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;=(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;=(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T&gt;
bool operator==(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator==(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator!=(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
void swap(local_ptr&lt;T&gt;&amp; a, local_ptr&lt;T&gt;&amp; b) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="private_ptr-class">private_ptr class</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class T&gt; class private_ptr
{
public:
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_private_t&lt;T&gt;&amp; reference;
typedef const add_private_t&lt;T&gt;&amp; const_reference;
typedef add_private_t&lt;T&gt;* pointer;
typedef const add_private_t&lt;T&gt;* const_pointer;
//constructors:
constexpr private_ptr() noexcept;
explicit private_ptr(pointer p) noexcept;
private_ptr(const private_ptr &amp;r) noexcept;
private_ptr(private_ptr &amp;&amp;r) noexcept;
constexpr private_ptr(nullptr_t) noexcept;
//assignment:
private_ptr &amp;operator=(const private_ptr &amp;r) noexcept;
private_ptr &amp;operator=(private_ptr &amp;&amp;r) noexcept;
private_ptr &amp;operator=(pointer r) noexcept;
private_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
add_lvalue_reference_t&lt;add_private_t&lt;T&gt;&gt; operator*() const noexcept;
pointer operator-&gt;() const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release() noexcept;
void reset(pointer p = pointer()) noexcept;
void swap(private_ptr&amp; r) noexcept;
private_ptr &amp;operator++() noexcept;
private_ptr operator++(int) noexcept;
private_ptr &amp;operator--() noexcept;
private_ptr operator--(int) noexcept;
private_ptr &amp;operator+=(difference_type r) noexcept;
private_ptr &amp;operator-=(difference_type r) noexcept;
private_ptr operator+(difference_type r) noexcept;
private_ptr operator-(difference_type r) noexcept;
};
template &lt;class T&gt; class private_ptr&lt;T[]&gt; {
public:
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_private_t&lt;T&gt;&amp; reference;
typedef const add_private_t&lt;T&gt;&amp; const_reference;
typedef add_private_t&lt;T&gt;* pointer;
typedef const add_private_t&lt;T&gt;* const_pointer;
//constructors:
constexpr private_ptr() noexcept;
explicit private_ptr(pointer p) noexcept;
private_ptr(const private_ptr &amp;r) noexcept;
private_ptr(private_ptr &amp;&amp;r) noexcept;
constexpr private_ptr(nullptr_t) noexcept;
//assignment:
private_ptr &amp;operator=(const private_ptr &amp;r) noexcept;
private_ptr &amp;operator=(private_ptr &amp;&amp;r) noexcept;
private_ptr &amp;operator=(pointer r) noexcept;
private_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
reference operator[](size_t pos) const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release()noexcept;
void reset(pointer p) noexcept;
void reset(nullptr_t p = nullptr) noexcept;
void swap(private_ptr&amp; r) noexcept;
private_ptr &amp;operator++() noexcept;
private_ptr operator++(int) noexcept;
private_ptr &amp;operator--() noexcept;
private_ptr operator--(int) noexcept;
private_ptr &amp;operator+=(difference_type r) noexcept;
private_ptr &amp;operator-=(difference_type r) noexcept;
private_ptr operator+(difference_type r) noexcept;
private_ptr operator-(difference_type r) noexcept;
};
template&lt;class T, class U&gt;
bool operator==(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator!=(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;=(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;=(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T&gt;
bool operator==(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator==(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator!=(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
void swap(private_ptr&lt;T&gt;&amp; a, private_ptr&lt;T&gt;&amp; b) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="constant_ptr-class">constant_ptr class</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class T&gt; class constant_ptr
{
public:
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_constant_t&lt;T&gt;&amp; reference;
typedef const add_constant_t&lt;T&gt;&amp; const_reference;
typedef add_constant_t&lt;T&gt;* pointer;
typedef const add_constant_t&lt;T&gt;* const_pointer;
//constructors:
constexpr constant_ptr() noexcept;
explicit constant_ptr(pointer p) noexcept;
constant_ptr(const constant_ptr &amp;r) noexcept;
constant_ptr(constant_ptr &amp;&amp;r) noexcept;
constexpr constant_ptr(nullptr_t) noexcept;
//assignment:
constant_ptr &amp;operator=(const constant_ptr &amp;r) noexcept;
constant_ptr &amp;operator=(constant_ptr &amp;&amp;r) noexcept;
constant_ptr &amp;operator=(pointer r) noexcept;
constant_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
add_lvalue_reference_t&lt;add_constant_t&lt;T&gt;&gt; operator*() const noexcept;
pointer operator-&gt;() const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release() noexcept;
void reset(pointer p = pointer()) noexcept;
void swap(constant_ptr&amp; r) noexcept;
constant_ptr &amp;operator++() noexcept;
constant_ptr operator++(int) noexcept;
constant_ptr &amp;operator--() noexcept;
constant_ptr operator--(int) noexcept;
constant_ptr &amp;operator+=(difference_type r) noexcept;
constant_ptr &amp;operator-=(difference_type r) noexcept;
constant_ptr operator+(difference_type r) noexcept;
constant_ptr operator-(difference_type r) noexcept;
};
template &lt;class T&gt; class constant_ptr&lt;T[]&gt;
{
public:
//types:
typedef T element_type;
typedef ptrdiff_t difference_type;
typedef add_constant_t&lt;T&gt;&amp; reference;
typedef const add_constant_t&lt;T&gt;&amp; const_reference;
typedef add_constant_t&lt;T&gt;* pointer;
typedef const add_constant_t&lt;T&gt;* const_pointer;
//constructors:
constexpr constant_ptr() noexcept;
explicit constant_ptr(pointer p) noexcept;
constant_ptr(const constant_ptr &amp;r) noexcept;
constant_ptr(constant_ptr &amp;&amp;r) noexcept;
constexpr constant_ptr(nullptr_t) noexcept;
//assignment:
constant_ptr &amp;operator=(const constant_ptr &amp;r) noexcept;
constant_ptr &amp;operator=(constant_ptr &amp;&amp;r) noexcept;
constant_ptr &amp;operator=(pointer r) noexcept;
constant_ptr &amp;operator=(nullptr_t) noexcept;
//observers:
reference operator[](size_t pos) const noexcept;
pointer get() const noexcept;
explicit operator bool() const noexcept;
//modifiers:
pointer release()noexcept;
void reset(pointer p) noexcept;
void reset(nullptr_t p = nullptr) noexcept;
void swap(constant_ptr&amp; r) noexcept;
constant_ptr &amp;operator++() noexcept;
constant_ptr operator++(int) noexcept;
constant_ptr &amp;operator--() noexcept;
constant_ptr operator--(int) noexcept;
constant_ptr &amp;operator+=(difference_type r) noexcept;
constant_ptr &amp;operator-=(difference_type r) noexcept;
constant_ptr operator+(difference_type r) noexcept;
constant_ptr operator-(difference_type r) noexcept;
};
template&lt;class T, class U&gt;
bool operator==(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator!=(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;=(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;=(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T&gt;
bool operator==(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator==(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator!=(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
void swap(constant_ptr&lt;T&gt;&amp; a, constant_ptr&lt;T&gt;&amp; b) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="constructors">Constructors</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>constexpr global_ptr() noexcept;
constexpr local_ptr() noexcept;
constexpr private_ptr() noexcept;
constexpr constant_ptr() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs an object which points to nothing.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>explicit global_ptr(pointer p) noexcept;
explicit local_ptr(pointer p) noexcept;
explicit private_ptr(pointer p) noexcept;
explicit constant_ptr(pointer p) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs an object which points to <code>p</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr(const global_ptr &amp;) noexcept;
local_ptr(const local_ptr &amp;) noexcept;
private_ptr(const private_ptr &amp;) noexcept;
constant_ptr(const constant_ptr &amp;) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Copy constructor.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr(global_ptr &amp;&amp;r) noexcept;
local_ptr(local_ptr &amp;&amp;r) noexcept;
private_ptr(private_ptr &amp;&amp;r) noexcept;
constant_ptr(constant_ptr &amp;&amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Move constructor.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>constexpr global_ptr(nullptr_t) noexcept;
constexpr local_ptr(nullptr_t) noexcept;
constexpr private_ptr(nullptr_t) noexcept;
constexpr constant_ptr(nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs an object initialized with <code>nullptr</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="assignment-operators">Assignment operators</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator=(const global_ptr &amp;r) noexcept;
local_ptr &amp;operator=(const local_ptr &amp;r) noexcept;
private_ptr &amp;operator=(const private_ptr &amp;r) noexcept;
constant_ptr &amp;operator=(const constant_ptr &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Copy assignment operator</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator=(global_ptr &amp;&amp;r) noexcept;
local_ptr &amp;operator=(local_ptr &amp;&amp;r) noexcept;
private_ptr &amp;operator=(private_ptr &amp;&amp;r) noexcept;
constant_ptr &amp;operator=(constant_ptr &amp;&amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Move assignment operator</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator=(pointer r) noexcept;
local_ptr &amp;operator=(pointer r) noexcept;
private_ptr &amp;operator=(pointer r) noexcept;
constant_ptr &amp;operator=(pointer r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigns <code>r</code> pointer to the stored pointer</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator=(nullptr_t) noexcept;
local_ptr &amp;operator=(nullptr_t) noexcept;
private_ptr &amp;operator=(nullptr_t) noexcept;
constant_ptr &amp;operator=(nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigns <code>nullptr</code> to the stored pointer</p>
</div>
</div>
<div class="sect4">
<h5 id="observers">Observers</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>add_lvalue_reference_t&lt;add_global_t&lt;T&gt;&gt; operator*() const noexcept;
add_lvalue_reference_t&lt;add_local_t&lt;T&gt;&gt; operator*() const noexcept;
add_lvalue_reference_t&lt;add_private_t&lt;T&gt;&gt; operator*() const noexcept;
add_lvalue_reference_t&lt;add_constant_t&lt;T&gt;&gt; operator*() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>*get()</code>. It is only defined in single object version of the explicit address space pointer class.
The result of this operator is undefined if <code>get() == nullptr</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>pointer operator-&gt;() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>get()</code>. It is only defined in single object version of the explicit address space pointer class.
The result of this operator is undefined if <code>get() == nullptr</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>reference operator[](size_t pos) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>get()[pos]</code>. The subscript operator is only defined in specialized <code>global_ptr&lt;T[]&gt;</code>, <code>local_ptr&lt;T[]&gt;</code>, <code>private_ptr&lt;T[]&gt;</code> and <code>constant_ptr&lt;T[]&gt;</code> version for array types.
The result of this operator is undefined if <code>pos &gt;=</code> the number of elements in the array to which the stored pointer points.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>pointer get() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the stored pointer.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>explicit operator bool() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>get() != nullptr</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="modifiers">Modifiers</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>pointer release() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigns <code>nullptr</code> to the stored pointer and returns the value <code>get()</code> had at the start of the call to release.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void reset(pointer p = pointer()) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigned <code>p</code> to the stored pointer.
It is only defined in single object version of the explicit address space pointer class</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void reset(pointer p) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigned <code>p</code> to the stored pointer.
It is only defined in specialized <code>global_ptr&lt;T[]&gt;</code>, <code>local_ptr&lt;T[]&gt;</code>, <code>private_ptr&lt;T[]&gt;</code> and <code>constant_ptr&lt;T[]&gt;</code> version for array types.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void reset(nullptr_t p = nullptr) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Equivalent to <code>reset(pointer())</code>.
It is only defined in specialized <code>global_ptr&lt;T[]&gt;</code>, <code>local_ptr&lt;T[]&gt;</code>, <code>private_ptr&lt;T[]&gt;</code> and <code>constant_ptr&lt;T[]&gt;</code> version for array types.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void swap(global_ptr&amp; r) noexcept;
void swap(local_ptr&amp; r) noexcept;
void swap(private_ptr&amp; r) noexcept;
void swap(constant_ptr&amp; r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Invokes swap on the stored pointers.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator++() noexcept;
local_ptr &amp;operator++() noexcept;
private_ptr &amp;operator++() noexcept;
constant_ptr &amp;operator++() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Prefix increment operator.
Increments the stored pointer by one.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr operator++(int) noexcept;
local_ptr operator++(int) noexcept;
private_ptr operator++(int) noexcept;
constant_ptr operator++(int) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Postfix increment operator.
Increments the stored pointer by one.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator--() noexcept;
local_ptr &amp;operator--() noexcept;
private_ptr &amp;operator--() noexcept;
constant_ptr &amp;operator--() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Prefix decrement operator.
Decrements the stored pointer by one.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr operator--(int) noexcept;
local_ptr operator--(int) noexcept;
private_ptr operator--(int) noexcept;
constant_ptr operator--(int) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Postfix decrement operator.
Decrements the stored pointer by one.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator+=(difference_type r) noexcept;
local_ptr &amp;operator+=(difference_type r) noexcept;
private_ptr &amp;operator+=(difference_type r) noexcept;
constant_ptr &amp;operator+=(difference_type r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Adds <code>r</code> to the stored pointer and returns <code>*this</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr &amp;operator-=(difference_type r) noexcept;
local_ptr &amp;operator-=(difference_type r) noexcept;
private_ptr &amp;operator-=(difference_type r) noexcept;
constant_ptr &amp;operator-=(difference_type r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Subtracts <code>r</code> to the stored pointer and returns <code>*this</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr operator+(difference_type r) noexcept;
local_ptr operator+(difference_type r) noexcept;
private_ptr operator+(difference_type r) noexcept;
constant_ptr operator+(difference_type r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Adds <code>r</code> to the stored pointer and returns the value <code>*this</code> has at the start of <code>operator+</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>global_ptr operator-(difference_type r) noexcept;
local_ptr operator-(difference_type r) noexcept;
private_ptr operator-(difference_type r) noexcept;
constant_ptr operator-(difference_type r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Subtracts <code>r</code> to the stored pointer and returns the value <code>*this</code> has at the start of <code>operator-</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="non-member-functions">Non-member functions</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, class U&gt;
bool operator==(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator==(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator==(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator==(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator==</code> for the explicit address space pointer classes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T&gt;
bool operator==(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator==(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator==(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator==(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator==(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator==(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator==(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator==(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator==</code> for the explicit address space pointer classes with a <code>nullptr_t</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, class U&gt;
bool operator!=(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator!=(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator!=(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator!=(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator!=</code> for the explicit address space pointer classes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T&gt;
bool operator!=(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator!=(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator!=(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator!=(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator!=(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator!=</code> for the explicit address space pointer classes with a <code>nullptr_t</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, class U&gt;
bool operator&lt;(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&lt;</code> for the explicit address space pointer classes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T&gt;
bool operator&lt;(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&lt;</code> for the explicit address space pointer classes with a <code>nullptr_t</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, class U&gt;
bool operator&gt;(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&gt;</code> for the explicit address space pointer classes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T&gt;
bool operator&gt;(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&gt;</code> for the explicit address space pointer classes with a <code>nullptr_t</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, class U&gt;
bool operator&lt;=(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;=(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;=(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&lt;=(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&lt;=</code> for the explicit address space pointer classes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&lt;=(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&lt;=(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&lt;=</code> for the explicit address space pointer classes with a <code>nullptr_t</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, class U&gt;
bool operator&gt;=(const global_ptr&lt;T&gt; &amp;a, const global_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;=(const local_ptr&lt;T&gt; &amp;a, const local_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;=(const private_ptr&lt;T&gt; &amp;a, const private_ptr&lt;U&gt; &amp;b) noexcept;
template&lt;class T, class U&gt;
bool operator&gt;=(const constant_ptr&lt;T&gt; &amp;a, const constant_ptr&lt;U&gt; &amp;b) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&gt;=</code> for the explicit address space pointer classes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const global_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const global_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const local_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const local_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const private_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const private_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;
template&lt;class T&gt;
bool operator&gt;=(nullptr_t, const constant_ptr&lt;T&gt; &amp;x) noexcept;
template&lt;class T&gt;
bool operator&gt;=(const constant_ptr&lt;T&gt; &amp;x, nullptr_t) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison <code>operator&gt;=</code> for the explicit address space pointer classes with a <code>nullptr_t</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T&gt;
void swap(global_ptr&lt;T&gt;&amp; a, global_ptr&lt;T&gt;&amp; b) noexcept;
template&lt;class T&gt;
void swap(local_ptr&lt;T&gt;&amp; a, local_ptr&lt;T&gt;&amp; b) noexcept;
template&lt;class T&gt;
void swap(private_ptr&lt;T&gt;&amp; a, private_ptr&lt;T&gt;&amp; b) noexcept;
template&lt;class T&gt;
void swap(constant_ptr&lt;T&gt;&amp; a, constant_ptr&lt;T&gt;&amp; b) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Calls <code>a.swap(b)</code></p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="other-functions">3.4.4. Other functions</h4>
<div class="paragraph">
<p>The OpenCL C++ address space library implements the address space query and cast functions.
The cast function that allows to explicitly convert from a pointer in the generic address space to a pointer in the global, local and private address space.</p>
</div>
<div class="sect4">
<h5 id="get_mem_fence">get_mem_fence</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class T&gt;
mem_fence get_mem_fence (T *ptr);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the <code>mem_fence</code> value for <code>ptr</code>.
<code>ptr</code> must be the generic pointer and it cannot be the explicit address space pointer (<code>global_ptr&lt;&gt;</code>, <code>local_ptr&lt;&gt;</code>, <code>private_ptr&lt;&gt;</code> and <code>constant_ptr&lt;&gt;</code>) or pointer to address space storage class (<code>global&lt;&gt;*</code>, <code>local&lt;&gt;*</code>, <code>priv&lt;&gt;*</code> and <code>constant&lt;&gt;*</code>).</p>
</div>
</div>
<div class="sect4">
<h5 id="dynamic_asptr_cast">dynamic_asptr_cast</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, class U&gt;
T dynamic_asptr_cast(U *ptr);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a pointer that points to a region in the address space pointer class specified in <code>T</code> if <code>dynamic_asptr_cast</code> can cast <code>ptr</code> to the specified address space.
Otherwise it returns <code>nullptr</code>.
Only <code>global_ptr&lt;U&gt;</code>, <code>local_ptr&lt;U&gt;</code> and <code>private_ptr&lt;U&gt;</code> are valid <code>T</code> template arguments.
<code>ptr</code> must be the generic pointer and it cannot be the explicit address space pointer (<code>global_ptr&lt;&gt;</code>, <code>local_ptr&lt;&gt;</code>, <code>private_ptr&lt;&gt;</code> and <code>constant_ptr&lt;&gt;</code>) or pointer to address space storage class (<code>global&lt;&gt;*</code>, <code>local&lt;&gt;*</code>, <code>priv&lt;&gt;*</code> and <code>constant&lt;&gt;*</code>).</p>
</div>
</div>
<div class="sect4">
<h5 id="static_asptr_cast">static_asptr_cast</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class T, class U&gt;
local_ptr&lt;T&gt; static_asptr_cast(local_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
global_ptr&lt;T&gt; static_asptr_cast(global_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
constant_ptr&lt;T&gt; static_asptr_cast(constant_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
private_ptr&lt;T&gt; static_asptr_cast(private_ptr&lt;U&gt; const&amp; ptr) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The expression <code>static_cast(r.get())</code> shall be well formed.</p>
</div>
</div>
<div class="sect4">
<h5 id="reinterpret_asptr_cast">reinterpret_asptr_cast</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class T, class U&gt;
local_ptr&lt;T&gt; reinterpret_asptr_cast(local_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
global_ptr&lt;T&gt; reinterpret_asptr_cast(global_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
constant_ptr&lt;T&gt; reinterpret_asptr_cast(constant_ptr&lt;U&gt; const&amp; ptr) noexcept;
template &lt;class T, class U&gt;
private_ptr&lt;T&gt; reinterpret_asptr_cast(private_ptr&lt;U&gt; const&amp; ptr) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The expression <code>reinterpret_cast(r.get())</code> shall be well formed.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="restrictions-2">3.4.5. Restrictions</h4>
<div class="paragraph">
<p>1.
The objects allocated using <code>global</code>, <code>local</code> and <code>constant</code> storage classes can be passed to a function only by reference or pointer</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_array&gt;
using namespace cl;
kernel void foo(global&lt;array&lt;int, 5&gt;&gt; val) {
// Error: variable in the global
// address space passed by value
//...
}
kernel void bar(global&lt;array&lt;int, 5&gt;&gt; &amp;val) { // OK
//...
}
kernel void foobar(global_ptr&lt;int&gt; val) { // OK
//...
}
kernel void barfoo(global_ptr&lt;int[]&gt; val) { // OK
//...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>2.
The <code>global</code>, <code>local</code>, <code>priv</code> and <code>constant</code> storage classes cannot be used as a return type of function</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_array&gt;
using namespace cl;
global&lt;array&lt;int, 5&gt;&gt; programVar;
global&lt;array&lt;int, 5&gt;&gt; foo() { // error: variable in the global
// address space returned by value
return programVar;
}
global&lt;array&lt;int, 5&gt;&gt; &amp;bar() { // OK
return programVar;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>3.
The <code>global</code>, <code>local</code> and <code>constant</code> storage classes cannot be used to declare class members unless <code>static</code> keyword is used</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_array&gt;
using namespace cl;
struct Foo {
global&lt;int&gt; a; // error: class members cannot be qualified
// with address space
local&lt;array&lt;int, 5&gt;&gt; b; // error: class members cannot be
// qualified with address space
static global&lt;int&gt; c; // OK
static local&lt;array&lt;int, 5&gt;&gt; d; // OK
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>4.
The <code>global</code> storage class cannot be used to declare variables at function scope unless <code>static</code> keyword is used</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
kernel void foo() {
global&lt;int&gt; b; // error
static global&lt;int&gt; b; // OK
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>5.
The <code>local</code> variables can be declared only at kernel function scope, program scope and with <code>static</code> keyword</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_array&gt;
using namespace cl;
// An array of 5 ints allocated in
// local address space.
local&lt;array&lt;int, 5&gt;&gt; a = { 10 }; // OK: program scope local
// variable
kernel void foo() {
// A single int allocated in
// local address space
local&lt;int&gt; b{1}; // OK
static local&lt;int&gt; d{1}; // OK
if(get_local_id(0) == 0) {
// example of variable in local address space
// but not declared at __kernel function scope.
local&lt;int&gt; c{2}; // not allowed
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>6.
The objects allocated using <code>global</code> storage class must be initialized with the constant expression arguments</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo() {
int a = get_local_id(0);
static global&lt;int&gt; b{a}; // undefined behavior
static global&lt;int&gt; c{0}; // OK
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>7.
The constructors of objects allocated using <code>constant</code> storage class must be constant expression</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
constant&lt;int&gt; b{0}; // OK
kernel void foo() {
int a = get_local_id(0);
static constant&lt;int&gt; b{a}; // undefined behavior
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>8.
Constant variables must be initialized</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
constant&lt;int&gt; a{0}; // OK
constant&lt;int&gt; b; // error: constant variable must be initialized
kernel void foo() {
static constant&lt;int&gt; c{0}; // OK
static constant&lt;int&gt; d; // error: constant variable must be initialized
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>9.
The <code>priv</code> storage class cannot be used to declare variables in the program scope or with <code>static</code> specifier.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
priv&lt;int&gt; a{0}; // error: priv variable in program scope
kernel void foo() {
static priv&lt;int&gt; c{0}; // error: priv variable with static specifier
priv&lt;int&gt; d; // OK
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>10.
<code>T</code> type used in <code>constant</code> storage class cannot have any user defined constructors, destructors, operators and methods</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
struct bar {
int get() { return 10; }
};
kernel void foo() {
constant&lt;bar&gt; a;
int b = a.get() // undefined behavior
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>11.
<code>T</code> type used in <code>global</code>, <code>local</code>, <code>priv</code> and <code>constant</code> storage class cannot be sealed class</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
struct bar final { };
kernel void foo() {
local&lt;bar&gt; a; // error: bar is marked as final
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>12.
Using work-group barriers or relying on a specific work-item to be executed in constructors and destructors of global and local objects can result in undefined behavior</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_synchronization&gt;
using namespace cl;
struct Foo {
Foo() {
work_group_barrier(mem_fence::local); // not allowed
}
~Foo() {
if(get_local_id(0) != 5) { // not allowed
while(1) {}
}
}
};
kernel void bar() {
local&lt;Foo&gt; a;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>13.
All local (address-space) variable declarations in kernel-scope shall be declared before any explicit return statement.
Declaring local variable after return statement may cause undefined behavior.
Implementation is encouraged to generate at least a warning in such cases.</p>
</div>
</div>
<div class="sect3">
<h4 id="examples-3">3.4.6. Examples</h4>
<div class="sect4">
<h5 id="example-1-3">Example 1</h5>
<div class="paragraph">
<p>Example of passing an explicit address space storage object to a kernel.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
kernel void foo(global&lt;int&gt; *arg) {
//...
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2-2">Example 2</h5>
<div class="paragraph">
<p>Example of passing an explicit address space pointer object to a kernel.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
kernel void foo(global_ptr&lt;int&gt; arg) {
//...
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-3-1">Example 3</h5>
<div class="paragraph">
<p>Example of casting a generic pointer to an explicit address space pointer object.
This is the runtime operation and the <code>dynamic_asptr_cast</code> can fail.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
using namespace cl;
kernel void foo(global_ptr&lt;int&gt; arg) {
int *ptr = arg;
auto globalPtr = dynamic_asptr_cast&lt;global_ptr&lt;int&gt;&gt;(ptr);
if(globalPtr)
{
//...
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-4">Example 4</h5>
<div class="paragraph">
<p>Example of using an array with an explicit address space storage class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_array&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo() {
local&lt;array&lt;int, 2&gt;&gt; localArray;
if(get_local_id(0) == 0) {
for(auto it = localArray.begin(); it != localArray.end(); ++it)
*it = 0;
}
work_group_barrier(mem_fence::local);
localArray[0] += 1;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-5">Example 5</h5>
<div class="paragraph">
<p>Example of using a fundamental type with an explicit address space storage class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo() {
local&lt;int&gt; a;
if(get_local_id(0) == 0)
a = 1;
work_group_barrier(mem_fence::local);
if(get_local_id(0) == 1)
a += 1;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="specialization-constants-library">3.5. Specialization Constants Library</h3>
<div class="paragraph">
<p>The specialization constants are objects that will not have known constant values until after initial generation of a SPIR-V module.
Such objects are called specialization constants.
Application might provide values for the specialization constants that will be used when SPIR-V program is built.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_spec_constant-synopsis">3.5.1. Header &lt;opencl_spec_constant&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T, unsigned int ID&gt;
struct spec_constant
{
spec_constant() = delete;
spec_constant(const spec_constant &amp;) = default;
spec_constant(spec_constant&amp;&amp;) = default;
constexpr spec_constant(const T&amp; value);
spec_constant&amp; operator=(const spec_constant&amp;) = delete;
spec_constant&amp; operator=(spec_constant&amp;&amp;) = delete;
const T&amp; get() const noexcept;
operator const T&amp;() const noexcept;
};
template&lt;class T, unsigned int ID&gt;
const T&amp; get(const spec_constant&lt;T, ID&gt; &amp;r) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="spec_constant-class-methods-and-get-function">3.5.2. spec_constant class methods and get function</h4>
<div class="sect4">
<h5 id="spec_constantspec_constant">spec_constant::spec_constant</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>constexpr spec_constant(const T&amp; value);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor of spec_constant class.
The value parameter is a default value of the specialization constant that will be used if a value is not set by the host API.
It must be a literal value.</p>
</div>
</div>
<div class="sect4">
<h5 id="get">get</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>const T&amp; get() const noexcept;
operator const T&amp;() const noexcept;
template&lt;class T, unsigned int ID&gt;
const T&amp; get(const spec_constant&lt;T, ID&gt; &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return a value of specialization constant.
If an object is not specialized from the host, the default value will be returned.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="requirements-2">3.5.3. Requirements</h4>
<div class="paragraph">
<p>Specialization constant variables cannot be defined <code>constexpr</code>.</p>
</div>
<div class="sect4">
<h5 id="data-1">Data</h5>
<div class="paragraph">
<p>Template parameter <code>T</code> in spec_constant class template denotes the data type of specialization constant.
The type <code>T</code> must be integral or floating point type.</p>
</div>
</div>
<div class="sect4">
<h5 id="id">ID</h5>
<div class="paragraph">
<p>Template parameter <code>ID</code> in spec_constant class template denotes an unique ID of the specialization constant that can be used to set a value from the host API.
The value of <code>ID</code> must be unique within this compilation unit and across any other SPIR-V modules that it is linked with.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="examples-9">3.5.4. Examples</h4>
<div class="sect4">
<h5 id="example-1-9">Example 1</h5>
<div class="paragraph">
<p>Example of using the specialization constant in the kernel.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_spec_constant&gt;
cl::spec_constant&lt;int, 1&gt; spec1{ 255 };
constexpr cl::spec_constant&lt;int, 2&gt; spec2{ 255 }; // error, constexpr specialization
// constant variables are not allowed
kernel void myKernel()
{
if(cl::get(spec1) == 255)
{
// do something if a default value is used
}
else
{
// do something if the spec constant was specialized by the host
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2-7">Example 2</h5>
<div class="paragraph">
<p>Example of specializing one of the dimensions in <code>cl::required_work_group_size</code> attribute.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_spec_constant&gt;
cl::spec_constant&lt;int, 1&gt; spec1{ 512 };
[[cl::required_work_group_size(spec1, 1, 1)]]
kernel void myKernel()
{
//...
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="half-wrapper-library">3.6. Half Wrapper Library</h3>
<div class="paragraph">
<p>The OpenCL C++ programming language implements a wrapper class for the built-in half data type (see the <a href="#builtin-half-data-type"><em>Built-in Half Data Type</em></a> section).
The class methods perform implicit <code>vload_half</code> and <code>vstore_half</code> operations from the <a href="#vector-data-load-and-store-functions"><em>Vector Data Load and Store Functions</em></a> section.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_half-synopsis">3.6.1. Header &lt;opencl_half&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl {
struct fp16
{
fp16() = default;
fp16(const fp16 &amp;) = default;
fp16(fp16 &amp;&amp;) = default;
fp16 &amp;operator=(const fp16 &amp;) = default;
fp16 &amp;operator=(fp16 &amp;&amp;) = default;
explicit operator bool() const noexcept;
#ifdef cl_khr_fp16
fp16(half r) noexcept;
fp16 &amp;operator=(half r) noexcept;
operator half() const noexcept;
#endif
fp16(float r) noexcept;
fp16 &amp;operator=(float r) noexcept;
operator float() const noexcept;
#ifdef cl_khr_fp64
fp16(double r) noexcept;
fp16 &amp;operator=(double r) noexcept;
operator double() const noexcept;
#endif
fp16 &amp;operator++() noexcept;
fp16 operator++(int) noexcept;
fp16 &amp;operator--() noexcept;
fp16 operator--(int) noexcept;
fp16 &amp;operator+=(const fp16 &amp;r) noexcept;
fp16 &amp;operator-=(const fp16 &amp;r) noexcept;
fp16 &amp;operator*=(const fp16 &amp;r) noexcept;
fp16 &amp;operator/=(const fp16 &amp;r) noexcept;
};
bool operator==(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
bool operator!=(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
bool operator&lt; (const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
bool operator&gt; (const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
bool operator&lt;=(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
bool operator&gt;=(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
fp16 operator+(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
fp16 operator-(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
fp16 operator*(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
fp16 operator/(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="constructors-1">3.6.2. Constructors</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16(const half &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs an object with a half built-in type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16(const float &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs an object with a float built-in type.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vstore_half</code> built-in function is called with the default rounding mode.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16(const double &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs an object with a double built-in type.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vstore_half</code> built-in function is called with the default rounding mode.
The constructor is only present if the double precision support is enabled.</p>
</div>
</div>
<div class="sect3">
<h4 id="assignment-operators-1">3.6.3. Assignment operators</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator=(const half &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigns r to the stored half type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator=(const float &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigns r to the stored half type.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vstore_half</code> built-in function is called with the default rounding mode.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator=(const double &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assigns r to the stored half type.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vstore_half</code> built-in function is called with the default rounding mode.
The operator is only present if the double precision support is enabled.</p>
</div>
</div>
<div class="sect3">
<h4 id="conversion-operators">3.6.4. Conversion operators</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>explicit operator bool() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>m != 0.0h</code>.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>operator half() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Conversion operator to the built-in half type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>operator float() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Conversion operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>operator double() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Conversion operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.
The operator is only present if the double precision support is enabled.</p>
</div>
</div>
<div class="sect3">
<h4 id="arithmetic-operations">3.6.5. Arithmetic operations</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator++() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Pre-increment operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 operator++(int) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Post-increment operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator--() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Pre-decrement operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 operator--(int) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Pre-decrement operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator+=(const fp16 &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Addition operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator-=(const fp16 &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Subtract operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator*=(const fp16 &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiplication operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 &amp;operator/=(const fp16 &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Division operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
</div>
<div class="sect3">
<h4 id="non-member-functions-1">3.6.6. Non-member functions</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool operator==(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison operator ==.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool operator!=(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison operator !=.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool operator&lt; (const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison operator &lt;.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool operator&gt; (const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison operator &gt;.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool operator&lt;=(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison operator &#8656;.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool operator&gt;=(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Comparison operator &gt;=.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> built-in function is called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 operator+(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Addition operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 operator-(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Subtract operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 operator*(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiplication operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>fp16 operator/(const fp16&amp; lhs, const fp16&amp; rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Division operator.
If the <strong>cl_khr_fp16</strong> extension is not supported, <code>vload_half</code> and <code>vstore_half</code> built-in functions are called.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vector-wrapper-library">3.7. Vector Wrapper Library</h3>
<div class="paragraph">
<p>The OpenCL C++ programming language implements a vector wrapper type that works efficiently on the OpenCL devices.
The vector class supports methods that allow construction of a new vector from a swizzled set of component elements or from a built-in vector type.
The vector class can be converted to a corresponding built-in vector type.</p>
</div>
<div class="paragraph">
<p>The <code>Size</code> parameter can be one of: 2, 3, 4, 8 or 16.
Any other value should produce a compilation failure.
The element type parameter <code>T</code>, must be one of the basic scalar types defined in <a href="#device_builtin_scalar_data_types">Device built-in scalar data types</a> table except void type.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_vec-synopsis">3.7.1. Header &lt;opencl_vec&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl {
static constexpr size_t undef_channel = static_cast&lt;size_t&gt;(-1);
enum class channel : size_t { r = 0, g = 1, b = 2, a = 3, x = 0, y = 1, z = 2, w = 3, undef = undef_channel };
template&lt;class T, size_t Size&gt;
struct vec
{
using element_type = T;
using vector_type = make_vector_t&lt;T, Size&gt;;
static constexpr size_t size = Size;
vec( ) = default;
vec(const vec &amp;) = default;
vec(vec &amp;&amp;) = default;
vec(const vector_type &amp;r) noexcept;
vec(vector_type &amp;&amp;r) noexcept;
template &lt;class... Params&gt;
vec(Params... params) noexcept;
vec&amp; operator=(const vec &amp;) = default;
vec&amp; operator=(vec &amp;&amp;) = default;
vec&amp; operator=(const vector_type &amp;r) noexcept;
vec&amp; operator=(vector_type &amp;&amp;r) noexcept;
operator vector_type() const noexcept;
vec&amp; operator++() noexcept;
vec&amp; operator++(int) noexcept;
vec&amp; operator--() noexcept;
vec&amp; operator--(int) noexcept;
vec&amp; operator+=(const vec &amp;r) noexcept;
vec&amp; operator+=(const element_type &amp;r) noexcept;
vec&amp; operator-=(const vec &amp;r) noexcept;
vec&amp; operator-=(const element_type &amp;r) noexcept;
vec&amp; operator*=(const vec &amp;r) noexcept;
vec&amp; operator*=(const element_type &amp;r) noexcept;
vec&amp; operator/=(const vec &amp;r) noexcept;
vec&amp; operator/=(const element_type &amp;r) noexcept;
vec&amp; operator%=(const vec &amp;r) noexcept;
vec&amp; operator%=(const element_type &amp;r) noexcept;
template &lt;size_t... Sizes&gt;
auto swizzle() noexcept;
template &lt;size_t... Sizes&gt;
auto swizzle() const noexcept;
#ifdef SIMPLE_SWIZZLES
auto x() noexcept;
...
auto xyzw() noexcept;
...
auto zzzz() noexcept;
#endif
};
template &lt;size_t... Swizzle, class Vec&gt;
auto swizzle(Vec&amp; v);
template &lt;channel... Swizzle, class Vec&gt;
auto swizzle(Vec&amp; v);
template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator==(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator!=(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&lt;(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&gt;(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&lt;=(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&gt;=(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator+(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator+(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator+(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator-(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator-(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator-(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator*(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator*(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator*(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator/(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator/(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator/(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="constructors-2">3.7.2. Constructors</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec(const vector_type &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Copy constructor.
Constructs an object with the corresponding built-in vector type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec(vector_type &amp;&amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Move constructor.
Constructs an object with the corresponding built-in vector type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class... Params&gt;
vec(Params... params) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs a vector object from a swizzled set of component elements.</p>
</div>
</div>
<div class="sect3">
<h4 id="assignment-operators-2">3.7.3. Assignment operators</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator=(const vector_type &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Copy assignment operator.
The operator assigns a corresponding built-in vector type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator=(vector_type &amp;&amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Move assignment operator.
The operator assigns a corresponding built-in vector type.</p>
</div>
</div>
<div class="sect3">
<h4 id="conversion-operators-1">3.7.4. Conversion operators</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>operator vector_type() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Conversion operator.
The operator converts from the vector wrapper class to a corresponding built-in vector type.</p>
</div>
</div>
<div class="sect3">
<h4 id="arithmetic-operations-1">3.7.5. Arithmetic operations</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator++() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Pre-increment operator.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator++(int) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Post-increment operator.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator--() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Pre-decrement operator.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator--(int) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Post-decrement operator.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator+=(const vec &amp;r) noexcept;
vec&amp; operator+=(const element_type &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Add each element of <code>r</code> to the respective element of the current vector in-place.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator-=(const vec &amp;r) noexcept;
vec&amp; operator-=(const element_type &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Subtract each element of <code>r</code> from the respective element of the current vector in-place.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator*=(const vec &amp;r) noexcept;
vec&amp; operator*=(const element_type &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiply each element of <code>r</code> by the respective element of the current vector in-place.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator/=(const vec &amp;r) noexcept;
vec&amp; operator/=(const element_type &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Divide each element of the current vector in-place by the respective element of <code>r</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>vec&amp; operator%=(const vec &amp;r) noexcept;
vec&amp; operator%=(const element_type &amp;r) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Remainder of each element of the current vector in-place by the respective element of <code>r</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="swizzle-methods">3.7.6. Swizzle methods</h4>
<div class="paragraph">
<p>All swizzle methods return a temporary object representing a swizzled set of the original vector&#8217;s member elements.
The swizzled vector may be used as a source (rvalue) and destination (lvalue).
In order to enable the r-value and lvalue swizzling to work, this returns an intermediate swizzled-vector class, which can be implicitly converted to a vector (rvalue evaluation) or assigned to.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;size_t... Sizes&gt;
auto swizzle() noexcept;
template &lt;size_t... Sizes&gt;
auto swizzle() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a vector swizzle.
The number of template parameters specified in <code>Sizes</code> must be from <code>1</code> to <code>Size</code>.
<code>Sizes</code> parameters must be channel values: <code>channel::r</code>, <code>channel::b</code>, <code>&#8230;&#8203;</code>.
Swizzle letters may be repeated or re-ordered.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>auto x() noexcept;
...
auto xyzw() noexcept;
...
auto zzzz() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a swizzle.
These swizzle methods are only generated if the user defined the <code>SIMPLE_SWIZZLES</code> macro before including <em>opencl_vec</em> header.</p>
</div>
</div>
<div class="sect3">
<h4 id="non-member-functions-2">3.7.7. Non-member functions</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;size_t... Swizzle, class Vec&gt;
auto swizzle(Vec&amp; v);
template &lt;channel... Swizzle, class Vec&gt;
auto swizzle(Vec&amp; v);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a vector swizzle.
The number of template parameters specified in <code>Sizes</code> must be from <code>1</code> to <code>Size</code>.
<code>Sizes</code> parameters must be channel values: <code>channel::r</code>, <code>channel::b</code>, <code>&#8230;&#8203;</code> .
Swizzle letters may be repeated or re-ordered.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator==(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if all elements of <code>rhs</code> compare equal to the respective element of <code>lhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator!=(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if any one element of <code>rhs</code> does not compare equal to the respective element of <code>lhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&lt;(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if all elements of <code>lhs</code> are less than the respective element of <code>rhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&gt;(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if all elements of <code>lhs</code> are greater than the respective element of <code>rhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&lt;=(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if all elements of <code>lhs</code> are less than or equal to the respective element of <code>rhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
make_vector_t&lt;bool, Size&gt; operator&gt;=(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if all elements of <code>lhs</code> are greater than or equal to the respective element of <code>rhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator+(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator+(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator+(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Add each element of <code>rhs</code> to the respective element of <code>lhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator-(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator-(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator-(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Subtract each element of <code>rhs</code> from the respective element of <code>lhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator*(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator*(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator*(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiply each element of <code>rhs</code> by the respective element of <code>lhs</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator/(const vec&lt;T, Size&gt; &amp;lhs,
const vec&lt;T, Size&gt; &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator/(const vec&lt;T, Size&gt; &amp;lhs, const T &amp;rhs) noexcept;
template&lt;class T, size_t Size&gt;
vec&lt;T, Size&gt; operator/(const T &amp;lhs, const vec&lt;T, Size&gt; &amp;rhs) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Divide each element of <code>lhs</code> by the respective element of the <code>rhs</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="range-library">3.8. Range Library</h3>
<div class="paragraph">
<p>OpenCL C++ implements small library that contains useful utilities to manipulate iterator ranges.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_range-synopsis">3.8.1. Header &lt;opencl_range&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class It&gt;
struct range_type
{
constexpr range_type(It&amp; it) noexcept;
constexpr range_type(It&amp; it, difference_type end) noexcept;
constexpr range_type(It&amp; it, difference_type begin,
difference_type end) noexcept;
constexpr auto begin( ) noexcept;
constexpr auto end( ) noexcept;
};
template &lt;class It&gt;
constexpr auto range(It&amp; it) noexcept;
template &lt;class It&gt;
constexpr auto range(It&amp; it, difference_type end) noexcept;
template &lt;class It&gt;
constexpr auto range(It&amp; it, difference_type begin,
difference_type end) noexcept;
// difference_type is It::difference_type if present ptrdiff_t otherwise.
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="range-type">3.8.2. Range type</h4>
<div class="paragraph">
<p>Range type represents a given range over iterable type.
Depending on constructor used:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>constexpr range_type(It&amp; it) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Represents range from <code>begin(it)</code> to <code>end(it)</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>constexpr range_type(It&amp; it, difference_type end) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Represents range from <code>begin(it)</code> to <code>begin(it)+end</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>constexpr range_type(It&amp; it, difference_type begin,
difference_type end) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Represents range from <code>begin(it)+begin</code> to <code>begin(it)+end</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="range-function">3.8.3. Range function</h4>
<div class="paragraph">
<p>range function is present in three overloads matching <code>range_type</code> constructors.
It is a factory function building <code>range_type</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This function main purpose is enabling the use of range based for loops on built-in vectors.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vector-utilities-library">3.9. Vector Utilities Library</h3>
<div class="paragraph">
<p>OpenCL C++ implements vector utilities library that contains multiple helper classes to help working with built-in vectors.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_vector_utility-synopsis">3.9.1. Header &lt;opencl_vector_utility&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;size_t Channel, class Vec&gt;
constexpr remove_attrs_t&lt;vector_element_t&lt;Vec&gt;&gt; get(Vec &amp; vector) noexcept;
template &lt;size_t Channel, class Vec&gt;
constexpr void set(Vec &amp; vector,
remove_attrs_t&lt;vector_element_t&lt;Vec&gt;&gt; value) noexcept;
template &lt;class Vec&gt;
struct channel_ref
{
using type = remove_attrs_t&lt;vector_element_t&lt;Vec&gt;&gt;;
constexpr operator type( ) noexcept;
constexpr channel_ref&amp; operator=(type value) noexcept;
constexpr channel_ref&amp; operator +=(type value) noexcept;
constexpr friend type operator +(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator -=(type value) noexcept;
constexpr friend type operator -(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator *=(type value) noexcept;
constexpr friend type operator *(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator /=(type value) noexcept;
constexpr friend type operator /(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator %=(type value) noexcept;
constexpr friend type operator %(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator ^=(type value) noexcept;
constexpr friend type operator ^(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator &amp;=(type value) noexcept;
constexpr friend type operator &amp;(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator |=(type value) noexcept;
constexpr friend type operator |(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator++( ) noexcept;
constexpr channel_ref operator++(int) noexcept;
constexpr channel_ref&amp; operator--( ) noexcept;
constexpr channel_ref operator--(int) noexcept;
};
template &lt;&gt;
struct channel_ref&lt;floating_point_vector&gt;
{
using type = remove_attrs_t&lt;vector_element_t&lt;Vec&gt;&gt;;
constexpr operator type( ) noexcept;
constexpr channel_ref&amp; operator=(type value) noexcept;
constexpr channel_ref&amp; operator +=(type value) noexcept;
constexpr friend type operator +(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator -=(type value) noexcept;
constexpr friend type operator -(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator *=(type value) noexcept;
constexpr friend type operator *(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator /=(type value) noexcept;
constexpr friend type operator /(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator++( ) noexcept;
constexpr channel_ref&amp; operator++(int) noexcept;
constexpr channel_ref&amp; operator--( ) noexcept;
constexpr channel_ref&amp; operator--(int) noexcept;
};
template &lt;&gt;
struct channel_ref&lt;boolean_vector&gt;
{
using type = remove_attrs_t&lt;vector_element_t&lt;Vec&gt;&gt;;
constexpr operator type( ) noexcept;
constexpr channel_ref&amp; operator=(type value) noexcept;
constexpr channel_ref&amp; operator +=(type value) noexcept;
constexpr friend type operator +(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator -=(type value) noexcept;
constexpr friend type operator -(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator *=(type value) noexcept;
constexpr friend type operator *(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator /=(type value) noexcept;
constexpr friend type operator /(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator %=(type value) noexcept;
constexpr friend type operator %(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator ^=(type value) noexcept;
constexpr friend type operator ^(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator &amp;=(type value) noexcept;
constexpr friend type operator &amp;(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator |=(type value) noexcept;
constexpr friend type operator |(channel_ref lhs, type rhs) noexcept;
constexpr channel_ref&amp; operator++( ) noexcept;
constexpr channel_ref&amp; operator++(int) noexcept;
};
template &lt;class Vec&gt;
struct channel_ptr
{
constexpr channel_ptr( ) noexcept;
constexpr channel_ptr(const channel_ref&lt;Vec&gt;&amp; ref) noexcept;
constexpr channel_ptr(const channel_ptr&amp;) noexcept = default;
constexpr channel_ptr(channel_ptr&amp;&amp;) noexcept = default;
constexpr channel_ptr&amp; operator=(const channel_ptr&amp;) noexcept = default;
constexpr channel_ptr&amp; operator=(channel_ptr&amp;&amp;) noexcept = default;
using type = remove_attrs_t&lt;vector_element_t&lt;Vec&gt;&gt;;
constexpr channel_ref&lt;Vec&gt;&amp; operator*( ) noexcept;
};
template &lt;class Vec&gt;
struct vector_iterator : iterator&lt;random_access_iterator_tag,
remove_attrs_t&lt;vector_element_t&lt;remove_attrs_t&lt;Vec&gt;&gt;&gt;,
ptrdiff_t,
channel_ptr&lt;remove_attrs_t&lt;Vec&gt;&gt;,
channel_ref&lt;remove_attrs_t&lt;Vec&gt;&gt;&gt;
{
using type = remove_attrs_t&lt;Vec&gt;;
constexpr vector_iterator(type &amp; vector, size_t offset) noexcept;
constexpr vector_iterator( ) noexcept = default;
constexpr vector_iterator(const vector_iterator&amp;) noexcept = default;
constexpr vector_iterator(vector_iterator&amp;&amp;) noexcept = default;
constexpr vector_iterator&amp; operator=(
const vector_iterator&amp;) noexcept = default;
constexpr vector_iterator&amp; operator=(vector_iterator&amp;&amp;) noexcept = default;
constexpr vector_iterator&amp; operator+=(difference_type value) noexcept;
constexpr friend vector_iterator operator+(const vector_iterator&amp; lhs,
difference_type rhs) noexcept;
constexpr friend vector_iterator operator+(difference_type lhs,
const vector_iterator&amp; rhs) noexcept;
constexpr vector_iterator&amp; operator-=(difference_type value) noexcept;
constexpr friend vector_iterator operator-(const vector_iterator&amp; lhs,
difference_type rhs) noexcept;
constexpr vector_iterator operator++(int) noexcept;
constexpr vector_iterator&amp; operator++( ) noexcept;
constexpr vector_iterator operator--(int) noexcept;
constexpr vector_iterator&amp; operator--( ) noexcept;
friend constexpr bool operator ==(const vector_iterator&amp; lhs,
const vector_iterator&amp; rhs) noexcept;
friend constexpr bool operator !=(const vector_iterator&amp; lhs,
const vector_iterator&amp; rhs) noexcept;
friend constexpr bool operator &lt;(const vector_iterator&amp; lhs,
const vector_iterator&amp; rhs) noexcept;
friend constexpr bool operator &lt;=(const vector_iterator&amp; lhs,
const vector_iterator&amp; rhs) noexcept;
friend constexpr bool operator &gt;(const vector_iterator&amp; lhs,
const vector_iterator&amp; rhs) noexcept;
friend constexpr bool operator &gt;=(const vector_iterator&amp; lhs,
const vector_iterator&amp; rhs) noexcept;
constexpr reference operator[ ](difference_type value) noexcept;
constexpr reference operator*( ) noexcept;
constexpr pointer operator-&gt;( ) noexcept;
};
template &lt;class Vec, class = enable_if_t&lt;is_vector_type&lt;Vec&gt;::value, void&gt;&gt;
constexpr channel_ref&lt;Vec&gt; index(Vec&amp; vector, size_t channel) noexcept;
template &lt;class Vec, class = enable_if_t&lt;is_vector_type&lt;Vec&gt;::value, void&gt;&gt;
constexpr vector_iterator&lt;Vec&gt; begin(Vec &amp; vector) noexcept;
template &lt;class Vec, class = enable_if_t&lt;is_vector_type&lt;Vec&gt;::value, void&gt;&gt;
constexpr vector_iterator&lt;Vec&gt; end(Vec &amp; vector) noexcept;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="vector-iterator">3.9.2. Vector iterator</h4>
<div class="paragraph">
<p>Vector iterator is a random access iterator that allows runtime iteration over vector channels.
Meets all the requirements for random access iterator.
Iterating outside of vector bounds is an undefined behavior.</p>
</div>
<div class="paragraph">
<p>The library also exposes non member begin and end functions for vectors.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Due to the usage of argument-dependent lookup in range based for loops this functions are not available, and the new range adapter has to be used
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>There is also an <code>index</code> function present in the library that allows runtime numerical indexing of channels.
It returns a channel reference to a given channel number.
Indexing out of vector bounds results in undefined behavior.</p>
</div>
<div class="paragraph">
<p>The following example will present simple template function computing sum of channels of a given vector:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;class V&gt;
auto sum(const V&amp; v) {
vector_element_t&lt;V&gt; temp = 0;
for(auto e : range(v)) {
temp += e;
}
return temp;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="channel-reference-and-channel-pointer">3.9.3. Channel reference and channel pointer</h4>
<div class="paragraph">
<p><code>channel_ref</code> and <code>channel_ptr</code> classes provide lightweight reference and pointer wrappers for vector channels.
This is required due to the fact that vector channels can be moved across memory during execution so direct physical addressing is impossible.
Reference wrapper provides a set of binary operators (depending on vector channel type).</p>
</div>
<div class="paragraph">
<p>The following example will present a simple usage of channel reference to set first channel of given vector to 0:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class V&gt;
void fun(V&amp; v) {
channel_ref&lt;V&gt; r = *begin(v);
r = 0;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="get-and-set-functions">3.9.4. Get and set functions</h4>
<div class="paragraph">
<p>Get and set functions allow compile time numerical indexing of channels to substitute for normal swizzling.
Indexing out of vector range generates a compile error.
Get function returns a copy of channel value.</p>
</div>
<div class="paragraph">
<p>The following example will present how get and set functions can be used to duplicate the value of the first channel of given vector:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class V&gt;
void fun(V&amp; v) {
auto c = get&lt; 0 &gt;(v);
set&lt; 0 &gt;(v, 2*c);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="examples-8">3.9.5. Examples</h4>
<div class="sect4">
<h5 id="example-1-8">Example 1</h5>
<div class="paragraph">
<p>Example of using built-in vector iterators.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_vector_utility&gt;
#include &lt;opencl_range&gt;
using namespace cl;
kernel void foo() {
int8 v_i8;
auto iter_begin = begin(v_i8);
auto iter_end = end(v_i8);
iter_begin = iter_end;
int a = 0;
a = *iter_begin;
a = iter_begin[0];
iter_begin++;
iter_begin+=1;
iter_begin = iter_begin + 1;
iter_begin--;
iter_begin-=1;
iter_begin = iter_begin - 1;
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2-6">Example 2</h5>
<div class="paragraph">
<p>Example of iterating though built-in vector channels and using range library.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_vector_utility&gt;
#include &lt;opencl_range&gt;
kernel void foo() {
int16 a;
for (auto it = cl::begin(a); it != cl::end(a); it++) {
int b = *it;
*it = 2;
}
for (auto c : cl::range(a,3,6)) {
int b = c;
c = 2;
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="marker-types">3.10. Marker Types</h3>
<div class="paragraph">
<p>Some types in OpenCL C++ are considered marker types.
These types are special in the manner that their usages need to be tracked by the compiler.
This results in the following set of restrictions that marker types have to follow:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Marker types have the default constructor deleted.</p>
</li>
<li>
<p>Marker types have all default copy and move assignment operators deleted.</p>
</li>
<li>
<p>Marker types have address-of operator deleted.</p>
</li>
<li>
<p>Marker types cannot be used in divergent control flow. It can result in undefined behavior.</p>
</li>
<li>
<p>Size of marker types is undefined.</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="header-opencl_marker-synopsis">3.10.1. Header &lt;opencl_marker&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
struct marker_type;
template&lt;class T&gt;
struct is_marker_type;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="marker_type-class">3.10.2. marker_type class</h4>
<div class="paragraph">
<p>All special OpenCL C++ types must use the <code>marker_type</code> class as a base class.</p>
</div>
</div>
<div class="sect3">
<h4 id="is_marker_type-type-trait">3.10.3. is_marker_type type trait</h4>
<div class="paragraph">
<p><code>is_marker_type</code> type trait provides compile-time check if the base of a class is <code>marker_type</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T&gt;
struct is_marker_type : integral_constant &lt;bool, is_base_of&lt;marker_type, T&gt;::value&gt; { };
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="examples">3.10.4. Examples</h4>
<div class="sect4">
<h5 id="example-1">Example 1</h5>
<div class="paragraph">
<p>The examples of invalid use of <code>marker types</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_image&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
float4 bar(image1d&lt;float4&gt; img) {
return img.read({get_global_id(0), get_global_id(1)});
}
kernel void foo(image1d&lt;float4&gt; img1, image1d&lt;float4&gt; img2) {
image1d&lt;float4&gt; img3; //error: marker type cannot be declared
// in the kernel
img1 = img2; //error: marker type cannot be assigned
image1d&lt;float4&gt; *imgPtr = &amp;img1; //error: taking address of
// marker type
size_t s = sizeof(img1); //undefined behavior: size of marker
// type is not defined
float4 val = bar(get_global_id(0) ? img1: img2);
//undefined behavior: divergent control flow
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2">Example 2</h5>
<div class="paragraph">
<p>The examples of how to use <code>is_marker_type</code> trait.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_image&gt;
using namespace cl;
kernel void foo(image1d&lt;float4&gt; img) {
static_assert(is_marker_type&lt;decltype(img)&gt;(), "");
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="images-and-samplers-library">3.11. Images and Samplers Library</h3>
<div class="paragraph">
<p>This section describes the image and sampler types and functions that can be used to read from and/or write to an image.
<code>image1d</code>, <code>image1d_buffer</code>, <code>image1d_array</code>, <code>image2d</code>, <code>image2d_array</code>, <code>image3d</code>, <code>image2d_depth</code>, <code>image2d_array_depth</code>, <code>image2d_ms</code>, <code>image2d_array_ms</code>, <code>image2d_depth_ms</code>, <code>image2d_array_depth_ms</code> <a id="ftnref13"></a> <a href="#ftn13">[13]</a> and <code>sampler</code> follow the rules for marker types (see the <a href="#marker-types"><em>Marker Types</em></a> section).
The image and sampler types can only be used if the device support images i.e. <code>CL_DEVICE_IMAGE_SUPPORT</code> as described in table 4.3 in OpenCL 2.2 specification is <code>CL_TRUE</code>.</p>
</div>
<div class="sect3">
<h4 id="image-and-sampler-host-types">3.11.1. Image and Sampler Host Types</h4>
<div class="paragraph">
<p>The below table describes the OpenCL image and sampler data types and the corresponding data type available to the application:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 10. Host image and sampler types</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Type in OpenCL C++</strong></th>
<th class="tableblock halign-left valign-top"><strong>API type for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl::image1d</code>,<br>
<code>cl::image1d_buffer</code>,<br>
<code>cl::image1d_array</code>,<br>
<code>cl::image2d</code>,<br>
<code>cl::image2d_array</code>,<br>
<code>cl::image3d</code>,<br>
<code>cl::image2d_depth</code>,<br>
<code>cl::image2d_array_depth</code>,<br>
<code>cl::image2d_ms</code>,<br>
<code>cl::image2d_array_ms</code>,<br>
<code>cl::image2d_depth_ms</code>,<br>
<code>cl::image2d_array_depth_ms</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_image</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl::sampler</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_sampler</code></p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="header-opencl_image-synopsis">3.11.2. Header &lt;opencl_image&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class image_access;
enum class image_channel_type;
enum class image_channel_order;
enum class addressing_mode;
enum class normalized_coordinates;
enum class filtering_mode;
struct sampler;
template &lt;addressing_mode A, normalized_coordinates C, filtering_mode F&gt;
constexpr sampler make_sampler();
template &lt;class T, image_access A, image_dim Dim, bool Depth, bool Array,
bool MS&gt;
struct image;
template &lt;class T, image_access A = image_access::read&gt;
using image1d = image&lt;T, A, image_dim::image_1d, false, false, false&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image1d_buffer = image&lt;T, A, image_dim::image_buffer, false, false,
false&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image1d_array = image&lt;T, A, image_dim::image_1d, false, true, false&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image2d = image&lt;T, A, image_dim::image_2d, false, false, false&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image2d_depth = image&lt;T, A, image_dim::image_2d, true, false, false&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image2d_array = image&lt;T, A, image_dim::image_2d, false, true, false&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image3d = image&lt;T, A, image_dim::image_3d, false, false, false&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image2d_array_depth = image&lt;T, A, image_dim:: image_2d, true, true,
false&gt;;
#if defined(cl_khr_gl_msaa_sharing) &amp;&amp; defined(cl_khr_gl_depth_images)
template &lt;class T, image_access A = image_access::read&gt;
using image2d_ms = image&lt;T, A, image_dim::image_2d, false, false, true&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image2d_array_ms = image&lt;T, A, image_dim::image_2d, false, true, true&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image2d_depth_ms = image&lt;T, A, image_dim::image_2d, true, false, true&gt;;
template &lt;class T, image_access A = image_access::read&gt;
using image2d_array_depth_ms = image&lt;T, A, image_dim::image_2d, true, true,
true&gt;;
#endif
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where <code>T</code> is the type of value returned when reading or sampling from given image or the type of color used to write to image.</p>
</div>
</div>
<div class="sect3">
<h4 id="image-class">3.11.3. image class</h4>
<div class="paragraph">
<p>Every image type has the following set of publicly available members and typedefs:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class T, image_access A, image_dim Dim, bool Depth, bool Array,
bool MS&gt;
struct image: marker_type
{
static constexpr image_dim dimension = Dim;
static constexpr size_t dimension_num = image_dim_num&lt;Dim&gt;::value;
static constexpr size_t image_size = dimension_num + (Array? 1: 0);
static constexpr image_access access = A;
static constexpr bool is_array = Array;
static constexpr bool is_depth = Depth;
#if defined(cl_khr_gl_msaa_sharing) &amp;&amp; defined(cl_khr_gl_depth_images)
static constexpr bool is_ms = MS;
#else
static constexpr bool is_ms = false;
#endif
typedef element_type T;
typedef integer_coord make_vector_t&lt;int, image_size&gt;;
typedef float_coord make_vector_t&lt;float, image_size&gt;;
#ifdef cl_khr_mipmap_image
typedef gradient_coord make_vector_t&lt;float, dimension_num&gt;;
#endif
struct pixel;
image() = delete;
image(const image&amp;) = default;
image(image&amp;&amp;) = default;
image&amp; operator=(const image&amp;) = delete;
image&amp; operator=(image&amp;&amp;) = delete;
image* operator&amp;() = delete;
};</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="image-element-types">3.11.4. Image element types</h4>
<div class="paragraph">
<p>We can classify images into four categories: depth images which have the <code>Depth</code> template parameter set to <code>true</code>, multi-sample depth images which have the <code>Depth</code> and <code>MS</code> template parameters set to <code>true</code>, multi-sample which have the <code>MS</code> template parameter set to <code>true</code>, and the normal images which have the <code>Depth</code> and <code>MS</code> template parameters set to <code>false</code>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>For non-multisample depth images the only valid element types are: <code>float</code> and <code>half</code> <a id="ftnref14"></a> <a href="#ftn4">[4]</a></p>
</li>
<li>
<p>For normal images the only valid element types are: <code>float4</code>, <code>half4</code> <a href="#ftn4">[4]</a>, <code>int4</code> and <code>uint4</code></p>
</li>
<li>
<p>For multi-sample 2D and multi-sample 2D array images the only valid element types are: <code>float4</code>, <code>int4</code> and <code>uint4</code></p>
</li>
<li>
<p>For multi-sample 2D depth and multi-sample 2D array depth images the only valid element type is: <code>float</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Image type with invalid pixel type is ill formed.</p>
</div>
</div>
<div class="sect3">
<h4 id="image-dimension">3.11.5. Image dimension</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class image_dim
{
image_1d,
image_2d,
image_3d,
image_buffer
};
template &lt;image_dim Dim&gt;
struct image_dim_num;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Image types present different set of methods depending on their dimensionality and arrayness.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Images of dimension 1 (<code>image_dim::image_1d</code> and <code>image_dim::buffer</code>) have method:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int width() const noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Images of dimension 2 (<code>image_dim::image_2d</code>) have all methods of 1 dimensional images and</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int height() const noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Images of dimension 3 (<code>image_dim::image_3d</code>) have all methods of 2 dimensional images and</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int depth() const noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Arrayed images have additional method</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int array_size() const noexcept;</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <strong>cl_khr_mipmap_image</strong> or <strong>cl_khr_mipmap_image_writes</strong> extension is enabled, then the following methods are also present:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Images of dimension 1 (<code>image_dim::image_1d</code> and <code>image_dim::buffer</code>) have method:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int width(int lod) const noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Images of dimension 2 (<code>image_dim::image_2d</code>) have all methods of 1 dimensional images and</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int height(int lod) const noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Images of dimension 3 (<code>image_dim::image_3d</code>) have all methods of 2 dimensional images and</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int depth(int lod) const noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Arrayed images have additional method</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int array_size(int lod) const noexcept;</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <strong>cl_khr_gl_msaa_sharing</strong> and <strong>cl_khr_gl_depth_images</strong> extensions are enabled, then the following methods are also present:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Images of dimension 2D (<code>image_dim::image_2d</code>) have method:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int num_samples() const noexcept;</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following table describes the <code>image_dim_num</code> trait that return a number of dimensions based on <code>image_dim</code> parameter.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 11. Image_dim_num trait</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Template</strong></th>
<th class="tableblock halign-left valign-top"><strong>Value</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;image_dim Dim&gt; struct image_dim_num;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>Dim</code> is <code>image_dim::image_1d</code> or <code>image_dim::image_buffer</code>, image dimension is 1.<br>
If <code>Dim</code> is <code>image_dim::image_2d</code>, image dimension is 2.<br>
If <code>Dim</code> is <code>image_dim::image_3d</code>, image dimension is 3.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="image-access">3.11.6. Image access</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class image_access
{
sample,
read,
write,
read_write
};
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The non-multisample image template class specializations present different set of methods based on their access parameter.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Images specified with <code>image_access::read</code> provide additional methods:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::read(integer_coord coord) const noexcept;
pixel image::operator[](integer_coord coord) const noexcept;
element_type image::pixel::operator element_type() const noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Images specified with <code>image_access::write</code> provide additional method:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void image::write(integer_coord coord, element_type color) noexcept;
image::pixel image::operator[](integer_coord coord) noexcept;
image::pixel &amp; image::pixel::operator=(element_type color) noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Images specified with <code>image_access::read_write</code> provide additional methods:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::read(integer_coord coord) const noexcept;
void image::write(integer_coord coord, element_type color) noexcept;
image::pixel image::operator[](integer_coord coord) noexcept;
element_type image::pixel::operator element_type() const noexcept;
image::pixel &amp; image::pixel::operator=(element_type color) noexcept;</code></pre>
</div>
</div>
</li>
<li>
<p>Images specified with <code>image_access::sample</code> provide additional methods:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::read(integer_coord coord) const noexcept;
element_type image::sample(const sampler &amp;s,
integer_coord coord) const noexcept;
element_type image::sample(const sampler &amp;s, float_coord coord) const noexcept;
image::pixel image::operator[](integer_coord coord) const noexcept;
element_type image::pixel::operator element_type() const noexcept;</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <strong>cl_khr_mipmap_image</strong> extension is enabled the following methods are added to the non-multisample image types:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Images specified with <code>image_access::sample</code> provide additional methods:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::sample(const sampler &amp;s, float_coord coord,
float lod) const noexcept;
element_type image::sample(const sampler &amp;s, float_coord coord,
gradient_coord gradient_x,
gradient_coord gradient_y) const noexcept;</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <strong>cl_khr_mipmap_image_writes</strong> extension is enabled the following methods are added to the non-multisample image types:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Images specified with <code>image_access::write</code> provide additional method:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void image::write(integer_coord coord, element_type color, int lod) noexcept;</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <strong>cl_khr_gl_msaa_sharing</strong> and <strong>cl_khr_gl_depth_images</strong> extensions are enabled and the multisample image type is used, the following method is available:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The multisample images specified with <code>image_access::read</code> provide method:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::read(integer_coord coord, int sample) noexcept;</code></pre>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="common-image-methods">3.11.7. Common image methods</h4>
<div class="paragraph">
<p>Each image type implements a set of common methods:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>image_channel_type image::data_type() const noexcept;
image_channel_order image::order() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the <strong>cl_khr_mipmap_image</strong> or <strong>cl_khr_mipmap_image_writes</strong> extension is enabled, then the following method is also present in the non-multisample image types:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int image::miplevels() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>where <code>image_channel_type</code> and <code>image_channel_order</code> are defined as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class image_channel_type
{
snorm_int8,
snorm_int16,
unorm_int8,
unorm_int16,
unorm_int24,
unorm_short_565,
unorm_short_555,
unorm_int_101010,
unorm_int_101010_2,
signed_int8,
signed_int16,
signed_int32,
unsigned_int8,
unsigned_int16,
unsigned_int32,
fp16,
fp32
};
enum class image_channel_order
{
a,
r,
rx,
rg,
rgx,
ra,
rgb,
rgbx,
rgba,
argb,
bgra,
intensity,
luminance,
abgr,
depth,
depth_stencil,
srgb,
srgbx,
srgba,
sbgra
};
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="other-image-methods">3.11.8. Other image methods</h4>
<div class="sect4">
<h5 id="imagesample">image::sample</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::sample(const sampler &amp;s, float_coord coord) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reads a color value from the non-multisample image using sampler and floating point coordinates.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::sample(const sampler &amp;s, integer_coord coord) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reads a color value from non-multisample image using sampler and integer coordinates.</p>
</div>
<div class="paragraph">
<p>A sampler must use filter mode set to <code>filtering_mode::nearest</code>, normalized coordinates and addressing mode set to <code>addressing_mode::clamp_to_edge</code>, <code>addressing_mode::clamp</code>, <code>addressing_mode::none</code>, otherwise the values returned are undefined.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::sample(const sampler &amp;s, float_coord coord, float lod) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reads a color value from non-multisample image using sampler and floating point coordinates in the mip-level specified by <code>lod</code>.</p>
</div>
<div class="paragraph">
<p>Method is present for non-multisample images if the <strong>cl_khr_mipmap_image</strong> extension is enabled.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::sample(const sampler &amp;s, float_coord coord,
gradient_coord gradient_x,
gradient_coord gradient_y) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Use the gradients to compute the lod and coordinate <code>coord</code> to do an element lookup in the mip-level specified by the computed lod.</p>
</div>
<div class="paragraph">
<p>Method is present if the <strong>cl_khr_mipmap_image</strong> extension is enabled.</p>
</div>
<div class="paragraph">
<p>Based on the parameters with which image was created on host side the
function will return different ranges of values</p>
</div>
<div class="ulist">
<ul>
<li>
<p>returns floating-point values in the range [0.0, 1.0] for image objects created with <code>image_channel_type</code> set to one of the pre-defined packed formats or <code>image_channel_type::unorm_int8</code> or <code>image_channel_type::unorm_int16</code>.</p>
</li>
<li>
<p>returns floating-point values in the range [-1.0, 1.0] for image objects created with <code>image_channel_type::snorm_int8</code> or <code>image_channel_type::snorm_int16</code>.</p>
</li>
<li>
<p>returns floating-point values for image objects created with <code>image_channel_type::float16</code> or <code>image_channel_type::float32</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Values returned by <code>image::sample</code> where <code>T</code> is a floating-point type for image objects with <code>image_channel_type</code> values not specified in the description above are undefined.</p>
</div>
<div class="paragraph">
<p>The <code>image::sample</code> functions that take an image object where <code>T</code> is a signed integer type can only be used with image objects created with:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>image_channel_type::sint8</code>,</p>
</li>
<li>
<p><code>image_channel_type::sint16</code> and</p>
</li>
<li>
<p><code>image_channel_type::sint32</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <code>image_channel_type</code> is not one of the above values, the values returned by <code>image::sample</code> are undefined.</p>
</div>
<div class="paragraph">
<p>The <code>image::sample</code> functions that take an image object where <code>T</code> is an unsigned integer type can only be used with image objects created with:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>image_channel_type::uint8</code>,</p>
</li>
<li>
<p><code>image_channel_type::uint16</code> and</p>
</li>
<li>
<p><code>image_channel_type::uint32</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <code>image_channel_type</code> is not one of the above values, the values returned by <code>image::sample</code> are undefined.</p>
</div>
</div>
<div class="sect4">
<h5 id="imageread">image::read</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::read(integer_coord coord) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reads a color value from non-multisample image without sampler and integral coordinates.
If the <strong>cl_khr_mipmap_image</strong> extension is present, may also perform reads from mipmap layer 0.</p>
</div>
<div class="paragraph">
<p>The image read function behaves exactly as the corresponding image sample function using a sampler
that has filter mode set to <code>filtering_mode::nearest</code>, normalized coordinates set to
<code>normalized_coordinates::unnormalized</code> and addressing mode set to <code>addressing_mode::none</code>.
There is one execption for cases where the image sample type is <code>image_channel_type::fp32</code>.
In this exceptional case, when channel data values are denormalized, the image read function may return
the denormalized data, while the sample function may flush denormalized channel data values to zero.
The coordinates must be between 0 and image size in that dimension non inclusive.</p>
</div>
<div class="paragraph">
<p>Based on the parameters with which image was created on host side the function will return different ranges of values</p>
</div>
<div class="ulist">
<ul>
<li>
<p>returns floating-point values in the range [0.0, 1.0] for image objects created with <code>image_channel_type</code> set to one of the pre-defined packed formats or <code>image_channel_type::unorm_int8</code> or <code>image_channel_type::unorm_int16</code>.</p>
</li>
<li>
<p>returns floating-point values in the range [-1.0, 1.0] for image objects created with <code>image_channel_type::snorm_int8</code> or <code>image_channel_type::snorm_int16</code>.</p>
</li>
<li>
<p>returns floating-point values for image objects created with <code>image_channel_type::float16</code> or <code>image_channel_type::float32</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Values returned by <code>image::read</code> where <code>T</code> is a floating-point type for image objects with <code>image_channel_type</code> values not specified in the description above are undefined.</p>
</div>
<div class="paragraph">
<p>The <code>image::read</code> functions that take an image object where <code>T</code> is a signed integer type can only be used with image objects created with:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>image_channel_type::sint8</code>,</p>
</li>
<li>
<p><code>image_channel_type::sint16</code> and</p>
</li>
<li>
<p><code>image_channel_type::sint32</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <code>image_channel_type</code> is not one of the above values, the values returned by <code>image::read</code> are undefined.</p>
</div>
<div class="paragraph">
<p>The <code>image::read</code> functions that take an image object where <code>T</code> is an unsigned integer type can only be used with image objects created with <code>image_channel_type</code> set to one of the following values:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>image_channel_type::uint8</code>,</p>
</li>
<li>
<p><code>image_channel_type::uint16</code> and</p>
</li>
<li>
<p><code>image_channel_type::uint32</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If the <code>image_channel_type</code> is not one of the above values, the values returned by <code>image::read</code> are undefined.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type image::read(integer_coord coord, int sample) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Use the coordinate and sample to do an element lookup in the image object.
Method is only available in the MSAA image types, and if the <strong>cl_khr_gl_msaa_sharing</strong> and <strong>cl_khr_gl_depth_images</strong> extensions are enabled.</p>
</div>
<div class="paragraph">
<p>When a multisample image is accessed in a kernel, the access takes one vector of integers describing which pixel to fetch and an integer corresponding to the sample numbers describing which sample within the pixel to fetch.
<code>sample</code> identifies the sample position in the multi-sample image.</p>
</div>
<div class="paragraph">
<p>For best performance, we recommend that sample be a literal value so it is known at compile time and the OpenCL compiler can perform appropriate optimizations for multisample reads on the device.</p>
</div>
<div class="paragraph">
<p>No standard sampling instructions are allowed on the multisample image.
Accessing a coordinate outside the image and/or a sample that is outside the number of samples associated with each pixel in the image is undefined.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagewrite">image::write</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void image::write(integer_coord coord, element_type color) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Writes a color value to location specified by coordinates from non-multisample image.
If the <strong>cl_khr_mipmap_image_writes</strong> extension is present, may also perform writes to mipmap layer 0.
The coordinates must be between 0 and image size in that dimension non inclusive.</p>
</div>
<div class="paragraph">
<p>Based on the parameters with which image was created on host side the function will perform appropriate data format conversions before writing a color value.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void image::write(integer_coord coord, element_type color, int lod) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Writes a color value to location specified by coordinates and lod from mipmap image.
The coordinates must be between 0 and image size in that dimension non inclusive.</p>
</div>
<div class="paragraph">
<p>Method is present if the <strong>cl_khr_mipmap_image</strong> extension is enabled.</p>
</div>
<div class="paragraph">
<p>Based on the parameters with which image was created on host side the function will perform appropriate data format conversions before writing a color value.</p>
</div>
<div class="paragraph">
<p>The <code>image::write</code> functions that take an image object where <code>T</code> is a floating-point type can only be used with image objects created with <code>image_channel_type</code> set to one of the pre-defined packed formats or set to:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>image_channel_type::snorm_int8</code></p>
</li>
<li>
<p><code>image_channel_type::unorm_int8</code></p>
</li>
<li>
<p><code>image_channel_type::snorm_int16</code></p>
</li>
<li>
<p><code>image_channel_type::unorm_int16</code></p>
</li>
<li>
<p><code>image_channel_type::float16</code></p>
</li>
<li>
<p><code>image_channel_type::float32</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>image::write</code> functions that take an image object where <code>T</code> is a signed integer type can only be used with image objects created with:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>image_channel_type::sint8</code></p>
</li>
<li>
<p><code>image_channel_type::sint16</code></p>
</li>
<li>
<p><code>image_channel_type::sint32</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>image::write</code> functions that take an image object where <code>T</code> is an unsigned integer type can only be used with image objects created with:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>image_channel_type::uint8</code></p>
</li>
<li>
<p><code>image_channel_type::uint16</code></p>
</li>
<li>
<p><code>image_channel_type::uint32</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The behavior of <code>image::write</code> for image objects created with
<code>image_channel_type</code> values not specified in the description above is undefined.</p>
</div>
</div>
<div class="sect4">
<h5 id="imageoperator">\image::operator[]</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>pixel operator[](integer_coord coord) noexcept;
pixel operator[](integer_coord coord) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Creates a pixel which can be used to read or/and write operation(s).
It depends on image_access specified in the image.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The pixel stores a reference to image and coordinates.
This operation can consume more private memory than <code>image::read</code> and <code>image::write</code> methods.
It can also negatively impact performance.
</td>
</tr>
</table>
</div>
</div>
<div class="sect4">
<h5 id="imagepixeloperator-element_type">image::pixel::operator element_type</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>element_type pixel::operator element_type() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reads a color value from non-multisample image without sampler and integral coordinates specified in pixel.
If the <strong>cl_khr_mipmap_image</strong> extension is present, may also perform reads from mipmap layer 0.</p>
</div>
<div class="paragraph">
<p>This function is similar to <code>image::read</code> method.
Please refer to description of this method for more details.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagepixeloperator">image::pixel::operator=</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>pixel &amp; pixel::operator=(element_type color) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Writes a color value to location specified by coordinates in pixel from non-multisample image.
If the <strong>cl_khr_mipmap_image_writes</strong> extension is present, may also perform writes to mipmap layer 0.
The coordinates specified in pixel must be between 0 and image size in that dimension non inclusive.</p>
</div>
<div class="paragraph">
<p>Based on the parameters with which image was created on host side the function will perform appropriate data format conversions before writing a color value.</p>
</div>
<div class="paragraph">
<p>This function is similar to <code>image::write</code> method.
Please refer to description of this method for more details.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagewidth">image::width</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int width() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns width of the image.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int width(int lod) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns width of the mip-level specified by <code>lod</code>.</p>
</div>
<div class="paragraph">
<p>Method is present in the non-multisample image types if the <strong>cl_khr_mipmap_image</strong> extension is enabled.</p>
</div>
</div>
<div class="sect4">
<h5 id="imageheight">image::height</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int height() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns height of the image.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int height(int lod) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns height of the mip-level specified by <code>lod</code>.</p>
</div>
<div class="paragraph">
<p>Method is present in the non-multisample image types if the <strong>cl_khr_mipmap_image</strong> extension is enabled.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagedepth">image::depth</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int depth() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns depth of the image.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int depth(int lod) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns depth of the mip-level specified by <code>lod</code>.</p>
</div>
<div class="paragraph">
<p>Method is present in the non-multisample image types if the <strong>cl_khr_mipmap_image</strong> extension is enabled.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagearray_size">image::array_size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int array_size() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns size of the image array.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int array_size(int lod) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns size of the image array specified by <code>lod</code>.</p>
</div>
<div class="paragraph">
<p>Method is present in the non-multisample image types if the <strong>cl_khr_mipmap_image</strong> extension is enabled.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagesize">image::size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>integer_coord size() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns appropriately sized vector, or scalar for 1 dimensional images, containing all image dimensions followed by array size.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagedata_type">image::data_type</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>image_channel_type image::data_type() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns format of the image as specified upon its creation on host side.</p>
</div>
</div>
<div class="sect4">
<h5 id="imageorder">image::order</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>image_channel_order image::order() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns channel order of the image as specified upon its creation on host side.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagemiplevels">image::miplevels</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int miplevels() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns number of mipmaps of image.
Method is present if the <strong>cl_khr_mipmap_image</strong> or <strong>cl_khr_mipmap_image_writes</strong> extension is enabled.</p>
</div>
</div>
<div class="sect4">
<h5 id="imagenum_samples">image::num_samples</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int num_samples() const noexcept;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="sampler">3.11.9. Sampler</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
struct sampler: marker_type
{
sampler() = delete;
sampler(const sampler&amp;) = default;
sampler(sampler&amp;&amp;) = default;
sampler&amp; operator=(const sampler&amp;) = delete;
sampler&amp; operator=(sampler&amp;&amp;) = delete;
sampler* operator&amp;() = delete;
};
template &lt;addressing_mode A, normalized_coordinates C, filtering_mode F&gt;
constexpr sampler make_sampler();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are only two ways of acquiring a sampler inside of a kernel. One is to pass it as a kernel parameter from host using <code>clSetKernelArg</code>, the other one is to create one using make_sampler function in the kernel code. <code>make_sampler</code> function has three template parameters specifying behavior of sampler. Once acquired sampler can only be passed by reference as all other marker types. The sampler objects at non-program scope must be declared with static specifier.</p>
</div>
<div class="paragraph">
<p>The maximum number of samplers that can be declared in a kernel can be queried using the <code>CL_DEVICE_MAX_SAMPLERS</code> token in <code>clGetDeviceInfo</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="sampler-modes">3.11.10. Sampler Modes</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class addressing_mode
{
mirrored_repeat,
repeat,
clamp_to_edge,
clamp,
none
};
enum class normalized_coordinates
{
normalized,
unnormalized
};
enum class filtering_mode
{
nearest,
linear
};
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following tables describe the inline sampler parameters and their behavior.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 12. Addressing modes</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Addressing mode</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>mirrored_repeat</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Out of range coordinates will be flipped at every integer junction. This addressing mode can only be used with normalized coordinates. If normalized coordinates are not used, this addressing mode may generate image coordinates that are undefined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>repeat</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Out of range image coordinates are wrapped to the valid range. This addressing mode can only be used with normalized coordinates. If normalized coordinates are not used, this addressing mode may generate image coordinates that are undefined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>clamp_to_edge</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Out of range image coordinates are clamped to the extent.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>clamp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Out of range image coordinates will return a border color.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>none</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For this addressing mode the programmer guarantees that the image coordinates used to sample elements of the image refer to a location inside the image; otherwise the results are undefined.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>For 1D and 2D image arrays, the addressing mode applies only to the <em>x</em> and (<em>x, y</em>) coordinates. The addressing mode for the coordinate which specifies the array index is always clamp_to_edge.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 13. Normalized coordinates</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Normalized Coordinate Values</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>normalized</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies whether the <em>x</em>, <em>y</em> and <em>z</em> coordinates are passed in as normalized values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>unnormalized</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specifies whether the <em>x</em>, <em>y</em> and <em>z</em> coordinates are passed in as unnormalized values.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Sampling from an image with samplers that differ in specification of coordinates normalization result in undefined behavior.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 14. Coordinate filtering modes</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Filtering mode</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>nearest</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Chooses a color of nearest pixel.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>linear</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Performs a linear sampling of adjacent pixels.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Refer to <em>section 4.2</em> in the OpenCL API specification for a description of these filter modes.</p>
</div>
</div>
<div class="sect3">
<h4 id="determining-the-border-color-or-value">3.11.11. Determining the border color or value</h4>
<div class="paragraph">
<p>If <code>&lt;addressing mode&gt;</code> in sampler is clamp, then out-of-range image coordinates return the border color. The border color selected depends on the image channel order and can be one of the following values:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If the image channel order is <code>image_channel_order::a</code>, <code>image_channel_order::intensity</code>, <code>image_channel_order::rx</code>, <code>image_channel_order::ra</code>, <code>image_channel_order::rgx</code>, <code>image_channel_order::rgbx</code>, <code>image_channel_order::srgbx</code>, <code>image_channel_order::argb</code>, <code>image_channel_order::bgra</code>, <code>image_channel_order::abgr</code>, <code>image_channel_order::rgba</code>, <code>image_channel_order::srgba</code> or <code>image_channel_order::sbgra</code>, the border color is (0.0f, 0.0f, 0.0f, 0.0f).</p>
</li>
<li>
<p>If the image channel order is <code>image_channel_order::r</code>, <code>image_channel_order::rg</code>, <code>image_channel_order::rgb</code>, or <code>image_channel_order::luminance</code>, the border color is (0.0f, 0.0f, 0.0f, 1.0f).</p>
</li>
<li>
<p>If the image channel order is <code>image_channel_order::depth</code>, the border value is 0.0f.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="srgb-images">3.11.12. sRGB Images</h4>
<div class="paragraph">
<p>The built-in image read functions perform sRGB to linear RGB conversions if the image is an sRGB image. Writes to sRGB images from a kernel is an optional extension. The <strong>cl_khr_srgb_image_writes</strong> extension will be reported in the <code>CL_DEVICE_EXTENSIONS</code> string if a device supports writing to sRGB images using <code>image::write</code>. <code>clGetSupportedImageFormats</code> will return the supported sRGB images if <code>CL_MEM_READ_WRITE</code> or <code>CL_MEM_WRITE_ONLY</code> is specified in <code>flags</code> argument and the device supports writing to an sRGB image. If the <strong>cl_khr_srgb_image_writes</strong> extension is supported and has been enabled, the built-in image write functions perform the linear to sRGB conversion.</p>
</div>
<div class="paragraph">
<p>Only the R, G and B components are converted from linear to sRGB and vice-versa. The alpha component is returned as is.</p>
</div>
</div>
<div class="sect3">
<h4 id="reading-and-writing-to-the-same-image-in-a-kernel">3.11.13. Reading and writing to the same image in a kernel</h4>
<div class="paragraph">
<p>To read and write to the same image in a kernel, the image must be declared with the <code>image_access::read_write</code>. Only sampler-less reads and write functions can be called on an image declared with the <code>image_access::read_write</code> access qualifier. Calling the <code>image::sample</code> functions on an image declared with the <code>image_access::read_write</code> will result in a compilation error.</p>
</div>
<div class="paragraph">
<p>The <code>atomic_fence</code> function from the <a href="#fences"><em>Atomic Fences</em></a> section can be used to make sure that writes are visible to later reads by the same work-item. Without use of the <code>atomic_fence</code> function, write-read coherence on image objects is not guaranteed: if a work-item reads from an image to which it has previously written without an intervening atomic_fence, it is not guaranteed that those previous writes are visible to the work-item. Only a scope of <code>memory_order_acq_rel</code> is valid for <code>atomic_fence</code> when passed the <code>mem_fence::image</code> flag. If multiple work-items are writing to and reading from multiple locations in an image, the <code>work_group_barrier</code> from the <a href="#synchronization-functions"><em>Synchronization Functions</em></a> section should be used.</p>
</div>
<div class="paragraph">
<p>Consider the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_work_item&gt;
#include &lt;opencl_atomic&gt;
#include &lt;opencl_image&gt;
using namespace cl;
kernel void foo(image2d&lt;float4, image_access::read_write&gt; img, ... ) {
int2 coord;
coord.x = (int)get_global_id(0);
coord.y = (int)get_global_id(1);
float4 clr = img.read(coord);
//...
img.write(coord, clr);
// required to ensure that following read from image at
// location coord returns the latest color value.
atomic_fence(mem_fence::image,
memory_order_acq_rel,
memory_scope_work_item);
float4 clr_new = img.read(coord);
//...
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="mapping-image-channels-to-color-values-returned-by-imagesample-imageread-and-color-values-passed-to-imagewrite-to-image-channels">3.11.14. Mapping image channels to color values returned by image::sample, image::read and color values passed to image::write to image channels</h4>
<div class="paragraph">
<p>The following table describes the mapping of the number of channels of an image element to the appropriate components in the <code>float4</code>, <code>int4</code> or <code>uint4</code> vector data type for the color values returned by <code>image::sample</code>, <code>image::read</code> or supplied to <code>image::write</code>. The unmapped components will be set to 0.0 for red, green and blue channels and will be set to 1.0 for the alpha channel.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 15. Image channel mappings</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Image Channel Order</strong></th>
<th class="tableblock halign-left valign-top"><strong>float4, int4 or uint4 components of channel data</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">r, rx</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(r, 0.0, 0.0, 1.0)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">a</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(0.0, 0.0, 0.0, a)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rg, rgx</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(r, g, 0.0, 1.0)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ra</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(r, 0.0, 0.0, a)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rgb, rgbx, srgb, srgbx</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(r, g, b, 1.0)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rgba, bgra, argb, abgr, srgba, sbgra</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(r, g, b, a)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">intensity</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(I, I, I, I)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">luminance</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(L, L, L, 1.0)</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>For <code>image_channel_order::depth</code> images, a scalar value is returned by <code>image::sample</code>, <code>image::read</code> or supplied to <code>image::write</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
A kernel that uses a sampler with the clamp addressing mode with multiple images may result in additional samplers being used internally by an implementation. If the same sampler is used with multiple images called via <code>image::sample</code>, then it is possible that an implementation may need to allocate an additional sampler to handle the different border color values that may be needed depending on the image formats being used. The implementation allocated samplers will count against the maximum sampler values supported by the device and given by <code>CL_DEVICE_MAX_SAMPLERS</code>. Enqueuing a kernel that requires more samplers than the implementation can support will result in a <code>CL_OUT_OF_RESOURCES</code> error being returned.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="restrictions-4">3.11.15. Restrictions</h4>
<div class="ulist">
<ul>
<li>
<p>The image and sampler types cannot be used with variables declared inside a class or union field, a pointer type, an array, global variables declared at program scope or the return type of a function.</p>
</li>
<li>
<p>The image and sampler types cannot be used with the <code>global</code>, <code>local</code>, <code>priv</code> and <code>constant</code> address space storage classes (see the <a href="#explicit-address-space-storage-classes"><em>Explicit address space storage classes</em></a> section).</p>
</li>
<li>
<p>The values returned by applying the <code>sizeof</code> operator to the image and sampler types are implementation-defined.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="examples-5">3.11.16. Examples</h4>
<div class="sect4">
<h5 id="example-1-5">Example 1</h5>
<div class="paragraph">
<p>The example how to use an image object with sampler-less reads.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_image&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo(image2d&lt;float4, image_access::read&gt; img) {
int2 coord;
coord.x = get_global_id(0);
coord.y = get_global_id(1);
float4 val = img.read(coord);
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2-3">Example 2</h5>
<div class="paragraph">
<p>The example how to use an image object with <code>image_access::read_write</code> access and <code>atomic_fence</code> function.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_image&gt;
#include &lt;opencl_atomic&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo(image2d&lt;float4, image_access::read_write&gt; img) {
int2 coord;
coord.x = get_global_id(0);
coord.y = get_global_id(1);
float4 val1{0.5f};
img[coord] = val1;
atomic_fence(mem_fence::image, memory_order_acq_rel,
memory_scope_work_item);
float4 val2 = img[coord];
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-3-2">Example 3</h5>
<div class="paragraph">
<p>The example how to use an image object with sampler passed by a kernel argument.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_image&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo(image2d&lt;float4, image_access::sample&gt; img, sampler s) {
int2 coord;
coord.x = get_global_id(0);
coord.y = get_global_id(1);
float4 val = img.sample(s, coord);
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-4-1">Example 4</h5>
<div class="paragraph">
<p>The example how to use an image object with sampler declared at program scope.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_image&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
sampler s = make_sampler&lt;addressing_mode::clamp,
normalized_coordinates::unnormalized,
filtering_mode::nearest&gt;();
kernel void foo(image2d&lt;float4, image_access::sample&gt; img) {
int2 coord;
coord.x = get_global_id(0);
coord.y = get_global_id(1);
float4 val = img.sample(s, coord);
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-5-1">Example 5</h5>
<div class="paragraph">
<p>The example how to use an image object with sampler declared at non-program scope.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_image&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo(image2d&lt;float4, image_access::sample&gt; img) {
int2 coord;
coord.x = get_global_id(0);
coord.y = get_global_id(1);
static sampler s = make_sampler&lt;addressing_mode::clamp,
normalized_coordinates::unnormalized,
filtering_mode::nearest&gt;();
float4 val = img.sample(s, coord);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="pipes-library">3.12. Pipes Library</h3>
<div class="paragraph">
<p>Header <em>&lt;opencl_pipe&gt;</em> defines <code>pipe</code> and <code>pipe_storage</code> template classes.
<code>pipe</code> and <code>pipe_storage</code> can be used as a communication channel between kernels.
<code>pipe</code>, <code>reservation</code> and <code>pipe_storage</code> template classes follow all the rules for marker types as specified in the <a href="#marker-types"><em>Marker Types</em></a> section.</p>
</div>
<div class="sect3">
<h4 id="pipe-host-type">3.12.1. Pipe Host Type</h4>
<div class="paragraph">
<p>The below describes the OpenCL pipe data type and the corresponding data type available to the application:</p>
</div>
<table id="host_pipe_type" class="tableblock frame-all grid-all spread">
<caption class="title">Table 16. Host pipe type</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Type in OpenCL C++</strong></th>
<th class="tableblock halign-left valign-top"><strong>API type for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl::pipe</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_pipe</code></p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="header-opencl_pipe-synopsis">3.12.2. Header &lt;opencl_pipe&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class pipe_access { read, write };
template &lt;class T, pipe_access Access = pipe_access::read&gt;
struct pipe;
template &lt;class T, size_t N&gt;
struct pipe_storage;
template&lt;pipe_access Access = pipe_access::read, class T, size_t N&gt;
pipe&lt;T, Access&gt; make_pipe(const pipe_storage&lt;T, N&gt;&amp; ps);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="pipe-class-specializations">3.12.3. pipe class specializations</h4>
<div class="paragraph">
<p><code>pipe</code> class has two distinct specializations depending on <code>pipe_access</code> parameter defined as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class T, pipe_access Access = pipe_access::read&gt;
struct pipe: marker_type
{
typedef T element_type;
static constexpr pipe_access access = Access;
template&lt;memory_scope S&gt;
struct reservation: marker_type
{
reservation() = delete;
reservation(const reservation&amp;) = default;
reservation(reservation&amp;&amp;) = default;
reservation&amp; operator=(const reservation&amp;) = delete;
reservation&amp; operator=(reservation&amp;&amp;) = delete;
reservation* operator&amp;() = delete;
bool is_valid() const noexcept;
bool read(uint index, T&amp; ref) const noexcept;
void commit() noexcept;
explicit operator bool() const noexcept;
};
pipe() = delete;
pipe(const pipe&amp;) = default;
pipe(pipe&amp;&amp;) = default;
pipe&amp; operator=(const pipe&amp;) = delete;
pipe&amp; operator=(pipe&amp;&amp;) = delete;
pipe* operator&amp;() = delete;
bool read(T&amp; ref) const noexcept;
reservation&lt;memory_scope_work_item&gt; reserve(
uint num_packets) const noexcept;
reservation&lt;memory_scope_work_group&gt; work_group_reserve(
uint num_packets) const noexcept;
reservation&lt;memory_scope_sub_group&gt; sub_group_reserve(
uint num_packets) const noexcept;
uint num_packets() const noexcept;
uint max_packets() const noexcept;
};
template &lt;class T&gt;
struct pipe&lt;T, pipe_access::write&gt;: marker_type
{
typedef T element_type;
static constexpr pipe_access access = pipe_access::write;
template&lt;memory_scope S&gt;
struct reservation: marker_type
{
reservation() = delete;
reservation(const reservation &amp;) = default;
reservation(reservation &amp;&amp;) = default;
reservation&amp; operator=(const reservation &amp;) noexcept = delete;
reservation&amp; operator=(reservation &amp;&amp;) noexcept = delete;
reservation* operator&amp;() = delete;
bool is_valid() const noexcept;
bool write(uint index, const T&amp; ref) noexcept;
void commit() noexcept;
explicit operator bool() const noexcept;
};
pipe() = delete;
pipe(const pipe&amp;) = default;
pipe(pipe&amp;&amp;) = default;
pipe&amp; operator=(const pipe&amp;) = delete;
pipe&amp; operator=(pipe&amp;&amp;) = delete;
pipe* operator&amp;() = delete;
bool write(const T&amp; ref) noexcept;
reservation&lt;memory_scope_work_item&gt; reserve(uint num_packets) noexcept;
reservation&lt;memory_scope_work_group&gt; work_group_reserve(
uint num_packets) noexcept;
reservation&lt;memory_scope_sub_group&gt; sub_group_reserve(
uint num_packets) noexcept;
uint num_packets() const noexcept;
uint max_packets() const noexcept;
};
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="pipe-class-methods">3.12.4. pipe class methods</h4>
<div class="sect4">
<h5 id="piperead">pipe::read</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool read(T&amp; ref) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Read packet from pipe into <code>ref</code>.</p>
</div>
<div class="paragraph">
<p>Returns <code>true</code> if read is successful and <code>false</code> if the pipe is empty.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipewrite">pipe::write</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool write(const T&amp; ref) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Write packet specified by <code>ref</code> to pipe.
Returns <code>true</code> if write is successful and <code>false</code> if the pipe is full.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipereserve">pipe::reserve</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>reservation reserve(uint num_packets) const noexcept;
reservation reserve(uint num_packets) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reserve <code>num_packets</code> entries for reading/writing from/to pipe.
Returns a valid reservation if the reservation is successful.</p>
</div>
<div class="paragraph">
<p>The reserved pipe entries are referred to by indices that go from <code>0 &#8230;&#8203; num_packets - 1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipework_group_reserve">pipe::work_group_reserve</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>reservation work_group_reserve(uint num_packets) const noexcept;
reservation work_group_reserve(uint num_packets) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reserve <code>num_packets</code> entries for reading/writing from/to pipe.
Returns a valid reservation if the reservation is successful.</p>
</div>
<div class="paragraph">
<p>The reserved pipe entries are referred to by indices that go from <code>0 &#8230;&#8203; num_packets - 1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipesub_group_reserve">pipe::sub_group_reserve</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>reservation sub_group_reserve(uint num_packets) const noexcept;
reservation sub_group_reserve(uint num_packets) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Reserve <code>num_packets</code> entries for reading/writing from/to pipe.
Returns a valid reservation if the reservation is successful.</p>
</div>
<div class="paragraph">
<p>The reserved pipe entries are referred to by indices that go from <code>0 &#8230;&#8203; num_packets - 1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipenum_packets">pipe::num_packets</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>uint num_packets() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the current number of packets that have been written to the pipe, but have not yet been read from the pipe.
The number of available entries in a pipe is a dynamic value.
The value returned should be considered immediately stale.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipemax_packets">pipe::max_packets</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>uint max_packets() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the maximum number of packets specified when pipe was created.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipereservationread">pipe::reservation::read</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool pipe::reservation::read(uint index, T&amp; ref) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Read packet from the reserved area of the pipe referred to by <code>index</code> into <code>ref</code>.</p>
</div>
<div class="paragraph">
<p>The reserved pipe entries are referred to by indices that go from <code>0 &#8230;&#8203; num_packets - 1</code>.</p>
</div>
<div class="paragraph">
<p>Returns <code>true</code> if read is successful and <code>false</code> otherwise.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipereservationwrite">pipe::reservation::write</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool pipe::reservation::write(uint index, const T&amp; ref) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Write packet specified by <code>ref</code> to the reserved area of the pipe referred to by <code>index</code>.</p>
</div>
<div class="paragraph">
<p>The reserved pipe entries are referred to by indices that go from <code>0 &#8230;&#8203; num_packets - 1</code>.</p>
</div>
<div class="paragraph">
<p>Returns <code>true</code> if write is successful and <code>false</code> otherwise.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipereservationcommit">pipe::reservation::commit</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void pipe::reservation::commit() const noexcept;
void pipe::reservation::commit() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Indicates that all reads/writes to <code>num_packets</code> associated with reservation are completed.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipereservationis_valid">pipe::reservation::is_valid</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool pipe::reservation::is_valid();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if reservation is a valid reservation and <code>false</code> otherwise.</p>
</div>
</div>
<div class="sect4">
<h5 id="pipereservationoperator-bool">pipe::reservation::operator bool</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>explicit pipe::reservation::operator bool() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>true</code> if reservation is a valid reservation and <code>false</code> otherwise.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="pipe_storage-class">3.12.5. pipe_storage class</h4>
<div class="paragraph">
<p>The lifetime of <code>pipe_storage</code> objects is the same as a program where they were declared.
The variables of such type are not shared across devices.</p>
</div>
<div class="paragraph">
<p><code>N</code> in the <code>pipe_storage</code> template class specifies the maximum number of packets which can be held by an object.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T, size_t N&gt;
struct pipe_storage: marker_type
{
pipe_storage();
pipe_storage(const pipe_storage&amp;) = default;
pipe_storage(pipe_storage&amp;&amp;) = default;
pipe_storage&amp; operator=(const pipe_storage&amp;) = delete;
pipe_storage&amp; operator=(pipe_storage&amp;&amp;) = delete;
pipe_storage* operator&amp;() = delete;
template&lt;pipe_access Access = pipe_access::read&gt;
pipe&lt;T, Access&gt; get() const noexcept
};
template&lt;pipe_access Access = pipe_access::read, class T, size_t N&gt;
pipe&lt;T, Access&gt; make_pipe(const pipe_storage&lt;T, N&gt;&amp; ps);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="pipe_storage-class-methods-and-make_pipe-function">3.12.6. pipe_storage class methods and make_pipe function</h4>
<div class="sect4">
<h5 id="pipe_storageget">pipe_storage::get</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;pipe_access Access = pipe_access::read&gt;
pipe&lt;T, Access&gt; get() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs a read only or write only pipe from <code>pipe_storage</code> object.
One kernel can have only one pipe accessor associated with one <code>pipe_storage</code> object.</p>
</div>
</div>
<div class="sect4">
<h5 id="make_pipe">make_pipe</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template&lt;pipe_access Access = pipe_access::read, class T, size_t N&gt;
pipe&lt;T, Access&gt; make_pipe(const pipe_storage&lt;T, N&gt;&amp; ps);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructs a read only or write only pipe from <code>pipe_storage</code> object.
One kernel can have only one pipe accessor associated with one <code>pipe_storage</code> object.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="operations-ordering-using-reservations">3.12.7. Operations ordering using reservations</h4>
<div class="paragraph">
<p>The <code>reservation::read</code> and <code>reservation::write</code> pipe functions can be used to read from or write to a packet index.
These functions can be used to read from or write to a packet index one or multiple times.
If a packet index that is reserved for writing is not written to using the <code>reservation::write</code> method, the contents of that packet in the pipe are undefined.
<code>reservation::commit</code> remove the entries reserved for reading from the pipe.
<code>reservation::commit</code> ensures that the entries reserved for writing are all added in-order as one contiguous set of packets to the pipe.</p>
</div>
<div class="paragraph">
<p>There can only be <code>CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS</code> (refer to <em>Table 4.3</em>) reservations active (i.e. reservations that have been reserved but not committed) per work-item or work-group for a pipe in a kernel executing on a device.</p>
</div>
<div class="paragraph">
<p>Work-item based reservations made by a work-item are ordered in the pipe as they are ordered in the program.
Reservations made by different work-items that belong to the same work-group can be ordered using the work-group barrier function.
The order of work-item based reservations that belong to different work-groups is implementation defined.</p>
</div>
<div class="paragraph">
<p>Work-group based reservations made by a work-group are ordered in the pipe as they are ordered in the program.
The order of work-group based reservations by different work-groups is implementation defined.</p>
</div>
</div>
<div class="sect3">
<h4 id="requirements">3.12.8. Requirements</h4>
<div class="sect4">
<h5 id="data">Data</h5>
<div class="paragraph">
<p>Template parameter <code>T</code> in <code>pipe</code> and <code>pipe_storage</code> class template denotes the data type stored in pipe.
The type <code>T</code> must be a POD type i.e. satisfy <code>is_pod&lt;T&gt;::value == true</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="work-group-operations">Work-group operations</h5>
<div class="paragraph">
<p>All work-group specific functions must be encountered by all work items in a work-group executing the kernel with the same argument values, otherwise the behavior is undefined.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub-group-operations">Sub-group operations</h5>
<div class="paragraph">
<p>All sub-group specific functions must be encountered by all work items in a sub-group executing the kernel with the same argument values, otherwise the behavior is undefined.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="restrictions-5">3.12.9. Restrictions</h4>
<div class="sect4">
<h5 id="pipe">pipe</h5>
<div class="ulist">
<ul>
<li>
<p>The <code>pipe</code> type cannot be used with variables declared inside a class or union field, a pointer type, an array, global variables declared at program scope or the return type of a function.</p>
</li>
<li>
<p>A kernel cannot read from and write to the same pipe object.</p>
</li>
<li>
<p>The <code>pipe</code> type cannot be used with the <code>global</code>, <code>local</code>, <code>priv</code> and <code>constant</code> address space storage classes (see the <a href="#explicit-address-space-storage-classes"><em>Explicit address space storage classes</em></a> section).</p>
</li>
<li>
<p>The value returned by applying the <code>sizeof</code> operator to the <code>pipe</code> type is implementation-defined.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="reservation">reservation</h5>
<div class="ulist">
<ul>
<li>
<p>The <code>reservation</code> type cannot be used with variables declared inside a class or union field, a pointer type, an array, global variables declared at program scope or the return type of a function.</p>
</li>
<li>
<p>The <code>reservation</code> type cannot be used with the <code>global</code>, <code>local</code>, <code>priv</code> and <code>constant</code> address space storage classes (see the <a href="#explicit-address-space-storage-classes"><em>Explicit address space storage classes</em></a> section).</p>
</li>
<li>
<p>The value returned by applying the <code>sizeof</code> operator to the <code>reservation</code> type is implementation-defined.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following behavior is undefined:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A kernel calls <code>reservation::read</code> or <code>reservation::write</code> with a valid reservation but with an index that is not a value from <code>0 &#8230;&#8203; num_packets - 1</code> specified to the corresponding call to <code>pipe::reserve</code>, <code>pipe::work_group_reserve</code> or <code>pipe::sub_group_reserve</code>.</p>
</li>
<li>
<p>A kernel calls <code>reservation::read</code> or <code>reservation::write</code> with a reservation that has already been committed (i.e. a <code>reservation::commit</code> with this reservation has already been called).</p>
</li>
<li>
<p>The contents of the reserved data packets in the pipe are undefined if the kernel does not call <code>reservation::write</code> for all entries that were reserved by the corresponding call to <code>pipe::reserve</code>, <code>pipe::work_group_reserve</code> or <code>pipe::sub_group_reserve</code>.</p>
</li>
<li>
<p>Calls to <code>reservation::read</code> and <code>reservation::commit</code> or <code>reservation::write</code> and <code>reservation::commit</code> for a given reservation must be called by the same kernel that made the reservation using <code>pipe::reserve</code>, <code>pipe::work_group_reserve</code> or <code>pipe::sub_group_reserve</code>. The reservation cannot be passed to another kernel including child kernels.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="pipe_storage">pipe_storage</h5>
<div class="ulist">
<ul>
<li>
<p>Variables of type <code>pipe_storage</code> can only be declared at program scope or with the static specifier.</p>
</li>
<li>
<p>The <code>pipe_storage</code> type cannot be used as a class or union field, a pointer type, an array or the return type of a function.</p>
</li>
<li>
<p>The <code>pipe_storage</code> type cannot be used with the <code>global</code>, <code>local</code>, <code>priv</code> and <code>constant</code> address space storage classes (see the <a href="#explicit-address-space-storage-classes"><em>Explicit address space storage classes</em></a> section).</p>
</li>
<li>
<p>The value returned by applying the <code>sizeof</code> operator to the <code>pipe_storage</code> type is implementation-defined.</p>
</li>
<li>
<p>Variables of type <code>pipe</code> created from <code>pipe_storage</code> can only be declared inside a kernel function at kernel scope.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following behavior is undefined:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A kernel cannot contain more than one <code>pipe</code> accessor made from one <code>pipe_storage</code> object. Otherwise behavior is undefined.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect3">
<h4 id="examples-6">3.12.10. Examples</h4>
<div class="sect4">
<h5 id="example-1-6">Example 1</h5>
<div class="paragraph">
<p>Example of reading from a pipe object.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_pipe&gt;
using namespace cl;
kernel void reader(pipe&lt;int&gt; p) {
int val;
if(p.read(val)) {
//...
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2-4">Example 2</h5>
<div class="paragraph">
<p>Example of writing to a pipe object.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_pipe&gt;
using namespace cl;
kernel void writer(pipe&lt;int, pipe_access::write&gt; p) {
//...
int val;
if(p.write(val)) {
//...
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-3-3">Example 3</h5>
<div class="paragraph">
<p>Example of reading from a pipe object using reservations.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_pipe&gt;
using namespace cl;
kernel void reader(pipe&lt;int, pipe_access::read&gt; p) {
int val;
auto rid = p.reserve(1);
if(rid.read(0, val)) {
//...
}
rid.commit();
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-4-2">Example 4</h5>
<div class="paragraph">
<p>Example of using a pipe_storage object and how to create the pipe objects/accessors from it.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_pipe&gt;
cl::pipe_storage &lt;int, 100&gt; myProgramPipe0;
kernel void producer() {
cl::pipe&lt;int, cl::pipe_access::write&gt; p =
myProgramPipe0.get&lt;cl::pipe_access::write&gt;();
//...
p.write(...);
}
kernel void consumer() {
cl::pipe&lt;int, cl::pipe_access::read&gt; p =
myProgramPipe0.get&lt;cl::pipe_access::read&gt;();
if(p.read(...)) {
//...
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-5-2">Example 5</h5>
<div class="paragraph">
<p>Example of using more than one pipe_storage object.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_pipe&gt;
using namespace cl;
pipe_storage&lt;int2, 20&gt; myProgramPipe2;
pipe_storage&lt;float, 40&gt; myProgramPipe3;
kernel void input() {
auto p = make_pipe&lt;pipe_access::write&gt;(myProgramPipe2);
//...
p.write(...);
}
kernel void processor() {
auto p_in = make_pipe&lt;pipe_access::read&gt;(myProgramPipe2);
auto p_out = make_pipe&lt;pipe_access::write&gt;(myProgramPipe3);
...
if(p_in.read(...)) {
//...
}
p_out.write(...);
}
kernel void output() {
auto p = make_pipe&lt;pipe_access::read&gt;(myProgramPipe3);
if(p.read(...)) {
//...
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="device-enqueue-library">3.13. Device Enqueue Library</h3>
<div class="paragraph">
<p>OpenCL C++ device enqueue functionality allows a kernel to enqueue the same device, without host interaction.
A kernel may enqueue code represented by lambda syntax, and control execution order with event dependencies including user events and markers.
<code>device_queue</code> follows all the rules for marker types as specified in the <a href="#marker-types"><em>Marker Types</em></a> section.</p>
</div>
<div class="sect3">
<h4 id="queue-host-type">3.13.1. Queue Host Type</h4>
<div class="paragraph">
<p>The below table describes the OpenCL queue data type and the corresponding data type available to the application:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 17. Host queue type</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Type in OpenCL C++</strong></th>
<th class="tableblock halign-left valign-top"><strong>API type for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl::device_queue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cl_queue</code></p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="header-opencl_device_queue-synopsis">3.13.2. Header &lt;opencl_device_queue&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class enqueue_status;
enum class enqueue_policy;
enum class event_status;
enum class event_profiling_info;
struct event
{
event();
event(const event&amp;) = default;
event(event&amp;) = default;
event&amp; operator=(const event&amp;) = default;
event&amp; operator=(event&amp;&amp;) = default;
bool is_valid() const noexcept;
void retain() noexcept;
void release() noexcept;
explicit operator bool() const noexcept;
void set_status(event_status status) noexcept;
void profiling_info(event_profiling_info name,
global_ptr&lt;long&gt; value) noexcept;
};
event make_user_event();
struct ndrange
{
explicit ndrange(size_t global_work_size) noexcept;
ndrange(size_t global_work_size,
size_t local_work_size) noexcept;
ndrange(size_t global_work_offset,
size_t global_work_size,
size_t local_work_size) noexcept;
template &lt;size_t N&gt;
ndrange(const size_t (&amp;global_work_size)[N]) noexcept;
template &lt;size_t N&gt;
ndrange(const size_t (&amp;global_work_size)[N],
const size_t (&amp;local_work_size)[N]) noexcept;
template &lt;size_t N&gt;
ndrange(const size_t (&amp;global_work_offset)[N],
const size_t (&amp;global_work_size)[N],
const size_t (&amp;local_work_size)[N]) noexcept;
};
struct device_queue: marker_type
{
device_queue() noexcept = delete;
device_queue(const device_queue&amp;) = default;
device_queue(device_queue&amp;&amp;) = default;
device_queue&amp; operator=(const device_queue&amp;) = delete;
device_queue&amp; operator=(device_queue&amp;&amp;) = delete;
device_queue* operator&amp;() = delete;
template &lt;class Fun, class... Args&gt;
enqueue_status enqueue_kernel(enqueue_policy flag,
const ndrange &amp;ndrange,
Fun fun,
Args... args) noexcept;
template &lt;class Fun, class... Args&gt;
enqueue_status enqueue_kernel(enqueue_policy flag,
uint num_events_in_wait_list,
const event *event_wait_list,
event *event_ret,
const ndrange &amp;ndrange,
Fun fun,
Args... args) noexcept;
enqueue_status enqueue_marker(uint num_events_in_wait_list,
const event *event_wait_list,
event *event_ret) noexcept;
};
device_queue get_default_device_queue();
template &lt;class Fun, class... Args&gt;
uint get_kernel_work_group_size(Fun fun, Args... args);
template &lt;class Fun, class... Args&gt;
uint get_kernel_preferred_work_group_size_multiple(Fun fun,
Args... args);
template &lt;class Fun, class... Args&gt;
uint get_kernel_sub_group_count_for_ndrange(const ndrange &amp;ndrange,
Fun fun,
Args... args);
template &lt;class Fun, class... Args&gt;
uint get_kernel_max_sub_group_size_for_ndrange(const ndrange &amp;ndrange,
Fun fun,
Args... args);
template &lt;class Fun, class... Args&gt;
uint get_kernel_local_size_for_sub_group_count(uint num_sub_groups,
Fun fun,
Args... args);
template &lt;class Fun, class... Args&gt;
uint get_kernel_max_num_sub_groups(Fun fun, Args... args);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="device_queue-class-methods">3.13.3. device_queue class methods</h4>
<div class="paragraph">
<p><code>device_queue</code> object represents work queue of the device.
Device queue meets all requirements of the marker types as in the <a href="#marker-types"><em>Marker Types</em></a> section.</p>
</div>
<div class="sect4">
<h5 id="enqueue_kernel">device_queue::enqueue_kernel</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
enqueue_status enqueue_kernel(enqueue_policy policy,
const ndrange &amp;ndrange,
Fun fun,
Args... args) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This method allows to enqueue functor or lambda <code>fun</code> on the device with specified <code>policy</code> over the specified <code>ndrange</code>.</p>
</div>
<div class="paragraph">
<p><code>args</code> are the arguments that will be passed to <code>fun</code> when kernel will be enqueued with the exception for <code>local_ptr</code> parameters.
For local pointers user must supply the size of local memory that will be allocated using <code>local_ptr&lt;T&gt;::size_type\{num elements}</code>.
Please see examples how to use <code>enqueue_kernel</code> are in the <a href="#examples-7"><em>Examples</em></a> section.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
enqueue_status enqueue_kernel(enqueue_policy policy,
uint num_events_in_wait_list,
const event *event_wait_list,
event *event_ret,
const ndrange &amp;ndrange,
Fun fun,
Args... args) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This method enqueues functor or lambda <code>fun</code> in the same way as the overload above with the exception for the passed event list.
If an event is returned, <code>enqueue_kernel</code> performs an implicit retain on the returned event.</p>
</div>
</div>
<div class="sect4">
<h5 id="enqueue_marker">device_queue::enqueue_marker</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>enqueue_status enqueue_marker(uint num_events_in_wait_list,
const event *event_wait_list,
event *event_ret) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This method enqueues a marker to device queue.
The marker command waits for a list of events specified by <code>event_wait_list</code> to complete before the marker completes.
<code>event_ret</code> must not be <code>nullptr</code> as otherwise this is a no-op.</p>
</div>
<div class="paragraph">
<p>If an event is returned, <code>enqueue_marker</code> performs an implicit retain on the returned event.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="event-class-methods">3.13.4. event class methods</h4>
<div class="sect4">
<h5 id="is_valid">event::is_valid</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool is_valid() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>true</code> if event object is a valid event.
Otherwise returns <code>false</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="operator-bool">event::operator bool</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>explicit operator bool() const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>true</code> if event object is a valid event.
Otherwise returns <code>false</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="retain">event::retain</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void retain() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Increments the event reference count.
Event must be an event returned by <code>enqueue_kernel</code> or <code>enqueue_marker</code> or a user event.</p>
</div>
</div>
<div class="sect4">
<h5 id="release">event::release</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void release() noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Decrements the event reference count.
The event object is deleted once the event reference count is zero, the specific command identified by this event has completed (or terminated) and there are no commands in any device command queue that require a wait for this event to complete.
Event must be an event returned by <code>enqueue_kernel</code>, <code>enqueue_marker</code> or a user event.</p>
</div>
</div>
<div class="sect4">
<h5 id="set_status">event::set_status</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void set_status(event_status status) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Sets the execution status of a user event.
Event must be a user event.
<code>status</code> can be either <code>event_status::complete</code> or <code>event_status::error</code> value indicating an error.</p>
</div>
</div>
<div class="sect4">
<h5 id="profiling_info">event::profiling_info</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void profiling_info(event_profiling_info name,
global_ptr&lt;long&gt; value) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Captures the profiling information for functions that are enqueued as commands.
The specific function being referred to is: <code>enqueue_kernel</code>.
These enqueued commands are identified by unique event objects.
The profiling information will be available in <code>value</code> once the command identified by event has completed.
Event must be an event returned by <code>enqueue_kernel</code>.</p>
</div>
<div class="paragraph">
<p><code>name</code> identifies which profiling information is to be queried and can be:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>event_profiling_info::exec_time</code></p>
<div class="paragraph">
<p><code>value</code> is a pointer to two 64-bit values.</p>
</div>
<div class="paragraph">
<p>The first 64-bit value describes the elapsed time <code>CL_PROFILING_COMMAND_END - CL_PROFILING_COMMAND_START</code> for the command identified by event in nanoseconds.</p>
</div>
<div class="paragraph">
<p>The second 64-bit value describes the elapsed time <code>CL_PROFILING_COMMAND_COMPLETE - CL_PROFILING_COMMAND_START</code> for the command identified by event in nanoseconds.</p>
</div>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<code>profiling_info</code> when called multiple times for the same event is undefined.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect3">
<h4 id="other-operations">3.13.5. Other operations</h4>
<div class="sect4">
<h5 id="get_default_device_queue">get_default_device_queue</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>device_queue get_default_device_queue();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the default device queue.
If a default device queue has not been created, <code>device_queue::is_valid()</code> will return <code>false</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="make_user_event">make_user_event</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>event make_user_event();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Creates a user event.
Returns the user event.
The execution status of the user event created is set to <code>event_status::submitted</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_kernel_work_group_size">get_kernel_work_group_size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
uint get_kernel_work_group_size(Fun fun, Args... args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>This provides a mechanism to query the maximum work-group size that can be used to execute a functor on the current device.</p>
</div>
<div class="paragraph">
<p><code>fun</code> specifies the functor representing the kernel code that would be enqueued.</p>
</div>
<div class="paragraph">
<p><code>args</code> are the arguments that will be passed to <code>fun</code> when kernel will be enqueued with the exception for <code>local_ptr</code> parameters.
For local pointers user must supply the size of local memory that will be allocated.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_kernel_preferred_work_group_size_multiple">get_kernel_preferred_work_group_size_multiple</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
uint get_kernel_preferred_work_group_size_multiple(Fun fun,
Args... args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the preferred multiple of work-group size for launch.
This is a performance hint.
Specifying a work-group size that is not a multiple of the value returned by this query as the value of the local work size argument to enqueue will not fail to enqueue the functor for execution unless the work-group size specified is larger than the device maximum.</p>
</div>
<div class="paragraph">
<p><code>fun</code> specifies the functor representing the kernel code that would be enqueued.</p>
</div>
<div class="paragraph">
<p><code>args</code> are the arguments that will be passed to <code>fun</code> when kernel will be enqueued with the exception for <code>local_ptr</code> parameters.
For local pointers user must supply the size of local memory that will be allocated.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_kernel_sub_group_count_for_ndrange">get_kernel_sub_group_count_for_ndrange</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
uint get_kernel_sub_group_count_for_ndrange(const ndrange &amp;ndrange,
Fun fun,
Args... args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of sub-groups in each work-group of the dispatch (except for the last in cases where the global size does not divide cleanly into work-groups) given the combination of the passed ndrange and functor.</p>
</div>
<div class="paragraph">
<p><code>fun</code> specifies the functor representing the kernel code that would be enqueued.</p>
</div>
<div class="paragraph">
<p><code>args</code> are the arguments that will be passed to <code>fun</code> when kernel will be enqueued with the exception for <code>local_ptr</code> parameters.
For local pointers user must supply the size of local memory that will be allocated.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_kernel_max_sub_group_size_for_ndrange">get_kernel_max_sub_group_size_for_ndrange</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
uint get_kernel_max_sub_group_size_for_ndrange(const ndrange &amp;ndrange,
Fun fun,
Args... args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the maximum sub-group size for a functor.</p>
</div>
<div class="paragraph">
<p><code>fun</code> specifies the functor representing the kernel code that would be enqueued.</p>
</div>
<div class="paragraph">
<p><code>args</code> are the arguments that will be passed to <code>fun</code> when kernel will be enqueued with the exception for <code>local_ptr</code> parameters.
For local pointers user must supply the size of local memory that will be allocated.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_kernel_local_size_for_sub_group_count">get_kernel_local_size_for_sub_group_count</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
uint get_kernel_local_size_for_sub_group_count(uint num_sub_groups,
Fun fun,
Args... args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a valid local size that would produce the requested number of sub-groups such that each sub-group is complete with no partial sub-groups.</p>
</div>
<div class="paragraph">
<p><code>fun</code> specifies the functor representing the kernel code that would be enqueued.</p>
</div>
<div class="paragraph">
<p><code>args</code> are the arguments that will be passed to <code>fun</code> when kernel will be enqueued with the exception for <code>local_ptr</code> parameters.
For local pointers user must supply the size of local memory that will be allocated.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_kernel_max_num_sub_groups">get_kernel_max_num_sub_groups</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class Fun, class... Args&gt;
uint get_kernel_max_num_sub_groups(Fun fun, Args... args);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Provides a mechanism to query the maximum number of sub-groups that can be used to execute the passed functor on the current device.</p>
</div>
<div class="paragraph">
<p><code>fun</code> specifies the functor representing the kernel code that would be enqueued.</p>
</div>
<div class="paragraph">
<p><code>args</code> are the arguments that will be passed to <code>fun</code> when kernel will be enqueued with the exception for <code>local_ptr</code> parameters.
For local pointers user must supply the size of local memory that will be allocated.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ndrange">3.13.6. ndrange</h4>
<div class="paragraph">
<p><code>ndrange</code> type is used to represent the size of the enqueued workload.
The dimension of the workload ranges from 1 to 3.
User can specify global work size, local work size and global work offset.
Unspecified parameters are defaulted to 0.</p>
</div>
</div>
<div class="sect3">
<h4 id="enqueue-policy">3.13.7. Enqueue policy</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>enum class enqueue_policy
{
no_wait,
wait_kernel,
wait_work_group
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>Enqueue policy enumerable is used to specify launch policy of enqueued kernel.
It is defined as follows:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 18. Enqueue policy</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Policy</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>no_wait</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Indicates that the enqueued kernels do not need to wait for the parent kernel to finish execution before they begin execution.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>wait_kernel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Indicates that all work-items of the parent kernel must finish executing and all immediate <a id="ftnref14"></a> <a href="#ftn14">[14]</a> side effects committed before the enqueued child kernel may begin execution.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>wait_work_group</code> <a id="ftnref15"></a> <a href="#ftn15">[15]</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Indicates that the enqueued kernels wait only for the work-group that enqueued the kernels to finish before they begin execution.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="enqueue-status">3.13.8. Enqueue status</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>enum class enqueue_status
{
success,
failure,
invalid_queue,
invalid_ndrange,
invalid_event_wait_list,
queue_full,
invalid_arg_size,
event_allocation_failure,
out_of_resources
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>enqueue_kernel</code> and <code>enqueue_marker</code> methods return <code>enqueue_status::success</code> if the command is enqueued successfully and return <code>enqueue_status::failure</code> otherwise.
If the <em>-g</em> compile option is specified in compiler options passed to <code>clBuildProgram</code>, the other errors may be returned instead of <code>enqueue_status::failure</code> to indicate why <code>enqueue_kernel</code> or <code>enqueue_marker</code> failed.
Enqueue status is defined as follows:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 19. Enqueue status</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Status</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>success</code></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>failure</code></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>invalid_queue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>queue</em> is not a valid device queue.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>invalid_ndrange</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>ndrange</code> is not a valid ND-range descriptor or if the program was compiled with <em>-cl-uniform-work-group-size</em> and the local work size is specified in <code>ndrange</code> but the global work size specified in <code>ndrange</code> is not a multiple of the local work size.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>invalid_event_wait_list</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>event_wait_list</code> is <code>nullptr</code> and <code>num_events_in_wait_list</code> &gt; 0, or if <code>event_wait_list</code> is not <code>nullptr</code> and <code>num_events_in_wait_list</code> is 0, or if <code>event</code> objects in <code>event_wait_list</code> are not valid events.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>queue_full</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <em>queue</em> is full.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>invalid_arg_size</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If size of local memory arguments is 0.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>event_allocation_failure</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>event_ret</code> is not <code>nullptr</code> and an event could not be allocated.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>out_of_resources</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If there is a failure to queue the kernel in <em>queue</em> because of insufficient resources needed to execute the kernel.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="event-status">3.13.9. Event status</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>enum class event_status
{
submitted,
complete,
error,
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>Event status enumerable is used to set a user event status.
It is defined as follows:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 20. Event status</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Status</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>submitted</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Initial status of a user event</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>complete</code></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>error</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Status indicating an error</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="determining-when-a-parent-kernel-has-finished-execution">3.13.10. Determining when a parent kernel has finished execution</h4>
<div class="paragraph">
<p>A parent kernel&#8217;s execution status is considered to be complete when it and all its child kernels have finished execution.
The execution status of a parent kernel will be <code>event_status::complete</code> if this kernel and all its child kernels finish execution successfully.
The execution status of the kernel will be <code>event_status::error</code> if it or any of its child kernels encounter an error, or are abnormally terminated.</p>
</div>
<div class="paragraph">
<p>For example, assume that the host enqueues a kernel <code>k</code> for execution on a device.
Kernel <code>k</code> when executing on the device enqueues kernels <code>A</code> and <code>B</code> to a device queue(s).
The <code>enqueue_kernel</code> call to enqueue kernel <code>B</code> specifies the event associated with kernel <code>A</code> in the <code>event_wait_list</code> argument i.e. wait for kernel <code>A</code> to finish execution before kernel <code>B</code> can begin execution.
Let&#8217;s assume kernel <code>A</code> enqueues kernels <code>X</code>, <code>Y</code> and <code>Z</code>.
Kernel <code>A</code> is considered to have finished execution i.e. its execution status is <code>event_status::complete</code> only after <code>A</code> and the kernels <code>A</code> enqueued (and any kernels these enqueued kernels enqueue and so on) have finished execution.</p>
</div>
</div>
<div class="sect3">
<h4 id="event-profiling-info">3.13.11. Event profiling info</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>enum class event_profiling_info
{
exec_time,
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>Event profiling info enumerable is used to determine the outcome of <code>event::profiling_info</code> function.
It is defined as follows:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 21. Event profiling info</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Status</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>exec_time</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Identifies profiling information to be queried.
If specified, the two 64-bit values are returned
</p><p class="tableblock"> The first 64-bit value describes the elapsed time: <code>CL_PROFILING_COMMAND_END - CL_PROFILING_COMMAND_START</code> for the command identified by event in nanoseconds.
</p><p class="tableblock"> The second 64-bit value describes the elapsed time <code>CL_PROFILING_COMMAND_COMPLETE - CL_PROFILING_COMMAND_START</code> for the command identified by event in nanoseconds.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="requirements-1">3.13.12. Requirements</h4>
<div class="paragraph">
<p>Functor and lambda objects passed to <code>enqueue_kernel</code> method of device queue has to follow specific restrictions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>It has to be trivially copyable.</p>
</li>
<li>
<p>It has to be trivially copy constructible.</p>
</li>
<li>
<p>It has to be trivially destructible.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Code enqueuing function objects that do not meet this criteria is ill-formed.</p>
</div>
<div class="sect4">
<h5 id="pointers-references-and-marker-types">Pointers, references and marker types</h5>
<div class="paragraph">
<p>Functors that are enqueued cannot have any reference and pointer fields, nor can have fields of marker types.
If object containing such fields is enqueued the behavior is undefined.</p>
</div>
<div class="paragraph">
<p>The same restrictions apply to <em>capture-list</em> variables in lambda.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This requirements are caused by the fact that kernel may be enqueued after parent kernel terminated all pointers and references will be invalidated by then.
</td>
</tr>
</table>
</div>
</div>
<div class="sect4">
<h5 id="events">Events</h5>
<div class="paragraph">
<p>Events can be used to identify commands enqueued to a command-queue from the host.
These events created by the OpenCL runtime can only be used on the host i.e. as events passed in <code>event_wait_list</code> argument to various <code>clEnqueue</code>* APIs or runtime APIs that take events as arguments such as <code>clRetainEvent</code>, <code>clReleaseEvent</code>, <code>clGetEventProfilingInfo</code>.</p>
</div>
<div class="paragraph">
<p>Similarly, events can be used to identify commands enqueued to a device queue (from a kernel).
These event objects cannot be passed to the host or used by OpenCL runtime APIs such as the <code>clEnqueue</code>* APIs or runtime APIs that take event arguments.</p>
</div>
<div class="paragraph">
<p><code>clRetainEvent</code> and <code>clReleaseEvent</code> will return <code>CL_INVALID_OPERATION</code> if event specified is an event that refers to any kernel enqueued to a device queue using <code>enqueue_kernel</code> or <code>enqueue_marker</code> or is a user event created by <code>make_user_event</code>.</p>
</div>
<div class="paragraph">
<p>Similarly, <code>clSetUserEventStatus</code> can only be used to set the execution status of events created using <code>clCreateUserEvent</code>.
User events created on the device can be set using <code>event::set_status</code> method.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="restrictions-6">3.13.13. Restrictions</h4>
<div class="ulist">
<ul>
<li>
<p>The <code>device_queue</code> type cannot be used with variables declared inside a class or union field, a pointer type, an array, global variables declared at program scope or the return type of a function.</p>
</li>
<li>
<p>The <code>event</code> type cannot be used with variables declared inside a class or union field, global variables declared at program scope or the return type of a function.</p>
</li>
<li>
<p>The <code>event</code> and <code>device_queue</code> type cannot be used with the <code>global</code>, <code>local</code>, <code>priv</code> and <code>constant</code> address space storage classes (see the <a href="#explicit-address-space-storage-classes"><em>Explicit address space storage classes</em></a> section).</p>
</li>
<li>
<p>The values returned by applying the <code>sizeof</code> operator to the <code>device_queue</code> and <code>event</code> types is implementation-defined.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="examples-7">3.13.14. Examples</h4>
<div class="sect4">
<h5 id="example-1-7">Example 1</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_device_queue&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo() {
auto q = get_default_device_queue();
q.enqueue_kernel(enqueue_policy::no_wait,
ndrange( 1 ),
[](){ uint tid = get_global_id(0); } );
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-2-5">Example 2</h5>
<div class="paragraph">
<p>Example of using the explicit local pointer class with <code>enqueue_kernel</code> method.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_device_queue&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
kernel void foo(device_queue q) {
auto lambda = [](local_ptr&lt;ushort16&gt; p) { uint tid = get_global_id(0); };
q.enqueue_kernel(enqueue_policy::no_wait,
ndrange{1},
lambda,
local_ptr&lt;ushort16&gt;::size_type{1});
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="example-3-4">Example 3</h5>
<div class="paragraph">
<p>Example of enqueuing a functor to a <code>device_queue</code> object.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_device_queue&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
struct Lambda {
template &lt;typename T&gt;
void operator ()(T t) const { uint tid = get_global_id(0); }
};
kernel void foo(device_queue q) {
auto lambda = Lambda{};
q.enqueue_kernel(enqueue_policy::no_wait,
ndrange{1},
lambda,
local_ptr&lt;ushort16&gt;::size_type{1});
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="work-item-functions">3.14. Work-Item Functions</h3>
<div class="paragraph">
<p>This section describes the library of work-item functions that can be used to query the number of dimensions, the global and local work size specified to <code>clEnqueueNDRangeKernel</code>, and the global and local identifier of each work-item when this kernel is being executed on a device.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_work_item-synopsis">3.14.1. Header &lt;opencl_work_item&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
uint get_work_dim();
size_t get_global_size(uint dimindx);
size_t get_global_id(uint dimindx);
size_t get_local_size(uint dimindx);
size_t get_enqueued_local_size(uint dimindx);
size_t get_local_id(uint dimindx);
size_t get_num_groups(uint dimindx);
size_t get_group_id(uint dimindx);
size_t get_global_offset(uint dimindx);
size_t get_global_linear_id();
size_t get_local_linear_id();
size_t get_sub_group_size();
size_t get_max_sub_group_size();
size_t get_num_sub_groups();
size_t get_enqueued_num_sub_groups();
size_t get_sub_group_id();
size_t get_sub_group_local_id();
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="work-item-operations">3.14.2. Work item operations</h4>
<div class="sect4">
<h5 id="get_work_dim">get_work_dim</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>uint get_work_dim()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of dimensions in use.
This is the value given to the <code>work_dim</code> argument specified in <code>clEnqueueNDRangeKernel</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_global_size">get_global_size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_global_size(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of global work-items specified for dimension identified by <code>dimindx</code>.
This value is given by the <code>global_work_size</code> argument to <code>clEnqueueNDRangeKernel</code>.
Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values of <code>dimindx</code>, <code>get_global_size()</code> returns <code>1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_global_id">get_global_id</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_global_id(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the unique global work-item ID value for dimension identified by <code>dimindx</code>.
The global work-item ID specifies the work-item ID based on the number of global work-items specified to execute the kernel.
Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values of <code>dimindx</code>, <code>get_global_id()</code> returns <code>0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_local_size">get_local_size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_local_size(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of local work-items specified in dimension identified by <code>dimindx</code>.
This value is at most the value given by the <code>local_work_size</code> argument to <code>clEnqueueNDRangeKernel</code> if <code>local_work_size</code> is not <code>NULL</code>; otherwise the OpenCL implementation chooses an appropriate <code>local_work_size</code> value which is returned by this function.
If the kernel is executed with a non-uniform work-group size <a id="ftnref19"></a> <a href="#ftn19">[19]</a>, calls to this built-in from some work-groups may return different values than calls to this built-in from other work-groups.</p>
</div>
<div class="paragraph">
<p>Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values of <code>dimindx</code>, <code>get_local_size()</code> returns <code>1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_enqueued_local_size">get_enqueued_local_size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_enqueued_local_size(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the same value as that returned by <code>get_local_size(dimindx)</code> if the kernel is executed with a uniform work-group size.</p>
</div>
<div class="paragraph">
<p>If the kernel is executed with a non-uniform work-group size, returns the number of local work-items in each of the work-groups that make up the uniform region of the global range in the dimension identified by <code>dimindx</code>.
If the <code>local_work_size</code> argument to <code>clEnqueueNDRangeKernel</code> is not <code>NULL</code>, this value will match the value specified in <code>local_work_size[dimindx]</code>.
If <code>local_work_size</code> is <code>NULL</code>, this value will match the local size that the implementation determined would be most efficient at implementing the uniform region of the global range.</p>
</div>
<div class="paragraph">
<p>Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values of <code>dimindx</code>, <code>get_enqueued_local_size()</code> returns <code>1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_local_id">get_local_id</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_local_id(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the unique local work-item ID i.e. a work-item within a specific work-group for dimension identified by <code>dimindx</code>.
Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values of <code>dimindx</code>, <code>get_local_id()</code> returns <code>0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_num_groups">get_num_groups</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_num_groups(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of work-groups that will execute a kernel for dimension identified by <code>dimindx</code>.
Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values of <code>dimindx</code>, <code>get_num_groups()</code> returns <code>1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_group_id">get_group_id</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_group_id(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>get_group_id</code> returns the work-group ID which is a number from <code>0 &#8230;&#8203; get_num_groups(dimindx)-1</code>.
Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values, <code>get_group_id()</code> returns <code>0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_global_offset">get_global_offset</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_global_offset(uint dimindx)</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>get_global_offset</code> returns the offset values specified in <code>global_work_offset</code> argument to <code>clEnqueueNDRangeKernel</code>.
Valid values of <code>dimindx</code> are <code>0</code> to <code>get_work_dim()-1</code>.
For other values, <code>get_global_offset()</code> returns <code>0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_global_linear_id">get_global_linear_id</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_global_linear_id()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the work-items 1-dimensional global ID.</p>
</div>
<div class="paragraph">
<p>For 1D work-groups, it is computed as:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>get_global_id(0) - get_global_offset(0)</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For 2D work-groups, it is computed as:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>( get_global_id(1) - get_global_offset(1)) * get_global_size(0) + (get_global_id(0) - get_global_offset(0) )</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For 3D work-groups, it is computed as:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>( (get_global_id(2) - get_global_offset(2) ) * get_global_size(1) * get_global_size(0)) + ( (get_global_id(1) - get_global_offset(1) ) * get_global_size (0) ) + ( get_global_id(0) - get_global_offset(0) )</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="get_local_linear_id">get_local_linear_id</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_local_linear_id()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the work-items 1-dimensional local ID.</p>
</div>
<div class="paragraph">
<p>For 1D work-groups, it is the same value as:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>get_local_id(0)</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For 2D work-groups, it is computed as:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>get_local_id(1) * get_local_size(0) + get_local_id(0)</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For 3D work-groups, it is computed as:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>(get_local_id(2) * get_local_size(1) * get_local_size(0)) + (get_local_id(1) * get_local_size(0)) + get_local_id(0)</code></p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="get_sub_group_size">get_sub_group_size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_sub_group_size()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of work-items in the sub-group.
This value is no more than the maximum sub-group size and is implementation-defined based on a combination of the compiled kernel and the dispatch dimensions.
This will be a constant value for the lifetime of the sub-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_max_sub_group_size">get_max_sub_group_size</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_max_sub_group_size()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the maximum size of a sub-group within the dispatch.
This value will be invariant for a given set of dispatch dimensions and a kernel object compiled for a given device.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_num_sub_groups">get_num_sub_groups</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_num_sub_groups()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of sub-groups that the current work-group is divided into.</p>
</div>
<div class="paragraph">
<p>This number will be constant for the duration of a work-group&#8217;s execution.
If the kernel is executed with a non-uniform work-group size <a href="#ftn17">[17]</a> values for any dimension, calls to this built-in from some work-groups may return different values than calls to this built-in from other work-groups.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_enqueued_num_sub_groups">get_enqueued_num_sub_groups</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_enqueued_num_sub_groups()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the same value as that returned by <code>get_num_sub_groups()</code> if the kernel is executed with a uniform work-group size.</p>
</div>
<div class="paragraph">
<p>If the kernel is executed with a non-uniform work-group size, returns the number of sub groups in each of the work groups that make up the uniform region of the global range.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_sub_group_id">get_sub_group_id</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_sub_group_id()</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>get_sub_group_id()</code> returns the sub-group ID which is a number from <code>0 &#8230;&#8203; get_num_sub_groups()-1</code>.</p>
</div>
<div class="paragraph">
<p>For <code>clEnqueueTask</code>, this returns <code>0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="get_sub_group_local_id">get_sub_group_local_id</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>size_t get_sub_group_local_id()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the unique work-item ID within the current sub-group.
The mapping from <code>get_local_id(dimindx)</code> to <code>get_sub_group_local_id()</code> will be invariant for the lifetime of the work-group.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="work-group-functions">3.15. Work-group Functions</h3>
<div class="paragraph">
<p>The OpenCL C++ library implements the following functions that operate on a work-group level.
These built-in functions must be encountered by all work-items in a work-group executing the kernel.</p>
</div>
<div class="paragraph">
<p>Here <code>gentype</code> matches: <code>int</code>, <code>uint</code>, <code>long</code>, <code>ulong</code>, <code>float</code>, <code>half</code> <a id="ftnref4"></a> <a href="#ftn4">[4]</a> or <code>double</code> <a id="ftnref18"></a> <a href="#ftn18">[18]</a>.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_work_group-synopsis">3.15.1. Header &lt;opencl_work_group&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum class work_group_op { add, min, max };
//logical operations
bool work_group_all(bool predicate);
bool work_group_any(bool predicate);
bool sub_group_all(bool predicate);
bool sub_group_any(bool predicate);
//broadcast functions
int work_group_broadcast(int a, size_t local_id);
uint work_group_broadcast(uint a, size_t local_id);
long work_group_broadcast(long a, size_t local_id);
ulong work_group_broadcast(ulong a, size_t local_id);
float work_group_broadcast(float a, size_t local_id);
#ifdef cl_khr_fp16
half work_group_broadcast(half a, size_t local_id);
#endif
#ifdef cl_khr_fp64
double work_group_broadcast(double a, size_t local_id);
#endif
int work_group_broadcast(int a, size_t local_id_x, size_t local_id_y);
uint work_group_broadcast(uint a, size_t local_id_x, size_t local_id_y);
long work_group_broadcast(long a, size_t local_id_x, size_t local_id_y);
ulong work_group_broadcast(ulong a, size_t local_id_x, size_t local_id_y);
float work_group_broadcast(float a, size_t local_id_x, size_t local_id_y);
#ifdef cl_khr_fp16
half work_group_broadcast(half a, size_t local_id_x, size_t local_id_y);
#endif
#ifdef cl_khr_fp64
double work_group_broadcast(double a, size_t local_id_x, size_t local_id_y);
#endif
int work_group_broadcast(int a, size_t local_id_x, size_t local_id_y,
size_t local_id_z);
uint work_group_broadcast(uint a, size_t local_id_x, size_t local_id_y,
size_t local_id_z);
long work_group_broadcast(long a, size_t local_id_x, size_t local_id_y,
size_t local_id_z);
ulong work_group_broadcast(ulong a, size_t local_id_x, size_t local_id_y,
size_t local_id_z);
float work_group_broadcast(float a, size_t local_id_x, size_t local_id_y,
size_t local_id_z);
#ifdef cl_khr_fp16
half work_group_broadcast(half a, size_t local_id_x, size_t local_id_y,
size_t local_id_z);
#endif
#ifdef cl_khr_fp64
double work_group_broadcast(double a, size_t local_id_x, size_t local_id_y,
size_t local_id_z);
#endif
int sub_group_broadcast(int a, size_t sub_group_local_id);
uint sub_group_broadcast(uint a, size_t sub_group_local_id);
long sub_group_broadcast(long a, size_t sub_group_local_id);
ulong sub_group_broadcast(ulong a, size_t sub_group_local_id);
float sub_group_broadcast(float a, size_t sub_group_local_id);
#ifdef cl_khr_fp16
half sub_group_broadcast(half a, size_t sub_group_local_id);
#endif
#ifdef cl_khr_fp64
double sub_group_broadcast(double a, size_t sub_group_local_id);
#endif
//numeric operations
template &lt;work_group_op op&gt; int work_group_reduce(int x);
template &lt;work_group_op op&gt; uint work_group_reduce(uint x);
template &lt;work_group_op op&gt; long work_group_reduce(long x);
template &lt;work_group_op op&gt; ulong work_group_reduce(ulong x);
template &lt;work_group_op op&gt; float work_group_reduce(float x);
#ifdef cl_khr_fp16
template &lt;work_group_op op&gt; half work_group_reduce(half x);
#endif
#ifdef cl_khr_fp64
template &lt;work_group_op op&gt; double work_group_reduce(double x);
#endif
template &lt;work_group_op op&gt; int work_group_scan_exclusive(int x);
template &lt;work_group_op op&gt; uint work_group_scan_exclusive(uint x);
template &lt;work_group_op op&gt; long work_group_scan_exclusive(long x);
template &lt;work_group_op op&gt; ulong work_group_scan_exclusive(ulong x);
template &lt;work_group_op op&gt; float work_group_scan_exclusive(float x);
#ifdef cl_khr_fp16
template &lt;work_group_op op&gt; half work_group_scan_exclusive(half x);
#endif
#ifdef cl_khr_fp64
template &lt;work_group_op op&gt; double work_group_scan_exclusive(double x);
#endif
template &lt;work_group_op op&gt; int work_group_scan_inclusive(int x);
template &lt;work_group_op op&gt; uint work_group_scan_inclusive(uint x);
template &lt;work_group_op op&gt; long work_group_scan_inclusive(long x);
template &lt;work_group_op op&gt; ulong work_group_scan_inclusive(ulong x);
template &lt;work_group_op op&gt; float work_group_scan_inclusive(float x);
#ifdef cl_khr_fp16
template &lt;work_group_op op&gt; half work_group_scan_inclusive(half x);
#endif
#ifdef cl_khr_fp64
template &lt;work_group_op op&gt; double work_group_scan_inclusive(double x);
#endif
template &lt;work_group_op op&gt; int sub_group_reduce(int x);
template &lt;work_group_op op&gt; uint sub_group_reduce(uint x);
template &lt;work_group_op op&gt; long sub_group_reduce(long x);
template &lt;work_group_op op&gt; ulong sub_group_reduce(ulong x);
template &lt;work_group_op op&gt; float sub_group_reduce(float x);
#ifdef cl_khr_fp16
template &lt;work_group_op op&gt; half sub_group_reduce(half x);
#endif
#ifdef cl_khr_fp64
template &lt;work_group_op op&gt; double sub_group_reduce(double x);
#endif
template &lt;work_group_op op&gt; int sub_group_scan_exclusive(int x);
template &lt;work_group_op op&gt; uint sub_group_scan_exclusive(uint x);
template &lt;work_group_op op&gt; long sub_group_scan_exclusive(long x);
template &lt;work_group_op op&gt; ulong sub_group_scan_exclusive(ulong x);
template &lt;work_group_op op&gt; float sub_group_scan_exclusive(float x);
#ifdef cl_khr_fp16
template &lt;work_group_op op&gt; half sub_group_scan_exclusive(half x);
#endif
#ifdef cl_khr_fp64
template &lt;work_group_op op&gt; double sub_group_scan_exclusive(double x);
#endif
template &lt;work_group_op op&gt; int sub_group_scan_inclusive(int x);
template &lt;work_group_op op&gt; uint sub_group_scan_inclusive(uint x);
template &lt;work_group_op op&gt; long sub_group_scan_inclusive(long x);
template &lt;work_group_op op&gt; ulong sub_group_scan_inclusive(ulong x);
template &lt;work_group_op op&gt; float sub_group_scan_inclusive(float x);
#ifdef cl_khr_fp16
template &lt;work_group_op op&gt; half sub_group_scan_inclusive(half x);
#endif
#ifdef cl_khr_fp64
template &lt;work_group_op op&gt; double sub_group_scan_inclusive(double x);
#endif
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="logical-operations">3.15.2. Logical operations</h4>
<div class="sect4">
<h5 id="work_group_all">work_group_all</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool work_group_all(bool predicate)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Evaluates <code>predicate</code> for all work-items in the work-group and returns <code>true</code> if <code>predicate</code> evaluates to <code>true</code> for all work-items in the work-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="work_group_any">work_group_any</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool work_group_any(bool predicate)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Evaluates <code>predicate</code> for all work-items in the work-group and returns <code>true</code> if <code>predicate</code> evaluates to <code>true</code> for any work-items in the work-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_group_all">sub_group_all</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool sub_group_all(bool predicate)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Evaluates <code>predicate</code> for all work-items in the sub-group and returns <code>true</code> value if <code>predicate</code> evaluates to <code>true</code> for all work-items in the sub-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_group_any">sub_group_any</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool sub_group_any(bool predicate)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Evaluates <code>predicate</code> for all work-items in the sub-group and returns <code>true</code> value if <code>predicate</code> evaluates to <code>true</code> for any work-items in the sub-group.</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_work_item&gt;
#include &lt;opencl_work_group&gt;
using namespace cl;
kernel void foo(int *p) {
//...
bool check = work_group_all(p[get_local_id(0)] == 0);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case <code>work_group_all</code> would return <code>true</code> for all work-items in work-group if all elements in <code>p</code>, in range specified by work-group&#8217;s size, are <code>true</code>.</p>
</div>
<div class="paragraph">
<p>One could achieve similar result by using analogical call to <code>work_group_any</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_work_item&gt;
#include &lt;opencl_work_group&gt;
using namespace cl;
kernel void foo(int *p) {
//...
bool check = !work_group_any(p[get_local_id(0)] != 0);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="broadcast-functions">3.15.3. Broadcast functions</h4>
<div class="sect4">
<h5 id="work_group_broadcast">work_group_broadcast</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype work_group_broadcast(gentype a,
size_t local_id);
gentype work_group_broadcast(gentype a,
size_t local_id_x,
size_t local_id_y);
gentype work_group_broadcast(gentype a,
size_t local_id_x,
size_t local_id_y,
size_t local_id_z);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Broadcast the value of <code>a</code> for work-item identified by <code>local_id</code> to all work-items in the work-group.</p>
</div>
<div class="paragraph">
<p><code>local_id</code> must be the same value for all work-items in the work-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_group_broadcast">sub_group_broadcast</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sub_group_broadcast(gentype a,
size_t sub_group_local_id);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Broadcast the value of <code>a</code> for work-item identified by <code>sub_group_local_id</code> (value returned by <code>get_sub_group_local_id</code>) to all work-items in the sub-group.</p>
</div>
<div class="paragraph">
<p><code>sub_group_local_id</code> must be the same value for all work-items in the sub-group.</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_work_item&gt;
#include &lt;opencl_work_group&gt;
using namespace cl;
kernel void foo(int *p) {
//...
int broadcasted_value = work_group_broadcast(p[get_local_id(0)], 0);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here we are broadcasting value passed to <code>work_group_broadcast</code> function by work-item with <code>local_id = 0</code> (which is <code>p[0]</code>).
This function will return <code>p[0]</code> for all callers.
Please note that <code>local_id</code> must be the same for all work-items, therefore something like this is invalid:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_work_item&gt;
#include &lt;opencl_work_group&gt;
using namespace cl;
kernel void foo(int *p) {
//...
int broadcasted_value =
work_group_broadcast(p[get_local_id(0)], get_local_id(0));
//invalid: second argument has different value
// for different work-items in work-group
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="numeric-operations">3.15.4. Numeric operations</h4>
<div class="sect4">
<h5 id="work_group_reduce">work_group_reduce</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;work_group_op op&gt;
gentype work_group_reduce(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return result of reduction operation specified by <code>op</code> for all values of <code>x</code> specified by work-items in a work-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="work_group_scan_exclusive">work_group_scan_exclusive</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;work_group_op op&gt;
gentype work_group_scan_exclusive(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Do an exclusive scan operation specified by <code>op</code> of all values specified by work-items in the work-group.
The scan results are returned for each work-item.</p>
</div>
<div class="paragraph">
<p>The scan order is defined by increasing 1D linear global ID within the work-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="work_group_scan_inclusive">work_group_scan_inclusive</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;work_group_op op&gt;
gentype work_group_scan_inclusive(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Do an inclusive scan operation specified by <code>op</code> of all values specified by work-items in the work-group.
The scan results are returned for each work-item.</p>
</div>
<div class="paragraph">
<p>The scan order is defined by increasing 1D linear global ID within the work-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_group_reduce">sub_group_reduce</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;work_group_op op&gt;
gentype sub_group_reduce(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return result of reduction operation specified by <code>op</code> for all values of <code>x</code> specified by work-items in a sub-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_group_scan_exclusive">sub_group_scan_exclusive</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;work_group_op op&gt;
gentype sub_group_scan_exclusive(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Do an exclusive scan operation specified by <code>op</code> of all values specified by work-items in a sub-group.
The scan results are returned for each work-item.</p>
</div>
<div class="paragraph">
<p>The scan order is defined by increasing 1D linear global ID within the sub-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_group_scan_inclusive">sub_group_scan_inclusive</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;work_group_op op&gt;
gentype sub_group_scan_inclusive(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Do an inclusive scan operation specified by <code>op</code> of all values specified by work-items in a sub-group.
The scan results are returned for each work-item.</p>
</div>
<div class="paragraph">
<p>The scan order is defined by increasing 1D linear global ID within the sub-group.</p>
</div>
<div class="paragraph">
<p>The inclusive scan operation takes a binary operator <code>op</code> with an identity I and n (where n is the size of the work-group) elements [a<sub>0</sub>, a<sub>1</sub>, &#8230;&#8203; a<sub>n-1</sub>] and returns [a<sub>0</sub>, (a<sub>0</sub> <em>op</em> a<sub>1</sub>), &#8230;&#8203; (a<sub>0</sub> <em>op</em> a<sub>1</sub> <em>op</em> &#8230;&#8203; <em>op</em> a<sub>n-1</sub>)].
If <code>op</code> is <code>work_group_op::add</code>, the identity I is 0.
If <code>op</code> is <code>work_group_op::min</code>, the identity I is <code>INT_MAX</code>, <code>UINT_MAX</code>, <code>LONG_MAX</code>, <code>ULONG_MAX</code>, for <code>int</code>, <code>uint</code>, <code>long</code>, <code>ulong</code> types and is <code>+INF</code> for floating-point types.
Similarly if <code>op</code> is <code>work_group_op::max</code>, the identity I is <code>INT_MIN</code>, <code>0</code>, <code>LONG_MIN</code>, <code>0</code> and <code>-INF</code>.</p>
</div>
<div class="paragraph">
<p>Consider the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_work_item&gt;
#include &lt;opencl_work_group&gt;
using namespace cl;
void foo(int *p)
{
...
int prefix_sum_val =
work_group_scan_inclusive&lt;work_group_op::add&gt;(
p[get_local_id(0)]);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the example above, let&#8217;s assume that the work-group size is 8 and p points to the following elements [3 1 7 0 4 1 6 3].
Work-item 0 calls <code>work_group_scan_inclusive&lt;work_group_op::add&gt;</code> with 3 and returns 3.
Work-item 1 calls <code>work_group_scan_inclusive&lt;work_group_op::add&gt;</code> with 1 and returns 4.
The full set of values returned by <code>work_group_scan_inclusive&lt;work_group_op::add&gt;</code> for work-items 0 &#8230;&#8203; 7 is [3 4 11 11 15 16 22 25].</p>
</div>
<div class="paragraph">
<p>The exclusive scan operation takes a binary associative operator <code>op</code> with an identity I and n (where n is the size of the work-group) elements [a<sub>0</sub>, a<sub>1</sub>, &#8230;&#8203; a<sub>n-1</sub>] and returns [I, a<sub>0</sub>, (a<sub>0</sub> <em>op</em> a<sub>1</sub>), &#8230;&#8203; (a<sub>0</sub> <em>op</em> a<sub>1</sub> <em>op</em> &#8230;&#8203; <em>op</em> a<sub>n-2</sub>)].
For the example above, the exclusive scan add operation on the ordered set [3 1 7 0 4 1 6 3] would return [0 3 4 11 11 15 16 22].</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The order of floating-point operations is not guaranteed for the <code>work_group_reduce&lt;op&gt;</code>, <code>work_group_scan_inclusive&lt;op&gt;</code> and <code>work_group_scan_exclusive&lt;op&gt;</code> built-in functions that operate on <code>half</code>, <code>float</code> and <code>double</code> data types.
The order of these floating-point operations is also non-deterministic for a given work-group.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="synchronization-functions">3.16. Synchronization Functions</h3>
<div class="paragraph">
<p>The OpenCL C++ library implements the following synchronization functions.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_synchronization-synopsis">3.16.1. Header &lt;opencl_synchronization&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
void work_group_barrier(mem_fence flags,
memory_scope scope = memory_scope_work_group);
void sub_group_barrier(mem_fence flags,
memory_scope scope = memory_scope_work_group);
#ifdef cl_khr_subgroup_named_barrier
struct work_group_named_barrier: marker_type
{
work_group_named_barrier(uint sub_group_count);
work_group_named_barrier() = delete;
work_group_named_barrier(const work_group_named_barrier&amp;) = default;
work_group_named_barrier(work_group_named_barrier&amp;&amp;) = default;
work_group_named_barrier&amp; operator=(
const work_group_named_barrier&amp;) = delete;
work_group_named_barrier&amp; operator=(work_group_named_barrier&amp;&amp;) = delete;
work_group_named_barrier* operator&amp;() = delete;
void wait(mem_fence flags,
memory_scope scope = memory_scope_work_group) const noexcept;
};
#endif
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="synchronization-operations">3.16.2. Synchronization operations</h4>
<div class="sect4">
<h5 id="work_group_barrier">work_group_barrier</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void work_group_barrier(mem_fence flags,
memory_scope scope = memory_scope_work_group);</code></pre>
</div>
</div>
<div class="paragraph">
<p>All work-items in a work-group executing the kernel on a processor must execute this function before any are allowed to continue execution beyond the <code>work_group_barrier</code>.
This function must be encountered by all work-items in a work-group executing the kernel.
These rules apply to ND-ranges implemented with uniform and non-uniform work-groups.</p>
</div>
<div class="paragraph">
<p>If <code>work_group_barrier</code> is inside a conditional statement, then all work-items must enter the conditional if any work-item enters the conditional statement and executes the <code>work_group_barrier</code>.</p>
</div>
<div class="paragraph">
<p>If <code>work_group_barrier</code> is inside a loop, all work-items must execute the <code>work_group_barrier</code> for each iteration of the loop before any are allowed to continue execution beyond the <code>work_group_barrier</code>.</p>
</div>
<div class="paragraph">
<p>The <code>scope</code> argument specifies whether the memory accesses of work-items in the work-group to memory address space(s) identified by <code>flags</code> become visible to all work-items in the work-group, the device or all SVM devices.</p>
</div>
<div class="paragraph">
<p>The <code>work_group_barrier</code> function can also be used to specify which memory operations i.e. to global memory, local memory or images become visible to the appropriate memory scope identified by <code>scope</code>.
The <code>flags</code> argument specifies the memory address spaces.
This is a bitfield and can be set to 0 or a combination of the following values ORed together.
When these flags are ORed together the <code>work_group_barrier</code> acts as a combined barrier for all address spaces specified by the flags ordering memory accesses both within and across the specified address spaces.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>mem_fence::local</code> - The <code>work_group_barrier</code> function will ensure that all local memory accesses become visible to all work-items in the work-group.
Note that the value of <code>scope</code> is ignored as the memory scope is always <code>memory_scope_work_group</code>.</p>
</li>
<li>
<p><code>mem_fence::global</code> - The <code>work_group_barrier</code> function ensure that all global memory accesses become visible to the appropriate scope as given by <code>scope</code>.</p>
</li>
<li>
<p><code>mem_fence::image</code> - The <code>work_group_barrier</code> function will ensure that all image memory accesses become visible to the appropriate scope as given by <code>scope</code>.
The value of <code>scope</code> must be <code>memory_scope_work_group</code> or <code>memory_scope_device</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><code>mem_fence::image</code> cannot be used together with <code>mem_fence::local</code> or <code>mem_fence::global</code>.</p>
</div>
<div class="paragraph">
<p>The values of <code>flags</code> and <code>scope</code> must be the same for all work-items in the work-group.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_group_barrier">sub_group_barrier</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void sub_group_barrier(mem_fence flags,
memory_scope scope = memory_scope_work_group);</code></pre>
</div>
</div>
<div class="paragraph">
<p>All work-items in a sub-group executing the kernel on a processor must execute this function before any are allowed to continue execution beyond the sub-group barrier.
This function must be encountered by all work-items in a sub-group executing the kernel.
These rules apply to ND-ranges implemented with uniform and non-uniform work-groups.</p>
</div>
<div class="paragraph">
<p>If <code>sub_group_barrier</code> is inside a conditional statement, then all work-items within the sub-group must enter the conditional if any work-item in the sub-group enters the conditional statement and executes the <code>sub_group_barrier</code>.</p>
</div>
<div class="paragraph">
<p>If <code>sub_group_barrier</code> is inside a loop, all work-items within the sub-group must execute the <code>sub_group_barrier</code> for each iteration of the loop before any are allowed to continue execution beyond the <code>sub_group_barrier</code>.</p>
</div>
<div class="paragraph">
<p>The <code>sub_group_barrier</code> function also queues a memory fence (reads and writes) to ensure correct ordering of memory operations to local or global memory.</p>
</div>
<div class="paragraph">
<p>The <code>flags</code> argument specifies the memory address spaces.
This is a bitfield and can be set to 0 or a combination of the following values ORed together.
When these flags are ORed together the <code>sub_group_barrier</code> acts as a combined barrier for all address spaces specified by the flags ordering memory accesses both within and across the specified address spaces.</p>
</div>
<div class="paragraph">
<p><code>mem_fence::local</code> - The <code>sub_group_barrier</code> function will ensure that all local memory accesses become visible to all work-items in the sub-group.
Note that the value of <code>scope</code> is ignored as the memory scope is always <code>memory_scope_work_group</code>.</p>
</div>
<div class="paragraph">
<p><code>mem_fence::global</code> - The <code>sub_group_barrier</code> function ensure that all global memory accesses become visible to the appropriate scope as given by <code>scope</code>.</p>
</div>
<div class="paragraph">
<p><code>mem_fence::image</code> - The <code>sub_group_barrier</code> function will ensure that all image memory accesses become visible to the appropriate scope as given by <code>scope</code>.
The value of <code>scope</code> must be <code>memory_scope_work_group</code> or <code>memory_scope_device</code>.</p>
</div>
<div class="paragraph">
<p><code>mem_fence::image</code> cannot be used together with <code>mem_fence::local</code> or <code>mem_fence::global</code>.</p>
</div>
<div class="paragraph">
<p>The values of <code>flags</code> and <code>scope</code> must be the same for all work-items in the sub-group.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="named-barriers">3.16.3. Named barriers</h4>
<div class="paragraph">
<p>This section describes the optional <strong>cl_khr_sub_group_named_barrier</strong> extension which exposes the ability to perform barrier synchronization on flexible portions of an execution domain.</p>
</div>
<div class="paragraph">
<p>If the <strong>cl_khr_sub_group_named_barrier</strong> extension is supported by a device, an application that wants to use it will need to define the <code>cl_khr_sub_group_named_barrier</code> macro before including the OpenCL C++ standard library headers or using the <em>-D</em> compiler option (<a href="#preprocessor_options"><em>Preprocessor options</em></a> section).</p>
</div>
<div class="paragraph">
<p>An implementation shall support at least 8 named barriers per work-group.
The exact maximum number can be queried using <code>clGetDeviceInfo</code> with <code>CL_DEVICE_MAX_NAMED_BARRIER_COUNT_KHR</code> from the OpenCL 2.2 Extension Specification.</p>
</div>
<div class="paragraph">
<p>Restrictions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <code>work_group_named_barrier</code> type cannot be used with variables declared inside a class or union field, a pointer type, an array, global variables declared at program scope or the return type of a function.</p>
</li>
<li>
<p>The <code>work_group_named_barrier</code> type cannot be used with the <code>global</code>, <code>priv</code> and <code>constant</code> address space storage classes (see the the <a href="#explicit-address-space-storage-classes"><em>Explicit address space storage classes</em></a> section).</p>
</li>
<li>
<p>The value returned by applying the <code>sizeof</code> operator to the <code>work_group_named_barrier</code> type is implementation-defined.</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="work_group_named_barrier">work_group_named_barrier</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>work_group_named_barrier(uint sub_group_count);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Initialize a new named barrier object to synchronize <code>sub_group_count</code> sub-groups in the current work-group.
Construction of a named-barrier object is a work-group operation and hence must be called uniformly across the work-group.
<code>sub_group_count</code> must be uniform across the work-group.</p>
</div>
<div class="paragraph">
<p>Named barrier objects can be reconstructed and assigned to underlying entities by the compiler, or reused.
Reused barriers will always be the same size and act in phases such that when each participating sub-group has waited the wait count is set to 0 and the entire process can start again.
The internal wait count will cycle through the range from <code>0</code> to <code>sub_group_count</code> in each phase of use of the barrier.</p>
</div>
<div class="paragraph">
<p>Named barrier objects can only be constructed within kernels, not within arbitrary functions.</p>
</div>
</div>
<div class="sect4">
<h5 id="wait">wait</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void wait(mem_fence flags,
memory_scope scope = memory_scope_work_group) const noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>All work-items in a sub-group executing the kernel on a processor must execute this method before any are allowed to continue execution beyond the barrier.
This function must be encountered by all work-items in a sub-group executing the kernel.</p>
</div>
<div class="paragraph">
<p>These rules apply to ND-ranges implemented with uniform and non-uniform work-groups.</p>
</div>
<div class="paragraph">
<p>If <code>wait</code> is called inside a conditional statement, then all work-items within the sub-group must enter the conditional if any work-item in the sub-group enters the conditional statement and executes the call to wait.</p>
</div>
<div class="paragraph">
<p>If <code>wait</code> is called inside a loop, all work-items within the sub-group must execute the wait operation for each iteration of the loop before any are allowed to continue execution beyond the call to wait.
The wait function causes the entire sub-group to wait until <code>sub_group_count</code> sub-groups have waited on the named barrier, where <code>sub_group_count</code> is the initialization value passed to the call to the constructor of the named barrier.
Once the wait count equals <code>sub_group_count</code>, any sub-groups waiting at the named barrier will be released and the barrier&#8217;s wait count reset to 0.</p>
</div>
<div class="paragraph">
<p>The <code>flags</code> argument specifies the memory address spaces.
This is a bitfield and can be set to 0 or a combination of the following values ORed together.
When these flags are ORed together the wait acts as a combined wait operation for all address spaces specified by the flags ordering memory accesses both within and across the specified address spaces.</p>
</div>
<div class="paragraph">
<p><code>mem_fence::local</code> - The wait function will ensure that all local memory accesses become visible to all work-items in the sub-group.
Note that the value of <code>scope</code> is ignored as the memory scope is always <code>memory_scope_work_group</code>.</p>
</div>
<div class="paragraph">
<p><code>mem_fence::global</code> - The wait function ensure that all global memory accesses become visible to the appropriate scope as given by <code>scope</code>.</p>
</div>
<div class="paragraph">
<p><code>mem_fence::image</code> cannot be specified as a flag for this function.</p>
</div>
<div class="paragraph">
<p>The values of <code>flags</code> and <code>scope</code> must be the same for all work-items in the sub-group.</p>
</div>
<div class="paragraph">
<p>The below example shows how to use the named barriers:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_synchronization&gt;
#include &lt;opencl_work_item&gt;
using namespace cl;
void aFunction(work_group_named_barrier &amp;b) {
while(...) {
// Do something in first set
b.wait(mem_fence::global);
}
}
kernel void aKernel() {
// Initialize a set of named barriers
local&lt;work_group_named_barrier&gt; a(4);
local&lt;work_group_named_barrier&gt; b(2);
local&lt;work_group_named_barrier&gt; c(2);
if(get_sub_group_id() &lt; 4) {
a.wait(mem_fence::local);
if(get_sub_group_id() &lt; 2) {
// Pass one of the named barriers to a function by reference
// Barrier cannot be constructed in a non-kernel function
aFunction(b);
} else {
// Do something else
c.wait(mem_fence::local);
// Continue
}
// Wait a second time on the first barrier
a.wait(mem_fence::global);
}
// Back to work-group uniform control flow,
// we can synchronize the entire group if necessary
work_group_barrier(mem_fence::global);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="common-functions">3.17. Common Functions</h3>
<div class="paragraph">
<p>This section describes the OpenCL C++ library common functions that take scalar or vector arguments.
Vector versions of common functions operate component-wise.
Descriptions are always per-component.</p>
</div>
<div class="paragraph">
<p>The built-in common functions are implemented using the round to nearest even rounding mode.</p>
</div>
<div class="paragraph">
<p>Here <code>gentype</code> matches: <code>half<em>n</em></code> <a id="ftnref4"></a> <a href="#ftn4">[4]</a>, <code>float<em>n</em></code> or <code>double<em>n</em></code> <a id="ftnref18"></a> <a href="#ftn18">[18]</a></p>
</div>
<div class="sect3">
<h4 id="header-opencl_common-synopsis">3.17.1. Header &lt;opencl_common&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
#ifdef cl_khr_fp16
halfn clamp(halfn x, halfn min, halfn max);
halfn degrees(halfn t);
halfn max(halfn x, halfn y);
halfn min(halfn x, halfn y);
halfn mix(halfn x, halfn y, halfn a);
halfn radians(halfn t);
halfn step(halfn edge, halfn x);
halfn smoothstep(halfn edge0, halfn edge1, halfn x);
halfn sign(halfn t);
#endif
#ifdef cl_khr_fp64
doublen clamp(doublen x, doublen min, doublen max);
doublen degrees(doublen t);
doublen max(doublen x, doublen y);
doublen min(doublen x, doublen y);
doublen mix(doublen x, doublen y, doublen a);
doublen radians(doublen t);
doublen step(doublen edge, doublen x);
doublen smoothstep(doublen edge0, doublen edge1, doublen x);
doublen sign(doublen t);
#endif
floatn clamp(floatn x, floatn min, floatn max);
floatn degrees(floatn t);
floatn max(floatn x, floatn y);
floatn min(floatn x, floatn y);
floatn mix(floatn x, floatn y, floatn a);
floatn radians(floatn t);
floatn step(floatn edge, floatn x);
floatn smoothstep(floatn edge0, floatn edge1, floatn x);
floatn sign(floatn t);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="common-operations">3.17.2. Common operations</h4>
<div class="sect4">
<h5 id="clamp-1">clamp</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype clamp(gentype x, gentype minval, gentype maxval);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>fmin(fmax(x, minval), maxval)</code>.</p>
</div>
<div class="paragraph">
<p>Results are undefined if <code>minval &gt; maxval</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="degrees">degrees</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype degrees(gentype radians);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Converts radians to degrees, i.e. <code>(180 / π) * radians</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="max-1">max</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype max(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>y</code> if <code>x &lt; y</code>, otherwise it returns <code>x</code>.
If <code>x</code> or <code>y</code> are <code>infinite</code> or <code>NaN</code>, the return values are undefined.</p>
</div>
</div>
<div class="sect4">
<h5 id="min-1">min</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype min(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>y</code> if <code>y &lt; x</code>, otherwise it returns <code>x</code>.
If <code>x</code> or <code>y</code> are <code>infinite</code> or <code>NaN</code>, the return values are undefined.</p>
</div>
</div>
<div class="sect4">
<h5 id="mix">mix</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype mix(gentype x, gentype y, gentype a);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the linear blend of <code>x</code> and <code>y</code> implemented as:</p>
</div>
<div class="paragraph">
<p><code>x + (y - x) * a</code></p>
</div>
<div class="paragraph">
<p><code>a</code> must be a value in the range 0.0 &#8230;&#8203; 1.0.
If <code>a</code> is not in the range 0.0 &#8230;&#8203; 1.0, the return values are undefined.</p>
</div>
</div>
<div class="sect4">
<h5 id="radians">radians</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype radians(gentype degrees);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Converts degrees to radians, i.e. <code>(π / 180) * degrees</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="step">step</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype step(gentype edge, gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>0.0</code> if <code>x &lt; edge</code>, otherwise it returns <code>1.0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="smoothstep">smoothstep</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype smoothstep(gentype edge0, gentype edge1, gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>0.0</code> if <code>x &lt;= edge0</code> and <code>1.0</code> if <code>x &gt;= edge1</code> and performs smooth Hermite interpolation between <code>0</code> and <code>1</code> when <code>edge0 &lt; x &lt; edge1</code>.
This is useful in cases where you would want a threshold function with a smooth transition.</p>
</div>
<div class="paragraph">
<p>This is equivalent to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype t;
t = clamp((x - edge0) / (edge1 - edge0), 0, 1);
return t * t * (3 - 2 * t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Results are undefined if <code>edge0 &gt;= edge1</code> or if <code>x</code>, <code>edge0</code> or <code>edge1</code> is a <code>NaN</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="sign">sign</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sign(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>1.0</code> if <code>x &gt; 0</code>, <code>-0.0</code> if <code>x = -0.0</code>, <code>+0.0</code> if <code>x = 0.0</code>, or <code>-1.0</code> if <code>x &lt; 0</code>.
Returns <code>0.0</code> if <code>x</code> is a <code>NaN</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="geometric-functions">3.18. Geometric Functions</h3>
<div class="paragraph">
<p>This section describes the OpenCL C++ library geometric functions that take scalar or vector arguments.
Vector versions of geometric functions operate component-wise.
Descriptions are always per-component.
The geometric functions are implemented using the round to nearest even rounding mode.</p>
</div>
<div class="paragraph">
<p><code>float<em>n</em></code> is <code>float</code>, <code>float2</code>, <code>float3</code> or <code>float4</code>.</p>
</div>
<div class="paragraph">
<p><code>half<em>n</em></code> <a id="ftnref4"></a> <a href="#ftn4">[4]</a> is <code>half</code>, <code>half2</code>, <code>half3</code> or <code>half4</code>.</p>
</div>
<div class="paragraph">
<p><code>double<em>n</em></code> <a id="ftnref18"></a> <a href="#ftn18">[18]</a> is <code>double</code>, <code>double2</code>, <code>double3</code> or <code>double4</code>.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_geometric-synopsis">3.18.1. Header &lt;opencl_geometric&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
#ifdef cl_khr_fp16
half3 cross(half3 p0, half3 p1);
half4 cross(half4 p0, half4 p1);
half dot(half p0, half p1);
half dot(half2 p0, half2 p1);
half dot(half3 p0, half3 p1);
half dot(half4 p0, half4 p1);
half distance(half p0, half p1);
half distance(half2 p0, half2 p1);
half distance(half3 p0, half3 p1;
half distance(half4 p0, half4 p1);
half length(half t);
half length(half2 t);
half length(half3 t);
half length(half4 t);
half normalize(half t);
half2 normalize(half2 t);
half3 normalize(half3 t);
half4 normalize(half4 t);
#endif
#ifdef cl_khr_fp64
double3 cross(double3 p0, double3 p1);
double4 cross(double4 p0, double4 p1);
double dot(double p0, double p1);
double dot(double2 p0, double2 p1);
double dot(double3 p0, double3 p1);
double dot(double4 p0, double4 p1);
double distance(double p0, double p1);
double distance(double2 p0, double2 p1);
double distance(double3 p0, double3 p1);
double distance(double4 p0, double4 p1);
double length(double t);
double length(double2 t);
double length(double3 t);
double length(double4 t);
double normalize(double t);
double2 normalize(double2 t);
double3 normalize(double3 t);
double4 normalize(double4 t);
#endif
float3 cross(float3 p0, float3 p1);
float4 cross(float4 p0, float4 p1);
float dot(float p0, float p1);
float dot(float2 p0, float2 p1);
float dot(float3 p0, float3 p1);
float dot(float4 p0, float4 p1);
float distance(float p0, float p1);
float distance(float2 p0, float2 p1);
float distance(float3 p0, float3 p1);
float distance(float4 p0, float4 p1);
float length(float t);
float length(float2 t);
float length(float3 t);
float length(float4 t);
float normalize(float t);
float2 normalize(float2 t);
float3 normalize(float3 t);
float4 normalize(float4 t);
float fast_distance(float p0, float p1);
float fast_distance(float2 p0, float2 p1);
float fast_distance(float3 p0, float3 p1);
float fast_distance(float4 p0, float4 p1);
float fast_length(float t);
float fast_length(float2 t);
float fast_length(float3 t);
float fast_length(float4 t);
float fast_normalize(float t);
float2 fast_normalize(float2 t);
float3 fast_normalize(float3 t);
float4 fast_normalize(float4 t);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="geometric-operations">3.18.2. Geometric operations</h4>
<div class="sect4">
<h5 id="cross">cross</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float4 cross(float4 p0, float4 p1);
float3 cross(float3 p0, float3 p1);
double4 cross(double4 p0, double4 p1);
double3 cross(double3 p0, double3 p1);
half4 cross(half4 p0, half4 p1);
half3 cross(half3 p0, half3 p1);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the cross product of <code>p0.xyz</code> and <code>p1.xyz</code>.
The <code>w</code> component of <code>float4</code> result returned will be <code>0.0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="dot">dot</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float dot(floatn p0, floatn p1);
double dot(doublen p0, doublen p1);
half dot(halfn p0, halfn p1);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute dot product.</p>
</div>
</div>
<div class="sect4">
<h5 id="distance">distance</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float distance(floatn p0, floatn p1);
double distance(doublen p0, doublen p1);
half distance(halfn p0, halfn p1);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the distance between <code>p0</code> and <code>p1</code>.</p>
</div>
<div class="paragraph">
<p>This is calculated as <code>length(p0 - p1)</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="length">length</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float length(floatn p);
double length(doublen p);
half length(halfn p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return the length of vector <code>p</code>, i.e.,
\(\sqrt{p.x^2 + p.y^2 + \ldots}\)</p>
</div>
</div>
<div class="sect4">
<h5 id="normalize">normalize</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn normalize(floatn p);
doublen normalize(doublen p);
halfn normalize(halfn p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a vector in the same direction as <code>p</code> but with a length of <code>1</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="fast_distance">fast_distance</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float fast_distance(floatn p0, floatn p1);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>fast_length(p0 - p1)</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="fast_length">fast_length</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float fast_length(floatn p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the length of vector <code>p</code> computed as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>half_sqrt(p.x^2 + p.y^2 + ...)</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="fast_normalize">fast_normalize</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn fast_normalize(floatn p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a vector in the same direction as <code>p</code> but with a length of 1.
<code>fast_normalize</code> is computed as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>p * half_rsqrt(p.x^2 + p.y^2 + ...)</code></pre>
</div>
</div>
<div class="paragraph">
<p>The result shall be within 8192 ulps error from the infinitely precise result of</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>if (all(p == 0.0f))
result = p;
else
result = p / sqrt(p.x^2 + p.y^2 + ... );</code></pre>
</div>
</div>
<div class="paragraph">
<p>with the following exceptions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If the sum of squares is greater than <code>FLT_MAX</code> then the value of the floating-point values in the result vector are undefined.</p>
</li>
<li>
<p>If the sum of squares is less than <code>FLT_MIN</code> then the implementation may return back <code>p</code>.</p>
</li>
<li>
<p>If the device is in &#8220;denorms are flushed to zero&#8221; mode, individual operand elements with magnitude less than <code>sqrt(FLT_MIN)</code> may be flushed to zero before proceeding with the calculation.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="math-functions">3.19. Math Functions</h3>
<div class="paragraph">
<p>,The list of the OpenCL C++ library math functions is described in <a href="#trigonometric-functions"><em>Trigonometric functions</em></a>, <a href="#logarithmic-functions"><em>Logarithmic functions</em></a>, <a href="#exponential-functions"><em>Exponential functions</em></a>, <a href="#floating-point-functions"><em>Floating-point functions</em></a>, <a href="#comparison-functions"><em>Comparison functions</em></a>, and <a href="#other-functions-1"><em>Other functions</em></a> sections.</p>
</div>
<div class="paragraph">
<p>The built-in math functions are categorized into the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A list of built-in functions that have scalar or vector argument versions.</p>
</li>
<li>
<p>A list of built-in functions that only take scalar float arguments.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The vector versions of the math functions operate component-wise.
The description is per-component.</p>
</div>
<div class="paragraph">
<p>The built-in math functions are not affected by the prevailing rounding mode in the calling environment, and always return the same value as they would if called with the round to nearest even rounding mode.</p>
</div>
<div class="paragraph">
<p>Here <code>gentype</code> matches: <code>half<em>n</em></code> <a id="ftnref4"></a> <a href="#ftn4">[4]</a>, <code>float<em>n</em></code> or <code>double<em>n</em></code> <a id="ftnref18"></a> <a href="#ftn18">[18]</a></p>
</div>
<div class="sect3">
<h4 id="header-opencl_math-synopsis">3.19.1. Header &lt;opencl_math&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
//trigonometric functions
gentype acos(gentype x);
gentype acosh(gentype x);
gentype acospi(gentype x);
gentype asin(gentype x);
gentype asinh(gentype x);
gentype asinpi(gentype x);
gentype atan(gentype x);
gentype atanh(gentype x);
gentype atanpi(gentype x);
gentype atan2(gentype y, gentype x);
gentype atan2pi(gentype y, gentype x);
gentype cos(gentype x);
gentype cosh(gentype x);
gentype cospi(gentype x);
gentype sin(gentype x);
gentype sincos(gentype x, gentype * cosval);
gentype sinh(gentype x);
gentype sinpi(gentype x);
gentype tan(gentype x);
gentype tanh(gentype x);
gentype tanpi(gentype x);
//power functions
gentype cbrt(gentype x);
gentype pow(gentype x, gentype y);
gentype pown(gentype x, intn y);
gentype powr(gentype x, gentype y);
gentype rootn(gentype x, intn y);
gentype rsqrt(gentype x);
gentype sqrt(gentype x);
//logarithmic functions
intn ilogb(gentype x);
gentype lgamma(gentype x);
gentype lgamma_r(gentype x, intn* signp);
gentype log(gentype x);
gentype logb(gentype x);
gentype log2(gentype x);
gentype log10(gentype x);
gentype log1p(gentype x);
//exponential functions
gentype exp(gentype x);
gentype expm1(gentype x);
gentype exp2(gentype x);
gentype exp10(gentype x);
gentype ldexp(gentype x, intn k);
//floating-point functions
gentype ceil(gentype x);
gentype copysign(gentype x, gentype y);
gentype floor(gentype x);
gentype fma(gentype a, gentype b, gentype c);
gentype fmod(gentype x, gentype y);
gentype fract(gentype x, gentype* iptr);
gentype frexp(gentype x, intn* exp);
gentype modf(gentype x, gentype* iptr);
#ifdef cl_khr_fp16
halfn nan(ushortn nancode);
#endif
floatn nan(uintn nancode);
#ifdef cl_khr_fp64
doublen nan(ulong nancode);
#endif
gentype nextafter(gentype x, gentype y);
gentype remainder(gentype x, gentype y);
gentype remquo(gentype x, gentype y, intn* quo);
gentype rint(gentype x);
gentype round(gentype x);
gentype trunc(gentype x);
//comparison functions
gentype fdim(gentype x, gentype y);
gentype fmax(gentype x, gentype y);
gentype fmin(gentype x, gentype y);
gentype maxmag(gentype x, gentype y);
gentype minmag(gentype x, gentype y);
//other functions
gentype erf(gentype x);
gentype erfc(gentype x);
gentype fabs(gentype x);
gentype hypot(gentype x, gentype y);
gentype mad(gentype a, gentype b, gentype c);
gentype tgamma(gentype x);
//native functions
namespace native
{
floatn cos(floatn x);
floatn exp(floatn x);
floatn exp2(floatn x);
floatn exp10(floatn x);
floatn log(floatn x);
floatn log2(floatn x);
floatn log10(floatn x);
floatn recip(floatn x);
floatn rsqrt(floatn x);
floatn sin(floatn x);
floatn sqrt(floatn x);
floatn tan(floatn x);
floatn divide(floatn x, floatn y);
floatn powr(floatn x, floatn y);
}
//half_math functions
namespace half_math
{
floatn cos(floatn x);
floatn exp(floatn x);
floatn exp2(floatn x);
floatn exp10(floatn x);
floatn log(floatn x);
floatn log2(floatn x);
floatn log10(floatn x);
floatn recip(floatn x);
floatn rsqrt(floatn x);
floatn sin(floatn x);
floatn sqrt(floatn x);
floatn tan(floatn x);
floatn divide(floatn x, floatn y);
floatn powr(floatn x, floatn y);
}
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="trigonometric-functions">3.19.2. Trigonometric functions</h4>
<div class="sect4">
<h5 id="acos">acos</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype acos(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Arc cosine function.
Returns an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="acosh">acosh</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype acosh(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Inverse hyperbolic cosine.
Returns an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="acospi">acospi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype acospi(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute acos(<code>x</code>) / π.</p>
</div>
</div>
<div class="sect4">
<h5 id="asin">asin</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype asin(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Arc sine function.
Returns an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="asinh">asinh</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype asinh(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Inverse hyperbolic sine.
Returns an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="asinpi">asinpi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype asinpi(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute asin(<code>x</code>) / π.</p>
</div>
</div>
<div class="sect4">
<h5 id="atan">atan</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype atan(gentype y_over_x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Arc tangent function.
Returns an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="atan2">atan2</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype atan2(gentype y, gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Arc tangent of <code>y / x</code>.
Returns an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="atanh">atanh</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype atanh(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Hyperbolic arc tangent.
Returns an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="atanpi">atanpi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype atanpi(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute atan(<code>x</code>) / π.</p>
</div>
</div>
<div class="sect4">
<h5 id="atan2pi">atan2pi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype atan2pi(gentype y, gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute atan2(<code>y</code>, <code>x</code>) / π.</p>
</div>
</div>
<div class="sect4">
<h5 id="cos">cos</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype cos(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute cosine, where <code>x</code> is an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="cosh">cosh</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype cosh(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute hyperbolic consine, where <code>x</code> is an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="cospi">cospi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype cospi(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute cos(π x).</p>
</div>
</div>
<div class="sect4">
<h5 id="sin">sin</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sin(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute sine, where <code>x</code> is an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="sincos">sincos</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sincos(gentype x, gentype *cosval);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute sine and cosine of <code>x</code>.
The computed sine is the return value and computed cosine is returned in <code>cosval</code>, where <code>x</code> is an angle in radians</p>
</div>
</div>
<div class="sect4">
<h5 id="sinh">sinh</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sinh(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute hyperbolic sine, where <code>x</code> is an angle in radians</p>
</div>
</div>
<div class="sect4">
<h5 id="sinpi">sinpi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sinpi(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute sin(π <code>x</code>).</p>
</div>
</div>
<div class="sect4">
<h5 id="tan">tan</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype tan(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute tangent, where <code>x</code> is an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="tanh">tanh</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype tanh(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute hyperbolic tangent, where <code>x</code> is an angle in radians.</p>
</div>
</div>
<div class="sect4">
<h5 id="tanpi">tanpi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype tanpi(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute tan(π <code>x</code>).</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="power-functions">3.19.3. Power function</h4>
<div class="sect4">
<h5 id="cbrt">cbrt</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype cbrt(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute cube-root.</p>
</div>
</div>
<div class="sect4">
<h5 id="pow">pow</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype pow(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x</code> to the power <code>y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="pown">pown</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn pown(gentype x, intn y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x</code> to the power <code>y</code>, where <code>y</code> is an integer.</p>
</div>
</div>
<div class="sect4">
<h5 id="powr">powr</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype powr(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x</code> to the power <code>y</code>, where <code>x</code> is <code>&gt;= 0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="rootn">rootn</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype powr(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x</code> to the power <code>1/y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="rsqrt">rsqrt</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype rsqrt(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute inverse square root.</p>
</div>
</div>
<div class="sect4">
<h5 id="sqrt">sqrt</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sqrt(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute square root.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="logarithmic-functions">3.19.4. Logarithmic functions</h4>
<div class="sect4">
<h5 id="ilogb">ilogb</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>intn ilogb(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return the exponent as an integer value.</p>
</div>
</div>
<div class="sect4">
<h5 id="lgamma">lgamma</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype lgamma(gentype x);
gentype lgamma_r(gentype x, intn *signp);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Log gamma function.
Returns the natural logarithm of the absolute value of the gamma function.
The sign of the gamma function is returned in the signp argument of <code>lgamma_r</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="log">log</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype log(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute natural logarithm.</p>
</div>
</div>
<div class="sect4">
<h5 id="log2">log2</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype log2(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute a base 2 logarithm.</p>
</div>
</div>
<div class="sect4">
<h5 id="log10">log10</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype log10(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute a base 10 logarithm.</p>
</div>
</div>
<div class="sect4">
<h5 id="log1p">log1p</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype log1p(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute log<sub>e</sub>(1.0 + x).</p>
</div>
</div>
<div class="sect4">
<h5 id="logb">logb</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype logb(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the exponent of <code>x</code>, which is the integral part of log<sub>r</sub>|<code>x</code>|.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="exponential-functions">3.19.5. Exponential functions</h4>
<div class="sect4">
<h5 id="exp">exp</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype exp(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the base e exponential of <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="exp2">exp2</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype exp2(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Exponential base 2 function.</p>
</div>
</div>
<div class="sect4">
<h5 id="exp10">exp10</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype exp10(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Exponential base 10 function.</p>
</div>
</div>
<div class="sect4">
<h5 id="expm1">expm1</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype expm1(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute e<sup>x</sup>- 1.0.</p>
</div>
</div>
<div class="sect4">
<h5 id="ldexp">ldexp</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype ldexp(gentype x, intn k);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiply <code>x</code> by 2 to the power <code>k</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="floating-point-functions">3.19.6. Floating-point functions</h4>
<div class="sect4">
<h5 id="ceil">ceil</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype ceil(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Round to integral value using the round to positive infinity rounding mode.</p>
</div>
</div>
<div class="sect4">
<h5 id="copysign">copysign</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype copysign(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns x with its sign changed to match the sign of y.</p>
</div>
</div>
<div class="sect4">
<h5 id="floor">floor</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype floor(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Round to integral value using the round to negative infinity rounding mode.</p>
</div>
</div>
<div class="sect4">
<h5 id="fma">fma</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fma(gentype a, gentype b, gentype c);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the correctly rounded floating-point representation of the sum of <code>c</code> with the infinitely precise product of <code>a</code> and <code>b</code>.
Rounding of intermediate products shall not occur.
Edge case behavior is per the IEEE 754-2008 standard.</p>
</div>
</div>
<div class="sect4">
<h5 id="fmod">fmod</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fmod(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Modulus. Returns <code>x - y * trunc (x/y)</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="fract">fract</h5>
<div class="paragraph">
<p><code>fract</code> <a id="ftnref20"></a> <a href="#ftn20">[20]</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fract(gentype x, gentype *iptr);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>fmin(x - floor(x), 0x1.fffffep-1f)</code>.</p>
</div>
<div class="paragraph">
<p><code>floor(x)</code> is returned in <code>iptr</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="frexp">frexp</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype frexp(gentype x, intn *exp);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Extract mantissa and exponent from <code>x</code>.
For each component the mantissa returned is a half with magnitude in the interval [1/2, 1) or 0.
Each component of <code>x</code> equals mantissa returned <code>* 2<sup>exp</sup></code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="modf">modf</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype modf(gentype x, gentype *iptr);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Decompose a floating-point number.
The modf function breaks the argument <code>x</code> into integral and fractional parts, each of which has the same sign as the argument.
It stores the integral part in the object pointed to by <code>iptr</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="nan">nan</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn nan(uintn nancode);
doublen nan(ulongn nancode);
halfn nan(ushortn nancode);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns a quiet <code>NaN</code>.
The nancode may be placed in the significand of the resulting <code>NaN</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="nextafter">nextafter</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype nextafter(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Computes the next representable single-precision floating-point value following <code>x</code> in the direction of <code>y</code>.
Thus, if <code>y</code> is less than <code>x</code>.
<code>nextafter()</code> returns the largest representable floating-point number less than <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="remainder">remainder</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype remainder(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the value <code>r</code> such that <code>r = x - n*y</code>, where <code>n</code> is the integer nearest the exact value of <code>x/y</code>.
If there are two integers closest to <code>x/y</code>, <code>n</code> shall be the even one.
If <code>r</code> is zero, it is given the same sign as <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="remquo">remquo</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype remquo(gentype x, gentype y, intn *quo);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The remquo function computes the value <code>r</code> such that <code>r = x - k*y</code>, where <code>k</code> is the integer nearest the exact value of <code>x/y</code>.
If there are two integers closest to <code>x/y</code>, <code>k</code> shall be the even one.
If <code>r</code> is zero, it is given the same sign as <code>x</code>.
This is the same value that is returned by the remainder function.
<code>remquo</code> also calculates at least the seven lower bits of the integral quotient <code>x/y</code>, and gives that value the same sign as <code>x/y</code>.
It stores this signed value in the object pointed to by <code>quo</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="rint">rint</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype rint(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Round to integral value (using round to nearest even rounding mode) in floating-point format.
Refer to the <a href="#rounding-modes"><em>Rounding Modes</em></a> section for description of rounding modes.</p>
</div>
</div>
<div class="sect4">
<h5 id="round">round</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype round(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return the integral value nearest to <code>x</code> rounding halfway cases away from zero, regardless of the current rounding direction.</p>
</div>
</div>
<div class="sect4">
<h5 id="trunc">trunc</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype trunc(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Round to integral value using the round to zero rounding mode.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="comparison-functions">3.19.7. Comparison functions</h4>
<div class="sect4">
<h5 id="fdim">fdim</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fdim(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>x - y</code> if <code>x &gt; y</code>, <code>+0</code> if <code>x</code> is less than or equal to <code>y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="fmax">fmax</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fmax(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>y</code> if <code>x &lt; y</code>, otherwise it returns <code>x</code>.
If one argument is a <code>NaN</code>, <code>fmax()</code> returns the other argument.
If both arguments are NaNs, <code>fmax()</code> returns a <code>NaN</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="fmin">fmin</h5>
<div class="paragraph">
<p><code>fmin</code> <a id="ftnref21"></a> <a href="#ftn21">[21]</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fmin(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>y</code> if <code>y &lt; x</code>, otherwise it returns <code>x</code>.
If one argument is a NaN, <code>fmin()</code> returns the other argument.
If both arguments are NaNs, <code>fmin()</code> returns a <code>NaN</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="fmod-1">fmod</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fmod(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Modulus.
Returns <code>x - y * trunc (x/y)</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="maxmag">maxmag</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype maxmag(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>x</code> if <code>|x| &gt; |y|</code>, <code>y</code> if <code>|y| &gt; |x|</code>, otherwise <code>fmax(x, y)</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="minmag">minmag</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype minmag(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>x</code> if <code>|x| &lt; |y|</code>, <code>y</code> if <code>|y| &lt; |x|</code>, otherwise <code>fmin(x, y)</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="other-functions-1">3.19.8. Other functions</h4>
<div class="sect4">
<h5 id="erfc">erfc</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype erfc(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Complementary error function.</p>
</div>
</div>
<div class="sect4">
<h5 id="erf">erf</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype erf(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Error function encountered in integrating the <a href="http://mathworld.wolfram.com/NormalDistribution.html">normal distribution</a>.</p>
</div>
</div>
<div class="sect4">
<h5 id="fabs">fabs</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype fabs(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute absolute value of a floating-point number.</p>
</div>
</div>
<div class="sect4">
<h5 id="hypot">hypot</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype hypot(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the value of the square root of <code>x<sup>2</sup> + y<sup>2</sup></code> without undue overflow or underflow.</p>
</div>
</div>
<div class="sect4">
<h5 id="mad">mad</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype mad(gentype a, gentype b, gentype c);</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>mad</code> computes <code>a * b + c</code>.
The function may compute <code>a * b + c</code> with reduced accuracy
in the embedded profile. See the SPIR-V OpenCL environment specification
for details. On some hardware the mad instruction may provide better
performance than expanded computation of <code>a * b + c</code>. <a id="ftnref22"></a> <a href="#ftn22">[22]</a></p>
</div>
</div>
<div class="sect4">
<h5 id="tgamma">tgamma</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype tgamma(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the gamma function.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="native-functions">3.19.9. Native functions</h4>
<div class="paragraph">
<p>This section describes the following functions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A subset of functions from previous sections that are defined in the <code>cl::native_math</code> namespace.
These functions may map to one or more native device instructions and will typically have better performance compared to the corresponding functions (without the native_math namespace) described in the <a href="#trigonometric-functions"><em>Trigonometric functions</em></a>, <a href="#logarithmic-functions"><em>Logarithmic functions</em></a>, <a href="#exponential-functions"><em>Exponential functions</em></a>, <a href="#floating-point-functions"><em>Floating-point functions</em></a>, <a href="#comparison-functions"><em>Comparison functions</em></a> and <a href="#other-functions-1"><em>Other functions</em></a> sections.
The accuracy (and in some cases the input range(s)) of these functions is implementation-defined.</p>
</li>
<li>
<p>Native functions for following basic operations: divide and reciprocal.</p>
</li>
<li>
<p>Support for denormal values is implementation-defined for native functions.</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="native_mathcos">native_math::cos</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::cos(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute cosine over an implementation-defined range, where <code>x</code> is an angle in radians.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathdivide">native_math::divide</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::divide(floatn x, floatn y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x / y</code> over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathexp">native_math::exp</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::exp(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the base e exponential of <code>x</code> over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathexp2">native_math::exp2</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::exp2(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the base 2 exponential of <code>x</code> over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathexp10">native_math::exp10</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::exp10(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the base 10 exponential of <code>x</code> over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathlog">native_math::log</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::log(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute natural logarithm over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathlog2">native_math::log2</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::log2(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute a base 2 logarithm over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathlog10">native_math::log10</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::log10(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute a base 10 logarithm over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathpowr">native_math::powr</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::powr(floatn x, floatn y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x</code> to the power <code>y</code>, where <code>x</code> is <code>&gt;= 0</code>.
The range of <code>x</code> and <code>y</code> are implementation-defined.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathrecip">native_math::recip</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::recip(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute reciprocal over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathrsqrt">native_math::rsqrt</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::rsqrt(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute inverse square root over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathsin">native_math::sin</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::sin(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute sine over an implementation-defined range, where <code>x</code> is an angle in radians.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathsqrt">native_math::sqrt</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::sqrt(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute square root over an implementation-defined range.
The maximum error is implementation-defined.</p>
</div>
</div>
<div class="sect4">
<h5 id="native_mathtan">native_math::tan</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn native_math::tan(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute tangent over an implementation-defined range, where <code>x</code> is an angle in radians.
The maximum error is implementation-defined.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="half-functions">3.19.10. Half functions</h4>
<div class="paragraph">
<p>This section describes the following functions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A subset of functions from previous sections that are defined in the <code>cl::half_math</code> namespace.
These functions are implemented with a minimum of 10-bits of accuracy i.e. an ULP value &lt;= 8192 ulp.</p>
</li>
<li>
<p>half functions for following basic operations: divide and reciprocal.</p>
</li>
<li>
<p>Support for denormal values is optional for half_math:: functions. The <code>half_math::</code> functions may return any result allowed by the <a href="#edge-case-behavior-in-flush-to-zero-mode"><em>Edge Case Behavior in Flush To Zero Mode</em></a> section, even when <code>-cl-denorms-are-zero</code> is not in force.</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="half_mathcos">half_math::cos</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::cos(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute cosine.
<code>x</code> is an angle in radians and it must be in the range -2<sup>16</sup> &#8230;&#8203; +2<sup>16</sup>.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathdivide">half_math::divide</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::divide(floatn x, floatn y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x / y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathexp">half_math::exp</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::exp(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the base e exponential of <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathexp2">half_math::exp2</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::exp2(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the base 2 exponential of <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathexp10">half_math::exp10</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::exp10(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute the base 10 exponential of <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathlog">half_math::log</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::log(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute natural logarithm.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathlog2">half_math::log2</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::log2(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute a base 2 logarithm.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathlog10">half_math::log10</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::log10(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute a base 10 logarithm.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathpowr">half_math::powr</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::powr(floatn x, floatn y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute <code>x</code> to the power <code>y</code>, where <code>x</code> is <code>&gt;= 0</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathrecip">half_math::recip</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::recip(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute reciprocal.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathrsqrt">half_math::rsqrt</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::rsqrt(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute inverse square root.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathsin">half_math::sin</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::sin(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute sine.
<code>x</code> is an angle in radians and it must be in the range -2<sup>16</sup> &#8230;&#8203; +2<sup>16</sup>.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathsqrt">half_math::sqrt</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::sqrt(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute square root.</p>
</div>
</div>
<div class="sect4">
<h5 id="half_mathtan">half_math::tan</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>floatn half_math::tan(floatn x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compute tangent.
<code>x</code> is an angle in radians and it must be in the range -2<sup>16</sup> &#8230;&#8203; +2<sup>16</sup>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="floating-point-pragmas">3.19.11. Floating-point pragmas</h4>
<div class="paragraph">
<p>The <code>FP_CONTRACT</code> pragma can be used to allow (if the state is on) or disallow (if the state is off) the implementation to contract expressions.
Each pragma can occur either outside external declarations or preceding all explicit declarations and statements inside a compound statement.
When outside external declarations, the pragma takes effect from its occurrence until another <code>FP_CONTRACT</code> pragma is encountered, or until the end of the translation unit.
When inside a compound statement, the pragma takes effect from its occurrence until another <code>FP_CONTRACT</code> pragma is encountered (including within a nested compound statement), or until the end of the compound statement; at the end of a compound statement the state for the pragma is restored to its condition just before the compound statement.
If this pragma is used in any other context, the behavior is undefined.</p>
</div>
<div class="paragraph">
<p>The pragma definition to set <code>FP_CONTRACT</code> is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#pragma OPENCL FP_CONTRACT on-off-switch
// on-off-switch is one of: ON, OFF or DEFAULT.</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>DEFAULT</code> value is <code>ON</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="integer-functions">3.20. Integer Functions</h3>
<div class="paragraph">
<p>This section describes the OpenCL C++ library integer functions that take scalar or vector arguments.
Vector versions of integer functions operate component-wise.
Descriptions are always per-component.</p>
</div>
<div class="paragraph">
<p>Here <code>gentype</code> matches: <code>char<em>n</em></code>, <code>uchar<em>n</em></code>, <code>short<em>n</em></code>, <code>ushort<em>n</em></code>, <code>int<em>n</em></code>, <code>uint<em>n</em></code>, <code>long<em>n</em></code> and <code>ulong<em>n</em></code>.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_integer-synopsis">3.20.1. Header &lt;opencl_integer&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
//bitwise functions
gentype clz(gentype x);
gentype ctz(gentype x);
gentype popcount(gentype x);
gentype rotate(gentype v, gentype i);
shortn upsample(charn hi, ucharn lo);
ushortn upsample(ucharn hi, ucharn lo);
intn upsample(shortn hi, ushortn lo);
uintn upsample(ushortn hi, ushortn lo);
longn upsample(intn hi, uintn lo);
ulongn upsample(uintn hi, uintn lo);
//numeric functions
ugentype abs(gentype x);
ugentype abs_diff(gentype x, gentype y);
gentype add_sat(gentype x, gentype y);
gentype hadd(gentype x, gentype y);
gentype rhadd(gentype x, gentype y);
gentype clamp(gentype x, gentype minval, gentype maxval);
gentype clamp(gentype x, sgentype minval, sgentype maxval);
gentype mad_hi(gentype a, gentype b, gentype c);
gentype mad_sat(gentype a, gentype b, gentype c);
gentype max(gentype x, gentype y);
gentype max(gentype x, sgentype y);
gentype min(gentype x, gentype y);
gentype min(gentype x, sgentype y);
gentype mul_hi(gentype x, gentype y);
gentype sub_sat(gentype x, gentype y);
//24-bits functions
intn mad24(intn x, intn y, intn z);
uintn mad24(uintn x, uintn y, uintn z);
intn mul24(intn x, intn y);
uintn mul24(uintn x, uintn y);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="bitwise-operations">3.20.2. Bitwise operations</h4>
<div class="sect4">
<h5 id="clz">clz</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype clz(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of leading 0-bits in <code>x</code>, starting at the most significant bit position.
If <code>x</code> is <code>0</code>, returns the size in bits of the type of <code>x</code> or component type of <code>x</code>, if <code>x</code> is a vector.</p>
</div>
</div>
<div class="sect4">
<h5 id="ctz">ctz</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype ctz(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the count of trailing 0-bits in <code>x</code>.
If <code>x</code> is <code>0</code>, returns the size in bits of the type of <code>x</code> or component type of <code>x</code>, if <code>x</code> is a vector.</p>
</div>
</div>
<div class="sect4">
<h5 id="rotate">rotate</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype rotate(gentype v, gentype i);</code></pre>
</div>
</div>
<div class="paragraph">
<p>For each element in <code>v</code>, the bits are shifted left by the number of bits given by the corresponding element in <code>i</code> (subject to usual shift modulo rules described in the <a href="#expressions"><em>Expressions</em></a> section).
Bits shifted off the left side of the element are shifted back in from the right.</p>
</div>
</div>
<div class="sect4">
<h5 id="upsample">upsample</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>shortn upsample(charn hi, ucharn lo);
ushortn upsample(ucharn hi, ucharn lo);
intn upsample(shortn hi, ushortn lo);
uintn upsample(ushortn hi, ushortn lo);
longn upsample(intn hi, uintn lo);
ulongn upsample(uintn hi, uintn lo);</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>result[i] = ((short)hi[i] &lt;&lt; 8) | lo[i]</code></p>
</div>
<div class="paragraph">
<p><code>result[i] = ((ushort)hi[i] &lt;&lt; 8) | lo[i]</code></p>
</div>
<div class="paragraph">
<p><code>result[i] = ((int)hi[i] &lt;&lt; 16) | lo[i]</code></p>
</div>
<div class="paragraph">
<p><code>result[i] = ((uint)hi[i] &lt;&lt; 16) | lo[i]</code></p>
</div>
<div class="paragraph">
<p><code>result[i] = ((long)hi[i] &lt;&lt; 32) | lo[i]</code></p>
</div>
<div class="paragraph">
<p><code>result[i] = ((ulong)hi[i] &lt;&lt; 32) | lo[i]</code></p>
</div>
</div>
<div class="sect4">
<h5 id="popcount">popcount</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype popcount(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the number of non-zero bits in <code>x</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="numeric-functions">3.20.3. Numeric functions</h4>
<div class="sect4">
<h5 id="abs">abs</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>ugentype abs(gentype x);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>|x|</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="abs_diff">abs_diff</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>ugentype abs_diff(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>|x - y|</code> without modulo overflow.</p>
</div>
</div>
<div class="sect4">
<h5 id="add_sat">add_sat</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype add_sat(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>x + y</code> and saturates the result.</p>
</div>
</div>
<div class="sect4">
<h5 id="hadd">hadd</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype hadd(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>(x + y) &gt;&gt; 1</code>.
The intermediate sum does not modulo overflow.</p>
</div>
</div>
<div class="sect4">
<h5 id="rhadd">rhadd</h5>
<div class="paragraph">
<p><code>rhadd</code> <a id="ftnref23"></a> <a href="#ftn23">[23]</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype rhadd(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>(x + y + 1) &gt;&gt; 1</code>.
The intermediate sum does not modulo overflow.</p>
</div>
</div>
<div class="sect4">
<h5 id="clamp">clamp</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype clamp(gentype x, gentype minval, gentype maxval);
gentype clamp(gentype x, sgentype minval, sgentype maxval);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>min(max(x, minval), maxval)</code>.</p>
</div>
<div class="paragraph">
<p>Results are undefined if <code>minval &gt; maxval</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="mad_hi">mad_hi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype mad_hi(gentype a, gentype b, gentype c);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>mul_hi(a, b) + c</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="mad_sat">mad_sat</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype mad_sat(gentype a, gentype b, gentype c);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>a * b + c</code> and saturates the result.</p>
</div>
</div>
<div class="sect4">
<h5 id="max">max</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype max(gentype x, gentype y);
gentype max(gentype x, sgentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>y</code> if <code>x &lt; y</code>, otherwise it returns <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="min">min</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype min(gentype x, gentype y);
gentype min(gentype x, sgentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>y</code> if <code>y &lt; x</code>, otherwise it returns <code>x</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="mul_hi">mul_hi</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype mul_hi(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Computes <code>x * y</code> and returns the high half of the product of <code>x</code> and <code>y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="sub_sat">sub_sat</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype sub_sat(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>x - y</code> and saturates the result.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="bits-operations">3.20.4. 24-bits operations</h4>
<div class="paragraph">
<p>In this section fast integer functions are described that can be used for optimizing performance of kernels.</p>
</div>
<div class="sect4">
<h5 id="mad24">mad24</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>intn mad24(intn x, intn y, intn z);
uintn mad24(uintn x, uintn y, uintn z);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiply two 24-bit integer values <code>x</code> and <code>y</code> and add the 32-bit integer result to the 32-bit integer <code>z</code>.
Refer to definition of mul24 to see how the 24-bit integer multiplication is performed.</p>
</div>
<div id="mul24" class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>intn mul24(intn x, intn y);
uintn mul24(uintn x, uintn y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiply two 24-bit integer values <code>x</code> and <code>y</code>.
<code>x</code> and <code>y</code> are 32-bit integers but only the low 24-bits are used to perform the multiplication.
<code>mul24</code> should only be used when values in <code>x</code> and <code>y</code> are in the range [-2<sup>23</sup>, 2<sup>23</sup>-1] if <code>x</code> and <code>y</code> are signed integers and in the range [0, 2<sup>24</sup>-1] if <code>x</code> and <code>y</code> are unsigned integers.
If <code>x</code> and <code>y</code> are not in this range, the multiplication result is implementation-defined.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="relational-functions">3.21. Relational Functions</h3>
<div class="paragraph">
<p>The relational and equality operators (<code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, <code>&gt;=</code>, <code>!=</code>, <code>==</code>) can be used with scalar and vector built-in types and produce a scalar or vector boolean result respectively as described in the <a href="#expressions"><em>Expressions</em></a> section.</p>
</div>
<div class="paragraph">
<p>Here <code>gentype</code> matches: <code>char<em>n</em></code>, <code>uchar<em>n</em></code>, <code>short<em>n</em></code>, <code>ushort<em>n</em></code>, <code>int<em>n</em></code>, <code>uint<em>n</em></code>, <code>long<em>n</em></code>, <code>ulong<em>n</em></code>, <code>half<em>n</em></code> <a id="ftnref4"></a> <a href="#ftn4">[4]</a>, <code>float<em>n</em></code> and <code>double<em>n</em></code> <a id="ftnref18"></a> <a href="#ftn18">[18]</a>.</p>
</div>
<div class="paragraph">
<p>The relational functions <code>isequal</code>, <code>isgreater</code>, <code>isgreaterequal</code>, <code>isless</code>, <code>islessequal</code>, and <code>islessgreater</code> always return <code>false</code> if either argument is not a number (NaN).
<code>isnotequal</code> returns <code>true</code> if one or both arguments are not a number (NaN).</p>
</div>
<div class="sect3">
<h4 id="header-opencl_relational-synopsis">3.21.1. Header &lt;opencl_relational&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
#ifdef cl_khr_fp16
booln isequal(halfn x, halfn y);
booln isnotequal(halfn x, halfn y);
booln isgreater(halfn x, halfn y);
booln isgreaterequal(halfn x, halfn y);
booln isless(halfn x, halfn y);
booln islessequal(halfn x, halfn y);
booln islessgreater(halfn x, halfn y);
booln isordered(halfn x, halfn y);
booln isunordered(halfn x, halfn y);
booln isfinite(halfn t);
booln isinf(halfn t);
booln isnan(halfn t);
booln isnormal(halfn t);
booln signbit(halfn t);
#endif
#ifdef cl_khr_fp64
booln isequal(doublen x, doublen y);
booln isnotequal(doublen x, doublen y);
booln isgreater(doublen x, doublen y);
booln isgreaterequal(doublen x, doublen y);
booln isless(doublen x, doublen y);
booln islessequal(doublen x, doublen y);
booln islessgreater(doublen x, doublen y);
booln isordered(doublen x, doublen y);
booln isunordered(doublen x, doublen y);
booln isfinite(doublen t);
booln isinf(doublen t);
booln isnan(doublen t);
booln isnormal(doublen t);
booln signbit(doublen t);
#endif //cl_khr_fp64
booln isequal(floatn x, floatn y);
booln isnotequal(floatn x, floatn y);
booln isgreater(floatn x, floatn y);
booln isgreaterequal(floatn x, floatn y);
booln isless(floatn x, floatn y);
booln islessequal(floatn x, floatn y);
booln islessgreater(floatn x, floatn y);
booln isordered(floatn x, floatn y);
booln isunordered(floatn x, floatn y);
booln isfinite(floatn t);
booln isinf(floatn t);
booln isnan(floatn t);
booln isnormal(floatn t);
booln signbit(floatn t);
bool any(booln t);
bool all(booln t);
gentype bitselect(gentype a, gentype b, gentype c);
gentype select(gentype a, gentype b, booln c);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="comparison-operations">3.21.2. Comparison operations</h4>
<div class="sect4">
<h5 id="isequal">isequal</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isequal(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the component-wise compare of <code>x == y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="isnotequal">isnotequal</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isnotequal(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the component-wise compare of <code>x != y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="isgreater">isgreater</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isgreater(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the component-wise compare of <code>x &gt; y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="isgreaterequal">isgreaterequal</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isgreaterequal(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the component-wise compare of <code>x &gt;= y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="isless">isless</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isless(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the component-wise compare of <code>x &lt; y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="islessequal">islessequal</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln islessequal(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the component-wise compare of <code>x &lt;= y</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="islessgreater">islessgreater</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln islessgreater(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns the component-wise compare of <code>(x &lt; y) || (x &gt; y)</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="test-operations">3.21.3. Test operations</h4>
<div class="sect4">
<h5 id="isfinite">isfinite</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isfinite(gentype t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test for finite value.</p>
</div>
</div>
<div class="sect4">
<h5 id="isinf">isinf</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isinf(gentype t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test for infinity value (positive or negative) .</p>
</div>
</div>
<div class="sect4">
<h5 id="isnan">isnan</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isnan(gentype t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test for a NaN.</p>
</div>
</div>
<div class="sect4">
<h5 id="isnormal">isnormal</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isnormal(gentype t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test for a normal value.</p>
</div>
</div>
<div class="sect4">
<h5 id="isordered">isordered</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isordered(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test if arguments are ordered.
<code>isordered()</code> takes arguments <code>x</code> and <code>y</code>, and returns the result of <code>isequal(x, x) &amp;&amp; isequal(y, y)</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="isunordered">isunordered</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln isunordered(gentype x, gentype y);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test if arguments are unordered.
<code>isunordered()</code> takes arguments <code>x</code> and <code>y</code>, returning <code>true</code> if <code>x</code> or <code>y</code> is NaN, and <code>false</code> otherwise.</p>
</div>
</div>
<div class="sect4">
<h5 id="signbit">signbit</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>booln signbit(gentype t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test for sign bit.
Returns a <code>true</code> if the sign bit in the float is set else returns <code>false</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="any">any</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool any(booln t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>true</code> if any component of <code>t</code> is <code>true</code>; otherwise returns <code>false</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="all">all</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>bool all(booln t);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Returns <code>true</code> if all components of <code>t</code> are <code>true</code>; otherwise returns <code>false</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="select-operations">3.21.4. Select operations</h4>
<div class="sect4">
<h5 id="bitselect">bitselect</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype bitselect(gentype a, gentype b, gentype c);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Each bit of the result is the corresponding bit of <code>a</code> if the corresponding bit of <code>c</code> is <code>0</code>.
Otherwise it is the corresponding bit of <code>b</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="select">select</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype select(gentype a, gentype b, booln c);</code></pre>
</div>
</div>
<div class="paragraph">
<p>For each component of a vector type,</p>
</div>
<div class="paragraph">
<p><code>result[i] = c[i] ? b[i] : a[i]</code>.</p>
</div>
<div class="paragraph">
<p>For a scalar type, <code>result = c ? b : a</code>.</p>
</div>
<div class="paragraph">
<p><code>booln</code> must have the same number of elements as <code>gentype</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vector-data-load-and-store-functions">3.22. Vector Data Load and Store Functions</h3>
<div class="paragraph">
<p>Functions described in this section allow user to read and write vector types from a pointer to memory.
The results of these functions are undefined if the address being read from or written to is not correctly aligned as described in following subsections.</p>
</div>
<div class="paragraph">
<p>Here <code>gentype</code> matches: <code>char<em>n</em></code>, <code>uchar<em>n</em></code>, <code>short<em>n</em></code>, <code>ushort<em>n</em></code>, <code>int<em>n</em></code>, <code>uint<em>n</em></code>, <code>long<em>n</em></code>, <code>ulong<em>n</em></code>, <code>half<em>n</em></code> <a id="ftnref4"></a> <a href="#ftn4">[4]</a>, <code>float<em>n</em></code> and <code>double<em>n</em></code> <a id="ftnref18"></a> <a href="#ftn18">[18]</a>.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_vector_load_store">3.22.1. Header &lt;opencl_vector_load_store&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
//basic load &amp; store
template &lt;size_t N, class T&gt;
make_vector_t&lt;T, N&gt; vload(size_t offset, const T* p);
template &lt;size_t N, class T&gt;
make_vector_t&lt;T, N&gt; vload(size_t offset, const constant_ptr&lt;T&gt; p);
template &lt;class T&gt;
void vstore(T data, size_t offset, vector_element_t&lt;T&gt;* p);
//half load &amp; store
template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vload_half(size_t offset, const half* p);
template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vload_half(size_t offset, const constant_ptr&lt;half&gt; p);
template &lt;rounding_mode rmode = rounding_mode::rte, class T&gt;
void vstore_half(T data, size_t offset, half* p);
//half array load &amp; store
template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vloada_half(size_t offset, const half* p);
template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vloada_half(size_t offset, const constant_ptr&lt;half&gt; p);
template &lt;rounding_mode rmode = rounding_mode::rte, class T&gt;
void vstorea_half(T data, size_t offset, half* p);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="basic-load-store">3.22.2. Basic load &amp; store</h4>
<div class="sect4">
<h5 id="vload">vload</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;size_t N, class T&gt;
make_vector_t&lt;T, N&gt; vload(size_t offset, const T* p);
template &lt;size_t N, class T&gt;
make_vector_t&lt;T, N&gt; vload(size_t offset, const constant_ptr&lt;T&gt; p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Return <code>sizeof(make_vector_t&lt;T, N&gt;)</code> bytes of data read from address <code>(p + (offset * n))</code>.</p>
</div>
<div class="paragraph">
<p>Requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The address computed as <code>(p+(offset*n))</code> must be 8-bit aligned if <code>T</code> is <code>char</code>, or <code>uchar</code>; 16-bit aligned if <code>T</code> is <code>short</code>, <code>ushort</code>, or <code>half</code> <a href="#ftn4">[4]</a>; 32-bit aligned if <code>T</code> is <code>int</code>, <code>uint</code>, or <code>float</code>; and 64-bit aligned if <code>T</code> is <code>long</code>, <code>ulong</code>, or <code>double</code> <a href="#ftn18">[18]</a>.</p>
</li>
<li>
<p><code>vload</code> function is only defined for n = 2, 3, 4, 8, 16.</p>
</li>
<li>
<p><code>half</code> version is only defined if the <strong>cl_khr_fp16</strong> extension is supported.</p>
</li>
<li>
<p><code>double</code> version is only defined if double precision is supported.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="vstore">vstore</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;class T&gt;
void vstore(T data, size_t offset, vector_element_t&lt;T&gt;* p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Write <code>sizeof(T)</code> bytes given by data to address <code>(p+(offset*n))</code>.</p>
</div>
<div class="paragraph">
<p>Requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The address computed as <code>(p+(offset*n))</code> must be 8-bit aligned if <code>T</code> is <code>char</code>, or <code>uchar</code>; 16-bit aligned if <code>T</code> is <code>short</code>, <code>ushort</code>, or <code>half</code> <a href="#ftn4">[4]</a>; 32-bit aligned if <code>T</code> is <code>int</code>, <code>uint</code>, or <code>float</code>; and 64-bit aligned if <code>T</code> is <code>long</code>, <code>ulong</code>, or <code>double</code> <a href="#ftn18">[18]</a>.</p>
</li>
<li>
<p><code>vstore</code> function is only defined for n = 2, 3, 4, 8, 16.</p>
</li>
<li>
<p><code>half</code> version is only defined if the <strong>cl_khr_fp16</strong> extension is supported.</p>
</li>
<li>
<p><code>double</code> version is only defined if double precision is supported.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect3">
<h4 id="half-vload-vstore">3.22.3. half vload &amp; vstore</h4>
<div class="sect4">
<h5 id="vload_half">vload_half</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vload_half(size_t offset, const half* p);
template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vload_half(size_t offset, const constant_ptr&lt;half&gt; p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Read <code>sizeof(halfn)</code> bytes of data from address <code>(p+(offset*n))</code>.
The data read is interpreted as a <code>halfn</code> value.
The <code>halfn</code> value read is converted to a <code>float</code> value and the <code>floatn</code> value is returned.</p>
</div>
<div class="paragraph">
<p>Requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The read address computed as <code>(p+(offset*n))</code> must be 16-bit aligned.</p>
</li>
<li>
<p><code>vload_half</code> function is only defined for n = 1, 2, 3, 4, 8, 16.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="vstore_half">vstore_half</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;rounding_mode rmode = rounding_mode::rte, class T&gt;
void vstore_half(T data, size_t offset, half* p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>T</code> value given by data is first converted to a <code>halfn</code> value using the appropriate rounding mode.
The <code>half</code> value is then written to address computed as <code>(p+offset)</code>.</p>
</div>
<div class="paragraph">
<p>Requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The address computed as <code>(p+offset)</code> must be 16-bit aligned.</p>
</li>
<li>
<p><code>T</code> can be <code>floatn</code> or <code>doublen</code> <a href="#ftn18">[18]</a>.</p>
</li>
<li>
<p><code>double</code> version is only defined if double precision is supported.</p>
</li>
<li>
<p><code>vstore_half</code> function is only defined for n = 1, 2, 3, 4, 8, 16.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect3">
<h4 id="half-array-vload-vstore">3.22.4. half array vload &amp; vstore</h4>
<div class="sect4">
<h5 id="vloada_half">vloada_half</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vloada_half(size_t offset, const half* p);
template &lt;size_t N&gt;
make_vector_t&lt;float, N&gt; vloada_half(size_t offset, const constant_ptr&lt;half&gt; p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>For <code>N</code> = 2, 4, 8 and 16 read <code>sizeof(halfn)</code> bytes of data from address <code>(p+(offset*n))</code>.
The data read is interpreted as a <code>halfn</code> value.
The <code>halfn</code> value read is converted to a <code>floatn</code> value and the <code>floatn</code> value is returned.</p>
</div>
<div class="paragraph">
<p>Requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The address computed as <code>(p+(offset*n))</code> must be aligned to <code>sizeof(halfn)</code> bytes.</p>
</li>
<li>
<p>For n = 3, <code>vloada_half</code> reads a <code>half3</code> from address <code>(p+(offset*4))</code> and returns a <code>float3</code>.
The address computed as <code>(p+(offset*4))</code> must be aligned to <code>sizeof(half)*4</code> bytes.</p>
</li>
<li>
<p><code>vloada_half</code> function is only defined for <code>N</code> = 2, 3, 4, 8, 16.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="vstorea_half">vstorea_half</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>template &lt;rounding_mode rmode = rounding_mode::rte, class T&gt;
void vstorea_half(T data, size_t offset, half* p);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>T</code> value is converted to a <code>halfn</code> value using the appropriate rounding mode.
For n = 2, 4, 8 or 16, the halfn value is written to the address computed as <code>(p+(offset*n))</code>.
For n = 3, the <code>half3</code> value is written to the address computed as <code>(p+(offset*4))</code>.
The address computed as <code>(p+(offset*4))</code> must be aligned to <code>sizeof(half)*4</code> bytes.</p>
</div>
<div class="paragraph">
<p>Requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The address computed as <code>(p+(offset* n))</code> must be aligned to <code>sizeof(halfn)</code> bytes.</p>
</li>
<li>
<p>For n = 3, the address computed as <code>(p+(offset*4))</code> must be aligned to <code>sizeof(half)*4</code> bytes.</p>
</li>
<li>
<p><code>T</code> can be <code>floatn</code> or <code>doublen</code> <a href="#ftn18">[18]</a>.</p>
</li>
<li>
<p><code>double</code> version is only defined if double precision is supported.</p>
</li>
<li>
<p><code>vstorea_half</code> function is only defined for n = 2, 3, 4, 8, 16.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="printf">3.23. printf</h3>
<div class="paragraph">
<p>The OpenCL C++ programming language implements the <code>printf</code> <a id="ftnref24"></a> <a href="#ftn24">[24]</a> function.
This function is defined in header <em>&lt;opencl_printf&gt;</em>.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_printf-synopsis">3.23.1. Header &lt;opencl_printf&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
int printf(const char *format, ...);
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="printf-function">3.23.2. printf function</h4>
<div class="sect4">
<h5 id="printf-1">printf</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>int printf(const char *format, ...);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>printf</code> built-in function writes output to an implementation-defined stream such as stdout under control of the string pointed to by <code>format</code> that specifies how subsequent arguments are converted for output.
If there are insufficient arguments for the format, the behavior is undefined.
If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored.
The <code>printf</code> function returns when the end of the format string is encountered.</p>
</div>
<div class="paragraph">
<p><code>printf</code> returns 0 if it was executed successfully and -1 otherwise.</p>
</div>
<div class="paragraph">
<p>Limitations:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Format must be known at compile time; otherwise it will be a compile time error.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="printf-output-synchronization">printf output synchronization</h5>
<div class="paragraph">
<p>When the event that is associated with a particular kernel invocation is completed, the output of all <code>printf()</code> calls executed by this kernel invocation is flushed to the implementation-defined output stream.
Calling <code>clFinish</code> on a host command queue flushes all pending output by <code>printf</code> in previously enqueued and completed commands to the implementation-defined output stream.
In the case that <code>printf</code> is executed from multiple work-items concurrently, there is no guarantee of ordering with respect to written data.
For example, it is valid for the output of a work-item with a global id (0,0,1) to appear intermixed with the output of a work-item with a global id (0,0,4) and so on.</p>
</div>
</div>
<div class="sect4">
<h5 id="printf-format-string">printf format string</h5>
<div class="paragraph">
<p>The format shall be a character sequence, beginning and ending in its initial shift state.
The format is composed of zero or more directives: ordinary characters (not <strong>%</strong>), which are copied unchanged to the output stream; and conversion specifications, each of which results in fetching zero or more subsequent arguments, converting them, if applicable, according to the corresponding conversion specifier, and then writing the result to the output stream.
The format is in the <code>constant</code> address space and must be resolvable at compile time i.e. cannot be dynamically created by the executing program, itself.</p>
</div>
<div class="paragraph">
<p>Each conversion specification is introduced by the character <strong>%</strong>.
After the <strong>%</strong>, the following appear in sequence:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Zero or more <em>flags</em> (in any order) that modify the meaning of the conversion specification.</p>
</li>
<li>
<p>An optional minimum <em>field width</em>.
If the converted value has fewer characters than the field width, it is padded with spaces (by default) on the left (or right, if the left adjustment flag, described later, has been given) to the field width.
The field width takes the form of a nonnegative decimal integer. <a id="ftnref25"></a> <a href="#ftn25">[25]</a></p>
</li>
<li>
<p>An optional <em>precision</em> that gives the minimum number of digits to appear for the <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em>, and <em>X</em> conversions, the number of digits to appear after the decimal-point character for <em>a</em>, <em>A</em>, <em>e</em>, <em>E</em>, <em>f</em>, and <em>F</em> conversions, the maximum number of significant digits for the <em>g</em> and <em>G</em> conversions, or the maximum number of bytes to be written for <em>s</em> conversions.
The precision takes the form of a period (.) followed by an optional decimal integer; if only the period is specified, the precision is taken as zero.
If a precision appears with any other conversion specifier, the behavior is undefined.</p>
</li>
<li>
<p>An optional <em>vector specifier</em>.</p>
</li>
<li>
<p>A <em>length modifier</em> that specifies the size of the argument.
The <em>length modifier</em> is required with a vector specifier and together specifies the vector type.
Implicit conversions between vector types are disallowed (as per the <a href="#implicit-type-conversions"><em>Implicit Type Conversions</em></a> section).
If the <em>vector specifier</em> is not specified, the <em>length modifier</em> is optional.</p>
</li>
<li>
<p>A <em>conversion specifier</em> character that specifies the type of conversion to be applied.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The flag characters and their meanings are:</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
<em>-</em>
</td>
<td class="hdlist2">
<p>The result of the conversion is left-justified within the field.
(It is right-justified if this flag is not specified.)</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>+</em>
</td>
<td class="hdlist2">
<p>The result of a signed conversion always begins with a plus or minus sign.
(It begins with a sign only when a negative value is converted if this flag is not specified.) <a id="ftnref26"></a> <a href="#ftn26">[26]</a></p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>space</em>
</td>
<td class="hdlist2">
<p>If the first character of a signed conversion is not a sign, or if a signed conversion results in no characters, a space is prefixed to the result.
If the <em>space</em> and <em>+</em> flags both appear, the <em>space</em> flag is ignored.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>#</em>
</td>
<td class="hdlist2">
<p>The result is converted to an "alternative form".
For <em>o</em> conversion, it increases the precision, if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are both 0, a single 0 is printed).
For <em>x</em> (or <em>X</em>) conversion, a nonzero result has <strong>0x</strong> (or <strong>0X</strong>) prefixed to it.
For <em>a</em>, <em>A</em>, <em>e</em>, <em>E</em>, <em>f</em>, <em>F</em>, <em>g</em> and <em>G</em> conversions, the result of converting a floating-point number always contains a decimal-point character, even if no digits follow it.
(Normally, a decimal-point character appears in the result of these conversions only if a digit follows it.) For <em>g</em> and <em>G</em> conversions, trailing zeros are <em>not</em> removed from the result.
For other conversions, the behavior is undefined.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>0</em>
</td>
<td class="hdlist2">
<p>For <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em>, <em>X</em>, <em>a</em>, <em>A</em>, <em>e</em>, <em>E</em>, <em>f</em>, <em>F</em>, <em>g</em> and <em>G</em> conversions, leading zeros (following any indication of sign or base) are used to pad to the field width rather than performing space padding, except when converting an infinity or NaN.
If the <em>0</em> and <em>-</em> flags both appear, the <em>0</em> flag is ignored.
For <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em>, and <em>X</em> conversions, if a precision is specified, the <em>0</em> flag is ignored.
For other conversions, the behavior is undefined.</p>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The vector specifier and its meaning is:</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
<em>vn</em>
</td>
<td class="hdlist2">
<p>Specifies that a following <em>a</em>, <em>A</em>, <em>e</em>, <em>E</em>, <em>f</em>, <em>F</em>, <em>g</em>, <em>G</em>, <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em> or <em>X</em> conversion specifier applies to a vector argument, where <em>n</em> is the size of the vector and must be 2, 3, 4, 8 or 16.</p>
<div class="paragraph">
<p>The vector value is displayed in the following general form:</p>
</div>
<div class="paragraph">
<p>value1 <em>C</em> value2 <em>C</em> &#8230;&#8203; <em>C</em> value<em>n</em></p>
</div>
<div class="paragraph">
<p>where <em>C</em> is a separator character.
The value for this separator character is a comma.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If the vector specifier is not used, the length modifiers and their meanings are:</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
<em>hh</em>
</td>
<td class="hdlist2">
<p>Specifies that a following <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em>, or <em>X</em> conversion specifier applies to a <code>char</code> or <code>uchar</code> argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to <code>char</code> or <code>uchar</code> before printing).</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>h</em>
</td>
<td class="hdlist2">
<p>Specifies that a following <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em> or <em>X</em> conversion specifier applies to a <code>short</code> or <code>ushort</code> argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to <code>short</code> or <code>ushort</code> before printing).</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>l</em> (ell)
</td>
<td class="hdlist2">
<p>Specifies that a following <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em> or <em>X</em> conversion specifier applies to a <code>long</code> or <code>ulong</code> argument.
The <em>l</em> modifier is supported by the full profile.
For the embedded profile, the <em>l</em> modifier is supported only if 64-bit integers are supported by the device.</p>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If the vector specifier is used, the length modifiers and their meanings are:</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
<em>hh</em>
</td>
<td class="hdlist2">
<p>Specifies that a following <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em> or <em>X</em> conversion specifier applies to a <code>char<em>n</em></code> or <code>uchar<em>n</em></code> argument (the argument will not be promoted).</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>h</em>
</td>
<td class="hdlist2">
<p>Specifies that a following <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em> or <em>X</em> conversion specifier applies to a <code>short<em>n</em></code> or <code>ushort<em>n</em></code> argument (the argument will not be promoted); that a following <em>a</em>, <em>A</em>, <em>e</em>, <em>E</em>, <em>f</em>, <em>F</em>, <em>g</em> or <em>G</em> conversion specifier applies to a <code>half<em>n</em></code> argument.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>hl</em>
</td>
<td class="hdlist2">
<p>This modifier can only be used with the vector specifier.
Specifies that a following <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em> or <em>X</em> conversion specifier applies to an <code>int<em>n</em></code> or <code>uint<em>n</em></code> argument; that a following <em>a</em>, <em>A</em>, <em>e</em>, <em>E</em>, <em>f</em>, <em>F</em>, <em>g</em> or <em>G</em> conversion specifier applies to a <code>float<em>n</em></code> argument.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>l</em> (ell)
</td>
<td class="hdlist2">
<p>Specifies that a following <em>d</em>, <em>i</em>, <em>o</em>, <em>u</em>, <em>x</em> or <em>X</em> conversion specifier applies to a <code>long<em>n</em></code> or <code>ulong<em>n</em></code> argument; that a following <em>a</em>, <em>A</em>, <em>e</em>, <em>E</em>, <em>f</em>, <em>F</em>, <em>g</em> or <em>G</em> conversion specifier applies to a <code>double<em>n</em></code> argument.
The <em>l</em> modifier is supported by the full profile.
For the embedded profile, the <em>l</em> modifier is supported only if 64-bit integers or double-precision floating-point are supported by the device.</p>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If a vector specifier appears without a length modifier, the behavior is undefined.
The vector data type described by the vector specifier and length modifier must match the data type of the argument; otherwise the behavior is undefined.</p>
</div>
<div class="paragraph">
<p>If a length modifier appears with any conversion specifier other than as specified above, the behavior is undefined.</p>
</div>
<div class="paragraph">
<p>The conversion specifiers and their meanings are:</p>
</div>
<div class="hdlist">
<table>
<tr>
<td class="hdlist1">
<em>d</em>,&#160;<em>i</em>
</td>
<td class="hdlist2">
<p>The <code>int</code>, <code>char<em>n</em></code>, <code>short<em>n</em></code>, <code>int<em>n</em></code> or <code>long<em>n</em></code> argument is converted to signed decimal in the style <em>[-]dddd</em>.
The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros.
The default precision is 1. The result of converting a zero value with a precision of zero is no characters.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>o</em>,&#160;<em>u</em>, <em>x</em>,&#160;<em>X</em>
</td>
<td class="hdlist2">
<p>The <code>uint</code>, <code>uchar<em>n</em></code>, <code>ushort<em>n</em></code>, <code>uint<em>n</em></code> or <code>ulong<em>n</em></code> argument is converted to unsigned octal (<em>o</em>), unsigned decimal (<em>u</em>), or unsigned hexadecimal notation (<em>x</em> or <em>X</em>) in the style <em>dddd</em>; the letters <strong>abcdef</strong> are used for <em>x</em> conversion and the letters <strong>ABCDEF</strong> for <em>X</em> conversion.
The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros.
The default precision is 1.
The result of converting a zero value with a precision of zero is no characters.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>f</em>,&#160;<em>F</em>
</td>
<td class="hdlist2">
<p>A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing a floating-point number is converted to decimal notation in the style <em>[-]ddd</em><strong>.</strong><em>ddd</em>, where the number of digits after the decimal-point character is equal to the precision specification.
If the precision is missing, it is taken as 6; if the precision is zero and the <em>#</em> flag is not specified, no decimal-point character appears.
If a decimal-point character appears, at least one digit appears before it.
The value is rounded to the appropriate number of digits.
A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing an infinity is converted in one of the styles <em>[-]</em><strong>inf</strong> or <em>[-]</em><strong>infinity</strong> - which style is implementation-defined.
A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing a NaN is converted in one of the styles <em>[-]</em><strong>nan</strong> or <em>[-]</em><strong>nan</strong>(<em>n-char-sequence</em>) - which style, and the meaning of any <em>n-char-sequence</em>, is implementation-defined.
The <em>F</em> conversion specifier produces <strong>INF</strong>, <strong>INFINITY</strong>, or <strong>NAN</strong> instead of <strong>inf</strong>, <strong>infinity</strong>, or <strong>nan</strong>, respectively. <a id="ftnref27"></a> <a href="#ftn27">[27]</a></p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>e</em>,&#160;<em>E</em>
</td>
<td class="hdlist2">
<p>A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing a floating-point number is converted in the style <em>[-]d</em><strong>.</strong><em>ddd</em><strong>e</strong><em>±dd</em>, where there is one digit (which is nonzero if the argument is nonzero) before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero and the <em>#</em> flag is not specified, no decimal-point character appears.
The value is rounded to the appropriate number of digits.
The <em>E</em> conversion specifier produces a number with <strong>E</strong> instead of <strong>e</strong> introducing the exponent.
The exponent always contains at least two digits, and only as many more digits as necessary to represent the exponent.
If the value is zero, the exponent is zero.
A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing an infinity or NaN is converted in the style of an <em>f</em> or <em>F</em> conversion specifier.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>g</em>,&#160;<em>G</em>
</td>
<td class="hdlist2">
<p>A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing a floating-point number is converted in style <em>f</em> or <em>e</em> (or in style <em>F</em> or <em>E</em> in the case of a <em>G</em> conversion specifier), depending on the value converted and the precision.
Let <em>P</em> equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero.
Then, if a conversion with style <em>E</em> would have an exponent of <em>X</em>:</p>
<div class="ulist">
<ul>
<li>
<p>if <em>P &gt; X ≥ -4, the conversion is with style _f</em> (or <em>F</em>) and precision <em>P - (X + 1)</em>.</p>
</li>
<li>
<p>otherwise, the conversion is with style <em>e</em> (or <em>E</em>) and precision <em>P - 1</em>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Finally, unless the <em>#</em> flag is used, any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining.
A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing an infinity or NaN is converted in the style of an <em>f</em> or <em>F</em> conversion specifier.</p>
</div>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>a</em>,&#160;<em>A</em>
</td>
<td class="hdlist2">
<p>A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing a floating-point number is converted in the style <em>[-]</em><strong>0x</strong><em>h</em><strong>.</strong><em>hhhh</em><strong>p</strong><em>±d</em>, where there is one hexadecimal digit (which is nonzero if the argument is a normalized floating-point number and is otherwise unspecified) before the decimal-point character <a id="ftnref28"></a> <a href="#ftn28">[28]</a> and the number of hexadecimal digits after it is equal to the precision; if the precision is missing, then the precision is sufficient for an exact representation of the value; if the precision is zero and the <em>#</em> flag is not specified, no decimal point character appears.
The letters <strong>abcdef</strong> are used for <em>a</em> conversion and the letters <strong>ABCDEF</strong> for <em>A</em> conversion.
The <em>A</em> conversion specifier produces a number with <strong>X</strong> and <strong>P</strong> instead of <strong>x</strong> and <strong>p</strong>.
The exponent always contains at least one digit, and only as many more digits as necessary to represent the decimal exponent of 2.
If the value is zero, the exponent is zero.
A <code>double</code>, <code>half<em>n</em></code>, <code>float<em>n</em></code> or <code>double<em>n</em></code> argument representing an infinity or NaN is converted in the style of an <em>f</em> or <em>F</em> conversion specifier.</p>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The conversion specifiers <em>e</em>, <em>E</em>, <em>g</em>, <em>G</em>, <em>a</em>, <em>A</em> convert a <code>float</code> or <code>half</code> argument that is a scalar type to a <code>double</code> only if the <code>double</code> data type is supported.
If the <code>double</code> data type is not supported, the argument will be a <code>float</code> instead of a <code>double</code> and the <code>half</code> type will be converted to a <code>float</code>.
</td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>c</em>
</td>
<td class="hdlist2">
<p>The <code>int</code> argument is converted to an <code>uchar</code> and the resulting character is written.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>s</em>
</td>
<td class="hdlist2">
<p>The argument shall be a literal string. <a id="ftnref29"></a> <a href="#ftn29">[29]</a>
Characters from the literal string array are written up to (but not including) the terminating null character.
If the precision is specified, no more than that many bytes are written.
If the precision is not specified or is greater than the size of the array, the array shall contain a null character.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>p</em>
</td>
<td class="hdlist2">
<p>The argument shall be a pointer to <code>void</code>.
The pointer can refer to a memory region in the global, constant, local, private or generic address space.
The value of the pointer is converted to a sequence of printing characters in an implementation-defined manner.</p>
</td>
</tr>
<tr>
<td class="hdlist1">
<em>%</em>
</td>
<td class="hdlist2">
<p>A <strong>%</strong> character is written.
No argument is converted. The complete conversion specification shall be <strong>%%</strong>.</p>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If a conversion specification is invalid, the behavior is undefined.
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.</p>
</div>
<div class="paragraph">
<p>In no case does a nonexistent or small field width cause truncation of a field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result.</p>
</div>
<div class="paragraph">
<p>For <em>a</em> and <em>A</em> conversions, the value is correctly rounded to a hexadecimal floating number with the given precision.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>float4 f = float4(1.0f, 2.0f, 3.0f, 4.0f);
uchar4 uc = uchar4(0xFA, 0xFB, 0xFC, 0xFD);
printf("f4 = %2.2v4hlf\n", f);
printf("uc = %#v4hhx\n", uc);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above two <code>printf</code> calls print the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>f4 = 1.00,2.00,3.00,4.00
uc = 0xfa,0xfb,0xfc,0xfd</pre>
</div>
</div>
<div class="paragraph">
<p>A few examples of valid use cases of <code>printf</code> for the conversion specifier <em>s</em> are given below.
The argument value must be a pointer to a literal string.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_printf&gt;
kernel void my_kernel( ... )
{
cl::printf("%s\n", "this is a test string\n");
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A few examples of invalid use cases of <code>printf</code> for the conversion specifier <em>s</em> are given below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_printf&gt;
kernel void my_kernel(char *s, ... )
{
cl::printf("%s\n", s);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A few examples of invalid use cases of <code>printf</code> where data types given by the vector specifier and length modifier do not match the argument type are given below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_printf&gt;
using namespace cl;
kernel void my_kernel( ... )
{
uint2 ui = uint2(0x12345678, 0x87654321);
printf("unsigned short value = (%#v2hx)\n", ui);
printf("unsigned char value = (%#v2hhx)\n", ui);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="differences-between-opencl-c-and-c14-printf">3.23.3. Differences between OpenCL C++ and C++14 printf</h4>
<div class="ulist">
<ul>
<li>
<p>The <em>l</em> modifier followed by a <em>c</em> conversion specifier or <em>s</em> conversion specifier is not supported by OpenCL C++.</p>
</li>
<li>
<p>The <em>ll</em>, <em>j</em>, <em>z</em>, <em>t</em>, and <em>L</em> length modifiers are not supported by OpenCL C++ but are reserved.</p>
</li>
<li>
<p>The <em>n</em> conversion specifier is not supported by OpenCL C++ but is reserved.</p>
</li>
<li>
<p>OpenCL C++ adds the optional <em>vn</em> vector specifier to support printing of vector types.</p>
</li>
<li>
<p>The conversion specifiers <em>f</em>, <em>F</em>, <em>e</em>, <em>E</em>, <em>g</em>, <em>G</em>, <em>a</em>, <em>A</em> convert a float argument to a double only if the double data type is supported.
Refer to the description of <code>CL_DEVICE_DOUBLE_FP_CONFIG</code> in <em>table 4.3</em>.
If the double data type is not supported, the argument will be a float instead of a double.</p>
</li>
<li>
<p>For the embedded profile, the <em>l</em> length modifier is supported only if 64-bit integers are supported.</p>
</li>
<li>
<p>In OpenCL C++, <code>printf</code> returns 0 if it was executed successfully and -1 otherwise vs. C++14 where <code>printf</code> returns the number of characters printed or a negative value if an output or encoding error occurred.</p>
</li>
<li>
<p>In OpenCL C++, the conversion specifier <em>s</em> can only be used for arguments that are literal strings.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="atomic-operations-library">3.24. Atomic Operations Library</h3>
<div class="paragraph">
<p>The OpenCL C++ programming language implements a subset of the C++14 atomics (refer to <em>chapter 29</em> of the C++14 specification) and synchronization operations.
These operations play a special role in making assignments in one work-item visible to another.
Please note that this chapter only presents synopsis of the atomics library and differences from C++14 specification.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_atomic-synopsis">3.24.1. Header &lt;opencl_atomic&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum memory_order;
enum memory_scope;
template&lt;class T&gt; struct atomic;
// specialization for scalar types T that satisfy cl::is_integral&lt;T&gt;
template&lt;&gt; struct atomic&lt;integral&gt;;
template&lt;class T&gt; struct atomic&lt;T*&gt;;
using atomic_int = atomic&lt;int&gt;;
using atomic_uint = atomic&lt;unsigned int&gt;;
#if defined(cl_khr_int64_base_atomics) &amp;&amp; defined(cl_khr_int64_extended_atomics)
using atomic_long = atomic&lt;long&gt;;
using atomic_ulong = atomic&lt;unsigned long&gt;;
#endif
using atomic_float = atomic&lt;float&gt;;
#if defined(cl_khr_fp64) &amp;&amp;
defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics)
using atomic_double = atomic&lt;double&gt;;
#endif
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__INTPTR_WIDTH__ == 64) ||
__INTPTR_WIDTH__ == 32
using atomic_intptr_t = atomic&lt;intptr_t&gt;;
using atomic_uintptr_t = atomic&lt;uintptr_t&gt;;
#endif
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__SIZE_WIDTH__ == 64) ||
__SIZE_WIDTH__ == 32
using atomic_size_t = atomic&lt;size_t&gt;;
#endif
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__PTRDIFF_WIDTH__ == 64) ||
__PTRDIFF_WIDTH__ == 32
using atomic_ptrdiff_t = atomic&lt;ptrdiff_t&gt;;
#endif
// Please note that all operations taking memory_order as a parameter have,
// in addition to cpp14 specification, additional parameter for memory_scope
template &lt;class T&gt;
bool atomic_is_lock_free(const volatile atomic&lt;T&gt;*) noexcept;
template &lt;class T&gt;
bool atomic_is_lock_free(const atomic&lt;T&gt;*) noexcept;
template &lt;class T&gt;
void atomic_init(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
void atomic_init(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
void atomic_store(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
void atomic_store(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
void atomic_store_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
void atomic_store_explicit(atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_load(const volatile atomic&lt;T&gt;*) noexcept;
template &lt;class T&gt;
T atomic_load(const atomic&lt;T&gt;*) noexcept;
template &lt;class T&gt;
T atomic_load_explicit(const volatile atomic&lt;T&gt;*, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_load_explicit(const atomic&lt;T&gt;*, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T atomic_exchange(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_exchange(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_exchange_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_exchange_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak(volatile atomic&lt;T&gt;*, T*, T) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak(atomic&lt;T&gt;*, T*, T) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong(volatile atomic&lt;T&gt;*, T*, T) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong(atomic&lt;T&gt;*, T*, T) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak_explicit(volatile atomic&lt;T&gt;*, T*, T,
memory_order, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak_explicit(atomic&lt;T&gt;*, T*, T, memory_order,
memory_order, memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong_explicit(volatile atomic&lt;T&gt;*, T*, T,
memory_order, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong_explicit(atomic&lt;T&gt;*, T*, T,
memory_order, memory_order,
memory_scope) noexcept;
// Please note that all operations taking memory_order as a parameter have
// additional overloads, in addition to cpp14 specification, taking both
// memory_order and memory_scope parameters.
template &lt;class T&gt;
T atomic_fetch_add(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_add(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_add_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_add_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_and(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_and(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_and_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_and_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_or(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_or(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_or_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_or_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
//OpenCL specific min/max atomics:
T atomic_fetch_min(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_min(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_min_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_min_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
T atomic_fetch_max(volatile atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_max(atomic&lt;T&gt;*, T) noexcept;
template &lt;class T&gt;
T atomic_fetch_max_explicit(volatile atomic&lt;T&gt;*, T, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_max_explicit(atomic&lt;T&gt;*, T, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
void atomic_store(atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
void atomic_store(volatile atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
void atomic_store_explicit(atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
void atomic_store_explicit(volatile atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_load(atomic&lt;T&gt;* object) noexcept;
template &lt;class T&gt;
T atomic_load(volatile atomic&lt;T&gt;* object) noexcept;
template &lt;class T&gt;
T atomic_load_explicit(atomic&lt;T&gt;* object, memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T atomic_load_explicit(volatile atomic&lt;T&gt;* object, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_exchange(atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_exchange(volatile atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_exchange_explicit(atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_exchange_explicit(volatile atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong(atomic&lt;T&gt;* object, T* expected,
T desired) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong(volatile atomic&lt;T&gt;* object, T* expected,
T desired) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong_explicit(atomic&lt;T&gt;* object, T* expected,
T desired, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_strong_explicit(volatile atomic&lt;T&gt;* object,
T* expected, T desired,
memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak(atomic&lt;T&gt;* object, T* expected,
T desired) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak(volatile atomic&lt;T&gt;* object, T* expected,
T desired) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak_explicit(atomic&lt;T&gt;* object, T* expected,
T desired, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
bool atomic_compare_exchange_weak_explicit(volatile atomic&lt;T&gt;* object,
T* expected, T desired,
memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_add(atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_add(volatile atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_add_explicit(atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_add_explicit(volatile atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_and(atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_and(volatile atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_and_explicit(atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_and_explicit(volatile atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_or(atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_or(volatile atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_or_explicit(atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_or_explicit(volatile atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub(atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub(volatile atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub_explicit(atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_sub_explicit(volatile atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor(atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor(volatile atomic&lt;T&gt;* object, T value) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor_explicit(atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T atomic_fetch_xor_explicit(volatile atomic&lt;T&gt;* object, T value, memory_order,
memory_scope) noexcept;
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__SIZE_WIDTH__ == 64) ||
__SIZE_WIDTH__ == 32
template &lt;class T&gt;
T* atomic_fetch_add(atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_add(volatile atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_add_explicit(atomic&lt;T*&gt;* object, ptrdiff_t value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_add_explicit(volatile atomic&lt;T*&gt;* object, ptrdiff_t value,
memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_and(atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_and(volatile atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_and_explicit(atomic&lt;T*&gt;* object, ptrdiff_t value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_and_explicit(volatile atomic&lt;T*&gt;* object, ptrdiff_t value,
memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_or(atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_or(volatile atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_or_explicit(atomic&lt;T*&gt;* object, ptrdiff_t value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_or_explicit(volatile atomic&lt;T*&gt;* object, ptrdiff_t value,
memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_sub(atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_sub(volatile atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_sub_explicit(atomic&lt;T*&gt;* object, ptrdiff_t value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_sub_explicit(volatile atomic&lt;T*&gt;* object, ptrdiff_t value,
memory_order, memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_xor(atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_xor(volatile atomic&lt;T*&gt;* object, ptrdiff_t value) noexcept;
template &lt;class T&gt;
T* atomic_fetch_xor_explicit(atomic&lt;T*&gt;* object, ptrdiff_t value, memory_order,
memory_scope) noexcept;
template &lt;class T&gt;
T* atomic_fetch_xor_explicit(volatile atomic&lt;T*&gt;* object, ptrdiff_t value,
memory_order, memory_scope) noexcept;
#endif
void atomic_fence(mem_fence flags, memory_order order,
memory_scope scope) noexcept;
#define ATOMIC_VAR_INIT(value) as described in cpp14 specification [atomics.types.operations]
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="order-and-scope">3.24.2. Order and scope</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
enum memory_order
{
memory_order_relaxed,
memory_order_acquire,
memory_order_release,
memory_order_acq_rel,
memory_order_seq_cst
};
enum memory_scope
{
memory_scope_all_svm_devices,
memory_scope_device,
memory_scope_work_group,
memory_scope_sub_group,
memory_scope_work_item
};
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>An enumeration <code>memory_order</code> is described in section [atomics.order] of C++14 specification. <a id="ftnref7"></a> <a href="#ftn7">[7]</a></p>
</div>
<div class="paragraph">
<p>The enumerated type <code>memory_scope</code> specifies whether the memory ordering constraints given by <code>memory_order</code> apply to work-items in a work-group or work-items of a kernel(s) executing on the device or across devices (in the case of shared virtual memory). Its enumeration constants are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>memory_scope_work_item</code> <a id="ftnref8"></a> <a href="#ftn8">[8]</a></p>
</li>
<li>
<p><code>memory_scope_sub_group</code></p>
</li>
<li>
<p><code>memory_scope_work_group</code></p>
</li>
<li>
<p><code>memory_scope_device</code></p>
</li>
<li>
<p><code>memory_scope_all_svm_devices</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The memory scope should only be used when performing atomic operations to global memory.
Atomic operations to local memory only guarantee memory ordering in the work-group not across work-groups and therefore ignore the <code>memory_scope</code> value.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
With fine-grained system SVM, sharing happens at the granularity of individual loads and stores anywhere in host memory.
Memory consistency is always guaranteed at synchronization points, but to obtain finer control over consistency, the OpenCL atomics functions may be used to ensure that the updates to individual data values made by
one unit of execution are visible to other execution units.
In particular, when a host thread needs fine control over the consistency of memory that is shared with one or more OpenCL devices, it must use atomic and fence operations that are compatible with the C++14 atomic operations <a id="ftnref9"></a> <a href="#ftn9">[9]</a>.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="atomic-lock-free-property">3.24.3. Atomic lock-free property</h4>
<div class="paragraph">
<p>OpenCL C++ requires all atomic types to be lock free.</p>
</div>
</div>
<div class="sect3">
<h4 id="atomic-types">3.24.4. Atomic types</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template &lt;class T&gt;
struct atomic
{
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
void store(T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
void store(T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
T load(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) const volatile noexcept;
T load(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) const noexcept;
operator T() const volatile noexcept;
operator T() const noexcept;
T exchange(T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
T exchange(T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
bool compare_exchange_weak(T&amp;, T, memory_order,
memory_order, memory_scope) volatile noexcept;
bool compare_exchange_weak(T&amp;, T, memory_order,
memory_order, memory_scope) noexcept;
bool compare_exchange_strong(T&amp;, T, memory_order,
memory_order, memory_scope) volatile noexcept;
bool compare_exchange_strong(T&amp;, T, memory_order,
memory_order, memory_scope) noexcept;
bool compare_exchange_weak(T&amp;, T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
bool compare_exchange_weak(T&amp;, T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
bool compare_exchange_strong(T&amp;, T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
bool compare_exchange_strong(T&amp;, T, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
atomic() noexcept = default;
constexpr atomic(T) noexcept;
atomic(const atomic&amp;) = delete;
atomic&amp; operator=(const atomic&amp;) = delete;
atomic&amp; operator=(const atomic&amp;) volatile = delete;
T operator=(T) volatile noexcept;
T operator=(T) noexcept;
};
template &lt;&gt;
struct atomic&lt;integral&gt;
{
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
void store(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
void store(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral load(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) const volatile noexcept;
integral load(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) const noexcept;
operator integral() const volatile noexcept;
operator integral() const noexcept;
integral exchange(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral exchange(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
bool compare_exchange_weak(integral&amp;, integral, memory_order,
memory_order, memory_scope) volatile noexcept;
bool compare_exchange_weak(integral&amp;, integral, memory_order, memory_order,
memory_scope) noexcept;
bool compare_exchange_strong(integral&amp;, integral, memory_order,
memory_order, memory_scope) volatile noexcept;
bool compare_exchange_strong(integral&amp;, integral, memory_order,
memory_order, memory_scope) noexcept;
bool compare_exchange_weak(integral&amp;, integral,
memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
bool compare_exchange_weak(integral&amp;, integral,
memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
bool compare_exchange_strong(integral&amp;, integral,
memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
bool compare_exchange_strong(integral&amp;, integral,
memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral fetch_add(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral fetch_add(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral fetch_sub(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral fetch_sub(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral fetch_and(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral fetch_and(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral fetch_or(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral fetch_or(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral fetch_xor(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral fetch_xor(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral fetch_min(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral fetch_min(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
integral fetch_max(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
integral fetch_max(integral, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
atomic() noexcept = default;
constexpr atomic(integral) noexcept;
atomic(const atomic&amp;) = delete;
atomic&amp; operator=(const atomic&amp;) = delete;
atomic&amp; operator=(const atomic&amp;) volatile = delete;
integral operator=(integral) volatile noexcept;
integral operator=(integral) noexcept;
integral operator++(int) volatile noexcept;
integral operator++(int) noexcept;
integral operator--(int) volatile noexcept;
integral operator--(int) noexcept;
integral operator++() volatile noexcept;
integral operator++() noexcept;
integral operator--() volatile noexcept;
integral operator--() noexcept;
integral operator+=(integral) volatile noexcept;
integral operator+=(integral) noexcept;
integral operator-=(integral) volatile noexcept;
integral operator-=(integral) noexcept;
integral operator&amp;=(integral) volatile noexcept;
integral operator&amp;=(integral) noexcept;
integral operator|=(integral) volatile noexcept;
integral operator|=(integral) noexcept;
integral operator^=(integral) volatile noexcept;
integral operator^=(integral) noexcept;
};
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__SIZE_WIDTH__ == 64) ||
__SIZE_WIDTH__ == 32
template &lt;class T&gt;
struct atomic&lt;T*&gt;
{
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
void store(T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
void store(T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
T* load(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) const volatile noexcept;
T* load(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) const noexcept;
operator T*() const volatile noexcept;
operator T*() const noexcept;
T* exchange(T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
T* exchange(T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
bool compare_exchange_weak(T*&amp;, T*, memory_order,
memory_order, memory_scope) volatile noexcept;
bool compare_exchange_weak(T*&amp;, T*, memory_order,
memory_order, memory_scope) noexcept;
bool compare_exchange_strong(T*&amp;, T*, memory_order,
memory_order, memory_scope) volatile noexcept;
bool compare_exchange_strong(T*&amp;, T*, memory_order,
memory_order, memory_scope) noexcept;
bool compare_exchange_weak(T*&amp;, T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
bool compare_exchange_weak(T*&amp;, T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
bool compare_exchange_strong(T*&amp;, T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
bool compare_exchange_strong(T*&amp;, T*, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
atomic() noexcept = default;
constexpr atomic(T*) noexcept;
atomic(const atomic&amp;) = delete;
atomic&amp; operator=(const atomic&amp;) = delete;
atomic&amp; operator=(const atomic&amp;) volatile = delete;
T* operator=(T*) volatile noexcept;
T* operator=(T*) noexcept;
T* operator++(int) volatile noexcept;
T* operator++(int) noexcept;
T* operator--(int) volatile noexcept;
T* operator--(int) noexcept;
T* operator++() volatile noexcept;
T* operator++() noexcept;
T* operator--() volatile noexcept;
T* operator--() noexcept;
T* operator+=(ptrdiff_t) volatile noexcept;
T* operator+=(ptrdiff_t) noexcept;
T* operator-=(ptrdiff_t) volatile noexcept;
T* operator-=(ptrdiff_t) noexcept;
};
#endif
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <em>opencl_atomic</em> header defines general specialization for class template <code>atomic&lt;T&gt;</code>.</p>
</div>
<div class="paragraph">
<p>There are explicit specializations for integral types.
Each of these specializations provides set of extra operators suitable for integral types.</p>
</div>
<div class="paragraph">
<p>There is an explicit specialization of the atomic template for pointer types.</p>
</div>
<div class="paragraph">
<p>All atomic classes have deleted copy constructor and deleted copy assignment operators.</p>
</div>
<div class="paragraph">
<p>There are several typedefs for atomic types specified as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
using atomic_int = atomic&lt;int&gt;;
using atomic_uint = atomic&lt;uint&gt;;
#if defined(cl_khr_int64_base_atomics) &amp;&amp; defined(cl_khr_int64_extended_atomics)
using atomic_long = atomic&lt;long&gt;;
using atomic_ulong = atomic&lt;ulong&gt;;
#endif
using atomic_float = atomic&lt;float&gt;;
#if defined(cl_khr_fp64) &amp;&amp;
defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics)
using atomic_double = atomic&lt;double&gt;;
#endif
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__INTPTR_WIDTH__ == 64) ||
__INTPTR_WIDTH__ == 32
using atomic_intptr_t = atomic&lt;intptr_t&gt;;
using atomic_uintptr_t = atomic&lt;uintptr_t&gt;;
#endif
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__SIZE_WIDTH__ == 64) ||
__SIZE_WIDTH__ == 32
using atomic_size_t = atomic&lt;size_t&gt;;
#endif
#if (defined(cl_khr_int64_base_atomics) &amp;&amp;
defined(cl_khr_int64_extended_atomics) &amp;&amp;
__PTRDIFF_WIDTH__ == 64) ||
__PTRDIFF_WIDTH__ == 32
using atomic_ptrdiff_t = atomic&lt;ptrdiff_t&gt;;
#endif
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="flag-type-and-operations">3.24.5. Flag type and operations</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
struct atomic_flag
{
bool test_and_set(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
bool test_and_set(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
void clear(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) volatile noexcept;
void clear(memory_order = memory_order_seq_cst,
memory_scope = memory_scope_device) noexcept;
atomic_flag() noexcept = default;
atomic_flag(const atomic_flag&amp;) = delete;
atomic_flag&amp; operator=(const atomic_flag&amp;) = delete;
atomic_flag&amp; operator=(const atomic_flag&amp;) volatile = delete;
};
bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;
bool atomic_flag_test_and_set(atomic_flag*) noexcept;
bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order,
memory_scope) noexcept;
bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order,
memory_scope) noexcept;
void atomic_flag_clear(volatile atomic_flag*) noexcept;
void atomic_flag_clear(atomic_flag*) noexcept;
void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order,
memory_scope) noexcept;
void atomic_flag_clear_explicit(atomic_flag*, memory_order,
memory_scope) noexcept;
#define ATOMIC_FLAG_INIT as described in cpp14 specification [atomics.flag]
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="fences">3.24.6. Fences</h4>
<div class="sect4">
<h5 id="atomic_fence">atomic_fence</h5>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>void atomic_fence(mem_fence flags, memory_order order, memory_scope scope) noexcept;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Orders loads or/and stores of a work-item executing a kernel.</p>
</div>
<div class="paragraph">
<p><code>flags</code> must be set to <code>mem_fence::global</code>, <code>mem_fence::local</code>, <code>mem_fence::image</code> or a combination of these values ORed together; otherwise the behavior is undefined.
The behavior of calling <code>atomic_fence</code> with <code>mem_fence::global</code> and <code>mem_fence::local</code> ORed together is equivalent to calling <code>atomic_fence</code> individually for each of the fence values set in <code>flags</code>.
<code>mem_fence::image</code> cannot be specified ORed with <code>mem_fence::global</code> and <code>mem_fence::local</code>.</p>
</div>
<div class="paragraph">
<p>Depending on the value of order, this operation:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Has no effects, if <code>order == memory_order_relaxed</code>.</p>
</li>
<li>
<p>Is an acquire fence, if <code>order == memory_order_acquire</code>.</p>
</li>
<li>
<p>Is a release fence, if <code>order == memory_order_release</code>.</p>
</li>
<li>
<p>Is both an acquire fence and a release fence, if <code>order == memory_order_acq_rel</code>.</p>
</li>
<li>
<p>Is a sequentially consistent acquire and release fence, if <code>order == memory_order_seq_cst</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For images declared with the <code>image_access::read_write</code>, the <code>atomic_fence</code> must be called to make sure that writes to the image by a work-item become visible to that work-item on subsequent reads to that image by that work-item.
Only a scope of <code>memory_order_acq_rel</code> is valid for <code>atomic_fence</code> when passed the <code>mem_fence::image</code> flag.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="bit-atomics">3.24.7. 64-bit Atomics</h4>
<div class="paragraph">
<p>The optional extensions <strong>cl_khr_int64_base_atomics</strong> and <strong>cl_khr_int64_extended_atomics</strong> implement atomic operations on 64-bit signed and unsigned integers to locations in global and local memory.</p>
</div>
<div class="paragraph">
<p>An application that wants to use 64-bit atomic types will need to define <code>cl_khr_int64_base_atomics</code> and <code>cl_khr_int64_extended_atomics</code> macros in the code before including the OpenCL C++ standard library headers or using <em>-D</em> compiler option (see the <a href="#preprocessor_options"><em>Preprocessor options</em></a> section).</p>
</div>
</div>
<div class="sect3">
<h4 id="restrictions-3">3.24.8. Restrictions</h4>
<div class="ulist">
<ul>
<li>
<p>The generic <code>atomic&lt;T&gt;</code> class template is only available if <code>T</code> is <code>int</code>, <code>uint</code>, <code>long</code>, <code>ulong</code> <a id="ftnref10"></a> <a href="#ftn10">[10]</a>, <code>float</code>, <code>double</code> <a id="ftnref11"></a> <a href="#ftn11">[11]</a>, <code>intptr_t</code> <a id="ftnref12"></a> <a href="#ftn12">[12]</a>, <code>uintptr_t</code>, <code>size_t</code>, <code>ptrdiff_t</code>.</p>
</li>
<li>
<p>The <code>atomic_bool</code>, <code>atomic_char</code>, <code>atomic_uchar</code>, <code>atomic_short</code>, <code>atomic_ushort</code>, <code>atomic_intmax_t</code> and <code>atomic_uintmax_t</code> types are not supported by OpenCL C++.</p>
</li>
<li>
<p>OpenCL C++ requires that the built-in atomic functions on atomic types are lock-free.</p>
</li>
<li>
<p>The atomic data types cannot be declared inside a kernel or non-kernel function unless they are declared as <code>static</code> keyword or in <code>local&lt;T&gt;</code> and <code>global&lt;T&gt;</code> containers.</p>
</li>
<li>
<p>The atomic operations on the private memory can result in undefined behavior.</p>
</li>
<li>
<p><code>memory_order_consume</code> is not supported by OpenCL C++.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="examples-4">3.24.9. Examples</h4>
<div class="sect4">
<h5 id="example-1-4">Example 1</h5>
<div class="paragraph">
<p>Examples of using atomic with and without an explicit address space
storage class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#include &lt;opencl_memory&gt;
#include &lt;opencl_atomic&gt;
using namespace cl;
atomic&lt;int&gt; a; // OK: atomic in the global memory
local&lt;atomic&lt;int&gt;&gt; b; // OK: atomic in the local memory
global&lt;atomic&lt;int&gt;&gt; c; // OK: atomic in the global memory
kernel void foo() {
static global&lt;atomic&lt;int&gt;&gt; d; // OK: atomic in the global memory
atomic&lt;global&lt;int&gt;&gt; e; // error: class members cannot be
// in address space
local&lt;atomic&lt;int&gt;&gt; f; // OK: atomic in the local memory
static atomic&lt;int&gt; g; // OK: atomic in the global memory
atomic&lt;int&gt; h; // undefined behavior
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="array-library">3.25. Array Library</h3>
<div class="paragraph">
<p>OpenCL C++ implements part of array library (<em>chapter 23.3.2</em>, <em>[array]</em>) from the C++14 standard.</p>
</div>
<div class="paragraph">
<p>For the detailed description please refer to C++14 standard.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_array-synopsis">3.25.1. Header &lt;opencl_array&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T, size_t N&gt;
struct array
{
//types:
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T&amp; reference;
typedef const T&amp; const_reference;
typedef implementation-defined iterator;
typedef implementation-defined const_iterator;
typedef T* pointer;
typedef const T* const_pointer;
typedef cl::reverse_iterator&lt;iterator&gt; reverse_iterator;
typedef cl::reverse_iterator&lt;const_iterator&gt; const_reverse_iterator;
value_type __elems[N]; // exposition only
// no explicit construct/copy/destroy for aggregate type
// iterators:
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
// capacity:
constexpr size_type size() const noexcept;
constexpr size_type max_size() const noexcept;
constexpr bool empty() const noexcept;
// element access:
reference operator[](size_type n) noexcept;
const_reference operator[](size_type n) const noexcept;
reference front() noexcept;
const_reference front() const noexcept;
reference back() noexcept;
const_reference back() const noexcept;
pointer data();
const_pointer data() const noexcept;
};
template &lt;class T&gt; class tuple_size;
template &lt;size_t I, class T&gt; class tuple_element;
template &lt;class T, size_t N&gt;
struct tuple_size&lt;array&lt;T, N&gt;&gt;;
template &lt;size_t I, class T, size_t N&gt;
struct tuple_element&lt;I, array&lt;T, N&gt;&gt;;
template &lt;size_t I, class T, size_t N&gt;
constexpr T&amp; get(array&lt;T, N&gt;&amp; a) noexcept;
template &lt;size_t I, class T, size_t N&gt;
constexpr T&amp;&amp; get(array&lt;T, N&gt;&amp;&amp; a) noexcept;
template &lt;size_t I, class T, size_t N&gt;
constexpr const T&amp; get(const array&lt;T, N&gt;&amp; a) noexcept;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="limits-library">3.26. Limits Library</h3>
<div class="paragraph">
<p>OpenCL C++ standard library implements modified version of the numeric limits library described in chapter <em>18.3 [support.limits]</em> of C++14 standard.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_limits-synopsis">3.26.1. Header &lt;opencl_limits&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T&gt; class numeric_limits;
enum float_round_style;
enum float_denorm_style;
#define CHAR_BIT 8
#define CHAR_MAX SCHAR_MAX
#define CHAR_MIN SCHAR_MIN
#define INT_MAX 2147483647
#define INT_MIN (-2147483647 - 1)
#define LONG_MAX 0x7fffffffffffffffL
#define LONG_MIN (-0x7fffffffffffffffL - 1)
#define SCHAR_MAX 127
#define SCHAR_MIN (-127 - 1)
#define SHRT_MAX 32767
#define SHRT_MIN (-32767 - 1)
#define UCHAR_MAX 255
#define USHRT_MAX 65535
#define UINT_MAX 0xffffffff
#define ULONG_MAX 0xffffffffffffffffUL
template&lt;&gt; class numeric_limits&lt;bool&gt;;
template&lt;&gt; class numeric_limits&lt;bool2&gt;;
template&lt;&gt; class numeric_limits&lt;bool3&gt;;
template&lt;&gt; class numeric_limits&lt;bool4&gt;;
template&lt;&gt; class numeric_limits&lt;bool8&gt;;
template&lt;&gt; class numeric_limits&lt;bool16&gt;;
template&lt;&gt; class numeric_limits&lt;char&gt;;
template&lt;&gt; class numeric_limits&lt;char2&gt;;
template&lt;&gt; class numeric_limits&lt;char3&gt;;
template&lt;&gt; class numeric_limits&lt;char4&gt;;
template&lt;&gt; class numeric_limits&lt;char8&gt;;
template&lt;&gt; class numeric_limits&lt;char16&gt;;
template&lt;&gt; class numeric_limits&lt;uchar&gt;;
template&lt;&gt; class numeric_limits&lt;uchar2&gt;;
template&lt;&gt; class numeric_limits&lt;uchar3&gt;;
template&lt;&gt; class numeric_limits&lt;uchar4&gt;;
template&lt;&gt; class numeric_limits&lt;uchar8&gt;;
template&lt;&gt; class numeric_limits&lt;uchar16&gt;;
template&lt;&gt; class numeric_limits&lt;short&gt;;
template&lt;&gt; class numeric_limits&lt;short2&gt;;
template&lt;&gt; class numeric_limits&lt;short3&gt;;
template&lt;&gt; class numeric_limits&lt;short4&gt;;
template&lt;&gt; class numeric_limits&lt;short8&gt;;
template&lt;&gt; class numeric_limits&lt;short16&gt;;
template&lt;&gt; class numeric_limits&lt;ushort&gt;;
template&lt;&gt; class numeric_limits&lt;ushort2&gt;;
template&lt;&gt; class numeric_limits&lt;ushort3&gt;;
template&lt;&gt; class numeric_limits&lt;ushort4&gt;;
template&lt;&gt; class numeric_limits&lt;ushort8&gt;;
template&lt;&gt; class numeric_limits&lt;ushort16&gt;;
template&lt;&gt; class numeric_limits&lt;int&gt;;
template&lt;&gt; class numeric_limits&lt;int2&gt;;
template&lt;&gt; class numeric_limits&lt;int3&gt;;
template&lt;&gt; class numeric_limits&lt;int4&gt;;
template&lt;&gt; class numeric_limits&lt;int8&gt;;
template&lt;&gt; class numeric_limits&lt;int16&gt;;
template&lt;&gt; class numeric_limits&lt;uint&gt;;
template&lt;&gt; class numeric_limits&lt;uint2&gt;;
template&lt;&gt; class numeric_limits&lt;uint3&gt;;
template&lt;&gt; class numeric_limits&lt;uint4&gt;;
template&lt;&gt; class numeric_limits&lt;uint8&gt;;
template&lt;&gt; class numeric_limits&lt;uint16&gt;;
template&lt;&gt; class numeric_limits&lt;long&gt;;
template&lt;&gt; class numeric_limits&lt;long2&gt;;
template&lt;&gt; class numeric_limits&lt;long3&gt;;
template&lt;&gt; class numeric_limits&lt;long4&gt;;
template&lt;&gt; class numeric_limits&lt;long8&gt;;
template&lt;&gt; class numeric_limits&lt;long16&gt;;
template&lt;&gt; class numeric_limits&lt;ulong&gt;;
template&lt;&gt; class numeric_limits&lt;ulong2&gt;;
template&lt;&gt; class numeric_limits&lt;ulong3&gt;;
template&lt;&gt; class numeric_limits&lt;ulong4&gt;;
template&lt;&gt; class numeric_limits&lt;ulong8&gt;;
template&lt;&gt; class numeric_limits&lt;ulong16&gt;;
#ifdef cl_khr_fp16
#define HALF_DIG 3
#define HALF_MANT_DIG 11
#define HALF_MAX_10_EXP +4
#define HALF_MAX_EXP +16
#define HALF_MIN_10_EXP -4
#define HALF_MIN_EXP -13
#define HALF_RADIX 2
#define HALF_MAX 0x1.ffcp15h
#define HALF_MIN 0x1.0p-14h
#define HALF_EPSILON 0x1.0p-10h
template&lt;&gt; class numeric_limits&lt;half&gt;;
#endif
#define FLT_DIG 6
#define FLT_MANT_DIG 24
#define FLT_MAX_10_EXP +38
#define FLT_MAX_EXP +128
#define FLT_MIN_10_EXP -37
#define FLT_MIN_EXP -125
#define FLT_RADIX 2
#define FLT_MAX 0x1.fffffep127f
#define FLT_MIN 0x1.0p-126f
#define FLT_EPSILON 0x1.0p-23f
template&lt;&gt; class numeric_limits&lt;float&gt;;
#ifdef cl_khr_fp64
#define DBL_DIG 15
#define DBL_MANT_DIG 53
#define DBL_MAX_10_EXP +308
#define DBL_MAX_EXP +1024
#define DBL_MIN_10_EXP -307
#define DBL_MIN_EXP -1021
#define DBL_MAX 0x1.fffffffffffffp1023
#define DBL_MIN 0x1.0p-1022
#define DBL_EPSILON 0x1.0p-52
template&lt;&gt; class numeric_limits&lt;double&gt;;
#endif
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="class-numeric_limits">3.26.2. Class numeric_limits</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T&gt;
class numeric_limits
{
public:
static constexpr bool is_specialized = false;
static constexpr T min() noexcept { return T(); }
static constexpr T max() noexcept { return T(); }
static constexpr T lowest() noexcept { return T(); }
static constexpr int digits = 0;
static constexpr int digits10 = 0;
static constexpr int max_digits10 = 0;
static constexpr bool is_signed = false;
static constexpr bool is_integer = false;
static constexpr bool is_exact = false;
static constexpr int radix = 0;
static constexpr T epsilon() noexcept { return T(); }
static constexpr T round_error() noexcept { return T(); }
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_NaN = false;
static constexpr bool has_signaling_NaN = false;
static constexpr float_denorm_style has_denorm = denorm_absent;
static constexpr bool has_denorm_loss = false;
static constexpr T infinity() noexcept { return T(); }
static constexpr T quiet_NaN() noexcept { return T(); }
static constexpr T signaling_NaN() noexcept { return T(); }
static constexpr T denorm_min() noexcept { return T(); }
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = false;
static constexpr bool is_modulo = false;
static constexpr bool traps = false;
static constexpr bool tinyness_before = false;
static constexpr float_round_style round_style = round_toward_zero;
static constexpr bool is_scalar = false;
static constexpr bool is_vector = false;
};
template&lt;class T&gt; class numeric_limits&lt;const T&gt;;
template&lt;class T&gt; class numeric_limits&lt;volatile T&gt;;
template&lt;class T&gt; class numeric_limits&lt;const volatile T&gt;;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="has_denorm-numeric_limits-class-member">3.26.3. has_denorm numeric_limits class member</h4>
<div class="paragraph">
<p><code>has_denorm</code> class member value depends on a macro:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>HAS_SINGLE_FP_DENORM</code> for type <code>float</code>.</p>
</li>
<li>
<p><code>HAS_HALF_FP_DENORM</code> for type <code>half</code>.</p>
</li>
<li>
<p><code>HAS_DOUBLE_FP_DENORM</code> for type <code>double</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If a macro is defined, <code>has_denorm</code> is set to <code>denorm_present</code>.
Otherwise it is <code>denorm_absent</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="floating-point-macros-and-limits">3.26.4. Floating-point macros and limits</h4>
<div class="paragraph">
<p>The macro names given in the following list must use the values specified.
These constant expressions are suitable for use in <code>#if</code> preprocessing directives.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#define FLT_DIG 6
#define FLT_MANT_DIG 24
#define FLT_MAX_10_EXP +38
#define FLT_MAX_EXP +128
#define FLT_MIN_10_EXP -37
#define FLT_MIN_EXP -125
#define FLT_RADIX 2
#define FLT_MAX 0x1.fffffep127f
#define FLT_MIN 0x1.0p-126f
#define FLT_EPSILON 0x1.0p-23f</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following table describes the built-in macro names given above in the OpenCL C++ library and the corresponding macro names available to the application.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 22. Float Built-in Macros</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Macro in OpenCL C++</strong></th>
<th class="tableblock halign-left valign-top"><strong>Macro for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_DIG</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_DIG</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_MANT_DIG</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_MANT_DIG</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_MAX_10_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_MAX_10_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_MAX_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_MAX_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_MIN_10_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_MIN_10_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_MIN_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_MIN_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_RADIX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_RADIX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FLT_EPSILSON</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_FLT_EPSILON</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The following macros shall expand to integer constant expressions whose values are returned by <code>ilogb(x)</code> if <code>x</code> is zero or NaN, respectively.
The value of <code>FP_ILOGB0</code> shall be either <code>INT_MIN</code> or <code>INT_MAX</code>. The value of <code>FP_ILOGBNAN</code> shall be either <code>INT_MAX</code> or <code>INT_MIN</code>.</p>
</div>
<div class="paragraph">
<p>If double precision is supported by the device, the following macros and constants are available:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#define DBL_DIG 15
#define DBL_MANT_DIG 53
#define DBL_MAX_10_EXP +308
#define DBL_MAX_EXP +1024
#define DBL_MIN_10_EXP -307
#define DBL_MIN_EXP -1021
#define DBL_MAX 0x1.fffffffffffffp1023
#define DBL_MIN 0x1.0p-1022
#define DBL_EPSILON 0x1.0p-52</code></pre>
</div>
</div>
<div class="paragraph">
<p>The macro names given in the following list must use the values specified.
These constant expressions are suitable for use in <code>#if</code> preprocessing directives.</p>
</div>
<div class="paragraph">
<p>The following table describes the built-in macro names given above in the OpenCL C++ library and the corresponding macro names available to the application.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 23. Double Built-in Macros</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Macro in OpenCL cpp</strong></th>
<th class="tableblock halign-left valign-top"><strong>Macro for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_DIG</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_DIG</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_MANT_DIG</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_MANT_DIG</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_MAX_10_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_MAX_10_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_MAX_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_MAX_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_MIN_10_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_MIN_10_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_MIN_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_MIN_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>DBL_EPSILSON</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_DBL_EPSILON</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>If half precision arithmetic operations are supported, the following macros and constants for half precision floating-point are available:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#define HALF_DIG 3
#define HALF_MANT_DIG 11
#define HALF_MAX_10_EXP +4
#define HALF_MAX_EXP +16
#define HALF_MIN_10_EXP -4
#define HALF_MIN_EXP -13
#define HALF_RADIX 2
#define HALF_MAX 0x1.ffcp15h
#define HALF_MIN 0x1.0p-14h
#define HALF_EPSILON 0x1.0p-10h</code></pre>
</div>
</div>
<div class="paragraph">
<p>The macro names given in the following list must use the values specified.
These constant expressions are suitable for use in <code>#if</code> preprocessing directives.</p>
</div>
<div class="paragraph">
<p>The following table describes the built-in macro names given above in the OpenCL C++ library and the corresponding macro names available to the application.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 24. Half Built-in Macros</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Macro in OpenCL cpp</strong></th>
<th class="tableblock halign-left valign-top"><strong>Macro for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_DIG</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_DIG</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_MANT_DIG</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_MANT_DIG</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_MAX_10_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_MAX_10_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_MAX_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_MAX_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_MIN_10_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_MIN_10_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_MIN_EXP</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_MIN_EXP</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_RADIX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_RADIX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HALF_EPSILSON</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_HALF_EPSILON</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The following symbolic constants are available.
Their values are of type float and are accurate within the precision of a single precision floating-point number.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 25. Float Symbolic Constants</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Constant Name</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>MAXFLOAT</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of maximum non-infinite single-precision floating-point number.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HUGE_VALF</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A positive float constant expression. <code>HUGE_VALF</code> evaluates to +infinity.
Used as an error value returned by the built-in math functions.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>INFINITY</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A constant expression of type float representing positive or unsigned infinity.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NAN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A constant expression of type float representing a quiet NaN.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>If double precision is supported by the device, the following symbolic constant will also be available:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 26. Double Symbolic Constants</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Constant Name</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HUGE_VAL</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A positive double constant expression.
<code>HUGE_VAL</code> evaluates to +infinity.
Used as an error value returned by the built-in math functions.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="integer-macros-and-limits">3.26.5. Integer macros and limits</h4>
<div class="paragraph">
<p>The macro names given in the following list must use the values specified.
The values shall all be constant expressions suitable for use in <code>#if</code> preprocessing directives.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>#define CHAR_BIT 8
#define CHAR_MAX SCHAR_MAX
#define CHAR_MIN SCHAR_MIN
#define INT_MAX 2147483647
#define INT_MIN (-2147483647 - 1)
#define LONG_MAX 0x7fffffffffffffffL
#define LONG_MIN (-0x7fffffffffffffffL - 1)
#define SCHAR_MAX 127
#define SCHAR_MIN (-127 - 1)
#define SHRT_MAX 32767
#define SHRT_MIN (-32767 - 1)
#define UCHAR_MAX 255
#define USHRT_MAX 65535
#define UINT_MAX 0xffffffff
#define ULONG_MAX 0xffffffffffffffffUL</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following table describes the built-in macro names given above in the OpenCL C++ library and the corresponding macro names available to the application.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 27. Integer built-in macros</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Macro in OpenCL cpp</strong></th>
<th class="tableblock halign-left valign-top"><strong>Macro for application</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CHAR_BIT</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_CHAR_BIT</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CHAR_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_CHAR_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CHAR_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_CHAR_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>INT_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_INT_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>INT_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_INT_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LONG_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_LONG_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LONG_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_LONG_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>SCHAR_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_SCHAR_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>SCHAR_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_SCHAR_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>SHRT_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_SHRT_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>SHRT_MIN</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_SHRT_MIN</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>UCHAR_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_UCHAR_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>USHRT_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_USHRT_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>UINT_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_UINT_MAX</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ULONG_MAX</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CL_ULONG_MAX</code></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="math-constants-library">3.27. Math Constants Library</h3>
<div class="paragraph">
<p>OpenCL C++ implements math constant library.
The purpose of this library is to provide the commonly used constants for half, float and double data types.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_math_constants-synopsis">3.27.1. Header &lt;opencl_math_constants&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T&gt; class math_constants;
#ifdef cl_khr_fp16
#define M_E_H see below
#define M_LOG2E_H see below
#define M_LOG10E_H see below
#define M_LN2_H see below
#define M_LN10_H see below
#define M_PI_H see below
#define M_PI_2_H see below
#define M_PI_4_H see below
#define M_1_PI_H see below
#define M_2_PI_H see below
#define M_2_SQRTPI_H see below
#define M_SQRT2_H see below
#define M_SQRT1_2_H see below
template&lt;&gt; class math_constants&lt;half&gt;;
template&lt;&gt; class math_constants&lt;half2&gt;;
template&lt;&gt; class math_constants&lt;half3&gt;;
template&lt;&gt; class math_constants&lt;half4&gt;;
template&lt;&gt; class math_constants&lt;half8&gt;;
template&lt;&gt; class math_constants&lt;half16&gt;;
#endif
#define M_E_F see below
#define M_LOG2E_F see below
#define M_LOG10E_F see below
#define M_LN2_F see below
#define M_LN10_F see below
#define M_PI_F see below
#define M_PI_2_F see below
#define M_PI_4_F see below
#define M_1_PI_F see below
#define M_2_PI_F see below
#define M_2_SQRTPI_F see below
#define M_SQRT2_F see below
#define M_SQRT1_2_F see below
template&lt;&gt; class math_constants&lt;float&gt;;
template&lt;&gt; class math_constants&lt;float2&gt;;
template&lt;&gt; class math_constants&lt;float3&gt;;
template&lt;&gt; class math_constants&lt;float4&gt;;
template&lt;&gt; class math_constants&lt;float8&gt;;
template&lt;&gt; class math_constants&lt;float16&gt;;
#ifdef cl_khr_fp64
#define M_E see below
#define M_LOG2E see below
#define M_LOG10E see below
#define M_LN2 see below
#define M_LN10 see below
#define M_PI see below
#define M_PI_2 see below
#define M_PI_4 see below
#define M_1_PI see below
#define M_2_PI see below
#define M_2_SQRTPI see below
#define M_SQRT2 see below
#define M_SQRT1_2 see below
template&lt;&gt; class math_constants&lt;double&gt;;
template&lt;&gt; class math_constants&lt;double2&gt;;
template&lt;&gt; class math_constants&lt;double3&gt;;
template&lt;&gt; class math_constants&lt;double4&gt;;
template&lt;&gt; class math_constants&lt;double8&gt;;
template&lt;&gt; class math_constants&lt;double16&gt;;
#endif
template&lt;class T&gt;
constexpr T e_v = math_constants&lt;T&gt;::e();
template&lt;class T&gt;
constexpr T log2e_v = math_constants&lt;T&gt;::log2e();
template&lt;class T&gt;
constexpr T log10e_v = math_constants&lt;T&gt;::log10e();
template&lt;class T&gt;
constexpr T ln2_v = math_constants&lt;T&gt;::ln2();
template&lt;class T&gt;
constexpr T ln10_v = math_constants&lt;T&gt;::ln10();
template&lt;class T&gt;
constexpr T pi_v = math_constants&lt;T&gt;::pi();
template&lt;class T&gt;
constexpr T pi_2_v = math_constants&lt;T&gt;::pi_2();
template&lt;class T&gt;
constexpr T pi_4_v = math_constants&lt;T&gt;::pi_4();
template&lt;class T&gt;
constexpr T one_pi_v = math_constants&lt;T&gt;::one_pi();
template&lt;class T&gt;
constexpr T two_pi_v = math_constants&lt;T&gt;::two_pi();
template&lt;class T&gt;
constexpr T two_sqrtpi_v = math_constants&lt;T&gt;::two_sqrtpi();
template&lt;class T&gt;
constexpr T sqrt2_v = math_constants&lt;T&gt;::sqrt2();
template&lt;class T&gt;
constexpr T sqrt1_2_v = math_constants&lt;T&gt;::sqrt1_2();
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="class-math_constants">3.27.2. Class math_constants</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T&gt;
class math_constants
{
public:
static constexpr T e() noexcept { return T(); }
static constexpr T log2e() noexcept { return T(); }
static constexpr T log10e() noexcept { return T(); }
static constexpr T ln2() noexcept { return T(); }
static constexpr T ln10() noexcept { return T(); }
static constexpr T pi() noexcept { return T(); }
static constexpr T pi_2() noexcept { return T(); }
static constexpr T pi_4() noexcept { return T(); }
static constexpr T one_pi() noexcept { return T(); }
static constexpr T two_pi() noexcept { return T(); }
static constexpr T two_sqrtpi() noexcept { return T(); }
static constexpr T sqrt2() noexcept { return T(); }
static constexpr T sqrt1_2() noexcept { return T(); }
};
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="half-constants">3.27.3. Half Constants</h4>
<div class="paragraph">
<p>The following constants are also available.
They are of type <code>half</code> and are accurate within the precision of the <code>half</code> type.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 28. Half Constants</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Constant</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>log2e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>2</sub>e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>log10e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>10</sub>e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>e</sub>2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln10</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>e</sub>10</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi_2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π / 2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi_4</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π / 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>one_pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 1 / π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>two_pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 2 / π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>two_sqrtpi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 2 / √π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sqrt2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of √2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sqrt1_2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 1 / √2</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="float-constants">3.27.4. Float Constants</h4>
<div class="paragraph">
<p>The following constants are also available.
They are of type <code>float</code> and are accurate within the precision of the <code>float</code> type.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 29. Float Constants</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Constant</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>log2e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>2</sub>e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>log10e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>10</sub>e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>e</sub>2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln10</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>e</sub>10</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi_2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π / 2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi_4</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π / 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>one_pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 1 / π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>two_pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 2 / π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>two_sqrtpi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 2 / √π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sqrt2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of √2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sqrt1_2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 1 / √2</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="double-constants">3.27.5. Double Constants</h4>
<div class="paragraph">
<p>The following constants are also available.
They are of type <code>double</code> and are accurate within the precision of the <code>double</code> type.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 30. Double Constants</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Constant</strong></th>
<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>log2e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>2</sub>e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>log10e</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>10</sub>e</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>e</sub>2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ln10</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of log<sub>e</sub>10</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi_2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π / 2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>pi_4</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of π / 4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>one_pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 1 / π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>two_pi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 2 / π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>two_sqrtpi</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 2 / √π</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sqrt2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of √2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sqrt1_2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of 1 / √2</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="tuple-library">3.28. Tuple Library</h3>
<div class="paragraph">
<p>OpenCL C++ standard library implements most of the tuples described in <em>chapter 20.4 [tuple]</em> of C++14 standard.</p>
</div>
<div class="paragraph">
<p>The following parts of tuple library are not supported:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>allocator related traits (C++14 standard, <em>section 20.4.2.8</em>)</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="header-opencl_tuple-synopsis">3.28.1. Header &lt;opencl_tuple&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
// class template tuple:
template &lt;class... Types&gt; class tuple;
// tuple creation functions:
const unspecified ignore;
template &lt;class... Types&gt;
constexpr tuple&lt;VTypes ...&gt; make_tuple(Types&amp;&amp;...);
template &lt;class... Types&gt;
constexpr tuple&lt;Types&amp;&amp;...&gt; forward_as_tuple(Types&amp;&amp;...) noexcept;
template&lt;class... Types&gt;
constexpr tuple&lt;Types&amp;...&gt; tie(Types&amp;...) noexcept;
template &lt;class... Tuples&gt;
constexpr tuple&lt;Ctypes ...&gt; tuple_cat(Tuples&amp;&amp;...);
// tuple helper classes:
template &lt;class T&gt; class tuple_size; // undefined
template &lt;class T&gt; class tuple_size&lt;const T&gt;;
template &lt;class T&gt; class tuple_size&lt;volatile T&gt;;
template &lt;class T&gt; class tuple_size&lt;const volatile T&gt;;
template &lt;class... Types&gt; class tuple_size&lt;tuple&lt;Types...&gt; &gt;;
template &lt;size_t I, class T&gt; class tuple_element; // undefined
template &lt;size_t I, class T&gt; class tuple_element&lt;I, const T&gt;;
template &lt;size_t I, class T&gt; class tuple_element&lt;I, volatile T&gt;;
template &lt;size_t I, class T&gt; class tuple_element&lt;I, const volatile T&gt;;
template &lt;size_t I, class... Types&gt; class tuple_element&lt;I, tuple&lt;Types...&gt; &gt;;
template &lt;size_t I, class T&gt;
using tuple_element_t = typename tuple_element&lt;I, T&gt;::type;
// element access:
template &lt;size_t I, class... Types&gt;
constexpr tuple_element_t&lt;I, tuple&lt;Types...&gt;&gt;&amp;
get(tuple&lt;Types...&gt;&amp;) noexcept;
template &lt;size_t I, class... Types&gt;
constexpr tuple_element_t&lt;I, tuple&lt;Types...&gt;&gt;&amp;&amp;
get(tuple&lt;Types...&gt;&amp;&amp;) noexcept;
template &lt;size_t I, class... Types&gt;
constexpr const tuple_element_t&lt;I, tuple&lt;Types...&gt;&gt;&amp;
get(const tuple&lt;Types...&gt;&amp;) noexcept;
template &lt;class T, class... Types&gt;
constexpr T&amp; get(tuple&lt;Types...&gt;&amp; t) noexcept;
template &lt;class T, class... Types&gt;
constexpr T&amp;&amp; get(tuple&lt;Types...&gt;&amp;&amp; t) noexcept;
template &lt;class T, class... Types&gt;
constexpr const T&amp; get(const tuple&lt;Types...&gt;&amp; t) noexcept;
// relational operators:
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator==(const tuple&lt;TTypes...&gt;&amp;, const tuple&lt;UTypes...&gt;&amp;);
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator&lt;(const tuple&lt;TTypes...&gt;&amp;, const tuple&lt;UTypes...&gt;&amp;);
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator!=(const tuple&lt;TTypes...&gt;&amp;, const tuple&lt;UTypes...&gt;&amp;);
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator&gt;(const tuple&lt;TTypes...&gt;&amp;, const tuple&lt;UTypes...&gt;&amp;);
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator&lt;=(const tuple&lt;TTypes...&gt;&amp;, const tuple&lt;UTypes...&gt;&amp;);
template&lt;class... TTypes, class... UTypes&gt;
constexpr bool operator&gt;=(const tuple&lt;TTypes...&gt;&amp;, const tuple&lt;UTypes...&gt;&amp;);
// specialized algorithms:
template &lt;class... Types&gt;
void swap(tuple&lt;Types...&gt;&amp; x, tuple&lt;Types...&gt;&amp; y) noexcept(see cpp14 standard);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="type-traits-library">3.29. Type Traits Library</h3>
<div class="paragraph">
<p>OpenCL C++ supports type traits defined in C++14 specification with following changes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the <a href="#unary-type-traits"><em>Unary Type Traits</em></a> section describes additions and changes to <em>UnaryTypeTraits</em>.</p>
</li>
<li>
<p>the <a href="#binary-type-traits"><em>Binary type traits</em></a> section describes additions and changes to <em>BinaryTypeTraits</em>.</p>
</li>
<li>
<p>the <a href="#transformation-traits"><em>Transformation traits</em></a> section describes additions and changes to <em>TransformationTraits</em>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This section specifies only OpenCL specific type traits and modifications.
All C++ type traits are described in <em>chapter 20.10 [meta]</em> of C++14 standard.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_type_traits-synopsis">3.29.1. Header &lt;opencl_type_traits&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
// helper class:
template &lt;class T, T v&gt; struct integral_constant;
typedef integral_constant&lt;bool, true&gt; true_type;
typedef integral_constant&lt;bool, false&gt; false_type;
// primary type categories:
template &lt;class T&gt; struct is_void;
template &lt;class T&gt; struct is_null_pointer;
template &lt;class T&gt; struct is_integral;
template &lt;class T&gt; struct is_floating_point;
template &lt;class T&gt; struct is_array;
template &lt;class T&gt; struct is_pointer;
template &lt;class T&gt; struct is_lvalue_reference;
template &lt;class T&gt; struct is_rvalue_reference;
template &lt;class T&gt; struct is_member_object_pointer;
template &lt;class T&gt; struct is_member_function_pointer;
template &lt;class T&gt; struct is_enum;
template &lt;class T&gt; struct is_union;
template &lt;class T&gt; struct is_class;
template &lt;class T&gt; struct is_function;
// composite type categories:
template &lt;class T&gt; struct is_reference;
template &lt;class T&gt; struct is_arithmetic;
template &lt;class T&gt; struct is_fundamental;
template &lt;class T&gt; struct is_object;
template &lt;class T&gt; struct is_scalar;
template &lt;class T&gt; struct is_compound;
template &lt;class T&gt; struct is_member_pointer;
// type properties:
template &lt;class T&gt; struct is_const;
template &lt;class T&gt; struct is_volatile;
template &lt;class T&gt; struct is_private;
template &lt;class T&gt; struct is_local;
template &lt;class T&gt; struct is_global;
template &lt;class T&gt; struct is_constant;
template &lt;class T&gt; struct is_generic;
template &lt;class T&gt; struct is_vector;
template &lt;class T&gt; struct is_trivial;
template &lt;class T&gt; struct is_trivially_copyable;
template &lt;class T&gt; struct is_standard_layout;
template &lt;class T&gt; struct is_pod;
template &lt;class T&gt; struct is_literal_type;
template &lt;class T&gt; struct is_empty;
template &lt;class T&gt; struct is_polymorphic;
template &lt;class T&gt; struct is_abstract;
template &lt;class T&gt; struct is_final;
template &lt;class T&gt; struct is_signed;
template &lt;class T&gt; struct is_unsigned;
template &lt;class T, class... Args&gt; struct is_constructible;
template &lt;class T&gt; struct is_default_constructible;
template &lt;class T&gt; struct is_copy_constructible;
template &lt;class T&gt; struct is_move_constructible;
template &lt;class T, class U&gt; struct is_assignable;
template &lt;class T&gt; struct is_copy_assignable;
template &lt;class T&gt; struct is_move_assignable;
template &lt;class T&gt; struct is_destructible;
template &lt;class T, class... Args&gt; struct is_trivially_constructible;
template &lt;class T&gt; struct is_trivially_default_constructible;
template &lt;class T&gt; struct is_trivially_copy_constructible;
template &lt;class T&gt; struct is_trivially_move_constructible;
template &lt;class T, class U&gt; struct is_trivially_assignable;
template &lt;class T&gt; struct is_trivially_copy_assignable;
template &lt;class T&gt; struct is_trivially_move_assignable;
template &lt;class T&gt; struct is_trivially_destructible;
template &lt;class T, class... Args&gt; struct is_nothrow_constructible;
template &lt;class T&gt; struct is_nothrow_default_constructible;
template &lt;class T&gt; struct is_nothrow_copy_constructible;
template &lt;class T&gt; struct is_nothrow_move_constructible;
template &lt;class T, class U&gt; struct is_nothrow_assignable;
template &lt;class T&gt; struct is_nothrow_copy_assignable;
template &lt;class T&gt; struct is_nothrow_move_assignable;
template &lt;class T&gt; struct is_nothrow_destructible;
template &lt;class T&gt; struct has_virtual_destructor;
// type property queries:
template &lt;class T&gt; struct alignment_of;
template &lt;class T&gt; struct rank;
template &lt;class T, unsigned I = 0&gt; struct extent;
// type relations:
template &lt;class T, class U&gt; struct is_same;
template &lt;class Base, class Derived&gt; struct is_base_of;
template &lt;class From, class To&gt; struct is_convertible;
// const-volatile modifications:
template &lt;class T&gt; struct remove_const;
template &lt;class T&gt; struct remove_volatile;
template &lt;class T&gt; struct remove_cv;
template &lt;class T&gt; struct add_const;
template &lt;class T&gt; struct add_volatile;
template &lt;class T&gt; struct add_cv;
template &lt;class T&gt;
using remove_const_t = typename remove_const&lt;T&gt;::type;
template &lt;class T&gt;
using remove_volatile_t = typename remove_volatile&lt;T&gt;::type;
template &lt;class T&gt;
using remove_cv_t = typename remove_cv&lt;T&gt;::type;
template &lt;class T&gt;
using add_const_t = typename add_const&lt;T&gt;::type;
template &lt;class T&gt;
using add_volatile_t = typename add_volatile&lt;T&gt;::type;
template &lt;class T&gt;
using add_cv_t = typename add_cv&lt;T&gt;::type;
// as modifications
template &lt;class T&gt; struct remove_constant;
template &lt;class T&gt; struct remove_local;
template &lt;class T&gt; struct remove_global;
template &lt;class T&gt; struct remove_private;
template &lt;class T&gt; struct remove_generic;
template &lt;class T&gt; struct remove_as;
template &lt;class T&gt; struct remove_attrs;
template &lt;class T&gt; struct add_constant;
template &lt;class T&gt; struct add_local;
template &lt;class T&gt; struct add_global;
template &lt;class T&gt; struct add_private;
template &lt;class T&gt; struct add_generic;
template &lt;class T&gt;
using remove_constant_t = typename remove_constant&lt;T&gt;::type;
template &lt;class T&gt;
using remove_local_t = typename remove_local&lt;T&gt;::type;
template &lt;class T&gt;
using remove_global_t = typename remove_global&lt;T&gt;::type;
template &lt;class T&gt;
using remove_private_t = typename remove_private&lt;T&gt;::type;
template &lt;class T&gt;
using remove_generic_t = typename remove_generic&lt;T&gt;::type;
template &lt;class T&gt;
using remove_as_t = typename remove_as&lt;T&gt;::type;
template &lt;class T&gt;
using remove_attrs_t = typename remove_attrs&lt;T&gt;::type;
template &lt;class T&gt;
using add_constant_t = typename add_constant&lt;T&gt;::type;
template &lt;class T&gt;
using add_local_t = typename add_local&lt;T&gt;::type;
template &lt;class T&gt;
using add_global_t = typename add_global&lt;T&gt;::type;
template &lt;class T&gt;
using add_private_t = typename add_private&lt;T&gt;::type;
template &lt;class T&gt;
using add_generic_t = typename add_generic&lt;T&gt;::type;
// reference modifications:
template &lt;class T&gt; struct remove_reference;
template &lt;class T&gt; struct add_lvalue_reference;
template &lt;class T&gt; struct add_rvalue_reference;
template &lt;class T&gt;
using remove_reference_t = typename remove_reference&lt;T&gt;::type;
template &lt;class T&gt;
using add_lvalue_reference_t = typename add_lvalue_reference&lt;T&gt;::type;
template &lt;class T&gt;
using add_rvalue_reference_t = typename add_rvalue_reference&lt;T&gt;::type;
// sign modifications:
template &lt;class T&gt; struct make_signed;
template &lt;class T&gt; struct make_unsigned;
template &lt;class T&gt;
using make_signed_t = typename make_signed&lt;T&gt;::type;
template &lt;class T&gt;
using make_unsigned_t = typename make_unsigned&lt;T&gt;::type;
// array modifications:
template &lt;class T&gt; struct remove_extent;
template &lt;class T&gt; struct remove_all_extents;
template &lt;class T&gt;
using remove_extent_t = typename remove_extent&lt;T&gt;::type;
template &lt;class T&gt;
using remove_all_extents_t = typename remove_all_extents&lt;T&gt;::type;
// pointer modifications:
template &lt;class T&gt; struct remove_pointer;
template &lt;class T&gt; struct add_pointer;
template &lt;class T&gt;
using remove_pointer_t = typename remove_pointer&lt;T&gt;::type;
template &lt;class T&gt;
using add_pointer_t = typename add_pointer&lt;T&gt;::type;
// built-in vector queries
template &lt;class T&gt; struct is_vector_type;
template &lt;class T&gt; struct vector_size;
// built-in vector modifications
template &lt;class T&gt; struct vector_element;
template &lt;class T, uint DIM&gt; struct make_vector;
template &lt;class T&gt;
using vector_element_t = typename vector_element&lt;T&gt;::type;
template &lt;class T, uint DIM&gt;
using make_vector_t = typename make_vector&lt;T,DIM&gt;::type;
// other transformations:
template &lt;cl::size_t Len,
cl::size_t Align = default-alignment&gt;
struct aligned_storage;
template &lt;cl::size_t Len, class... Types&gt; struct aligned_union;
template &lt;class T&gt; struct decay;
template &lt;bool, class T = void&gt; struct enable_if;
template &lt;bool, class T, class F&gt; struct conditional;
template &lt;class... T&gt; struct common_type;
template &lt;class T&gt; struct underlying_type;
template &lt;class&gt; class result_of; // not defined
template &lt;class F, class... ArgTypes&gt; class result_of&lt;F(ArgTypes...)&gt;;
template &lt;cl::size_t Len,
cl::size_t Align = default-alignment &gt;
using aligned_storage_t = typename aligned_storage&lt;Len,Align&gt;::type;
template &lt;cl::size_t Len, class... Types&gt;
using aligned_union_t = typename aligned_union&lt;Len,Types...&gt;::type;
template &lt;class T&gt;
using decay_t = typename decay&lt;T&gt;::type;
template &lt;bool b, class T = void&gt;
using enable_if_t = typename enable_if&lt;b,T&gt;::type;
template &lt;bool b, class T, class F&gt;
using conditional_t = typename conditional&lt;b,T,F&gt;::type;
template &lt;class... T&gt;
using common_type_t = typename common_type&lt;T...&gt;::type;
template &lt;class T&gt;
using underlying_type_t = typename underlying_type&lt;T&gt;::type;
template &lt;class T&gt;
using result_of_t = typename result_of&lt;T&gt;::type;
template &lt;class...&gt;
using void_t = void;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="unary-type-traits">3.29.2. Unary Type Traits</h4>
<div class="sect4">
<h5 id="additional-type-property-predicates">Additional type property predicates</h5>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 31. Additional type property predicates</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Template</strong></th>
<th class="tableblock halign-left valign-top"><strong>Condition</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; struct is_private;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; struct is_local;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; struct is_global;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; struct is_constant;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; struct is_generic;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; struct is_vector;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>T</code> is built-in vector type.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="additional-type-property-queries">Additional type property queries</h5>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 32. Additional type property queries</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Template</strong></th>
<th class="tableblock halign-left valign-top"><strong>Value</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; struct vector_size;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>T</code> names a built-in vector type, an integer value representing number of <code>T</code>'s components; otherwise <code>1</code>.</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="binary-type-traits">3.29.3. Binary type traits</h4>
<div class="sect4">
<h5 id="changed-relationships-traits">Changed relationships traits</h5>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 33. Changed relationship traits</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Template</strong></th>
<th class="tableblock halign-left valign-top"><strong>Condition</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T, class U&gt; struct is_same;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>T</code> and <code>U</code> name the same type with the same <em>cv qualifications</em>.</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="transformation-traits">3.29.4. Transformation traits</h4>
<div class="sect4">
<h5 id="address-space-and-vector-modifications">Address space and vector modifications</h5>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 34. Address space and vector traits</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Template</strong></th>
<th class="tableblock halign-left valign-top"><strong>Comments</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct remove_private;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct remove_local;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct remove_global;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct remove_constant;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct remove_generic;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct remove_as;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct remove_attrs;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct add_private;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct add_local;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct add_global;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct add_constant;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct add_generic;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation defined.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T&gt; Xstruct vector_element;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>T</code> is a built-in vector type, member typedef <code>T</code> shall name type of <code>T</code>'s component; otherwise it shall name <code>T</code>.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>template &lt;class T, size_t Dim&gt; struct make_vector;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If type <code>U</code> exists and names a built-in vector type with <code>Dim</code> components of type <code>T</code>, member typedef type shall name <code>U</code>; otherwise it shall name <code>T</code>.</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="iterator-library">3.30. Iterator Library</h3>
<div class="paragraph">
<p>OpenCL C++ implements part of iterator library (<em>chapter 24, [iterators]</em>) from the C++14 standard.
Primitives (C++14 standard, <em>section 24.4</em>), iterator operations (C++14 standard, <em>section 24.4.4,</em>), predefined iterators (C++14 standard, <em>section 24.5</em>) and range access (C++14 standard, <em>section 24.7</em>) are supported.</p>
</div>
<div class="paragraph">
<p>For the detailed description please refer to C++14 standard.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_iterator-synopsis">3.30.1. Header &lt;opencl_iterator&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
// primitives:
template&lt;class Iterator&gt; struct iterator_traits;
template&lt;class T&gt; struct iterator_traits&lt;T*&gt;;
template&lt;class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&amp;&gt; struct iterator;
struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag: public input_iterator_tag { };
struct bidirectional_iterator_tag: public forward_iterator_tag { };
struct random_access_iterator_tag: public bidirectional_iterator_tag { };
// iterator operations:
template &lt;class InputIterator, class Distance&gt;
void advance(InputIterator&amp; i, Distance n);
template &lt;class InputIterator&gt;
typename iterator_traits&lt;InputIterator&gt;::difference_type
distance(InputIterator first, InputIterator last);
template &lt;class ForwardIterator&gt;
ForwardIterator next(ForwardIterator x,
typename std::iterator_traits&lt;ForwardIterator&gt;::difference_type n = 1);
template &lt;class BidirectionalIterator&gt;
BidirectionalIterator prev(BidirectionalIterator x,
typename std::iterator_traits&lt;BidirectionalIterator&gt;::difference_type n = 1);
// predefined iterators:
template &lt;class Iterator&gt; class reverse_iterator;
template &lt;class Iterator1, class Iterator2&gt;
bool operator==(
const reverse_iterator&lt;Iterator1&gt;&amp; x,
const reverse_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&lt;(
const reverse_iterator&lt;Iterator1&gt;&amp; x,
const reverse_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator!=(
const reverse_iterator&lt;Iterator1&gt;&amp; x,
const reverse_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&gt;(
const reverse_iterator&lt;Iterator1&gt;&amp; x,
const reverse_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&gt;=(
const reverse_iterator&lt;Iterator1&gt;&amp; x,
const reverse_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&lt;=(
const reverse_iterator&lt;Iterator1&gt;&amp; x,
const reverse_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
auto operator-(
const reverse_iterator&lt;Iterator1&gt;&amp; x,
const reverse_iterator&lt;Iterator2&gt;&amp; y) -&gt;decltype(y.base() - x.base());
template &lt;class Iterator&gt;
reverse_iterator&lt;Iterator&gt;
operator+(typename reverse_iterator&lt;Iterator&gt;::difference_type n,
const reverse_iterator&lt;Iterator&gt;&amp; x);
template &lt;class Iterator&gt;
reverse_iterator&lt;Iterator&gt; make_reverse_iterator(Iterator i);
template &lt;class Container&gt; class back_insert_iterator;
template &lt;class Container&gt;
back_insert_iterator&lt;Container&gt; back_inserter(Container&amp; x);
template &lt;class Container&gt; class front_insert_iterator;
template &lt;class Container&gt;
front_insert_iterator&lt;Container&gt; front_inserter(Container&amp; x);
template &lt;class Container&gt; class insert_iterator;
template &lt;class Container&gt;
insert_iterator&lt;Container&gt; inserter(Container&amp; x,
typename Container::iterator i);
template &lt;class Iterator&gt; class move_iterator;
template &lt;class Iterator1, class Iterator2&gt;
bool operator==(
const move_iterator&lt;Iterator1&gt;&amp; x, const move_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator!=(
const move_iterator&lt;Iterator1&gt;&amp; x, const move_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&lt;(
const move_iterator&lt;Iterator1&gt;&amp; x, const move_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&lt;=(
const move_iterator&lt;Iterator1&gt;&amp; x, const move_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&gt;(
const move_iterator&lt;Iterator1&gt;&amp; x, const move_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
bool operator&gt;=(
const move_iterator&lt;Iterator1&gt;&amp; x, const move_iterator&lt;Iterator2&gt;&amp; y);
template &lt;class Iterator1, class Iterator2&gt;
auto operator-(
const move_iterator&lt;Iterator1&gt;&amp; x,
const move_iterator&lt;Iterator2&gt;&amp; y) -&gt; decltype(x.base() - y.base());
template &lt;class Iterator&gt;
move_iterator&lt;Iterator&gt; operator+(
typename move_iterator&lt;Iterator&gt;::difference_type n,
const move_iterator&lt;Iterator&gt;&amp; x);
template &lt;class Iterator&gt;
move_iterator&lt;Iterator&gt; make_move_iterator(Iterator i);
// range access:
template &lt;class C&gt; auto begin(C&amp; c) -&gt; decltype(c.begin());
template &lt;class C&gt; auto begin(const C&amp; c) -&gt; decltype(c.begin());
template &lt;class C&gt; auto end(C&amp; c) -&gt; decltype(c.end());
template &lt;class C&gt; auto end(const C&amp; c) -&gt; decltype(c.end());
template &lt;class T, size_t N&gt; constexpr T* begin(T (&amp;array)[N]) noexcept;
template &lt;class T, size_t N&gt; constexpr T* end(T (&amp;array)[N]) noexcept;
template &lt;class C&gt;
constexpr auto cbegin(const C&amp; c) noexcept(noexcept(std::begin(c)))
-&gt; decltype(std::begin(c));
template &lt;class C&gt;
constexpr auto cend(const C&amp; c) noexcept(noexcept(std::end(c)))
-&gt; decltype(std::end(c));
template &lt;class C&gt; auto rbegin(C&amp; c) -&gt; decltype(c.rbegin());
template &lt;class C&gt; auto rbegin(const C&amp; c) -&gt; decltype(c.rbegin());
template &lt;class C&gt; auto rend(C&amp; c) -&gt; decltype(c.rend());
template &lt;class C&gt; auto rend(const C&amp; c) -&gt; decltype(c.rend());
template &lt;class T, size_t N&gt; reverse_iterator&lt;T*&gt; rbegin(T (&amp;array)[N]);
template &lt;class T, size_t N&gt; reverse_iterator&lt;T*&gt; rend(T (&amp;array)[N]);
template &lt;class E&gt; reverse_iterator&lt;const E*&gt; rbegin(initializer_list&lt;E&gt; il);
template &lt;class E&gt; reverse_iterator&lt;const E*&gt; rend(initializer_list&lt;E&gt; il);
template &lt;class C&gt; auto crbegin(const C&amp; c) -&gt; decltype(std::rbegin(c));
template &lt;class C&gt; auto crend(const C&amp; c) -&gt; decltype(std::rend(c));
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="general-utilities-library">3.31. General Utilities Library</h3>
<div class="paragraph">
<p>OpenCL C++ implements part of utility library (<em>chapter 20.2, [utilities]</em>) from the C++14 standard.</p>
</div>
<div class="paragraph">
<p>For the detailed description please refer to C++14 standard.</p>
</div>
<div class="sect3">
<h4 id="header-opencl_utility-synopsis">3.31.1. Header &lt;opencl_utility&gt; Synopsis</h4>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>namespace cl
{
template&lt;class T&gt;
add_rvalue_reference_t&lt;T&gt; declval( );
template &lt;class T&gt;
constexpr T&amp;&amp; forward(typename remove_reference_t&amp; t) noexcept;
template &lt;class T&gt;
constexpr T&amp;&amp; forward(typename remove_reference_t&amp;&amp; t) noexcept;
template &lt;class T&gt;
constexpr typename remove_reference_t&amp;&amp; move(T&amp;&amp; t) noexcept;
template&lt;class T&gt;
void swap(T&amp; a, T&amp; b) noexcept;
template &lt;class T&gt;
constexpr conditional_t&lt;
!is_nothrow_move_constructible&lt;T&gt;::value &amp;&amp; is_copy_constructible&lt;T&gt;::value,
const T&amp;, T&amp;&amp;&gt; move_if_noexcept(T&amp; x) noexcept;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="opencl-numerical-compliance">4. OpenCL Numerical Compliance</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This section describes features of the C++14 and IEEE 754 standards that must be supported by all OpenCL compliant devices.</p>
</div>
<div class="paragraph">
<p>This section describes the functionality that must be supported by all OpenCL devices for single precision floating-point numbers.
Currently, only single precision and half precision floating-point is a requirement.
Double precision floating-point is an optional feature.</p>
</div>
<div class="sect2">
<h3 id="rounding-modes-1">4.1. Rounding Modes</h3>
<div class="paragraph">
<p>Floating-point calculations may be carried out internally with extra precision and then rounded to fit into the destination type.
IEEE 754 defines four possible rounding modes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Round to nearest even.</p>
</li>
<li>
<p>Round toward +infinity.</p>
</li>
<li>
<p>Round toward -infinity.</p>
</li>
<li>
<p>Round toward zero.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><em>Round to nearest even</em> is currently the only rounding mode required <a id="ftnref30"></a> <a href="#ftn30">[30]</a> by the OpenCL specification for single precision and double precision operations and is therefore the default rounding mode.
In addition, only static selection of rounding mode is supported.
Static and dynamic selection of rounding mode is not supported.</p>
</div>
</div>
<div class="sect2">
<h3 id="inf-nan-and-denormalized-numbers">4.2. INF, NaN and Denormalized Numbers</h3>
<div class="paragraph">
<p>INF and NaNs must be supported.
Support for signaling NaNs is not required.</p>
</div>
<div class="paragraph">
<p>Support for denormalized numbers with single precision floating-point is optional.
Denormalized single precision floating-point numbers passed as input or produced as the output of single precision floating-point operations such as add, sub, mul, divide, and the functions defined in <a href="#math-functions">Math Functions</a>, <a href="#common-functions">Common Functions</a> and <a href="#geometric-functions">Geometric Functions</a> may be flushed to zero.</p>
</div>
</div>
<div class="sect2">
<h3 id="floating-point-exceptions">4.3. Floating-Point Exceptions</h3>
<div class="paragraph">
<p>Floating-point exceptions are disabled in OpenCL.
The result of a floating-point exception must match the IEEE 754 spec for the exceptions not enabled case.
Whether and when the implementation sets floating-point flags or raises floating-point exceptions is implementation-defined.
This standard provides no method for querying, clearing or setting floating-point flags or trapping raised exceptions.
Due to non-performance, non-portability of trap mechanisms and the impracticality of servicing precise exceptions in a vector context (especially on heterogeneous hardware), such features are discouraged.</p>
</div>
<div class="paragraph">
<p>Implementations that nevertheless support such operations through an extension to the standard shall initialize with all exception flags cleared and the exception masks set so that exceptions raised by arithmetic operations do not trigger a trap to be taken.
If the underlying work is reused by the implementation, the implementation is however not responsible for reclearing the flags or resetting exception masks to default values before entering the kernel.
That is to say that kernels that do not inspect flags or enable traps are licensed to expect that their arithmetic will not trigger a trap.
Those kernels that do examine flags or enable traps are responsible for clearing flag state and disabling all traps before returning control to the implementation.
Whether or when the underlying work-item (and accompanying global floating-point state if any) is reused is implementation-defined.</p>
</div>
<div class="paragraph">
<p>The expressions math_errorhandling and MATH_ERREXCEPT are reserved for use by this standard, but not defined.
Implementations that extend this specification with support for floating-point exceptions shall define <code>math_errorhandling</code> and <code>MATH_ERREXCEPT</code> per ISO / IEC 9899 : TC2.</p>
</div>
</div>
<div class="sect2">
<h3 id="relative-error-as-ulps">4.4. Relative Error as ULPs</h3>
<div class="paragraph">
<p>In this section we discuss the maximum relative error defined as ulp (units in the last place).
Addition, subtraction, multiplication, fused multiply-add and conversion between integer and a single precision floating-point format are IEEE 754 compliant and are therefore correctly rounded.
Conversion between floating-point formats and explicit conversions specified in the <a href="#conversions-library"><em>Conversions Library</em></a> section must be correctly rounded.</p>
</div>
<div class="paragraph">
<p>The ULP is defined as follows:</p>
</div>
<div class="paragraph">
<p>If x is a real number that lies between two finite consecutive floating-point numbers a and b, without being equal to one of them, then ulp(x) = |b - a|, otherwise ulp(x) is the distance between the two non-equal finite floating-point numbers nearest x.
Moreover, ulp(NaN) is NaN.</p>
</div>
<div class="paragraph">
<p><em>Attribution: This definition was taken with consent from Jean-Michel Muller with slight clarification for behavior at zero.
Refer to <a href="ftp://ftp.inria.fr/INRIA/publication/publi-pdf/RR/RR-5504.pdf" class="bare">ftp://ftp.inria.fr/INRIA/publication/publi-pdf/RR/RR-5504.pdf</a></em></p>
</div>
<div class="paragraph">
<p><a href="#ulp_values_for_single_precision_builtin_math_functions">ULP values for single precision built-in math functions</a> <a id="ftnref31"></a> <a href="#ftn31">[31]</a> table describes the minimum accuracy of single precision floating-point arithmetic operations given as ULP values.
The reference value used to compute the ULP value of an arithmetic operation is the infinitely precise result.</p>
</div>
<table id="ulp_values_for_single_precision_builtin_math_functions" class="tableblock frame-all grid-all spread">
<caption class="title">Table 35. ULP values for single precision built-in math functions</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Function</strong></th>
<th class="tableblock halign-left valign-top"><strong>Min Accuracy - ULP values <a id="ftnref32"></a> <a href="#ftn32">[32]</a></strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> + <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> - <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> * <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0 / <em>x</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2.5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> / <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2.5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2pi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cbrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ceil</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">copysign</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erfc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">expm1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fabs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fdim</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">floor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmax</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmod</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fract</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">frexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hypot</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ilogb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ldexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log1p</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">logb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mad</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented either as a correctly rounded fma or as a multiply followed by an add both of which are correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">maxmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">minmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">modf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nextafter</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pow(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pown(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">powr(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remainder</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remquo</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rint</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rootn</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">round</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rsqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sincos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp for sine and cosine values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tgamma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">trunc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::cos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::divide</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::exp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::exp2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::exp10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::log2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::log10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::powr</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::recip</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::rsqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::sin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::sqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::tan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><a href="#ulp_values_for_single_precision_builtin_math_functions_for_embedded_profile">ULP values for single precision builtin math functions for embedded profile</a> table describes the minimum accuracy of single precision floating-point arithmetic operations given as ULP values for the embedded profile.
The reference value used to compute the ULP value of an arithmetic operation is the infinitely precise result.</p>
</div>
<table id="ulp_values_for_single_precision_builtin_math_functions_for_embedded_profile" class="tableblock frame-all grid-all spread">
<caption class="title">Table 36. ULP values for single precision built-in math functions for embedded profile</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Function</strong></th>
<th class="tableblock halign-left valign-top"><strong>Min Accuracy - ULP values <a href="#ftn32">[32]</a></strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> + <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> - <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> * <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0 / <em>x</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>x</em> / <em>y</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2pi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cbrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ceil</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">copysign</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erfc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">expm1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fabs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fdim</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">floor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmax</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmod</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fract</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">frexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hypot</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ilogb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ldexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log1p</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">logb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mad</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any value allowed (infinite ulp)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">maxmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">minmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">modf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nextafter</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pow(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pown(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">powr(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remainder</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remquo</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rint</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rootn</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">round</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rsqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sincos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp for sine and cosine values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tgamma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">trunc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_cos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_divide</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_exp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_exp2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_exp10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_log2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_log10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_powr</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_recip</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_rsqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_sin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_sqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">half_tan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 8192 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::cos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::divide</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::exp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::exp2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::exp10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::log2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::log10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::powr</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::recip</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::rsqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::sin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::sqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">native_math::tan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-defined</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><a href="#ulp_values_for_single_precision_builtin_math_functions_with_fast_relaxed_math">ULP values for single precision built-in math functions with unsafe math optimizations</a> table describes the minimum accuracy of commonly used single precision floating-point arithmetic operations given as ULP values if the <em>-cl-unsafe-math-optimizations</em> compiler option is specified when compiling or building an OpenCL program.
For derived implementations, the operations used in the derivation may themselves be relaxed according to <a href="#ulp_values_for_single_precision_builtin_math_functions_with_fast_relaxed_math">ULP values for single precision built-in math functions with unsafe math optimizations</a> table.
The minimum accuracy of math functions not defined in <a href="#ulp_values_for_single_precision_builtin_math_functions_with_fast_relaxed_math">ULP values for single precision built-in math functions with unsafe math optimizations</a> table when the <em>-cl-unsafe-math-optimizations</em> compiler option is specified is as defined in <a href="#ulp_values_for_single_precision_builtin_math_functions">ULP values for single precision built-in math functions</a> table when operating in the full profile, and as defined in <a href="#ulp_values_for_single_precision_builtin_math_functions_for_embedded_profile">ULP values for single precision built-in math functions for embedded profile</a> table when operating in the embedded profile.
The reference value used to compute the ULP value of an arithmetic operation is the infinitely precise result.</p>
</div>
<table id="ulp_values_for_single_precision_builtin_math_functions_with_fast_relaxed_math" class="tableblock frame-all grid-all spread">
<caption class="title">Table 37. ULP values for single precision built-in math functions with unsafe math optimizations in the full and embedded profiles</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Function</strong></th>
<th class="tableblock halign-left valign-top"><strong>Min Accuracy - ULP values <a href="#ftn32">[32]</a></strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0 / x</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2.5 ulp for x in the domain of 2<sup>-126</sup> to 2<sup>126</sup> for the full profile, and &lt;= 3 ulp for the embedded profile.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x / y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2.5 ulp for x in the domain of 2<sup>-62</sup> to 2<sup>62</sup> and <em>y</em> in the domain of 2<sup>-62</sup> to 2<sup>62</sup> for the full profile, and &lt;= 3 ulp for the embedded profile.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acos(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4096 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acospi(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as acos(x) * M_PI_F.
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asin(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4096 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinpi(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as asin(x) * M_PI_F.
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4096 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2(y, x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as atan(y/x) for x &gt; 0, atan(y/x) + M_PI_F for x &lt; 0 and y &gt; 0 and atan(y/x) - M_PI_F for x &lt; 0 and y &lt; 0.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanpi(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as atan(x) * M_1_PI_F.
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2pi(y, x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as atan2(y, x) * M_1_PI_F.
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acosh(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as log( x + sqrt(x*x - 1) ).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinh(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as log( x + sqrt(x*x + 1) ).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanh(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defined for x in the domain (-1, 1). For x in [-2<sup>-10</sup>, 2<sup>-10</sup>], implemented as x.
For x outside of [-2<sup>-10</sup>, 2<sup>-10</sup>], implemented as 0.5f * log( (1.0f + x) / (1.0f - x) ).
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cbrt(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented as rootn(x, 3).
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cos(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For x in the domain [-π, π], the maximum absolute error is &lt;= 2<sup>-11</sup> and larger otherwise.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cosh(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defined for x in the domain [-88, 88] and implemented as 0.5f * ( exp(x) + exp(-x) ).
For non-derived implementations, the error is &lt;= 8192 ULP.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cospi(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For x in the domain [-1, 1], the maximum absolute error is &lt;= 2<sup>-11</sup> and larger otherwise.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 + floor( fabs(2 * x) ) ulp for the full profile, and &lt;= 4 ulp for the embedded profile.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp2(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 + floor( fabs(2 * x) ) ulp for the full profile, and &lt;= 4 ulp for the embedded profile.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp10(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Derived implementations implement this as exp2( x * log2(10) ).
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">expm1(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Derived implementations implement this as exp(x) - 1.
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For x in the domain [0.5, 2] the maximum absolute error is &lt;= 2<sup>-21</sup>; otherwise the maximum error is &lt;=3 ulp for the full profile and &lt;= 4 ulp for the embedded profile</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log2(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For x in the domain [0.5, 2] the maximum absolute error is &lt;= 2<sup>-21</sup>; otherwise the maximum error is &lt;=3 ulp for the full profile and &lt;= 4 ulp for the embedded profile</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log10(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For x in the domain [0.5, 2] the maximum absolute error is &lt;= 2<sup>-21</sup>; otherwise the maximum error is &lt;=3 ulp for the full profile and &lt;= 4 ulp for the embedded profile</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log1p(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Derived implementations implement this as log(x + 1).
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pow(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Undefined for x = 0 and y = 0.
Undefined for x &lt; 0 and non-integer y.
Undefined for x &lt; 0 and y outside the domain [-2<sup>24</sup>, 2<sup>24</sup>].
For x &gt; 0 or x &lt; 0 and even y, derived implementations implement this as exp2( y * log2(x) ).
For x &lt; 0 and odd y, derived implementations implement this as -exp2( y * log2(fabs(x) ) <a id="ftnref33"></a> <a href="#ftn33">[33]</a>.
For x == 0 and nonzero y, derived implementations return zero.
For non-derived implementations, the error is &lt;= 8192 ULP.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pown(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defined only for integer values of y.
Undefined for x = 0 and y = 0.
For x &gt;= 0 or x &lt; 0 and even y, derived implementations implement this as exp2( y * log2(x) ).
For x &lt; 0 and odd y, derived implementations implement this as -exp2( y * log2( fabs(x) ) ).
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">powr(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defined only for x &gt;= 0.
Undefined for x = 0 and y = 0.
Derived implementations implement this as exp2( y * log2(x) ).
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rootn(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defined for x &gt; 0 when y is non-zero, derived implementations implement this case as exp2( log2(x) / y ). Defined for x &lt; 0 when y is odd, derived implementations implement this case as -exp2( log2(-x) / y ).
Defined for x = +/-0 when y &gt; 0, derived implementations will return +0 in this case.
For non-derived implementations, the error is &lt;= 8192 ULP.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sin(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For x in the domain [-π, π], the maximum absolute error is &lt;= 2<sup>-11</sup> and larger otherwise.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sincos(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">ulp values as defined for sin(x) and cos(x).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinh(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defined for x in the domain [-88, 88].
For x in [-2<sup>-10</sup>, 2<sup>-10</sup>], derived implementations implement as x.
For x outside of [-2<sup>-10</sup>, 2<sup>-10</sup>], derived implement as 0.5f * ( exp(x) - exp(-x) ).
For non-derived implementations, the error is &lt;= 8192 ULP.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinpi(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">For x in the domain [-1, 1], the maximum absolute error is &lt;= 2<sup>-11</sup> and larger otherwise.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tan(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Derived implementations implement this as sin(x) * ( 1.0f / cos(x) ).
For non-derived implementations, the error is &lt;= 8192 ulp.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Defined for x in the domain [-88, 88].
For x in [-2<sup>-10</sup>, 2<sup>-10</sup>], derived implementations implement as x.
For x outside of [-2<sup>-10</sup>, 2<sup>-10</sup>], derived implementations implement as ( exp(x) - exp(-x) ) / ( exp(x) + exp(-x) ).
For non-derived implementations, the error is &lt;= 8192 ULP.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanpi(x)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Derived implementations implement this as tan(x * M_PI_F).
For non-derived implementations, the error is &lt;= 8192 ulp for x in the domain [-1, 1].</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x * y + z</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented either as a correctly rounded fma or as a multiply and an add both of which are correctly rounded.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><a href="#ulp_values_for_double_precision_builtin_math_functions">ULP values for double precision built-in math functions</a> table describes the minimum accuracy of double precision floating-point arithmetic operations given as ULP values.
The reference value used to compute the ULP value of an arithmetic operation is the infinitely precise result.</p>
</div>
<table id="ulp_values_for_double_precision_builtin_math_functions" class="tableblock frame-all grid-all spread">
<caption class="title">Table 38. ULP values for double precision built-in math functions</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Function</strong></th>
<th class="tableblock halign-left valign-top"><strong>Min Accuracy - ULP values <a href="#ftn32">[32]</a></strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x + y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x - y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x * y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0 / x</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x / y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2pi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cbrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ceil</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">copysign</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erfc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">expm1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fabs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fdim</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">floor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmax</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmod</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fract</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">frexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hypot</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ilogb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ldexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 3 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log1p</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">logb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mad</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented either as a correctly rounded fma or as a multiply followed by an add both of which are correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">maxmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">minmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">modf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nextafter</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pow(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pown(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">powr(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remainder</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remquo</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rint</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rootn</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">round</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rsqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sincos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp for sine and cosine values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 5 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 6 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tgamma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 16 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">trunc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><a href="#ulp_values_for_half_precision_builtin_math_functions">ULP values for half precision built-in math functions</a> table describes the minimum accuracy of half precision floating-point arithmetic operations given as ULP values.
The reference value used to compute the ULP value of an arithmetic operation is the infinitely precise result.</p>
</div>
<table id="ulp_values_for_half_precision_builtin_math_functions" class="tableblock frame-all grid-all spread">
<caption class="title">Table 39. ULP values for half precision built-in math functions</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Function</strong></th>
<th class="tableblock halign-left valign-top"><strong>Min Accuracy - ULP values <a href="#ftn32">[32]</a></strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x + y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x - y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x * y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0 / x</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">x / y</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atan2pi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">asinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">atanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cbrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ceil</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">copysign</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cosh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cospi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erfc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">erf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">exp10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">expm1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fabs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fdim</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">floor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmax</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fmod</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fract</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">frexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">hypot</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ilogb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ldexp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">log1p</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">logb</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mad</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implemented either as a correctly rounded fma or as a multiply followed by an add both of which are correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">maxmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">minmag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">modf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nextafter</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pow(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">pown(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">powr(x, y)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remainder</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">remquo</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rint</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rootn</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">round</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">rsqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 1 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sincos</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp for sine and cosine values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sinpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">sqrt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tan</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanh</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tanpi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 2 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">tgamma</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;= 4 ulp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">trunc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Correctly rounded</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="edge-case-behavior">4.5. Edge Case Behavior</h3>
<div class="paragraph">
<p>The edge case behavior of the math functions (see the <a href="#math-functions"><em>Math Functions</em></a> section) shall conform to sections F.9 and G.6 of ISO/IEC 9899:TC 2, except where noted below in the <a href="#additional-requirements-beyond-isoiec-9899tc2"><em>Additional Requirements Beyond ISO/IEC 9899:TC2</em></a> section.</p>
</div>
<div class="sect3">
<h4 id="additional-requirements-beyond-isoiec-9899tc2">4.5.1. Additional Requirements Beyond ISO/IEC 9899:TC2</h4>
<div class="paragraph">
<p>Functions that return a NaN with more than one NaN operand shall return one of the NaN operands.
Functions that return a NaN operand may silence the NaN if it is a signaling NaN.
A non-signaling NaN shall be converted to a non-signaling NaN.
A signaling NaN shall be converted to a NaN, and should be converted to a non-signaling NaN.
How the rest of the NaN payload bits or the sign of NaN is converted is undefined.</p>
</div>
<div class="paragraph">
<p>The usual allowances for rounding error (see the <a href="#relative-error-as-ulps"><em>Relative Error as ULPs</em></a> section) or flushing behavior (see the <a href="#edge-case-behavior-in-flush-to-zero-mode"><em>Edge Case Behavior in Flush To Zero Mode</em></a> section) shall not apply for those values for which <em>section F.9</em> of ISO/IEC 9899:,TC2, or the <a href="#additional-requirements-beyond-isoiec-9899tc2"><em>Additional Requirements Beyond ISO/IEC 9899:TC2</em></a> and the <a href="#edge-case-behavior-in-flush-to-zero-mode"><em>Edge Case Behavior in Flush To Zero Mode</em></a> sections below (and similar sections for other floating-point precisions) prescribe a result (e.g. ceil( -1 &lt; x &lt; 0 ) returns -0).
Those values shall produce exactly the prescribed answers, and no other.
Where the ± symbol is used, the sign shall be preserved.
For example, sin(±0) = ±0 shall be interpreted to mean sin(+0) is +0 and sin(-0) is -0.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>acospi( 1 ) = +0.</p>
</li>
<li>
<p>acospi( x ) returns a NaN for | x | &gt; 1.</p>
</li>
<li>
<p>asinpi( ±0 ) = ±0.</p>
</li>
<li>
<p>asinpi( x ) returns a NaN for | x | &gt; 1.</p>
</li>
<li>
<p>atanpi( ±0 ) = ±0.</p>
</li>
<li>
<p>atanpi ( ±∞ ) = ±0.5.</p>
</li>
<li>
<p>atan2pi ( ±0, -0 ) = ±1.</p>
</li>
<li>
<p>atan2pi ( ±0, +0 ) = ±0.</p>
</li>
<li>
<p>atan2pi ( ±0, x ) returns ±1 for x &lt; 0.</p>
</li>
<li>
<p>atan2pi ( ±0, x) returns ±0 for x &gt; 0.</p>
</li>
<li>
<p>atan2pi ( y, ±0 ) returns -0.5 for y &lt; 0.</p>
</li>
<li>
<p>atan2pi ( y, ±0 ) returns 0.5 for y &gt; 0.</p>
</li>
<li>
<p>atan2pi ( ±y, -∞ ) returns ±1 for finite y &gt; 0.</p>
</li>
<li>
<p>atan2pi ( ±y, +∞ ) returns ±0 for finite y &gt; 0.</p>
</li>
<li>
<p>atan2pi ( ±∞, x ) returns ±0.5 for finite x.</p>
</li>
<li>
<p>atan2pi ( ±∞, -∞ ) returns ±0.75.</p>
</li>
<li>
<p>atan2pi ( ±∞, +∞ ) returns ±0.25.</p>
</li>
<li>
<p>ceil( -1 &lt; x &lt; 0 ) returns -0.</p>
</li>
<li>
<p>cospi( ±0 ) returns 1</p>
</li>
<li>
<p>cospi( n + 0.5 ) is +0 for any integer n where n + 0.5 is representable.</p>
</li>
<li>
<p>cospi( ±∞ ) returns a NaN.</p>
</li>
<li>
<p>exp10( ±0 ) returns 1.</p>
</li>
<li>
<p>exp10( -∞ ) returns +0.</p>
</li>
<li>
<p>exp10( +∞ ) returns +∞.</p>
</li>
<li>
<p>distance( x, y ) calculates the distance from x to y without overflow or extraordinary precision loss due to underflow.</p>
</li>
<li>
<p>fdim( any, NaN ) returns NaN.</p>
</li>
<li>
<p>fdim( NaN, any ) returns NaN.</p>
</li>
<li>
<p>fmod( ±0, NaN ) returns NaN.</p>
</li>
<li>
<p>frexp( ±∞, exp ) returns ±∞ and stores 0 in exp.</p>
</li>
<li>
<p>frexp( NaN, exp ) returns the NaN and stores 0 in exp.</p>
</li>
<li>
<p>fract( x, iptr) shall not return a value greater than or equal to 1.0, and shall not return a value less than 0.</p>
</li>
<li>
<p>fract( +0, iptr ) returns +0 and +0 in iptr.</p>
</li>
<li>
<p>fract( -0, iptr ) returns -0 and -0 in iptr.</p>
</li>
<li>
<p>fract( +inf, iptr ) returns +0 and +inf in iptr.</p>
</li>
<li>
<p>fract( -inf, iptr ) returns -0 and -inf in iptr.</p>
</li>
<li>
<p>fract( NaN, iptr ) returns the NaN and NaN in iptr.</p>
</li>
<li>
<p>length calculates the length of a vector without overflow or extraordinary precision loss due to underflow.</p>
</li>
<li>
<p>lgamma_r( x, signp ) returns 0 in signp if x is zero or a negative integer.</p>
</li>
<li>
<p>nextafter( -0, y &gt; 0 ) returns smallest positive denormal value.</p>
</li>
<li>
<p>nextafter( +0, y &lt; 0 ) returns smallest negative denormal value.</p>
</li>
<li>
<p>normalize shall reduce the vector to unit length, pointing in the same direction without overflow or extraordinary precision loss due to underflow.</p>
</li>
<li>
<p>normalize( v ) returns v if all elements of v are zero.</p>
</li>
<li>
<p>normalize( v ) returns a vector full of NaNs if any element is a NaN.</p>
</li>
<li>
<p>normalize( v ) for which any element in v is infinite shall proceed as if the elements in v were replaced as follows:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>for( i = 0; i &lt; sizeof(v) / sizeof(v[0] ); i++ )
v[i] = isinf(v[i] ) ? copysign(1.0, v[i]) : 0.0 * v [i];</code></pre>
</div>
</div>
</li>
<li>
<p>pow( ±0, -∞ ) returns +∞</p>
</li>
<li>
<p>pown( x, 0 ) is 1 for any x, even zero, NaN or infinity.</p>
</li>
<li>
<p>pown( ±0, n ) is ±∞ for odd n &lt; 0.</p>
</li>
<li>
<p>pown( ±0, n ) is +∞ for even n &lt; 0.</p>
</li>
<li>
<p>pown( ±0, n ) is +0 for even n &gt; 0.</p>
</li>
<li>
<p>pown( ±0, n ) is ±0 for odd n &gt; 0.</p>
</li>
<li>
<p>powr( x, ±0 ) is 1 for finite x &gt; 0.</p>
</li>
<li>
<p>powr( ±0, y ) is +∞ for finite y &lt; 0.</p>
</li>
<li>
<p>powr( ±0, -∞) is +∞.</p>
</li>
<li>
<p>powr( ±0, y ) is +0 for y &gt; 0.</p>
</li>
<li>
<p>powr( +1, y ) is 1 for finite y.</p>
</li>
<li>
<p>powr( x, y ) returns NaN for x &lt; 0.</p>
</li>
<li>
<p>powr( ±0, ±0 ) returns NaN.</p>
</li>
<li>
<p>powr( +∞, ±0 ) returns NaN.</p>
</li>
<li>
<p>powr( +1, ±∞ ) returns NaN.</p>
</li>
<li>
<p>powr( x, NaN ) returns the NaN for x &gt;= 0.</p>
</li>
<li>
<p>powr( NaN, y ) returns the NaN.</p>
</li>
<li>
<p>rint( -0.5 &lt;= x &lt; 0 ) returns -0.</p>
</li>
<li>
<p>remquo(x, y, &amp;quo) returns a NaN and 0 in quo if x is ±∞, or if y is 0 and the other argument is non-NaN or if either argument is a NaN.</p>
</li>
<li>
<p>rootn( ±0, n ) is ±∞ for odd n &lt; 0.</p>
</li>
<li>
<p>rootn( ±0, n ) is +∞ for even n &lt; 0.</p>
</li>
<li>
<p>rootn( ±0, n ) is +0 for even n &gt; 0.</p>
</li>
<li>
<p>rootn( ±0, n ) is ±0 for odd n &gt; 0.</p>
</li>
<li>
<p>rootn( x, n ) returns a NaN for x &lt; 0 and n is even.</p>
</li>
<li>
<p>rootn( x, 0 ) returns a NaN.</p>
</li>
<li>
<p>round( -0.5 &lt; x &lt; 0 ) returns -0.</p>
</li>
<li>
<p>sinpi( ±0 ) returns ±0.</p>
</li>
<li>
<p>sinpi( +n) returns +0 for positive integers n.</p>
</li>
<li>
<p>sinpi( -n ) returns -0 for negative integers n.</p>
</li>
<li>
<p>sinpi( ±∞ ) returns a NaN.</p>
</li>
<li>
<p>tanpi( ±0 ) returns ±0.</p>
</li>
<li>
<p>tanpi( ±∞ ) returns a NaN.</p>
</li>
<li>
<p>tanpi( n ) is copysign( 0.0, n ) for even integers n.</p>
</li>
<li>
<p>tanpi( n ) is copysign( 0.0, - n) for odd integers n.</p>
</li>
<li>
<p>tanpi( n + 0.5 ) for even integer n is +∞ where n + 0.5 is representable.</p>
</li>
<li>
<p>tanpi( n + 0.5 ) for odd integer n is -∞ where n + 0.5 is representable.</p>
</li>
<li>
<p>trunc( -1 &lt; x &lt; 0 ) returns -0.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="changes-to-isoiec-9899-tc2-behavior">4.5.2. Changes to ISO/IEC 9899: TC2 Behavior</h4>
<div class="paragraph">
<p><code>modf</code> behaves as though implemented by:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>gentype modf( gentype value, gentype *iptr )
{
*iptr = trunc( value );
return copysign( isinf( value ) ? 0.0 : value - *iptr, value );
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>rint always rounds according to round to nearest even rounding mode even if the caller is in some other rounding mode.</p>
</div>
</div>
<div class="sect3">
<h4 id="edge-case-behavior-in-flush-to-zero-mode">4.5.3. Edge Case Behavior in Flush To Zero Mode</h4>
<div class="paragraph">
<p>If denormals are flushed to zero, then a function may return one of four results:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Any conforming result for non-flush-to-zero mode.</p>
</li>
<li>
<p>If the result given by 1. is a sub-normal before rounding, it may be flushed to zero.</p>
</li>
<li>
<p>Any non-flushed conforming result for the function if one or more of its sub-normal operands are flushed to zero.</p>
</li>
<li>
<p>If the result of 3. is a sub-normal before rounding, the result may be flushed to zero.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In each of the above cases, if an operand or result is flushed to zero, the sign of the zero is undefined.</p>
</div>
<div class="paragraph">
<p>If subnormals are flushed to zero, a device may choose to conform to the following edge cases for nextafter instead of those listed in the <a href="#additional-requirements-beyond-isoiec-9899tc2"><em>Additional Requirements Beyond ISO/IEC 9899:TC2</em></a> section:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>nextafter ( +smallest normal, y &lt; +smallest normal ) = +0.</p>
</li>
<li>
<p>nextafter ( -smallest normal, y &gt; -smallest normal ) = -0.</p>
</li>
<li>
<p>nextafter ( -0, y &gt; 0 ) returns smallest positive normal value.</p>
</li>
<li>
<p>nextafter ( +0, y &lt; 0 ) returns smallest negative normal value.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For clarity, subnormals or denormals are defined to be the set of representable numbers in the range 0 &lt; x &lt; <code>TYPE_MIN</code> and <code>-TYPE_MIN</code> &lt; x &lt; -0.
They do not include ±0.
A non-zero number is said to be sub-normal before rounding if after normalization, its radix-2 exponent is less than <code>(TYPE_MIN_EXP - 1)</code>. <a id="ftnref35"></a> <a href="#ftn35">[35]</a></p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="image-addressing-and-filtering">5. Image Addressing and Filtering</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let w<sub>t</sub>, h<sub>t</sub> and d<sub>t</sub> be the width, height (or image array size for a 1D image array) and depth (or image array size for a 2D image array) of the image in pixels.
Let coord.xy also referred to as (s,t) or coord.xyz also referred to as (s,t,r) be the coordinates specified to <code>image::read</code>.
The sampler specified in <code>image::read</code> is used to determine how to sample the image and return an appropriate color.</p>
</div>
<div class="sect2">
<h3 id="image-coordinates">5.1. Image Coordinates</h3>
<div class="paragraph">
<p>This affects the interpretation of image coordinates.
If image coordinates specified to <code>image::read</code> are normalized (as specified in the sampler), the s,t, and r coordinate values are multiplied by w<sub>t</sub>, h<sub>t,</sub> and d<sub>t</sub> respectively to generate the unnormalized coordinate values.
For image arrays, the image array coordinate (i.e. t if it is a 1D image array or r if it is a 2D image array) specified to <code>image::read</code> must always be the unnormalized image coordinate value.</p>
</div>
<div class="paragraph">
<p>Let (u,v,w) represent the unnormalized image coordinate values.</p>
</div>
</div>
<div class="sect2">
<h3 id="addressing-and-filter-modes">5.2. Addressing and Filter Modes</h3>
<div class="paragraph">
<p>We first describe how the addressing and filter modes are applied to generate the appropriate sample locations to read from the image if the addressing mode is not <code>addressing_mode::repeat</code> nor <code>addressing_mode::mirrored_repeat</code>.</p>
</div>
<div class="paragraph">
<p>After generating the image coordinate (u,v,w) we apply the appropriate addressing and filter mode to generate the appropriate sample locations to read from the image.</p>
</div>
<div class="paragraph">
<p>If values in (u,v,w) are INF or NaN, the behavior of <code>image::read</code> is undefined.</p>
</div>
<div class="sect3">
<h4 id="filtering_modenearest">5.2.1. filtering_mode::nearest</h4>
<div class="paragraph">
<p>When filter mode is <code>filtering_mode::nearest</code>, the image element in the image that is nearest (in Manhattan distance) to that specified by (u,v,w) is obtained.
This means the image element at location (i,j,k) becomes the image element value, where</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
i &amp;=&amp; address\_mode((int)floor(u))\\
j &amp;=&amp; address\_mode((int)floor(v))\\
k &amp;=&amp; address\_mode((int)floor(w))
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>For a 3D image, the image element at location (i, j, k) becomes the color value.
For a 2D image, the image element at location (i, j) becomes the color value.</p>
</div>
<div class="paragraph">
<p>The below table describes the <code>address_mode</code> function.</p>
</div>
<table id="addressing_modes_to_generate_texel_location" class="tableblock frame-all grid-all spread">
<caption class="title">Table 40. Addressing modes to generate texel location</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top"><strong>Addressing Mode</strong></th>
<th class="tableblock halign-left valign-top"><strong>Result of address_mode(coord)</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><code>clamp_to_edge</code></p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>clamp (coord, 0, size - 1)</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><code>clamp</code></p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>clamp (coord, -1, size)</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><code>none</code></p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Coord</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The size term in <a href="#addressing_modes_to_generate_texel_location">Addressing modes to generate texel location</a> table is w<sub>t</sub> for u, h<sub>t</sub> for v and d<sub>t</sub> for w.</p>
</div>
<div class="paragraph">
<p>The clamp function used in <a href="#addressing_modes_to_generate_texel_location">Addressing modes to generate texel location</a> table is defined as:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"></dt>
<dd>
<p>\(clamp(a, b, c) = return (a &lt; b) ? b : ((a &gt; c) ? c : a)\)</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>If the selected texel location (i,j,k) refers to a location outside the image, the border color is used as the color value for this texel.</p>
</div>
</div>
<div class="sect3">
<h4 id="filtering_modelinear">5.2.2. filtering_mode::linear</h4>
<div class="paragraph">
<p>When filter mode is <code>filtering_mode::linear</code>, a 2 x 2 square of image elements for a 2D image or a 2 x 2 x 2 cube of image elements for a 3D image is selected.
This 2 x 2 square or 2 x 2 x 2 cube is obtained as follows.</p>
</div>
<div class="paragraph">
<p>Let</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
i0 &amp; = address\_mode((int)floor(u - 0.5))\\
j0 &amp; = address\_mode((int)floor(v - 0.5))\\
k0 &amp; = address\_mode((int)floor(w - 0.5))\\
i1 &amp; = address\_mode((int)floor(u - 0.5) + 1)\\
j1 &amp; = address\_mode((int)floor(v - 0.5) + 1)\\
k1 &amp; = address\_mode((int)floor(w - 0.5) + 1)\\
a &amp; = frac(u - 0.5)\\
b &amp; = frac(v - 0.5)\\
c &amp; = frac(w - 0.5)
\end{aligned}\]
</div>
</div>
<div class="paragraph">
<p>where frac(x) denotes the fractional part of x and is computed as x - floor(x).</p>
</div>
<div class="paragraph">
<p>For a 3D image, the image element value is found as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
T &amp;=&amp; (1 - a) * (1 - b) * (1 - c) * T_{i0j0k0}\\
&amp; &amp; {} + a * (1 - b) * (1 - c) * T_{i1j0k0}\\
&amp; &amp; {} + (1 - a) * b * (1 - c) * T_{i0j1k0}\\
&amp; &amp; {} + a * b * (1 - c) * T_{i1j1k0}\\
&amp; &amp; {} + (1 - a) * (1 - b) * c * T_{i0j0k1}\\
&amp; &amp; {} + a * (1 - b) * c * T_{i1j0k1}\\
&amp; &amp; {} + (1 - a) * b * c * T_{i0j1k1}\\
&amp; &amp; {} + a * b * c * T_{i1j1k1}
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where T<sub>ijk</sub> is the image element at location (i,j,k) in the 3D image.</p>
</div>
<div class="paragraph">
<p>For a 2D image, the image element value is found as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
T &amp;=&amp; (1 - a) * (1 - b) * T_{i0j0}\\
&amp; &amp; {} + a * (1 - b) * T_{i1j0}\\
&amp; &amp; {} + (1 - a) * b * T_{i0j1}\\
&amp; &amp; {} + a * b * T_{i1j1}
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where T<sub>ij</sub> is the image element at location (i,j) in the 2D image.</p>
</div>
<div class="paragraph">
<p>If any of the selected T<sub>ijk</sub> or T<sub>ij</sub> in the above equations refers to a location outside the image, the border color is used as the color value for T<sub>ijk</sub> or T<sub>ij</sub>.</p>
</div>
<div class="paragraph">
<p>If the image channel type is <code>CL_FLOAT</code> or <code>CL_HALF_FLOAT</code> and any of the image elements T<sub>ijk</sub> or T<sub>ij</sub> is INF or NaN, the behavior of the built-in image read function is undefined.</p>
</div>
<div class="paragraph">
<p>We now discuss how the addressing and filter modes are applied to generate the appropriate sample locations to read from the image if the addressing mode is <code>addressing_mode::repeat</code>.</p>
</div>
<div class="paragraph">
<p>If values in (s,t,r) are INF or NaN, the behavior of the built-in image read functions is undefined.</p>
</div>
</div>
<div class="sect3">
<h4 id="filtering_modenearest-1">5.2.3. filtering_mode::nearest</h4>
<div class="paragraph">
<p>When filter mode is <code>filtering_mode::nearest</code>, the image element at location (i,j,k) becomes the image element value, with i, j and k computed as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{l}
u = (s - floor(s)) * w_t\\
i = (int)floor(u)\\
if\ (i &gt; w_t - 1)\\
\qquad i = i - w_t\\
v = (t - floor(t)) * h_t\\
j = (int)floor(v)\\
if\ (j &gt; h_t - 1)\\
\qquad j = j - h_t\\
w = (r - floor(r)) * d_t\\
k = (int)floor(w)\\
if\ (k &gt; d_t - 1)\\
\qquad k = k - d_t
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>For a 3D image, the image element at location (i, j, k) becomes the color value.
For a 2D image, the image element at location (i, j) becomes the color value.</p>
</div>
</div>
<div class="sect3">
<h4 id="filtering_modelinear-1">5.2.4. filtering_mode::linear</h4>
<div class="paragraph">
<p>When filter mode is <code>filtering_mode::linear</code>, a 2 x 2 square of image elements for a 2D image or a 2 x 2 x 2 cube of image elements for a 3D image is selected.
This 2 x 2 square or 2 x 2 x 2 cube is obtained as follows.</p>
</div>
<div class="paragraph">
<p>Let</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{l}
u = (s - floor(s)) * w_t\\
i0 = (int)floor(u - 0.5)\\
i1 = i0 + 1\\
if (i0 &lt; 0)\\
i0 = w_t + i0\\
if\ (i1 &gt; w_t - 1)\\
\qquad i1 = i1 - w_t\\
v = (t - floor(t)) * h_t\\
j0 = (int)floor(v - 0.5)\\
j1 = j0 + 1\\
if (j0 &lt; 0)\\
j0 = h_t + j0\\
if\ (j1 &gt; h_t - 1)\\
\qquad j1 = j1 - h_t\\
w = (r - floor(r)) * d_t\\
k0 = (int)floor(w - 0.5)\\
k1 = k0 + 1\\
if (k0 &lt; 0)\\
\qquad k0 = d_t + k0\\
if\ (k1 &gt; d_t - 1)\\
\qquad k1 = k1 - d_t\\
a = frac(u - 0.5)\\
b = frac(v - 0.5)\\
c = frac(w - 0.5)
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where frac(x) denotes the fractional part of x and is computed as x - floor(x).</p>
</div>
<div class="paragraph">
<p>For a 3D image, the image element value is found as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
T &amp;=&amp; (1 - a) * (1 - b) * (1 - c) * T_{i0j0k0}\\
&amp; &amp; {} + a * (1 - b) * (1 - c) * T_{i1j0k0}\\
&amp; &amp; {} + (1 - a) * b * (1 - c) * T_{i0j1k0}\\
&amp; &amp; {} + a * b * (1 - c) * T_{i1j1k0}\\
&amp; &amp; {} + (1 - a) * (1 - b) * c * T_{i0j0k1}\\
&amp; &amp; {} + a * (1 - b) * c * T_{i1j0k1}\\
&amp; &amp; {} + (1 - a) * b * c * T_{i0j1k1}\\
&amp; &amp; {} + a * b * c * T_{i1j1k1}
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where T<sub>ijk</sub> is the image element at location (i,j,k) in the 3D image.</p>
</div>
<div class="paragraph">
<p>For a 2D image, the image element value is found as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
T &amp;=&amp; (1 - a) * (1 - b) * T_{i0j0}\\
&amp; &amp; {} + a * (1 - b) * T_{i1j0}\\
&amp; &amp; {} + (1 - a) * b * T_{i0j1}\\
&amp; &amp; {} + a * b * T_{i1j1}
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where T<sub>ij</sub> is the image element at location (i,j) in the 2D image.</p>
</div>
<div class="paragraph">
<p>If the image channel type is <code>CL_FLOAT</code> or <code>CL_HALF_FLOAT</code> and any of the image elements T<sub>ijk</sub> or T<sub>ij</sub> is INF or NaN, the behavior of the built-in image read function is undefined.</p>
</div>
<div class="paragraph">
<p>We now discuss how the addressing and filter modes are applied to generate the appropriate sample locations to read from the image if the addressing mode is <code>addressing_mode::repeat</code>.
The <code>addressing_mode::mirrored_repeat</code> addressing mode causes the image to be read as if it is tiled at every integer seam with the interpretation of the image data flipped at each integer crossing.
For example, the (s,t,r) coordinates between 2 and 3 are addressed into the image as coordinates from 1 down to 0.
If values in (s,t,r) are INF or NaN, the behavior of the built-in image read functions is undefined.</p>
</div>
</div>
<div class="sect3">
<h4 id="filtering_modenearest-2">5.2.5. filtering_mode::nearest</h4>
<div class="paragraph">
<p>When filter mode is <code>filtering_mode::nearest</code>, the image element at location (i,j,k) becomes the image element value, with i,j and k computed as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
s' &amp;=&amp; 2.0f * rint(0.5f * s)\\
s' &amp;=&amp; fabs(s - s')\\
u &amp;=&amp; s' * w_t\\
i &amp;=&amp; (int)floor(u)\\
i &amp;=&amp; min(i, w_t - 1)\\
t' &amp;=&amp; 2.0f * rint(0.5f * t)\\
t' &amp;=&amp; fabs(t - t')\\
v &amp;=&amp; t' * h_t\\
j &amp;=&amp; (int)floor(v)\\
j &amp;=&amp; min(j, h_t - 1)\\
r' &amp;=&amp; 2.0f * rint(0.5f * r)\\
r' &amp;=&amp; fabs(r - r')\\
w &amp;=&amp; r' * d_t\\
k &amp;=&amp; (int)floor(w)\\
k &amp;=&amp; min(k, d_t - 1)
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>For a 3D image, the image element at location (i, j, k) becomes the color value.
For a 2D image, the image element at location (i, j) becomes the color value.</p>
</div>
</div>
<div class="sect3">
<h4 id="filtering_modelinear-2">5.2.6. filtering_mode::linear</h4>
<div class="paragraph">
<p>When filter mode is <code>filtering_mode::linear</code>, a 2 x 2 square of image elements for a 2D image or a 2 x 2 x 2 cube of image elements for a 3D image is selected.
This 2 x 2 square or 2 x 2 x 2 cube is obtained as follows.</p>
</div>
<div class="paragraph">
<p>Let</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
s' &amp;=&amp; 2.0f * rint(0.5f * s)\\
s' &amp;=&amp; fabs(s - s')\\
u &amp;=&amp; s' * w_t\\
i0 &amp;=&amp; (int)floor(u - 0.5f)\\
i1 &amp;=&amp; i0 + 1\\
i0 &amp;=&amp; max(i0, 0)\\
i1 &amp;=&amp; min(i1, w_t - 1)\\
t' &amp;=&amp; 2.0f * rint(0.5f * t)\\
t' &amp;=&amp; fabs(t - t')\\
v &amp;=&amp; t' * h_t\\
j0 &amp;=&amp; (int)floor(v - 0.5f)\\
j1 &amp;=&amp; j0 + 1\\
j0 &amp;=&amp; max(j0, 0)\\
j1 &amp;=&amp; min(j1, h_t - 1)\\
r' &amp;=&amp; 2.0f * rint(0.5f * r)\\
r' &amp;=&amp; fabs(r - r')\\
w &amp;=&amp; r' * d_t\\
k0 &amp;=&amp; (int)floor(w - 0.5f)\\
k1 &amp;=&amp; k0 + 1\\
k0 &amp;=&amp; max(k0, 0)\\
k1 &amp;=&amp; min(k1, d_t - 1)\\
a &amp;=&amp; frac(u - 0.5)\\
b &amp;=&amp; frac(v - 0.5)\\
c &amp;=&amp; frac(w - 0.5)
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where frac(x) denotes the fractional part of x and is computed as x - floor(x).</p>
</div>
<div class="paragraph">
<p>For a 3D image, the image element value is found as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
T &amp;=&amp; (1 - a) * (1 - b) * (1 - c) * T_{i0j0k0}\\
&amp; &amp; {} + a * (1 - b) * (1 - c) * T_{i1j0k0}\\
&amp; &amp; {} + (1 - a) * b * (1 - c) * T_{i0j1k0}\\
&amp; &amp; {} + a * b * (1 - c) * T_{i1j1k0}\\
&amp; &amp; {} + (1 - a) * (1 - b) * c * T_{i0j0k1}\\
&amp; &amp; {} + a * (1 - b) * c * T_{i1j0k1}\\
&amp; &amp; {} + (1 - a) * b * c * T_{i0j1k1}\\
&amp; &amp; {} + a * b * c * T_{i1j1k1}
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where T<sub>ijk</sub> is the image element at location (i,j,k) in the 3D image.</p>
</div>
<div class="paragraph">
<p>For a 2D image, the image element value is found as</p>
</div>
<div class="stemblock">
<div class="content">
\[\begin{array}{rcl}
T &amp;=&amp; (1 - a) * (1 - b) * T_{i0j0}\\
&amp; &amp; {} + a * (1 - b) * T_{i1j0}\\
&amp; &amp; {} + (1 - a) * b * T_{i0j1}\\
&amp; &amp; {} + a * b * T_{i1j1}
\end{array}\]
</div>
</div>
<div class="paragraph">
<p>where T<sub>ij</sub> is the image element at location (i,j) in the 2D image.</p>
</div>
<div class="paragraph">
<p>For a 1D image, the image element value is found as</p>
</div>
<div class="stemblock">
<div class="content">
\[T = (1 - a) * T_i0 + a * T_i1\]
</div>
</div>
<div class="paragraph">
<p>where T<sub>i</sub> is the image element at location (i) in the 1D image.</p>
</div>
<div class="paragraph">
<p>If the image channel type is <code>CL_FLOAT</code> or <code>CL_HALF_FLOAT</code> and any of the image elements T<sub>ijk</sub> or T<sub>ij</sub> is INF or NaN, the behavior of the built-in image read function is undefined.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If the sampler is specified as using unnormalized coordinates (floating-point or integer coordinates), filter mode set to <code>filtering_mode::nearest</code> and addressing mode set to one of the following modes - <code>addressing_mode::none</code>, <code>addressing_mode::clamp_to_edge</code> or <code>addressing_mode::clamp</code>, the location of the image element in the image given by (i, j, k) will be computed without any loss of precision.
For all other sampler combinations of normalized or unnormalized coordinates, filter and addressing modes, the relative error or precision of the addressing mode calculations and the image filter operation are not defined by this revision of the OpenCL specification.
To ensure a minimum precision of image addressing and filter calculations across any OpenCL device, for these sampler combinations, developers should unnormalize the image coordinate in the kernel and implement the linear filter in the kernel with appropriate calls to <code>image::read</code> with a sampler that uses unnormalized coordinates, filter mode set to <code>filtering_mode::nearest</code>, addressing mode set to <code>addressing_mode::none</code>, <code>addressing_mode::clamp_to_edge</code> or <code>addressing_mode::clamp</code> and finally performing the interpolation of color values read from the image to generate the filtered color value.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="conversion-rules">5.3. Conversion Rules</h3>
<div class="paragraph">
<p>In this section we discuss conversion rules that are applied when reading and writing images in a kernel.</p>
</div>
<div class="sect3">
<h4 id="conversion-rules-for-normalized-integer-channel-data-types">5.3.1. Conversion rules for normalized integer</h4>
<div class="paragraph">
<p>In this section we discuss converting normalized integer channel data types to half-precision and single-precision floating-point values and vice-versa.</p>
</div>
<div class="sect4">
<h5 id="converting-normalized-integer-channel-data-types-to-half-precision-floating-point-values">Converting normalized integer channel data types to half precision floating-point values</h5>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_UNORM_INT8</code> and <code>CL_UNORM_INT16</code>, <code>image::read</code> will convert the channel values from an 8-bit or 16-bit unsigned integer to normalized half precision floating-point values in the range [0.0h &#8230;&#8203; 1.0h].</p>
</div>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_SNORM_INT8</code> and <code>CL_SNORM_INT16</code>, <code>image::read</code> will convert the channel values from an 8-bit or 16-bit signed integer to normalized half precision floating-point values in the range [-1.0h &#8230;&#8203; 1.0h].</p>
</div>
<div class="paragraph">
<p>These conversions are performed as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CL_UNORM_INT8</code> (8-bit unsigned integer) &#8594; <code>half</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_half\_value(x)=round\_to\_half(\frac{x}{255})\]
</div>
</div>
</li>
<li>
<p><code>CL_UNORM_INT_101010</code> (10-bit unsigned integer) &#8594; <code>half</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_half\_value(x)=round\_to\_half(\frac{x}{1023})\]
</div>
</div>
</li>
<li>
<p><code>CL_UNORM_INT16</code> (16-bit unsigned integer) &#8594; <code>half</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_half\_value(x)=round\_to\_half(\frac{x}{65535})\]
</div>
</div>
</li>
<li>
<p><code>CL_SNORM_INT8</code> (8-bit signed integer) &#8594; <code>half</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_half\_value(x)=max(-1.0h, round\_to\_half(\frac{x}{127}))\]
</div>
</div>
</li>
<li>
<p><code>CL_SNORM_INT16</code> (16-bit signed integer) &#8594; <code>half</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_half\_value(x)=max(-1.0h, round\_to\_half(\frac{x}{32767}))\]
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The precision of the above conversions is &lt;= 1.5 ulp except for the following cases.</p>
</div>
<div class="paragraph">
<p>For <code>CL_UNORM_INT8</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>0 must convert to 0.0h and</p>
</li>
<li>
<p>255 must convert to 1.0h</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_UNORM_INT_101010</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>0 must convert to 0.0h and</p>
</li>
<li>
<p>1023 must convert to 1.0h</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_UNORM_INT16</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>0 must convert to 0.0h and</p>
</li>
<li>
<p>65535 must convert to 1.0h</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_SNORM_INT8</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>-128 and -127 must convert to -1.0h,</p>
</li>
<li>
<p>0 must convert to 0.0h and</p>
</li>
<li>
<p>127 must convert to 1.0h</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_SNORM_INT16</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>-32768 and -32767 must convert to -1.0h,</p>
</li>
<li>
<p>0 must convert to 0.0h and</p>
</li>
<li>
<p>32767 must convert to 1.0h</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="converting-half-precision-floating-point-values-to-normalized-integer-channel-data-types">Converting half precision floating-point values to normalized integer channel data types</h5>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_UNORM_INT8</code> and <code>CL_UNORM_INT16</code>, <code>image::write</code> will convert the half precision floating-point color value to an 8-bit or 16-bit unsigned integer.</p>
</div>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_SNORM_INT8</code> and <code>CL_SNORM_INT16</code>, <code>image::write</code> will convert the half precision floating-point color value to an 8-bit or 16-bit signed integer.</p>
</div>
<div class="paragraph">
<p>OpenCL implementations may choose to approximate the rounding mode used in the conversions described below.
When approximate rounding is used instead of the preferred rounding, the result of the conversion must satisfy the bound given below.</p>
</div>
<div class="paragraph">
<p>The conversions from half precision floating-point values to normalized integer values are performed is as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>half</code> &#8594; <code>CL_UNORM_INT8</code> (8-bit unsigned integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(0,min(255,255 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint8(f(x)) &amp; x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint8(f(x)) &amp; x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
<li>
<p><code>half</code> &#8594; <code>CL_UNORM_INT16</code> (16-bit unsigned integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(0,min(65535,65535 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
<li>
<p><code>half</code> &#8594; <code>CL_SNORM_INT8</code> (8-bit signed integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(-128,min(127,127 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint8(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint8(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
<li>
<p><code>half</code> &#8594; <code>CL_SNORM_INT16</code> (16-bit signed integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(-32768,min(32767,32767 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="converting-normalized-integer-channel-data-types-to-floating-point-values">Converting normalized integer channel data types to floating-point values</h5>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_UNORM_INT8</code> and <code>CL_UNORM_INT16</code>, <code>image::read</code> will convert the channel values from an 8-bit or 16-bit unsigned integer to normalized floating-point values in the range [0.0f &#8230;&#8203; 1.0f].</p>
</div>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_SNORM_INT8</code> and <code>CL_SNORM_INT16</code>, <code>image::read</code> will convert the channel values from an 8-bit or 16-bit signed integer to normalized floating-point values in the range [-1.0f &#8230;&#8203; 1.0f].</p>
</div>
<div class="paragraph">
<p>These conversions are performed as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CL_UNORM_INT8</code> (8-bit unsigned integer) &#8594; <code>float</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_float\_value(x)=round\_to\_float(\frac{x}{255})\]
</div>
</div>
</li>
<li>
<p><code>CL_UNORM_INT_101010</code> (10-bit unsigned integer) &#8594; <code>float</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_float\_value(x)=round\_to\_float(\frac{x}{1023})\]
</div>
</div>
</li>
<li>
<p><code>CL_UNORM_INT16</code> (16-bit unsigned integer) &#8594; <code>float</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_float\_value(x)=round\_to\_float(\frac{x}{65535})\]
</div>
</div>
</li>
<li>
<p><code>CL_SNORM_INT8</code> (8-bit signed integer) &#8594; <code>float</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_float\_value(x)=max(-1.0f, round\_to\_float(\frac{x}{127}))\]
</div>
</div>
</li>
<li>
<p><code>CL_SNORM_INT16</code> (16-bit signed integer) &#8594; <code>float</code></p>
<div class="stemblock">
<div class="content">
\[normalized\_float\_value(x)=max(-1.0f, round\_to\_float(\frac{x}{32767}))\]
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The precision of the above conversions is &lt;= 1.5 ulp except for the following cases.</p>
</div>
<div class="paragraph">
<p>For <code>CL_UNORM_INT8</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>0 must convert to 0.0f and</p>
</li>
<li>
<p>255 must convert to 1.0f</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_UNORM_INT_101010</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>0 must convert to 0.0f and</p>
</li>
<li>
<p>1023 must convert to 1.0f</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_UNORM_INT16</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>0 must convert to 0.0f and</p>
</li>
<li>
<p>65535 must convert to 1.0f</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_SNORM_INT8</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>-128 and -127 must convert to -1.0f,</p>
</li>
<li>
<p>0 must convert to 0.0f and</p>
</li>
<li>
<p>127 must convert to 1.0f</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For <code>CL_SNORM_INT16</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>-32768 and -32767 must convert to -1.0f,</p>
</li>
<li>
<p>0 must convert to 0.0f and</p>
</li>
<li>
<p>32767 must convert to 1.0f</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="converting-floating-point-values-to-normalized-integer-channel-data-types">Converting floating-point values to normalized integer channel data types</h5>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_UNORM_INT8</code> and <code>CL_UNORM_INT16</code>, <code>image::write</code> will convert the floating-point color value to an 8-bit or 16-bit unsigned integer.</p>
</div>
<div class="paragraph">
<p>For images created with image channel data type of <code>CL_SNORM_INT8</code> and <code>CL_SNORM_INT16</code>, <code>image::write</code> will convert the floating-point color value to an 8-bit or 16-bit signed integer.</p>
</div>
<div class="paragraph">
<p>OpenCL implementations may choose to approximate the rounding mode used in the conversions described below.
When approximate rounding is used instead of the preferred rounding, the result of the conversion must satisfy the bound given below.</p>
</div>
<div class="paragraph">
<p>The conversions from half precision floating-point values to normalized integer values are performed is as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>float</code> &#8594; <code>CL_UNORM_INT8</code> (8-bit unsigned integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(0,min(255,255 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint8(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint8(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
<li>
<p><code>float</code> &#8594; <code>CL_UNORM_INT_101010</code> (10-bit unsigned integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(0,min(1023,1023 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint10(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint10(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
<li>
<p><code>float</code> &#8594; <code>CL_UNORM_INT16</code> (16-bit unsigned integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(0,min(65535,65535 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
<li>
<p><code>float</code> &#8594; <code>CL_SNORM_INT8</code> (8-bit signed integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(-128,min(127,127 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint8(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint8(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
<li>
<p><code>float</code> &#8594; <code>CL_SNORM_INT16</code> (16-bit signed integer)</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
f(x)=max(-32768,min(32767,32767 \times x))\\
\\
f_{preferred}(x) =
\begin{cases}
round\_to\_nearest\_even\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
f_{approx}(x) =
\begin{cases}
round\_to\_impl\_uint16(f(x)) &amp; \quad x \neq \infty \text{ and } x \neq NaN\\
\text{implementation-defined} &amp; \quad x = \infty \text{ or } x = NaN
\end{cases}\\
\\
|f(x) - f_{approx}(x)|\leq 0.6, x \neq \infty \text{ and } x \neq NaN
\end{aligned}\]
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect3">
<h4 id="conversion-rules-for-half-precision-floating-point-channel-data-type">5.3.2. Conversion rules for half precision floating-point channel data type</h4>
<div class="paragraph">
<p>For images created with a channel data type of <code>CL_HALF_FLOAT</code>, the conversions of half to float and half to half are lossless (as described in the <a href="#builtin-half-data-type"><em>Built-in Half Data Type</em></a> section).
Conversions from float to half round the mantissa using the round to nearest even or round to zero rounding mode.
Denormalized numbers for the half data type which may be generated when converting a float to a half may be flushed to zero.
A float NaN must be converted to an appropriate NaN in the half type.
A float INF must be converted to an appropriate INF in the half type.</p>
</div>
</div>
<div class="sect3">
<h4 id="conversion-rules-for-floating-point-channel-data-type">5.3.3. Conversion rules for floating-point channel data type</h4>
<div class="paragraph">
<p>The following rules apply for reading and writing images created with channel data type of <code>CL_FLOAT</code>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>NaNs may be converted to a NaN value(s) supported by the device.</p>
</li>
<li>
<p>Denorms can be flushed to zero.</p>
</li>
<li>
<p>All other values must be preserved.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="conversion-rules-for-signed-and-unsigned-8-bit-16-bit-and-32-bit-integer-channel-data-types">5.3.4. Conversion rules for signed and unsigned 8-bit, 16-bit and 32-bit integer channel data types</h4>
<div class="paragraph">
<p>Calls to <code>image::read</code> with channel data type values of <code>CL_SIGNED_INT8</code>, <code>CL_SIGNED_INT16</code> and <code>CL_SIGNED_INT32</code> return the unmodified integer values stored in the image at specified location.</p>
</div>
<div class="paragraph">
<p>Calls to <code>image::read</code> with channel data type values of <code>CL_UNSIGNED_INT8</code>, <code>CL_UNSIGNED_INT16</code> and <code>CL_UNSIGNED_INT32</code> return the unmodified integer values stored in the image at specified location.</p>
</div>
<div class="paragraph">
<p>Calls to <code>image::write</code> will perform one of the following conversions:</p>
</div>
<div class="paragraph">
<p>32 bit signed integer &#8594; 8-bit signed integer</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>convert_cast&lt;char,saturate::on&gt;(i)</code></pre>
</div>
</div>
<div class="paragraph">
<p>32 bit signed integer &#8594; 16-bit signed integer</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>convert_cast&lt;short,saturate::on&gt;(i)</code></pre>
</div>
</div>
<div class="paragraph">
<p>32 bit signed integer &#8594; 32-bit signed integer</p>
</div>
<div class="listingblock">
<div class="content">
<pre>no conversion is performed</pre>
</div>
</div>
<div class="paragraph">
<p>Calls to image::write will perform one of the following conversions:</p>
</div>
<div class="paragraph">
<p>32 bit unsigned integer &#8594; 8-bit unsigned integer</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>convert_cast&lt;uchar,saturate::on&gt;(i)</code></pre>
</div>
</div>
<div class="paragraph">
<p>32 bit unsigned integer &#8594; 16-bit unsigned integer</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>convert_cast&lt;ushort,saturate::on&gt;(i)</code></pre>
</div>
</div>
<div class="paragraph">
<p>32 bit unsigned integer &#8594; 32-bit unsigned integer</p>
</div>
<div class="listingblock">
<div class="content">
<pre>no conversion is performed</pre>
</div>
</div>
<div class="paragraph">
<p>The conversions described in this section must be correctly saturated.</p>
</div>
</div>
<div class="sect3">
<h4 id="conversion-rules-for-srgba-and-sbgra-images">5.3.5. Conversion rules for sRGBA and sBGRA images</h4>
<div class="paragraph">
<p>Standard RGB data, which roughly displays colors in a linear ramp of luminosity levels such that an average observer, under average viewing conditions, can view them as perceptually equal steps on an average display.
All 0&#8217;s maps to 0.0f, and all 1&#8217;s maps to 1.0f.
The sequence of unsigned integer encodings between all 0&#8217;s and all 1&#8217;s represent a nonlinear progression in the floating-point interpretation of the numbers between 0.0f to 1.0f.
For more detail, see the <a href="#sRGB-spec">SRGB color standard</a>.</p>
</div>
<div class="paragraph">
<p>Conversion from sRGB space is automatically done by image::read built-in functions if the image channel order is one of the sRGB values described above.
When reading from an sRGB image, the conversion from sRGB to linear RGB is performed before the filter specified in the sampler specified to image::sample is applied.
If the format has an alpha channel, the alpha data is stored in linear color space.
Conversion to sRGB space is automatically done by image::write built-in functions if the image channel order is one of the sRGB values described above and the device supports writing to sRGB images.</p>
</div>
<div class="paragraph">
<p>If the format has an alpha channel, the alpha data is stored in linear color space.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The following process is used by image::read and image::sample to convert a normalized 8-bit unsigned integer sRGB color value x to a floating-point linear RGB color value y:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>Convert a normalized 8-bit unsigned integer sRGB value x to a floating-point sRGB value r as per rules described in the <a href="#converting-floating-point-values-to-normalized-integer-channel-data-types"><em>Converting floating-point values to normalized integer channel data types</em></a> section.</p>
<div class="stemblock">
<div class="content">
\[r=normalized\_float\_value(x)\]
</div>
</div>
</li>
<li>
<p>Convert a floating-point sRGB value r to a floating-point linear RGB color value y:</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
c_{linear}(x) =
\begin{cases}
\frac{r}{12.92} &amp; \quad r \geq 0 \text{ and } r \leq 0.04045\\[1em]
(\frac{r + 0.055}{1.055})^{2.4} &amp; \quad r &gt; 0.04045 \text{ and } \leq 1
\end{cases}\\
\\
y = c_{linear}(r)
\end{aligned}\]
</div>
</div>
</li>
</ol>
</div>
</li>
<li>
<p>The following process is used by <code>image::write</code> to convert a linear RGB floating-point color value y to a normalized 8-bit unsigned integer sRGB value x:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>Convert a floating-point linear RGB value y to a normalized floating point sRGB value r:</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
c_{linear}(x) =
\begin{cases}
0 &amp; \quad y \geq NaN \text{ or } y &lt; 0\\
12.92 \times y &amp; \quad y \geq 0 \text{ and } y &lt; 0.0031308\\
1.055 \times y^{(\frac{1}{2.4})} &amp; \quad y \geq 0.0031308 \text{ and } y \leq 1\\
1 &amp; \quad y &gt; 1
\end{cases}\\
\\
r = c_{sRGB}(y)
\end{aligned}\]
</div>
</div>
</li>
<li>
<p>Convert a normalized floating-point sRGB value r to a normalized 8-bit unsigned integer sRGB value x as per rules described in <a href="#converting-normalized-integer-channel-data-types-to-half-precision-floating-point-values">Converting normalized integer channel data types to half precision floating-point values</a> section.</p>
<div class="stemblock">
<div class="content">
\[\begin{aligned}
g(r) =
\begin{cases}
f_{preferred}(r) &amp; \quad \text{if rounding mode is round to even}\\
f_{approx}(r) &amp; \quad \text{if implementation-defined rounding mode}
\end{cases}\\
\\
x = g(r)
\end{aligned}\]
</div>
</div>
</li>
</ol>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>The accuracy required of using <code>image::read</code> and <code>image::sample</code> to convert a normalized 8-bit unsigned integer sRGB color value x to a floating-point linear RGB color value y is given by:</p>
</div>
<div class="stemblock">
<div class="content">
\[|x-255 \times c_{sRGB}(y)|\leq 0.5\]
</div>
</div>
<div class="paragraph">
<p>The accuracy required of using <code>image::write</code> to convert a linear RGB floating-point color value y to a normalized 8-bit unsigned integer sRGB value x is given by:</p>
</div>
<div class="stemblock">
<div class="content">
\[|x-255 \times c_{sRGB}(y)|\leq 0.6\]
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="selecting-an-image-from-an-image-array">5.4. Selecting an Image from an Image Array</h3>
<div class="paragraph">
<p>Let (u,v,w) represent the unnormalized image coordinate values for reading from and/or writing to a 2D image in a 2D image array.</p>
</div>
<div class="paragraph">
<p>When read using a sampler, the 2D image layer selected is computed as:</p>
</div>
<div class="stemblock">
<div class="content">
\[layer = clamp(rint(w), 0, d_t - 1)\]
</div>
</div>
<div class="paragraph">
<p>otherwise the layer selected is computed as:</p>
</div>
<div class="stemblock">
<div class="content">
\[layer = w\]
</div>
</div>
<div class="paragraph">
<p>(since w is already an integer) and the result is undefined if w is not one of the integers 0, 1, &#8230;&#8203; d<sub>t</sub> - 1.</p>
</div>
<div class="paragraph">
<p>Let (u,v) represent the unnormalized image coordinate values for reading from and/or writing to a 1D image in a 1D image array.</p>
</div>
<div class="paragraph">
<p>When read using a sampler, the 1D image layer selected is computed as:</p>
</div>
<div class="stemblock">
<div class="content">
\[layer = clamp(rint(v), 0, h_t - 1)\]
</div>
</div>
<div class="paragraph">
<p>otherwise the layer selected is computed as:</p>
</div>
<div class="stemblock">
<div class="content">
\[layer = v\]
</div>
</div>
<div class="paragraph">
<p>(since v is already an integer) and the result is undefined if v is not one of the integers 0, 1, &#8230;&#8203; h<sub>t</sub> - 1.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="compiler_options">6. Compiler options</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The compiler options are categorized as preprocessor options, options for controlling the OpenCL C++ version, options that control FP16 and FP64 support.
This specification defines a standard set of options that must be supported by the compiler when building program executables online or offline from OpenCL C++ to an IL.
These may be extended by a set of vendor or platform specific options.</p>
</div>
<div class="sect2">
<h3 id="preprocessor_options">6.1. Preprocessor options</h3>
<div class="paragraph">
<p>These options control the OpenCL C++ preprocessor which is run on each program source before actual compilation.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-D name</pre>
</div>
</div>
<div class="paragraph">
<p>Predefine name as a macro, with definition 1.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-D name=definition</pre>
</div>
</div>
<div class="paragraph">
<p>The contents of definition are tokenized and processed as if they appeared during translation phase three in a <code>#define</code> directive.
In particular, the definition will be truncated by embedded newline characters.</p>
</div>
</div>
<div class="sect2">
<h3 id="options-controlling_the-opencl_c_version">6.2. Options Controlling the OpenCL C++ version</h3>
<div class="paragraph">
<p>The following option controls the version of OpenCL C++ that the compiler accepts.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-cl-std=</pre>
</div>
</div>
<div class="paragraph">
<p>Determine the OpenCL C++ language version to use.
A value for this option must be provided.
Valid values are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>c++ - Support all OpenCL C++ programs that use the OpenCL C++ language features defined in the <a href="#openclcpp-programming-language"><em>OpenCL C++ Programming Language</em></a> section.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="fp16_and_fp64_options">6.3. Double and half-precision floating-point options</h3>
<div class="paragraph">
<p>The following option controls the double and half floating-point support that the compiler accepts.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-cl-fp16-enable</pre>
</div>
</div>
<div class="paragraph">
<p>This option enables full half data type support.
The option defines <code>cl_khr_fp16</code> macro.
The default is disabled.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-cl-fp64-enable</pre>
</div>
</div>
<div class="paragraph">
<p>This option enables double data type support.
The option defines <code>cl_khr_fp64</code> macro.
The default is disabled.</p>
</div>
</div>
<div class="sect2">
<h3 id="other_options">6.4. Other options</h3>
<div class="listingblock">
<div class="content">
<pre>-cl-zero-init-local-mem-vars</pre>
</div>
</div>
<div class="paragraph">
<p>This option enables software zero-initialization of variables allocated in local memory.</p>
</div>
<div style="page-break-after: always;"></div>
<hr>
<div id="ftn2" class="paragraph">
<p><a href="#ftnref2">[2]</a> The <code>double</code> data type is an optional type that is supported if <code>CL_DEVICE_DOUBLE_FP_CONFIG</code> in table 4.3 for a device is not zero.</p>
</div>
<div id="ftn3" class="paragraph">
<p><a href="#ftnref3">[3]</a> The question mark ? in numerical selector refers to special undefined component of vector; reading from it results in undefined value, writing to it is discarded.</p>
</div>
<div id="ftn4" class="paragraph">
<p><a href="#ftnref4">[4]</a> Only if the <strong>cl_khr_fp16</strong> extension is enabled and has been supported</p>
</div>
<div id="ftn5" class="paragraph">
<p><a href="#ftnref5">[5]</a> For conversions to floating-point format, when a finite source value exceeds the maximum representable finite floating-point destination value, the rounding mode will affect whether the result is the maximum finite floating-point value or infinity of same sign as the source value, per IEEE-754 rules for rounding.</p>
</div>
<div id="ftn6" class="paragraph">
<p><a href="#ftnref6">[6]</a> The <code>as_type&lt;T&gt;</code> function is intended to reflect the organization of data in register.
The <code>as_type&lt;T&gt;</code> construct is intended to compile to no instructions on devices that use a shared register file designed to operate on both the operand and result types.
Note that while differences in memory organization are expected to largely be limited to those arising from endianness, the register based representation may also differ due to size of the element in register.
(For example, an architecture may load a char into a 32-bit register, or a char vector into a SIMD vector register with fixed 32-bit element size.)
If the element count does not match, then the implementation should pick a data representation that most closely matches what would happen if an appropriate result type operator was applied to a register containing data of the source type.
So, for example if an implementation stores all single precision data as double in register, it should implement <code>as_type&lt;int&gt;(float)</code> by first downconverting the double to single precision and then (if necessary) moving the single precision bits to a register suitable for operating on integer data.
If data stored in different address spaces do not have the same endianness, then the "dominant endianness" of the device should prevail.</p>
</div>
<div id="ftn7" class="paragraph">
<p><a href="#ftnref7">[7]</a> <code>memory_order_consume</code> is not supported in OpenCL C++</p>
</div>
<div id="ftn8" class="paragraph">
<p><a href="#ftnref8">[8]</a> This value for <code>memory_scope</code> can only be used with <code>atomic_fence</code> with flags set to <code>mem_fence::image</code>.</p>
</div>
<div id="ftn9" class="paragraph">
<p><a href="#ftnref9">[9]</a> We can&#8217;t require C++14 atomics since host programs can be implemented in other programming languages and versions of C or C++, but we do require that the host programs use atomics and that those atomics be compatible with those in C++14.</p>
</div>
<div id="ftn10" class="paragraph">
<p><a href="#ftnref10">[10]</a> The <code>atomic_long</code> and <code>atomic_ulong</code> types are supported if the <strong>cl_khr_int64_base_atomics</strong> and <strong>cl_khr_int64_extended_atomics</strong> extensions are supported and have been enabled.</p>
</div>
<div id="ftn11" class="paragraph">
<p><a href="#ftnref11">[11]</a> The <code>atomic_double</code> type is only supported if double precision is supported and the <strong>cl_khr_int64_base_atomics</strong> and <strong>cl_khr_int64_extended_atomics</strong> extensions are supported and have been enabled.</p>
</div>
<div id="ftn12" class="paragraph">
<p><a href="#ftnref12">[12]</a> If the device address space is 64-bits, the data types <code>atomic_intptr_t</code>, <code>atomic_uintptr_t</code>, <code>atomic_size_t</code> and <code>atomic_ptrdiff_t</code> are supported only if the <strong>cl_khr_int64_base_atomics</strong> and <strong>cl_khr_int64_extended_atomics</strong> extensions are supported and have been enabled.</p>
</div>
<div id="ftn13" class="paragraph">
<p><a href="#ftnref13">[13]</a> The <code>*_ms</code> types are supported only if the *cl_khr_gl_msaa_sharing* and <strong>cl_khr_gl_depth_images</strong> extensions are supported and have been enabled.</p>
</div>
<div id="ftn14" class="paragraph">
<p><a href="#ftnref14">[14]</a> Immediate meaning not side effects resulting from child kernels. The side effects would include stores to global memory and pipe reads and writes.</p>
</div>
<div id="ftn15" class="paragraph">
<p><a href="#ftnref15">[15]</a> This acts as a memory synchronization point between work-items in a work-group and child kernels enqueued by work-items in the work-group.</p>
</div>
<div id="ftn17" class="paragraph">
<p><a href="#ftnref17">[17]</a> i.e. the <code>global_work_size</code> values specified to <code>clEnqueueNDRangeKernel</code> are not evenly divisible by the <code>local_work_size</code> values for each dimension.</p>
</div>
<div id="ftn18" class="paragraph">
<p><a href="#ftnref18">[18]</a> Only if double precision is supported and has been enabled.</p>
</div>
<div id="ftn19" class="paragraph">
<p><a href="#ftnref19">[19]</a> Refer to the <a href="#order-and-scope"><em>Memory order and scope</em></a> section for description of <code>memory_scope</code>.</p>
</div>
<div id="ftn20" class="paragraph">
<p><a href="#ftnref20">[20]</a> The <code>min()</code> operator is there to prevent <code>fract(-small)</code> from returning 1.0.
It returns the largest positive floating-point number less than 1.0.</p>
</div>
<div id="ftn21" class="paragraph">
<p><a href="#ftnref21">[21]</a> fmin and fmax behave as defined by C++14 and may not match the IEEE 754-2008 definition for minNum and maxNum with regard to signaling NaNs.
Specifically, signaling NaNs may behave as quiet NaNs.</p>
</div>
<div id="ftn22" class="paragraph">
<p><a href="#ftnref22">[22]</a> The user is cautioned that for some usages, e.g. <code>mad(a, b, -a*b)</code>, the definition of <code>mad()</code> in the embedded profile is loose enough that almost any result is allowed from <code>mad()</code> for some values of <code>a</code> and <code>b</code>.</p>
</div>
<div id="ftn23" class="paragraph">
<p><a href="#ftnref23">[23]</a> Frequently vector operations need n + 1 bits temporarily to calculate a result.
The rhadd instruction gives you an extra bit without needing to upsample and downsample. This can be a profound performance win.</p>
</div>
<div id="ftn24" class="paragraph">
<p><a href="#ftnref24">[24]</a> The primary purpose of the printf function is to help in debugging OpenCL kernels.</p>
</div>
<div id="ftn25" class="paragraph">
<p><a href="#ftnref25">[25]</a> Note that <em>0</em> is taken as a flag, not as the beginning of a field width.</p>
</div>
<div id="ftn26" class="paragraph">
<p><a href="#ftnref26">[26]</a> The results of all floating conversions of a negative zero, and of negative values that round to zero, include a minus sign.</p>
</div>
<div id="ftn27" class="paragraph">
<p><a href="#ftnref27">[27]</a> When applied to infinite and NaN values, the -, +, and space flag characters have their usual meaning; the # and <em>0</em> flag characters have no effect.</p>
</div>
<div id="ftn28" class="paragraph">
<p><a href="#ftnref28">[28]</a> Binary implementations can choose the hexadecimal digit to the left of the decimal-point character so that subsequent digits align to nibble (4-bit) boundaries.</p>
</div>
<div id="ftn29" class="paragraph">
<p><a href="#ftnref29">[29]</a> No special provisions are made for multibyte characters.
The behavior of printf with the <em>s</em> conversion specifier is undefined if the argument value is not a pointer to a literal string.</p>
</div>
<div id="ftn30" class="paragraph">
<p><a href="#ftnref30">[30]</a> Except for the embedded profile whether either round to zero or round to nearest rounding mode may be supported for single precision floating-point.</p>
</div>
<div id="ftn31" class="paragraph">
<p><a href="#ftnref31">[31]</a> The ULP values for built-in math functions <code>lgamma</code> and <code>lgamma_r</code> is currently undefined.</p>
</div>
<div id="ftn32" class="paragraph">
<p><a href="#ftnref32">[32]</a> 0 ulp is used for math functions that do not require rounding.</p>
</div>
<div id="ftn33" class="paragraph">
<p><a href="#ftnref33">[33]</a> On some implementations, <code>powr()</code> or <code>pown()</code> may perform faster than <code>pow()</code>.
If <code>x</code> is known to be <code>&gt;= 0</code>, consider using <code>powr()</code> in place of <code>pow()</code>, or if <code>y</code> is known to be an integer, consider using <code>pown()</code> in place of <code>pow()</code>.</p>
</div>
<div id="ftn35" class="paragraph">
<p><a href="#ftnref35">[35]</a> Here <code>TYPE_MIN</code> and <code>TYPE_MIN_EXP</code> should be substituted by constants appropriate to the floating-point type under consideration, such as <code>FLT_MIN</code> and <code>FLT_MIN_EXP</code> for float.</p>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Version 2.2-8<br>
Last updated 2018-09-24 21:35:08 PDT
</div>
</div>
</body>
</html>