Skip to content

Conversation

@gunney1
Copy link
Contributor

@gunney1 gunney1 commented Jan 2, 2026

Summary

  • This PR is a refactoring
  • It does the following:
    • Refactor and generalize the mesh clipper's statistics collection, reduction and logging code.

Statistics are stored in the key-value pairs of a conduit::Node. New quantities can be added without modifying the mesh clipper implementation. The mesh clipper can just add, globally reduce and log statistics without having to know what quantities they are.

The screen level parameter is also added. It's a run-time parameter for studying how effective screening is. It's integrated with statistics so it's included on this branch.

This change is part of the clipping performance work and has been separated to make smaller change sets. Some of the statistics code introduced here may seem unused, but they will be used in up-coming PRs.

Counter statistics are now placed in a conduit::Node
so new statistics can be added without modifying the
mesh clipper implementation.  The mesh clipper can just
add and globally reduce and log statistics without
having to know what quantities they are.

The screen level parameter is also added.  It's a run-time
parameter for studying how effective screening is.  It's
integrated with statistics so it's included on this branch.
@gunney1 gunney1 self-assigned this Jan 2, 2026
@gunney1 gunney1 added the Quest Issues related to Axom's 'quest' component label Jan 2, 2026
Base automatically changed from feature/gunney/18-tets-per-hex to develop January 6, 2026 18:07
Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a useful feature @gunney1

Please check that this doesn't have a performance overhead in cases where you don't want/need to collect statistics.

Comment on lines 218 to 251
* @param [in] shapeMesh Blueprint mesh to shape into.
* @param [out] ovlap Shape overlap volume of each cell
* in the \c shapeMesh. It's initialized to zeros.
* @param [out] statistics Optional statistics to record
* consisting of child nodes with integer values.
*
* The default implementation has no specialized method,
* so it's a no-op and returns false.
*
* If this method returns false, then exactly one of the
* @c getShapesAs...() methods must be provided.
*
* @return True if clipping was done and false if a no-op.
*
* This method need not be implemented if labelCellsInOut()
* returns true.
*
* Setting the statistics is not required except for getting
* accurate statistics.
*
* If implementation returns true, it should ensure these
* post-conditions hold:
* @post ovlap.size() == shapeMesh.getCellCount()
* @post ovlap.getAllocatorID() == shapeMesh.getAllocatorId()
*/
virtual bool specializedClipCells(quest::experimental::ShapeMesh& shapeMesh,
axom::ArrayView<double> ovlap)
axom::ArrayView<double> ovlap,
conduit::Node& statistics)
{
AXOM_UNUSED_VAR(shapeMesh);
AXOM_UNUSED_VAR(ovlap);
AXOM_UNUSED_VAR(statistics);
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • @param [out] statistics Optional statistics to record
    consisting of child nodes with integer values.

Since statistics is given by reference, rather than a pointer which could be nullptr (or perhaps a std::optional), it looks like it is required, rather than optional.

Is there a performance cost to passing in the statistics? E.g. if the statistics are written to the conduit node within an inner loop, and then ignored.

Copy link
Contributor Author

@gunney1 gunney1 Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't access the Node in inner loops. That doesn't work anyway when the inner loop is a GPU kernel. A typical use is to use a RAJA sum object in the inner loop then get the value after the loop. I have not seen any significant cost to computing statistics this way.

Comment on lines 87 to 93
/*!
* @brief Log clipping statistics.
* Intended for developer use.
*
* This is a collective method if MPI-parallel.
*/
void logClippingStats(bool local = false, bool sum = true, bool max = false) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document these three parameters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 109 to 113
/*!
* @brief Set the level of screening,
* intended for developer use.
*/
void setScreenLevel(int screenLevel) { m_screenLevel = screenLevel; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the valid levels and their meanings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines +101 to +107
/*!
* @brief Get global assorted clipping statistics,
* intended for developer use.
*
* This is a collective method if MPI-parallel.
*/
conduit::Node getGlobalClippingStats() const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gut-check: Is this supposed to return by value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The global clipping stats are not stored internally.

}

m_impl->collectOnIndices(tetLabels.view(), tetsOnBdry);
m_impl->remapTetIndices(cellsOnBdry, tetsOnBdry);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gut check: Was this change intentional? Or perhaps a bug fix? I don't see an API change in this PR for Impl::remapTetIndices()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It fixes an error I made when I split up the huge PR into smaller ones. I didn't catch the error immediately because this code wasn't exercised until the PRs I submitted later. So this is a correction to a code that wasn't being exercised, but I thought it made sense to keep the correction as close as possible to the place where the error was made. In the original huge PR, it was correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Quest Issues related to Axom's 'quest' component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants