[MLIR] Vulkan runtime does not restore `std::cout` precision, causing incorrect RunnerUtils float output
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
The MLIR Vulkan runtime changes the precision of the global std::cout stream while printing GPU timing information and does not restore the previous stream state. Consequently, floating-point values subsequently printed by RunnerUtils use only three significant digits. In the reproducer below, the same memref containing 858.5f is printed before and after launching a no-op Vulkan kernel. The first print produces 858.5, while the second produces 858.
The issue is reproducible with both the NVIDIA Vulkan backend and the Intel Vulkan backend using Mesa.
### Input Program
**input.mlir**
```llvm
module attributes {
gpu.container_module,
spirv.target_env = #spirv.target_env<
#spirv.vce,
#spirv.resource_limits<>>
} {
gpu.module @kernels {
gpu.func @noop(%value : memref<1xf32>) kernel
attributes {
spirv.entry_point_abi =
#spirv.entry_point_abi
} {
gpu.return
}
}
func.func @main() {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%value = memref.alloc() : memref<1xf32>
%c858_5 = arith.constant 858.5 : f32
memref.store %c858_5, %value[%c0] : memref<1xf32>
%value_unranked =
memref.cast %value : memref<1xf32> to memref<*xf32>
// Print the value before invoking the Vulkan runtime.
call @printMemrefF32(%value_unranked) : (memref<*xf32>) -> ()
// The kernel does not read or modify the memref.
gpu.launch_func @kernels::@noop
blocks in (%c1, %c1, %c1) threads in (%c1, %c1, %c1)
args(%value : memref<1xf32>)
// Print the unchanged value after invoking the Vulkan runtime.
call @printMemrefF32(%value_unranked) : (memref<*xf32>) -> ()
// Print its raw f32 bit pattern.
%loaded = memref.load %value[%c0] : memref<1xf32>
%bits = arith.bitcast %loaded : f32 to i32
%bits_buffer = memref.alloc() : memref<1xi32>
memref.store %bits, %bits_buffer[%c0] : memref<1xi32>
%bits_unranked =
memref.cast %bits_buffer : memref<1xi32> to memref<*xi32>
call @printMemrefI32(%bits_unranked) : (memref<*xi32>) -> ()
memref.dealloc %bits_buffer : memref<1xi32>
memref.dealloc %value : memref<1xf32>
return
}
func.func private @printMemrefF32(memref<*xf32>)
attributes {llvm.emit_c_interface}
func.func private @printMemrefI32(memref<*xi32>)
attributes {llvm.emit_c_interface}
}
```
### Lowering Command
```bash
mlir-opt \
input.mlir \
'--pass-pipeline=builtin.module(
spirv-attach-target{
ver=v1.3
caps=Shader
exts=SPV_KHR_storage_buffer_storage_class
},
test-convert-to-spirv{
convert-gpu-modules=true
nest-in-gpu-module=true
},
gpu.module(
spirv.module(
spirv-lower-abi-attrs,
spirv-update-vce
)
),
gpu-module-to-binary,
finalize-memref-to-llvm,
func.func(llvm-request-c-wrappers),
gpu-to-llvm{
use-bare-pointers-for-kernels=true
intersperse-sizes-for-kernels=true
},
reconcile-unrealized-casts
)' \
-o lower.mlir
```
### Execution Command
```bash
mlir-runner \
lower.mlir \
--shared-libs=$$LLVM_BUILD/lib/libmlir_vulkan_runtime.so \
--shared-libs=$$LLVM_BUILD/lib/libmlir_runner_utils.so \
--shared-libs=$$LLVM_BUILD/lib/libmlir_c_runner_utils.so \
--entry-point-result=void
```
A particular Vulkan device can be selected through VK_ICD_FILENAMES. For example, the NVIDIA device was selected with:
```bash
export VK_LOADER_LAYERS_DISABLE="*"
export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/nvidia_icd.json
```
After the no-op Vulkan kernel launch, RunnerUtils prints the unchanged value 858.5f as 858. It should still print 858.5.
The raw bit pattern remains 0x4456a000, confirming that the stored value is unchanged and only the output formatting is incorrect.
Version: 0e0e0c388ec7894ff22d84e4f1c1c0d2833509a2
Contributor guide
Research direction
Start with the supplied input.mlir, lowering command, and execution through libmlir_vulkan_runtime.so with libmlir_runner_utils.so; compare RunnerUtils output before and after the no-op Vulkan launch. Trace the Vulkan runtime's GPU timing output and stream-state handling. Done means the unchanged value prints as 858.5 after execution and the raw bit pattern remains 0x4456a000.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100