Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

godot_error: message must be ASCII #384

Open
GaspardCulis opened this issue Aug 18, 2023 · 3 comments
Open

godot_error: message must be ASCII #384

GaspardCulis opened this issue Aug 18, 2023 · 3 comments
Labels
bug c: core Core components

Comments

@GaspardCulis
Copy link

Hello, here is all of my source code lol:

use godot::prelude::*;
use ndarray::{Array, ArrayBase, Dim, OwnedRepr};
use rand::Rng;

type NNArray = ArrayBase<OwnedRepr<f64>, Dim<[usize; 2]>>;

macro_rules! godot_panic {
    ($msg:expr) => {{
        godot_error!($msg);
        println!($msg);
        panic!($msg);
    }};
}

trait Layer {
    fn new(input_shape: usize, output_shape: usize) -> Self;

    fn forward(&self, inputs: NNArray) -> NNArray;
}

#[derive(Debug, GodotClass)]
#[class(base=Resource)]
struct Dense {
    weights: NNArray,
    biases: NNArray,
    input_size: usize,
    output_size: usize,
}

impl Layer for Dense {
    fn new(input_size: usize, output_size: usize) -> Self {
        Dense {
            weights: Array::from_shape_fn((output_size, input_size), |(_, _)| {
                rand::thread_rng().gen_range(-2f64..2f64)
            }),
            biases: Array::from_shape_fn((output_size, 1), |(_, _)| {
                rand::thread_rng().gen_range(-2f64..2f64)
            }),
            input_size,
            output_size,
        }
    }

    fn forward(&self, inputs: NNArray) -> NNArray {
        inputs.dot(&self.weights) + &self.biases
    }
}

#[godot_api]
impl ResourceVirtual for Dense {
    fn init(_: Base<Resource>) -> Self {
        Self {
            weights: Array::zeros((0, 0)),
            biases: Array::zeros((0, 0)),
            input_size: 0,
            output_size: 0,
        }
    }
}

struct WrappedGDArray(VariantArray);

impl From<WrappedGDArray> for NNArray {
    fn from(value: WrappedGDArray) -> NNArray {
        let value = value.0;
        if value.len() == 0 {
            godot_panic!("Empty array provided");
        }

        let f = value.first().unwrap();
        if f.get_type() != VariantType::Array {
            godot_panic!("Array isn t a matrix (not an array of arrays)");
        }

        let f: VariantArray = f.to();
        if f.len() == 0 {
            godot_panic!("Array of empty arrays provided");
        }

        if f.first().unwrap().get_type() != VariantType::Float {
            godot_panic!("Matrix of non floats provided");
        }

        let shape = [value.len(), f.len()];

        NNArray::from_shape_fn(shape, |(i, j)| {
            value.get(i).to::<VariantArray>().get(j).to()
        })
    }
}

impl Into<WrappedGDArray> for NNArray {
    fn into(self) -> WrappedGDArray {
        let mut gd_array = WrappedGDArray(VariantArray::new());
        for row in self.rows() {
            let mut gd_row = VariantArray::new();
            for &value in row {
                gd_row.push(Variant::from(value));
            }
            gd_array.0.push(gd_row.to_variant());
        }
        gd_array
    }
}

#[godot_api]
impl Dense {
    #[func]
    fn init(&mut self, input_size: i32, output_size: i32) {
        self.input_size = input_size as usize;
        self.output_size = output_size as usize;
        self.weights = Array::from_shape_fn((self.output_size, self.input_size), |(_, _)| {
            rand::thread_rng().gen_range(-2f64..2f64)
        });
        self.biases = Array::from_shape_fn((self.output_size, 1), |(_, _)| {
            rand::thread_rng().gen_range(-2f64..2f64)
        });
    }

    #[func]
    fn think(&self, inputs: VariantArray) -> VariantArray {
        if inputs.len() != self.input_size {
            godot_panic!("Mismatched input size");
        }
        let nnarray_inputs = Array::from(WrappedGDArray(WrappedGDArray(inputs).0));

        let out: WrappedGDArray = self.forward(nnarray_inputs).into();

        out.0
    }
}

struct Godumb;

#[gdextension]
unsafe impl ExtensionLibrary for Godumb {}

(sry no line numbers)
Worked like a charm until it didn't

Here is the error I get with the full rust backtrace:

[gaspard@Zephyrus ~]$ RUST_BACKTRACE=full godot
Godot Engine v4.1.1.stable.official.bd6af8e0e - https://godotengine.org
libGL error: glx: failed to create dri3 screen
libGL error: failed to load driver: nouveau
OpenGL API 4.6 (Core Profile) Mesa 23.1.5 - Compatibility - Using Device: AMD - AMD Radeon Graphics (renoir, LLVM 15.0.7, DRM 3.52, 6.4.10-zen2-1-zen)
 
Editing project: /home/gaspard/Programmation/Godot/Godumb
Initialize GDExtension API for Rust: Godot Engine v4.1.1.stable.official
Godot Engine v4.1.1.stable.official.bd6af8e0e - https://godotengine.org
Vulkan API 1.3.242 - Forward+ - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce RTX 3070 Laptop GPU
[gaspard@Zephyrus ~]$  
WARNING: Blend file import is enabled in the project settings, but no Blender path is configured in the editor settings. Blend files will not be imported.
     at: _editor_init (modules/gltf/register_types.cpp:73)
Initialize GDExtension API for Rust: Godot Engine v4.1.1.stable.official
Godot Engine v4.1.1.stable.official.bd6af8e0e - https://godotengine.org
Vulkan API 1.3.242 - Forward+ - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce RTX 3070 Laptop GPU
 
ERROR: Rust function panicked in file /home/gaspard/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ndarray-0.15.6/src/linalg/impl_linalg.rs at line 299. Context: think
   at: <function unset> (/home/gaspard/.cargo/git/checkouts/gdext-76630c89719e160c/b4e6fd6/godot-core/src/lib.rs:150)
thread '<unnamed>' panicked at 'godot_error: message must be ASCII', /home/gaspard/.cargo/git/checkouts/gdext-76630c89719e160c/b4e6fd6/godot-core/src/lib.rs:101:13
stack backtrace:
   0:     0x7f64e7309641 - std::backtrace_rs::backtrace::libunwind::trace::h6aeaf83abc038fe6
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x7f64e7309641 - std::backtrace_rs::backtrace::trace_unsynchronized::h4f9875212db0ad97
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x7f64e7309641 - std::sys_common::backtrace::_print_fmt::h3f820027e9c39d3b
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/sys_common/backtrace.rs:65:5
   3:     0x7f64e7309641 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hded4932df41373b3
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x7f64e7329d3f - core::fmt::rt::Argument::fmt::hc8ead7746b2406d6
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/fmt/rt.rs:138:9
   5:     0x7f64e7329d3f - core::fmt::write::hb1cb56105a082ad9
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/fmt/mod.rs:1094:21
   6:     0x7f64e73078b1 - std::io::Write::write_fmt::h797fda7085c97e57
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/io/mod.rs:1713:15
   7:     0x7f64e7309455 - std::sys_common::backtrace::_print::h492d3c92d7400346
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x7f64e7309455 - std::sys_common::backtrace::print::hf74aa2eef05af215
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x7f64e730a957 - std::panicking::default_hook::{{closure}}::h8cad394227ea3de8
  10:     0x7f64e730a744 - std::panicking::default_hook::h249cc184fec99a8a
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/panicking.rs:288:9
  11:     0x7f64e730af6d - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h0be7fc2421582b49
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/alloc/src/boxed.rs:1999:9
  12:     0x7f64e730af6d - std::panicking::rust_panic_with_hook::h82ebcd5d5ed2fad4
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/panicking.rs:709:13
  13:     0x7f64e730acc1 - std::panicking::begin_panic_handler::{{closure}}::h810bed8ecbe66f1a
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/panicking.rs:595:13
  14:     0x7f64e7309a76 - std::sys_common::backtrace::__rust_end_short_backtrace::h1410008071796261
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/sys_common/backtrace.rs:151:18
  15:     0x7f64e730aa52 - rust_begin_unwind
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/panicking.rs:593:5
  16:     0x7f64e71e6133 - core::panicking::panic_fmt::ha0a42a25e0cf258d
                               at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/panicking.rs:67:14
  17:     0x7f64e72d5b0c - godot_core::private::print_panic_message::hc0376a14122a969a
                               at /home/gaspard/.cargo/git/checkouts/gdext-76630c89719e160c/b4e6fd6/godot-core/src/lib.rs:101:13
  18:     0x7f64e72d536d - godot_core::private::print_panic::hdaf3958432ca5661
                               at /home/gaspard/.cargo/git/checkouts/gdext-76630c89719e160c/b4e6fd6/godot-core/src/lib.rs:87:13
  19:     0x7f64e71f2664 - godot_core::private::handle_panic::he97613106a053e9f
                               at /home/gaspard/.cargo/git/checkouts/gdext-76630c89719e160c/b4e6fd6/godot-core/src/lib.rs:156:17
  20:     0x7f64e720a774 - <godumb::Dense as godot_core::obj::traits::cap::ImplementsGodotApi>::__register_methods::function::hbef2250033aa3533
                               at /home/gaspard/Programmation/Godot/Godumb/rust/src/lib.rs:106:1
  21:          0x47c5f18 - <unknown>
  22:          0x47d7128 - <unknown>
  23:          0x463082a - <unknown>
  24:          0x1289db4 - <unknown>
  25:          0x118d948 - <unknown>
  26:          0x2d1c928 - <unknown>
  27:          0x32dcaa2 - <unknown>
  28:          0x47c4d94 - <unknown>
  29:          0x2ccbf46 - <unknown>
  30:          0x2ccbef4 - <unknown>
  31:          0x2d3c5df - <unknown>
  32:          0x2d3c6ff - <unknown>
  33:           0xe46423 - <unknown>
  34:     0x7f64f0427cd0 - <unknown>
  35:     0x7f64f0427d8a - __libc_start_main
  36:           0xe777ae - <unknown>
  37:                0x0 - <unknown>
fatal runtime error: failed to initiate panic, error 5

Weird ASCII thing related to [#godot_api] decorator at line 106 (right before Dense impl)

At first thought it was due to my godot_panic macro for some reason but no.

Here's my setup:

  • rustc 1.71.0 (8ede3aae2 2023-07-12)
  • godot 4.1.1.stable
  • arch linux (btw)

Called cargo uptade didn't changed a thing after recompiling

And finally here is my godot code calling the thing, its just and empty Node2D scene

extends Node2D


# Called when the node enters the scene tree for the first time.
func _ready():
	var l = Dense.new()
	l.init(2, 3)
	print(l.think([[1.1, 2.1],[1.1, 2.1]]))
	print("JAAJ")
	


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass
@Bromeon
Copy link
Member

Bromeon commented Aug 18, 2023

Hello 🙂 I disabled this check on another WIP branch, since I ran into the same problem, but I didn't have time to investigate the details around it yet.

Could you reduce your source code to a Minimal reproducible example? Without external dependencies and anything unrelated to the problem.

That would help me find out what exactly causes this, or when non-ASCII symbols are involved.

@Bromeon Bromeon added bug c: core Core components labels Aug 18, 2023
@GaspardCulis
Copy link
Author

GaspardCulis commented Aug 18, 2023

Figured it out here is my minimal example:

use godot::prelude::*;

#[derive(Debug, GodotClass)]
#[class(base=Resource)]
struct Dense {}

#[godot_api]
impl ResourceVirtual for Dense {
    fn init(_: Base<Resource>) -> Self {
        Self {}
    }
}

#[godot_api]
impl Dense {
    #[func]
    fn think(&self) {
        panic!("😀")
    }
}

struct Godumb;

#[gdextension]
unsafe impl ExtensionLibrary for Godumb {}

Thing is my dot product paniqued bcz I don't know ho to do matrix multiplication (wrong shapes) and the panic message of the dot call contained non ascii characters that godot couldn't handle or some stuff.

@Bromeon
Copy link
Member

Bromeon commented Aug 19, 2023

Oh, it's that simple! Thanks a lot for reproducing it! 👍

IIRC I added the check because Godot was unable to print some characters, but it's probably still better than a panic. Will have another look at this...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug c: core Core components
Projects
None yet
Development

No branches or pull requests

2 participants