tensorflow / mlir

"Multi-Level Intermediate Representation" Compiler Infrastructure
1.73k stars 257 forks source link

How to convert MLIR to SPIR-V? #91

Open stakemura opened 5 years ago

stakemura commented 5 years ago

Would you like to give me any information how to convert from MLIR to SPIR-V? I tried to use mlir-translate with serialize-spirv option, but I couldn't realize how to use this option.

antiagainst commented 5 years ago

Hey @stakemura, thanks for your interest!

-serialize-spirv and -deserialize-spirv in mlir-translate is for serializing a spv.module of the SPIR-V dialect into its binary format and deserializing a SPIR-V binary into is spv.module equivalent, respectively. The API entry points are here. Tests can serve as an example for how to use the command-line tool. (Please ignore the outer function wrapping around the spv.module in those tests; they are mandated by mlir-translate infra and should be removed later. We just haven't gotten back to it.)

If you are talking about conversion between the SPIR-V dialect and other dialects, then that's still under development right now and we expect to have more on it in the coming weeks.

I guess I'm not quite clear about your use case. Could you share more about what you intend to do with the SPIR-V dialect? That will also help me to answer your questions better. :)

stakemura commented 5 years ago

@antiagainst I truly appreciate your quick reply.

One of my motivations is to run compute shader based inference like Stadia’s Style Transfer ML.

Currently I'm using TVM to generate SPIR-V assembler as the following code shows.

import sys

import tvm
import tvm.relay as relay
import numpy as np

in_n, in_c, in_h, in_w = tvm.var("n"), 3, 256, 256
x = relay.var("x", relay.ty.TensorType((in_n, in_c, in_h, in_w), "float32"))
w = relay.var("w")
y = relay.nn.conv2d(x, w,
                    kernel_size=(3, 3),
                    padding=(1, 1),
                    channels=2)
mod = relay.Function([x, w], y)
x_data = np.random.rand(1, in_c, in_h, in_w).astype('float32')
params = {"x": tvm.nd.array(x_data)}

target = "vulkan"

with relay.build_config(opt_level=3):
    graph, lib, params = relay.build(mod, target, params=params)
    spv = lib.imported_modules[0].get_source()
    with open("conv2d.ll", mode='w') as f:
        f.write(spv)

The SPIR-V assembler "conv2d.ll" is generated as follows.

; SPIR-V
; Version: 1.1
; Generator: Khronos; 0
; Bound: 330
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %15 "fused_nn_conv2d_kernel0" %gl_WorkGroupID %gl_LocalInvocationID
               OpExecutionMode %15 LocalSize 32 1 2
               OpDecorate %_runtimearr_float ArrayStride 4
               OpMemberDecorate %_struct_10 0 Offset 0
               OpDecorate %_struct_10 BufferBlock
               OpDecorate %12 DescriptorSet 0
               OpDecorate %12 Binding 0
               OpDecorate %13 DescriptorSet 0
               OpDecorate %13 Binding 1
               OpDecorate %14 DescriptorSet 0
               OpDecorate %14 Binding 2
               OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
               OpDecorate %_arr_float_uint_4 ArrayStride 4
               OpMemberDecorate %_struct_26 0 Offset 0
               OpDecorate %_arr_float_uint_204 ArrayStride 4
               OpMemberDecorate %_struct_31 0 Offset 0
               OpDecorate %_arr_float_uint_18 ArrayStride 4
               OpMemberDecorate %_struct_36 0 Offset 0
               OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
        %int = OpTypeInt 32 1
       %uint = OpTypeInt 32 0
       %bool = OpTypeBool
      %float = OpTypeFloat 32
      %int_0 = OpConstant %int 0
       %void = OpTypeVoid
          %8 = OpTypeFunction %void
%_runtimearr_float = OpTypeRuntimeArray %float
 %_struct_10 = OpTypeStruct %_runtimearr_float
%_ptr_Uniform__struct_10 = OpTypePointer Uniform %_struct_10
         %12 = OpVariable %_ptr_Uniform__struct_10 Uniform
         %13 = OpVariable %_ptr_Uniform__struct_10 Uniform
         %14 = OpVariable %_ptr_Uniform__struct_10 Uniform
      %v3int = OpTypeVector %int 3
%_ptr_Input_v3int = OpTypePointer Input %v3int
%gl_WorkGroupID = OpVariable %_ptr_Input_v3int Input
%_ptr_Input_int = OpTypePointer Input %int
      %int_2 = OpConstant %int 2
     %uint_4 = OpConstant %uint 4
%_arr_float_uint_4 = OpTypeArray %float %uint_4
 %_struct_26 = OpTypeStruct %_arr_float_uint_4
%_ptr_Function__struct_26 = OpTypePointer Function %_struct_26
   %uint_204 = OpConstant %uint 204
%_arr_float_uint_204 = OpTypeArray %float %uint_204
 %_struct_31 = OpTypeStruct %_arr_float_uint_204
%_ptr_Workgroup__struct_31 = OpTypePointer Workgroup %_struct_31
         %33 = OpVariable %_ptr_Workgroup__struct_31 Workgroup
    %uint_18 = OpConstant %uint 18
%_arr_float_uint_18 = OpTypeArray %float %uint_18
 %_struct_36 = OpTypeStruct %_arr_float_uint_18
%_ptr_Workgroup__struct_36 = OpTypePointer Workgroup %_struct_36
         %38 = OpVariable %_ptr_Workgroup__struct_36 Workgroup
      %int_1 = OpConstant %int 1
%gl_LocalInvocationID = OpVariable %_ptr_Input_v3int Input
    %float_0 = OpConstant %float 0
%_ptr_Function_float = OpTypePointer Function %float
      %int_3 = OpConstant %int 3
    %int_272 = OpConstant %int 272
      %int_4 = OpConstant %int 4
      %int_6 = OpConstant %int 6
     %int_34 = OpConstant %int 34
    %int_204 = OpConstant %int 204
    %int_102 = OpConstant %int 102
    %int_257 = OpConstant %int 257
     %int_32 = OpConstant %int 32
%_ptr_Uniform_float = OpTypePointer Uniform %float
    %int_256 = OpConstant %int 256
   %int_1024 = OpConstant %int 1024
  %int_65536 = OpConstant %int 65536
%_ptr_Workgroup_float = OpTypePointer Workgroup %float
      %int_9 = OpConstant %int 9
     %int_18 = OpConstant %int 18
     %int_27 = OpConstant %int 27
     %int_68 = OpConstant %int 68
    %int_512 = OpConstant %int 512
    %int_768 = OpConstant %int 768
         %15 = OpFunction %void None %8
         %16 = OpLabel
         %22 = OpAccessChain %_ptr_Input_int %gl_WorkGroupID %int_2
         %23 = OpLoad %int %22
         %28 = OpVariable %_ptr_Function__struct_26 Function
         %40 = OpAccessChain %_ptr_Input_int %gl_WorkGroupID %int_1
         %41 = OpLoad %int %40
         %42 = OpAccessChain %_ptr_Input_int %gl_WorkGroupID %int_0
         %43 = OpLoad %int %42
         %45 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_2
         %46 = OpLoad %int %45
         %47 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_1
         %48 = OpLoad %int %47
         %49 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_0
         %50 = OpLoad %int %49
         %53 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_0
               OpStore %53 %float_0 None
         %54 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_1
               OpStore %54 %float_0 None
         %55 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_2
               OpStore %55 %float_0 None
         %57 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_3
               OpStore %57 %float_0 None
               OpBranch %58
         %58 = OpLabel
         %62 = OpPhi %int %int_0 %16 %288 %60
         %63 = OpSLessThan %bool %62 %int_3
               OpLoopMerge %61 %60 Unroll
               OpBranchConditional %63 %59 %61 128 1
         %59 = OpLabel
         %64 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_2
         %65 = OpLoad %int %64
         %66 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_1
         %67 = OpLoad %int %66
         %68 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_0
         %69 = OpLoad %int %68
               OpControlBarrier %int_2 %int_2 %int_272
               OpBranch %72
         %72 = OpLabel
         %76 = OpPhi %int %int_0 %59 %168 %74
         %77 = OpSLessThan %bool %76 %int_4
               OpLoopMerge %75 %74 Unroll
               OpBranchConditional %77 %73 %75 128 1
         %73 = OpLabel
         %80 = OpIMul %int %69 %int_4
         %81 = OpIAdd %int %80 %76
         %82 = OpSDiv %int %81 %int_34
         %83 = OpIMul %int %65 %int_3
         %84 = OpIAdd %int %83 %82
         %85 = OpSLessThan %bool %84 %int_6
               OpSelectionMerge %87 None
               OpBranchConditional %85 %86 %87 128 1
         %86 = OpLabel
         %89 = OpIMul %int %69 %int_4
         %91 = OpIMul %int %65 %int_102
         %92 = OpIAdd %int %91 %89
         %93 = OpIAdd %int %92 %76
         %94 = OpSLessThan %bool %93 %int_204
               OpSelectionMerge %96 None
               OpBranchConditional %94 %95 %96 128 1
         %95 = OpLabel
         %97 = OpIMul %int %69 %int_4
         %98 = OpIAdd %int %97 %76
         %99 = OpSLessThan %bool %98 %int_102
               OpSelectionMerge %101 None
               OpBranchConditional %99 %100 %101 128 1
        %100 = OpLabel
        %102 = OpIMul %int %69 %int_4
        %103 = OpIAdd %int %102 %76
        %104 = OpSDiv %int %103 %int_34
        %105 = OpIMul %int %65 %int_3
        %106 = OpIAdd %int %105 %104
        %107 = OpIMul %int %41 %int_4
        %108 = OpIAdd %int %107 %106
        %109 = OpSLessThanEqual %bool %int_1 %108
        %111 = OpIMul %int %69 %int_4
        %112 = OpIAdd %int %111 %76
        %113 = OpSDiv %int %112 %int_34
        %114 = OpIMul %int %65 %int_3
        %115 = OpIAdd %int %114 %113
        %116 = OpIMul %int %41 %int_4
        %117 = OpIAdd %int %116 %115
        %118 = OpSLessThan %bool %117 %int_257
        %119 = OpLogicalAnd %bool %109 %118
        %120 = OpIMul %int %69 %int_4
        %121 = OpIAdd %int %120 %76
        %122 = OpSRem %int %121 %int_34
        %124 = OpIMul %int %43 %int_32
        %125 = OpIAdd %int %124 %122
        %126 = OpSLessThanEqual %bool %int_1 %125
        %127 = OpLogicalAnd %bool %119 %126
        %128 = OpIMul %int %69 %int_4
        %129 = OpIAdd %int %128 %76
        %130 = OpSRem %int %129 %int_34
        %131 = OpIMul %int %43 %int_32
        %132 = OpIAdd %int %131 %130
        %133 = OpSLessThan %bool %132 %int_257
        %134 = OpLogicalAnd %bool %127 %133
               OpSelectionMerge %137 None
               OpBranchConditional %134 %135 %136
        %135 = OpLabel
        %139 = OpIMul %int %69 %int_4
        %140 = OpIAdd %int %139 %76
        %141 = OpSRem %int %140 %int_34
        %142 = OpIMul %int %43 %int_32
        %144 = OpIMul %int %69 %int_4
        %145 = OpIMul %int %65 %int_102
        %146 = OpIAdd %int %145 %144
        %147 = OpIAdd %int %146 %76
        %148 = OpSDiv %int %147 %int_34
        %149 = OpIMul %int %148 %int_256
        %151 = OpIMul %int %41 %int_1024
        %153 = OpIMul %int %62 %int_65536
        %154 = OpIAdd %int %153 %151
        %155 = OpIAdd %int %154 %149
        %156 = OpIAdd %int %155 %142
        %157 = OpIAdd %int %156 %141
        %158 = OpISub %int %157 %int_257
        %159 = OpInBoundsAccessChain %_ptr_Uniform_float %12 %int_0 %158
        %160 = OpLoad %float %159 None
               OpBranch %137
        %136 = OpLabel
               OpBranch %137
        %137 = OpLabel
        %161 = OpPhi %float %160 %135 %float_0 %136
        %163 = OpIMul %int %69 %int_4
        %164 = OpIMul %int %65 %int_102
        %165 = OpIAdd %int %164 %163
        %166 = OpIAdd %int %165 %76
        %167 = OpInBoundsAccessChain %_ptr_Workgroup_float %33 %int_0 %166
               OpStore %167 %161 None
               OpBranch %101
        %101 = OpLabel
               OpBranch %96
         %96 = OpLabel
               OpBranch %87
         %87 = OpLabel
               OpBranch %74
         %74 = OpLabel
        %168 = OpIAdd %int %76 %int_1
               OpBranch %72
         %75 = OpLabel
        %169 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_2
        %170 = OpLoad %int %169
        %171 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_1
        %172 = OpLoad %int %171
        %173 = OpAccessChain %_ptr_Input_int %gl_LocalInvocationID %int_0
        %174 = OpLoad %int %173
        %176 = OpSDiv %int %174 %int_9
        %177 = OpIAdd %int %176 %170
        %178 = OpSLessThan %bool %177 %int_2
               OpSelectionMerge %180 None
               OpBranchConditional %178 %179 %180 128 1
        %179 = OpLabel
        %181 = OpSDiv %int %174 %int_3
        %182 = OpIMul %int %170 %int_3
        %183 = OpIAdd %int %182 %181
        %184 = OpSLessThan %bool %183 %int_6
               OpSelectionMerge %186 None
               OpBranchConditional %184 %185 %186 128 1
        %185 = OpLabel
        %188 = OpIMul %int %170 %int_9
        %189 = OpIAdd %int %188 %174
        %190 = OpSLessThan %bool %189 %int_18
               OpSelectionMerge %192 None
               OpBranchConditional %190 %191 %192 128 1
        %191 = OpLabel
        %193 = OpSLessThan %bool %174 %int_9
               OpSelectionMerge %195 None
               OpBranchConditional %193 %194 %195 128 1
        %194 = OpLabel
        %196 = OpIMul %int %62 %int_9
        %198 = OpIMul %int %170 %int_27
        %199 = OpIAdd %int %198 %196
        %200 = OpIAdd %int %199 %174
        %201 = OpInBoundsAccessChain %_ptr_Uniform_float %13 %int_0 %200
        %202 = OpLoad %float %201 None
        %203 = OpIMul %int %170 %int_9
        %204 = OpIAdd %int %203 %174
        %205 = OpInBoundsAccessChain %_ptr_Workgroup_float %38 %int_0 %204
               OpStore %205 %202 None
               OpBranch %195
        %195 = OpLabel
               OpBranch %192
        %192 = OpLabel
               OpBranch %186
        %186 = OpLabel
               OpBranch %180
        %180 = OpLabel
               OpControlBarrier %int_2 %int_2 %int_272
               OpBranch %206
        %206 = OpLabel
        %210 = OpPhi %int %int_0 %180 %287 %208
        %211 = OpSLessThan %bool %210 %int_3
               OpLoopMerge %209 %208 Unroll
               OpBranchConditional %211 %207 %209 128 1
        %207 = OpLabel
               OpBranch %212
        %212 = OpLabel
        %216 = OpPhi %int %int_0 %207 %286 %214
        %217 = OpSLessThan %bool %216 %int_3
               OpLoopMerge %215 %214 Unroll
               OpBranchConditional %217 %213 %215 128 1
        %213 = OpLabel
        %218 = OpIMul %int %210 %int_3
        %219 = OpIMul %int %46 %int_9
        %220 = OpIAdd %int %219 %218
        %221 = OpIAdd %int %220 %216
        %222 = OpInBoundsAccessChain %_ptr_Workgroup_float %38 %int_0 %221
        %223 = OpLoad %float %222 None
        %224 = OpIMul %int %210 %int_34
        %225 = OpIAdd %int %224 %50
        %226 = OpIAdd %int %225 %216
        %227 = OpInBoundsAccessChain %_ptr_Workgroup_float %33 %int_0 %226
        %228 = OpLoad %float %227 None
        %229 = OpFMul %float %228 %223
        %230 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_0
        %231 = OpLoad %float %230 None
        %232 = OpFAdd %float %231 %229
        %233 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_0
               OpStore %233 %232 None
        %234 = OpIMul %int %210 %int_3
        %235 = OpIMul %int %46 %int_9
        %236 = OpIAdd %int %235 %234
        %237 = OpIAdd %int %236 %216
        %238 = OpInBoundsAccessChain %_ptr_Workgroup_float %38 %int_0 %237
        %239 = OpLoad %float %238 None
        %240 = OpIMul %int %210 %int_34
        %241 = OpIAdd %int %240 %50
        %242 = OpIAdd %int %241 %216
        %243 = OpIAdd %int %242 %int_34
        %244 = OpInBoundsAccessChain %_ptr_Workgroup_float %33 %int_0 %243
        %245 = OpLoad %float %244 None
        %246 = OpFMul %float %245 %239
        %247 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_1
        %248 = OpLoad %float %247 None
        %249 = OpFAdd %float %248 %246
        %250 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_1
               OpStore %250 %249 None
        %251 = OpIMul %int %210 %int_3
        %252 = OpIMul %int %46 %int_9
        %253 = OpIAdd %int %252 %251
        %254 = OpIAdd %int %253 %216
        %255 = OpInBoundsAccessChain %_ptr_Workgroup_float %38 %int_0 %254
        %256 = OpLoad %float %255 None
        %258 = OpIMul %int %210 %int_34
        %259 = OpIAdd %int %258 %50
        %260 = OpIAdd %int %259 %216
        %261 = OpIAdd %int %260 %int_68
        %262 = OpInBoundsAccessChain %_ptr_Workgroup_float %33 %int_0 %261
        %263 = OpLoad %float %262 None
        %264 = OpFMul %float %263 %256
        %265 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_2
        %266 = OpLoad %float %265 None
        %267 = OpFAdd %float %266 %264
        %268 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_2
               OpStore %268 %267 None
        %269 = OpIMul %int %210 %int_3
        %270 = OpIMul %int %46 %int_9
        %271 = OpIAdd %int %270 %269
        %272 = OpIAdd %int %271 %216
        %273 = OpInBoundsAccessChain %_ptr_Workgroup_float %38 %int_0 %272
        %274 = OpLoad %float %273 None
        %275 = OpIMul %int %210 %int_34
        %276 = OpIAdd %int %275 %50
        %277 = OpIAdd %int %276 %216
        %278 = OpIAdd %int %277 %int_102
        %279 = OpInBoundsAccessChain %_ptr_Workgroup_float %33 %int_0 %278
        %280 = OpLoad %float %279 None
        %281 = OpFMul %float %280 %274
        %282 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_3
        %283 = OpLoad %float %282 None
        %284 = OpFAdd %float %283 %281
        %285 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_3
               OpStore %285 %284 None
               OpBranch %214
        %214 = OpLabel
        %286 = OpIAdd %int %216 %int_1
               OpBranch %212
        %215 = OpLabel
               OpBranch %208
        %208 = OpLabel
        %287 = OpIAdd %int %210 %int_1
               OpBranch %206
        %209 = OpLabel
               OpBranch %60
         %60 = OpLabel
        %288 = OpIAdd %int %62 %int_1
               OpBranch %58
         %61 = OpLabel
        %289 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_0
        %290 = OpLoad %float %289 None
        %291 = OpIMul %int %43 %int_32
        %292 = OpIMul %int %41 %int_1024
        %293 = OpIMul %int %46 %int_65536
        %294 = OpIAdd %int %293 %292
        %295 = OpIAdd %int %294 %291
        %296 = OpIAdd %int %295 %50
        %297 = OpInBoundsAccessChain %_ptr_Uniform_float %14 %int_0 %296
               OpStore %297 %290 None
        %298 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_1
        %299 = OpLoad %float %298 None
        %300 = OpIMul %int %43 %int_32
        %301 = OpIMul %int %41 %int_1024
        %302 = OpIMul %int %46 %int_65536
        %303 = OpIAdd %int %302 %301
        %304 = OpIAdd %int %303 %300
        %305 = OpIAdd %int %304 %50
        %306 = OpIAdd %int %305 %int_256
        %307 = OpInBoundsAccessChain %_ptr_Uniform_float %14 %int_0 %306
               OpStore %307 %299 None
        %308 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_2
        %309 = OpLoad %float %308 None
        %311 = OpIMul %int %43 %int_32
        %312 = OpIMul %int %41 %int_1024
        %313 = OpIMul %int %46 %int_65536
        %314 = OpIAdd %int %313 %312
        %315 = OpIAdd %int %314 %311
        %316 = OpIAdd %int %315 %50
        %317 = OpIAdd %int %316 %int_512
        %318 = OpInBoundsAccessChain %_ptr_Uniform_float %14 %int_0 %317
               OpStore %318 %309 None
        %319 = OpInBoundsAccessChain %_ptr_Function_float %28 %int_0 %int_3
        %320 = OpLoad %float %319 None
        %322 = OpIMul %int %43 %int_32
        %323 = OpIMul %int %41 %int_1024
        %324 = OpIMul %int %46 %int_65536
        %325 = OpIAdd %int %324 %323
        %326 = OpIAdd %int %325 %322
        %327 = OpIAdd %int %326 %50
        %328 = OpIAdd %int %327 %int_768
        %329 = OpInBoundsAccessChain %_ptr_Uniform_float %14 %int_0 %328
               OpStore %329 %320 None
               OpReturn
               OpFunctionEnd

I intended to generate SPIR-V assembler with MLIR like TVM. Finally I want to generate the inference shaders for Vulkan, Metal and Direct3D 12 with MLIR and SPIRV-Cross. Thanks.

antiagainst commented 5 years ago

Hey @stakemura, thanks for the explanation; it's exciting to see this coming! :)

We are actively working on the SPIR-V dialect in MLIR and its conversion right now. The end goal is to take in computation graph expressed in TensorFlow (as TF dialect in MLIR) and lower it progressively to SPIR-V and run on Vulkan. So eventually we hope you can just write the style transfer or whatever other inference logic in high-level TensorFlow code. Right now we are still not quite there yet. The whole conversion flow is still under development. For the SPIR-V dialect itself, we haven't gotten to control flow constructs (which is the next step). So there are still functionalities missing to support the above use case. (If you can help us to make it happen that would be truly awesome!) If you are trying to utilize the SPIR-V dialect directly "as a SPIR-V builder", it can be a bit verbose. You will need to write C++ code to construct the IR manually; the deserializer can act as an example of how to call the APIs. Pay particular attention to those opBuilder.create<...> calls. Let me know if you have other questions and I'm happy to help.

bhack commented 5 years ago

@antiagainst Are you directly active in the Kronos ML technical subgroup? https://www.phoronix.com/scan.php?page=news_item&px=SIGGRAPH-2019-Vulkan-ML

antiagainst commented 5 years ago

Hey @bhack, I started to participate in the TSG discussion.

bhack commented 5 years ago

Anything public?

antiagainst commented 5 years ago

Hey @bhack, thanks for the interest! But I don't think I'm in the position to speak publicly for the whole Vulkan ML TSG. You may watch the Khronos Group's official channels for updates. :)

jon-chuang commented 3 years ago

Would C++/Rust with additional intrinsics be able to lower to MLIR and by extension spirv? What would need to be done to get this to work?

antiagainst commented 3 years ago

Hi @jon-chuang, please note that right now MLIR is part of LLVM monorepo so issues no this repo is not maintained anymore.

Your question here is quite vague. What C++/Rust features are you interested? What additional intrinsics? Which SPIR-V target environment (Vulkan/OpenCL/OpenGL/etc.) you are considering? We might be able to convert some depending on the particular answers to the above questions; still I'd assume they typically incur a significant amount of work.