-
Notifications
You must be signed in to change notification settings - Fork 139
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
HSPotential Helper replace ifdefs with const expr templates #4623
HSPotential Helper replace ifdefs with const expr templates #4623
Conversation
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.
LGTM
Will need a non-ORNL merge.
We should talk if there is anything tricky under AFQMC given our focus on the real space code.
Note: we are at the mercy of the AFMC test coverage here. Recommend you have |
src/AFQMC/config.0.h
Outdated
template <class T> | ||
struct is_complex : std::false_type {}; | ||
template <> | ||
struct is_complex<ComplexType> : std::true_type {}; | ||
template <> | ||
struct is_complex<SPComplexType> : std::true_type {}; | ||
|
||
{}; |
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.
template <class T> | |
struct is_complex : std::false_type {}; | |
template <> | |
struct is_complex<ComplexType> : std::true_type {}; | |
template <> | |
struct is_complex<SPComplexType> : std::true_type {}; | |
{}; | |
template <class T> | |
struct is_complex : std::false_type {}; | |
template <class T> | |
struct is_complex<std::complex<T>> : std::true_type {}; | |
template< class T> | |
inline constexpr bool is_complex_v = is_complex<T>::value; |
#if defined(QMC_COMPLEX) | ||
count[2 * (*cik) + 1] += size_t(2); // Lik - 0 | ||
#endif | ||
if constexpr (is_complex<T>::value) |
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.
if constexpr (is_complex<T>::value) | |
if constexpr (is_complex_v<T>) |
Requires the helper function I suggested adding in config.0.h
@@ -35,7 +35,7 @@ namespace | |||
{ | |||
//inline double const& ma::conj(double const& d){return d;} | |||
//inline float const& ma::conj(float const& f){return f;} | |||
|
|||
template<class T> |
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.
Since these functions are in the implementation file we need to explicitly instantiate them.
William's branch has a couple macros to make this easier.
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 feel the template parameter should be bool instead of T. Then the explicit instantiation only needs true and false two times.
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.
If we go that route, make it an enum or enum class. Names would be clearer than true
and false
and if in the future we want to add more template options (mixed precision?) there is less to change.
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.
Good point @quantumsteve . We will want to add mixed precision support in future to do away with QMC_MIXED_PRECISION. If we can pick a pattern that make both r/c and sp/dp combinations simpler to support, we should.
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.
There's another problem here. Something that was overlooked here is that the type of the SpVType_shm_csr_matrix
function parameter for these functions would need to become a template parameter since it is dependent on the SPValueType
. Following that we could use the CSR_matrix_type::value_type
to determine if we're dealing with complex or not.
To Ye's suggestion then, we would still need to make explicit instantiations for just the two sp value types (where the rest of the specialization of csr_matrix
remains the same: int, std::size_t, shared_allocator
).
* update is_complex template tree to look for generic complex * ask for is_complex_v instead of is_complex::value * macro instantiate template functions to help avoid linking errors
ebc93c0
to
4fdd6d2
Compare
QMC_FOREACH_REAL_TYPE(MACRO) \ | ||
QMC_FOREACH_COMPLEX_TYPE(MACRO) |
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 may want to pick one the other based on QMC_COMPLEX
.
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.
if we're going for a unified build, shouldnt both be available?
@@ -23,15 +23,17 @@ namespace afqmc | |||
{ | |||
namespace HamHelper | |||
{ | |||
template<class T> |
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 making template<bool IS_COMPLEX>
reduce the complexity of explicit template instantiation cases.
src/AFQMC/config.0.h
Outdated
template <class T> | ||
struct is_complex : std::false_type {}; | ||
|
||
template <class T> | ||
struct is_complex<std::complex<T>> : std::true_type {}; |
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.
is_complex is already in the codebase
qmcpack/src/type_traits/complex_help.hpp
Line 17 in 2db0b25
template<typename T> |
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.
Naming convention is also wrong here.
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 this can be made a bit simpler and more readable by reexamining the typealias choices made in config.h.
csr_matrix lacks meaningful documentation but pretty clearly is primarily templated on a VALUE type
src/AFQMC/config.0.h
Outdated
template <class T> | ||
struct is_complex : std::false_type {}; | ||
|
||
template <class T> | ||
struct is_complex<std::complex<T>> : std::true_type {}; |
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.
Naming convention is also wrong here.
std::vector<std::size_t> count_nnz_per_cholvec(double cut, TaskGroup_& TG, SpVType_shm_csr_matrix& V2, int NMO); | ||
|
||
template<class T> |
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.
in config.h
replace
using SpCType_shm_csr_matrix =
ma::sparse::csr_matrix<SPComplexType, int, std::size_t, shared_allocator<SPComplexType>, ma::sparse::is_root>;
using SpVType_shm_csr_matrix =
ma::sparse::csr_matrix<SPValueType, int, std::size_t, shared_allocator<SPValueType>, ma::sparse::is_root>;
using CType_shm_csr_matrix =
ma::sparse::csr_matrix<ComplexType, int, std::size_t, shared_allocator<ComplexType>, ma::sparse::is_root>;
using VType_shm_csr_matrix =
ma::sparse::csr_matrix<ValueType, int, std::size_t, shared_allocator<ValueType>, ma::sparse::is_root>;
with
template<typename T>
using CSRMtrxShared<T> = ma::sparse::csr_matrix<SPComplexType, int, std::size_t, shared_allocator<SPComplexType>, ma::sparse::is_root>;
In most cases this will just read
CSRMatrixShared<Value>
or CSRMatrixShared<Complex>
which is much easier to read quickly and surfaces the important parameter for both read and specializing code.
then one can write
template<typename T>
...(...
CSRMatrix<T> WorthlessTwoLetterVariableName,
...)
{
....
if constexpr (IsComplex_t<T>::value) {
...
}
...
}
assert(map_[2 * (*ci) + 1] >= 0); | ||
assert(map_[2 * (*ci) + 1] - c_origin < vn.size(1)); | ||
vn.emplace_back({ik, (map_[2 * (*ci) + 1] - c_origin)}, | ||
static_cast<SPValueType>(half * im * (*vi - ma::conj(*vi)))); // Lii - Lii* |
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 should be static_cast<decltype(vn)::value_type>
* use existing is_complex evaluators * add templated CSR Matrix * extend IsComplex evaluators with valued version
Please review the developer documentation
on the wiki of this project that contains help and requirements.
Proposed changes
This is a refactor of
HSPotential_Helpers.cpp
andHSPotential_Helpers.h
in accordance with this gist https://gist.github.com/williamfgc/28ffbd23f6888ed89530e3f68c992c93#refactoring-strategyIt removes the QMC_COMPLEX ifdefs and replaces them with templates and const expr as to generate complex/real versions in one compile.
Describe what this PR changes and why. If it closes an issue, link to it here
with a supported keyword.
What type(s) of changes does this code introduce?
Delete the items that do not apply
Does this introduce a breaking change?
What systems has this change been tested on?
Checklist
Update the following with a yes where the items apply. If you're unsure about any of them, don't hesitate to ask. This is
simply a reminder of what we are going to look for before merging your code.