Skip to main content
Log in

Mojo function

debug_assert

debug_assert[: origin.set, //, cond: fn() capturing -> Bool, assert_mode: StringLiteral = "none", cpu_only: Bool = False, *Ts: Writable = *?](*messages: *Ts)

Asserts that the condition is true.

You can pass in multiple args that are Writable to generate a formatted message, by default this will be a no-op:

x = 0
debug_assert(x > 0, "expected x to be more than 0 but got: ", x)
x = 0
debug_assert(x > 0, "expected x to be more than 0 but got: ", x)

You can change the assertion level for example:

mojo -D ASSERT=all main.mojo
mojo -D ASSERT=all main.mojo

Assertion modes:

  • none: turn off all assertions for performance at the cost of safety.
  • warn: print any errors instead of aborting.
  • safe: standard safety checks that are on even in release builds.
  • all: turn on all assertions.

You can set the assert_mode to safe so the assertion runs even in release builds:

debug_assert[assert_mode="safe"](
x > 0, "expected x to be more than 0 but got: ", x
)
debug_assert[assert_mode="safe"](
x > 0, "expected x to be more than 0 but got: ", x
)

To ensure that you have no runtime penality from your assertion in release builds, make sure there are no side effects in your message and condition. Take this example:

person = "name: john, age: 50"
name = "john"
debug_assert(String("name: ") + name == person, "unexpected name")
person = "name: john, age: 50"
name = "john"
debug_assert(String("name: ") + name == person, "unexpected name")

This will have a runtime penality due to allocating a String in the condition even in release builds, you must put the condition inside a closure so it only runs when the assertion is turned on:

fn check_name() capturing -> Bool:
return String("name: ") + name == person

debug_assert[check_name]("unexpected name")
fn check_name() capturing -> Bool:
return String("name: ") + name == person

debug_assert[check_name]("unexpected name")

If you need to allocate, and so don't want the assert to ever run on GPU, you can set it to CPU only:

debug_assert[check_name, cpu_only=True]("unexpected name")
debug_assert[check_name, cpu_only=True]("unexpected name")

Parameters:

  • cond (fn() capturing -> Bool): The function to invoke to check if the assertion holds.
  • assert_mode (StringLiteral): Determines when the assert is turned on.
  • cpu_only (Bool): If true, only run the assert on CPU.
  • *Ts (Writable): The element types conforming to Writable for the message.

Args:

  • *messages (*Ts): Arguments to convert to a String message.

debug_assert[assert_mode: StringLiteral = "none", cpu_only: Bool = False, *Ts: Writable = *?](cond: Bool, *messages: *Ts)

Asserts that the condition is true.

You can pass in multiple args that are Writable to generate a formatted message, by default this will be a no-op:

x = 0
debug_assert(x > 0, "expected x to be more than 0 but got: ", x)
x = 0
debug_assert(x > 0, "expected x to be more than 0 but got: ", x)

You can change the assertion level for example:

mojo -D ASSERT=all main.mojo
mojo -D ASSERT=all main.mojo

Assertion modes:

  • none: turn off all assertions for performance at the cost of safety.
  • warn: print any errors instead of aborting.
  • safe: standard safety checks that are on even in release builds.
  • all: turn on all assertions.

You can set the assert_mode to safe so the assertion runs even in release builds:

debug_assert[assert_mode="safe"](
x > 0, "expected x to be more than 0 but got: ", x
)
debug_assert[assert_mode="safe"](
x > 0, "expected x to be more than 0 but got: ", x
)

To ensure that you have no runtime penality from your assertion in release builds, make sure there are no side effects in your message and condition. Take this example:

person = "name: john, age: 50"
name = "john"
debug_assert(String("name: ") + name == person, "unexpected name")
person = "name: john, age: 50"
name = "john"
debug_assert(String("name: ") + name == person, "unexpected name")

This will have a runtime penality due to allocating a String in the condition even in release builds, you must put the condition inside a closure so it only runs when the assertion is turned on:

fn check_name() capturing -> Bool:
return String("name: ") + name == person

debug_assert[check_name]("unexpected name")
fn check_name() capturing -> Bool:
return String("name: ") + name == person

debug_assert[check_name]("unexpected name")

If you need to allocate, and so don't want the assert to ever run on GPU, you can set it to CPU only:

debug_assert[check_name, cpu_only=True]("unexpected name")
debug_assert[check_name, cpu_only=True]("unexpected name")

Parameters:

  • assert_mode (StringLiteral): Determines when the assert is turned on.
  • cpu_only (Bool): If true, only run the assert on CPU.
  • *Ts (Writable): The element types conforming to Writable for the message.

Args:

  • cond (Bool): The bool value to assert.
  • *messages (*Ts): Arguments to convert to a String message.