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

Add functionality to print hashes and computed errors in tests #778

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from

Conversation

jmachado-amd
Copy link
Collaborator

rocSOLVER's tests currently output no useful information for passing tests, which makes it hard to ascertain when new code adversely affects the accuracy of methods while also hindering the investigation of bugs that may affect determinism.

This PR adds code to print the computed error in each test and hashing functions to allow printing hashes of input and output matrices, when desired.

rocSOLVER's tests currently output no useful information for passing
tests, which makes it hard to ascertain when new code adversely affects
the accuracy of methods while also hindering the investigation of bugs
that may affect determinism.

This commit adds code to print the computed error in each test and
hashing functions to allow printing hashes of input and output matrices,
when desired.
@jmachado-amd jmachado-amd added the noOptimizations Disable optimized kernels for small sizes for some routines label Aug 2, 2024
Copy link
Contributor

@EdDAzevedo EdDAzevedo left a comment

Choose a reason for hiding this comment

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

The std::hash may be implementation dependent. One may consider another hash function such as the following (found using edge browser) to make this more portable across OS and compiler versions. Just a suggestion.

unsigned hash(const char* s, unsigned salt) {
    unsigned h = salt;
    while (*s)
        h = h * 101 + static_cast<unsigned>(*s++);
    return h;
}

Copy link
Collaborator

@cgmb cgmb left a comment

Choose a reason for hiding this comment

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

I would like to be able to control this behaviour at runtime. Could we control this with an environment variable, rather than a preprocessor flag?

Comment on lines +57 to +58
#define ANSI_CODE_GTEST_GREEN "\033[0;32m"
#define ANSI_CODE_NORMAL_TERM "\033[0;0m"
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we're going to print with colour, we should follow Google Test's lead by obeying the gtest_color option and using TTY detection for the default. I'd suggest printing without colour for now, as that is a bit of a distraction from the main purpose of this change.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, the fmtlib that we use in rocsolver has a color API. https://fmt.dev/11.0/api/#color-api

#define ANSI_CODE_NORMAL_TERM "\033[0;0m"
// Macro ROCSOLVER_GTEST_MSG_PRINTER is also used to print hashes in tests
#define ROCSOLVER_GTEST_MSG_PRINTER \
std::cout << ANSI_CODE_GTEST_GREEN << "[ ] " << ANSI_CODE_NORMAL_TERM
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use fmt. We added it as a dependency to do atomic prints and avoid the iostreams interfaces where the printing of a line may be split into multiple function calls. It's not that important at the moment, but it's an invariant we inherited from rocfft / rocblas and I want to retain it in case we do ever run tests in parallel.

Comment on lines +73 to +79
ROCSOLVER_GTEST_MSG_PRINTER \
<< "Computed error: " << ROCSOLVER_STRNGFY(max_error) << " / " \
<< ROCSOLVER_STRNGFY(((tol)*get_epsilon<T>())) << " = " \
<< std::setprecision(max_precision) \
<< ((max_error_ >= 0.) && (tol_ > 0.) ? max_error_ / tol_ : -1.) \
<< std::setprecision(default_precision) << std::endl \
<< std::flush; \
Copy link
Collaborator

Choose a reason for hiding this comment

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

This would be so much nicer using the fmtlib interface.

@@ -263,6 +263,8 @@ void sygvx_hegvx_initData(const rocblas_handle handle,
// for testing purposes, we start with a reduced matrix M for the standard equivalent problem
// with spectrum in a desired range (-20, 20). Then we construct the generalized pair
// (A, B) from there.

[[maybe_unused]] volatile auto mptr = memset(hB[b], 0, n * ldb * sizeof(T));
Copy link
Collaborator

Choose a reason for hiding this comment

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

I assume the volatile auto mptr is an attempt to ensure that memset is not optimized out, but I'm not sure that's guaranteed. Why is this needed?

ROCSOLVER_GTEST_MSG_PRINTER << "Input matrix hash: " << input_hash << std::endl << std::flush;
ROCSOLVER_GTEST_MSG_PRINTER << "Rocsolver eigenvalues hash: " << rocsolver_eigenvalues_hash
<< std::endl
<< std::flush;
Copy link
Collaborator

Choose a reason for hiding this comment

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

std::endl is defined as a newline and a flush, so this is redundant. Although, again, I would suggest using fmt rather than iostreams.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
noOptimizations Disable optimized kernels for small sizes for some routines
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants