-
Notifications
You must be signed in to change notification settings - Fork 120
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
Testing Framework for Hull #875
Conversation
I've tried my best to include only the relevant things from our experiments, if there's something I missed or something I should remove. I would gladly make the change. |
extras/test_hull_performace.cpp
Outdated
return; | ||
} | ||
|
||
void PrintManifold(Manifold input, Manifold (Manifold::*hull_func)() const) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should this take a manifold method? I think you can just make it take a generic function that returns a manifold given a set of points.
extras/test_hull_performace.cpp
Outdated
std::cout << elapsed.count() << " sec"; | ||
} | ||
|
||
void PrintCGAL(Manifold input, Manifold (Manifold::*hull_func)() const) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably don't need a separate CGAL one as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason, I kept it, is since we had discussed that we don't want to keep the other implementations in our code. CGAL, seemed like the simplest way to compare the outputs relatively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, we can just use the function for PrintManifold
? Just run CGAL hull in the hull_func
function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, since we don't need the Manfiold Method function, we can just use that. I will change that too. Now, that I think of it, that was a very redundant piece of code thanks for pointing it out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so, since we aren't storing the output of CGAL as a manifold, I am just computing the CGAL output, and then printing the outputs using the CGAL functions. I didn't want to convert the CGAL output back to manifold as that would add time overhead, so what should I do in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The simplest way would be to do the time measurement in the callback, or you can split the function into two, the actual hull operation as well as a postprocessing operation which returns a manifold, and you only measure the time in the actual hull operation.
class HullImpl {
public:
// actual hull operation, we will measure the time needed to evaluate this function.
virtual void hull(const std::vector<glm::vec3>& points);
// return the result of the hull operation, should be called after `hull`.
virtual manifold::Manifold result();
};
And just let the implementations inherit this class. (or if you use template, you don't need inheritance).
I think we also talked about checking if the convex hull result is a valid convex polyhedron? I think that is a pretty important thing to test for. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to bother with Draft PRs - our CI will only run on regular ones.
bindings/python/manifold3d.cpp
Outdated
@@ -107,7 +107,7 @@ struct nb::detail::type_caster<glm::mat<C, R, T, Q>> { | |||
static handle from_cpp(glm_type mat, rv_policy policy, | |||
cleanup_list *cleanup) noexcept { | |||
T *buffer = new T[R * C]; | |||
nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[] (T *)p; }); | |||
nb::capsule mem_mgr(buffer, [](void *p) noexcept { delete[](T *) p; }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is due to using the wrong version of clang-format. Make sure you've pulled master.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try it again, thanks for pointing it out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you guide me on how to fix this, I had used the latest commit from master on the main repository.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What clang-format version are you using? Use a newer one, e.g. 16.
extras/test_hull_performace.cpp
Outdated
if (!strcmp(argv[2], "Hull")) | ||
PrintManifold(inputManifold, &Manifold::Hull); | ||
else if (!strcmp(argv[2], "Hull_CGAL")) | ||
PrintCGAL(inputManifold, &Manifold::Hull); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you're always using Manifold::Hull()
- do we still need this input?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right, I forgot that we didn't need input of the hull function there, as we're using CGAL, I'll make that change, thanks for pointing it out. And the reason I am taking this input, is that we can run a comparison between various implementations (or for the bare minimum at least with CGAL).
extras/test_hull_performace.cpp
Outdated
// Constructs a high quality sphere, and tests the convex hull implementation on | ||
// it (you can pass the specific hull implementation to be tested). Comparing | ||
// the volume and surface area with CGAL implementation | ||
void SphereTestHull(Manifold (Manifold::*hull_func)() const, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We talked about how this one can test our precision by checking if the number of verts is the same between input and output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also printing the number of vertices of the original Manifold and the Hull in the output, I just forgot to mention that in the comment, I'll re-frame the comment. Also, do we want to add this test into hull_test.cpp
as well?
CMakeLists.txt
Outdated
@@ -46,6 +46,7 @@ endif() | |||
option(TRACY_ENABLE "Use tracy profiling" OFF) | |||
option(TRACY_MEMORY_USAGE "Track memory allocation with tracy (expensive)" OFF) | |||
option(BUILD_TEST_CGAL "Build CGAL performance comparisons" OFF) | |||
option(TEST_HULL_PERFORMANCE "Test Hulling Algorithm" OFF) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd rather build this under the TEST_CGAL
flag instead of adding another.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I will change that.
extras/test_hull_performace.cpp
Outdated
// (you can pass the specific hull implementation to be tested). Comparing the | ||
// volume and surface area with CGAL implementation, for various values of | ||
// rotation | ||
void MengerTestHull(Manifold (Manifold::*hull_func)() const, float rx, float ry, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for comparison to CGAL, but I'm actually more interested in adding to our own testing framework. Can you build tests like this directly into hull_test.cpp
for just Manifold's implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we just want to keep this testing script for the tests on datasets, and these single tests, I can shift to hull_test.cpp
?
I had created the check for this in the implementation of the algorithm itself, so that I could perform a check for each iteration while testing. While moving the implementation to our code, I am working on adding that function as well. |
I've made the changes as suggested, except adding the check for the valid convex hull, since I was debating whether we wanted that in the code with the implementation that we're moving to our library or in this testing framework, what's your opinion on it? |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #875 +/- ##
==========================================
- Coverage 91.84% 89.90% -1.94%
==========================================
Files 37 64 +27
Lines 4976 9216 +4240
Branches 0 960 +960
==========================================
+ Hits 4570 8286 +3716
- Misses 406 930 +524 ☔ View full report in Codecov by Sentry. |
Just ping me know when I should review it. |
I'm currently working on the reduced points cases that Emmett had suggested, but I'm having difficulties with it, I've added the check for valid convex hull. If you plan to start the refactoring of the code soon, I can commit this much for now. And we can add these failing cases later? |
No hurry, I just asked because I saw the conflicts are now resolved and tests seem to be passing. You can do it later. |
I think I'd like to land this PR before #881, since it's good to have regression tests in place for a big change like that. What troubles are you having with the other test cases? I would expect some to fail for now (you can mark them as e.g. |
I was having issues with the recreating the error, with the points values (not storing them in binary). I am working on that now, I hope to resolve it soon and I will add the tests as you suggested. I will focus on this PR then, considering what we had planned for #881 is pretty much finished |
I've added the test for the valid convex hull in Also, for checking if for any input file the output hull is valid or not, I'm using the MANIFOLD_DEBUG flag for now, should I change that in any way, and do you want that function to compile only when that flag is enabled? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good - let's just do these small updates and get it merged.
test/hull_test.cpp
Outdated
@@ -94,3 +94,54 @@ TEST(Hull, Sphere) { | |||
EXPECT_FLOAT_EQ(sphereHull.GetProperties().volume, | |||
sphere.GetProperties().volume); | |||
} | |||
|
|||
// TEST(Hull, FailingTest1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of commenting these tests, you can change them to TEST(Hull, DISABLED_FailingTest1)
- this way they get compiled, but just not run, and we get a warning to remind us.
test/hull_test.cpp
Outdated
// {-20.442623138f, -35.407661438f, 8.2749996185f}, | ||
// {10.229375839f, -14.717799187f, 10.508025169f}}; | ||
// auto hull = Manifold::Hull(hullPts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for these odd shapes I think testing IsConvex()
is the way to go.
I've made the suggested changes ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
@elalish and @pca006132, I've cleaned the code for the testing framework, keeping the tests of a High Quality Sphere, Menger Sponge and the script to run the code on the Thingi10K dataset, and then get the statistics for the implementations. I've attached instructions as to how to run the code in the comments. I would appreciate it if you could review the code once as well.
As for instructions:
To run the executable (run this in ./build directory)
Usage: ./test_hull_performance <Test (Sphere/Menger/Input)> <Implementation (Hull/Hull_CGAL)> <Print Header (1/0)> <Input Mesh (filename)>
Example: ./extras/testHullPerformace Menger Hull 1
The Input test allows the user to enter a custom file to run the implementation on. You can test our current implementation as well as CGAL implementation. The Print Header refers to printing the corresponding header for the csv file (it's mainly used by the script for the dataset, for single testing purposes just use 1 there)
To run the script for the dataset (run this is ./extras directory)
Usage : ./run.sh ../build/extras/testHullPerformance {path_to_dataset_folder} {name_of_csv} {implementation(Hull,Hull_CGAL)}
example : ./run.sh ../build/extras/testHullPerformance ./Thingi10K/raw_meshes/ Hull.csv Hull