Skip to content
Merged
Show file tree
Hide file tree
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
41 changes: 21 additions & 20 deletions src/integrals/libint/libint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,39 +26,37 @@
namespace integrals::libint {
namespace {

template<typename FloatType, unsigned int N>
template<typename FloatType>
auto build_eigen_buffer(const std::vector<libint2::BasisSet>& basis_sets,
double thresh) {
parallelzone::runtime::RuntimeView& rv, double thresh) {
FloatType initial_value;
if constexpr(std::is_same_v<FloatType, double>) {
initial_value = 0.0;
} else { // Presumably sigma::UDouble
initial_value = FloatType(0.0, thresh);
}
Eigen::array<Eigen::Index, N> dims_bfs;
for(decltype(N) i = 0; i < N; ++i) dims_bfs[i] = basis_sets[i].nbf();
auto N = basis_sets.size();
std::vector<decltype(N)> dims(N);
for(decltype(N) i = 0; i < N; ++i) dims[i] = basis_sets[i].nbf();

using shape_t = tensorwrapper::shape::Smooth;
using layout_t = tensorwrapper::layout::Physical;
using buffer_t = tensorwrapper::buffer::Eigen<FloatType, N>;
using data_t = typename buffer_t::data_type;

shape_t s{dims_bfs.begin(), dims_bfs.end()};
shape_t s{dims.begin(), dims.end()};
layout_t l(s);
data_t d(dims_bfs);
buffer_t b{d, l};
b.value().setConstant(initial_value);
return b;
tensorwrapper::allocator::Eigen<FloatType> alloc(rv);
return alloc.construct(l, initial_value);
}

template<typename FloatType, unsigned int N>
template<std::size_t N, typename FloatType>
auto fill_tensor(const std::vector<libint2::BasisSet>& basis_sets,
const chemist::qm_operator::OperatorBase& op, double thresh) {
const chemist::qm_operator::OperatorBase& op,
parallelzone::runtime::RuntimeView& rv, double thresh) {
// Dimensional information
std::vector<std::size_t> dims_shells(N);
for(decltype(N) i = 0; i < N; ++i) dims_shells[i] = basis_sets[i].size();

auto b = build_eigen_buffer<FloatType, N>(basis_sets, thresh);
auto pbuffer = build_eigen_buffer<FloatType>(basis_sets, rv, thresh);

// Make libint engine
LibintVisitor visitor(basis_sets, thresh);
Expand All @@ -77,7 +75,7 @@ auto fill_tensor(const std::vector<libint2::BasisSet>& basis_sets,
auto ord = detail_::shells2ord(basis_sets, shells);
auto n_ord = ord.size();
for(decltype(n_ord) i_ord = 0; i_ord < n_ord; ++i_ord) {
b.value().data()[ord[i_ord]] += vals[i_ord];
pbuffer->data()[ord[i_ord]] += vals[i_ord];
}
}

Expand All @@ -93,7 +91,8 @@ auto fill_tensor(const std::vector<libint2::BasisSet>& basis_sets,
}
}

return simde::type::tensor(b.layout().shape().clone(), b);
auto pshape = pbuffer->layout().shape().clone();
return simde::type::tensor(std::move(pshape), std::move(pbuffer));
}

} // namespace
Expand Down Expand Up @@ -122,6 +121,7 @@ TEMPLATED_MODULE_RUN(Libint, BraKetType) {
auto bra = braket.bra();
auto ket = braket.ket();
auto& op = braket.op();
auto& rv = this->get_runtime();

// Gather information from Bra, Ket, and Op
auto basis_sets = detail_::get_basis_sets(bra, ket);
Expand All @@ -130,16 +130,17 @@ TEMPLATED_MODULE_RUN(Libint, BraKetType) {
simde::type::tensor t;
if(with_uq) {
if constexpr(integrals::type::has_sigma()) {
t = fill_tensor<type::uncertain_double, N>(basis_sets, op, thresh);
t = fill_tensor<N, type::uncertain_double>(basis_sets, op, rv,
thresh);
} else {
throw std::runtime_error("Sigma support not enabled!");
}
} else {
t = fill_tensor<double, N>(basis_sets, op, thresh);
t = fill_tensor<N, double>(basis_sets, op, rv, thresh);
}

auto rv = results();
return my_pt::wrap_results(rv, t);
auto result = results();
return my_pt::wrap_results(result, t);
}

#define LIBINT(bra, op, ket) Libint<braket<bra, op, ket>>
Expand Down
17 changes: 10 additions & 7 deletions tests/cxx/unit/integrals/ao_integrals/ao_integrals_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@ using simde::type::tensor;
namespace {

void compare_matrices(const tensor& A, const tensor& A_corr) {
using alloc_type = tensorwrapper::allocator::Eigen<double, 2>;
using alloc_type = tensorwrapper::allocator::Eigen<double>;
const auto& A_buffer = alloc_type::rebind(A.buffer());
const auto& A_corr_buffer = alloc_type::rebind(A_corr.buffer());
const auto& A_eigen = A_buffer.value();
const auto& A_corr_eigen = A_corr_buffer.value();

const auto tol = 1E-6;
REQUIRE(A_eigen(0, 0) == Catch::Approx(A_corr_eigen(0, 0)).margin(tol));
REQUIRE(A_eigen(0, 1) == Catch::Approx(A_corr_eigen(0, 1)).margin(tol));
REQUIRE(A_eigen(1, 0) == Catch::Approx(A_corr_eigen(1, 0)).margin(tol));
REQUIRE(A_eigen(1, 1) == Catch::Approx(A_corr_eigen(1, 1)).margin(tol));
auto A00 = A_buffer.at(0, 0);
auto A01 = A_buffer.at(0, 1);
auto A10 = A_buffer.at(1, 0);
auto A11 = A_buffer.at(1, 1);

REQUIRE(A00 == Catch::Approx(A_corr_buffer.at(0, 0)).margin(tol));
REQUIRE(A01 == Catch::Approx(A_corr_buffer.at(0, 1)).margin(tol));
REQUIRE(A10 == Catch::Approx(A_corr_buffer.at(1, 0)).margin(tol));
REQUIRE(A11 == Catch::Approx(A_corr_buffer.at(1, 1)).margin(tol));
}

} // namespace
Expand Down
10 changes: 5 additions & 5 deletions tests/cxx/unit/integrals/ao_integrals/j_four_center.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ TEST_CASE("Four center J builder") {
// Call module
const auto& T = mm.at("Four center J builder").run_as<pt>(braket);

auto t = test::eigen_buffer<2>(T.buffer());
REQUIRE(t.value()(0, 0) == Catch::Approx(0.56044143).margin(1E-6));
REQUIRE(t.value()(0, 1) == Catch::Approx(0.24704427).margin(1E-6));
REQUIRE(t.value()(1, 0) == Catch::Approx(0.24704427).margin(1E-6));
REQUIRE(t.value()(1, 1) == Catch::Approx(0.56044143).margin(1E-6));
auto t = test::eigen_tensor<2>(T.buffer());
REQUIRE(t(0, 0) == Catch::Approx(0.56044143).margin(1E-6));
REQUIRE(t(0, 1) == Catch::Approx(0.24704427).margin(1E-6));
REQUIRE(t(1, 0) == Catch::Approx(0.24704427).margin(1E-6));
REQUIRE(t(1, 1) == Catch::Approx(0.56044143).margin(1E-6));
}
10 changes: 5 additions & 5 deletions tests/cxx/unit/integrals/ao_integrals/k_four_center.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ TEST_CASE("Four center K builder") {
// Call module
const auto& T = mm.at("Four center K builder").run_as<pt>(braket);

auto t = test::eigen_buffer<2>(T.buffer());
REQUIRE(t.value()(0, 0) == Catch::Approx(0.45617623).margin(1E-6));
REQUIRE(t.value()(0, 1) == Catch::Approx(0.35130947).margin(1E-6));
REQUIRE(t.value()(1, 0) == Catch::Approx(0.35130947).margin(1E-6));
REQUIRE(t.value()(1, 1) == Catch::Approx(0.45617623).margin(1E-6));
auto t = test::eigen_tensor<2>(T.buffer());
REQUIRE(t(0, 0) == Catch::Approx(0.45617623).margin(1E-6));
REQUIRE(t(0, 1) == Catch::Approx(0.35130947).margin(1E-6));
REQUIRE(t(1, 0) == Catch::Approx(0.35130947).margin(1E-6));
REQUIRE(t(1, 1) == Catch::Approx(0.45617623).margin(1E-6));
}
45 changes: 21 additions & 24 deletions tests/cxx/unit/integrals/libint/test_arbitrary_operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,9 @@ TEST_CASE("OperatorBase") {
auto T = mod.run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<2>(T.buffer());
REQUIRE(test::trace(t) ==
REQUIRE(test::trace<2>(T.buffer()) ==
Catch::Approx(124.7011973877891364).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<2>(T.buffer()) ==
Catch::Approx(90.2562579028763707).margin(1.0e-16));
}

Expand All @@ -89,14 +88,13 @@ TEST_CASE("OperatorBase") {
auto T = mod.run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<2, udouble>(T.buffer());
REQUIRE(unwrap_mean(test::trace(t)) ==
REQUIRE(unwrap_mean(test::trace<2, udouble>(T.buffer())) ==
Catch::Approx(124.7011973877891364).margin(1.0e-16));
REQUIRE(unwrap_sd(test::trace(t)) ==
REQUIRE(unwrap_sd(test::trace<2, udouble>(T.buffer())) ==
Catch::Approx(7e-16).margin(1.0e-16));
REQUIRE(unwrap_mean(test::norm(t)) ==
REQUIRE(unwrap_mean(test::norm<2, udouble>(T.buffer())) ==
Catch::Approx(90.2562579028763707).margin(1.0e-16));
REQUIRE(unwrap_sd(test::norm(t)) ==
REQUIRE(unwrap_sd(test::norm<2, udouble>(T.buffer())) ==
Catch::Approx(3e-16).margin(1.0e-16));
}
}
Expand All @@ -115,10 +113,9 @@ TEST_CASE("OperatorBase") {
auto T = mod.run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<3>(T.buffer());
REQUIRE(test::trace(t) ==
REQUIRE(test::trace<3>(T.buffer()) ==
Catch::Approx(16.8245948391706577).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<3>(T.buffer()) ==
Catch::Approx(20.6560572032543597).margin(1.0e-16));
}

Expand All @@ -129,14 +126,14 @@ TEST_CASE("OperatorBase") {
auto T = mod.run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<3, udouble>(T.buffer());
REQUIRE(unwrap_mean(test::trace(t)) ==
auto& t = T.buffer();
REQUIRE(unwrap_mean(test::trace<3, udouble>(t)) ==
Catch::Approx(16.8245948391706577).margin(1.0e-16));
REQUIRE(unwrap_sd(test::trace(t)) ==
REQUIRE(unwrap_sd(test::trace<3, udouble>(t)) ==
Catch::Approx(7e-16).margin(1.0e-16));
REQUIRE(unwrap_mean(test::norm(t)) ==
REQUIRE(unwrap_mean(test::norm<3, udouble>(t)) ==
Catch::Approx(20.6560572032543597).margin(1.0e-16));
REQUIRE(unwrap_sd(test::norm(t)) ==
REQUIRE(unwrap_sd(test::norm<3, udouble>(t)) ==
Catch::Approx(7e-16).margin(1.0e-16));
}
}
Expand All @@ -157,10 +154,10 @@ TEST_CASE("OperatorBase") {
auto T = mod.run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<4>(T.buffer());
REQUIRE(test::trace(t) ==
auto& t = T.buffer();
REQUIRE(test::trace<4>(t) ==
Catch::Approx(9.7919608941952063).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<4>(t) ==
Catch::Approx(7.7796143419802553).margin(1.0e-16));
}

Expand All @@ -171,14 +168,14 @@ TEST_CASE("OperatorBase") {
auto T = mod.run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<4, udouble>(T.buffer());
REQUIRE(unwrap_mean(test::trace(t)) ==
auto& t = T.buffer();
REQUIRE(unwrap_mean(test::trace<4, udouble>(t)) ==
Catch::Approx(9.7919608941952063).margin(1.0e-16));
REQUIRE(unwrap_sd(test::trace(t)) ==
REQUIRE(unwrap_sd(test::trace<4, udouble>(t)) ==
Catch::Approx(7e-16).margin(1.0e-16));
REQUIRE(unwrap_mean(test::norm(t)) ==
REQUIRE(unwrap_mean(test::norm<4, udouble>(t)) ==
Catch::Approx(7.7796143419802553).margin(1.0e-16));
REQUIRE(unwrap_sd(test::norm(t)) ==
REQUIRE(unwrap_sd(test::norm<4, udouble>(t)) ==
Catch::Approx(11e-16).margin(1.0e-16));
}
}
Expand Down
6 changes: 3 additions & 3 deletions tests/cxx/unit/integrals/libint/test_eri2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ TEST_CASE("ERI2") {
auto T = mm.at("ERI2").run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<2>(T.buffer());
REQUIRE(test::trace(t) ==
auto& t = T.buffer();
REQUIRE(test::trace<2>(t) ==
Catch::Approx(124.7011973877891364).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<2>(t) ==
Catch::Approx(90.2562579028763707).margin(1.0e-16));
}
6 changes: 3 additions & 3 deletions tests/cxx/unit/integrals/libint/test_eri3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ TEST_CASE("ERI3") {
auto T = mm.at("ERI3").run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<3>(T.buffer());
REQUIRE(test::trace(t) ==
auto& t = T.buffer();
REQUIRE(test::trace<3>(t) ==
Catch::Approx(16.8245948391706577).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<3>(t) ==
Catch::Approx(20.6560572032543597).margin(1.0e-16));
}
7 changes: 4 additions & 3 deletions tests/cxx/unit/integrals/libint/test_eri4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ TEST_CASE("ERI4") {
auto T = mm.at("ERI4").run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<4>(T.buffer());
REQUIRE(test::trace(t) ==
auto& t = T.buffer();
REQUIRE(test::trace<4>(t) ==
Catch::Approx(9.7919608941952063).margin(1.0e-16));
REQUIRE(test::norm(t) == Catch::Approx(7.7796143419802553).margin(1.0e-16));
REQUIRE(test::norm<4>(t) ==
Catch::Approx(7.7796143419802553).margin(1.0e-16));
}
6 changes: 3 additions & 3 deletions tests/cxx/unit/integrals/libint/test_kinetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ TEST_CASE("Kinetic") {
auto T = mm.at("Kinetic").run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<2>(T.buffer());
REQUIRE(test::trace(t) ==
auto& t = T.buffer();
REQUIRE(test::trace<2>(t) ==
Catch::Approx(38.9175852621874441).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<2>(t) ==
Catch::Approx(29.3665362218072552).margin(1.0e-16));
}
6 changes: 3 additions & 3 deletions tests/cxx/unit/integrals/libint/test_nuclear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ TEST_CASE("Nuclear") {
auto T = mm.at("Nuclear").run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<2>(T.buffer());
REQUIRE(test::trace(t) ==
auto& t = T.buffer();
REQUIRE(test::trace<2>(t) ==
Catch::Approx(-111.9975421879705664).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<2>(t) ==
Catch::Approx(66.4857539908047528).margin(1.0e-16));
}
6 changes: 3 additions & 3 deletions tests/cxx/unit/integrals/libint/test_overlap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ TEST_CASE("Overlap") {
auto S = mm.at("Overlap").run_as<test_pt>(braket);

// Check output
auto t = test::eigen_buffer<2>(S.buffer());
REQUIRE(test::trace(t) ==
auto& t = S.buffer();
REQUIRE(test::trace<2>(t) ==
Catch::Approx(7.00000000000000266).margin(1.0e-16));
REQUIRE(test::norm(t) ==
REQUIRE(test::norm<2>(t) ==
Catch::Approx(2.87134497074907324).margin(1.0e-16));
}
34 changes: 24 additions & 10 deletions tests/cxx/unit/integrals/testing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,39 @@
#include <catch2/catch_approx.hpp>
#include <catch2/catch_test_macros.hpp>

#include <unsupported/Eigen/CXX11/Tensor>

namespace test {

template<typename FloatType, std::size_t N, std::size_t... Is>
auto eigen_tensor_(const tensorwrapper::buffer::BufferBase& buffer,
std::array<int, N> extents, std::index_sequence<Is...>) {
const auto& b = tensorwrapper::allocator::Eigen<FloatType>::rebind(buffer);
using eigen_type = Eigen::Tensor<const FloatType, N, Eigen::RowMajor>;
return Eigen::TensorMap<eigen_type>(b.data(), extents[Is]...);
}

// Checking eigen outputs
template<std::size_t N, typename FloatType = double>
auto eigen_buffer(const tensorwrapper::buffer::BufferBase& buffer) {
return static_cast<const tensorwrapper::buffer::Eigen<FloatType, N>&>(
buffer);
auto eigen_tensor(const tensorwrapper::buffer::BufferBase& buffer) {
std::array<int, N> extents;
auto shape = buffer.layout().shape().as_smooth();
for(std::size_t i = 0; i < N; ++i) extents[i] = shape.extent(i);
return eigen_tensor_<FloatType>(buffer, extents,
std::make_index_sequence<N>());
}

template<typename FloatType, unsigned short Rank>
auto trace(const tensorwrapper::buffer::Eigen<FloatType, Rank>& t) {
Eigen::Tensor<FloatType, 0, Eigen::RowMajor> trace = t.value().trace();
template<unsigned short Rank, typename FloatType = double>
auto trace(const tensorwrapper::buffer::BufferBase& buffer) {
auto t = eigen_tensor<Rank, FloatType>(buffer);
Eigen::Tensor<FloatType, 0, Eigen::RowMajor> trace = t.trace();
return trace.coeff();
}

template<typename FloatType, unsigned short Rank>
auto norm(const tensorwrapper::buffer::Eigen<FloatType, Rank>& t) {
Eigen::Tensor<FloatType, 0, Eigen::RowMajor> norm =
t.value().square().sum().sqrt();
template<unsigned short Rank, typename FloatType = double>
auto norm(const tensorwrapper::buffer::BufferBase& buffer) {
auto t = eigen_tensor<Rank, FloatType>(buffer);
Eigen::Tensor<FloatType, 0, Eigen::RowMajor> norm = t.square().sum().sqrt();
return norm.coeff();
}

Expand Down