Commit e91e8cfe authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

compiler cleanup, adding hardware dependent transformations to qcor compiler



Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent ac9a8629
Pipeline #58973 passed with stages
in 7 minutes and 12 seconds
#include "QCORCompiler.hpp" #include "QCORCompiler.hpp"
#include "IRProvider.hpp"
#include "xacc_service.hpp"
namespace qcor { namespace qcor {
std::shared_ptr<IR> QCORCompiler::compile(const std::string &src, std::shared_ptr<IR> QCORCompiler::compile(const std::string &src,
std::shared_ptr<Accelerator> acc) { std::shared_ptr<Accelerator> acc) {
return nullptr; return nullptr;
} }
...@@ -16,19 +17,21 @@ std::shared_ptr<IR> QCORCompiler::compile(const std::string &src) { ...@@ -16,19 +17,21 @@ std::shared_ptr<IR> QCORCompiler::compile(const std::string &src) {
const std::shared_ptr<Function> const std::shared_ptr<Function>
QCORCompiler::compile(std::shared_ptr<Function> f, std::shared_ptr<Accelerator> acc) { QCORCompiler::compile(std::shared_ptr<Function> f, std::shared_ptr<Accelerator> acc) {
if (acc) { auto provider = xacc::getService<xacc::IRProvider>("quantum");
// xacc::info("[qcor] Compiling for " + acc->name()); auto ir = provider->createIR();
} ir->addKernel(f);
// Hardware Independent Transformation
// FIXME Hardware Independent Transformation
// Hardware Dependent Transformations // Hardware Dependent Transformations
if (acc) { if (acc) {
auto ts = acc->getIRTransformations();
for (auto& t : ts) {
ir = t->transform(ir);
}
} }
// Program Verification??? // FIXME Program Verification???
return f; return f;
} }
......
...@@ -30,9 +30,12 @@ bool FuzzyParsingExternalSemaSource::LookupUnqualified(clang::LookupResult &R, ...@@ -30,9 +30,12 @@ bool FuzzyParsingExternalSemaSource::LookupUnqualified(clang::LookupResult &R,
// If this is a valid quantum instruction, tell Clang its // If this is a valid quantum instruction, tell Clang its
// all gonna be ok, we got this... // all gonna be ok, we got this...
if (std::find(validInstructions.begin(), validInstructions.end(), if (std::find(validInstructions.begin(), validInstructions.end(), // not template scope
unknownName) != validInstructions.end()) { unknownName) != validInstructions.end() && S->getFlags() != 128 && S->getBlockParent() != nullptr) {
// std::cout << "HELLO FP: " << unknownName << ", " << S->getFlags() << "\n";
// S->dump();
// S->getBlockParent()->dump();
IdentifierInfo *II = Name.getAsIdentifierInfo(); IdentifierInfo *II = Name.getAsIdentifierInfo();
SourceLocation Loc = R.getNameLoc(); SourceLocation Loc = R.getNameLoc();
auto fdecl = FunctionDecl::Create( auto fdecl = FunctionDecl::Create(
......
...@@ -162,8 +162,8 @@ bool LambdaVisitor::CallExprToIRGenerator::VisitInitListExpr( ...@@ -162,8 +162,8 @@ bool LambdaVisitor::CallExprToIRGenerator::VisitInitListExpr(
ScanInitListExpr visitor; ScanInitListExpr visitor;
visitor.TraverseStmt(child); visitor.TraverseStmt(child);
options.insert({visitor.key, visitor.value}); options.insert({visitor.key, visitor.value});
std::cout << "Inserting " << visitor.key << ", " // std::cout << "Inserting " << visitor.key << ", "
<< visitor.value.toString() << "\n"; // << visitor.value.toString() << "\n";
} }
keepSearching = false; keepSearching = false;
...@@ -182,7 +182,6 @@ bool LambdaVisitor::CallExprToIRGenerator::VisitDeclRefExpr(DeclRefExpr *decl) { ...@@ -182,7 +182,6 @@ bool LambdaVisitor::CallExprToIRGenerator::VisitDeclRefExpr(DeclRefExpr *decl) {
if (dyn_cast<ParmVarDecl>(decl->getDecl())) { if (dyn_cast<ParmVarDecl>(decl->getDecl())) {
auto declName = decl->getNameInfo().getAsString(); auto declName = decl->getNameInfo().getAsString();
// std::cout << "IRGENERATOR FOUND PARAM: " << declName << "\n";
options.insert({"param-id", declName}); options.insert({"param-id", declName});
} }
return true; return true;
...@@ -268,6 +267,7 @@ bool LambdaVisitor::ScanInitListExpr::VisitStringLiteral( ...@@ -268,6 +267,7 @@ bool LambdaVisitor::ScanInitListExpr::VisitStringLiteral(
} }
return true; return true;
} }
bool LambdaVisitor::ScanInitListExpr::VisitFloatingLiteral( bool LambdaVisitor::ScanInitListExpr::VisitFloatingLiteral(
FloatingLiteral *literal) { FloatingLiteral *literal) {
...@@ -280,6 +280,7 @@ bool LambdaVisitor::ScanInitListExpr::VisitFloatingLiteral( ...@@ -280,6 +280,7 @@ bool LambdaVisitor::ScanInitListExpr::VisitFloatingLiteral(
} }
return true; return true;
} }
bool LambdaVisitor::ScanInitListExpr::VisitIntegerLiteral( bool LambdaVisitor::ScanInitListExpr::VisitIntegerLiteral(
IntegerLiteral *literal) { IntegerLiteral *literal) {
...@@ -325,8 +326,8 @@ bool LambdaVisitor::VisitLambdaExpr(LambdaExpr *LE) { ...@@ -325,8 +326,8 @@ bool LambdaVisitor::VisitLambdaExpr(LambdaExpr *LE) {
// If it is, then map it to XACC IR // If it is, then map it to XACC IR
if (isqk.isQuantumKernel()) { if (isqk.isQuantumKernel()) {
LE->dumpColor(); // LE->dumpColor();
// exit(0);
auto cb = LE->capture_begin(); // implicit_capture_begin(); auto cb = LE->capture_begin(); // implicit_capture_begin();
auto ce = LE->capture_end(); auto ce = LE->capture_end();
VarDecl *v; VarDecl *v;
...@@ -386,7 +387,7 @@ bool LambdaVisitor::VisitLambdaExpr(LambdaExpr *LE) { ...@@ -386,7 +387,7 @@ bool LambdaVisitor::VisitLambdaExpr(LambdaExpr *LE) {
} }
} }
std::cout << "\n\nXACC IR:\n" << function->toString() << "\n"; // std::cout << "\n\nXACC IR:\n" << function->toString() << "\n";
// Check if we have IRGenerators in the tree // Check if we have IRGenerators in the tree
if (function->hasIRGenerators()) { if (function->hasIRGenerators()) {
......
#include "QCORASTConsumer.hpp" #include "QCORASTConsumer.hpp"
#include "LambdaVisitor.hpp" #include "LambdaVisitor.hpp"
#include <chrono>
// #include "clang/ASTMatchers/ASTMatchFinder.h"
// #include "clang/ASTMatchers/ASTMatchers.h"
// using namespace clang::ast_matchers;
using namespace clang; using namespace clang;
namespace qcor { namespace qcor {
namespace compiler { namespace compiler {
QCORASTConsumer::QCORASTConsumer(CompilerInstance &c, Rewriter& rw) QCORASTConsumer::QCORASTConsumer(CompilerInstance &c, Rewriter &rw)
: ci(c), fuzzyParser(std::make_shared<FuzzyParsingExternalSemaSource>( : ci(c), fuzzyParser(std::make_shared<FuzzyParsingExternalSemaSource>(
c.getASTContext())), rewriter(rw) {} c.getASTContext())),
rewriter(rw) {}
bool QCORASTConsumer::HandleTopLevelDecl(DeclGroupRef DR) { bool QCORASTConsumer::HandleTopLevelDecl(DeclGroupRef DR) {
using namespace std::chrono;
auto start = std::chrono::high_resolution_clock::now();
LambdaVisitor visitor(ci, rewriter); LambdaVisitor visitor(ci, rewriter);
ci.getSema().addExternalSource(fuzzyParser.get());
for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) { for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) {
// if (std::string((*b)->getDeclKindName()) == "Function") {
// std::cout << (*b)->getDeclKindName() << "\n";
// (*b)->dumpColor();
visitor.TraverseDecl(*b); visitor.TraverseDecl(*b);
// }
} }
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<microseconds>(stop - start);
// std::cout << "Visitor time: " << duration.count() << ", " << std::endl;
return true; return true;
} }
} // namespace compiler } // namespace compiler
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <fstream> #include <fstream>
#include <string> #include <string>
#include "FuzzyParsingExternalSemaSource.hpp"
#include "QCORASTConsumer.hpp" #include "QCORASTConsumer.hpp"
#include "XACC.hpp" #include "XACC.hpp"
using namespace clang; using namespace clang;
...@@ -46,6 +48,9 @@ protected: ...@@ -46,6 +48,9 @@ protected:
CI.createSema(getTranslationUnitKind(), nullptr); CI.createSema(getTranslationUnitKind(), nullptr);
rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
qcor::compiler::FuzzyParsingExternalSemaSource source(CI.getASTContext());
CI.getSema().addExternalSource(&source);
ParseAST(CI.getSema()); ParseAST(CI.getSema());
CI.getDiagnosticClient().EndSourceFile(); CI.getDiagnosticClient().EndSourceFile();
...@@ -86,7 +91,6 @@ int main(int argc, char **argv) { ...@@ -86,7 +91,6 @@ int main(int argc, char **argv) {
xacc::error("File " + fileName + " does not exist."); xacc::error("File " + fileName + " does not exist.");
} }
std::ifstream t(fileName); std::ifstream t(fileName);
std::string src((std::istreambuf_iterator<char>(t)), std::string src((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>()); std::istreambuf_iterator<char>());
...@@ -96,10 +100,8 @@ int main(int argc, char **argv) { ...@@ -96,10 +100,8 @@ int main(int argc, char **argv) {
auto action = new QCORFrontendAction(Rewrite, fileName); auto action = new QCORFrontendAction(Rewrite, fileName);
std::vector<std::string> args{ std::vector<std::string> args{
"-std=c++11", "-I@CMAKE_INSTALL_PREFIX@/include/qcor", "-ftime-report", "-std=c++11", "-I@CMAKE_INSTALL_PREFIX@/include/qcor",
"-I@CMAKE_INSTALL_PREFIX@/include/xacc", "-I@CMAKE_INSTALL_PREFIX@/include/xacc"};
"-I@CMAKE_INSTALL_PREFIX@/include/cppmicroservices4",
"-I@CMAKE_INSTALL_PREFIX@/include/quantum/gate"};
if (!tooling::runToolOnCodeWithArgs(action, src, args)) { if (!tooling::runToolOnCodeWithArgs(action, src, args)) {
xacc::error("Error running qcor compiler."); xacc::error("Error running qcor compiler.");
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
using namespace xacc; using namespace xacc;
namespace qcor{ namespace qcor {
namespace instructions { namespace instructions {
bool HWE::validateOptions() { bool HWE::validateOptions() {
if (options.count("n-qubits")) { if (options.count("n-qubits")) {
...@@ -17,23 +17,23 @@ bool HWE::validateOptions() { ...@@ -17,23 +17,23 @@ bool HWE::validateOptions() {
return true; return true;
} }
std::shared_ptr<Function> HWE::generate( std::shared_ptr<Function>
std::shared_ptr<AcceleratorBuffer> buffer, HWE::generate(std::shared_ptr<AcceleratorBuffer> buffer,
std::vector<InstructionParameter> parameters) { std::vector<InstructionParameter> parameters) {
xacc::error("qcor::HWE::generate(buffer,params) not implemented."); xacc::error("qcor::HWE::generate(buffer,params) not implemented.");
return nullptr; return nullptr;
} }
std::shared_ptr<xacc::Function> HWE::generate( std::shared_ptr<xacc::Function>
std::map<std::string, xacc::InstructionParameter>& parameters) { HWE::generate(std::map<std::string, xacc::InstructionParameter> &parameters) {
if (!parameters.empty()) { if (!parameters.empty()) {
options = parameters; options = parameters;
} }
return generate(std::map<std::string, InstructionParameter>{}); return generate(std::map<std::string, InstructionParameter>{});
} }
std::shared_ptr<Function> HWE::generate( std::shared_ptr<Function>
std::map<std::string, InstructionParameter>&& parameters ) { HWE::generate(std::map<std::string, InstructionParameter> &&parameters) {
if (!parameters.empty()) { if (!parameters.empty()) {
options = parameters; options = parameters;
...@@ -47,8 +47,8 @@ std::shared_ptr<Function> HWE::generate( ...@@ -47,8 +47,8 @@ std::shared_ptr<Function> HWE::generate(
if (options.count("coupling")) { if (options.count("coupling")) {
connectivity = options["coupling"].as<std::vector<std::pair<int, int>>>(); connectivity = options["coupling"].as<std::vector<std::pair<int, int>>>();
} else { } else {
for (int i = 0; i < nQubits-1; i++) { for (int i = 0; i < nQubits - 1; i++) {
connectivity.push_back({i,i+1}); connectivity.push_back({i, i + 1});
} }
} }
...@@ -62,7 +62,7 @@ std::shared_ptr<Function> HWE::generate( ...@@ -62,7 +62,7 @@ std::shared_ptr<Function> HWE::generate(
} }
std::vector<InstructionParameter> fParams; std::vector<InstructionParameter> fParams;
for (int nP = 0; nP < (2*nQubits + 3 * nQubits * layers); nP++) for (int nP = 0; nP < (2 * nQubits + 3 * nQubits * layers); nP++)
fParams.push_back(InstructionParameter(paramLetter + std::to_string(nP))); fParams.push_back(InstructionParameter(paramLetter + std::to_string(nP)));
auto provider = xacc::getService<IRProvider>("gate"); auto provider = xacc::getService<IRProvider>("gate");
...@@ -72,12 +72,14 @@ std::shared_ptr<Function> HWE::generate( ...@@ -72,12 +72,14 @@ std::shared_ptr<Function> HWE::generate(
// Zeroth layer, start with X and Z rotations // Zeroth layer, start with X and Z rotations
for (int q = 0; q < nQubits; q++) { for (int q = 0; q < nQubits; q++) {
auto rx = provider->createInstruction( auto rx = provider->createInstruction(
"Rx", {q}, {InstructionParameter(paramLetter + std::to_string(angleCounter))}); "Rx", {q},
{InstructionParameter(paramLetter + std::to_string(angleCounter))});
auto rz = provider->createInstruction( auto rz = provider->createInstruction(
"Rz", {q}, {InstructionParameter(paramLetter + std::to_string(angleCounter+1))}); "Rz", {q},
{InstructionParameter(paramLetter + std::to_string(angleCounter + 1))});
f->addInstruction(rx); f->addInstruction(rx);
f->addInstruction(rz); f->addInstruction(rz);
angleCounter+=2; angleCounter += 2;
} }
for (int d = 0; d < layers; d++) { for (int d = 0; d < layers; d++) {
...@@ -93,12 +95,14 @@ std::shared_ptr<Function> HWE::generate( ...@@ -93,12 +95,14 @@ std::shared_ptr<Function> HWE::generate(
auto rx = provider->createInstruction( auto rx = provider->createInstruction(
"Rx", {q}, "Rx", {q},
{InstructionParameter(paramLetter + std::to_string(angleCounter+1))}); {InstructionParameter(paramLetter +
std::to_string(angleCounter + 1))});
f->addInstruction(rx); f->addInstruction(rx);
auto rz2 = provider->createInstruction( auto rz2 = provider->createInstruction(
"Rz", {q}, "Rz", {q},
{InstructionParameter(paramLetter + std::to_string(angleCounter + 2))}); {InstructionParameter(paramLetter +
std::to_string(angleCounter + 2))});
f->addInstruction(rz2); f->addInstruction(rz2);
angleCounter += 3; angleCounter += 3;
...@@ -108,5 +112,5 @@ std::shared_ptr<Function> HWE::generate( ...@@ -108,5 +112,5 @@ std::shared_ptr<Function> HWE::generate(
return f; return f;
} }
} } // namespace instructions
} } // namespace qcor
\ No newline at end of file \ No newline at end of file
...@@ -54,16 +54,11 @@ Eigen::MatrixXd compute_2body_fock(const libint2::BasisSet &shells, ...@@ -54,16 +54,11 @@ Eigen::MatrixXd compute_2body_fock(const libint2::BasisSet &shells,
auto s12_34_deg = (s1 == s3) ? (s2 == s4 ? 1.0 : 2.0) : 2.0; auto s12_34_deg = (s1 == s3) ? (s2 == s4 ? 1.0 : 2.0) : 2.0;
auto s1234_deg = s12_deg * s34_deg * s12_34_deg; auto s1234_deg = s12_deg * s34_deg * s12_34_deg;
const auto tstart = std::chrono::high_resolution_clock::now();
engine.compute(shells[s1], shells[s2], shells[s3], shells[s4]); engine.compute(shells[s1], shells[s2], shells[s3], shells[s4]);
const auto *buf_1234 = buf[0]; const auto *buf_1234 = buf[0];
if (buf_1234 == nullptr) if (buf_1234 == nullptr)
continue; // if all integrals screened out, skip to next quartet continue; // if all integrals screened out, skip to next quartet
const auto tstop = std::chrono::high_resolution_clock::now();
time_elapsed += tstop - tstart;
for (auto f1 = 0, f1234 = 0; f1 != n1; ++f1) { for (auto f1 = 0, f1234 = 0; f1 != n1; ++f1) {
const auto bf1 = f1 + bf1_first; const auto bf1 = f1 + bf1_first;
for (auto f2 = 0; f2 != n2; ++f2) { for (auto f2 = 0; f2 != n2; ++f2) {
...@@ -96,11 +91,11 @@ Eigen::MatrixXd compute_2body_fock(const libint2::BasisSet &shells, ...@@ -96,11 +91,11 @@ Eigen::MatrixXd compute_2body_fock(const libint2::BasisSet &shells,
Eigen::MatrixXd Gt = G.transpose(); Eigen::MatrixXd Gt = G.transpose();
return 0.5 * (G + Gt); return 0.5 * (G + Gt);
} }
void LibIntWrapper::generate(std::map<std::string, std::string> &&options) { void LibIntWrapper::generate(std::map<std::string, std::string> &&options, std::vector<int> active, std::vector<int> frozen) {
generate(options); generate(options, active, frozen);
} }
void LibIntWrapper::generate(std::map<std::string, std::string> &options) { void LibIntWrapper::generate(std::map<std::string, std::string> &options, std::vector<int> active, std::vector<int> frozen) {
auto basis = options["basis"]; auto basis = options["basis"];
auto geom = options["geometry"]; auto geom = options["geometry"];
...@@ -137,12 +132,6 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) { ...@@ -137,12 +132,6 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) {
libint2::Shell::do_enforce_unit_normalization(false); libint2::Shell::do_enforce_unit_normalization(false);
// std::cout << "Atomic Cartesian coordinates (a.u.):" << std::endl;
// for (const auto &a : atoms) {
// std::cout << a.atomic_number << " " << a.x << " " << a.y << " " << a.z
// << std::endl;
// }
libint2::initialize(); libint2::initialize();
libint2::BasisSet obs(basis, atoms, true); libint2::BasisSet obs(basis, atoms, true);
...@@ -170,24 +159,19 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) { ...@@ -170,24 +159,19 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) {
// const auto& is very important! // const auto& is very important!
nBasis = obs.nbf(); nBasis = obs.nbf();
auto nshells = obs.size(); auto nshells = obs.size();
// std::cout << "NBF: " << nBasis << "\n";
Eigen::Tensor<double,4> eri_data_t(nBasis, nBasis, nBasis, nBasis);
eri_data_t.setZero();
Eigen::Tensor<double, 1> data_(std::pow(nBasis, 4)); Eigen::Tensor<double, 1> data_(std::pow(nBasis, 4));
int ii = 0; int ii = 0;
// std::cout << "MATRIX:\n" << result << "\n";
for (auto s1 = 0; s1 != obs.size(); ++s1) { for (auto s1 = 0; s1 != obs.size(); ++s1) {
for (auto s2 = 0; s2 != obs.size(); ++s2) { for (auto s2 = 0; s2 != obs.size(); ++s2) {
for (auto s3 = 0; s3 != obs.size(); ++s3) { for (auto s3 = 0; s3 != obs.size(); ++s3) {
for (auto s4 = 0; s4 != obs.size(); ++s4) { for (auto s4 = 0; s4 != obs.size(); ++s4) {
// std::cout << "compute shell set {" << s1 << "," << s2 << "," << s3
// << "," << s4 << "} ... ";
eri_engine.compute(obs[s1], obs[s2], obs[s3], obs[s4]); eri_engine.compute(obs[s1], obs[s2], obs[s3], obs[s4]);
// std::cout << "done. ";
auto ints_shellset = buf[0]; auto ints_shellset = buf[0];
// std::cout << ii << ", " << ints_shellset[0] << "\n";
data_(ii) = ints_shellset[0]; data_(ii) = ints_shellset[0];
eri_data.push_back(ints_shellset[0]); eri_data.push_back(ints_shellset[0]);
ii++; ii++;
...@@ -196,12 +180,8 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) { ...@@ -196,12 +180,8 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) {
} }
} }
// std::cout << "ERI Vec:\n" << data_ << "\n";
// std::cout << "obs size: " << obs.size() << "\n";
const auto &kinetic_buf_vec = const auto &kinetic_buf_vec =
kinetic_engine.results(); // will point to computed shell sets kinetic_engine.results();
// const auto& is very important!
Eigen::Tensor<double, 2> T(nBasis, nBasis); Eigen::Tensor<double, 2> T(nBasis, nBasis);
for (auto s1 = 0; s1 != obs.size(); ++s1) { for (auto s1 = 0; s1 != obs.size(); ++s1) {
...@@ -233,6 +213,7 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) { ...@@ -233,6 +213,7 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) {
} }
} }
} }
// kinetic_data =
// std::cout << "T:\n" << T << "\n"; // std::cout << "T:\n" << T << "\n";
...@@ -317,6 +298,8 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) { ...@@ -317,6 +298,8 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) {
Eigen::MatrixXd H = T_ + V_; Eigen::MatrixXd H = T_ + V_;
std::cout << "T:\n" << T << "\n\n";
std::cout << "V:\n" << V << "\n\n";
Eigen::MatrixXd D; Eigen::MatrixXd D;
// solve H C = e S C // solve H C = e S C
Eigen::GeneralizedSelfAdjointEigenSolver<Eigen::MatrixXd> gen_eig_solver(H, Eigen::GeneralizedSelfAdjointEigenSolver<Eigen::MatrixXd> gen_eig_solver(H,
...@@ -469,15 +452,17 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) { ...@@ -469,15 +452,17 @@ void LibIntWrapper::generate(std::map<std::string, std::string> &options) {
Eigen::Tensor<double, 4> gmo = Eigen::Tensor<double, 4> gmo =
tmp3.contract(CTensor, Eigen::array<IP, 1>{IP(0, 0)}); tmp3.contract(CTensor, Eigen::array<IP, 1>{IP(0, 0)});
Eigen::Tensor<double, 2> H_core_ao = getAOKinetic() + getAOPotential(); Eigen::Tensor<double, 2> H_core_ao = Eigen::TensorMap<Eigen::Tensor<double,2>>(H.data(), nBasis,nBasis);
Eigen::MatrixXd H_core_ao_m = // std::cout << "HCOREAO:\n" << H_core_ao << "\n\n";
Eigen::Map<Eigen::MatrixXd>(H_core_ao.data(), nBasis, nBasis); Eigen::MatrixXd H_core_ao_m = H;
// Eigen::Map<Eigen::MatrixXd>(H_core_ao.data(), nBasis, nBasis);
Eigen::MatrixXd H_1body_ao(2 * nBasis, 2 * nBasis); Eigen::MatrixXd H_1body_ao(2 * nBasis, 2 * nBasis);
H_1body_ao.block(0, 0, nBasis, nBasis) = H_core_ao_m; H_1body_ao.block(0, 0, nBasis, nBasis) = H_core_ao_m;
H_1body_ao.block(nBasis, nBasis, nBasis, nBasis) = H_core_ao_m; H_1body_ao.block(nBasis, nBasis, nBasis, nBasis) = H_core_ao_m;