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

Refactor nvbench helper less_t #2905

Merged
merged 1 commit into from
Nov 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 39 additions & 40 deletions cub/benchmarks/nvbench_helper/nvbench_helper/nvbench_helper.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -418,52 +418,51 @@ struct less_t
{
return lhs < rhs;
}
};

template <>
__host__ __device__ inline bool less_t::operator()(const complex& lhs, const complex& rhs) const
{
double magnitude_0 = cuda::std::abs(lhs);
double magnitude_1 = cuda::std::abs(rhs);

if (cuda::std::isnan(magnitude_0) || cuda::std::isnan(magnitude_1))
{
// NaN's are always equal.
return false;
}
else if (cuda::std::isinf(magnitude_0) || cuda::std::isinf(magnitude_1))
__host__ __device__ inline bool operator()(const complex& lhs, const complex& rhs) const
{
// If the real or imaginary part of the complex number has a very large value
// (close to the maximum representable value for a double), it is possible that
// the magnitude computation can result in positive infinity:
// ```cpp
// const double large_number = std::numeric_limits<double>::max() / 2;
// std::complex<double> z(large_number, large_number);
// std::abs(z) == inf;
// ```
// Dividing both components by a constant before computing the magnitude prevents overflow.
const complex::value_type scaler = 0.5;

magnitude_0 = cuda::std::abs(lhs * scaler);
magnitude_1 = cuda::std::abs(rhs * scaler);
}
double magnitude_0 = cuda::std::abs(lhs);
double magnitude_1 = cuda::std::abs(rhs);

if (cuda::std::isnan(magnitude_0) || cuda::std::isnan(magnitude_1))
{
// NaN's are always equal.
return false;
}
else if (cuda::std::isinf(magnitude_0) || cuda::std::isinf(magnitude_1))
{
// If the real or imaginary part of the complex number has a very large value
// (close to the maximum representable value for a double), it is possible that
// the magnitude computation can result in positive infinity:
// ```cpp
// const double large_number = std::numeric_limits<double>::max() / 2;
// std::complex<double> z(large_number, large_number);
// std::abs(z) == inf;
// ```
// Dividing both components by a constant before computing the magnitude prevents overflow.
const complex::value_type scaler = 0.5;

magnitude_0 = cuda::std::abs(lhs * scaler);
magnitude_1 = cuda::std::abs(rhs * scaler);
}

const complex::value_type difference = cuda::std::abs(magnitude_0 - magnitude_1);
const complex::value_type threshold = cuda::std::numeric_limits<complex::value_type>::epsilon() * 2;
const complex::value_type difference = cuda::std::abs(magnitude_0 - magnitude_1);
const complex::value_type threshold = cuda::std::numeric_limits<complex::value_type>::epsilon() * 2;

if (difference < threshold)
{
// Triangles with the same magnitude are sorted by their phase angle.
const complex::value_type phase_angle_0 = cuda::std::arg(lhs);
const complex::value_type phase_angle_1 = cuda::std::arg(rhs);
if (difference < threshold)
{
// Triangles with the same magnitude are sorted by their phase angle.
const complex::value_type phase_angle_0 = cuda::std::arg(lhs);
const complex::value_type phase_angle_1 = cuda::std::arg(rhs);

return phase_angle_0 < phase_angle_1;
}
else
{
return magnitude_0 < magnitude_1;
return phase_angle_0 < phase_angle_1;
}
else
{
return magnitude_0 < magnitude_1;
}
}
}
};

struct max_t
{
Expand Down
Loading