From 0cdf950e84e20d607245e294ab1be531660c488d Mon Sep 17 00:00:00 2001 From: Thijs Vogels Date: Thu, 16 Oct 2025 14:43:57 +0200 Subject: [PATCH 1/6] add CPU C++ integration example code This adds an example project integrating Skala in a CPU-based C++ application using LibTorch. It comes with: - a conda environment with C++ dependencies of the example, like nlohmann_json and cmake, - a Python script to download the Skala functional as a TorchScript model. - a Python script to prepare meta-GGA input features using PySCF for testing - a C++ program that loads the model and features, and computes Exc and components for Vxc. Co-authored-by: awvwgk <28669218+awvwgk@users.noreply.github.com> Co-authored-by: tvogels <840825+tvogels@users.noreply.github.com> --- README.md | 2 +- examples/cpp/cpp_integration/.gitignore | 3 + examples/cpp/cpp_integration/CMakeLists.txt | 22 +++ examples/cpp/cpp_integration/README.md | 52 ++++++ .../cpp/cpp_integration/download_model.py | 63 ++++++++ examples/cpp/cpp_integration/environment.yml | 11 ++ examples/cpp/cpp_integration/main.cpp | 152 ++++++++++++++++++ .../cpp/cpp_integration/prepare_inputs.py | 58 +++++++ 8 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 examples/cpp/cpp_integration/.gitignore create mode 100644 examples/cpp/cpp_integration/CMakeLists.txt create mode 100644 examples/cpp/cpp_integration/README.md create mode 100755 examples/cpp/cpp_integration/download_model.py create mode 100644 examples/cpp/cpp_integration/environment.yml create mode 100644 examples/cpp/cpp_integration/main.cpp create mode 100755 examples/cpp/cpp_integration/prepare_inputs.py diff --git a/README.md b/README.md index 376549d..ea5a3c2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This repository contains two main components: 1. The Python package `microsoft-skala`, which is also distributed [on PyPI](https://pypi.org/project/microsoft-skala/) and contains a Pytorch implementation of the Skala model, its hookups to quantum chemistry packages [PySCF](https://pyscf.org/) and [ASE](https://ase-lib.org/), and an independent client library for the Skala model served [in Azure AI Foundry](https://ai.azure.com/catalog/models/Skala). 2. A development version of the CPU/GPU C++ library for XC functionals [GauXC](https://github.com/wavefunction91/GauXC) with an add-on supporting Pytorch-based functionals like Skala. GauXC is part of the stack that serves Skala in Azure AI Foundry and can be used to integrate Skala into other third-party DFT codes. -All information below relates to the Python package, the development version of GauXC including its license and other information can be found in [`third_party/gauxc`](https://github.com/microsoft/skala/tree/main/third_party/gauxc). +All information below relates to the Python package, the development version of GauXC including its license and other information can be found in [`third_party/gauxc`](https://github.com/microsoft/skala/tree/main/third_party/gauxc). For an example of how to use Skala directly in C++ applications with LibTorch, see [`examples/cpp/cpp_integration`](https://github.com/microsoft/skala/tree/main/examples/cpp/cpp_integration). ## Getting started diff --git a/examples/cpp/cpp_integration/.gitignore b/examples/cpp/cpp_integration/.gitignore new file mode 100644 index 0000000..d911015 --- /dev/null +++ b/examples/cpp/cpp_integration/.gitignore @@ -0,0 +1,3 @@ +*.pt +*.fun +/_build diff --git a/examples/cpp/cpp_integration/CMakeLists.txt b/examples/cpp/cpp_integration/CMakeLists.txt new file mode 100644 index 0000000..201a3c9 --- /dev/null +++ b/examples/cpp/cpp_integration/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) +project( + "skala_cpp_integration" + VERSION "0.0.1" + LANGUAGES CXX +) + +find_package(nlohmann_json REQUIRED) +find_package(Torch REQUIRED) + +add_executable( + ${PROJECT_NAME} + ./main.cpp +) +target_link_libraries( + ${PROJECT_NAME} + "${TORCH_LIBRARIES}" +) +set_property( + TARGET ${PROJECT_NAME} + PROPERTY CXX_STANDARD 17 +) \ No newline at end of file diff --git a/examples/cpp/cpp_integration/README.md b/examples/cpp/cpp_integration/README.md new file mode 100644 index 0000000..80a75eb --- /dev/null +++ b/examples/cpp/cpp_integration/README.md @@ -0,0 +1,52 @@ +# Integrating Skala in C++ code + +This example demonstrates how to use the Skala machine learning functional in C++ CPU applications using LibTorch. + +## Setup environment + +Set up the conda environment using the provided environment file: + +```bash +cd examples/cpp/cpp_integration +mamba env create -n skala_cpp_integration -f environment.yml +mamba activate skala_cpp_integration +``` + +## Build library + +The example can be built using CMake. +The provided environment is configured for CMake to find the required dependencies. + +```bash +cmake -S . -B _build -G Ninja +cmake --build _build +``` + +For any changes to the code, rebuild using the last command. + +## Run example + +Download the Skala model, as well as a reference LDA functional from HuggingFace +using the provided download script: + +```bash +./download_model.py +``` + +Prepare the molecular features for a test molecule (H2) using the provided script: + +```bash +python ./prepare_inputs.py --output-dir H2 +``` + +Finally, run $E_\text{xc}$ and (partial) $V_\text{xc}$ computations with the C++ example: + +```bash +./_build/skala_cpp_integration skala-1.0.fun H2 +``` + +**Note:** You are expected to add D3 dispersion correction (using b3lyp settings) to the final energy of Skala. + +## Performance tuning + +[This guide](https://intel.github.io/intel-extension-for-pytorch/cpu/latest/tutorials/performance_tuning/tuning_guide.html) from Intel provides useful tips on how to tune performance of PyTorch models on CPU. diff --git a/examples/cpp/cpp_integration/download_model.py b/examples/cpp/cpp_integration/download_model.py new file mode 100755 index 0000000..a1042f5 --- /dev/null +++ b/examples/cpp/cpp_integration/download_model.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 + +""" +This script downloads the Skala model, as well as a reference LDA functional from HuggingFace. + +The LDA functional computes -3 / 4 * (3 / math.pi) ** (1 / 3) * density.abs() ** (4 / 3), +and can be used to verify that the C++ integration is working correctly. +""" + +import shutil + +from huggingface_hub import hf_hub_download + +from skala.functional.load import TracedFunctional + +GRID_SIZE = "grid_size" +NUM_ATOMS = "num_atoms" + +feature_shapes = { + "density": [2, GRID_SIZE], + "kin": [2, GRID_SIZE], + "grad": [2, 3, GRID_SIZE], + "grid_coords": [GRID_SIZE, 3], + "grid_weights": [GRID_SIZE], + "coarse_0_atomic_coords": [NUM_ATOMS, 3], +} + +feature_labels = { + "density": "Electron density on grid, two spin channels", + "kin": "Kinetic energy density on grid, two spin channels", + "grad": "Gradient of electron density on grid, two spin channels", + "grid_coords": "Coordinates of grid points", + "grid_weights": "Weights of grid points", + "coarse_0_atomic_coords": "Atomic coordinates", +} + + +def main() -> None: + huggingface_repo_id = "microsoft/skala" + for filename in ("skala-1.0.fun", "lda.fun"): + output_path = filename + download_model(huggingface_repo_id, filename, output_path) + + +def download_model(huggingface_repo_id: str, filename: str, output_path: str) -> None: + path = hf_hub_download(repo_id=huggingface_repo_id, filename=filename) + shutil.copyfile(path, output_path) + + print(f"Downloaded the {filename} functional to {output_path}") + + fun = TracedFunctional.load(output_path) + + print("\nExpected inputs:") + for feature in fun.features: + print( + f"- {feature} {feature_shapes[feature]} in float64 ({feature_labels[feature]})" + ) + + print(f"\nExpected D3 dispersion settings: {fun.expected_d3_settings}\n") + + +if __name__ == "__main__": + main() diff --git a/examples/cpp/cpp_integration/environment.yml b/examples/cpp/cpp_integration/environment.yml new file mode 100644 index 0000000..b2ad794 --- /dev/null +++ b/examples/cpp/cpp_integration/environment.yml @@ -0,0 +1,11 @@ +name: skala-cpp-integration +channels: +- conda-forge +dependencies: +- cmake +- cxx-compiler +- ninja +- nlohmann_json +- pytorch +- pip: + - microsoft-skala diff --git a/examples/cpp/cpp_integration/main.cpp b/examples/cpp/cpp_integration/main.cpp new file mode 100644 index 0000000..52d07a2 --- /dev/null +++ b/examples/cpp/cpp_integration/main.cpp @@ -0,0 +1,152 @@ +#include +#include +// For at::empty_cache() +#include + +#include +#include + +using json = nlohmann::json; +using IValueList = std::vector; +using IValueMap = std::unordered_map; +using FeatureDict = c10::Dict; + +at::Tensor +load_feature(const std::string &filename, torch::DeviceType device) +{ + std::ifstream input(filename, std::ios::binary); + if (!input.is_open()) + { + throw std::runtime_error("Failed to open feature file: " + filename); + } + std::vector bytes( + (std::istreambuf_iterator(input)), + (std::istreambuf_iterator())); + + input.close(); + return torch::jit::pickle_load(bytes).toTensor().to(device); +} + +FeatureDict +load_features(const std::string &prefix, const std::vector &keys, torch::DeviceType device) +{ + FeatureDict featmap; + for (const auto &key : keys) + { + featmap.insert(key, load_feature(prefix + "/" + key + ".pt", device)); + } + return featmap; +} + +std::tuple> +load_model(const std::string &filename, torch::DeviceType device) +{ + torch::jit::script::Module mod; + torch::jit::ExtraFilesMap extra_files{{"features", ""}, {"protocol_version", ""}}; + std::vector keys; + + try + { + // Deserialize the ScriptModule from a file using torch::jit::load(). + mod = torch::jit::load(filename, device, extra_files); + } + catch (const c10::Error &e) + { + throw std::runtime_error("Error loading the model from " + filename + ": " + e.what()); + } + + auto version = json::parse(extra_files.at("protocol_version")).get(); + if (version != 2) + { + throw std::runtime_error("Unsupported protocol version " + std::to_string(version)); + } + + auto features = json::parse(extra_files.at("features")); + // check if features is array + if (!features.is_array()) + { + throw std::runtime_error("features is not an array"); + } + for (const auto &feature : features) + { + if (!feature.is_string()) + { + throw std::runtime_error("feature is not a string"); + } + keys.push_back(feature.get()); + } + + return std::make_tuple(mod.get_method("get_exc_density"), keys); +} + +at::Tensor +get_exc(const torch::jit::Method &exc_func, const FeatureDict &features) +{ + IValueList args; + IValueMap kwargs; + kwargs["mol"] = features; + return exc_func(args, kwargs).toTensor(); +} + +std::tuple> +get_exc_and_grad(const torch::jit::Method &exc_func, const FeatureDict &features) +{ + // Create a mutable copy only for the tensors that need gradients + FeatureDict features_with_grad; + for (const auto &kv : features) + { + features_with_grad.insert(kv.key(), kv.value().clone().requires_grad_(true)); + } + + IValueList args; + IValueMap kwargs; + kwargs["mol"] = features_with_grad; + + auto exc_on_grid = exc_func(args, kwargs).toTensor(); + auto exc = (exc_on_grid * features_with_grad.at("grid_weights")).sum(); + exc.backward(); + + c10::Dict grad; + for (const auto &kv : features_with_grad) + { + grad.insert(kv.key(), kv.value().grad()); + } + + return std::make_tuple(exc_on_grid, grad); +} + +int main(int argc, const char *argv[]) +{ + if (argc != 3) + { + std::cerr << "usage: skala_cpp_integration \n"; + return -1; + } + + const torch::DeviceType device = torch::kCPU; + + const auto [exc_func, feature_keys] = load_model(std::string(argv[1]), device); + const auto features = load_features(std::string(argv[2]), feature_keys, device); + + std::cout << "Compute Exc..." << std::endl; + + const auto exc_on_grid = get_exc(exc_func, features); + const auto exc = (exc_on_grid * features.at("grid_weights")).sum(); + + std::cout << "Exc = " << exc.item() << std::endl; + + std::cout << "Compute Exc and dExc/dfeat..." << std::endl; + + const auto [exc_on_grid2, grad] = get_exc_and_grad(exc_func, features); + const auto exc2 = (exc_on_grid2 * features.at("grid_weights")).sum(); + + std::cout << "Exc = " << exc2.item() << std::endl; + for (const auto &kv : grad) + { + std::cout << "|dExc/d(" << kv.key() << ")| = " << kv.value().norm().item() << std::endl; + } + + at::empty_cache(); + + return 0; +} diff --git a/examples/cpp/cpp_integration/prepare_inputs.py b/examples/cpp/cpp_integration/prepare_inputs.py new file mode 100755 index 0000000..6865394 --- /dev/null +++ b/examples/cpp/cpp_integration/prepare_inputs.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import argparse +from pathlib import Path + +import torch +from pyscf import dft, gto +from pyscf.dft import gen_grid + +from skala.pyscf.features import generate_features + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument( + "--output-dir", + default=".", + type=Path, + help="Output directory for generated feature files.", + ) + args = parser.parse_args() + + args.output_dir.mkdir(parents=True, exist_ok=True) + + molecule = gto.Mole( + atom="H 0 0 0; H 0 0 1", + basis="def2-qzvp", + verbose=0, + ).build() + + # Create a set of meta-GGA features for this molecule. + dm = get_density_matrix(molecule) + grid = gen_grid.Grids(molecule) + grid.level = 3 + grid.build() + features = generate_features(molecule, dm, grid) + + # Add a feature called `coarse_0_atomic_coords` containing the atomic coordinates. + features["coarse_0_atomic_coords"] = torch.from_numpy(molecule.atom_coords()) + + # Save all features as individual .pt files. + for key, value in features.items(): + torch.save(value, str(args.output_dir / f"{key}.pt")) + + print(f"Saved features to {args.output_dir}") + + +def get_density_matrix(mol: gto.Mole) -> torch.Tensor: + """Computes an example density matrix for a given molecule using PySCF.""" + ks = dft.RKS(mol, xc="b3lyp5") + ks = ks.density_fit() + ks.kernel() + dm = torch.from_numpy(ks.make_rdm1()) + return dm + + +if __name__ == "__main__": + main() From ed4f085fdb9d2263265bb1322cf99a18161841ab Mon Sep 17 00:00:00 2001 From: Thijs Vogels Date: Thu, 16 Oct 2025 18:14:28 +0200 Subject: [PATCH 2/6] a few improvements --- README.md | 3 ++- examples/cpp/cpp_integration/download_model.py | 4 ++-- examples/cpp/cpp_integration/environment.yml | 3 ++- examples/cpp/cpp_integration/main.cpp | 4 ---- examples/cpp/cpp_integration/prepare_inputs.py | 4 ++++ 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ea5a3c2..574d4d7 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,9 @@ This repository contains two main components: 1. The Python package `microsoft-skala`, which is also distributed [on PyPI](https://pypi.org/project/microsoft-skala/) and contains a Pytorch implementation of the Skala model, its hookups to quantum chemistry packages [PySCF](https://pyscf.org/) and [ASE](https://ase-lib.org/), and an independent client library for the Skala model served [in Azure AI Foundry](https://ai.azure.com/catalog/models/Skala). 2. A development version of the CPU/GPU C++ library for XC functionals [GauXC](https://github.com/wavefunction91/GauXC) with an add-on supporting Pytorch-based functionals like Skala. GauXC is part of the stack that serves Skala in Azure AI Foundry and can be used to integrate Skala into other third-party DFT codes. +3. An example of using Skala in C++ CPU applications through LibTorch, see [`examples/cpp/cpp_integration`](examples/cpp/cpp_integration). -All information below relates to the Python package, the development version of GauXC including its license and other information can be found in [`third_party/gauxc`](https://github.com/microsoft/skala/tree/main/third_party/gauxc). For an example of how to use Skala directly in C++ applications with LibTorch, see [`examples/cpp/cpp_integration`](https://github.com/microsoft/skala/tree/main/examples/cpp/cpp_integration). +All information below relates to the Python package, the development version of GauXC including its license and other information can be found in [`third_party/gauxc`](https://github.com/microsoft/skala/tree/main/third_party/gauxc). ## Getting started diff --git a/examples/cpp/cpp_integration/download_model.py b/examples/cpp/cpp_integration/download_model.py index a1042f5..f4b317b 100755 --- a/examples/cpp/cpp_integration/download_model.py +++ b/examples/cpp/cpp_integration/download_model.py @@ -37,8 +37,8 @@ def main() -> None: huggingface_repo_id = "microsoft/skala" - for filename in ("skala-1.0.fun", "lda.fun"): - output_path = filename + for filename in ("skala-1.0.fun", "baselines/ldax.fun"): + output_path = filename.split("/")[-1] download_model(huggingface_repo_id, filename, output_path) diff --git a/examples/cpp/cpp_integration/environment.yml b/examples/cpp/cpp_integration/environment.yml index b2ad794..1e184f5 100644 --- a/examples/cpp/cpp_integration/environment.yml +++ b/examples/cpp/cpp_integration/environment.yml @@ -6,6 +6,7 @@ dependencies: - cxx-compiler - ninja - nlohmann_json -- pytorch +- libtorch +- pytorch # Only required to produce example features. - pip: - microsoft-skala diff --git a/examples/cpp/cpp_integration/main.cpp b/examples/cpp/cpp_integration/main.cpp index 52d07a2..6e8a3ad 100644 --- a/examples/cpp/cpp_integration/main.cpp +++ b/examples/cpp/cpp_integration/main.cpp @@ -1,7 +1,5 @@ #include #include -// For at::empty_cache() -#include #include #include @@ -146,7 +144,5 @@ int main(int argc, const char *argv[]) std::cout << "|dExc/d(" << kv.key() << ")| = " << kv.value().norm().item() << std::endl; } - at::empty_cache(); - return 0; } diff --git a/examples/cpp/cpp_integration/prepare_inputs.py b/examples/cpp/cpp_integration/prepare_inputs.py index 6865394..454dcb3 100755 --- a/examples/cpp/cpp_integration/prepare_inputs.py +++ b/examples/cpp/cpp_integration/prepare_inputs.py @@ -8,6 +8,7 @@ from pyscf.dft import gen_grid from skala.pyscf.features import generate_features +from skala.functional.traditional import LDA def main() -> None: @@ -44,6 +45,9 @@ def main() -> None: print(f"Saved features to {args.output_dir}") + lda_exc = LDA().get_exc(features) + print(f"For reference, LDAx Exc = {lda_exc.item()}") + def get_density_matrix(mol: gto.Mole) -> torch.Tensor: """Computes an example density matrix for a given molecule using PySCF.""" From 55defc49d2e92f899fef09bc3607aa3defa8ae00 Mon Sep 17 00:00:00 2001 From: Jan Hermann Date: Thu, 16 Oct 2025 20:56:33 +0000 Subject: [PATCH 3/6] polish --- README.md | 3 +-- examples/cpp/cpp_integration/README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 574d4d7..36afa28 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Learn more about Skala in our [ArXiv paper](https://arxiv.org/abs/2506.14665). ## What's in here -This repository contains two main components: +This repository contains three main components: 1. The Python package `microsoft-skala`, which is also distributed [on PyPI](https://pypi.org/project/microsoft-skala/) and contains a Pytorch implementation of the Skala model, its hookups to quantum chemistry packages [PySCF](https://pyscf.org/) and [ASE](https://ase-lib.org/), and an independent client library for the Skala model served [in Azure AI Foundry](https://ai.azure.com/catalog/models/Skala). 2. A development version of the CPU/GPU C++ library for XC functionals [GauXC](https://github.com/wavefunction91/GauXC) with an add-on supporting Pytorch-based functionals like Skala. GauXC is part of the stack that serves Skala in Azure AI Foundry and can be used to integrate Skala into other third-party DFT codes. @@ -60,4 +60,3 @@ This project may contain trademarks or logos for projects, products, or services Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies. - diff --git a/examples/cpp/cpp_integration/README.md b/examples/cpp/cpp_integration/README.md index 80a75eb..7c9e4a2 100644 --- a/examples/cpp/cpp_integration/README.md +++ b/examples/cpp/cpp_integration/README.md @@ -9,7 +9,7 @@ Set up the conda environment using the provided environment file: ```bash cd examples/cpp/cpp_integration mamba env create -n skala_cpp_integration -f environment.yml -mamba activate skala_cpp_integration +conda activate skala_cpp_integration ``` ## Build library From d7861a91a35ddc0d7025babe9f54b0b5ef484a15 Mon Sep 17 00:00:00 2001 From: Thijs Vogels Date: Fri, 17 Oct 2025 09:31:46 +0200 Subject: [PATCH 4/6] mamba -> conda --- examples/cpp/cpp_integration/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/cpp_integration/README.md b/examples/cpp/cpp_integration/README.md index 7c9e4a2..4d3aac0 100644 --- a/examples/cpp/cpp_integration/README.md +++ b/examples/cpp/cpp_integration/README.md @@ -8,7 +8,7 @@ Set up the conda environment using the provided environment file: ```bash cd examples/cpp/cpp_integration -mamba env create -n skala_cpp_integration -f environment.yml +conda env create -n skala_cpp_integration -f environment.yml conda activate skala_cpp_integration ``` From ed94628c2a05abd44c189853eeb3a1088f88340e Mon Sep 17 00:00:00 2001 From: Thijs Vogels Date: Fri, 17 Oct 2025 09:47:45 +0200 Subject: [PATCH 5/6] switch to torch::autograd::grad --- examples/cpp/cpp_integration/main.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/examples/cpp/cpp_integration/main.cpp b/examples/cpp/cpp_integration/main.cpp index 6e8a3ad..9de1e10 100644 --- a/examples/cpp/cpp_integration/main.cpp +++ b/examples/cpp/cpp_integration/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -91,9 +92,15 @@ get_exc_and_grad(const torch::jit::Method &exc_func, const FeatureDict &features { // Create a mutable copy only for the tensors that need gradients FeatureDict features_with_grad; + std::vector input_tensors; + std::vector tensor_keys; + for (const auto &kv : features) { - features_with_grad.insert(kv.key(), kv.value().clone().requires_grad_(true)); + auto tensor_with_grad = kv.value().clone().requires_grad_(true); + features_with_grad.insert(kv.key(), tensor_with_grad); + input_tensors.push_back(tensor_with_grad); + tensor_keys.push_back(kv.key()); } IValueList args; @@ -102,12 +109,20 @@ get_exc_and_grad(const torch::jit::Method &exc_func, const FeatureDict &features auto exc_on_grid = exc_func(args, kwargs).toTensor(); auto exc = (exc_on_grid * features_with_grad.at("grid_weights")).sum(); - exc.backward(); + + auto gradients = torch::autograd::grad( + {exc}, // outputs + input_tensors, // inputs + /*grad_outputs=*/{}, // grad_outputs (defaults to ones) + /*retain_graph=*/false, // retain_graph, necessary for higher-order grads + /*create_graph=*/false, // create_graph, necessary for higher-order grads + /*allow_unused=*/true // allow_unused + ); c10::Dict grad; - for (const auto &kv : features_with_grad) + for (size_t i = 0; i < tensor_keys.size(); ++i) { - grad.insert(kv.key(), kv.value().grad()); + grad.insert(tensor_keys[i], gradients[i]); } return std::make_tuple(exc_on_grid, grad); @@ -120,7 +135,7 @@ int main(int argc, const char *argv[]) std::cerr << "usage: skala_cpp_integration \n"; return -1; } - + const torch::DeviceType device = torch::kCPU; const auto [exc_func, feature_keys] = load_model(std::string(argv[1]), device); From dd376183284776fb05162f56611e98dee04a92bd Mon Sep 17 00:00:00 2001 From: Thijs Vogels Date: Fri, 17 Oct 2025 09:57:28 +0200 Subject: [PATCH 6/6] fix formatting --- examples/cpp/cpp_integration/prepare_inputs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/cpp_integration/prepare_inputs.py b/examples/cpp/cpp_integration/prepare_inputs.py index 454dcb3..9f3369f 100755 --- a/examples/cpp/cpp_integration/prepare_inputs.py +++ b/examples/cpp/cpp_integration/prepare_inputs.py @@ -7,8 +7,8 @@ from pyscf import dft, gto from pyscf.dft import gen_grid -from skala.pyscf.features import generate_features from skala.functional.traditional import LDA +from skala.pyscf.features import generate_features def main() -> None: