{"id":309,"date":"2022-04-04T14:39:11","date_gmt":"2022-04-04T12:39:11","guid":{"rendered":"https:\/\/threedots.ovh\/blog\/?p=309"},"modified":"2022-04-04T14:39:11","modified_gmt":"2022-04-04T12:39:11","slug":"opencl-on-metal-3-metal-compilation","status":"publish","type":"post","link":"https:\/\/threedots.ovh\/blog\/2022\/04\/opencl-on-metal-3-metal-compilation\/","title":{"rendered":"OpenCL on Metal #3: Metal compilation"},"content":{"rendered":"\n<p><em>AIR<\/em> is the LLVM IR dialect used by Metal. AIR shader binaries are guaranteed to run unmodified on a future operating system release.<\/p>\n\n\n\n<p>However, Apple explicitly chose to not document AIR, making the <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.apple.com\/metal\/Metal-Shading-Language-Specification.pdf\" target=\"_blank\">Metal Shading Language<\/a> the only officially supported input language.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">The compiler<\/h4>\n\n\n\n<p><em>metal<\/em>, the compiler, supports two input languages under the hood. But only one of which is exposed through public API, the Metal Shading Language.<\/p>\n\n\n\n<p>That second input language is <em>OpenCL<\/em>, usable through <code>--driver-mode=openclc -x cl<\/code>. That&#8217;s what Apple&#8217;s OpenCL implementation on M1 uses under the hood. <em>It&#8217;s an internal implementation detail not exposed to developers<\/em>.<\/p>\n\n\n\n<p>The Metal tool set as shipped as part of Xcode does <em>not<\/em> ship with opencl-c.h however, and the resulting binaries do not seem to be loadable through clCreateProgramWithBinary.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Offline compilation<\/h4>\n\n\n\n<p>In the Metal API, offline compilation is a first-class citizen. Apple&nbsp;<em>do<\/em>es&nbsp;ship <em>metal-as<\/em> as an AIR assembler, a disassembler for AIR (<em>metal-objdump<\/em>) and a linker (<em>metallib<\/em>). <\/p>\n\n\n\n<p>At runtime, <em>Metal<\/em> doesn&#8217;t take LLVM bitcode files directly (.air, equivalent to .bc), but does take linked programs (.metallib). <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Online compilation<\/h4>\n\n\n\n<p>Online compilation is also available. However, options are quite limited there, without possibility to pass compiler arguments or even custom include paths.<\/p>\n\n\n\n<p>For the OpenCL implementation, argument filtering is also done, to block non-allowlisted arguments from being passed through to the compiler.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">AIR versions<\/h4>\n\n\n\n<p><em>This section is a work in progress.<\/em> <\/p>\n\n\n\n<p>AIR is versioned, with the version number shared with the Metal Shading Language version<\/p>\n\n\n\n<p>Multiple different GPUCompiler libraries ship with macOS. Version 3802, 3902, 31001<\/p>\n","protected":false},"excerpt":{"rendered":"<p>AIR is the LLVM IR dialect used by Metal. AIR shader binaries are guaranteed to run unmodified on a future operating system release. However, Apple explicitly chose to not document AIR, making the Metal Shading Language the only officially supported input language. The compiler metal, the compiler, supports two input languages under the hood. But&hellip;&nbsp;<a href=\"https:\/\/threedots.ovh\/blog\/2022\/04\/opencl-on-metal-3-metal-compilation\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">OpenCL on Metal #3: Metal compilation<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-309","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/309","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/comments?post=309"}],"version-history":[{"count":5,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/309\/revisions"}],"predecessor-version":[{"id":314,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/309\/revisions\/314"}],"wp:attachment":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/media?parent=309"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/categories?post=309"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/tags?post=309"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}