File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ Metal Logging
2+ =============
3+
4+ In debug builds, MLX compiles Metal kernels with ``os_log `` enabled so shader
5+ warnings and debug messages are visible during development.
6+
7+ .. note ::
8+ Metal logging is only available with Metal 3.2 or higher (macOS 15 and up,
9+ iOS 18 and up).
10+
11+ To enable logging from kernels, first make sure to build in debug mode:
12+
13+ .. code-block :: bash
14+
15+ DEBUG=1 python -m pip install -e .
16+
17+ Then, in the kernel source code include MLX's logging shim and use
18+ ``mlx::os_log ``:
19+
20+ .. code-block ::
21+
22+ #include "mlx/backend/metal/kernels/logging.h"
23+
24+ constant mlx::os_log logger("mlx", "my_kernel");
25+
26+ kernel void my_kernel(/* ... */) {
27+ // ...
28+ logger.log_debug("unexpected state: idx=%u", idx);
29+ }
30+
31+ When you run the program, set the Metal log level to your desired level and
32+ forward logs to ``stderr ``:
33+
34+ .. code-block :: bash
35+
36+ MTL_LOG_LEVEL=MTLLogLevelDebug MTL_LOG_TO_STDERR=1 python script.py
37+
38+ See the `Metal logging guide `_ for more details.
39+
40+ .. _`Metal logging guide` : https://developer.apple.com/documentation/metal/logging-shader-debug-messages
Original file line number Diff line number Diff line change @@ -89,5 +89,6 @@ are the CPU and GPU.
8989
9090 dev/extensions
9191 dev/metal_debugger
92+ dev/metal_logging
9293 dev/custom_metal_kernels
9394 dev/mlx_in_cpp
Original file line number Diff line number Diff line change @@ -22,7 +22,7 @@ function(make_jit_source SRC_FILE)
2222endfunction (make_jit_source )
2323
2424make_jit_source (utils kernels/bf16.h kernels/bf16_math.h kernels/complex.h
25- kernels/defines.h )
25+ kernels/defines.h kernels/logging.h )
2626make_jit_source (unary_ops kernels/erf.h kernels/expm1f.h kernels/fp8.h )
2727make_jit_source (binary_ops )
2828make_jit_source (ternary_ops )
Original file line number Diff line number Diff line change @@ -224,7 +224,7 @@ MTL::Library* load_library(
224224 std::ostringstream msg;
225225 msg << " Failed to load the metallib " << lib_name << " .metallib. "
226226 << " We attempted to load it from <" << current_binary_dir () << " /"
227- << lib_name << " .metallib" << " >" ;
227+ << lib_name << " .metallib>" ;
228228#ifdef SWIFTPM_BUNDLE
229229 msg << " and from the Swift PM bundle." ;
230230#endif
@@ -529,6 +529,11 @@ MTL::Library* Device::build_library_(const std::string& source_string) {
529529 auto options = MTL::CompileOptions::alloc ()->init ();
530530 options->setFastMathEnabled (false );
531531 options->setLanguageVersion (get_metal_version ());
532+ #ifndef NDEBUG
533+ if (options->languageVersion () >= MTL::LanguageVersion3_2) {
534+ options->setEnableLogging (true );
535+ }
536+ #endif
532537 auto mtl_lib = device_->newLibrary (ns_code, options, &error);
533538 options->release ();
534539
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ set(BASE_HEADERS
66 erf.h
77 expm1f.h
88 fp8.h
9+ logging.h
910 utils.h)
1011
1112function (build_kernel_base TARGET SRCFILE DEPS )
@@ -20,6 +21,9 @@ function(build_kernel_base TARGET SRCFILE DEPS)
2021 if (MLX_METAL_DEBUG)
2122 set (METAL_FLAGS ${METAL_FLAGS} -gline-tables-only -frecord-sources)
2223 endif ()
24+ if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND MLX_METAL_VERSION GREATER_EQUAL 320)
25+ set (METAL_FLAGS ${METAL_FLAGS} -fmetal-enable-logging)
26+ endif ()
2327 if (NOT CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "" )
2428 set (METAL_FLAGS ${METAL_FLAGS}
2529 "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} " )
Original file line number Diff line number Diff line change 55#include < metal_integer>
66#include < metal_math>
77
8+ constant mlx::os_log logger (" mlx" , " binary_ops" );
9+
810struct Add {
911 template <typename T>
1012 T operator ()(T x, T y) {
@@ -225,6 +227,8 @@ struct Power {
225227 T res = 1 ;
226228 // Undefined to raise integer to negative power
227229 if (exp < 0 ) {
230+ logger.log_debug (
231+ " int pow exp<0 (base=%ld exp=%ld)" , (long )base, (long )exp);
228232 return 0 ;
229233 }
230234
Original file line number Diff line number Diff line change 22
33#pragma once
44
5+ constant mlx::os_log logger (" mlx" , " masked_assign" );
6+
57template <typename T, bool src_contiguous>
68[[kernel]] void masked_assign_impl (
79 const device bool * mask [[buffer(0 )]],
@@ -21,6 +23,7 @@ template <typename T, bool src_contiguous>
2123
2224 const uint src_index = scatter_offsets[idx];
2325 if (src_index >= src_batch_size) {
26+ logger.log_debug (" Out of bound read from src" );
2427 return ;
2528 }
2629
Original file line number Diff line number Diff line change 1+ // Copyright © 2025 Apple Inc.
2+
3+ #pragma once
4+
5+ #if defined(__METAL_VERSION__) && (__METAL_VERSION__ >= 320)
6+ #include < metal_logging>
7+
8+ namespace mlx {
9+ using os_log = metal::os_log;
10+ } // namespace mlx
11+
12+ #else
13+
14+ namespace mlx {
15+ struct os_log {
16+ constexpr os_log (constant char *, constant char *) constant {}
17+
18+ template <typename ... Args>
19+ void log_debug (constant char *, Args...) const {}
20+
21+ template <typename ... Args>
22+ void log_debug (constant char *, Args...) const constant {}
23+ };
24+ } // namespace mlx
25+
26+ #endif
Original file line number Diff line number Diff line change 88#include " mlx/backend/metal/kernels/bf16_math.h"
99#include " mlx/backend/metal/kernels/complex.h"
1010#include " mlx/backend/metal/kernels/defines.h"
11+ #include " mlx/backend/metal/kernels/logging.h"
1112
1213typedef half float16_t ;
1314
You can’t perform that action at this time.
0 commit comments