Compile Metal with CLI tool from env. Parameters ---------- code : str The Metal code. path_target : str, optional Output file. sdk : str, optional The target platform SDK. Return ------ metallib : bytearray The bytearray of the met
(code, path_target=None, sdk="macosx", min_os_version=None)
| 108 | |
| 109 | |
| 110 | def compile_metal(code, path_target=None, sdk="macosx", min_os_version=None): |
| 111 | """Compile Metal with CLI tool from env. |
| 112 | |
| 113 | Parameters |
| 114 | ---------- |
| 115 | code : str |
| 116 | The Metal code. |
| 117 | |
| 118 | path_target : str, optional |
| 119 | Output file. |
| 120 | |
| 121 | sdk : str, optional |
| 122 | The target platform SDK. |
| 123 | |
| 124 | Return |
| 125 | ------ |
| 126 | metallib : bytearray |
| 127 | The bytearray of the metallib |
| 128 | """ |
| 129 | temp = utils.tempdir() |
| 130 | temp_code = temp.relpath("my_lib.metal") |
| 131 | temp_ir = temp.relpath("my_lib.air") |
| 132 | temp_target = temp.relpath("my_lib.metallib") |
| 133 | |
| 134 | with open(temp_code, "w") as out_file: |
| 135 | out_file.write(code) |
| 136 | file_target = path_target if path_target else temp_target |
| 137 | |
| 138 | # See: |
| 139 | # - https://developer.apple.com/documentation/metal/gpu_functions_libraries/building_a_library_with_metal_s_command-line_tools#overview # pylint: disable=line-too-long |
| 140 | # |
| 141 | # xcrun -sdk macosx metal -c MyLibrary.metal -o MyLibrary.air |
| 142 | # xcrun -sdk macosx metallib MyLibrary.air -o MyLibrary.metallib |
| 143 | min_target = __get_min_os_version_cmd(sdk, min_os_version) |
| 144 | if sdk == "macosx": |
| 145 | language_version = "-std=macos-metal2.3" |
| 146 | elif sdk in ("iphoneos", "iphonesimulator"): |
| 147 | language_version = "-std=ios-metal2.3" |
| 148 | else: |
| 149 | raise RuntimeError(f"Unsupported sdk: {sdk}") |
| 150 | cmd1 = ["xcrun", "-sdk", sdk, "metal", language_version, min_target, "-O3"] |
| 151 | cmd1 += ["-c", temp_code, "-o", temp_ir] |
| 152 | cmd2 = ["xcrun", "-sdk", sdk, "metallib"] |
| 153 | cmd2 += [temp_ir, "-o", file_target] |
| 154 | proc = subprocess.Popen( |
| 155 | " ".join(cmd1) + ";" + " ".join(cmd2), |
| 156 | shell=True, |
| 157 | stdout=subprocess.PIPE, |
| 158 | stderr=subprocess.STDOUT, |
| 159 | ) |
| 160 | (out, _) = proc.communicate() |
| 161 | if proc.returncode != 0: |
| 162 | sys.stderr.write("Compilation error:\n") |
| 163 | sys.stderr.write(out.decode("utf-8", errors="replace")) |
| 164 | sys.stderr.flush() |
| 165 | libbin = None |
| 166 | else: |
| 167 | libbin = bytearray(open(file_target, "rb").read()) |
searching dependent graphs…