Code Monkey home page Code Monkey logo

Comments (17)

nickodell avatar nickodell commented on May 27, 2024 1

Fix confirmed.

$ ./ao/test/ao-test ao_tree_eval_f 
===============================================================================
All tests passed (3 assertions in 1 test case)

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

Interesting, I can't reproduce this on my system:

screen shot 2017-10-10 at 8 19 43 am

Do any of the unit tests fail (running ./ao/test/ao-test in the build directory)?

from libfive.

nickodell avatar nickodell commented on May 27, 2024

Update to the reproduction steps: It seems to happen whenever I remove one of the variables. Entirely deleting the x clause also triggers it.

The tests never finish or produce any output. Running ao-test under gdb, I see a segmentation fault.

Program received signal SIGSEGV, Segmentation fault.
_int_malloc (av=av@entry=0x7ffff66edb00 <main_arena>, bytes=bytes@entry=27680)
    at malloc.c:3840
3840	malloc.c: No such file or directory.
(gdb) bt
#0  _int_malloc (av=av@entry=0x7ffff66edb00 <main_arena>, 
    bytes=bytes@entry=27680) at malloc.c:3840
#1  0x00007ffff63cef34 in __GI___libc_malloc (bytes=27680) at malloc.c:2928
#2  0x00007ffff7957694 in Eigen::internal::handmade_aligned_malloc (size=27648)
    at /usr/include/eigen3/Eigen/src/Core/util/Memory.h:88
#3  Eigen::internal::aligned_malloc (size=27648)
    at /usr/include/eigen3/Eigen/src/Core/util/Memory.h:164
#4  Eigen::internal::conditional_aligned_malloc<true> (size=27648)
    at /usr/include/eigen3/Eigen/src/Core/util/Memory.h:214
#5  Eigen::internal::conditional_aligned_new_auto<Eigen::Array<float, 3, 256, 0, 3, 256>, true> (size=<optimized out>)
    at /usr/include/eigen3/Eigen/src/Core/util/Memory.h:374
#6  Eigen::DenseStorage<Eigen::Array<float, 3, 256, 0, 3, 256>, -1, -1, 1, 0>::resize (rows=9, size=9, this=0x7fffffffb340)
    at /usr/include/eigen3/Eigen/src/Core/DenseStorage.h:550
#7  Eigen::PlainObjectBase<Eigen::Array<Eigen::Array<float, 3, 256, 0, 3, 256>, -1, 1, 0, -1, 1> >::resize (cols=1, rows=9, this=0x7fffffffb340)
    at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:293
#8  Eigen::PlainObjectBase<Eigen::Array<Eigen::Array<float, 3, 256, 0, 3, 256>, -1, 1, 0, -1, 1> >::_init2<unsigned long, int> (cols=1, rows=9, 
    this=0x7fffffffb340)
    at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:739
#9  Eigen::Array<Eigen::Array<float, 3, 256, 0, 3, 256>, -1, 1, 0, -1, 1>::Array---Type <return> to continue, or q <return> to quit---
<unsigned long, int> (val1=<optimized out>, val0=<optimized out>, 
    this=0x7fffffffb340) at /usr/include/eigen3/Eigen/src/Core/Array.h:181
#10 Kernel::DerivArrayEvaluator::DerivArrayEvaluator (this=0x7fffffffb200, 
    t=..., vars=...) at /home/nick/ao/ao/src/eval/eval_deriv_array.cpp:31
#11 0x00007ffff797a69b in Kernel::XTreeEvaluator::XTreeEvaluator (
    this=0x7fffffffb1e0, t=..., vars=std::map with 0 elements)
    at /home/nick/ao/ao/src/../include/ao/render/brep/eval_xtree.hpp:36
#12 0x00007ffff7989c93 in Kernel::XTree<2u>::build (t=..., 
    vars=std::map with 0 elements, region=..., 
    min_feature=0.10000000149011612, max_err=1e-08, 
    multithread=<optimized out>, cancel=...)
    at /home/nick/ao/ao/src/render/brep/xtree.cpp:63
#13 0x00007ffff798a94f in Kernel::XTree<2u>::build (t=..., region=..., 
    min_feature=<optimized out>, max_err=max_err@entry=1e-08, 
    multithread=multithread@entry=true)
    at /home/nick/ao/ao/src/render/brep/xtree.cpp:47
#14 0x00007ffff799358a in Kernel::Contours::render (t=..., r=..., 
    min_feature=<optimized out>)
    at /home/nick/ao/ao/src/render/brep/contours.cpp:80
#15 0x00007ffff79ba0e2 in ao_tree_render_slice (
    tree=tree@entry=0x5555558cc360, R=..., z=z@entry=0, res=res@entry=10)
    at /home/nick/ao/ao/src/ao.cpp:176
#16 0x00005555555b16b1 in ____C_A_T_C_H____T_E_S_T____66 ()
---Type <return> to continue, or q <return> to quit---
    at /home/nick/ao/ao/test/api.cpp:76
#17 0x00005555555adcf9 in Catch::RunContext::invokeActiveTestCase (
    this=0x7fffffffd2d0) at /home/nick/ao/ao/test/catch.hpp:5473
#18 Catch::RunContext::runCurrentTest (redirectedCerr="", redirectedCout="", 
    this=0x7fffffffd2d0) at /home/nick/ao/ao/test/catch.hpp:5445
#19 Catch::RunContext::runTest (testCase=..., this=0x7fffffffd2d0)
    at /home/nick/ao/ao/test/catch.hpp:5284
#20 Catch::Runner::runTests (this=0x7fffffffd9f0)
    at /home/nick/ao/ao/test/catch.hpp:5603
#21 0x00005555555ae664 in Catch::Session::run (this=<optimized out>)
    at /home/nick/ao/ao/test/catch.hpp:5734
#22 0x000055555557eaa7 in Catch::Session::run (argv=0x7fffffffdf98, argc=1, 
    this=0x7fffffffdd40) at /home/nick/ao/ao/test/catch.hpp:5714
#23 main (argc=1, argv=0x7fffffffdf98) at /home/nick/ao/ao/test/main.cpp:24

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

I think this is ye olde aligned new operator issue on Linux. Can you see whether 488bf4c fixes either the unit tests or the crashes?

from libfive.

nickodell avatar nickodell commented on May 27, 2024

No, it doesn't fix either. On ao-test, there's a nearly identical stack trace and segfault.

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

One more thing to try: switch the compile mode from RELEASE to DEBUG in the top-level CMakeLists.txt, rebuild, and re-run that unit test (looks like it's ./ao/test/ao-test ao_tree_render_slice). In debug builds, more Eigen assertions are enabled, so it will tell us if we're doing something wrong with the matrices.

from libfive.

nickodell avatar nickodell commented on May 27, 2024

Got it. Here's the output of ao-test:

ao-test: /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:425: Eigen::DenseCoeffsBase<Derived, 1>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(Eigen::Index) [with Derived = Eigen::Array<float, -1, 1>; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = float; Eigen::Index = long int]: Assertion `index >= 0 && index < size()' failed.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ao-test is a Catch v1.1 b3 host application.
Run with -? for options

-------------------------------------------------------------------------------
ao_tree_eval_f
-------------------------------------------------------------------------------
/home/nick/ao/ao/test/api.cpp:51
...............................................................................

/home/nick/ao/ao/test/api.cpp:51: FAILED:
due to a fatal error condition:
  SIGABRT - Abort (abnormal termination) signal

===============================================================================
test cases: 3 | 2 passed | 1 failed
assertions: 8 | 7 passed | 1 failed

Looks like index-out-of-bounds.

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

Awesome! That's still a little vague – can you run it in a debugger to get the abort's backtrace, so we can see what part of the kernel is misbehaving?

from libfive.

nickodell avatar nickodell commented on May 27, 2024

Sure:

$ gdb -x cmd ./ao/test/ao-test
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./ao/test/ao-test...done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ao-test: /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:425: Eigen::DenseCoeffsBase<Derived, 1>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(Eigen::Index) [with Derived = Eigen::Array<float, -1, 1>; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = float; Eigen::Index = long int]: Assertion `index >= 0 && index < size()' failed.

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff563d3fa in __GI_abort () at abort.c:89
#2  0x00007ffff5634e37 in __assert_fail_base (fmt=<optimized out>, 
    assertion=assertion@entry=0x7ffff77abdf5 "index >= 0 && index < size()", 
    file=file@entry=0x7ffff77abdc0 "/usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h", line=line@entry=425, 
    function=function@entry=0x7ffff77ac7c0 <Eigen::DenseCoeffsBase<Eigen::Array<float, -1, 1, 0, -1, 1>, 1>::operator()(long)::__PRETTY_FUNCTION__> "Eigen::DenseCoeffsBase<Derived, 1>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(Eigen::Index) [with Derived = Eigen::Array<float, -1, 1>; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = float;"...) at assert.c:92
#3  0x00007ffff5634ee2 in __GI___assert_fail (
    assertion=0x7ffff77abdf5 "index >= 0 && index < size()", 
    file=0x7ffff77abdc0 "/usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h", line=425, 
    function=0x7ffff77ac7c0 <Eigen::DenseCoeffsBase<Eigen::Array<float, -1, 1, 0, -1, 1>, 1>::operator()(long)::__PRETTY_FUNCTION__> "Eigen::DenseCoeffsBase<Derived, 1>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(Eigen::Index) [with Derived = Eigen::Array<float, -1, 1>; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = float;"...) at assert.c:101
#4  0x00007ffff75ad99c in Eigen::DenseCoeffsBase<Eigen::Array<float, -1, 1, 0, -1, 1>, 1>::operator() (this=0x7fffffffc4e0, index=5)
    at /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:425
#5  0x00007ffff761be14 in Kernel::PointEvaluator::eval (this=0x7fffffffc4d0, 
    pt=...) at /home/nick/ao/ao/src/eval/eval_point.cpp:51
#6  0x00007ffff77a9913 in ao_tree_eval_f (t=0x555555adce20, p=...)
    at /home/nick/ao/ao/src/ao.cpp:161
#7  0x0000555555760faf in ____C_A_T_C_H____T_E_S_T____51 ()
    at /home/nick/ao/ao/test/api.cpp:57
#8  0x000055555572ff58 in Catch::FreeFunctionTestCase::invoke (
    this=0x555555acea40) at /home/nick/ao/ao/test/catch.hpp:5874
#9  0x000055555571cae3 in Catch::TestCase::invoke (this=0x555555afaf10)
    at /home/nick/ao/ao/test/catch.hpp:6779
#10 0x000055555572e007 in Catch::RunContext::invokeActiveTestCase (
    this=0x7fffffffd630) at /home/nick/ao/ao/test/catch.hpp:5473
#11 0x000055555572dce5 in Catch::RunContext::runCurrentTest (
    this=0x7fffffffd630, redirectedCout="", redirectedCerr="")
    at /home/nick/ao/ao/test/catch.hpp:5445
#12 0x000055555572c6e9 in Catch::RunContext::runTest (this=0x7fffffffd630, 
    testCase=...) at /home/nick/ao/ao/test/catch.hpp:5284
#13 0x000055555572e6e8 in Catch::Runner::runTests (this=0x7fffffffda50)
    at /home/nick/ao/ao/test/catch.hpp:5603
#14 0x000055555572f6bd in Catch::Session::run (this=0x7fffffffdd50)
    at /home/nick/ao/ao/test/catch.hpp:5734
#15 0x000055555572f572 in Catch::Session::run (this=0x7fffffffdd50, argc=1, 
    argv=0x7fffffffdf98) at /home/nick/ao/ao/test/catch.hpp:5714
#16 0x0000555555721745 in main (argc=1, argv=0x7fffffffdf98)
    at /home/nick/ao/ao/test/main.cpp:24
Kill the program being debugged? (y or n) [answered Y; input not from terminal]

from libfive.

nickodell avatar nickodell commented on May 27, 2024

PS: I wrote a guide to building this on debian. https://gist.github.com/nickodell/46180d736a7c2cb6836291a8f168ef20

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

Thanks for the Debian guide!

I'm pretty mystified by the bug you're seeing. Let me explain why, to help you debug on your end:

The failing test for ao_tree_eval_f builds a tree representing f(x, y) = x / y. It then converts this into a tape, which is a flattened 1D structure that can be walked to evaluate the tree. The tape will include clauses for x, y, x / y, and z (because we always create slots for the base variables, even if they're unused). It also includes the null clause, with index 0.

The tape also has an associated array of results, which should have room for 5 values (null, x, y, x/y, and z). When I instrument the tape constructor with debug print statements, it tells me that X is at slot 3, Y is at slot 2, and Z is at slot 4. In your system, the index of the z clause into the result array is being recorded as 5 instead of 4; you can see this in items #5 and #4 of your traceback.

Can you drop a debug print statement at the end of the Tape constructor, e.g.

    std::cout << "Got " << num_clauses << " clauses with\n"
              << "X = " << X << "\n"
              << "Y = " << Y << "\n"
              << "Z = " << Z << "\n";

then rerun the failing unit test (./ao/test/ao-test ao_tree_eval_f)?

If my explanation helped clarify the underlying logic, feel free to debug more independently on your end as well 😃

from libfive.

nickodell avatar nickodell commented on May 27, 2024

Reading the logic in Tape's constructor, it looks like it's functioning as intended.

    // Make sure that X, Y, Z have been allocated space
    std::vector<Tree> axes = {Tree::X(), Tree::Y(), Tree::Z()};
    for (auto a : axes)
    {
        if (clauses.find(a.id()) == clauses.end())
        {
            std::cout << "can't find " << a;
            clauses[a.id()] = clauses.size();
        }
    }

The cout here says "can't find z" That's not surprising, because z isn't in the expression. This propagates through and sets Z to 5, the size of the vector. If we change the testcase to involve z, then z is in clauses, and there's no crash.

This testcase works:

TEST_CASE("ao_tree_eval_f")
{
    auto a = ao_tree_x();
    auto b = ao_tree_y();
    auto d = ao_tree_z();
    auto c = ao_tree_binary(Opcode::DIV, a, b);
    auto e = ao_tree_binary(Opcode::ADD, c, d);

    REQUIRE(ao_tree_eval_f(e, {1,2,3}) == 3.5);
    REQUIRE(ao_tree_eval_f(e, {1,4,3}) == 3.25);
    REQUIRE(ao_tree_eval_f(e, {1,-1,3}) == 2);

    ao_tree_delete(a);
    ao_tree_delete(b);
    ao_tree_delete(c);
}

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

The cout here says "can't find z" That's not surprising, because z isn't in the expression. This propagates through and sets Z to 5, the size of the vector.

This is where things are misbehaving: Z should be set to 4, because there's only three clauses at that point (x, y, and x / y), plus the null clause, so clause.size() should be 4.

Can you sprinkle a few more print statements around to try and figure out why Z is set to 5 rather than 4? Adding a print statement to the newClause lambda function may be informative.

from libfive.

nickodell avatar nickodell commented on May 27, 2024

Can you sanity check something for me?

Run this on your system. It prints 1 for me.

#include <iostream>
#include <unordered_map>
using namespace std;

int main() {
	std::unordered_map<int, int> u;
	u[0] = u.size();
	cout << u[0] << endl;
	return 0;
}

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

Good catch, that prints 0 for me. It's probably related to how operator[] works on maps, where it adds the slot before checking the size on your system but not mine.

Can you see if 2b71b9a fixes the problem?

from libfive.

mkeeter avatar mkeeter commented on May 27, 2024

Cool, thanks for your help in debugging! I assume this also fixes the original meshing crash?

from libfive.

nickodell avatar nickodell commented on May 27, 2024

Yes, it does.

from libfive.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.